~ubuntu-branches/ubuntu/precise/gnome-games/precise-proposed

« back to all changes in this revision

Viewing changes to glchess/src/lib/gtkui/network.py

  • Committer: Package Import Robot
  • Author(s): Rodrigo Moya
  • Date: 2011-05-30 13:32:04 UTC
  • mfrom: (1.3.4)
  • mto: (163.1.3 precise)
  • mto: This revision was merged to the branch mainline in revision 143.
  • Revision ID: package-import@ubuntu.com-20110530133204-celaq1v1dsxc48q1
Tags: upstream-3.0.2
ImportĀ upstreamĀ versionĀ 3.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
import gettext
3
 
 
4
 
import gobject
5
 
import gtk
6
 
import pango
7
 
 
8
 
import gtkui
9
 
import glchess.ui
10
 
 
11
 
_ = gettext.gettext
12
 
 
13
 
class GtkNetworkAddDialog:
14
 
 
15
 
    def __init__(self, networkDialog, parent):
16
 
        self.__networkDialog = networkDialog
17
 
 
18
 
        # Load the UI
19
 
        self.__gui = gtkui.loadUIFile('network_new_server.ui')
20
 
        self.__gui.connect_signals(self)
21
 
        
22
 
        self.__gui.get_object('add_account_dialog').set_transient_for(parent)
23
 
        
24
 
        # FIXME: Hard-coded servers       
25
 
        # name, host, port
26
 
        self.serverModel = gtk.ListStore(str, str, int)
27
 
        # Translators: Add Network Profile Dialog: Connect to the GGZ Gaming Zone server (the default)
28
 
        self.serverModel.set(self.serverModel.append(), 0, _("GGZ Gaming Zone"), 1, "gnome.ggzgamingzone.org", 2, 5688)
29
 
        # Translators: Add Network Profile Dialog: Use a custom server
30
 
        self.serverModel.set(self.serverModel.append(), 0, _("Custom"), 1, "", 2, 5688)
31
 
        
32
 
        widget = self.__gui.get_object('server_combo')
33
 
        widget.set_model(self.serverModel)
34
 
        cell = gtk.CellRendererText()
35
 
        widget.pack_start(cell, False)
36
 
        widget.add_attribute(cell, 'text', 0)
37
 
        widget.set_model(self.serverModel)
38
 
        widget.set_active(0)
39
 
 
40
 
    def setVisible(self, isVisible):
41
 
        widget = self.__gui.get_object('add_account_dialog')
42
 
        if isVisible:
43
 
            widget.present()
44
 
        else:
45
 
            widget.hide()
46
 
            self.clear()
47
 
            
48
 
    def clear(self):
49
 
        self.__gui.get_object('server_combo').set_active(0)
50
 
        self.__gui.get_object('username_entry').set_text('')        
51
 
            
52
 
    def _on_server_changed(self, widget):
53
 
        widget = self.__gui.get_object('server_combo')
54
 
        model = widget.get_model()
55
 
        iter = widget.get_active_iter()
56
 
        (host,) = model.get(iter, 1)
57
 
        (port,) = model.get(iter, 2)
58
 
        self.__gui.get_object('host_entry').set_text(host)
59
 
        self.__gui.get_object('port_spin').set_value(port)
60
 
        table = self.__gui.get_object('custom_server_table')
61
 
        if host == '':
62
 
            table.show()
63
 
        else:
64
 
            table.hide()
65
 
            
66
 
    def have_data(self):
67
 
        username = self.__gui.get_object('username_entry').get_text()
68
 
        host = self.__gui.get_object('host_entry').get_text()
69
 
        return username != '' and host != ''
70
 
 
71
 
    def _on_input_changed(self, widget):
72
 
        self.__gui.get_object('add_button').set_sensitive(self.have_data())
73
 
 
74
 
    def _on_username_activate(self, widget):
75
 
        if self.have_data():
76
 
            self._on_response(None, gtk.RESPONSE_OK)
