root / trunk / twisted / spread / ui / gtk2util.py

Revision 11450, 6.9 kB (checked in by radix, 5 years ago)

MIT LICENSE: new LICENSE file and new preambles for all .py files. This is not all.

Line 
1
2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 from __future__ import nested_scopes
7
8 import gtk
9
10 from twisted import copyright
11 from twisted.internet import defer
12 from twisted.python import failure, log, util
13 from twisted.spread import pb
14 from twisted.cred.credentials import UsernamePassword
15
16 from twisted.internet import error as netError
17
18 def login(client=None, **defaults):
19     """
20     @param host:
21     @param port:
22     @param identityName:
23     @param password:
24     @param serviceName:
25     @param perspectiveName:
26
27     @returntype: Deferred RemoteReference of Perspective
28     """
29     d = defer.Deferred()
30     LoginDialog(client, d, defaults)
31     return d
32
33 class GladeKeeper:
34     """
35     @cvar gladefile: The file in which the glade GUI definition is kept.
36     @type gladefile: str
37
38     @cvar _widgets: Widgets that should be attached to me as attributes.
39     @type _widgets: list of strings
40     """
41
42     gladefile = None
43     _widgets = ()
44
45     def __init__(self):
46         from gtk import glade
47         self.glade = glade.XML(self.gladefile)
48
49         # mold can go away when we get a newer pygtk (post 1.99.14)
50         mold = {}
51         for k in dir(self):
52             mold[k] = getattr(self, k)
53         self.glade.signal_autoconnect(mold)
54         self._setWidgets()
55
56     def _setWidgets(self):
57         get_widget = self.glade.get_widget
58         for widgetName in self._widgets:
59             setattr(self, "_" + widgetName, get_widget(widgetName))
60
61
62 class LoginDialog(GladeKeeper):
63     # IdentityConnector host port identityName password
64     # requestLogin -> identityWrapper or login failure
65     # requestService serviceName perspectiveName client
66
67     # window killed
68     # cancel button pressed
69     # login button activated
70
71     fields = ['host','port','identityName','password',
72               'perspectiveName']
73
74     _widgets = ("hostEntry", "portEntry", "identityNameEntry", "passwordEntry",
75                 "perspectiveNameEntry", "statusBar",
76                 "loginDialog")
77
78     _advancedControls = ['perspectiveLabel', 'perspectiveNameEntry',
79                          'protocolLabel', 'versionLabel']
80
81     gladefile = util.sibpath(__file__, "login2.glade")
82
83     def __init__(self, client, deferred, defaults):
84         self.client = client
85         self.deferredResult = deferred
86
87         GladeKeeper.__init__(self)
88
89         self.setDefaults(defaults)
90         self._loginDialog.show()
91
92
93     def setDefaults(self, defaults):
94         if not defaults.has_key('port'):
95             defaults['port'] = str(pb.portno)
96         elif isinstance(defaults['port'], (int, long)):
97             defaults['port'] = str(defaults['port'])
98
99         for k, v in defaults.iteritems():
100             if k in self.fields:
101                 widget = getattr(self, "_%sEntry" % (k,))
102                 widget.set_text(v)
103
104     def _setWidgets(self):
105         GladeKeeper._setWidgets(self)
106         self._statusContext = self._statusBar.get_context_id("Login dialog.")
107         get_widget = self.glade.get_widget
108         get_widget("versionLabel").set_text(copyright.longversion)
109         get_widget("protocolLabel").set_text("Protocol PB-%s" %
110                                              (pb.Broker.version,))
111
112     def _on_loginDialog_response(self, widget, response):
113         handlers = {gtk.RESPONSE_NONE: self._windowClosed,
114                    gtk.RESPONSE_DELETE_EVENT: self._windowClosed,
115                    gtk.RESPONSE_OK: self._doLogin,
116                    gtk.RESPONSE_CANCEL: self._cancelled}
117         handler = handlers.get(response)
118         if handler is not None:
119             handler()
120         else:
121             log.msg("Unexpected dialog response %r from %s" % (response,
122                                                                widget))
123
124     def _on_loginDialog_close(self, widget, userdata=None):
125         self._windowClosed()
126
127     def _on_loginDialog_destroy_event(self, widget, userdata=None):
128         self._windowClosed()
129
130     def _cancelled(self):
131         if not self.deferredResult.called:
132             self.deferredResult.errback(netError.UserError("User hit Cancel."))
133         self._loginDialog.destroy()
134
135     def _windowClosed(self, reason=None):
136         if not self.deferredResult.called:
137             self.deferredResult.errback(netError.UserError("Window closed."))
138
139     def _doLogin(self):
140         idParams = {}
141
142         idParams['host'] = self._hostEntry.get_text()
143         idParams['port'] = self._portEntry.get_text()
144         idParams['identityName'] = self._identityNameEntry.get_text()
145         idParams['password'] = self._passwordEntry.get_text()
146
147         try:
148             idParams['port'] = int(idParams['port'])
149         except ValueError:
150             pass
151
152         f = pb.PBClientFactory()
153         from twisted.internet import reactor
154         reactor.connectTCP(idParams['host'], idParams['port'], f)
155         creds = UsernamePassword(idParams['identityName'], idParams['password'])
156         f.login(creds, self.client
157             ).addCallbacks(self._cbGotPerspective, self._ebFailedLogin
158             ).setTimeout(30
159             )
160         self.statusMsg("Contacting server...")
161
162         # serviceName = self._serviceNameEntry.get_text()
163         # perspectiveName = self._perspectiveNameEntry.get_text()
164         # if not perspectiveName:
165         #     perspectiveName = idParams['identityName']
166
167         # d = _identityConnector.requestService(serviceName, perspectiveName,
168         #                                       self.client)
169         # d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
170         # setCursor to waiting
171
172     def _cbGotPerspective(self, perspective):
173         self.statusMsg("Connected to server.")
174         self.deferredResult.callback(perspective)
175         # clear waiting cursor
176         self._loginDialog.destroy()
177
178     def _ebFailedLogin(self, reason):
179         if isinstance(reason, failure.Failure):
180             reason = reason.value
181         self.statusMsg(reason)
182         if isinstance(reason, (unicode, str)):
183             text = reason
184         else:
185             text = unicode(reason)
186         msg = gtk.MessageDialog(self._loginDialog,
187                                 gtk.DIALOG_DESTROY_WITH_PARENT,
188                                 gtk.MESSAGE_ERROR,
189                                 gtk.BUTTONS_CLOSE,
190                                 text)
191         msg.show_all()
192         msg.connect("response", lambda *a: msg.destroy())
193
194         # hostname not found
195         # host unreachable
196         # connection refused
197         # authentication failed
198         # no such service
199         # no such perspective
200         # internal server error
201
202     def _on_advancedButton_toggled(self, widget, userdata=None):
203         active = widget.get_active()
204         if active:
205             op = "show"
206         else:
207             op = "hide"
208         for widgetName in self._advancedControls:
209             widget = self.glade.get_widget(widgetName)
210             getattr(widget, op)()
211
212     def statusMsg(self, text):
213         if not isinstance(text, (unicode, str)):
214             text = unicode(text)
215         return self._statusBar.push(self._statusContext, text)
Note: See TracBrowser for help on using the browser.