diff --git a/src/dialogs.py b/src/dialogs.py
index b1377afb36620d3f31b1d8e1ab956ebcb6bc7192..be36d389ec902ceea8a9fc9685bd2f231f18809b 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -4,7 +4,7 @@
 ##	- Yann Le Boulanger <asterix@lagaule.org>
 ##	- Vincent Hanquez <tab@snarc.org>
 ##	- Nikos Kouremenos <kourem@gmail.com>
-##  - Dimitur Kirov <dkirov@gmail.com>
+##	- Dimitur Kirov <dkirov@gmail.com>
 ##
 ##	Copyright (C) 2003-2005 Gajim Team
 ##
@@ -26,12 +26,13 @@ import os
 import gtkgui_helpers
 
 from vcard import VcardWindow
+from filetransfers_window import FileTransfersWindow
 from gajim_themes_window import GajimThemesWindow
 from advanced import AdvancedConfigurationWindow
 from gajim import Contact
 from common import gajim
-from common import i18n
 from common import helpers
+from common import i18n
 
 _ = i18n._
 APP = i18n.APP
@@ -521,381 +522,6 @@ class InformationDialog(HigDialog):
 	def on_ok_button_clicked(self, widget):
 		self.destroy()
 
-class BaseTooltip:
-	''' Base Tooltip . Usage:
-		tooltip = BaseTooltip()
-		.... 
-		tooltip.show_tooltip('', window_postions, widget_postions)
-		....
-		if tooltip.timeout != 0:
-			tooltip.hide_tooltip()
-	'''
-	def __init__(self):
-		self.timeout = 0
-		self.prefered_position = [0, 0]
-		self.win = None
-		self.id = None
-		
-	def populate(self, data):
-		''' this method must be overriden by all extenders '''
-		self.create_window()
-		self.win.add(gtk.Label(data))
-		
-	def create_window(self):
-		''' create a popup window each time tooltip is requested '''
-		self.win = gtk.Window(gtk.WINDOW_POPUP)
-		self.win.set_border_width(3)
-		self.win.set_resizable(False)
-		self.win.set_name('gtk-tooltips')
-		
-		
-		self.win.set_events(gtk.gdk.POINTER_MOTION_MASK)
-		self.win.connect_after('expose_event', self.expose)
-		self.win.connect('size-request', self.size_request)
-		self.win.connect('motion-notify-event', self.motion_notify_event)
-	
-	def motion_notify_event(self, widget, event):
-		self.hide_tooltip()
-
-	def size_request(self, widget, requisition):
-		screen = self.win.get_screen()
-		half_width = requisition.width / 2 + 1
-		if self.prefered_position[0] < half_width:
-			self.prefered_position[0] = 0
-		elif self.prefered_position[0]  + requisition.width > screen.get_width() \
-				+ half_width:
-			self.prefered_position[0] = screen.get_width() - requisition.width
-		else:
-			self.prefered_position[0] -= half_width 
-			screen.get_height()
-		if self.prefered_position[1] + requisition.height > screen.get_height():
-			# flip tooltip up
-			self.prefered_position[1] -= requisition.height  + self.widget_height + 8
-		if self.prefered_position[1] < 0:
-			self.prefered_position[1] = 0
-		self.win.move(self.prefered_position[0], self.prefered_position[1])
-
-	def expose(self, widget, event):
-		style = self.win.get_style()
-		size = self.win.get_size()
-		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
-			self.win, 'tooltip', 0, 0, -1, 1)
-		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
-			self.win, 'tooltip', 0, size[1] - 1, -1, 1)
-		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
-			self.win, 'tooltip', 0, 0, 1, -1)
-		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
-			self.win, 'tooltip', size[0] - 1, 0, 1, -1)
-		return True
-	
-	def show_tooltip(self, data, widget_pos, win_size):
-		self.populate(data)
-		new_x = win_size[0] + widget_pos[0] 
-		new_y = win_size[1] + widget_pos[1] + 4
-		self.prefered_position = [new_x, new_y]
-		self.widget_height = widget_pos[1]
-		self.win.ensure_style()
-		self.win.show_all()
-
-	def hide_tooltip(self):
-		if(self.timeout > 0):
-			gobject.source_remove(self.timeout)
-			self.timeout = 0
-		if self.win:
-			self.win.destroy()
-			self.win = None
-		self.id = None
-
-class StatusTable:
-	''' Contains methods for creating status table. This 
-	is used in Roster and NotificationArea tooltips	'''
-	def __init__(self):
-		self.current_row = 1
-		self.table = None
-		self.text_lable = None
-		
-	def create_table(self):
-		self.table = gtk.Table(3, 1)
-		self.table.set_property('column-spacing', 6)
-		self.text_lable = gtk.Label()
-		self.text_lable.set_line_wrap(True)
-		self.text_lable.set_alignment(0, 0)
-		self.text_lable.set_selectable(False)
-		self.table.attach(self.text_lable, 1, 4, 1, 2)
-		
-	def get_status_info(self, resource, priority, show, status):
-		str_status = resource + ' (' + str(priority) + ')'
-		if status:
-			status = status.strip()
-			if status != '':
-				if gtk.gtk_version < (2, 6, 0) or gtk.pygtk_version < (2, 6, 0):
-					# FIXME: check and do the same if we have more than one \n 
-					status = gtkgui_helpers.reduce_chars_newlines(status, 50, 1)
-				else:
-					status = gtkgui_helpers.reduce_chars_newlines(status, 0, 1)
-				str_status += ' - ' + status
-		return gtkgui_helpers.escape_for_pango_markup(str_status)
-	
-	def add_status_row(self, file_path, show, str_status):
-		''' appends a new row with status icon to the table '''
-		self.current_row += 1
-		state_file = show.replace(' ', '_')
-		files = []
-		files.append(os.path.join(file_path, state_file + '.png'))
-		files.append(os.path.join(file_path, state_file + '.gif'))
-		image = gtk.Image()
-		image.set_from_pixbuf(None)
-		spacer = gtk.Label('   ')
-		for file in files:
-			if os.path.exists(file):
-				image.set_from_file(file)
-				break
-		image.set_alignment(0.01, 1)
-		self.table.attach(spacer, 1, 2, self.current_row, 
-			self.current_row + 1, 0, 0, 0, 0)
-		self.table.attach(image,2,3,self.current_row, 
-			self.current_row + 1, 0, 0, 3, 0)
-		image.set_alignment(0.01, 1)
-		status_label = gtk.Label()
-		status_label.set_markup(str_status)
-		status_label.set_alignment(00, 0)
-		self.table.attach(status_label, 3, 4, self.current_row,
-			self.current_row + 1, gtk.EXPAND | gtk.FILL, 0, 0, 0)
-	
-class NotificationAreaTooltip(BaseTooltip, StatusTable):
-	''' Tooltip that is shown in the notification area '''
-	def __init__(self, plugin):
-		self.plugin = plugin
-		BaseTooltip.__init__(self)
-		StatusTable.__init__(self)
-
-	def populate(self, data):
-		self.create_window()
-		self.create_table()
-		self.hbox = gtk.HBox()
-		self.table.set_property('column-spacing', 1)
-		text, single_line, accounts = '', '', []
-		if gajim.contacts:
-			for account in gajim.contacts.keys():
-				status_idx = gajim.connections[account].connected
-				# uncomment the following to hide offline accounts
-				# if status_idx == 0: continue
-				from common.connection import STATUS_LIST
-				status = STATUS_LIST[status_idx]
-				message = gajim.connections[account].status
-				single_line = helpers.get_uf_show(status)
-				if message is None:
-					message = ''
-				else:
-					message = message.strip()
-				if message != '':
-					single_line += ': ' + message
-				# the other solution is to hide offline accounts
-				elif status == 'offline':
-					message = helpers.get_uf_show(status)
-				accounts.append({'name': account, 'status_line': single_line, 
-						'show': status, 'message': message})
-		unread_messages_no = self.plugin.roster.nb_unread
-		if unread_messages_no > 1:
-			text = _('Gajim - %s unread messages') % unread_messages_no
-		elif unread_messages_no == 1:
-			text = _('Gajim - 1 unread message')
-		elif len(accounts) > 1:
-			text = _('Gajim')
-			self.current_row = 1
-			self.table.resize(2,1)
-			iconset = gajim.config.get('iconset')
-			if not iconset:
-				iconset = 'sun'
-			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
-			for acct in accounts:
-				message = gtkgui_helpers.reduce_chars_newlines(acct['message'], 50, 1)
-				message = gtkgui_helpers.escape_for_pango_markup(message)
-				self.add_status_row(file_path, acct['show'], '<span weight="bold">' + 
-					gtkgui_helpers.escape_for_pango_markup(acct['name']) + '</span>' 
-					+ ' - ' + message)
-					
-		elif len(accounts) == 1:
-			message = gtkgui_helpers.reduce_chars_newlines(accounts[0]['status_line'], 
-				50, 1)
-			message = gtkgui_helpers.escape_for_pango_markup(message)
-			text = _('Gajim - %s') % message
-		else:
-			text = _('Gajim - %s') % helpers.get_uf_show('offline')
-		self.text_lable.set_markup(text)
-		self.hbox.add(self.table)
-		self.win.add(self.hbox)
-	
-class FileTransfersTooltip(BaseTooltip):
-	''' Tooltip that is shown in the notification area '''
-	def __init__(self):
-		self.text_lable = gtk.Label()
-		self.text_lable.set_line_wrap(True)
-		self.text_lable.set_alignment(0, 0)
-		self.text_lable.set_selectable(False)
-		BaseTooltip.__init__(self)
-
-	def populate(self, file_props):
-		self.create_window()
-		self.hbox = gtk.HBox()
-		text = '<b>' + _('Name: ') + '</b>' 
-		name = file_props['name']
-		if not name and file_props['file-name']:
-			if os.path.exists(file_props['file-name']):
-				(path, name) = os.path.split(file_props['file-name'])
-		text += gtkgui_helpers.escape_for_pango_markup(name) 
-		text += '\n<b>' + _('Type: ') + '</b>'
-		if file_props['type'] == 'r':
-			text += _('Download')
-		else:
-			text += _('Upload')
-		if file_props['type'] == 'r':
-			text += '\n<b>' + _('Sender: ') + '</b>'
-			sender = str(file_props['sender']).split('/')[0]
-			name = gajim.get_first_contact_instance_from_jid( 
-				file_props['tt_account'], sender).name
-		else:
-			text += '\n<b>' + _('Recipient: ') + '</b>' 
-			receiver = file_props['receiver']
-			if hasattr(receiver, 'name'):
-				receiver = receiver.name
-			receiver = receiver.split('/')[0]
-			if receiver.find('@') == -1:
-				name = receiver
-			else:
-				name = gajim.get_first_contact_instance_from_jid( 
-				file_props['tt_account'], receiver).name
-		text +=  gtkgui_helpers.escape_for_pango_markup(name)
-		text += '\n<b>' + _('Size: ') + '</b>' 
-		text += helpers.convert_bytes(file_props['size'])
-		text += '\n<b>' + _('Transferred: ') + '</b>' 
-		transfered_len = 0
-		if file_props.has_key('received-len'):
-			transfered_len = file_props['received-len']
-		text += helpers.convert_bytes(transfered_len)
-		text += '\n<b>' + _('Status: ') + '</b>' 
-		status = '' 
-		if not file_props.has_key('started') or not file_props['started']:
-			status =  _('not started')
-		elif file_props.has_key('connected'):
-			if file_props.has_key('stopped') and \
-				file_props['stopped'] == True:
-				status = _('stopped')
-			elif file_props['completed']:
-					status = _('completed')
-			elif file_props['connected'] == False:
-				if file_props['completed']:
-					status = _('completed')
-			else:
-				if file_props.has_key('paused') and  \
-					file_props['paused'] == True:
-					status = _('paused')
-				elif file_props.has_key('stalled') and \
-					file_props['stalled'] == True:
-					status = _('stalled')
-				else:
-					status = _('transferring')
-		else:
-			status =  _('not started')
-		
-		text += status
-		self.text_lable.set_markup(text)
-		self.hbox.add(self.text_lable)
-		self.win.add(self.hbox)
-		
-class RosterTooltip(BaseTooltip, StatusTable):
-	''' Tooltip that is shown in the roster treeview '''
-	def __init__(self, plugin):
-		self.account = None
-		self.plugin = plugin
-		
-		self.image = gtk.Image()
-		self.image.set_alignment(0.5, 0.025)
-		BaseTooltip.__init__(self)
-		StatusTable.__init__(self)
-		
-	def populate(self, contacts):
-		if not contacts or len(contacts) == 0:
-			return
-		self.create_window()
-		self.hbox = gtk.HBox()
-		self.hbox.set_homogeneous(False)
-		self.create_table()
-		# primary contact
-		prim_contact = gajim.get_highest_prio_contact_from_contacts(contacts)
-		
-		# try to find the image for the contact status
-		state_file = prim_contact.show.replace(' ', '_')
-		transport = self.plugin.roster.get_transport_name_by_jid(prim_contact.jid)
-		if transport:
-			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', 'transports', 
-				transport , '16x16')
-		else:
-			iconset = gajim.config.get('iconset')
-			if not iconset:
-				iconset = 'sun'
-			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
-
-		files = []
-		file_full_path = os.path.join(file_path, state_file)
-		files.append(file_full_path + '.png')
-		files.append(file_full_path + '.gif')
-		self.image.set_from_pixbuf(None)
-		for file in files:
-			if os.path.exists(file):
-				self.image.set_from_file(file)
-				break
-		
-		info = '<span size="large" weight="bold">' + prim_contact.jid + '</span>'
-		info += '\n<span weight="bold">' + _('Name: ') + '</span>' + \
-			gtkgui_helpers.escape_for_pango_markup(prim_contact.name)
-		info += '\n<span weight="bold">' + _('Subscription: ') + '</span>' + \
-			gtkgui_helpers.escape_for_pango_markup(prim_contact.sub)
-
-		if prim_contact.keyID:
-			keyID = None
-			if len(prim_contact.keyID) == 8:
-				keyID = prim_contact.keyID
-			elif len(prim_contact.keyID) == 16:
-				keyID = prim_contact.keyID[8:]
-			if keyID:
-				info += '\n<span weight="bold">' + _('OpenPGP: ') + \
-					'</span>' + gtkgui_helpers.escape_for_pango_markup(keyID)
-
-		single_line, resource_str, multiple_resource= '', '', False
-		num_resources = 0
-		for contact in contacts:
-			if contact.resource:
-				num_resources += 1
-		if num_resources > 1:
-			self.current_row = 1
-			self.table.resize(2,1)
-			info += '\n<span weight="bold">' + _('Status: ') + '</span>'
-			for contact in contacts:
-				if contact.resource:
-					status_line = self.get_status_info(contact.resource, contact.priority, 
-						contact.show, contact.status)
-					self.add_status_row(file_path, contact.show, status_line)
-					
-		else: # only one resource
-			if contact.resource:
-				info += '\n<span weight="bold">' + _('Resource: ') + \
-					'</span>' + gtkgui_helpers.escape_for_pango_markup(
-						contact.resource) + ' (' + str(contact.priority) + ')'
-			if contact.show:
-				info += '\n<span weight="bold">' + _('Status: ') + \
-					'</span>' + helpers.get_uf_show(contact.show) 
-				if contact.status:
-					status = contact.status.strip()
-					if status != '':
-						# escape markup entities. Is it posible to have markup in status?
-						info += ' - ' + gtkgui_helpers.escape_for_pango_markup(status)
-		
-		self.text_lable.set_markup(info)
-		self.hbox.pack_start(self.image, False, False)
-		self.hbox.pack_start(self.table, True, True)
-		self.win.add(self.hbox)
-
 class InputDialog:
 	'''Class for Input dialog'''
 	def __init__(self, title, label_str, input_str = None, is_modal = True, ok_handler = None):