77
 
 
78
 
    def _on_response(self, widget, response_id):
79
 
        username = self.__gui.get_object('username_entry').get_text()
80
 
        host = self.__gui.get_object('host_entry').get_text()
81
 
        port = self.__gui.get_object('port_spin').get_value_as_int()
82
 
        name = '%s@%s' % (username, host) # FIXME
83
 
        
84
 
        if response_id == gtk.RESPONSE_OK:
85
 
            profile = self.__networkDialog.feedback.addProfile((name, username, host, port))
86
 
            self.__networkDialog.addProfile(profile, profile.name, useNow = True)
87
 
        
88
 
        self.__gui.get_object('add_account_dialog').hide()
89
 
        self.clear()
90
 
            
91
 
    def _on_delete(self, widget, event):
92
 
        # Hide; don't delete this window
93
 
        return True
94
 
 
95
 
class GtkNetworkGameDialog(glchess.ui.NetworkController):
96
 
    """
97
 
    """
98
 
 
99
 
    def __init__(self, mainUI, feedback):
100
 
        """Constructor for a new game dialog.
101
 
        
102
 
        'mainUI' is the main UI.
103
 
        'feedback' is the object to feedback events with.
104
 
        """
105
 
        self.__mainUI = mainUI
106
 
        self.feedback = feedback
107
 
 
108
 
        # Load the UI
109
 
        self.__gui = gtkui.loadUIFile('network_game.ui')
110
 
 
111
 
        self.infobar = gtk.InfoBar()
112
 
        vbox = gtk.VBox()
113
 
        self.infobar.add(vbox)
114
 
        vbox.show()
115
 
        self.infoTitleLabel = gtk.Label()
116
 
        vbox.pack_start(self.infoTitleLabel, False, True, 0)
117
 
        self.infoTitleLabel.show()
118
 
        self.infoDescriptionLabel = gtk.Label()
119
 
        vbox.pack_start(self.infoDescriptionLabel, False, True, 0);
120
 
        self.infoDescriptionLabel.show()
121
 
 
122
 
        self.__gui.get_object('network_game_dialog').get_content_area().pack_start(self.infobar, False, False, 0)
123
 
 
124
 
        self.__gui.connect_signals(self)
125
 
        
126
 
        # Selected profile
127
 
        self.__profile = None
128
 
        
129
 
        self.profileModel = gtk.ListStore(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, str)
130
 
        # Translators: Server Combo Box: Not connected to a server
131
 
        self.profileModel.set(self.profileModel.append(), 0, None, 1, self._set_profile, 2, _('Disconnected'))
132
 
        self.profileModelSuffixCount = 0
133
 
        self.profileModel.set(self.profileModel.append(), 1, None)
134
 
        self.profileModelSuffixCount += 1
135
 
        # Translators: Server Combo Box: Add new profile
136
 
        self.profileModel.set(self.profileModel.append(), 0, None, 1, self._new_profile, 2, _('New profile...'))
137
 
        self.profileModelSuffixCount += 1
138
 
 
139
 
        widget = self.__gui.get_object('server_combo')
140
 
        widget.set_model(self.profileModel)
141
 
        widget.set_active(0)
142
 
        widget.set_row_separator_func(self._is_profile_model_separator)
143
 
        cell = gtk.CellRendererText()
144
 
        widget.pack_start(cell, False)
145
 
        widget.add_attribute(cell, 'text', 2)
146
 
 
147
 
        # room object, index, name, num players, description, font weight, font style, icon_name
148
 
        self.roomModel = gtk.TreeStore(gobject.TYPE_PYOBJECT, int, str, str, str, int, int, str)
149
 
        self.firstNonChessIter = None
150
 
        self.roomIters = {}
151
 
        view = self.__gui.get_object('room_list')
152
 
        view.set_model(self.roomModel)
153
 
        cell = gtk.CellRendererText()
154
 
        column = gtk.TreeViewColumn('', cell)
