from twisted.internet import reactor import pygtk import gtk from pyscrabble.net.client import ScrabbleClient from pyscrabble.gui.main import MainWindow from pyscrabble.gtkconstants import * from pyscrabble.constants import * from pyscrabble.gui.register import * from pyscrabble.gui import options from pyscrabble import manager from pyscrabble import util from pyscrabble import gtkutil class LoginWindow(gtk.Window): ''' The LoginWindow class presents a Window for the user to log in to the server ''' def clickLogin(self, widget, data=None): ''' Callback when the user clicks the login button. @param widget: Button that was clicked @param data: ''' username = self.username.get_text() password = util.hashPassword( self.password.get_text() ) if (self.hostname.get_child().get_text().find(':') == -1): self.error(util.ErrorMessage(_("Hostname value must be hostname:port."))) return (host, port) = self.hostname.get_child().get_text().split(':') try: port = int(port) except ValueError: self.error(util.ErrorMessage(_("Port must be a number."))) return self.client = ScrabbleClient(host, port, self) self.client.login( username, password, VERSION ) widget.set_sensitive(False) def loginOK(self): ''' Callback from server if the user is authenticated. Start the MainWindow ''' h = self.hostname.get_child().get_text() if h not in self.history: self.history.append(h) r = manager.ResourceManager() history_file = file(r["config"][SERVER_HISTORY], 'w+') for host in self.history: history_file.write('%s\n' % host) history_file.close() o = manager.OptionManager() if o.get_default_bool_option(OPTION_SAVE_LOGIN, True): o.set_option(OPTION_SAVE_UNAME, self.username.get_text()) o.set_option(OPTION_SAVE_PWORD, self.password.get_text()) o.set_option(OPTION_SAVE_HOST, h) MainWindow(self.client, self.username.get_text()) self.destroy() def error(self, data): ''' Callback from the server when an error happens @param data: ErrorMessage data ''' s = _("Error") self.dialog = gtk.MessageDialog(parent=self, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format="") self.dialog.set_markup("%s: %s" % (s, data.getErrorMessage())) self.dialog.connect("response", lambda w,e: self.dialog.destroy()) self.dialog.show() self.loginButton.set_sensitive(True) def getLabels(self): ''' Get screen labels @return: gtk.VBox ''' left = gtk.VBox( False, 10 ) # Add Username label s = _("Username") username_t = gtk.Label("%s: " %s) username_t.set_justify( gtk.JUSTIFY_LEFT ) # Add Password label s = _("Password") password_t = gtk.Label("%s: " % s) password_t.set_justify( gtk.JUSTIFY_LEFT ) # Add Host label s = _("Hostname") hostname_t = gtk.Label("%s: " % s) hostname_t.set_justify( gtk.JUSTIFY_LEFT ) left.pack_start(username_t, False, False, 5) left.pack_start(password_t, False, False, 3) left.pack_start(hostname_t, False, False, 0) return left def getEntries(self): ''' Get entries @return: gtk.VBox containg gtk.Entry's ''' right = gtk.VBox( False, 10 ) self.username = gtk.Entry() self.password = gtk.Entry() self.password.set_visibility( False ) #self.hostname = gtk.Entry() self.hostname = gtk.combo_box_entry_new_text() self.username.connect("key-press-event", self.entryKeyPress_cb) self.password.connect("key-press-event", self.entryKeyPress_cb) self.hostname.get_child().connect("key-press-event", self.entryKeyPress_cb) right.pack_start(self.username, False, False, 0) right.pack_start(self.password, False, False, 0) right.pack_start(self.hostname, False, False, 0) return right def getHeaderLabel(self): ''' Get the header label @return: gtk.Label ''' s = _("Welcome to PyScrabble") header = gtk.Label () header.set_justify( gtk.JUSTIFY_LEFT ) header.set_markup("""%s""" % s) return header def getButtons(self): ''' Get the Buttons @return: ButtonBox ''' box = gtk.VButtonBox() box.set_border_width(5) box.set_spacing(0) button = gtk.Button(label=_("Login")) button.set_image( gtk.image_new_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)) button.connect("clicked", self.clickLogin) button.set_relief( gtk.RELIEF_NONE ) box.add(button) self.loginButton = button button = gtk.Button(label=_("Find Public Servers")) button.set_image( gtk.image_new_from_stock(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) ) button.connect("clicked", self.findServer_cb) button.set_relief( gtk.RELIEF_NONE ) box.add(button) return box def delete_event(self, widget=None, event=None, data=None): ''' Delete event callback @param widget: @param event: @param data: ''' self.stopReactor() def stopReactor(self): ''' Stop the reactor ''' reactor.stop() def __init__(self): ''' Constructor. Show the LoginWindow. ''' gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL ) self.connect("delete_event", self.delete_event ) self.set_title( "PyScrabble" ) self.set_default_size( 300, 200 ) self.optionWindowShown = False left_right = gtk.HBox( False, 20 ) main = gtk.VBox( False, 20) left_right.pack_start( self.getLabels(), False, False, 0 ) left_right.pack_start( self.getEntries(), False, False, 0 ) left_right.set_border_width( 10 ) main.pack_start( self.createMenuBar(), False, False, 0) main.pack_start( self.getHeaderLabel(), False, False, 0 ) main.pack_start( left_right, False, False, 0 ) main.pack_start( self.getButtons(), False, False, 0 ) r = manager.ResourceManager() history_file = file(r["config"][SERVER_HISTORY], "ab+") self.history = [] for server in reversed(history_file.read().split()): self.hostname.append_text(server) self.history.append(server) history_file.close() self.restoreCredentials() #self.set_border_width( 10 ) self.add( main ) self.show_all() self.loggingOut = False self.client = None def createMenuBar(self): ''' Create the main menu bar @return gtk.MenuBar ''' ui = gtk.UIManager() self.add_accel_group( ui.get_accel_group() ) ui.add_ui_from_string(LOGIN_MENU_DATA) group = gtk.ActionGroup('MainMenuBarGroup') group.add_actions([('Exit', gtk.STOCK_QUIT, _('_Exit'), None, None, self.delete_event), ('Preferences', gtk.STOCK_PREFERENCES, _('_Preferences'), 'P', None, self.showOptions), ('Online Help', gtk.STOCK_HELP, _('_Online Help'), None, None, util.showHelp), ('About', gtk.STOCK_ABOUT, _('_About'), None, None, gtkutil.showAbout), ('Help', None, _('_Help')), ('Options', None, _('_Tools')), ('File', None, _('_File'))]) ui.insert_action_group(group, 0) return ui.get_widget('/MainMenuBar') def fatalError(self, msg): ''' Call the fatal error handler @param msg: ErrorMessage ''' if not self.loggingOut: gtkutil.fatalError(msg) def findServer_cb(self, widget): ''' Show the find server window @param widget: Widget that activated this callback ''' x = RegisterWindow(self) def restoreCredentials(self): ''' If the user has a preference to save their username/password/host, restore it here ''' o = manager.OptionManager() if o.get_default_bool_option(OPTION_SAVE_LOGIN, True): uname = o.get_default_option(OPTION_SAVE_UNAME, '') pword = o.get_default_option(OPTION_SAVE_PWORD, '') host = o.get_default_option(OPTION_SAVE_HOST, '') self.populateFields_cb(uname,pword,host) def populateFields_cb(self, username, password, host): ''' Populate the login fields @param username: Username @param password: Password @param host: Hostname ''' if username is not None: self.username.set_text( username ) if password is not None: self.password.set_text( password ) if host not in self.history and host is not '': self.hostname.append_text(host) model = self.hostname.get_model() iter = model.get_iter_first() while iter: val = model.get_value(iter, 0) if val == host: self.hostname.set_active_iter(iter) iter = model.iter_next(iter) def showOptions(self, widget): if not self.optionWindowShown: self.optionWindowShown = True x = options.OptionWindow(self) def optionWindowClosed(self): self.optionWindowShown = False def entryKeyPress_cb(self, widget, event): ''' Key press event on one of the entries If its a return, send the login command @param widget: @param event: ''' if event.keyval == gtk.keysyms.Return: self.clickLogin(self.loginButton, None)