def setupUi(self): """create all Ui elements but do not fill them""" self.buttonBox = KDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) # Ubuntu 11.10 unity is a bit strange - without this, it sets focus on # the cancel button (which it shows on the left). I found no obvious # way to use setDefault and setAutoDefault for fixing this. self.buttonBox.button(QDialogButtonBox.Ok).setFocus(True) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) vbox = QVBoxLayout(self) self.grid = QFormLayout() self.cbServer = QComboBox() self.cbServer.setEditable(True) self.grid.addRow(i18n('Game server:'), self.cbServer) self.cbUser = QComboBox() self.cbUser.setEditable(True) self.grid.addRow(i18n('Username:'******'Password:'******'kajongg', 'Ruleset:'), self.cbRuleset) vbox.addLayout(self.grid) vbox.addWidget(self.buttonBox) pol = QSizePolicy() pol.setHorizontalPolicy(QSizePolicy.Expanding) self.cbUser.setSizePolicy(pol) self.__port = None
def __init__(self, url, username, password): KDialog.__init__(self) decorateWindow(self, i18n('Create User Account')) self.setButtons(KDialog.ButtonCode(KDialog.Ok | KDialog.Cancel)) vbox = QVBoxLayout() grid = QFormLayout() self.lbServer = QLabel() self.lbServer.setText(url) grid.addRow(i18n('Game server:'), self.lbServer) self.lbUser = QLabel() grid.addRow(i18n('Username:'******'Password:'******'Repeat password:'), self.edPassword2) vbox.addLayout(grid) widget = QWidget(self) widget.setLayout(vbox) self.setMainWidget(widget) pol = QSizePolicy() pol.setHorizontalPolicy(QSizePolicy.Expanding) self.lbUser.setSizePolicy(pol) self.edPassword.textChanged.connect(self.passwordChanged) self.edPassword2.textChanged.connect(self.passwordChanged) StateSaver(self) self.username = username self.password = password self.passwordChanged() self.edPassword2.setFocus()
def removeTable(self, table, reason, message=None, *args): """remove a table""" assert reason in ('silent', 'tableRemoved', 'gameOver', 'abort') # HumanClient implements methods remote_tableRemoved etc. message = message or '' if Debug.connections or reason == 'abort': logDebug('%s%s ' % (('%s:' % table.game.seed) if table.game else '', i18n(message, *args)), withGamePrefix=None) if table.tableid in self.tables: del self.tables[table.tableid] if reason == 'silent': tellUsers = [] else: tellUsers = table.users if table.running else self.srvUsers for user in tellUsers: # this may in turn call removeTable again! self.callRemote(user, reason, table.tableid, message, *args) for user in table.users: table.delUser(user) if Debug.table: logDebug('removing table %d: %s %s' % (table.tableid, i18n(message, *args), reason)) if table.game: table.game.close()
def __startLocalServer(self): """start a local server""" try: args = self.__findServerProgram() if self.useSocket or os.name == 'nt': # for nt --socket tells the server to bind to 127.0.0.1 args.append('--socket=%s' % socketName()) if removeIfExists(socketName()): logInfo( i18n('removed stale socket <filename>%1</filename>', socketName())) if not self.useSocket: args.append('--port=%d' % self.port) if self.isLocalGame: args.append('--db={}'.format( os.path.normpath(os.path.join(appdataDir(), 'local3.db')))) if Debug.argString: args.append('--debug=%s' % Debug.argString) if os.name == 'nt': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW else: startupinfo = None process = subprocess.Popen( args, startupinfo=startupinfo) # , shell=os.name == 'nt') if Debug.connections: logDebug( i18n( 'started the local kajongg server: pid=<numid>%1</numid> %2', process.pid, ' '.join(args))) except OSError as exc: exc.filename = ' '.join(args) logException(exc)
def __init__(self, parent): QDialog.__init__(self) self.parent = parent self._data = {} self.table = QTableWidget(self) self.table.horizontalHeader().setStretchLastSection(True) self.table.verticalHeader().setVisible(False) self.table.setEditTriggers(QTableWidget.NoEditTriggers) self.table.itemChanged.connect(self.itemChanged) self.updateTable() self.buttonBox = QDialogButtonBox() self.buttonBox.setStandardButtons( QDialogButtonBox.Close) # Close has the Rejected role self.buttonBox.rejected.connect(self.accept) self.newButton = self.buttonBox.addButton( i18nc('define a new player', "&New"), QDialogButtonBox.ActionRole) self.newButton.setIcon(KIcon("document-new")) self.newButton.clicked.connect(self.slotInsert) self.deleteButton = self.buttonBox.addButton( i18n("&Delete"), QDialogButtonBox.ActionRole) self.deleteButton.setIcon(KIcon("edit-delete")) self.deleteButton.clicked.connect(self.delete) cmdLayout = QHBoxLayout() cmdLayout.addWidget(self.buttonBox) layout = QVBoxLayout() layout.addWidget(self.table) layout.addLayout(cmdLayout) self.setLayout(layout) decorateWindow(self, i18n("Players")) self.setObjectName('Players')
def setupUILastTileMeld(self, pGrid): """setup UI elements for last tile and last meld""" self.lblLastTile = QLabel(i18n('&Last Tile:')) self.cbLastTile = QComboBox() self.cbLastTile.setMinimumContentsLength(1) vpol = QSizePolicy() vpol.setHorizontalPolicy(QSizePolicy.Fixed) self.cbLastTile.setSizePolicy(vpol) self.cbLastTile.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.lblLastTile.setBuddy(self.cbLastTile) self.lblLastMeld = QLabel(i18n('L&ast Meld:')) self.prevLastTile = None self.cbLastMeld = QComboBox() self.cbLastMeld.setMinimumContentsLength(1) self.cbLastMeld.setSizePolicy(vpol) self.cbLastMeld.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLengthWithIcon) self.lblLastMeld.setBuddy(self.cbLastMeld) self.comboTilePairs = set() pGrid.setRowStretch(6, 5) pGrid.addWidget(self.lblLastTile, 7, 0, 1, 2) pGrid.addWidget(self.cbLastTile, 7, 2, 1, 1) pGrid.addWidget(self.lblLastMeld, 8, 0, 1, 2) pGrid.addWidget(self.cbLastMeld, 8, 2, 1, 2)
def refresh(self): """refresh for new values""" lines = [] if self.game is None: lines.append(i18n('There is no active game')) else: i18nName = i18n(self.game.ruleset.name) lines.append(i18n('%1', i18nName)) lines.append('') for player in self.game.players: pLines = [] explainHand = player.explainHand() if explainHand.hasTiles(): total = explainHand.total() if total: pLines = ['%s - %s' % (player.localName, total)] for line in explainHand.explain(): pLines.append('- ' + line) elif player.handTotal: pLines.append( i18n('Manual score for %1: %2 points', player.localName, player.handTotal)) if pLines: pLines.append('') lines.extend(pLines) if 'xxx'.join(lines) != 'xxx'.join( str(x) for x in self.model.stringList()): # TODO: ohne? # QStringListModel does not optimize identical lists away, so we do self.model.setStringList(lines)
def toolTip(self, button, dummyTile): """for the action button which will send this message""" myself = button.client.game.myself maySay = myself.sayable[self] if not maySay: return '', False, '' txt = [] warn = False if myself.originalCall and myself.mayWin: warn = True txt.append(i18n('saying %1 violates Original Call', self.i18nName)) dangerousMelds = myself.maybeDangerous(self) if dangerousMelds: lastDiscard = myself.game.lastDiscard warn = True if Debug.dangerousGame and len(dangerousMelds) != len(maySay): button.client.game.debug( 'only some claimable melds are dangerous: %s' % dangerousMelds) if len(dangerousMelds) == 1: txt.append( i18n( 'claiming %1 is dangerous because you will have to discard a dangerous tile', lastDiscard.name())) else: for meld in dangerousMelds: txt.append( i18n( 'claiming %1 for %2 is dangerous because you will have to discard a dangerous tile', lastDiscard.name(), str(meld))) if not txt: txt = [i18n('You may say %1', self.i18nName)] return '<br><br>'.join(txt), warn, ''
def headerData( # pylint: disable=no-self-use self, section, orientation, role=Qt.DisplayRole): """show header""" if role == Qt.TextAlignmentRole: if orientation == Qt.Horizontal: if section in [3, 4]: return int(Qt.AlignLeft) else: return int(Qt.AlignHCenter | Qt.AlignVCenter) if role != Qt.DisplayRole: return if orientation != Qt.Horizontal: return int(section + 1) result = '' if section < 5: result = [ i18n('Table'), '', i18n('Players'), i18nc('table status', 'Status'), i18n('Ruleset') ][section] return result
def tooltip(self): """tooltip for rule: just the name of the ruleset""" ruleset = self.ruleset() if self.rawContent.description: return '<b>' + i18n(ruleset.name) + '</b><br><br>' + \ i18n(self.rawContent.description) else: return i18n(ruleset.name)
def __str__(self): local = self.localtimestamp() # pylint: disable=no-member # pylint says something about NotImplemented, check with later versions _ = i18n(self.message) if self.isStatusMessage: _ = '[{}]'.format(_) return '%02d:%02d:%02d %s: %s' % (local.hour, local.minute, local.second, self.fromUser, i18n(self.message))
def loadRules(self): ClassicalChinese.loadRules(self) # the squirming snake is only covered by standard mahjongg rule if # tiles are ordered self.mjRules.createRule( 'Squirming Snake', 'FSquirmingSnake', limits=1, description=i18n( 'All tiles of same color. Pung or Kong of 1 and 9, pair of 2, 5 or 8 and two ' 'Chows of the remaining values')) self.handRules.createRule( 'Little Three Dragons', 'FLittleThreeDragons', doubles=1, description=i18n( '2 Pungs or Kongs of dragons and 1 pair of dragons')) self.handRules.createRule( 'Big Three Dragons', 'FBigThreeDragons', doubles=2, description=i18n('3 Pungs or Kongs of dragons')) self.handRules.createRule( 'Little Four Joys', 'FLittleFourJoys', doubles=1, description=i18n('3 Pungs or Kongs of winds and 1 pair of winds')) self.handRules.createRule( 'Big Four Joys', 'FBigFourJoys', doubles=2, description=i18n('4 Pungs or Kongs of winds')) self.winnerRules['OnlyHonors'].doubles = 2 self.penaltyRules.createRule( 'False Naming of Discard, Claimed for Chow', points=-50) self.penaltyRules.createRule( 'False Naming of Discard, Claimed for Pung/Kong', points=-100) self.penaltyRules.createRule( 'False Declaration of Mah Jongg by One Player', 'Oabsolute payees=3', points=-300) self.penaltyRules.createRule( 'False Declaration of Mah Jongg by Two Players', 'Oabsolute payers=2 payees=2', points=-300) self.penaltyRules.createRule( 'False Declaration of Mah Jongg by Three Players', 'Oabsolute payers=3', points=-300) self.penaltyRules.createRule( 'False Naming of Discard, Claimed for Mah Jongg', 'Oabsolute payees=3', points=-300)
def name(self): """returns name of a single tile""" if self.group.lower() == Tile.wind: result = { East: i18n('East Wind'), South: i18n('South Wind'), West: i18n('West Wind'), North: i18n('North Wind') }[self.value] else: result = i18nc('kajongg tile name', '{group} {value}') return result.format(value=self.valueName(), group=self.groupName())
def __init__(self, parent, name): # pylint: disable=super-init-not-called KConfigDialog.__init__(self, parent, name, Internal.Preferences) StateSaver(self) self.pages = [ self.addPage(PlayConfigTab(self), i18nc('kajongg', 'Play'), "arrow-right"), self.addPage(TilesetSelector(self), i18n("Tiles"), "games-config-tiles"), self.addPage(BackgroundSelector(self), i18n("Backgrounds"), "games-config-background") ]
def __init__(self, client): super(TableList, self).__init__(None) self.autoStarted = False self.client = client self.setObjectName('TableList') self.resize(700, 400) self.view = MJTableView(self) self.differ = None self.debugModelTest = None self.requestedNewTable = False self.view.setItemDelegateForColumn(2, RichTextColumnDelegate(self.view)) buttonBox = QDialogButtonBox(self) self.newButton = buttonBox.addButton( i18nc('allocate a new table', "&New"), QDialogButtonBox.ActionRole) self.newButton.setIcon(KIcon("document-new")) self.newButton.setToolTip(i18n("Allocate a new table")) self.newButton.clicked.connect(self.client.newTable) self.joinButton = buttonBox.addButton(i18n("&Join"), QDialogButtonBox.AcceptRole) self.joinButton.clicked.connect(client.joinTable) self.joinButton.setIcon(KIcon("list-add-user")) self.joinButton.setToolTip(i18n("Join a table")) self.leaveButton = buttonBox.addButton(i18n("&Leave"), QDialogButtonBox.AcceptRole) self.leaveButton.clicked.connect(self.leaveTable) self.leaveButton.setIcon(KIcon("list-remove-user")) self.leaveButton.setToolTip(i18n("Leave a table")) self.compareButton = buttonBox.addButton( i18nc('Kajongg-Ruleset', 'Compare'), QDialogButtonBox.AcceptRole) self.compareButton.clicked.connect(self.compareRuleset) self.compareButton.setIcon(KIcon("preferences-plugin-script")) self.compareButton.setToolTip( i18n('Compare the rules of this table with my own rulesets')) self.chatButton = buttonBox.addButton(i18n('&Chat'), QDialogButtonBox.AcceptRole) self.chatButton.setIcon(KIcon("call-start")) self.chatButton.clicked.connect(self.chat) self.startButton = buttonBox.addButton(i18n('&Start'), QDialogButtonBox.AcceptRole) self.startButton.clicked.connect(self.startGame) self.startButton.setIcon(KIcon("arrow-right")) self.startButton.setToolTip( i18n("Start playing on a table. " "Empty seats will be taken by robot players.")) cmdLayout = QHBoxLayout() cmdLayout.addWidget(buttonBox) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(cmdLayout) self.setLayout(layout) self.view.doubleClicked.connect(client.joinTable) StateSaver(self, self.view.horizontalHeader()) self.updateButtonsForTable(None)
def __init__(self, game): """selection for this player, tiles are the still available tiles""" QDialog.__init__(self, None) decorateWindow(self, i18n("Penalty")) self.game = game grid = QGridLayout(self) lblOffense = QLabel(i18n('Offense:')) crimes = list([ x for x in game.ruleset.penaltyRules if not ('absolute' in x.options and game.winner) ]) self.cbCrime = ListComboBox(crimes) lblOffense.setBuddy(self.cbCrime) grid.addWidget(lblOffense, 0, 0) grid.addWidget(self.cbCrime, 0, 1, 1, 4) lblPenalty = QLabel(i18n('Total Penalty')) self.spPenalty = PenaltyBox(2) self.spPenalty.setRange(0, 9999) lblPenalty.setBuddy(self.spPenalty) self.lblUnits = QLabel(i18n('points')) grid.addWidget(lblPenalty, 1, 0) grid.addWidget(self.spPenalty, 1, 1) grid.addWidget(self.lblUnits, 1, 2) self.payers = [] self.payees = [] # a penalty can never involve the winner, neither as payer nor as payee for idx in range(3): self.payers.append(ListComboBox(game.losers())) self.payees.append(ListComboBox(game.losers())) for idx, payer in enumerate(self.payers): grid.addWidget(payer, 3 + idx, 0) payer.lblPayment = QLabel() grid.addWidget(payer.lblPayment, 3 + idx, 1) for idx, payee in enumerate(self.payees): grid.addWidget(payee, 3 + idx, 3) payee.lblPayment = QLabel() grid.addWidget(payee.lblPayment, 3 + idx, 4) grid.addWidget(QLabel(''), 6, 0) grid.setRowStretch(6, 10) for player in self.payers + self.payees: player.currentIndexChanged.connect(self.playerChanged) self.spPenalty.valueChanged.connect(self.penaltyChanged) self.cbCrime.currentIndexChanged.connect(self.crimeChanged) buttonBox = KDialogButtonBox(self) grid.addWidget(buttonBox, 7, 0, 1, 5) buttonBox.setStandardButtons(QDialogButtonBox.Cancel) buttonBox.rejected.connect(self.reject) self.btnExecute = buttonBox.addButton(i18n("&Execute"), QDialogButtonBox.AcceptRole) self.btnExecute.clicked.connect(self.accept) self.crimeChanged() StateSaver(self)
def refresh(self): """load this game and this player. Keep parameter list identical with ExplainView""" if not self.game: # keep scores of previous game on display return if self.scoreModel: expandGroups = [ self.viewLeft.isExpanded( self.scoreModel.index(x, 0, QModelIndex())) for x in range(4) ] else: expandGroups = [True, False, True, True] gameid = str(self.game.seed or self.game.gameid) if self.game.finished(): title = i18n('Final scores for game <numid>%1</numid>', gameid) else: title = i18n('Scores for game <numid>%1</numid>', gameid) decorateWindow(self, title) self.ruleTree.rulesets = list([self.game.ruleset]) self.scoreModel = ScoreModel(self) if Debug.modelTest: self.scoreModelTest = ModelTest(self.scoreModel, self) for view in [self.viewLeft, self.viewRight]: view.setModel(self.scoreModel) header = view.header() header.setStretchLastSection(False) view.setAlternatingRowColors(True) self.viewRight.header().setSectionResizeMode(QHeaderView.Fixed) for col in range(self.viewLeft.header().count()): self.viewLeft.header().setSectionHidden(col, col > 0) self.viewRight.header().setSectionHidden(col, col == 0) self.scoreLayout.setStretch(1, 100) self.scoreLayout.setSpacing(0) self.viewLeft.setFrameStyle(QFrame.NoFrame) self.viewRight.setFrameStyle(QFrame.NoFrame) self.viewLeft.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) for master, slave in ((self.viewRight, self.viewLeft), (self.viewLeft, self.viewRight)): master.expanded.connect(slave.expand) master.collapsed.connect(slave.collapse) master.verticalScrollBar().valueChanged.connect( slave.verticalScrollBar().setValue) for row, expand in enumerate(expandGroups): self.viewLeft.setExpanded( self.scoreModel.index(row, 0, QModelIndex()), expand) self.viewLeft.resizeColumnToContents(0) self.viewRight.setColWidth() # we need a timer since the scrollbar is not yet visible QTimer.singleShot(0, self.scrollRight)
def headerData(self, section, orientation, role): """tell the view about the wanted headers""" if role == Qt.TextAlignmentRole: if orientation == Qt.Horizontal: return int(Qt.AlignLeft | Qt.AlignVCenter) if role != Qt.DisplayRole: return if orientation == Qt.Horizontal: if section == 0: return i18nc('Kajongg', 'Rule') if section == 1: return i18n(self.view.cbRuleset1.current.name) if section == 2: return i18n(self.view.cbRuleset2.current.name)
def __init__(self, parent=None): super(Games, self).__init__(parent) self.selectedGame = None self.onlyPending = True decorateWindow(self, i18nc('kajongg', 'Games')) self.setObjectName('Games') self.resize(700, 400) self.model = GamesModel() if Debug.modelTest: self.modelTest = ModelTest(self.model, self) self.view = MJTableView(self) self.view.setModel(self.model) self.selection = QItemSelectionModel(self.model, self.view) self.view.setSelectionModel(self.selection) self.view.setSelectionBehavior(QAbstractItemView.SelectRows) self.view.setSelectionMode(QAbstractItemView.SingleSelection) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel) self.newButton = self.buttonBox.addButton( i18nc('start a new game', "&New"), QDialogButtonBox.ActionRole) self.newButton.setIcon(KIcon("document-new")) self.newButton.clicked.connect(self.accept) self.loadButton = self.buttonBox.addButton( i18n("&Load"), QDialogButtonBox.AcceptRole) self.loadButton.clicked.connect(self.loadGame) self.loadButton.setIcon(KIcon("document-open")) self.deleteButton = self.buttonBox.addButton( i18n("&Delete"), QDialogButtonBox.ActionRole) self.deleteButton.setIcon(KIcon("edit-delete")) self.deleteButton.clicked.connect(self.delete) chkPending = QCheckBox(i18n("Show only pending games"), self) chkPending.setChecked(True) cmdLayout = QHBoxLayout() cmdLayout.addWidget(chkPending) cmdLayout.addWidget(self.buttonBox) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(cmdLayout) self.setLayout(layout) StateSaver(self) self.selection.selectionChanged.connect(self.selectionChanged) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.view.doubleClicked.connect(self.loadGame) chkPending.stateChanged.connect(self.pendingOrNot)
def addParameterRules(self): """as the name says""" self.parameterRules.createRule('Points Needed for Mah Jongg', 'intminMJPoints', parameter=0) self.parameterRules.createRule( 'Minimum number of doubles needed for Mah Jongg', 'intminMJDoubles', parameter=0) self.parameterRules.createRule('Points for a Limit Hand', 'intlimit||Omin=1', parameter=500) self.parameterRules.createRule( 'Play with the roof off', 'boolroofOff', parameter=False, description=i18n('Play with no upper scoring limit')) self.parameterRules.createRule('Claim Timeout', 'intclaimTimeout', parameter=10) self.parameterRules.createRule( 'Size of Kong Box', 'intkongBoxSize', parameter=16, description=i18n( 'The Kong Box is used for replacement tiles when declaring kongs' )) self.parameterRules.createRule( 'Play with Bonus Tiles', 'boolwithBonusTiles', parameter=True, description=i18n('Bonus tiles increase the luck factor')) self.parameterRules.createRule('Minimum number of rounds in game', 'intminRounds', parameter=4) self.parameterRules.createRule( 'number of allowed chows', 'intmaxChows', parameter=4, description=i18n('The number of chows a player may build')) self.parameterRules.createRule( 'must declare calling hand', 'boolmustDeclareCallingHand', parameter=False, description=i18n( 'Mah Jongg is only allowed after having declared to have a calling hand' )) self.parameterRules.createRule( 'Standard Rotation', 'FStandardRotation||Orotate||Ointernal')
def toolTip(self, button, tile): """for the action button which will send this message""" assert isinstance(tile, Tile), tile myself = button.client.game.myself isCalling = bool((myself.hand - tile).callingHands) if not isCalling: txt = i18n( 'discarding %1 and declaring Original Call makes this hand unwinnable', tile.name()) return txt, True, txt else: return (i18n( 'Discard a tile, declaring Original Call meaning you need only one ' 'tile to complete the hand and will not alter the hand in any way (except bonus tiles)' ), False, '')
def findDangerousTiles(self): """update the list of dangerous tile""" pName = self.localName dangerous = list() expMeldCount = len(self._exposedMelds) if expMeldCount >= 3: if all(x in elements.greenHandTiles for x in self.visibleTiles): dangerous.append( (elements.greenHandTiles, i18n('Player %1 has 3 or 4 exposed melds, all are green', pName))) group = list(defaultdict.keys(self.visibleTiles))[0].group # see https://www.logilab.org/ticket/23986 assert group.islower(), self.visibleTiles if group in Tile.colors: if all(x.group == group for x in self.visibleTiles): suitTiles = set([Tile(group, x) for x in Tile.numbers]) if self.visibleTiles.count(suitTiles) >= 9: dangerous.append( (suitTiles, i18n('Player %1 may try a True Color Game', pName))) elif all(x.value in Tile.terminals for x in self.visibleTiles): dangerous.append( (elements.terminals, i18n('Player %1 may try an All Terminals Game', pName))) if expMeldCount >= 2: windMelds = sum(self.visibleTiles[x] >= 3 for x in elements.winds) dragonMelds = sum(self.visibleTiles[x] >= 3 for x in elements.dragons) windsDangerous = dragonsDangerous = False if windMelds + dragonMelds == expMeldCount and expMeldCount >= 3: windsDangerous = dragonsDangerous = True windsDangerous = windsDangerous or windMelds >= 3 dragonsDangerous = dragonsDangerous or dragonMelds >= 2 if windsDangerous: dangerous.append((set(x for x in elements.winds if x not in self.visibleTiles), i18n('Player %1 exposed many winds', pName))) if dragonsDangerous: dangerous.append((set(x for x in elements.dragons if x not in self.visibleTiles), i18n('Player %1 exposed many dragons', pName))) self.dangerousTiles = dangerous if dangerous and Debug.dangerousGame: self.game.debug('dangerous:%s' % dangerous)
def toolTip(self, button, dummyTile): """for the action button which will send this message""" myself = button.client.game.myself maySay = myself.sayable[self] if not maySay: return '', False, '' txt = [] warn = False if myself.originalCall and myself.mayWin: warn = True txt.append( i18n('saying Kong for %1 violates Original Call', Tile(maySay[0][0]).name())) if not txt: txt = [i18n('You may say Kong for %1', Tile(maySay[0][0]).name())] return '<br><br>'.join(txt), warn, ''
def updateTable(self, data=None, currentName=None): """fills self.table from DB""" self.table.itemChanged.disconnect(self.itemChanged) table = self.table table.clear() if data is None: data = dict( Query('select name, id from player where name not like "ROBOT %"').records) self._data = data table.setColumnCount(1) table.setRowCount(len(self._data)) table.setHorizontalHeaderLabels([i18n("Player")]) table.setSelectionBehavior(QTableWidget.SelectRows) table.setSelectionMode(QTableWidget.SingleSelection) selectedItem = None for row, name in enumerate(sorted(self._data, key=self.sortKey)): item = QTableWidgetItem(name) if selectedItem is None: selectedItem = item table.setItem(row, 0, item) if name == currentName: selectedItem = item if selectedItem: table.setCurrentItem(selectedItem) table.scrollToItem(selectedItem) self.table.itemChanged.connect(self.itemChanged)
def requestAvatarId(self, cred): # pylint: disable=no-self-use """get user id from database""" cred.username = cred.username.decode('utf-8') args = cred.username.split(SERVERMARK) if len(args) > 1: if args[0] == 'adduser': cred.username = args[1] password = args[2] query = Query( 'insert or ignore into player(name,password) values(?,?)', (cred.username, password)) elif args[1] == 'deluser': pass query = Query('select id, password from player where name=?', (cred.username, )) if not len(query.records): template = 'Wrong username: %1' if Debug.connections: logDebug(i18n(template, cred.username)) return fail( credError.UnauthorizedLogin(srvMessage(template, cred.username))) userid, password = query.records[0] defer1 = maybeDeferred(cred.checkPassword, password.encode('utf-8')) defer1.addCallback(DBPasswordChecker._checkedPassword, userid) return defer1
def notifyAction(self, client, move): if client.beginQuestion or client.game: Sorry(i18n('%1 is not ready to start the game', move.player.name)) if client.beginQuestion: client.beginQuestion.cancel() elif client.game: return client.game.close()
def translateServerMessage(msg): """because a PB exception can not pass a list of arguments, the server encodes them into one string using SERVERMARK as separator. That string is always english. Here we unpack and translate it into the client language.""" if msg.find(SERVERMARK) >= 0: return i18n(*tuple(msg.split(SERVERMARK)[1:-1])) return msg
def itemChanged(self, item): """this must be new because editing is disabled for others""" currentName = item.text() if currentName in self._data: Sorry(i18n('Player %1 already exists', currentName)) self.setFocus() del self._data[self.table.item(self.table.currentRow(), 0).text()] self.updateTable(currentName=currentName) return query = Query('insert into player(name) values(?)', (currentName, )) if query.failure: Sorry( i18n( 'Error while adding player %1: %2', currentName, query.failure.message)) self.updateTable(currentName=currentName)
def __noTilesetFound(cls): """No resources found""" directories = '\n\n' + '\n'.join(cls.__directories()) logException( i18n( 'cannot find any %1 in the following directories, ' 'is libkmahjongg installed?', cls.resourceName) + directories) # TODO: nicht schoen
def __checkExistingConnections(self, dummy=None): """do we already have a connection to the wanted URL?""" for client in self.client.humanClients: if client.connection and client.connection.url == self.url: logWarning( i18n('You are already connected to server %1', self.url)) client.tableList.activateWindow() raise CancelledError