155
 
        column.add_attribute(cell, 'text', 3)
156
 
        view.append_column(column)
157
 
        cell = gtk.CellRendererPixbuf()
158
 
        column = gtk.TreeViewColumn('', cell)
159
 
        column.add_attribute(cell, 'icon-name', 7)
160
 
        view.append_column(column)
161
 
        cell = gtk.CellRendererText()
162
 
        column = gtk.TreeViewColumn('', cell)
163
 
        column.add_attribute(cell, 'text', 2)
164
 
        column.add_attribute(cell, 'weight', 5)
165
 
        column.add_attribute(cell, 'style', 6)
166
 
        view.append_column(column)
167
 
        cell = gtk.CellRendererText()
168
 
        column = gtk.TreeViewColumn('', cell)
169
 
        column.add_attribute(cell, 'text', 4)
170
 
        #view.append_column(column)
171
 
        view.connect('row-activated', self._on_room_changed)
172
 
 
173
 
        # player, name, icon
174
 
        self.playerModel = gtk.ListStore(gobject.TYPE_PYOBJECT, str, str)
175
 
        view = self.__gui.get_object('player_list')
176
 
        view.set_model(self.playerModel)
177
 
        cell = gtk.CellRendererPixbuf()
178
 
        column = gtk.TreeViewColumn('', cell)
179
 
        column.add_attribute(cell, 'icon-name', 2)
180
 
        view.append_column(column)
181
 
        cell = gtk.CellRendererText()
182
 
        column = gtk.TreeViewColumn('', cell)
183
 
        column.add_attribute(cell, 'text', 1)
184
 
        view.append_column(column)
185
 
 
186
 
        # table, number, seats, description, seat model, can connect
187
 
        self.tableModel = gtk.ListStore(gobject.TYPE_PYOBJECT, str, str, str, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
188
 
        self.tableIters = {}
189
 
        
190
 
        view = self.__gui.get_object('table_list')
191
 
        view.get_selection().connect('changed', self._on_table_selected)
192
 
        view.set_model(self.tableModel)
193
 
        
194
 
        cell = gtk.CellRendererText()
195
 
        # Translators: Available GGZ Tables: Table name column title
196
 
        column = gtk.TreeViewColumn(_('Table'), cell)
197
 
        column.add_attribute(cell, 'text', 1)
198
 
        view.append_column(column)
199
 
        cell = gtk.CellRendererText()
200
 
        # Translators: Available GGZ Tables: Seat status column title
201
 
        column = gtk.TreeViewColumn(_('Seats'), cell)
202
 
        column.add_attribute(cell, 'text', 2)
203
 
        view.append_column(column)
204
 
        cell = gtk.CellRendererText()
205
 
        # Translators: Available GGZ Tables: Table description column title        
206
 
        column = gtk.TreeViewColumn(_('Description'), cell)
207
 
        column.add_attribute(cell, 'text', 3)
208
 
        view.append_column(column)
209
 
 
210
 
        view = self.__gui.get_object('seat_list')
211
 
        cell = gtk.CellRendererText()
212
 
        # Translators: Current GGZ Table: Seat name column title
213
 
        column = gtk.TreeViewColumn(_('Seat'), cell)
214
 
        column.add_attribute(cell, 'text', 2)
215
 
        view.append_column(column)
216
 
        # Translators: Current GGZ Table: Player name column title        
217
 
        column = gtk.TreeViewColumn(_('Player'), cell)
218
 
        column.add_attribute(cell, 'text', 3)
219
 
        column.add_attribute(cell, 'style', 4)
220
 
        view.append_column(column)
221
 
        
222
 
        self.__loadThrobber()
223
 
 
224
 
        # Create styles for the buffer
225
 
        buffer = self.__gui.get_object('chat_textview').get_buffer()
226
 
        buffer.create_tag('motd', family='Monospace', foreground = 'red')
227
 
        buffer.create_tag('chat', family='Monospace')
228
 
        #buffer.create_tag('output', family='Monospace', weight = pango.WEIGHT_BOLD)
229
 
        #buffer.create_tag('move', family='Monospace', foreground = 'blue')
230
 
        buffer.create_tag('info', family='Monospace', foreground = 'gray')
231
 
        #buffer.create_tag('error', family='Monospace', foreground = 'red')
232
 
        buffer.create_mark('end', buffer.get_end_iter())
233
 
        
234
 
        self.__addProfileDialog = GtkNetworkAddDialog(self, self.__gui.get_object('network_game_dialog'))
235
 
 
236
 
    # Extended methods
237
 
        
238
 
    def setVisible(self, isVisible):
239
 
        """Called by glchess.ui.NetworkController"""
240
 
        widget = self.__gui.get_object('network_game_dialog')
241
 
        if isVisible:
242
 
            widget.present()
243
 
            
244
 
            # Prompt for new profile if none configured
245
 
            # FIXME: Make this clearer this is the count of non-profile elements in the combo
246
 
            if len(self.profileModel) <= (self.profileModelSuffixCount + 1):
247
 
                self.__addProfileDialog.setVisible(True)
248
 
        else:
249
 
            self.__addProfileDialog.setVisible(False)
250
 
            self.__editProfileDialog.setVisible(False)            
251
 
            widget.hide()
252
 
            
253
 
    def setSensitive(self, isSensitive):
254
 
        widget = self.__gui.get_object('controls_box')
255
 
        widget.set_sensitive(isSensitive)
256
 
 
257
 
    def setError(self, title, description):
258
 
        self.infobar.set_message_type(gtk.MESSAGE_ERROR);
259
 
        self.infoTitleLabel.set_markup('<big><b>%s</b></big>' % title)
260
 
        self.infoDescriptionLabel.set_markup('<i>%s</i>' % description)
261
 
        self.infobar.show()
262
 
 
263
 
    def clearError(self):
264
 
        self.infobar.hide()
265
 
 
266
 
    def addProfile(self, profile, name, useNow = False):
267
 
        """Called by glchess.ui.UIController"""
268
 
        iter = self.profileModel.insert(len(self.profileModel) - self.profileModelSuffixCount)
269
 
        self.profileModel.set(iter, 0, profile, 1, self._set_profile, 2, name)        
270
 
        if self.__profile is None and useNow:
271
 
            self.__gui.get_object('server_combo').set_active_iter(iter)
272
 
 
273
 
    def setBusy(self, isBusy):
274
 
        """Called by glchess.ui.UIController"""
275
 
        if self._throbberTimer is not None:
276
 
            gobject.source_remove(self._throbberTimer)
277
 
            self._throbberTimer = None
278
 
 
279
 
        # Disable room buttons when busy
280
 
        widget = self.__gui.get_object('room_button_box')
281
 
        widget.set_sensitive(not isBusy)
282
 
        
283
 
        # Display animating frames if busy or idle frame if not
284
 
        if isBusy:
285
 
            self._throbberFrame = 1
286
 
            self._throbberTimer = gobject.timeout_add(25, self._updateThrobber)
287
 
        else:
288
 
            self._throbberFrame = 0
289
 
        self._updateThrobber()
290
 
 
291
 
    def addRoom(self, index, name, nPlayers, description, room, protocol):
292
 
        """Called by glchess.ui.UIController"""
293
 
        try:
294
 
            (icon, isSupported) = {None:       ('stock_people', True),
295
 
                                   'Chess':    ('gnome-glchess', True),
296
 
                                   'Reversi':  ('gnome-iagno', False),
297
 
                                   'GGZCards': ('gnome-aisleriot', False),
298
 
                                   'Gnect':    ('gnome-gnect', False),
299
 
                                   'Gnibbles': ('gnome-gnibbles', False),
300
 
                                   'Freeciv':  ('civclient', False)}[protocol]
301
 
        except KeyError:
302
 
            isSupported = False
303
 
            icon = None
304
 
            
305
 
        if isSupported:
306
 
            iter = self.roomModel.insert_before(None, self.firstNonChessIter)
307
 
            style = pango.STYLE_NORMAL
308
 
        else:
309
 
            iter = self.roomModel.append(None)
310
 
            if self.firstNonChessIter is None:
311
 
                self.firstNonChessIter = iter
312
 
            style = pango.STYLE_ITALIC
313
 
 
314
 
        self.roomIters[room] = iter
315
 
        self.roomModel.set(iter, 0, room, 1, index, 2, name, 3, nPlayers, 4, description, 5, pango.WEIGHT_NORMAL, 6, style, 7, icon)
316
 
 
317
 
    def enterRoom(self, room):
318
 
        """Called by glchess.ui.UIController"""
319
 
        for (r, iter) in self.roomIters.iteritems():
320
 
            if r is room:
321
 
                weight = pango.WEIGHT_BOLD
322
 
            else:
323
 
                weight = pango.WEIGHT_NORMAL
324
 
            self.roomModel.set(iter, 5, weight)
325
 
 
326
 
    def updateRoom(self, room, nPlayers):
327
 
        try:
328
 
            iter = self.roomIters[room]
329
 
        except KeyError:
330
 
            print 'Unknown room!'
331
 
            return
332
 
        self.roomModel.set(iter, 3, nPlayers)
333
 
    
334
 
    def removeRoom(self, room):
335
 
        """Called by glchess.ui.UIController"""
336
 
        iter = self.roomModel.get_iter_first()
337
 
        while iter is not None:
338
 
            if room is self.roomModel.get_value(iter, 0):
339
 
                self.roomModel.remove(iter)
340
 
                return
341
 
            iter = self.roomModel.iter_next(iter)
342
 
 
343
 
    def clearRooms(self):
344
 
        """Called by glchess.ui.UIController"""
345
 
        self.firstNonChessIter = None
346
 
        self.roomIters = {}
347
 
        self.roomModel.clear()
348
 
    
349
 
    def updateTable(self, table, name, seats, description, canConnect):
350
 
        """Called by glchess.ui.UIController"""
351
 
        try:
352
 
            iter = self.tableIters[table]
353
 
            seatModel = self.tableModel.get_value(iter, 4)
354
 
        except KeyError:
355
 
            iter = self.tableModel.append()
356
 
            self.tableIters[table] = iter
357
 
            seatModel = gtk.ListStore(int, str, str, str, int) # number, type, name, occupant, font style
358
 
        self.tableModel.set(iter, 0, table, 1, name, 2, seats, 3, description, 4, seatModel, 5, canConnect)
359
 
 
360
 
    def updateSeat(self, table, number, type, name):
361
 
        """Called by glchess.ui.UIController"""
362
 
        iter = self.tableIters[table]
363
 
        seatModel = self.tableModel.get_value(iter, 4)
364
 
        iter = seatModel.get_iter_first()
365
 
        while iter is not None:
366
 
            if number == seatModel.get_value(iter, 0):
367
 
                break
368
 
            iter = seatModel.iter_next(iter)
369
 
        if iter is None:
370
 
            iter = seatModel.append()
371
 
            
372
 
        if number == 0:
373
 
            # Translators: GGZ seat is occupied by the white player
374
 
            seatName = _('White')
375
 
        elif number == 1:
376
 
            # Translators: GGZ seat is occupied by the black player            
377
 
            seatName = _('Black')
378
 
        else:
379
 
            # Translators: GGZ seat is occupied by a spectator
380
 
            seatName = _('Spectator')
381
 
 
382
 
        style = pango.STYLE_ITALIC
383
 
        occupant = name
384
 
        if type == 'player':
385
 
            style = pango.STYLE_NORMAL
386
 
        elif type == 'reserved':
387
 
            # Translators: GGZ seat status: This seat is reserved. %s is replaced with
388
 
            # the name of the player the seat is reserved for.
389
 
            occupant = _('Reserved for %s') % name
390
 
        elif type == 'open':
391
 
            # Translators: GGZ seat status: This seat is not taken
392
 
            occupant = _('Seat empty')
393
 
        elif type == 'bot':
394
 
            # Translators: GGZ seat status: This seat contains an AI player.
395
 
            # %s is replaced with the name of the AI.
396
 
            occupant = _('AI (%s)') % name
397
 
 
398
 
        seatModel.set(iter, 0, number, 1, type, 2, seatName, 3, occupant, 4, style)
399
 
 
400
 
    def removeTable(self, table):
401
 
        """Called by glchess.ui.UIController"""
402
 
        iter = self.tableIters[table]
403
 
        self.tableModel.remove(iter)
404
 
            
405
 
    def joinTable(self, table):
406
 
        """Called by glchess.ui.UIController"""
407
 
        gameFrame = self.__gui.get_object('game_frame')
408
 
        roomFrame = self.__gui.get_object('room_frame')
409
 
        if table is None:
410
 
            gameFrame.hide()
411
 
            roomFrame.show()
412
 
        else:
413
 
            iter = self.tableIters[table]
414
 
            
415
 
            seatModel = self.tableModel.get_value(iter, 4)
416
 
            self.__gui.get_object('seat_list').set_model(seatModel)
417
 
            
418
 
            name = self.tableModel.get_value(iter, 3)
419
 
            self.__gui.get_object('game_name_label').set_text(name)
420
 
            roomFrame.hide()
421
 
            gameFrame.show()
422
 
 
423
 
    def clearTables(self):
424
 
        """Called by glchess.ui.UIController"""
425
 
        self.tableIters = {}
426
 
        self.tableModel.clear()
427
 
 
428
 
    def addPlayer(self, player, name, icon):
429
 
        """Called by glchess.ui.UIController"""
430
 
        iter = self.playerModel.append()
431
 
        self.playerModel.set(iter, 0, player, 1, name, 2, icon)
432
 
 
433
 
    def removePlayer(self, player):
434
 
        """Called by glchess.ui.UIController"""
435
 
        iter = self.playerModel.get_iter_first()
436
 
        while iter is not None:
437
 
            if player is self.playerModel.get_value(iter, 0):
438
 
                self.playerModel.remove(iter)
439
 
                return
440
 
            iter = self.playerModel.iter_next(iter)
441
 
    
442
 
    def clearPlayers(self):
443
 
        """Called by glchess.ui.UIController"""
444
 
        self.playerModel.clear()
445
 
    
446
 
    def addText(self, text, style):
447
 
        """Called by glchess.ui.UIController"""
448
 
        view = self.__gui.get_object('chat_textview')
449
 
        scroll = self.__gui.get_object('chat_scroll_window')
450
 
        adj = scroll.get_vadjustment()
451
 
        atBottom = adj.value >= adj.upper - adj.page_size
452
 
        buffer = view.get_buffer()
453
 
        mark = buffer.get_mark('end')
454
 
        buffer.insert_with_tags_by_name(buffer.get_iter_at_mark(mark), text, style)
455
 
        if atBottom:
456
 
            view.scroll_mark_onscreen(mark)
457
 
 
458
 
    def clearText(self):
459
 
        buffer = self.__gui.get_object('chat_textview').get_buffer()
460
 
        buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
461
 
 
462
 
    def close(self):
463
 
        """Called by glchess.ui.UIController"""
464
 
        self.__gui.get_object('network_game_dialog').hide()        
465
 
 
466
 
    # Private methods
467
 
    
468
 
    def __loadThrobber(self):
469
 
        self._throbberTimer = None
470
 
        theme = gtk.icon_theme_get_default()
471
 
        size = 32
472
 
        self._throbberFrames = []
473
 
        
474
 
        try:
475
 
            icon = theme.load_icon('process-idle', size, 0)
476
 
        except gobject.GError:
477
 
            pass
478
 
        else:
479
 
            self._throbberFrames.append(icon)
480
 
 
481
 
        try:
482
 
            icon = theme.load_icon('process-working', size, 0)
483
 
        except gobject.GError:
484
 
            pass
485
 
        else:
486
 
            # If a smaller icon was received than expected then use that size
487
 
            height = icon.get_height()
488
 
            width = icon.get_width()
489
 
            size = min(size, height, width)
490
 
 
491
 
            for i in xrange(height / size):
492
 
                for j in xrange(width / size):
493
 
                    frame = icon.subpixbuf(j * size, i * size, size, size)
494
 
                    self._throbberFrames.append(frame)
495
 
                
496
 
        # Display idle frame
497
 
        self._throbberFrame = 0
498
 
        self._updateThrobber()
499
 
 
500
 
    def _updateThrobber(self):
501
 
        widget = self.__gui.get_object('throbber_image')
502
 
        try:
503
 
            icon = self._throbberFrames[self._throbberFrame]
504
 
        except IndexError:
505
 
            pass
506
 
        else:
507
 
            widget.set_from_pixbuf(icon)
508
 
        
509
 
        # Move to next frame restarting animation after idle frame
510
 
        self._throbberFrame += 1
511
 
        if self._throbberFrame >= len(self._throbberFrames):
512
 
            self._throbberFrame = 1
513
 
        return True
514
 
    
515
 
    def __setCombo(self, comboName, key):
516
 
        widget = self.__gui.get_object(comboName)
517
 
        iter = self.__getIter(widget.get_model(), key)
518
 
        if iter is not None:
519
 
            widget.set_active_iter(iter)
520
 
    
521
 
    def __getIter(self, model, key, default = None):
522
 
        """
523
 
        """
524
 
        iter = model.get_iter_first()
525
 
        while iter:
526
 
            if model.get_value(iter, 0) == key:
527
 
                return iter
528
 
 
529
 
            iter = model.iter_next(iter)
530
 
        return default
531
 
                
532
 
    def __getComboData(self, comboBox, index):
533
 
        """
534
 
        """
535
 
        model = comboBox.get_model()
536
 
        iter = comboBox.get_active_iter()
537
 
        if iter is None:
538
 
            return None
539
 
        
540
 
        data = model.get(iter, index)
541
 
        return data[0]
542
 
       
543
 
    def __startGame(self):
544
 
        game = glchess.ui.Game()
545
 
        game.name = self.__gui.get_object('game_name_entry').get_text()
546
 
        game.allowSpectators = True
547
 
        
548
 
        # Get the players
549
 
        game.white.type  = self.__getComboData(self.__gui.get_object('white_type_combo'), 0)
550
 
        if game.white.type == '':
551
 
            game.white.name = _('White')
552
 
        else:
553
 
            game.white.name = self.__getComboData(self.__gui.get_object('white_type_combo'), 2)
554
 
        game.white.level = self.__getComboData(self.__gui.get_object('white_difficulty_combo'), 0)
555
 
        game.black.type  = self.__getComboData(self.__gui.get_object('black_type_combo'), 0)
556
 
        if game.black.type == '':
557
 
            game.black.name = _('Black')
558
 
        else:
559
 
            game.black.name = self.__getComboData(self.__gui.get_object('black_type_combo'), 2)
560
 
        game.black.level = self.__getComboData(self.__gui.get_object('black_difficulty_combo'), 0)
561
 
 
562
 
        game.duration = self.__getComboData(self.__gui.get_object('time_combo'), 1)
563
 
        if game.duration < 0:
564
 
            multiplier = self.__getComboData(self.__gui.get_object('custom_time_units_combo'), 1)
565
 
            game.duration = self.__getComboData(self.__gui.get_object('custom_time_spin'), 1) * multiplier
566
 
            
567
 
        # Save properties
568
 
        glchess.config.set('new_game_dialog/white/type', game.white.type)
569
 
        glchess.config.set('new_game_dialog/white/difficulty', game.white.level)
570
 
        glchess.config.set('new_game_dialog/black/type', game.black.type)
571
 
        glchess.config.set('new_game_dialog/black/difficulty', game.black.level)
572
 
 
573
 
        # Inform the child class
574
 
        self.__mainUI.feedback.onGameStart(game)
575
 
        
576
 
    def _is_profile_model_separator(self, model, iter):
577
 
        return model.get(iter, 1)[0] is None
578
 
 
579
 
    def _set_profile(self, profile):
580
 
        if profile != self.__profile:
581
 
            self.__profile = profile
582
 
            self.feedback.setProfile(profile)
583
 
            
584
 
    def __selectActiveProfile(self):
585
 
        iter = self.profileModel.get_iter_first()
586
 
        while iter is not None:
587
 
            if self.__profile == self.profileModel.get_value(iter, 0):
588
 
                break
589
 
            iter = self.profileModel.iter_next(iter)
590
 
        self.__gui.get_object('server_combo').set_active_iter(iter)
591
 
 
592
 
    def _new_profile(self, profile):
593
 
        self.__selectActiveProfile()
594
 
        self.__addProfileDialog.setVisible(True)
595
 
        
596
 
    # Gtk+ signal handlers
597
 
    
598
 
    def _on_table_selected(self, selection):
599
 
        (model, iter) = selection.get_selected()
600
 
        if iter is None:
601
 
            isSensitive = False
602
 
        else:
603
 
            isSensitive = model.get_value(iter, 5)
604
 
 
605
 
        widget = self.__gui.get_object('table_join_button')
606
 
        widget.set_sensitive(isSensitive)
607
 
        
608
 
    def _on_table_list_activated(self):
609
 
        pass
610
 
    
611
 
    def _on_server_combo_changed(self, widget):
612
 
        """Gtk+ callback"""
613
 
        model = widget.get_model()
614
 
        iter = widget.get_active_iter()
615
 
        (method,) = model.get(iter, 1)
616
 
        (profile,) = model.get(iter, 0)
617
 
        method(profile)
618
 
 
619
 
    def _on_chat_entry_activate(self, widget):
620
 
        """Gtk+ callback"""
621
 
        text = widget.get_text()
622
 
        widget.set_text('')
623
 
        self.feedback.sendChat(text)
624
 
        
625
 
    def _on_delete(self, widget, event):
626
 
        # Hide; don't delete this window
627
 
        return True
628
 
 
629
 
    def _on_response(self, widget, response_id):
630
 
        """Gtk+ callback"""
631
 
        self.__gui.get_object('network_game_dialog').hide()
632
 
 
633
 
    def _on_room_changed(self, widget, path, column):
634
 
        """Gtk+ callback"""
635
 
        # FIXME: Only if allowed to enter room (state machine)
636
 
        model = self.__gui.get_object('room_list').get_model()
637
 
        iter = model.get_iter(path)
638
 
        if iter is None:
639
 
            return True
640
 
        room = model.get_value(iter, 0)
641
 
        if room is not None:
642
 
            self.feedback.enterRoom(room)
643
 
        return True
644
 
 
645
 
    def _on_table_join_button_clicked(self, widget):
646
 
        """Gtk+ callback"""
647
 
        (model, iter) = self.__gui.get_object('table_list').get_selection().get_selected()
648
 
        if iter is None:
649
 
            return
650
 
        table = model.get_value(iter, 0)
651
 
        self.feedback.joinTable(table)
652
 
 
653
 
    def _on_table_leave_button_clicked(self, widget):
654
 
        """Gtk+ callback"""
655
 
        self.feedback.leaveTable()
656
 
 
657
 
    def _on_table_new_button_clicked(self, widget):
658
 
        """Gtk+ callback"""
659
 
        self.feedback.startTable()