@@ -1552,693 +1178,6 @@ class XMLConsoleWindow:
 		# remove us from open windows
 		del self.plugin.windows[self.account]['xml_console']
 		widget.destroy()
-		
-class FileTransfersWindow:
-	def __init__(self, plugin):
-		self.files_props = {'r' : {}, 's': {}}
-		self.plugin = plugin
-		self.height_diff = 0
-		self.last_save_dir = None
-		self.xml = gtk.glade.XML(GTKGUI_GLADE, 'file_transfers_window', APP)
-		self.window = self.xml.get_widget('file_transfers_window')
-		self.tree = self.xml.get_widget('transfers_list')
-		self.cancel_button = self.xml.get_widget('cancel_button')
-		self.pause_button = self.xml.get_widget('pause_restore_button')
-		self.remove_button = self.xml.get_widget('remove_button')
-		self.notify_ft_checkbox = self.xml.get_widget(
-			'notify_ft_complete_checkbox')
-		notify = gajim.config.get('notify_on_file_complete')
-		if notify:
-			self.notify_ft_checkbox.set_active(True)
-		else:
-			self.notify_ft_checkbox.set_active(False)
-		self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, str, str)
-		self.tree.set_model(self.model)
-		col = gtk.TreeViewColumn()
-		
-		render_pixbuf = gtk.CellRendererPixbuf()
-		
-		col.pack_start(render_pixbuf, expand = True)
-		render_pixbuf.set_property('xpad', 3)
-		render_pixbuf.set_property('ypad', 3)
-		render_pixbuf.set_property('yalign', .0)
-		col.add_attribute(render_pixbuf, 'pixbuf', 0)
-		self.tree.append_column(col)
-		
-		col = gtk.TreeViewColumn(_('File'))
-		renderer = gtk.CellRendererText()
-		col.pack_start(renderer, expand=False)
-		col.add_attribute(renderer, 'markup' , 1)
-		renderer.set_property('yalign', 0.)
-		renderer = gtk.CellRendererText()
-		col.pack_start(renderer, expand=True)
-		col.add_attribute(renderer, 'markup' , 2)
-		renderer.set_property('xalign', 0.)
-		renderer.set_property('yalign', 0.)
-		col.set_resizable(True)
-		col.set_expand(True)
-		self.tree.append_column(col)
-		
-		col = gtk.TreeViewColumn(_('Progress'))
-		renderer = gtk.CellRendererText()
-		renderer.set_property('yalign', 0.)
-		renderer.set_property('xalign', 0.)
-		col.pack_start(renderer, expand = True)
-		col.set_expand(False)
-		col.add_attribute(renderer, 'text' , 3)
-		self.tree.append_column(col)
-		self.set_images()
-		self.tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
-		self.tree.get_selection().connect('changed', self.selection_changed)
-		self.tooltip = FileTransfersTooltip()
-		self.xml.signal_autoconnect(self)
-		popup_xml = gtk.glade.XML(GTKGUI_GLADE, 'file_transfers_menu',
-			APP)
-		self.file_transfers_menu = popup_xml.get_widget('file_transfers_menu')
-		self.open_folder_menuitem = popup_xml.get_widget('open_folder_menuitem')
-		self.cancel_menuitem = popup_xml.get_widget('cancel_menuitem')
-		self.pause_menuitem = popup_xml.get_widget('pause_menuitem')
-		self.continue_menuitem = popup_xml.get_widget('continue_menuitem')
-		self.remove_menuitem = popup_xml.get_widget('remove_menuitem')
-		self.clean_up_menuitem = popup_xml.get_widget('clean_up_menuitem')
-		if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
-			self.pause_button.set_image(gtk.image_new_from_stock(
-		gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU))
-		popup_xml.signal_autoconnect(self)
-		
-	def show_completed(self, jid, file_props):
-		self.window.present()
-		self.window.window.focus()
-		sectext = '\t' + _('Filename: %s') % \
-			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
-		sectext += '\n\t' + _('Size: %s') % \
-		helpers.convert_bytes(file_props['size'])
-		sectext += '\n\t' +_('Sender: %s') % \
-			gtkgui_helpers.escape_for_pango_markup(jid)
-		if file_props['type'] == 'r':
-			(path, file) = os.path.split(file_props['file-name'])
-			sectext += '\n\t' +_('Saved in: %s') % \
-				gtkgui_helpers.escape_for_pango_markup(path)
-		dialog = HigDialog(None, _('File transfer completed'), sectext, 
-			gtk.STOCK_DIALOG_INFO, [[_('_Open Containing Folder'), gtk.RESPONSE_ACCEPT], [ gtk.STOCK_OK, gtk.RESPONSE_OK ]])
-		button = dialog.get_button(1)
-		if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
-			button.set_image(gtk.image_new_from_stock(
-		gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_BUTTON))
-		dialog.show_all()
-		if file_props['type'] == 's':
-			button.hide()
-		response = dialog.run()
-		dialog.destroy()
-		if response == gtk.RESPONSE_ACCEPT:
-			if not file_props.has_key('file-name'):
-				return
-			(path, file) = os.path.split(file_props['file-name'])
-			if os.path.exists(path) and os.path.isdir(path):
-				helpers.launch_file_manager(path)
-			self.tree.get_selection().unselect_all()
-		
-	def show_request_error(self, file_props):
-		self.window.present()
-		self.window.window.focus()
-		InformationDialog(_('File transfer canceled'), _('Connection with peer cannot be established.'))
-		self.tree.get_selection().unselect_all()
-		
-	def show_send_error(self, file_props):
-		self.window.present()
-		self.window.window.focus()
-		InformationDialog(_('File transfer canceled'),
-_('Connection with peer cannot be established.'))
-		self.tree.get_selection().unselect_all()
-	
-	def show_stopped(self, jid, file_props):
-		self.window.present()
-		self.window.window.focus()
-		sectext = '\t' + _('Filename: %s') % \
-			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
-		sectext += '\n\t' + _('Sender: %s') % \
-			gtkgui_helpers.escape_for_pango_markup(jid)
-		ErrorDialog(_('File transfer stopped by the contact of the other side'), \
-			sectext).get_response()
-		self.tree.get_selection().unselect_all()
-		
-	def show_file_send_request(self, account, contact):
-		#FIXME: user better name for this function
-		#atm it's like it shows popup for incoming file transfer request
-		dialog = gtk.FileChooserDialog(title=_('Choose File to Send...'), 
-			action=gtk.FILE_CHOOSER_ACTION_OPEN, 
-			buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
-		butt = dialog.add_button(_('Send'), gtk.RESPONSE_OK)
-		butt.set_use_stock(True)
-		dialog.set_default_response(gtk.RESPONSE_OK)
-		if self.last_save_dir and os.path.exists(self.last_save_dir) \
-			and os.path.isdir(self.last_save_dir):
-			dialog.set_current_folder(self.last_save_dir)
-		file_props = {}
-		response = dialog.run()
-		if response == gtk.RESPONSE_OK:
-			file_path =  unicode(dialog.get_filename(), 'utf-8')
-			(file_dir, file_name) = os.path.split(file_path)
-			if file_dir:
-				self.last_save_dir = file_dir
-			dialog.destroy()
-			self.send_file(account, contact, file_path)
-		else:
-			dialog.destroy()
-
-	def send_file(self, account, contact, file_path):
-		(file_dir, file_name) = os.path.split(file_path)
-		file_props = self.get_send_file_props(account, contact, 
-				file_path, file_name)
-		self.add_transfer(account, contact, file_props)
-		gajim.connections[account].send_file_request(file_props)
-	
-	def show_file_request(self, account, contact, file_props):
-		if file_props is None or not file_props.has_key('name'):
-			return
-		sec_text = '\t' + _('File: %s') % \
-			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
-		if file_props.has_key('size'):
-			sec_text += '\n\t' + _('Size: %s') % \
-				helpers.convert_bytes(file_props['size'])
-		if file_props.has_key('mime-type'):
-			sec_text += '\n\t' + _('Type: %s') % \
-				gtkgui_helpers.escape_for_pango_markup(file_props['mime-type'])
-		if file_props.has_key('desc'):
-			sec_text += '\n\t' + _('Description: %s') % \
-				gtkgui_helpers.escape_for_pango_markup(file_props['desc'])
-		prim_text = _('%s wants to send you a file:') % contact.jid
-		dialog = ConfirmationDialog(prim_text, sec_text)
-		if dialog.get_response() == gtk.RESPONSE_OK:
-			dialog = gtk.FileChooserDialog(title=_('Save File as...'), 
-				action=gtk.FILE_CHOOSER_ACTION_SAVE, 
-				buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 
-				gtk.STOCK_SAVE, gtk.RESPONSE_OK))
-			dialog.set_current_name(file_props['name'])
-			dialog.set_default_response(gtk.RESPONSE_OK)
-			if self.last_save_dir and os.path.exists(self.last_save_dir) \
-				and os.path.isdir(self.last_save_dir):
-				dialog.set_current_folder(self.last_save_dir)
-			while True:
-				response = dialog.run()
-				if response == gtk.RESPONSE_OK:
-					file_path = dialog.get_filename()
-					if os.path.exists(file_path):
-						primtext = _('This file already exists')
-						sectext = _('Would you like to overwrite it?')
-						dialog2 = ConfirmationDialog(primtext, sectext)
-						if dialog2.get_response() != gtk.RESPONSE_OK:
-							continue
-					(file_dir, file_name) = os.path.split(file_path)
-					if file_dir:
-						self.last_save_dir = file_dir
-					file_props['file-name'] = file_path.decode('utf-8')
-					self.add_transfer(account, contact, file_props)
-					gajim.connections[account].send_file_approval(file_props)
-				else:
-					gajim.connections[account].send_file_rejection(file_props)
-				dialog.destroy()
-				break
-		else:
-			gajim.connections[account].send_file_rejection(file_props)
-	
-	def set_images(self):
-		self.images = {}
-		self.images['upload'] = self.window.render_icon(gtk.STOCK_GO_UP, 
-			gtk.ICON_SIZE_MENU)
-		self.images['download'] = self.window.render_icon(gtk.STOCK_GO_DOWN, 
-			gtk.ICON_SIZE_MENU)
-		self.images['stop'] = self.window.render_icon(gtk.STOCK_STOP, 
-			gtk.ICON_SIZE_MENU)
-		self.images['waiting'] = self.window.render_icon(gtk.STOCK_REFRESH, 
-			gtk.ICON_SIZE_MENU)
-		self.images['pause'] = self.window.render_icon(gtk.STOCK_MEDIA_PAUSE, 
-			gtk.ICON_SIZE_MENU)
-		self.images['continue'] = self.window.render_icon(gtk.STOCK_MEDIA_PLAY, 
-			gtk.ICON_SIZE_MENU)
-		self.images['ok'] = self.window.render_icon(gtk.STOCK_APPLY, 
-			gtk.ICON_SIZE_MENU)
-			
-	def set_status(self, typ, sid, status):
-		iter = self.get_iter_by_sid(typ, sid)
-		if iter is None:
-			return
-		sid = self.model[iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		if status == 'stop':
-			file_props['stopped'] = True
-		elif status == 'ok':
-			file_props['completed'] = True
-		self.model.set(iter, 0, self.images[status])
-	
-	def set_progress(self, typ, sid, transfered_size, iter = None):
-		if not self.files_props[typ].has_key(sid):
-			return
-		file_props = self.files_props[typ][sid]
-		full_size = int(file_props['size'])
-		if full_size == 0:
-			percent = 0
-		else:
-			percent = round(float(transfered_size) / full_size * 100)
-		if iter is None:
-			iter = self.get_iter_by_sid(typ, sid)
-		if iter is not None:
-			text = str(percent) + '%\n' 
-			if transfered_size == 0:
-				text += '0'
-			else:
-				text += helpers.convert_bytes(transfered_size)
-			text += '/' + helpers.convert_bytes(full_size)
-			self.model.set(iter, 3, text)
-			if file_props['type'] == 'r':
-				status = 'download'
-			else:
-				status = 'upload'
-			if file_props.has_key('paused') and file_props['paused'] == True:
-				status = 'pause'
-			elif file_props.has_key('stalled') and file_props['stalled'] == True:
-				status = 'waiting'
-			if file_props.has_key('connected') and file_props['connected'] == False:
-				status = 'stop'
-			self.model.set(iter, 0, self.images[status])
-			if percent == 100:
-				self.set_status(typ, sid, 'ok')
-	
-	def get_iter_by_sid(self, typ, sid):
-		'''returns iter to the row, which holds file transfer, identified by the
-		session id'''
-		iter = self.model.get_iter_root()
-		while iter:
-			if typ + sid == self.model[iter][4]:
-				return iter
-			iter = self.model.iter_next(iter)
-	
-	def get_sid(self):
-		rng = range(65, 90)
-		rng.extend(range(48, 57))
-		char_sequence = map(lambda e:chr(e), rng)
-		from random import sample
-		return reduce(lambda e1, e2: e1 + e2, 
-				sample(char_sequence, 16))
-	
-	def get_send_file_props(self, account, contact, file_path, file_name):
-		file_props = {'file-name' : file_path, 'name' : file_name, 
-			'type' : 's'}
-		if os.path.exists(file_path) and os.path.isfile(file_path):
-			stat = os.stat(file_path)
-		os.stat(file_path)
-		file_props['size'] = str(stat[6])
-		file_props['sid'] = self.get_sid()
-		file_props['completed'] = False
-		file_props['started'] = False
-		file_props['sender'] = account
-		file_props['receiver'] = contact
-		file_props['tt_account'] = account
-		return file_props
-		
-	def add_transfer(self, account, contact, file_props):
-		self.on_transfers_list_leave_notify_event(None)
-		if file_props is None:
-			return
-		self.files_props[file_props['type']][file_props['sid']] = file_props
-		iter = self.model.append()
-		text_labels = '<b>' + _('Name: ') + '</b>\n' 
-		if file_props['type'] == 'r':
-			text_labels += '<b>' + _('Sender: ') + '</b>' 
-		else:
-			text_labels += '<b>' + _('Recipient: ') + '</b>' 
-		text_props = gtkgui_helpers.escape_for_pango_markup(file_props['name']) + '\n'
-		text_props += gtkgui_helpers.escape_for_pango_markup(contact.name)
-		self.model.set(iter, 1, text_labels, 2, text_props, 4, \
-			file_props['type'] + file_props['sid'])
-		self.set_progress(file_props['type'], file_props['sid'], 0, iter)
-		if file_props.has_key('started') and file_props['started'] is False:
-			status = 'waiting'
-		elif file_props['type'] == 'r':
-			status = 'download'
-		else:
-			status = 'upload'
-		file_props['tt_account'] = account
-		self.set_status(file_props['type'], file_props['sid'], status)
-		self.window.show_all()
-	
-	def on_transfers_list_motion_notify_event(self, widget, event):
-		pointer = self.tree.get_pointer()
-		orig = widget.window.get_origin()
-		props = widget.get_path_at_pos(int(event.x), int(event.y))
-		self.height_diff = pointer[1] - int(event.y)
-		if self.tooltip.timeout > 0:
-			if not props or self.tooltip.id != props[0]:
-				self.tooltip.hide_tooltip()
-		if props:
-			[row, col, x, y] = props
-			iter = None
-			try:
-				iter = self.model.get_iter(row)
-			except:
-				self.tooltip.hide_tooltip()
-				return
-			sid = self.model[iter][4]
-			file_props = self.files_props[sid[0]][sid[1:]]
-			if file_props is not None:
-				if self.tooltip.timeout == 0 or self.tooltip.id != props[0]:
-					self.tooltip.id = row
-					self.tooltip.timeout = gobject.timeout_add(500,
-						self.show_tooltip, widget)
-	
-	def on_transfers_list_leave_notify_event(self, widget = None, event = None):
-		if event is not None:
-			self.height_diff = int(event.y)
-		elif self.height_diff is 0:
-			return
-		pointer = self.tree.get_pointer()
-		props = self.tree.get_path_at_pos(pointer[0], 
-			pointer[1] - self.height_diff)
-		if self.tooltip.timeout > 0:
-			if not props or self.tooltip.id == props[0]:
-				self.tooltip.hide_tooltip()
-	
-	def on_transfers_list_row_activated(self, widget, path, col):
-		# try to open the containing folder
-		self.on_open_folder_menuitem_activate(widget)
-		
-	def is_transfer_paused(self, file_props):
-		if file_props.has_key('stopped') and file_props['stopped']:
-			return False
-		if file_props.has_key('completed') and file_props['completed']:
-			return False
-		if not file_props.has_key('disconnect_cb'):
-			return False
-		return file_props['paused']
-		
-	def is_transfer_active(self, file_props):
-		if file_props.has_key('stopped') and file_props['stopped']:
-			return False
-		if file_props.has_key('completed') and file_props['completed']:
-			return False
-		if not file_props.has_key('started') or not file_props['started']:
-			return False
-		if not file_props.has_key('paused'):
-			return True
-		return not file_props['paused']
-		
-	def is_transfer_stoped(self, file_props):
-		if file_props.has_key('error') and file_props['error'] != 0:
-			return True
-		if file_props.has_key('completed') and file_props['completed']:
-			return True
-		if not file_props.has_key('stopped') or not \
-			file_props['stopped']:
-			return False
-		return True
-		
-	def set_all_insensitive(self):
-		self.pause_button.set_sensitive(False)
-		self.pause_menuitem.set_sensitive(False)
-		self.continue_menuitem.set_sensitive(False)
-		self.remove_button.set_sensitive(False)
-		self.remove_menuitem.set_sensitive(False)
-		self.cancel_button.set_sensitive(False)
-		self.cancel_menuitem.set_sensitive(False)
-		self.open_folder_menuitem.set_sensitive(False)
-	
-	def set_buttons_sensitive(self, path, is_row_selected):
-		if path is None:
-			self.set_all_insensitive()
-			return
-		current_iter = self.model.get_iter(path)
-		sid = self.model[current_iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		self.remove_button.set_sensitive(is_row_selected)
-		self.remove_menuitem.set_sensitive(is_row_selected)
-		self.open_folder_menuitem.set_sensitive(is_row_selected)
-		is_stopped = False
-		if self.is_transfer_stoped(file_props):
-			is_stopped = True
-		self.cancel_button.set_sensitive(not is_stopped)
-		self.cancel_menuitem.set_sensitive(not is_stopped)
-		if not is_row_selected:
-			# no selection, disable the buttons
-			self.set_all_insensitive()
-		elif not is_stopped:
-			if self.is_transfer_active(file_props):
-				# file transfer is active
-				self.toggle_pause_continue(True)
-				self.pause_button.set_sensitive(True)
-			elif self.is_transfer_paused(file_props):
-				# file transfer is paused
-				self.toggle_pause_continue(False)
-				self.pause_button.set_sensitive(True)
-			else:
-				self.pause_button.set_sensitive(False)
-				self.pause_menuitem.set_sensitive(False)
-				self.continue_menuitem.set_sensitive(False)
-		else:
-			self.pause_button.set_sensitive(False)
-			self.pause_menuitem.set_sensitive(False)
-			self.continue_menuitem.set_sensitive(False)
-		return True
-	
-	def selection_changed(self, args):
-		selection = args
-		selected = selection.get_selected_rows()
-		if selected[1] != []:
-			selected_path = selected[1][0]
-			self.select_func(selected_path)
-		else:
-			self.set_all_insensitive()
-	
-	def select_func(self, path):
-		is_selected = False
-		selected = self.tree.get_selection().get_selected_rows()
-		if selected[1] != []:
-			selected_path = selected[1][0]
-			if selected_path == path:
-				is_selected = True
-		self.set_buttons_sensitive(path, is_selected)
-		return True
-	
-	def on_remove_button_clicked(self, widget):
-		selected = self.tree.get_selection().get_selected()
-		if selected is None or selected[1] is None:
-			return 
-		s_iter = selected[1]
-		sid = self.model[s_iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		if not file_props.has_key('tt_account'):
-			# file transfer is not set yet
-			return 
-		account = file_props['tt_account']
-		if not gajim.connections.has_key(account):
-			# no connection to the account
-			return
-		gajim.connections[account].remove_transfer(file_props)
-		self.model.remove(s_iter)
-		self.set_all_insensitive()
-	
-	def toggle_pause_continue(self, status):
-		if status:
-			label = _('Pause')
-			self.pause_button.set_label(label)
-			if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
-				self.pause_button.set_image(gtk.image_new_from_stock(
-			gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU))
-			
-			self.pause_menuitem.set_sensitive(True)
-			self.pause_menuitem.set_no_show_all(False)
-			self.continue_menuitem.hide()
-			self.continue_menuitem.set_no_show_all(True)
-			
-		else:
-			label = _('_Continue')
-			self.pause_button.set_label(label)
-			if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
-				self.pause_button.set_image(gtk.image_new_from_stock(
-			gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU))
-			self.pause_menuitem.hide()
-			self.pause_menuitem.set_no_show_all(True)
-			self.continue_menuitem.set_sensitive(True)
-			self.continue_menuitem.set_no_show_all(False)
-	
-	def on_pause_restore_button_clicked(self, widget):
-		selected = self.tree.get_selection().get_selected()
-		if selected is None or selected[1] is None:
-			return 
-		s_iter = selected[1]
-		sid = self.model[s_iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		if self.is_transfer_paused(file_props):
-			file_props['paused'] = False
-			types = {'r' : 'download', 's' : 'upload'}
-			self.set_status(file_props['type'], file_props['sid'], types[sid[0]])
-			self.toggle_pause_continue(True)
-		elif self.is_transfer_active(file_props):
-			file_props['paused'] = True
-			self.set_status(file_props['type'], file_props['sid'], 'pause')
-			self.toggle_pause_continue(False)
-		
-	def on_cancel_button_clicked(self, widget):
-		selected = self.tree.get_selection().get_selected()
-		if selected is None or selected[1] is None:
-			return 
-		s_iter = selected[1]
-		sid = self.model[s_iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		if not file_props.has_key('tt_account'):
-			return 
-		account = file_props['tt_account']
-		if not gajim.connections.has_key(account):
-			return
-		gajim.connections[account].disconnect_transfer(file_props)
-		self.set_status(file_props['type'], file_props['sid'], 'stop')
-	
-	def show_tooltip(self, widget):
-		if self.height_diff == 0:
-			self.tooltip.hide_tooltip()
-			return
-		pointer = self.tree.get_pointer()
-		props = self.tree.get_path_at_pos(pointer[0], 
-			pointer[1] - self.height_diff)
-		if props and self.tooltip.id == props[0]:
-			# check if the current pointer is at the same path
-			# as it was before setting the timeout
-			iter = self.model.get_iter(props[0])
-			sid = self.model[iter][4]
-			file_props = self.files_props[sid[0]][sid[1:]]
-			rect =  self.tree.get_cell_area(props[0],props[1])
-			position = widget.window.get_origin()
-			self.tooltip.show_tooltip(file_props , (pointer[0], rect.height ), 
-				 (position[0], position[1] + rect.y + self.height_diff))
-		else:
-			self.tooltip.hide_tooltip()
-	
-	def on_notify_ft_complete_checkbox_toggled(self, widget):
-		gajim.config.set('notify_on_file_complete', 
-			widget.get_active())
-		
-	def on_file_transfers_dialog_delete_event(self, widget, event):
-		self.on_transfers_list_leave_notify_event(widget, None)
-		self.window.hide()
-		return True # do NOT destory window
-	
-	def on_close_button_clicked(self, widget):
-		self.window.hide()
-
-	def show_context_menu(self, event, iter):
-		# change the sensitive propery of the buttons and menuitems
-		if len(self.model) == 0:
-			self.clean_up_menuitem.set_sensitive(False)
-		else:
-			self.clean_up_menuitem.set_sensitive(True)
-		path = None
-		if iter is not None:
-			path = self.model.get_path(iter)
-		self.set_buttons_sensitive(path, True)
-		
-		event_button = self.get_possible_button_event(event)
-		self.file_transfers_menu.popup(None, self.tree, None, 
-			event_button, event.time)
-		self.file_transfers_menu.show_all()
-	
-	def get_possible_button_event(self, event):
-		'''mouse or keyboard caused the event?'''
-		if event.type == gtk.gdk.KEY_PRESS:
-			event_button = 0 # no event.button so pass 0
-		else: # BUTTON_PRESS event, so pass event.button
-			event_button = event.button
-		
-		return event_button
-	
-	def on_transfers_list_key_press_event(self, widget, event):
-		'''when a key is pressed in the treeviews'''
-		self.tooltip.hide_tooltip()
-		iter = None
-		try:
-			store, iter = self.tree.get_selection().get_selected()
-		except TypeError:
-			self.tree.get_selection().unselect_all()
-		
-		if iter is not None:
-			path = self.model.get_path(iter)
-			self.tree.get_selection().select_path(path)
-		
-		if event.keyval == gtk.keysyms.Menu:
-			self.show_context_menu(event, iter)
-			return True
-			
-	
-	def on_transfers_list_button_release_event(self, widget, event):
-		# hide tooltip, no matter the button is pressed
-		self.tooltip.hide_tooltip()
-		path = None
-		try:
-			path, column, x, y = self.tree.get_path_at_pos(int(event.x), 
-				int(event.y))
-		except TypeError:
-			self.tree.get_selection().unselect_all()
-		if path is None:
-			self.set_all_insensitive()
-		else:
-			self.select_func(path)
-			
-	def on_transfers_list_button_press_event(self, widget, event):
-		# hide tooltip, no matter the button is pressed
-		self.tooltip.hide_tooltip()
-		path, iter = None, None
-		try:
-			path, column, x, y = self.tree.get_path_at_pos(int(event.x), 
-				int(event.y))
-		except TypeError:
-			self.tree.get_selection().unselect_all()
-		if event.button == 3: # Right click
-			if path is not None:
-				self.tree.get_selection().select_path(path)
-				iter = self.model.get_iter(path)
-			self.show_context_menu(event, iter)
-			if path is not None:
-				return True
-		
-	
-	def on_clean_up_menuitem_activate(self, widget):
-		i = len(self.model) - 1
-		while i >= 0:
-			iter = self.model.get_iter((i))
-			sid = self.model[iter][4]
-			file_props = self.files_props[sid[0]][sid[1:]]
-			if file_props.has_key('completed') and file_props['completed']:
-				self.model.remove(iter)
-			elif file_props.has_key('stopped') and file_props['stopped']:
-				self.model.remove(iter)
-			i -= 1
-		self.tree.get_selection().unselect_all()
-		self.set_all_insensitive()
-		
-	def on_open_folder_menuitem_activate(self, widget):
-		selected = self.tree.get_selection().get_selected()
-		if selected is None or selected[1] is None:
-			return 
-		s_iter = selected[1]
-		sid = self.model[s_iter][4]
-		file_props = self.files_props[sid[0]][sid[1:]]
-		if not file_props.has_key('file-name'):
-			return
-		(path, file) = os.path.split(file_props['file-name'])
-		if os.path.exists(path) and os.path.isdir(path):
-			helpers.launch_file_manager(path)
-		
-	def on_cancel_menuitem_activate(self, widget):
-		self.on_cancel_button_clicked(widget)
-		
-	def on_continue_menuitem_activate(self, widget):
-		self.on_pause_restore_button_clicked(widget)
-	
-	def on_pause_menuitem_activate(self, widget):
-		self.on_pause_restore_button_clicked(widget)
-		# TODO change the stock
-		
-	def on_remove_menuitem_activate(self, widget):
-		self.on_remove_button_clicked(widget)
-
 
 class InvitationDialog:
 	def __init__(self, plugin, account, room_jid, contact_jid, password = None, comment = None):
diff --git a/src/filetransfers_window.py b/src/filetransfers_window.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c59ba532b781d0213cb77a5178d041aa3dacfe9
--- /dev/null
+++ b/src/filetransfers_window.py
@@ -0,0 +1,725 @@
+##	filetransfers_window.py
+##
+## Gajim Team:
+##	- Yann Le Boulanger <asterix@lagaule.org>
+##	- Vincent Hanquez <tab@snarc.org>
+##	- Nikos Kouremenos <kourem@gmail.com>
+##	- Dimitur Kirov <dkirov@gmail.com>
+##
+##	Copyright (C) 2003-2005 Gajim Team
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 2 only.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+
+import gtk
+import gtk.glade
+import gobject
+import os
+
+import gtkgui_helpers
+import tooltips
+import dialogs
+
+from common import gajim
+from common import helpers
+from common import i18n
+
+_ = i18n._
+APP = i18n.APP
+gtk.glade.bindtextdomain (APP, i18n.DIR)
+gtk.glade.textdomain (APP)
+
+GTKGUI_GLADE = 'gtkgui.glade'
+
+class FileTransfersWindow:
+	def __init__(self, plugin):
+		self.files_props = {'r' : {}, 's': {}}
+		self.plugin = plugin
+		self.height_diff = 0
+		self.last_save_dir = None
+		self.xml = gtk.glade.XML(GTKGUI_GLADE, 'file_transfers_window', APP)
+		self.window = self.xml.get_widget('file_transfers_window')
+		self.tree = self.xml.get_widget('transfers_list')
+		self.cancel_button = self.xml.get_widget('cancel_button')
+		self.pause_button = self.xml.get_widget('pause_restore_button')
+		self.remove_button = self.xml.get_widget('remove_button')
+		self.notify_ft_checkbox = self.xml.get_widget(
+			'notify_ft_complete_checkbox')
+		notify = gajim.config.get('notify_on_file_complete')
+		if notify:
+			self.notify_ft_checkbox.set_active(True)
+		else:
+			self.notify_ft_checkbox.set_active(False)
+		self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str, str, str)
+		self.tree.set_model(self.model)
+		col = gtk.TreeViewColumn()
+		
+		render_pixbuf = gtk.CellRendererPixbuf()
+		
+		col.pack_start(render_pixbuf, expand = True)
+		render_pixbuf.set_property('xpad', 3)
+		render_pixbuf.set_property('ypad', 3)
+		render_pixbuf.set_property('yalign', .0)
+		col.add_attribute(render_pixbuf, 'pixbuf', 0)
+		self.tree.append_column(col)
+		
+		col = gtk.TreeViewColumn(_('File'))
+		renderer = gtk.CellRendererText()
+		col.pack_start(renderer, expand=False)
+		col.add_attribute(renderer, 'markup' , 1)
+		renderer.set_property('yalign', 0.)
+		renderer = gtk.CellRendererText()
+		col.pack_start(renderer, expand=True)
+		col.add_attribute(renderer, 'markup' , 2)
+		renderer.set_property('xalign', 0.)
+		renderer.set_property('yalign', 0.)
+		col.set_resizable(True)
+		col.set_expand(True)
+		self.tree.append_column(col)
+		
+		col = gtk.TreeViewColumn(_('Progress'))
+		renderer = gtk.CellRendererText()
+		renderer.set_property('yalign', 0.)
+		renderer.set_property('xalign', 0.)
+		col.pack_start(renderer, expand = True)
+		col.set_expand(False)
+		col.add_attribute(renderer, 'text' , 3)
+		self.tree.append_column(col)
+		self.set_images()
+		self.tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
+		self.tree.get_selection().connect('changed', self.selection_changed)
+		self.tooltip = tooltips.FileTransfersTooltip()
+		self.xml.signal_autoconnect(self)
+		popup_xml = gtk.glade.XML(GTKGUI_GLADE, 'file_transfers_menu',
+			APP)
+		self.file_transfers_menu = popup_xml.get_widget('file_transfers_menu')
+		self.open_folder_menuitem = popup_xml.get_widget('open_folder_menuitem')
+		self.cancel_menuitem = popup_xml.get_widget('cancel_menuitem')
+		self.pause_menuitem = popup_xml.get_widget('pause_menuitem')
+		self.continue_menuitem = popup_xml.get_widget('continue_menuitem')
+		self.remove_menuitem = popup_xml.get_widget('remove_menuitem')
+		self.clean_up_menuitem = popup_xml.get_widget('clean_up_menuitem')
+		if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
+			self.pause_button.set_image(gtk.image_new_from_stock(
+		gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU))
+		popup_xml.signal_autoconnect(self)
+		
+	def show_completed(self, jid, file_props):
+		self.window.present()
+		self.window.window.focus()
+		sectext = '\t' + _('Filename: %s') % \
+			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
+		sectext += '\n\t' + _('Size: %s') % \
+		helpers.convert_bytes(file_props['size'])
+		sectext += '\n\t' +_('Sender: %s') % \
+			gtkgui_helpers.escape_for_pango_markup(jid)
+		if file_props['type'] == 'r':
+			(path, file) = os.path.split(file_props['file-name'])
+			sectext += '\n\t' +_('Saved in: %s') % \
+				gtkgui_helpers.escape_for_pango_markup(path)
+		dialog = dialogs.HigDialog(None, _('File transfer completed'), sectext, 
+			gtk.STOCK_DIALOG_INFO, [[_('_Open Containing Folder'), gtk.RESPONSE_ACCEPT], [ gtk.STOCK_OK, gtk.RESPONSE_OK ]])
+		button = dialog.get_button(1)
+		if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
+			button.set_image(gtk.image_new_from_stock(
+		gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_BUTTON))
+		dialog.show_all()
+		if file_props['type'] == 's':
+			button.hide()
+		response = dialog.run()
+		dialog.destroy()
+		if response == gtk.RESPONSE_ACCEPT:
+			if not file_props.has_key('file-name'):
+				return
+			(path, file) = os.path.split(file_props['file-name'])
+			if os.path.exists(path) and os.path.isdir(path):
+				helpers.launch_file_manager(path)
+			self.tree.get_selection().unselect_all()
+		
+	def show_request_error(self, file_props):
+		self.window.present()
+		self.window.window.focus()
+		dialogs.InformationDialog(_('File transfer canceled'), _('Connection with peer cannot be established.'))
+		self.tree.get_selection().unselect_all()
+		
+	def show_send_error(self, file_props):
+		self.window.present()
+		self.window.window.focus()
+		dialogs.InformationDialog(_('File transfer canceled'),
+_('Connection with peer cannot be established.'))
+		self.tree.get_selection().unselect_all()
+	
+	def show_stopped(self, jid, file_props):
+		self.window.present()
+		self.window.window.focus()
+		sectext = '\t' + _('Filename: %s') % \
+			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
+		sectext += '\n\t' + _('Sender: %s') % \
+			gtkgui_helpers.escape_for_pango_markup(jid)
+		dialogs.ErrorDialog(_('File transfer stopped by the contact of the other side'), \
+			sectext).get_response()
+		self.tree.get_selection().unselect_all()
+		
+	def show_file_send_request(self, account, contact):
+		#FIXME: user better name for this function
+		#atm it's like it shows popup for incoming file transfer request
+		dialog = gtk.FileChooserDialog(title=_('Choose File to Send...'), 
+			action=gtk.FILE_CHOOSER_ACTION_OPEN, 
+			buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
+		butt = dialog.add_button(_('Send'), gtk.RESPONSE_OK)
+		butt.set_use_stock(True)
+		dialog.set_default_response(gtk.RESPONSE_OK)
+		if self.last_save_dir and os.path.exists(self.last_save_dir) \
+			and os.path.isdir(self.last_save_dir):
+			dialog.set_current_folder(self.last_save_dir)
+		file_props = {}
+		response = dialog.run()
+		if response == gtk.RESPONSE_OK:
+			file_path =  unicode(dialog.get_filename(), 'utf-8')
+			(file_dir, file_name) = os.path.split(file_path)
+			if file_dir:
+				self.last_save_dir = file_dir
+			dialog.destroy()
+			self.send_file(account, contact, file_path)
+		else:
+			dialog.destroy()
+
+	def send_file(self, account, contact, file_path):
+		(file_dir, file_name) = os.path.split(file_path)
+		file_props = self.get_send_file_props(account, contact, 
+				file_path, file_name)
+		self.add_transfer(account, contact, file_props)
+		gajim.connections[account].send_file_request(file_props)
+	
+	def show_file_request(self, account, contact, file_props):
+		if file_props is None or not file_props.has_key('name'):
+			return
+		sec_text = '\t' + _('File: %s') % \
+			gtkgui_helpers.escape_for_pango_markup(file_props['name'])
+		if file_props.has_key('size'):
+			sec_text += '\n\t' + _('Size: %s') % \
+				helpers.convert_bytes(file_props['size'])
+		if file_props.has_key('mime-type'):
+			sec_text += '\n\t' + _('Type: %s') % \
+				gtkgui_helpers.escape_for_pango_markup(file_props['mime-type'])
+		if file_props.has_key('desc'):
+			sec_text += '\n\t' + _('Description: %s') % \
+				gtkgui_helpers.escape_for_pango_markup(file_props['desc'])
+		prim_text = _('%s wants to send you a file:') % contact.jid
+		dialog = dialogs.ConfirmationDialog(prim_text, sec_text)
+		if dialog.get_response() == gtk.RESPONSE_OK:
+			dialog = gtk.FileChooserDialog(title=_('Save File as...'), 
+				action=gtk.FILE_CHOOSER_ACTION_SAVE, 
+				buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 
+				gtk.STOCK_SAVE, gtk.RESPONSE_OK))
+			dialog.set_current_name(file_props['name'])
+			dialog.set_default_response(gtk.RESPONSE_OK)
+			if self.last_save_dir and os.path.exists(self.last_save_dir) \
+				and os.path.isdir(self.last_save_dir):
+				dialog.set_current_folder(self.last_save_dir)
+			while True:
+				response = dialog.run()
+				if response == gtk.RESPONSE_OK:
+					file_path = dialog.get_filename()
+					if os.path.exists(file_path):
+						primtext = _('This file already exists')
+						sectext = _('Would you like to overwrite it?')
+						dialog2 = dialogs.ConfirmationDialog(primtext, sectext)
+						if dialog2.get_response() != gtk.RESPONSE_OK:
+							continue
+					(file_dir, file_name) = os.path.split(file_path)
+					if file_dir:
+						self.last_save_dir = file_dir
+					file_props['file-name'] = file_path.decode('utf-8')
+					self.add_transfer(account, contact, file_props)
+					gajim.connections[account].send_file_approval(file_props)
+				else:
+					gajim.connections[account].send_file_rejection(file_props)
+				dialog.destroy()
+				break
+		else:
+			gajim.connections[account].send_file_rejection(file_props)
+	
+	def set_images(self):
+		self.images = {}
+		self.images['upload'] = self.window.render_icon(gtk.STOCK_GO_UP, 
+			gtk.ICON_SIZE_MENU)
+		self.images['download'] = self.window.render_icon(gtk.STOCK_GO_DOWN, 
+			gtk.ICON_SIZE_MENU)
+		self.images['stop'] = self.window.render_icon(gtk.STOCK_STOP, 
+			gtk.ICON_SIZE_MENU)
+		self.images['waiting'] = self.window.render_icon(gtk.STOCK_REFRESH, 
+			gtk.ICON_SIZE_MENU)
+		self.images['pause'] = self.window.render_icon(gtk.STOCK_MEDIA_PAUSE, 
+			gtk.ICON_SIZE_MENU)
+		self.images['continue'] = self.window.render_icon(gtk.STOCK_MEDIA_PLAY, 
+			gtk.ICON_SIZE_MENU)
+		self.images['ok'] = self.window.render_icon(gtk.STOCK_APPLY, 
+			gtk.ICON_SIZE_MENU)
+			
+	def set_status(self, typ, sid, status):
+		iter = self.get_iter_by_sid(typ, sid)
+		if iter is None:
+			return
+		sid = self.model[iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		if status == 'stop':
+			file_props['stopped'] = True
+		elif status == 'ok':
+			file_props['completed'] = True
+		self.model.set(iter, 0, self.images[status])
+	
+	def set_progress(self, typ, sid, transfered_size, iter = None):
+		if not self.files_props[typ].has_key(sid):
+			return
+		file_props = self.files_props[typ][sid]
+		full_size = int(file_props['size'])
+		if full_size == 0:
+			percent = 0
+		else:
+			percent = round(float(transfered_size) / full_size * 100)
+		if iter is None:
+			iter = self.get_iter_by_sid(typ, sid)
+		if iter is not None:
+			text = str(percent) + '%\n' 
+			if transfered_size == 0:
+				text += '0'
+			else:
+				text += helpers.convert_bytes(transfered_size)
+			text += '/' + helpers.convert_bytes(full_size)
+			self.model.set(iter, 3, text)
+			if file_props['type'] == 'r':
+				status = 'download'
+			else:
+				status = 'upload'
+			if file_props.has_key('paused') and file_props['paused'] == True:
+				status = 'pause'
+			elif file_props.has_key('stalled') and file_props['stalled'] == True:
+				status = 'waiting'
+			if file_props.has_key('connected') and file_props['connected'] == False:
+				status = 'stop'
+			self.model.set(iter, 0, self.images[status])
+			if percent == 100:
+				self.set_status(typ, sid, 'ok')
+	
+	def get_iter_by_sid(self, typ, sid):
+		'''returns iter to the row, which holds file transfer, identified by the
+		session id'''
+		iter = self.model.get_iter_root()
+		while iter:
+			if typ + sid == self.model[iter][4]:
+				return iter
+			iter = self.model.iter_next(iter)
+	
+	def get_sid(self):
+		rng = range(65, 90)
+		rng.extend(range(48, 57))
+		char_sequence = map(lambda e:chr(e), rng)
+		from random import sample
+		return reduce(lambda e1, e2: e1 + e2, 
+				sample(char_sequence, 16))
+	
+	def get_send_file_props(self, account, contact, file_path, file_name):
+		file_props = {'file-name' : file_path, 'name' : file_name, 
+			'type' : 's'}
+		if os.path.exists(file_path) and os.path.isfile(file_path):
+			stat = os.stat(file_path)
+		os.stat(file_path)
+		file_props['size'] = str(stat[6])
+		file_props['sid'] = self.get_sid()
+		file_props['completed'] = False
+		file_props['started'] = False
+		file_props['sender'] = account
+		file_props['receiver'] = contact
+		file_props['tt_account'] = account
+		return file_props
+		
+	def add_transfer(self, account, contact, file_props):
+		self.on_transfers_list_leave_notify_event(None)
+		if file_props is None:
+			return
+		self.files_props[file_props['type']][file_props['sid']] = file_props
+		iter = self.model.append()
+		text_labels = '<b>' + _('Name: ') + '</b>\n' 
+		if file_props['type'] == 'r':
+			text_labels += '<b>' + _('Sender: ') + '</b>' 
+		else:
+			text_labels += '<b>' + _('Recipient: ') + '</b>' 
+		text_props = gtkgui_helpers.escape_for_pango_markup(file_props['name']) + '\n'
+		text_props += gtkgui_helpers.escape_for_pango_markup(contact.name)
+		self.model.set(iter, 1, text_labels, 2, text_props, 4, \
+			file_props['type'] + file_props['sid'])
+		self.set_progress(file_props['type'], file_props['sid'], 0, iter)
+		if file_props.has_key('started') and file_props['started'] is False:
+			status = 'waiting'
+		elif file_props['type'] == 'r':
+			status = 'download'
+		else:
+			status = 'upload'
+		file_props['tt_account'] = account
+		self.set_status(file_props['type'], file_props['sid'], status)
+		self.window.show_all()
+	
+	def on_transfers_list_motion_notify_event(self, widget, event):
+		pointer = self.tree.get_pointer()
+		orig = widget.window.get_origin()
+		props = widget.get_path_at_pos(int(event.x), int(event.y))
+		self.height_diff = pointer[1] - int(event.y)
+		if self.tooltip.timeout > 0:
+			if not props or self.tooltip.id != props[0]:
+				self.tooltip.hide_tooltip()
+		if props:
+			[row, col, x, y] = props
+			iter = None
+			try:
+				iter = self.model.get_iter(row)
+			except:
+				self.tooltip.hide_tooltip()
+				return
+			sid = self.model[iter][4]
+			file_props = self.files_props[sid[0]][sid[1:]]
+			if file_props is not None:
+				if self.tooltip.timeout == 0 or self.tooltip.id != props[0]:
+					self.tooltip.id = row
+					self.tooltip.timeout = gobject.timeout_add(500,
+						self.show_tooltip, widget)
+	
+	def on_transfers_list_leave_notify_event(self, widget = None, event = None):
+		if event is not None:
+			self.height_diff = int(event.y)
+		elif self.height_diff is 0:
+			return
+		pointer = self.tree.get_pointer()
+		props = self.tree.get_path_at_pos(pointer[0], 
+			pointer[1] - self.height_diff)
+		if self.tooltip.timeout > 0:
+			if not props or self.tooltip.id == props[0]:
+				self.tooltip.hide_tooltip()
+	
+	def on_transfers_list_row_activated(self, widget, path, col):
+		# try to open the containing folder
+		self.on_open_folder_menuitem_activate(widget)
+		
+	def is_transfer_paused(self, file_props):
+		if file_props.has_key('stopped') and file_props['stopped']:
+			return False
+		if file_props.has_key('completed') and file_props['completed']:
+			return False
+		if not file_props.has_key('disconnect_cb'):
+			return False
+		return file_props['paused']
+		
+	def is_transfer_active(self, file_props):
+		if file_props.has_key('stopped') and file_props['stopped']:
+			return False
+		if file_props.has_key('completed') and file_props['completed']:
+			return False
+		if not file_props.has_key('started') or not file_props['started']:
+			return False
+		if not file_props.has_key('paused'):
+			return True
+		return not file_props['paused']
+		
+	def is_transfer_stoped(self, file_props):
+		if file_props.has_key('error') and file_props['error'] != 0:
+			return True
+		if file_props.has_key('completed') and file_props['completed']:
+			return True
+		if not file_props.has_key('stopped') or not \
+			file_props['stopped']:
+			return False
+		return True
+		
+	def set_all_insensitive(self):
+		self.pause_button.set_sensitive(False)
+		self.pause_menuitem.set_sensitive(False)
+		self.continue_menuitem.set_sensitive(False)
+		self.remove_button.set_sensitive(False)
+		self.remove_menuitem.set_sensitive(False)
+		self.cancel_button.set_sensitive(False)
+		self.cancel_menuitem.set_sensitive(False)
+		self.open_folder_menuitem.set_sensitive(False)
+	
+	def set_buttons_sensitive(self, path, is_row_selected):
+		if path is None:
+			self.set_all_insensitive()
+			return
+		current_iter = self.model.get_iter(path)
+		sid = self.model[current_iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		self.remove_button.set_sensitive(is_row_selected)
+		self.remove_menuitem.set_sensitive(is_row_selected)
+		self.open_folder_menuitem.set_sensitive(is_row_selected)
+		is_stopped = False
+		if self.is_transfer_stoped(file_props):
+			is_stopped = True
+		self.cancel_button.set_sensitive(not is_stopped)
+		self.cancel_menuitem.set_sensitive(not is_stopped)
+		if not is_row_selected:
+			# no selection, disable the buttons
+			self.set_all_insensitive()
+		elif not is_stopped:
+			if self.is_transfer_active(file_props):
+				# file transfer is active
+				self.toggle_pause_continue(True)
+				self.pause_button.set_sensitive(True)
+			elif self.is_transfer_paused(file_props):
+				# file transfer is paused
+				self.toggle_pause_continue(False)
+				self.pause_button.set_sensitive(True)
+			else:
+				self.pause_button.set_sensitive(False)
+				self.pause_menuitem.set_sensitive(False)
+				self.continue_menuitem.set_sensitive(False)
+		else:
+			self.pause_button.set_sensitive(False)
+			self.pause_menuitem.set_sensitive(False)
+			self.continue_menuitem.set_sensitive(False)
+		return True
+	
+	def selection_changed(self, args):
+		selection = args
+		selected = selection.get_selected_rows()
+		if selected[1] != []:
+			selected_path = selected[1][0]
+			self.select_func(selected_path)
+		else:
+			self.set_all_insensitive()
+	
+	def select_func(self, path):
+		is_selected = False
+		selected = self.tree.get_selection().get_selected_rows()
+		if selected[1] != []:
+			selected_path = selected[1][0]
+			if selected_path == path:
+				is_selected = True
+		self.set_buttons_sensitive(path, is_selected)
+		return True
+	
+	def on_remove_button_clicked(self, widget):
+		selected = self.tree.get_selection().get_selected()
+		if selected is None or selected[1] is None:
+			return 
+		s_iter = selected[1]
+		sid = self.model[s_iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		if not file_props.has_key('tt_account'):
+			# file transfer is not set yet
+			return 
+		account = file_props['tt_account']
+		if not gajim.connections.has_key(account):
+			# no connection to the account
+			return
+		gajim.connections[account].remove_transfer(file_props)
+		self.model.remove(s_iter)
+		self.set_all_insensitive()
+	
+	def toggle_pause_continue(self, status):
+		if status:
+			label = _('Pause')
+			self.pause_button.set_label(label)
+			if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
+				self.pause_button.set_image(gtk.image_new_from_stock(
+			gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU))
+			
+			self.pause_menuitem.set_sensitive(True)
+			self.pause_menuitem.set_no_show_all(False)
+			self.continue_menuitem.hide()
+			self.continue_menuitem.set_no_show_all(True)
+			
+		else:
+			label = _('_Continue')
+			self.pause_button.set_label(label)
+			if gtk.gtk_version >= (2, 6, 0) and gtk.pygtk_version >= (2, 6, 0):
+				self.pause_button.set_image(gtk.image_new_from_stock(
+			gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU))
+			self.pause_menuitem.hide()
+			self.pause_menuitem.set_no_show_all(True)
+			self.continue_menuitem.set_sensitive(True)
+			self.continue_menuitem.set_no_show_all(False)
+	
+	def on_pause_restore_button_clicked(self, widget):
+		selected = self.tree.get_selection().get_selected()
+		if selected is None or selected[1] is None:
+			return 
+		s_iter = selected[1]
+		sid = self.model[s_iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		if self.is_transfer_paused(file_props):
+			file_props['paused'] = False
+			types = {'r' : 'download', 's' : 'upload'}
+			self.set_status(file_props['type'], file_props['sid'], types[sid[0]])
+			self.toggle_pause_continue(True)
+		elif self.is_transfer_active(file_props):
+			file_props['paused'] = True
+			self.set_status(file_props['type'], file_props['sid'], 'pause')
+			self.toggle_pause_continue(False)
+		
+	def on_cancel_button_clicked(self, widget):
+		selected = self.tree.get_selection().get_selected()
+		if selected is None or selected[1] is None:
+			return 
+		s_iter = selected[1]
+		sid = self.model[s_iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		if not file_props.has_key('tt_account'):
+			return 
+		account = file_props['tt_account']
+		if not gajim.connections.has_key(account):
+			return
+		gajim.connections[account].disconnect_transfer(file_props)
+		self.set_status(file_props['type'], file_props['sid'], 'stop')
+	
+	def show_tooltip(self, widget):
+		if self.height_diff == 0:
+			self.tooltip.hide_tooltip()
+			return
+		pointer = self.tree.get_pointer()
+		props = self.tree.get_path_at_pos(pointer[0], 
+			pointer[1] - self.height_diff)
+		if props and self.tooltip.id == props[0]:
+			# check if the current pointer is at the same path
+			# as it was before setting the timeout
+			iter = self.model.get_iter(props[0])
+			sid = self.model[iter][4]
+			file_props = self.files_props[sid[0]][sid[1:]]
+			rect =  self.tree.get_cell_area(props[0],props[1])
+			position = widget.window.get_origin()
+			self.tooltip.show_tooltip(file_props , (pointer[0], rect.height ), 
+				 (position[0], position[1] + rect.y + self.height_diff))
+		else:
+			self.tooltip.hide_tooltip()
+	
+	def on_notify_ft_complete_checkbox_toggled(self, widget):
+		gajim.config.set('notify_on_file_complete', 
+			widget.get_active())
+		
+	def on_file_transfers_dialog_delete_event(self, widget, event):
+		self.on_transfers_list_leave_notify_event(widget, None)
+		self.window.hide()
+		return True # do NOT destory window
+	
+	def on_close_button_clicked(self, widget):
+		self.window.hide()
+
+	def show_context_menu(self, event, iter):
+		# change the sensitive propery of the buttons and menuitems
+		if len(self.model) == 0:
+			self.clean_up_menuitem.set_sensitive(False)
+		else:
+			self.clean_up_menuitem.set_sensitive(True)
+		path = None
+		if iter is not None:
+			path = self.model.get_path(iter)
+		self.set_buttons_sensitive(path, True)
+		
+		event_button = self.get_possible_button_event(event)
+		self.file_transfers_menu.popup(None, self.tree, None, 
+			event_button, event.time)
+		self.file_transfers_menu.show_all()
+	
+	def get_possible_button_event(self, event):
+		'''mouse or keyboard caused the event?'''
+		if event.type == gtk.gdk.KEY_PRESS:
+			event_button = 0 # no event.button so pass 0
+		else: # BUTTON_PRESS event, so pass event.button
+			event_button = event.button
+		
+		return event_button
+	
+	def on_transfers_list_key_press_event(self, widget, event):
+		'''when a key is pressed in the treeviews'''
+		self.tooltip.hide_tooltip()
+		iter = None
+		try:
+			store, iter = self.tree.get_selection().get_selected()
+		except TypeError:
+			self.tree.get_selection().unselect_all()
+		
+		if iter is not None:
+			path = self.model.get_path(iter)
+			self.tree.get_selection().select_path(path)
+		
+		if event.keyval == gtk.keysyms.Menu:
+			self.show_context_menu(event, iter)
+			return True
+			
+	
+	def on_transfers_list_button_release_event(self, widget, event):
+		# hide tooltip, no matter the button is pressed
+		self.tooltip.hide_tooltip()
+		path = None
+		try:
+			path, column, x, y = self.tree.get_path_at_pos(int(event.x), 
+				int(event.y))
+		except TypeError:
+			self.tree.get_selection().unselect_all()
+		if path is None:
+			self.set_all_insensitive()
+		else:
+			self.select_func(path)
+			
+	def on_transfers_list_button_press_event(self, widget, event):
+		# hide tooltip, no matter the button is pressed
+		self.tooltip.hide_tooltip()
+		path, iter = None, None
+		try:
+			path, column, x, y = self.tree.get_path_at_pos(int(event.x), 
+				int(event.y))
+		except TypeError:
+			self.tree.get_selection().unselect_all()
+		if event.button == 3: # Right click
+			if path is not None:
+				self.tree.get_selection().select_path(path)
+				iter = self.model.get_iter(path)
+			self.show_context_menu(event, iter)
+			if path is not None:
+				return True
+		
+	
+	def on_clean_up_menuitem_activate(self, widget):
+		i = len(self.model) - 1
+		while i >= 0:
+			iter = self.model.get_iter((i))
+			sid = self.model[iter][4]
+			file_props = self.files_props[sid[0]][sid[1:]]
+			if file_props.has_key('completed') and file_props['completed']:
+				self.model.remove(iter)
+			elif file_props.has_key('stopped') and file_props['stopped']:
+				self.model.remove(iter)
+			i -= 1
+		self.tree.get_selection().unselect_all()
+		self.set_all_insensitive()
+		
+	def on_open_folder_menuitem_activate(self, widget):
+		selected = self.tree.get_selection().get_selected()
+		if selected is None or selected[1] is None:
+			return 
+		s_iter = selected[1]
+		sid = self.model[s_iter][4]
+		file_props = self.files_props[sid[0]][sid[1:]]
+		if not file_props.has_key('file-name'):
+			return
+		(path, file) = os.path.split(file_props['file-name'])
+		if os.path.exists(path) and os.path.isdir(path):
+			helpers.launch_file_manager(path)
+		
+	def on_cancel_menuitem_activate(self, widget):
+		self.on_cancel_button_clicked(widget)
+		
+	def on_continue_menuitem_activate(self, widget):
+		self.on_pause_restore_button_clicked(widget)
+	
+	def on_pause_menuitem_activate(self, widget):
+		self.on_pause_restore_button_clicked(widget)
+		# TODO change the stock
+		
+	def on_remove_menuitem_activate(self, widget):
+		self.on_remove_button_clicked(widget)
diff --git a/src/roster_window.py b/src/roster_window.py
index db754393735c76b8df6d6b0c534c6eab3418180b..bb742fe4374cd56337259bbf688ae1bb5d50ed1f 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -32,6 +32,7 @@ import dialogs
 import config
 import gtkgui_helpers
 import cell_renderer_image
+import tooltips
 
 from gajim import Contact
 from common import gajim
@@ -2156,7 +2157,7 @@ _('If "%s" accepts this request you will know his status.') %jid)
 			self.on_status_combobox_changed)
 
 		self.collapsed_rows = gajim.config.get('collapsed_rows').split('\t')
-		self.tooltip = dialogs.RosterTooltip(self.plugin)
+		self.tooltip = tooltips.RosterTooltip(self.plugin)
 		self.make_menu()
 		self.draw_roster()
 
diff --git a/src/systray.py b/src/systray.py
index 813f3cb724f1af2232e116d9f14b5294e4c417c7..7ed7d68d9dbf1ead9281ec58b30ea49e11685d2c 100644
--- a/src/systray.py
+++ b/src/systray.py
@@ -24,6 +24,8 @@ import gobject
 import dialogs
 import os
 
+import tooltips
+
 from common import gajim
 from common.connection import STATUS_LIST
 from common import helpers
@@ -321,7 +323,7 @@ class Systray:
 			eb.connect('button-press-event', self.on_clicked)
 			eb.connect('motion-notify-event', self.on_tray_motion_notify_event)
 			eb.connect('leave-notify-event', self.on_tray_leave_notify_event)
-			self.tooltip = dialogs.NotificationAreaTooltip(self.plugin)
+			self.tooltip = tooltips.NotificationAreaTooltip(self.plugin)
 
 			self.img_tray = gtk.Image()
 			eb.add(self.img_tray)
diff --git a/src/tooltips.py b/src/tooltips.py
new file mode 100644
index 0000000000000000000000000000000000000000..c54369bf2e40c0a8dbd2907f7a847bd0a975305c
--- /dev/null
+++ b/src/tooltips.py
@@ -0,0 +1,407 @@
+##	tooltips.py
+##
+## Gajim Team:
+##	- Yann Le Boulanger <asterix@lagaule.org>
+##	- Vincent Hanquez <tab@snarc.org>
+##	- Nikos Kouremenos <kourem@gmail.com>
+##	- Dimitur Kirov <dkirov@gmail.com>
+##
+##	Copyright (C) 2003-2005 Gajim Team
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 2 only.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+
+import gtk
+import gobject
+import os
+
+import gtkgui_helpers
+
+from common import gajim
+from common import helpers
+from common import i18n
+
+_ = i18n._
+APP = i18n.APP
+
+class BaseTooltip:
+	''' Base Tooltip . Usage:
+		tooltip = BaseTooltip()
+		.... 
+		tooltip.show_tooltip('', window_postions, widget_postions)
+		....
+		if tooltip.timeout != 0:
+			tooltip.hide_tooltip()
+	'''
+	def __init__(self):
+		self.timeout = 0
+		self.prefered_position = [0, 0]
+		self.win = None
+		self.id = None
+		
+	def populate(self, data):
+		''' this method must be overriden by all extenders '''
+		self.create_window()
+		self.win.add(gtk.Label(data))
+		
+	def create_window(self):
+		''' create a popup window each time tooltip is requested '''
+		self.win = gtk.Window(gtk.WINDOW_POPUP)
+		self.win.set_border_width(3)
+		self.win.set_resizable(False)
+		self.win.set_name('gtk-tooltips')
+		
+		
+		self.win.set_events(gtk.gdk.POINTER_MOTION_MASK)
+		self.win.connect_after('expose_event', self.expose)
+		self.win.connect('size-request', self.size_request)
+		self.win.connect('motion-notify-event', self.motion_notify_event)
+	
+	def motion_notify_event(self, widget, event):
+		self.hide_tooltip()
+
+	def size_request(self, widget, requisition):
+		screen = self.win.get_screen()
+		half_width = requisition.width / 2 + 1
+		if self.prefered_position[0] < half_width:
+			self.prefered_position[0] = 0
+		elif self.prefered_position[0]  + requisition.width > screen.get_width() \
+				+ half_width:
+			self.prefered_position[0] = screen.get_width() - requisition.width
+		else:
+			self.prefered_position[0] -= half_width 
+			screen.get_height()
+		if self.prefered_position[1] + requisition.height > screen.get_height():
+			# flip tooltip up
+			self.prefered_position[1] -= requisition.height  + self.widget_height + 8
+		if self.prefered_position[1] < 0:
+			self.prefered_position[1] = 0
+		self.win.move(self.prefered_position[0], self.prefered_position[1])
+
+	def expose(self, widget, event):
+		style = self.win.get_style()
+		size = self.win.get_size()
+		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
+			self.win, 'tooltip', 0, 0, -1, 1)
+		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
+			self.win, 'tooltip', 0, size[1] - 1, -1, 1)
+		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
+			self.win, 'tooltip', 0, 0, 1, -1)
+		style.paint_flat_box(self.win.window, gtk.STATE_NORMAL, gtk.SHADOW_OUT, None,
+			self.win, 'tooltip', size[0] - 1, 0, 1, -1)
+		return True
+	
+	def show_tooltip(self, data, widget_pos, win_size):
+		self.populate(data)
+		new_x = win_size[0] + widget_pos[0] 
+		new_y = win_size[1] + widget_pos[1] + 4
+		self.prefered_position = [new_x, new_y]
+		self.widget_height = widget_pos[1]
+		self.win.ensure_style()
+		self.win.show_all()
+
+	def hide_tooltip(self):
+		if(self.timeout > 0):
+			gobject.source_remove(self.timeout)
+			self.timeout = 0
+		if self.win:
+			self.win.destroy()
+			self.win = None
+		self.id = None
+
+class StatusTable:
+	''' Contains methods for creating status table. This 
+	is used in Roster and NotificationArea tooltips	'''
+	def __init__(self):
+		self.current_row = 1
+		self.table = None
+		self.text_lable = None
+		
+	def create_table(self):
+		self.table = gtk.Table(3, 1)
+		self.table.set_property('column-spacing', 6)
+		self.text_lable = gtk.Label()
+		self.text_lable.set_line_wrap(True)
+		self.text_lable.set_alignment(0, 0)
+		self.text_lable.set_selectable(False)
+		self.table.attach(self.text_lable, 1, 4, 1, 2)
+		
+	def get_status_info(self, resource, priority, show, status):
+		str_status = resource + ' (' + str(priority) + ')'
+		if status:
+			status = status.strip()
+			if status != '':
+				if gtk.gtk_version < (2, 6, 0) or gtk.pygtk_version < (2, 6, 0):
+					# FIXME: check and do the same if we have more than one \n 
+					status = gtkgui_helpers.reduce_chars_newlines(status, 50, 1)
+				else:
+					status = gtkgui_helpers.reduce_chars_newlines(status, 0, 1)
+				str_status += ' - ' + status
+		return gtkgui_helpers.escape_for_pango_markup(str_status)
+	
+	def add_status_row(self, file_path, show, str_status):
+		''' appends a new row with status icon to the table '''
+		self.current_row += 1
+		state_file = show.replace(' ', '_')
+		files = []
+		files.append(os.path.join(file_path, state_file + '.png'))
+		files.append(os.path.join(file_path, state_file + '.gif'))
+		image = gtk.Image()
+		image.set_from_pixbuf(None)
+		spacer = gtk.Label('   ')
+		for file in files:
+			if os.path.exists(file):
+				image.set_from_file(file)
+				break
+		image.set_alignment(0.01, 1)
+		self.table.attach(spacer, 1, 2, self.current_row, 
+			self.current_row + 1, 0, 0, 0, 0)
+		self.table.attach(image,2,3,self.current_row, 
+			self.current_row + 1, 0, 0, 3, 0)
+		image.set_alignment(0.01, 1)
+		status_label = gtk.Label()
+		status_label.set_markup(str_status)
+		status_label.set_alignment(00, 0)
+		self.table.attach(status_label, 3, 4, self.current_row,
+			self.current_row + 1, gtk.EXPAND | gtk.FILL, 0, 0, 0)
+	
+class NotificationAreaTooltip(BaseTooltip, StatusTable):
+	''' Tooltip that is shown in the notification area '''
+	def __init__(self, plugin):
+		self.plugin = plugin
+		BaseTooltip.__init__(self)
+		StatusTable.__init__(self)
+
+	def populate(self, data):
+		self.create_window()
+		self.create_table()
+		self.hbox = gtk.HBox()
+		self.table.set_property('column-spacing', 1)
+		text, single_line, accounts = '', '', []
+		if gajim.contacts:
+			for account in gajim.contacts.keys():
+				status_idx = gajim.connections[account].connected
+				# uncomment the following to hide offline accounts
+				# if status_idx == 0: continue
+				from common.connection import STATUS_LIST
+				status = STATUS_LIST[status_idx]
+				message = gajim.connections[account].status
+				single_line = helpers.get_uf_show(status)
+				if message is None:
+					message = ''
+				else:
+					message = message.strip()
+				if message != '':
+					single_line += ': ' + message
+				# the other solution is to hide offline accounts
+				elif status == 'offline':
+					message = helpers.get_uf_show(status)
+				accounts.append({'name': account, 'status_line': single_line, 
+						'show': status, 'message': message})
+		unread_messages_no = self.plugin.roster.nb_unread
+		if unread_messages_no > 1:
+			text = _('Gajim - %s unread messages') % unread_messages_no
+		elif unread_messages_no == 1:
+			text = _('Gajim - 1 unread message')
+		elif len(accounts) > 1:
+			text = _('Gajim')
+			self.current_row = 1
+			self.table.resize(2,1)
+			iconset = gajim.config.get('iconset')
+			if not iconset:
+				iconset = 'sun'
+			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
+			for acct in accounts:
+				message = gtkgui_helpers.reduce_chars_newlines(acct['message'], 50, 1)
+				message = gtkgui_helpers.escape_for_pango_markup(message)
+				self.add_status_row(file_path, acct['show'], '<span weight="bold">' + 
+					gtkgui_helpers.escape_for_pango_markup(acct['name']) + '</span>' 
+					+ ' - ' + message)
+					
+		elif len(accounts) == 1:
+			message = gtkgui_helpers.reduce_chars_newlines(accounts[0]['status_line'], 
+				50, 1)
+			message = gtkgui_helpers.escape_for_pango_markup(message)
+			text = _('Gajim - %s') % message
+		else:
+			text = _('Gajim - %s') % helpers.get_uf_show('offline')
+		self.text_lable.set_markup(text)
+		self.hbox.add(self.table)
+		self.win.add(self.hbox)
+		
+class RosterTooltip(BaseTooltip, StatusTable):
+	''' Tooltip that is shown in the roster treeview '''
+	def __init__(self, plugin):
+		self.account = None
+		self.plugin = plugin
+		
+		self.image = gtk.Image()
+		self.image.set_alignment(0.5, 0.025)
+		BaseTooltip.__init__(self)
+		StatusTable.__init__(self)
+		
+	def populate(self, contacts):
+		if not contacts or len(contacts) == 0:
+			return
+		self.create_window()
+		self.hbox = gtk.HBox()
+		self.hbox.set_homogeneous(False)
+		self.create_table()
+		# primary contact
+		prim_contact = gajim.get_highest_prio_contact_from_contacts(contacts)
+		
+		# try to find the image for the contact status
+		state_file = prim_contact.show.replace(' ', '_')
+		transport = self.plugin.roster.get_transport_name_by_jid(prim_contact.jid)
+		if transport:
+			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', 'transports', 
+				transport , '16x16')
+		else:
+			iconset = gajim.config.get('iconset')
+			if not iconset:
+				iconset = 'sun'
+			file_path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
+
+		files = []
+		file_full_path = os.path.join(file_path, state_file)
+		files.append(file_full_path + '.png')
+		files.append(file_full_path + '.gif')
+		self.image.set_from_pixbuf(None)
+		for file in files:
+			if os.path.exists(file):
+				self.image.set_from_file(file)
+				break
+		
+		info = '<span size="large" weight="bold">' + prim_contact.jid + '</span>'
+		info += '\n<span weight="bold">' + _('Name: ') + '</span>' + \
+			gtkgui_helpers.escape_for_pango_markup(prim_contact.name)
+		info += '\n<span weight="bold">' + _('Subscription: ') + '</span>' + \
+			gtkgui_helpers.escape_for_pango_markup(prim_contact.sub)
+
+		if prim_contact.keyID:
+			keyID = None
+			if len(prim_contact.keyID) == 8:
+				keyID = prim_contact.keyID
+			elif len(prim_contact.keyID) == 16:
+				keyID = prim_contact.keyID[8:]
+			if keyID:
+				info += '\n<span weight="bold">' + _('OpenPGP: ') + \
+					'</span>' + gtkgui_helpers.escape_for_pango_markup(keyID)
+
+		single_line, resource_str, multiple_resource= '', '', False
+		num_resources = 0
+		for contact in contacts:
+			if contact.resource:
+				num_resources += 1
+		if num_resources > 1:
+			self.current_row = 1
+			self.table.resize(2,1)
+			info += '\n<span weight="bold">' + _('Status: ') + '</span>'
+			for contact in contacts:
+				if contact.resource:
+					status_line = self.get_status_info(contact.resource, contact.priority, 
+						contact.show, contact.status)
+					self.add_status_row(file_path, contact.show, status_line)
+					
+		else: # only one resource
+			if contact.resource:
+				info += '\n<span weight="bold">' + _('Resource: ') + \
+					'</span>' + gtkgui_helpers.escape_for_pango_markup(
+						contact.resource) + ' (' + str(contact.priority) + ')'
+			if contact.show:
+				info += '\n<span weight="bold">' + _('Status: ') + \
+					'</span>' + helpers.get_uf_show(contact.show) 
+				if contact.status:
+					status = contact.status.strip()
+					if status != '':
+						# escape markup entities. Is it posible to have markup in status?
+						info += ' - ' + gtkgui_helpers.escape_for_pango_markup(status)
+		
+		self.text_lable.set_markup(info)
+		self.hbox.pack_start(self.image, False, False)
+		self.hbox.pack_start(self.table, True, True)
+		self.win.add(self.hbox)
+
+class FileTransfersTooltip(BaseTooltip):
+	''' Tooltip that is shown in the notification area '''
+	def __init__(self):
+		self.text_lable = gtk.Label()
+		self.text_lable.set_line_wrap(True)
+		self.text_lable.set_alignment(0, 0)
+		self.text_lable.set_selectable(False)
+		BaseTooltip.__init__(self)
+
+	def populate(self, file_props):
+		self.create_window()
+		self.hbox = gtk.HBox()
+		text = '<b>' + _('Name: ') + '</b>' 
+		name = file_props['name']
+		if not name and file_props['file-name']:
+			if os.path.exists(file_props['file-name']):
+				(path, name) = os.path.split(file_props['file-name'])
+		text += gtkgui_helpers.escape_for_pango_markup(name) 
+		text += '\n<b>' + _('Type: ') + '</b>'
+		if file_props['type'] == 'r':
+			text += _('Download')
+		else:
+			text += _('Upload')
+		if file_props['type'] == 'r':
+			text += '\n<b>' + _('Sender: ') + '</b>'
+			sender = str(file_props['sender']).split('/')[0]
+			name = gajim.get_first_contact_instance_from_jid( 
+				file_props['tt_account'], sender).name
+		else:
+			text += '\n<b>' + _('Recipient: ') + '</b>' 
+			receiver = file_props['receiver']
+			if hasattr(receiver, 'name'):
+				receiver = receiver.name
+			receiver = receiver.split('/')[0]
+			if receiver.find('@') == -1:
+				name = receiver
+			else:
+				name = gajim.get_first_contact_instance_from_jid( 
+				file_props['tt_account'], receiver).name
+		text +=  gtkgui_helpers.escape_for_pango_markup(name)
+		text += '\n<b>' + _('Size: ') + '</b>' 
+		text += helpers.convert_bytes(file_props['size'])
+		text += '\n<b>' + _('Transferred: ') + '</b>' 
+		transfered_len = 0
+		if file_props.has_key('received-len'):
+			transfered_len = file_props['received-len']
+		text += helpers.convert_bytes(transfered_len)
+		text += '\n<b>' + _('Status: ') + '</b>' 
+		status = '' 
+		if not file_props.has_key('started') or not file_props['started']:
+			status =  _('not started')
+		elif file_props.has_key('connected'):
+			if file_props.has_key('stopped') and \
+				file_props['stopped'] == True:
+				status = _('stopped')
+			elif file_props['completed']:
+					status = _('completed')
+			elif file_props['connected'] == False:
+				if file_props['completed']:
+					status = _('completed')
+			else:
+				if file_props.has_key('paused') and  \
+					file_props['paused'] == True:
+					status = _('paused')
+				elif file_props.has_key('stalled') and \
+					file_props['stalled'] == True:
+					status = _('stalled')
+				else:
+					status = _('transferring')
+		else:
+			status =  _('not started')
+		
+		text += status
+		self.text_lable.set_markup(text)
+		self.hbox.add(self.text_lable)
+		self.win.add(self.hbox)