# -*- coding: utf-8 -*-
# h-client, a client for an h-source server (such as http://www.h-node.org/)
# Copyright (C) 2011  Antonio Gallo
#
#
# h-client 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, either version 3 of the License, or
# (at your option) any later version.
#
# h-client 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.
#
# You should have received a copy of the GNU General Public License
# along with h-client.  If not, see <http://www.gnu.org/licenses/>.


from __future__ import absolute_import

import pygtk
pygtk.require('2.0')
import gtk
import pkg_resources

from hclient.hlibrary import Client
from hclient.l10n import _
from hclient import devices, devicetypes, machine


def get_img_path(name):
	""""Return path to image resource file of specified name."""
	return pkg_resources.resource_filename("hclient.img", name)


class hclient(object):

	#: The device shown in the right window.
	currentDevice = None
	currentDeviceCode = None

	def isInserting(self):
		return self.client.devices[self.currentDeviceCode][2] == "insert"

	def isUpdating(self):
		return self.client.devices[self.currentDeviceCode][2] == "update"

	def getActive(self, combo, default="not-specified"):
		"""Get the active text from a *combo*.

		*combo* is the GTK combo instance.  If active index is
        negative, the *default* value is used.
		"""
		model = combo.get_model()
		active = combo.get_active()
		if active < 0:
			return default
		else:
			return model[active][0]

	def applyChanges(self, widget):
		"""Update the current device by taking the values from the entries."""
		self.currentDevice.setModel(self.modelNameEntry.get_text())

		otherNamesBuffer = self.otherNamesText.get_buffer()
		startiter, enditer = otherNamesBuffer.get_bounds()
		self.currentDevice.setOtherNames([])
		self.currentDevice.addOtherNames(otherNamesBuffer.get_text(startiter, enditer))

		self.currentDevice.subtype = self.subtypeCombo.get_active()

		self.currentDevice.tracks_users = self.itTracksUsersCombo.get_active()

		year = self.getActive(self.commYearCombo)
		try:
			self.currentDevice.setYear(int(year))
		except ValueError:
			self.currentDevice.setYear(None)

		self.currentDevice.interface = self.interfaceCombo.get_active()

		self.currentDevice.setDistributions([])
		self.currentDevice.addDistributions(self.distributionEntry.get_text())

		self.currentDevice.kernel = self.kernelEntry.get_text()

		self.currentDevice.how_it_works = self.howItWorksCombo.get_active()

		self.currentDevice.setDriver(self.driverEntry.get_text())

		descriptionBuffer = self.descriptionText.get_buffer()
		startiter, enditer = descriptionBuffer.get_bounds()
		self.currentDevice.setDescription(descriptionBuffer.get_text(startiter, enditer))

	def resetChanges(self,widget):
		"""Reset the modifications."""
		self.setEntries()

	def setCurrentDevice(self, selection):
		"""Set the device that has to be displaced in the right window
		and fill the entries.
		"""
		model, path = selection.get_selected()
		if path:
			#get the code:
			code = model.get_value(path, 1)

			if code in self.client.devices:
				
				#set the current device
				self.currentDevice = self.client.devices[code][0]
				self.currentDeviceCode = code

				self.setEntries()

				#make sensitive the apply button
				if self.currentDevice.type is not devicetypes.Unknown:
					self.enableButtons()
				else:
					self.disableButtons()

				self.setDeviceInfoLabel()

			else:
				#make non sensitive the apply button
				self.disableButtons()
				self.currentDevice = None
				self.currentDeviceCode = None

				#self.updateStatus()

	def enableButtons(self):
		"""Enable the bottom buttons."""
		self.applyButton.set_sensitive(True)
		self.resetButton.set_sensitive(True)
		self.submitButton.set_sensitive(True)

	def disableButtons(self):
		"""Disable the bottom buttons."""
		self.applyButton.set_sensitive(False)
		self.resetButton.set_sensitive(False)
		self.submitButton.set_sensitive(False)

	def setDeviceInfoLabel(self):
		"""Set the top label."""
		if self.currentDeviceCode != None:
			self.bigIcon.set_from_file(get_img_path("devices/big/"+self.currentDevice.type.icon))
			if self.client.devices[self.currentDeviceCode][2] == 'insert':
				self.deviceInfoLabel.set_markup(_("this device is not present in the server database,\n would you like to <b>insert</b> it?"))
			else:
				self.deviceInfoLabel.set_markup(_("this device is already present in the server database,\n would you like to <b>update</b> it?"))

	def setEntries(self):
		"""Set the pyGTK device entries."""
		if self.currentDevice == None:
			return
		#set the type entry
		self.setTypeEntry()
		#set the model entry
		self.setModelEntry()
		#set the other names entry
		self.setOtherNamesEntry()
		#set the vendorid:productid entry
		self.setVendorIdProductIDCode()
		#set the subtype entry (in the case of printers)
		self.setSubtypeEntry()
		#set the commercialization year entry
		self.setCommYearEntry()
		#set the interface entry
		self.setInterfaceEntry()
		#set the distribution entry
		self.setDistributionEntry()
		#set the kernel entry
		self.setKernelEntry()
		#set the howItWorks entry
		self.setHowItWorksEntry()
		#set the driver entry
		self.setDriverEntry()
		#set the description entry
		self.setDescriptionEntry()
		#set the it_tracks_users entry
		self.setItTracksUsersEntry()

	def changeType(self,widget):
		"""Change the type of a device."""
		if self.isInserting():
			Type = self.getActive(self.typeCombo)
			if self.currentDevice.type.type_name == Type:
				return
			self.client.changeType(self.currentDeviceCode,Type)
		self.setDeviceTree()

	def setTypeEntry(self):
		"""Set the subtype entry of a printer."""
		if self.currentDevice.type.type_name in devices.get_types():
			index = devices.get_types().index(self.currentDevice.type.type_name)
		else:
			index = 0

		self.typeCombo.set_active(index)

	def setModelEntry(self):
		"""Set the model name entry."""
		self.modelNameEntry.set_text(self.currentDevice.getModel())

	def setOtherNamesEntry(self):
		"""Set the other names entry."""
		textbuffer = gtk.TextBuffer(table=None)
		textbuffer.set_text(self.currentDevice.createOtherNamesEntry())
		self.otherNamesText.set_buffer(textbuffer)

	def setVendorIdProductIDCode(self):
		"""set the ``vendorid:productid`` entry."""
		self.vendorIdProductIdEntry.set_text(self.currentDevice.getVendorId() + ':' + self.currentDevice.getProductId())

	def setSubtypeEntry(self):
		"""Set the subtype entry of a printer."""
		self.subtypeCombo.get_model().clear()
		device_type = self.currentDevice.type
		for subtype in device_type.subtypes:
			self.subtypeCombo.append_text(subtype)
		self.subtypeCombo.set_active(self.currentDevice.subtype)

	def setItTracksUsersEntry(self):
		"""Set the itTracksUsers entry of a printer."""
		self.itTracksUsersCombo.get_model().clear()
		device_type = self.currentDevice.type
		for option in device_type.tracks_users:
			self.itTracksUsersCombo.append_text(option)
		self.itTracksUsersCombo.set_active(self.currentDevice.tracks_users)

	def setCommYearEntry(self):
		"""Set the year of commercialization."""
		self.commYearCombo.get_model().clear()
		device_type = self.currentDevice.type
		for year in device_type.years:
			if year is not None:
				self.commYearCombo.append_text(str(year))
			else:
				self.commYearCombo.append_text(_("not specified"))

		try:
			year = int(self.currentDevice.getYear())
		except (ValueError, TypeError):
			year = None

		if year in device_type.years:
			index = device_type.years.index(year)
		else:
			index = 0

		self.commYearCombo.set_active(index)

	def setInterfaceEntry(self):
		"""Set the interface."""
		self.interfaceCombo.get_model().clear()
		device_type = self.currentDevice.type
		for interface in device_type.interfaces:
			self.interfaceCombo.append_text(interface)
		self.interfaceCombo.set_active(self.currentDevice.interface)

	def setDistributionEntry(self):
		"""Set the distribution entry."""
		self.distributionEntry.set_text(self.currentDevice.createDistroEntry())

	def setKernelEntry(self):
		"""Set the kernel libre entry."""
		self.kernelEntry.set_text(self.currentDevice.kernel)

	def setHowItWorksEntry(self):
		"""Set the howItWorks entry."""
		self.howItWorksCombo.get_model().clear()
		for option in self.currentDevice.type.how_it_works:
			self.howItWorksCombo.append_text(option)
		self.howItWorksCombo.set_active(self.currentDevice.how_it_works)

	def setDriverEntry(self):
		"""Set the driver entry."""
		self.driverEntry.set_text(self.currentDevice.getDriver())

	def setDescriptionEntry(self):
		"""Set the description entry."""
		textbuffer = gtk.TextBuffer(table=None)
		textbuffer.set_text(self.currentDevice.getDescription())
		self.descriptionText.set_buffer(textbuffer)

	def setNode(self, widget):
		"""Set the node."""
		self.client.logout()
		self.client.errors = []
		self.client.node = self.serverEntry.get_text()
		self.updateStatus()
		self.synchronize(None)
		self.prefWindow.destroy()

	def closePref(self, widget):
		"""Close the preferences window."""
		self.prefWindow.destroy()

	def submitAnonymously(self,widget):
		"""Submit anonymously to the server."""
		self._submitFlag = False
		self.loginWindow.destroy()
		
		if self.client.submit(self.currentDeviceCode):
			self.synchronize(None)
		else:
			self.printErrors()

	def login(self,widget):
		"""Login to the server."""
		self.client.login(self.usernameEntry.get_text(),self.passwordEntry.get_text())
		self.updateStatus()

		if self._submitFlag:
			if self.client.isLogged():
				self.applyChanges(None)
				if self.client.submit(self.currentDeviceCode):
					self.synchronize(None)
				else:
					self.printErrors()

		self._submitFlag = False
			
		#self.printErrors()
		self.loginWindow.destroy()

	def submit(self,widget):
		"""Submit data to the server."""
		self.applyChanges(None)
		self.licenseNoticeWindow.destroy()

		if self.client.isLogged():
			if self.client.submit(self.currentDeviceCode):
				self.synchronize(None)
			else:
				self.printErrors()
		else:
			self._submitFlag = True
			self.openLoginWindow(None)

	def logout(self,widget):
		"""Logout to the server."""
		self.client.logout()
		self.updateStatus()
		#self.printErrors()

	def closeLoginWindow(self,widget):
		"""Close the login window."""
		self._submitFlag = False
		self.updateStatus()
		self.loginWindow.destroy()

	def closeLicenseNoticeWindow(self,widget):
		"""Close the license notice window."""
		self.licenseNoticeWindow.destroy()

	def openInfoWindow(self,widget):
		"""Open the dialog with the software info."""
		about = gtk.AboutDialog()
		about.set_program_name("h-node client")
		about.set_version(pkg_resources.get_distribution("hclient").version)
		about.set_copyright("(c) Antonio Gallo")
		about.set_comments(_("simple client for h-node.org, licensed under the GPLv3"))
		about.set_website("http://h-node.org/")
		#about.set_logo(gtk.gdk.pixbuf_new_from_file("battery.png"))
		about.run()
		about.destroy()

	def closeDistroHelperWindow(self,widget):
		"""Close the window containing the list of allowed distributions."""
		self.distroHelperWindow.destroy()

	def setDistributions(self,widget):
		"""Update the distribution entry."""
		self.currentDevice.setDistributions(self._tempDistributions)
		self.distributionEntry.set_text(self.currentDevice.createDistroEntry())
		self.distroHelperWindow.destroy()

	def addTempDistribution(self,widget,data):
		"""Add a distrocode to the self._tempDistributions property."""
		if widget.get_active():
			self._tempDistributions.append(data)
		else:
			try:
				del self._tempDistributions[self._tempDistributions.index(data)]
			except:
				pass

	def openDistroHelperWindow(self,widget,data):
		"""Open the window containing the list of allowed distributions."""
		#used to temporarily save the list of distributions from the distribution entry or from the distribution checkButtons
		self._tempDistributions = []
		
		self.distroHelperWindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.distroHelperWindow.set_title(_("choose the distribution"))
		self.distroHelperWindow.set_position(gtk.WIN_POS_CENTER)
		self.distroHelperWindow.set_icon_from_file(get_img_path("icon.png"))
		self.distroHelperWindow.set_size_request(300, -1)
		self.distroHelperWindow.set_transient_for(self.window)
		self.distroHelperWindow.set_modal(True)

		self.vboxCh = gtk.VBox(False, 0)
		self.vboxCh.set_border_width(10)
		self.distroHelperWindow.add(self.vboxCh)

		# The list is too big to fit on 1024x600 screens.
		scrolledwindow = gtk.ScrolledWindow()
		scrolledwindow.set_size_request(-1, 300)
		scrolledwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
		inner_vbox = gtk.VBox(False, 0)

		scrolledwindow.add_with_viewport(inner_vbox)
		self.vboxCh.add(scrolledwindow)

		#fill the self._tempDistributions list with the distros already contained inside the distribution entry
		checkedDistros = self.distributionEntry.get_text().split(',')
		
		for distro in checkedDistros:
			distro = distro.strip()
			if self.client.distroIsAllowed(distro):
				self._tempDistributions.append(distro)

		#create and pack the checkButtons
		for distroCode,distroLabel in self.client.allowedDistros.iteritems():
			chbutton = gtk.CheckButton(distroLabel)
			if distroCode in self._tempDistributions:
				chbutton.set_active(True)
			chbutton.connect("clicked", self.addTempDistribution,distroCode)
			inner_vbox.pack_start(chbutton, True, True, 2)

		hbox = gtk.HBox(False, 0)
		hbox.set_border_width(10)
		applyButton = gtk.Button(stock=gtk.STOCK_APPLY)
		closeButton = gtk.Button(stock=gtk.STOCK_CANCEL)
		applyButton.connect("clicked", self.setDistributions)
		closeButton.connect("clicked", self.closeDistroHelperWindow)
		hbox.pack_end(applyButton, False, True, 0)
		hbox.pack_end(closeButton, False, True, 3)
		self.vboxCh.pack_start(hbox, False, True, 0)
		
		self.distroHelperWindow.show_all()

	def openHelpWindow(self, widget, data):
		"""Open the window with the entry help."""
		self.helpWindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.helpWindow.set_title(_("help window"))
		self.helpWindow.set_position(gtk.WIN_POS_CENTER)
		self.helpWindow.set_icon_from_file(get_img_path("icon.png"))
		self.helpWindow.set_size_request(300, -1)
		self.helpWindow.set_transient_for(self.window)
		self.helpWindow.set_modal(True)

		vbox = gtk.VBox(False, 0)
		vbox.set_border_width(10)
		self.helpWindow.add(vbox)

		sw = gtk.ScrolledWindow()
		sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)

		noticeText = gtk.TextView()
		noticeText.set_editable(False)
		noticeText.modify_base(gtk.STATE_NORMAL, self.helpWindow.get_style().bg[gtk.STATE_NORMAL] )

		noticeText.set_wrap_mode(gtk.WRAP_WORD_CHAR)

		textbuffer = gtk.TextBuffer(table=None)
		if isinstance(data, basestring):
			helpText = data
		elif self.currentDevice is not None:
			helpText = data(self.currentDevice.type)
		else:
			helpText = data(None)
		textbuffer.set_text(helpText)
		noticeText.set_buffer(textbuffer)

		sw.add(noticeText)

		vbox.pack_start(sw, False, True, 5)
		self.helpWindow.show_all()

	def openLicenseNoticeWindow(self,widget):
		"""Start the window containing the license notice."""
		result = self.client.getLicenseNotice();

		if result:
			self.licenseNoticeWindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
			self.licenseNoticeWindow.set_title(_("license notice"))
			self.licenseNoticeWindow.set_position(gtk.WIN_POS_CENTER)
			self.licenseNoticeWindow.set_icon_from_file(get_img_path("icon.png"))
			self.licenseNoticeWindow.set_size_request(300, -1)
			self.licenseNoticeWindow.set_transient_for(self.window)
			self.licenseNoticeWindow.set_modal(True)

			vbox = gtk.VBox(False, 0)
			vbox.set_border_width(10)
			self.licenseNoticeWindow.add(vbox)

			#description input
			sw = gtk.ScrolledWindow()
			#sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
			sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)

			noticeText = gtk.TextView()
			#noticeText.set_decorated(False)
			noticeText.set_editable(False)
			noticeText.modify_base(gtk.STATE_NORMAL, self.licenseNoticeWindow.get_style().bg[gtk.STATE_NORMAL] )

			noticeText.set_wrap_mode(gtk.WRAP_WORD_CHAR)

			textbuffer = gtk.TextBuffer(table=None)
			textbuffer.set_text(result)
			noticeText.set_buffer(textbuffer)

			sw.add(noticeText)
			#sw.show()
			#sw.show_all()

			vbox.pack_start(sw, False, True, 5)

			hbox = gtk.HBox(False, 0)
			hbox.set_border_width(10)
			applyButton = gtk.Button(stock=gtk.STOCK_APPLY)
			closeButton = gtk.Button(stock=gtk.STOCK_CANCEL)
			applyButton.connect("clicked", self.submit)
			closeButton.connect("clicked", self.closeLicenseNoticeWindow)
			hbox.pack_end(applyButton, False, True, 0)
			hbox.pack_end(closeButton, False, True, 3)
			vbox.pack_start(hbox, False, True, 0)

			self.licenseNoticeWindow.show_all()
		else:
			self.printErrors()

	def openLoginWindow(self,widget):
		"""Open the login window."""
		#window for preferences
		self.loginWindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.loginWindow.set_title(_("login"))
		self.loginWindow.set_position(gtk.WIN_POS_CENTER)
		self.loginWindow.set_icon_from_file(get_img_path("icon.png"))
		self.loginWindow.set_size_request(300, -1)
		self.loginWindow.set_transient_for(self.window)
		self.loginWindow.set_modal(True)

		self.loginWindow.connect("delete_event", self.delete_event_login)
		
		#self.prefWindow.set_size_request(300, -1)

		vbox = gtk.VBox(False, 0)

		self.loginWindow.add(vbox)

		ext_hbox = gtk.HBox(True, 0)

		vbox.pack_start(ext_hbox, False, True, 0)

		table = gtk.Table(4, 2, True)
		table.set_border_width(10)

		label = gtk.Label(_("<b>Login to the server</b>"))
		label.set_use_markup(True)

		vbox_inner = gtk.VBox(False, 0)
		vbox_inner_right = gtk.VBox(False, 0)
		
		ext_hbox.pack_start(vbox_inner, False, True, 0)

		vbox_inner.pack_start(label, False, True, 0)
		
		vbox_inner.pack_start(table, False, True, 0)
		
		### username
		usernameLabel = gtk.Label(_("username:"))
		usernameLabel.set_alignment(0.95,0.5)
		#add the label
		table.attach(usernameLabel, 0, 1, 0, 1)

		self.usernameEntry = gtk.Entry()
		#add the input to the table
		table.attach(self.usernameEntry, 1, 2, 0, 1)

		### password
		passwordLabel = gtk.Label(_("password:"))
		passwordLabel.set_alignment(0.95,0.5)
		#add the label
		table.attach(passwordLabel, 0, 1, 1, 2)

		self.passwordEntry = gtk.Entry()
		self.passwordEntry.set_visibility(False)

		#add the input to the table
		table.attach(self.passwordEntry, 1, 2, 1, 2)

		### create new account
		label = gtk.Label(_("<a href='http://%susers/add/en'>Create new account</a>") % self.client.node)
		label.set_use_markup(True)
		label.set_alignment(0.98,0.5)
		#add the label
		table.attach(label, 0, 2, 2, 3)

		### request new password
		label = gtk.Label(_("<a href='http://%susers/forgot/en'>Request new password</a>") % self.client.node)
		label.set_use_markup(True)
		label.set_alignment(0.98,0.5)
		#add the label
		table.attach(label, 0, 2, 3, 4)

		hbox = gtk.HBox(False, 0)
		hbox.set_border_width(10)
		applyButton = gtk.Button(stock=gtk.STOCK_APPLY)
		closeButton = gtk.Button(stock=gtk.STOCK_CANCEL)
		applyButton.connect("clicked", self.login)
		closeButton.connect("clicked", self.closeLoginWindow)
		hbox.pack_end(applyButton, False, True, 0)
		hbox.pack_end(closeButton, False, True, 3)
		vbox_inner.pack_start(hbox, False, True, 0)

		#right box - anonymous submission
		label = gtk.Label(_("<b>Anonymous submission</b>"))
		label.set_use_markup(True)

		vbox_inner_right.pack_start(label, False, True, 0)

		#description input
		sw = gtk.ScrolledWindow()
		#sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)

		noticeText = gtk.TextView()
		#noticeText.set_decorated(False)
		noticeText.set_editable(False)
		#noticeText.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(50,100,150) )
		noticeText.modify_base(gtk.STATE_NORMAL, self.loginWindow.get_style().bg[gtk.STATE_NORMAL] )

		noticeText.set_wrap_mode(gtk.WRAP_WORD_CHAR)

		textbuffer = gtk.TextBuffer(table=None)
		textbuffer.set_text(_("If you do not have an account and you don't want to register you can submit your device information anyway (anonymous submission) but your contribution won't be published until an administrator approves it."))
		noticeText.set_buffer(textbuffer)

		sw.set_size_request(-1, 110)
		
		sw.add(noticeText)

		vbox_inner_right.pack_start(sw, False, True, 10)

		hbox = gtk.HBox(False, 0)
		anonymousButton = gtk.Button(_("Submit anonymously"))
		anonymousButton.set_size_request(-1,33)
		anonymousButton.connect("clicked", self.submitAnonymously)
		hbox.pack_end(anonymousButton, False, True, 0)
		vbox_inner_right.pack_start(hbox, False, True, 0)
		
		#anonymous submission
		if self._submitFlag and self.isInserting():
			self.loginWindow.set_size_request(500, -1)
			ext_hbox.pack_start(vbox_inner_right, False, True, 10)
		
		self.loginWindow.show_all()

	def listHardware(self,widget):
		"""Create the local device objects."""
		self.client.createDevices()
		self.synchronize(None)

	def openPrefWindow(self,widget):
		"""Open the preferences window."""
		#window for preferences
		self.prefWindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.prefWindow.set_title(_("preferences"))
		self.prefWindow.set_position(gtk.WIN_POS_CENTER)
		self.prefWindow.set_icon_from_file(get_img_path("icon.png"))
		self.prefWindow.set_size_request(300, -1)
		self.prefWindow.set_transient_for(self.window)
		self.prefWindow.set_modal(True)

		vbox = gtk.VBox(False, 0)

		self.prefWindow.add(vbox)
		
		table = gtk.Table(1, 2, True)
		table.set_border_width(10)
		
		vbox.pack_start(table, False, True, 0)
		
		### server
		serverLabel = gtk.Label(_("Server URL:"))
		#add the label
		table.attach(serverLabel, 0, 1, 0, 1)

		self.serverEntry = gtk.Entry()
		self.serverEntry.set_text(self.client.node)
		#add the input to the table
		table.attach(self.serverEntry, 1, 2, 0, 1)

		hbox = gtk.HBox(False, 0)
		hbox.set_border_width(10)
		applyButton = gtk.Button(stock=gtk.STOCK_APPLY)
		closeButton = gtk.Button(stock=gtk.STOCK_CLOSE)
		applyButton.connect("clicked", self.setNode)
		closeButton.connect("clicked", self.closePref)
		hbox.pack_end(applyButton, False, True, 0)
		hbox.pack_end(closeButton, False, True, 3)
		vbox.pack_start(hbox, False, True, 0)
		#applyButton.connect("clicked", self.applyChanges)
		
		self.prefWindow.show_all()

	def synchronize(self,widget):
		"""Synchronize with the server database."""
		result = self.client.sync()
		self.printErrors()
		#print self.client.errors
		self.setEntries()
		self.setDeviceInfoLabel()
		self.setDeviceTree()

		if result:
			self.isConnectedBox.show()
			self.isNotConnectedBox.hide()
			self.setConnectIconTooltip()
		else:
			self.isNotConnectedBox.show()
			self.isConnectedBox.hide()


	def printErrors(self):
		#destroy the error bar HBox
		if hasattr(self, "errorBarHBox"):
			self.errorBarHBox.destroy()
			#drop the border
			errorBarViewPort = self.errorBar.get_child()
			errorBarViewPort.set_shadow_type(gtk.SHADOW_NONE)

		if len(self.client.errors) > 0:
			self.client.errors = list(set(self.client.errors))
			#self.errorBar.set_shadow_type(gtk.SHADOW_ETCHED_IN)
			
			self.errorBarHBox = gtk.HBox(False, 0)
			for error in self.client.errors:
				label = gtk.Label(error)
				self.errorBarHBox.pack_start(label, False, True, 10)
				
			self.errorBar.add_with_viewport(self.errorBarHBox)
			#add the border
			errorBarViewPort = self.errorBar.get_child()
			errorBarViewPort.set_shadow_type(gtk.SHADOW_IN)
			
			self.errorBar.show_all()
			
			self.client.errors = []

	def updateStatus(self):
		"""Hide or show the login/logout buttons."""
		if self.client.isLogged() == True:
			self.loginButton.hide()
			self.logoutButton.show()
			info = self.client.getUserInfo()
			if info != False:
				self.statusLabel.set_markup(_("<i>hello</i> <b>%s</b>, <i>you are logged in</i>") % info['username'])

			if self.currentDeviceCode != None:
				self.submitButton.set_sensitive(True)
			
		else:
			self.loginButton.show()
			self.logoutButton.hide()
			self.statusLabel.set_markup(_("<i>you are not logged in</i>"))

		self.printErrors()

	def delete_event_login(self, widget, event, data=None):
		"""Delete event of the login window."""
		self._submitFlag = False
		return False

	def setDeviceTree(self):
		"""Update the device tree."""
		#get the current selection
		ts, itera = self.tree.get_selection().get_selected()
		if itera:
			path = ts.get_path(itera)
			
		self.treestore = gtk.TreeStore(str,str,int,gtk.gdk.Pixbuf,int)

		pci = self.treestore.append(None, [_("Your PCI Devices"),"",800,gtk.gdk.pixbuf_new_from_file(get_img_path('title_png.png')),4])
		usb = self.treestore.append(None, [_("Your USB Devices"),"",800,gtk.gdk.pixbuf_new_from_file(get_img_path('title_png.png')),4])
		for key,dev in self.client.devices.iteritems():

			if key[0] == 'p':
				self.treestore.append(pci, [dev[0].type.type_name,key,400,gtk.gdk.pixbuf_new_from_file(get_img_path('devices/small/'+dev[0].type.icon)),4])

			if key[0] == 'u':
				self.treestore.append(usb, [dev[0].type.type_name,key,400,gtk.gdk.pixbuf_new_from_file(get_img_path('devices/small/'+dev[0].type.icon)),4])

		self.tree.set_model(self.treestore)

		#selection = self.tree.get_selection()
		#selection.connect('changed', self.setCurrentDevice)

		self.tree.expand_all()

		#select the device on the tree
		if itera:
			self.tree.get_selection().select_path(path)
		else:
			#select the first device
			self.tree.get_selection().select_path(0)
			ts, itera = self.tree.get_selection().get_selected()
			if itera:
				next = ts.iter_nth_child(itera, 0)
				path = ts.get_path(next)
				self.tree.get_selection().select_path(path)

	def setConnectIconTooltip(self):
		"""Set the tooltip of the connect icon."""
		self.imageConnect.set_tooltip_text(_('You are connected to the server %s') % self.client.node[:-1])

	def delete_event(self, widget, event, data=None):
		self.client.logout()
		gtk.main_quit()
		return False

	def getHelpButton(self, data):
		"""Return an entry help button."""
		img = gtk.Image()
		img.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_SMALL_TOOLBAR)
		img.set_tooltip_text(_('More info'))
		helpButton = gtk.Button()
		helpButton.set_image(img)
		helpButton.props.relief = gtk.RELIEF_NONE
		helpButton.set_size_request(1, -1)
		helpButton.connect("clicked", self.openHelpWindow, data)
		return helpButton

	def __init__(self):

		#does it have to submit after the login?
		self._submitFlag = False

		#start the client object
		self.client = Client('https://h-node.org')
		self.client.createDevices()
		
		# Create the main window
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

		self.window.set_title("h-client")

		self.window.set_icon_from_file(get_img_path("icon.png"))
		self.window.set_size_request(700, -1)
		self.window.set_position(gtk.WIN_POS_CENTER)
		
		self.window.connect("delete_event", self.delete_event)

		#self.window.set_border_width(0)

		vbox = gtk.VBox(False, 0)

		#add the bottom box
		self.window.add(vbox)
		
		self.centerWindow = gtk.HBox(False, 0)
		self.bottomWindow = gtk.HBox(False, 0)

		self.infoConnection = gtk.HBox(False, 0) #info about the connection to the server (if it is connected and the name of the server)
		#self.infoConnection.set_size_request(-1,50)

		self.isConnectedBox = gtk.VBox(False, 0)
		self.isNotConnectedBox = gtk.VBox(False, 0)

		self.infoConnection.pack_start(self.isConnectedBox, True, True, 0)
		self.infoConnection.pack_start(self.isNotConnectedBox, True, True, 0)

		#connected icon
		self.imageConnect = gtk.Image()
		self.imageConnect.set_tooltip_text(_('You are connected to the server %s') % self.client.node[:-1])
		self.imageConnect.set_from_stock(gtk.STOCK_CONNECT,gtk.ICON_SIZE_LARGE_TOOLBAR)
		self.isConnectedBox.pack_start(self.imageConnect, True, True, 0)

		#not connected icon
		imageDisconnect = gtk.Image()
		imageDisconnect.set_tooltip_text(_('You are not connected to the server'))
		imageDisconnect.set_from_stock(gtk.STOCK_DISCONNECT,gtk.ICON_SIZE_LARGE_TOOLBAR)
		self.isNotConnectedBox.pack_start(imageDisconnect, True, True, 0)
		
		self.errorBar = gtk.ScrolledWindow()
		self.errorBar.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
		#self.errorBar.set_border_width(5)
		self.errorBar.set_size_request(630,40)
		self.bottomWindow.pack_start(self.infoConnection, True, True, 0)
		self.bottomWindow.pack_start(self.errorBar, True, True, 5)

		self.errorBar.show_all()
		
		## build the toolbar ##
		toolbar = gtk.Toolbar()
		toolbar.set_tooltips(True)
		#toolbar.set_style(gtk.TOOLBAR_BOTH)

		pref = gtk.ToolButton(gtk.STOCK_PREFERENCES)
		pref.set_tooltip_text(_('Preferences'))
		pref.connect("clicked", self.openPrefWindow)
		sync = gtk.ToolButton(gtk.STOCK_REFRESH)
		sync.set_tooltip_text(_('Synchronize with the server: this will override the entries of your devices'))
		sync.connect("clicked", self.synchronize)
		info = gtk.ToolButton(gtk.STOCK_INFO)
		info.set_tooltip_text(_('Information'))
		info.connect("clicked",self.openInfoWindow);

		toolbar.insert(sync, 0)
		toolbar.insert(pref, 1)
		toolbar.insert(info, 2)
		toolbar.show_all()

		#create the menu
		file_menu = gtk.Menu()
		list_hardware = gtk.MenuItem(_("Scan computer and list hardware"))
		list_hardware.connect("activate", self.listHardware)

		file_menu.append(list_hardware)

		menu_bar = gtk.MenuBar()

		file_item = gtk.MenuItem(_("File"))
		file_item.set_submenu(file_menu)
		menu_bar.append(file_item)
		menu_bar.show_all()

		vbox.pack_start(menu_bar, True, True, 0)
		vbox.pack_start(toolbar, True, True, 0)
		

		vbox.pack_start(self.centerWindow, True, True, 0)
		vbox.pack_start(self.bottomWindow, True, True, 0)
		vbox.show()

		
		## build the left window ##
		
		#start the left vertical box
		self.leftWindow = gtk.VBox(False, 0)
		#self.leftWindow.set_border_width(5)

		self.centerWindow.pack_start(self.leftWindow, True, True, 0)

		#treeFrame.add(self.leftWindow)
		#self.centerWindow.pack_start(self.rframe, True, True, 5)

		#self.leftWindow.pack_start(gtk.Label("Your hardware:"), False, True, 5)

		self.tree = gtk.TreeView()
		self.tree.set_headers_visible(False)

		self.devices = gtk.TreeViewColumn(_("Your PCI and USB devices"))

		device_icon = gtk.CellRendererPixbuf()
		self.devices.pack_start(device_icon, True)
		self.devices.add_attribute(device_icon, 'pixbuf', 3)
		#self.devices.set_cell_data_func(device_icon, self.setTreeViewCell)


		device_name = gtk.CellRendererText()
		self.devices.pack_start(device_name, True)
		self.devices.add_attribute(device_name, "text", 0)
		self.devices.add_attribute(device_name, "xpad", 4)
		self.devices.add_attribute(device_name, "weight", 2)
		
		
		self.tree.append_column(self.devices)
		

		treesw = gtk.ScrolledWindow()
		treesw.set_size_request(110,401)
		treesw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		treesw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		treesw.add(self.tree)

		self.leftWindow.set_border_width(5)
		self.leftWindow.pack_start(treesw, False, True, 0)

		self.leftWindow.show_all()
		
		#treeFrame.add(self.leftWindow)

		## build the right window ##

		#right top
		rthbox = gtk.HBox(False, 0)
		rthbox.set_border_width(5)
		#login button
		self.loginButton = gtk.Button(_("Login"))
		self.loginButton.set_sensitive(True)
		self.loginButton.connect("clicked", self.openLoginWindow)
		rthbox.pack_start(self.loginButton, False, True, 0)

		#login button
		self.logoutButton = gtk.Button(_("Logout"))
		self.logoutButton.set_sensitive(True)
		self.logoutButton.connect("clicked", self.logout)
		rthbox.pack_start(self.logoutButton, False, True, 0)

		#status label
		self.statusLabel = gtk.Label("")
		self.statusLabel.set_use_markup(True)
		rthbox.pack_end(self.statusLabel, False, True, 0)

		#top image
		self.tihbox = gtk.HBox(False, 0)
		self.bigIcon = gtk.Image()
		self.bigIcon.set_from_file(get_img_path("devices/big/unknown.png"))
		self.tihbox.pack_end(self.bigIcon, False, True, 0)
		
		self.deviceInfoLabel = gtk.Label("")
		self.deviceInfoLabel.set_use_markup(True)
		self.tihbox.pack_start(self.deviceInfoLabel, False, True, 3)

		#create the entries

		notebook = gtk.Notebook()
		notebook.set_tab_pos(gtk.POS_TOP)
		notebook.show()
		label_base = gtk.Label(_("Base"))
		label_adv = gtk.Label(_("Advanced"))

		self.rightTable = gtk.Table(6, 3, False)
		self.rightTableAdvances = gtk.Table(6, 3, False)

		self.rightTable.set_border_width(5)
		self.rightTableAdvances.set_border_width(5)

		self.rightTable.set_row_spacings(3)
		self.rightTableAdvances.set_row_spacings(3)
		
		notebook.append_page(self.rightTable, label_base)
		notebook.append_page(self.rightTableAdvances, label_adv)

		###type entry
		#year of commercialization label
		self.typeLabel = gtk.Label(_("Select the device category (if not correct):"))
		self.typeLabel.set_alignment(0.75,0.5)
		#add the label
		self.rightTable.attach(self.typeLabel, 0, 1, 0, 1)

		self.typeCombo = gtk.combo_box_new_text()

		for dtype in devices.get_types():
			self.typeCombo.append_text(dtype)
		
		#add the combo to the table
		self.rightTable.attach(self.typeCombo, 1, 2, 0, 1)
		self.typeCombo.connect("changed", self.changeType)

		##create the help icon widget
		self.rightTable.attach(self.getHelpButton(_("Choose the type of the device if it is wrong. You can change the type only if the device has not been inserted in the database yet.")), 2, 3, 0, 1)
		
		### model
		#model name label
		self.modelNameLabel = gtk.Label(_("Model name:"))
		self.modelNameLabel.set_alignment(0.94,0.5)
		#add the label
		self.rightTable.attach(self.modelNameLabel, 0, 1, 1, 2)

		#model name input
		self.modelNameEntry = gtk.Entry()
		#add the input to the table
		self.rightTable.attach(self.modelNameEntry, 1, 2, 1, 2)

		##create the help icon widget
		self.rightTable.attach(self.getHelpButton(_("This is the model name obtained by the lspci command (for PCI devices) or lsusb command (for USB devices)")), 2, 3, 1, 2)

		### other names
		#other names label
		self.otherNamesLabel = gtk.Label(_("Possible other names of the device:\n(<i>write one name per row</i>)"))
		self.otherNamesLabel.set_use_markup(True)
		self.otherNamesLabel.set_alignment(0.83,0.5)
		self.otherNamesLabel.set_justify(gtk.JUSTIFY_RIGHT)
		self.rightTable.attach(self.otherNamesLabel, 0, 1, 2, 3)

		#other names text area
		s = gtk.ScrolledWindow()
		s.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		s.set_size_request(-1,50)
		s.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

		self.otherNamesText = gtk.TextView()
		#self.otherNamesText.set_size_request(-1,60)
		self.otherNamesText.set_wrap_mode(gtk.WRAP_WORD_CHAR)
		self.otherNamesText.set_left_margin(5)
		self.otherNamesText.set_right_margin(5)

		s.add(self.otherNamesText)
		s.show()
		s.show_all()
		self.rightTable.attach(s, 1, 2, 2, 3)

		##create the help icon widget
		self.rightTable.attach(self.getHelpButton(_("This is the subsystem name. It is automatically retrieved by means of the lspci command.")), 2, 3, 2, 3)
		
		### vendorid:productid
		#vendorid:productid label
		self.vendorIdProductIdLabel = gtk.Label(_("VendorID:productID code:"))
		self.vendorIdProductIdLabel.set_size_request(230, -1)
		self.vendorIdProductIdLabel.set_alignment(0.88,0.5)
		#add the label
		self.rightTableAdvances.attach(self.vendorIdProductIdLabel, 0, 1, 0, 1)

		#vendorid:productid input
		self.vendorIdProductIdEntry = gtk.Entry()
		#set as not editable
		self.vendorIdProductIdEntry.set_editable(False)
		#add the input to the table
		self.rightTableAdvances.attach(self.vendorIdProductIdEntry, 1, 2, 0, 1)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("the vendorid:productid code is used to identify the chipset of your device")), 2, 3, 0, 1)
		
		###subtype
		#subtype label
		self.subtypeLabel = gtk.Label(_("Subtype:"))
		self.subtypeLabel.set_alignment(0.94,0.5)
		#add the label
		self.rightTableAdvances.attach(self.subtypeLabel, 0, 1, 1, 2)

		#subtype input
		self.subtypeCombo = gtk.combo_box_new_text()
		#add the input to the table
		self.rightTableAdvances.attach(self.subtypeCombo, 1, 2, 1, 2)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("the type of printing process")), 2, 3, 1, 2)
		
		###year of commercialization
		#year of commercialization label
		self.commYearLabel = gtk.Label(_("Year of commercialization:"))
		self.commYearLabel.set_alignment(0.87,0.5)
		#add the label
		self.rightTableAdvances.attach(self.commYearLabel, 0, 1, 2, 3)

		self.commYearCombo = gtk.combo_box_new_text()

		#add the combo to the table
		self.rightTableAdvances.attach(self.commYearCombo, 1, 2, 2, 3)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("choose the year of commercialization of your device")), 2, 3, 2, 3)
		
		###interface
		#interface label
		self.interfaceLabel = gtk.Label(_("Interface:"))
		self.interfaceLabel.set_alignment(0.94,0.5)
		#add the label
		self.rightTableAdvances.attach(self.interfaceLabel, 0, 1, 3, 4)

		self.interfaceCombo = gtk.combo_box_new_text()

		self.interfaceCombo.append_text('not-specified')

		self.interfaceCombo.set_active(0)

		#add the combo to the table
		self.rightTableAdvances.attach(self.interfaceCombo, 1, 2, 3, 4)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("choose the interface used by your device")), 2, 3, 3, 4)
		
		### distribution
		#distribution label
		self.distributionLabel = gtk.Label(_("Distribution used: "))
		self.distributionLabel.set_alignment(0.95,0.5)
		#add the label
		self.rightTable.attach(self.distributionLabel, 0, 1, 3, 4)

		#distribution input
		self.distributionEntry = gtk.Entry()
		self.distributionEntry.connect("button-press-event", self.openDistroHelperWindow)
		
		
		#add the input
		self.rightTable.attach(self.distributionEntry, 1, 2, 3, 4)

		##create the help icon widget
		self.rightTable.attach(self.getHelpButton(_("Choose the GNU/Linux distribution used for the test. Only distributions that are considered fully free can be used to test the hardware that will be submitted to h-node.")), 2, 3, 3, 4)

		### kernel
		#kernel label
		self.kernelLabel = gtk.Label(_("Kernel libre version:"))
		self.kernelLabel.set_alignment(0.92,0.5)
		#add the label
		self.rightTableAdvances.attach(self.kernelLabel, 0, 1, 4, 5)

		#kernel input
		self.kernelEntry = gtk.Entry()
		#add the input
		self.rightTableAdvances.attach(self.kernelEntry, 1, 2, 4, 5)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("the kernel libre used for the test")), 2, 3, 4, 5)
		
		###how it works
		#how it works label
		self.howItWorksLabel = gtk.Label(_("Does it work?"))
		self.howItWorksLabel.set_alignment(0.95,0.5)
		#add the label
		self.rightTable.attach(self.howItWorksLabel, 0, 1, 4, 5)

		self.howItWorksCombo = gtk.combo_box_new_text()

		#add the combo to the table
		self.rightTable.attach(self.howItWorksCombo, 1, 2, 4, 5)

		##create the help icon widget
		def does_it_work_help(device_type):
			if device_type is devicetypes.VideoCard:
				return _("How does it work with free software? You can also specify if the 3D acceleration works or not with the free driver.")
			elif device_type is devicetypes.Printer:
				return _("Choose the compatibility level with free software.\n\n There are three levels:\n - Class A (Full): all device functions and features are supported\n - Class B (Partial): printing supported but possibly at limited speed or print quality; scanning and/or faxing on some multifunction devices may not be supported\n - Class C (None): the printer does not work with free software")
			elif device_type is devicetypes.Scanner:
				return _("Choose the compatibility level with free software.\n\n There are three levels:\n - Class A (Full): all device functions and features are supported\n - Class B (Partial): scanning supported but possibly at limited speed or quality; some other features may not be supported\n - Class C (None): the scanner does not work with free software")
			else:
				return _("Does it work with free software?")
		self.rightTable.attach(self.getHelpButton(does_it_work_help), 2, 3, 4, 5)
		###it tracks users
		#how it works label
		self.howItTracksUsersLabel = gtk.Label(_("Does it adopt any technique to track users?"))
		self.howItTracksUsersLabel.set_alignment(0.70,0.5)
		#add the label
		self.rightTable.attach(self.howItTracksUsersLabel, 0, 1, 5, 6)

		self.itTracksUsersCombo = gtk.combo_box_new_text()

		#add the combo to the table
		self.rightTable.attach(self.itTracksUsersCombo, 1, 2, 5, 6)

		##create the help icon widget
		self.rightTable.attach(self.getHelpButton(_("Some color laser printer models print yellow tracking dots on their output.\n\nThis is a list in progress (maintained by EFF - https://www.eff.org/) of printer models that do or do not print yellow tracking dots on their output:\nhttps://www.eff.org/pages/list-printers-which-do-or-do-not-display-tracking-dots\n\nIn most cases, we are confident that the arrangement of dots is intentional and is intended to track users.\n\nPlease choose not-specified if your printer is not in the list or if you have verified that your printer does not print yellow dots")), 2, 3, 5, 6)
		
		### driver
		#driver label
		self.driverLabel = gtk.Label(_("Free driver used:"))
		self.driverLabel.set_alignment(0.94,0.5)
		#add the label
		self.rightTableAdvances.attach(self.driverLabel, 0, 1, 5, 6)

		#driver input
		self.driverEntry = gtk.Entry()
		#add the input
		self.rightTableAdvances.attach(self.driverEntry, 1, 2, 5, 6)

		##create the help icon widget
		self.rightTableAdvances.attach(self.getHelpButton(_("the free driver used")), 2, 3, 5, 6)
		
		### description
		#description label
		self.descriptionLabel = gtk.Label(_("Description:"))
		self.descriptionLabel.set_alignment(0,0.5)

		#description input
		sw = gtk.ScrolledWindow()
		sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
		sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		
		self.descriptionText = gtk.TextView()
		self.descriptionText.set_wrap_mode(gtk.WRAP_WORD_CHAR)
		self.descriptionText.set_left_margin(5)
		self.descriptionText.set_right_margin(5)

		sw.add(self.descriptionText)
		sw.show()
		sw.show_all()
		
		##add the input
		#self.rightTable.attach(sw, 1, 2, 7, 8)

		self.rightTable.show_all()

		#apply and submit buttons
		hboxBelowEntries = gtk.HBox(False, 0)
		#apply button
		self.applyButton = gtk.Button(stock=gtk.STOCK_APPLY)
		self.applyButton.set_sensitive(False)
		self.applyButton.connect("clicked", self.applyChanges)
		self.applyButton.set_tooltip_text(_('apply your local modifications: no change will be applied to the server'))
		#reset button
		self.resetButton = gtk.Button(stock=gtk.STOCK_REVERT_TO_SAVED)
		self.resetButton.set_sensitive(False)
		self.resetButton.connect("clicked", self.resetChanges)
		self.resetButton.set_tooltip_text(_('restore the entries'))
		#submit button
		self.submitButton = gtk.Button(_("Submit"))
		self.submitButton.set_sensitive(False)
		self.submitButton.connect("clicked", self.openLicenseNoticeWindow)
		self.submitButton.set_tooltip_text(_('submit your modifications to the server'))

		#create the device tree
		self.setDeviceTree()

		selection = self.tree.get_selection()
		selection.connect('changed', self.setCurrentDevice)
		
		hboxBelowEntries.pack_end(self.applyButton, False, True, 0)
		hboxBelowEntries.pack_end(self.resetButton, False, True, 0)
		hboxBelowEntries.pack_start(self.submitButton, False, True, 0)
		hboxBelowEntries.show_all()

		#lFrame = gtk.Frame()
		#lFrame.add(rhbox)
		#lFrame.set_border_width(5)
		
		#start the left vertical box
		self.rightWindow = gtk.VBox(False, 0)

		self.rightWindow.pack_start(self.tihbox, True, True, 3)
		self.rightWindow.pack_start(notebook, False, True, 3)
		self.rightWindow.pack_start(self.descriptionLabel, False, True, 3)
		self.rightWindow.pack_start(sw, False, True, 0)
		self.rightWindow.pack_start(hboxBelowEntries, False, True, 10)
		#self.rightWindow.show_all()

		rhbox = gtk.HBox(False, 0)
		rhbox.pack_start(self.rightWindow, True, True, 5)


		rvbox = gtk.VBox(False, 0)
		
		rvbox.pack_start(rthbox, True, True, 0)
		rvbox.pack_start(rhbox, True, True, 0)

		self.centerWindow.pack_start(rvbox, True, True, 0)
		
		#self.rframe.add(self.rightWindow)
		#self.rframe.set_border_width(30)
		
		self.centerWindow.show_all()
		self.bottomWindow.show_all()
		self.isConnectedBox.hide()
		self.leftWindow.show()
		self.window.show()

		self.synchronize(None)
		self.updateStatus()

		#self.logoutButton.hide()

		# Tell the user if the distro is not supported.
		user_distribution = machine.user_distribution()
		if not user_distribution:
			dialog = gtk.MessageDialog(parent=self.window,
									   flags=gtk.DIALOG_MODAL,
									   type=gtk.MESSAGE_WARNING,
									   buttons=gtk.BUTTONS_OK,
									   message_format=_("The distribution that you are using could not be detected.  You should manually add it to the list of tested distributions when adding devices.  If this distribution is accepted by the server you use, please report this at https://savannah.nongnu.org/bugs/?group=h-client."))
			dialog.run()
			dialog.destroy()
		elif not self.client.distroIsAllowed(user_distribution):
			dialog = gtk.MessageDialog(parent=self.window,
									   flags=gtk.DIALOG_MODAL,
									   type=gtk.MESSAGE_WARNING,
									   buttons=gtk.BUTTONS_OK,
									   message_format=_("The distribution that you are using, %s, is not accepted by the server.  If this is incorrect, please report this at https://savannah.nongnu.org/bugs/?group=h-client.") % user_distribution)
			dialog.run()
			dialog.destroy()


def main():
	Client = hclient()
	# Avoid pyflakes unused variable warning, since hclient
	# constructor has side effects.
	assert Client is not None
	gtk.main()


if __name__ == "__main__":
	main()

# Local Variables:
# indent-tabs-mode: t
# python-guess-indent: nil
# python-indent: 4
# tab-width: 4
# End:
