Exemple #1
0
 def showMoveHelper(self, visible=None):
     """show help text In empty HandBoards"""
     if visible is None:
         visible = not self.uiTiles
     if self.__moveHelper and not isAlive(self.__moveHelper):
         return
     if visible:
         if not self.__moveHelper:
             splitter = QGraphicsRectItem(self)
             hbCenter = self.rect().center()
             splitter.setRect(
                 hbCenter.x() * 0.5,
                 hbCenter.y(),
                 hbCenter.x() * 1,
                 1)
             helpItems = [splitter]
             for name, yFactor in [(m18n('Move Exposed Tiles Here'), 0.5),
                                   (m18n('Move Concealed Tiles Here'), 1.5)]:
                 helper = QGraphicsSimpleTextItem(name, self)
                 helper.setScale(3)
                 nameRect = QRectF()
                 nameRect.setSize(
                     helper.mapToParent(helper.boundingRect()).boundingRect().size())
                 center = QPointF(hbCenter)
                 center.setY(center.y() * yFactor)
                 helper.setPos(center - nameRect.center())
                 if self.sceneRotation() == 180:
                     rotateCenter(helper, 180)
                 helpItems.append(helper)
             self.__moveHelper = self.scene().createItemGroup(helpItems)
         self.__moveHelper.setVisible(True)
     else:
         if self.__moveHelper:
             self.__moveHelper.setVisible(False)
Exemple #2
0
 def toolTip(self, button, dummyTile):
     """decorate 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(m18n('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(m18n(
                 'claiming %1 is dangerous because you will have to discard a dangerous tile',
                 lastDiscard.name()))
         else:
             for meld in dangerousMelds:
                 txt.append(m18n(
                     'claiming %1 for %2 is dangerous because you will have to discard a dangerous tile',
                     lastDiscard.name(), str(meld)))
     if not txt:
         txt = [m18n('You may say %1', self.i18nName)]
     return '<br><br>'.join(txt), warn, ''
Exemple #3
0
 def refresh(self):
     """refresh for new values"""
     lines = []
     if self.game is None:
         lines.append(m18n("There is no active game"))
     else:
         i18nName = m18n(self.game.ruleset.name)
         lines.append(m18n("%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(m18n("Manual score for %1: %2 points", player.localName, player.handTotal))
             if pLines:
                 pLines.append("")
             lines.extend(pLines)
     if "xxx".join(lines) != "xxx".join(unicode(x) for x in self.model.stringList()):
         # QStringListModel does not optimize identical lists away, so we do
         self.model.setStringList(lines)
Exemple #4
0
    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(
            m18nc('define a new player',
                  "&New"),
            QDialogButtonBox.ActionRole)
        self.newButton.setIcon(KIcon("document-new"))
        self.newButton.clicked.connect(self.slotInsert)
        self.deleteButton = self.buttonBox.addButton(
            m18n("&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, m18n("Players"))
        self.setObjectName('Players')
Exemple #5
0
 def tooltip(self):
     """tooltip for rule: just the name of the ruleset"""
     ruleset = self.ruleset()
     if self.rawContent.description:
         return u'<b>' + m18n(ruleset.name) + u'</b><br><br>' + \
             m18n(self.rawContent.description)
     else:
         return m18n(ruleset.name)
Exemple #6
0
 def __init__(self, swappers):
     QMessageBox.__init__(self)
     decorateWindow(self, m18n("Swap Seats"))
     self.setText(
         m18n("By the rules, %1 and %2 should now exchange their seats. ",
              swappers[0].name, swappers[1].name))
     self.yesAnswer = QPushButton(m18n("&Exchange"))
     self.addButton(self.yesAnswer, QMessageBox.YesRole)
     self.noAnswer = QPushButton(m18n("&Keep seat"))
     self.addButton(self.noAnswer, QMessageBox.NoRole)
Exemple #7
0
 def name(self):
     """returns name of a single tile"""
     if self.group.lower() == Tile.wind:
         result = {
             East: m18n("East Wind"),
             South: m18n("South Wind"),
             West: m18n("West Wind"),
             North: m18n("North Wind"),
         }[self.value]
     else:
         result = m18nc("kajongg tile name", "{group} {value}")
     return result.format(value=self.valueName(), group=self.groupName())
Exemple #8
0
    def __init__(self, desktopFileName=None):
        if desktopFileName is None:
            desktopFileName = 'default'
        self.__svg = None
        self.__pmap = None
        QPixmapCache.setCacheLimit(20480)  # the chinese landscape needs much
        self.defineCatalog()
        self.desktopFileName = desktopFileName
        self.path = locatebackground(desktopFileName + '.desktop')
        if self.path.isEmpty():
            self.path = locatebackground('default.desktop')
            if self.path.isEmpty():
                directories = '\n\n' + \
                    '\n'.join(str(x)
                              for x in KGlobal.dirs().resourceDirs("kmahjonggbackground"))
                logException(BackgroundException(m18n(
                    'cannot find any background in the following directories, is libkmahjongg installed?')
                                                 + directories))
            else:
                logWarning(
                    m18n(
                        'cannot find background %1, using default',
                        desktopFileName))
                self.desktopFileName = 'default'
        config = KConfig(self.path)
        group = config.group("KMahjonggBackground")
        self.name = group.readEntry("Name") or m18n("unknown background")

        # Version control
        backgroundversion = int(group.readEntry("VersionFormat")) or 0
        # Format is increased when we have incompatible changes, meaning that
        # older clients are not able to use the remaining information safely
        if backgroundversion > BACKGROUNDVERSIONFORMAT:
            logException(BackgroundException('backgroundversion file / program: %d/%d' %
                                             (backgroundversion, BACKGROUNDVERSIONFORMAT)))

        self.tiled = group.readEntry('Tiled') == '1'
        if self.tiled:
            self.imageWidth, entryOk = group.readEntry('Width').toInt()
            if not entryOk:
                raise Exception('cannot scan Width from background file')
            self.imageHeight, entryOk = group.readEntry('Height').toInt()
            if not entryOk:
                raise Exception('cannot scan Height from background file')
        self.isPlain = bool(group.readEntry('Plain'))
        if not self.isPlain:
            graphName = QString(group.readEntry("FileName"))
            self.__graphicspath = locatebackground(graphName)
            if self.__graphicspath.isEmpty():
                logException(BackgroundException(
                    'cannot find kmahjongglib/backgrounds/%s for %s' %
                    (graphName, self.desktopFileName)))
Exemple #9
0
    def __init__(self, parent=None):
        super(Games, self).__init__(parent)
        self.selectedGame = None
        self.onlyPending = True
        decorateWindow(self, m18nc('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(
            m18nc('start a new game', "&New"), QDialogButtonBox.ActionRole)
        self.newButton.setIcon(KIcon("document-new"))
        self.newButton.clicked.connect(self.accept)
        self.loadButton = self.buttonBox.addButton(
            m18n("&Load"), QDialogButtonBox.AcceptRole)
        self.loadButton.clicked.connect(self.loadGame)
        self.loadButton.setIcon(KIcon("document-open"))
        self.deleteButton = self.buttonBox.addButton(
            m18n("&Delete"), QDialogButtonBox.ActionRole)
        self.deleteButton.setIcon(KIcon("edit-delete"))
        self.deleteButton.clicked.connect(self.delete)

        chkPending = QCheckBox(m18n("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)
Exemple #10
0
 def toolTip(self, button, tile):
     """decorate 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 = m18n(
             'discarding %1 and declaring Original Call makes this hand unwinnable',
             tile.name())
         return txt, True, txt
     else:
         return (m18n(
             '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, '')
Exemple #11
0
 def __init__(self, parent, name):
     # pylint: disable=super-init-not-called
     KConfigDialog.__init__(
         self, parent, QString(name), Internal.Preferences)
     StateSaver(self)
     self.pages = [
         self.addPage(
             PlayConfigTab(self),
             m18nc('kajongg', 'Play'), "arrow-right"),
         self.addPage(
             TilesetSelector(self),
             m18n("Tiles"), "games-config-tiles"),
         self.addPage(
             BackgroundSelector(self),
             m18n("Backgrounds"), "games-config-background")]
Exemple #12
0
 def headerData(self, section, orientation, role):
     """tell the view about the wanted headers"""
     if role == Qt.TextAlignmentRole:
         if orientation == Qt.Horizontal:
             return toQVariant(int(Qt.AlignLeft | Qt.AlignVCenter))
     if role != Qt.DisplayRole:
         return toQVariant()
     if orientation == Qt.Horizontal:
         if section == 0:
             return toQVariant(m18nc("Kajongg", "Rule"))
         if section == 1:
             return toQVariant(m18n(self.view.cbRuleset1.current.name))
         if section == 2:
             return toQVariant(m18n(self.view.cbRuleset2.current.name))
         return toQVariant()
Exemple #13
0
 def remote_tableRemoved(self, tableid, message, *args):
     """update table list"""
     Client.remote_tableRemoved(self, tableid, message, *args)
     self.__updateTableList()
     if message:
         if self.name not in args or not message.endswith('has logged out'):
             logWarning(m18n(message, *args))
Exemple #14
0
 def notifyAction(self, client, move):
     if client.beginQuestion or client.game:
         Sorry(m18n('%1 is not ready to start the game', move.player.name))
     if client.beginQuestion:
         client.beginQuestion.cancel()
     elif client.game:
         return client.game.close()
Exemple #15
0
 def toolTip(self, button, dummyTile):
     """decorate 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(
             m18n('saying Kong for %1 violates Original Call',
                  Tile(maySay[0][0]).name()))
     if not txt:
         txt = [m18n('You may say Kong for %1', Tile(maySay[0][0]).name())]
     return '<br><br>'.join(txt), warn, ''
Exemple #16
0
 def _saveScores(self):
     """save computed values to database,
     update score table and balance in status line"""
     scoretime = datetime.datetime.now().replace(microsecond=0).isoformat()
     logMessage = u''
     for player in self.players:
         if player.hand:
             manualrules = '||'.join(x.rule.name
                                     for x in player.hand.usedRules)
         else:
             manualrules = m18n('Score computed manually')
         Query(
             "INSERT INTO SCORE "
             "(game,hand,data,manualrules,player,scoretime,won,prevailing,"
             "wind,points,payments, balance,rotated,notrotated) "
             "VALUES(%d,%d,?,?,%d,'%s',%d,'%s','%s',%d,%d,%d,%d,%d)" %
             (self.gameid, self.handctr, player.nameid,
              scoretime, int(player == self.__winner),
              self.roundWind.char, player.wind,
              player.handTotal, player.payment, player.balance,
              self.rotated, self.notRotated),
             (player.hand.string, manualrules))
         logMessage += u'{player:<12} {hand:>4} {total:>5} {won} | '.format(
             player=unicode(player)[:12], hand=player.handTotal,
             total=player.balance,
             won='WON' if player == self.winner else '   ')
         for usedRule in player.hand.usedRules:
             rule = usedRule.rule
             if rule.score.limits:
                 self.addCsvTag(rule.name.replace(' ', ''))
     if Debug.scores:
         self.debug(logMessage)
Exemple #17
0
    def __init__(self):
        SelectRuleset.__init__(self)
        Players.load()
        decorateWindow(self, m18n('Select four players'))
        self.names = None
        self.nameWidgets = []
        for idx, wind in enumerate(Wind.all4):
            cbName = QComboBox()
            cbName.manualSelect = False
            # increase width, we want to see the full window title
            cbName.setMinimumWidth(350)  # is this good for all platforms?
            cbName.addItems(list(Players.humanNames.values()))
            self.grid.addWidget(cbName, idx + 1, 1)
            self.nameWidgets.append(cbName)
            self.grid.addWidget(WindLabel(wind), idx + 1, 0)
            cbName.currentIndexChanged.connect(self.slotValidate)

        query = Query(
            "select p0,p1,p2,p3 from game where seed is null and game.id = (select max(id) from game)")
        if len(query.records):
            with BlockSignals(self.nameWidgets):
                for cbName, playerId in zip(self.nameWidgets, query.records[0]):
                    try:
                        playerName = Players.humanNames[playerId]
                        playerIdx = cbName.findText(playerName)
                        if playerIdx >= 0:
                            cbName.setCurrentIndex(playerIdx)
                    except KeyError:
                        logError(u'database is inconsistent: player with id %d is in game but not in player'
                                 % playerId)
        self.slotValidate()
Exemple #18
0
 def __getName(playerid):
     """get name for playerid
     """
     try:
         return Players.allNames[playerid]
     except KeyError:
         return m18n('Player %1 not known', playerid)
Exemple #19
0
 def __upgrade(self):
     """upgrade the structure of an existing kajongg database"""
     try:
         Internal.db = DBHandle(self.path)
         if isPython3:
             allVersions = list(['4.13.0', '8300'])
         else:
             allVersions = list(['4.13.0', '8200'])
         assert allVersions[-1] == str(Internal.defaultPort), '{} != {}'.format(
             allVersions[-1], str(Internal.defaultPort))
         # skip versions before current db versions:
         currentVersion = self.__currentVersion()
         while allVersions and allVersions[0] <= currentVersion:
             allVersions = allVersions[1:]
         for version in allVersions:
             currentVersion = self.__currentVersion()
             with Internal.db:  # transaction
                 updateMethodName = 'updateToVersion{}'.format(version.replace('.', '_'))
                 if hasattr(self, updateMethodName):
                     getattr(self, updateMethodName)()
                 Query('UPDATE general SET schemaversion=?', (version,))
             logInfo(m18n('Database %1 updated from schema %2 to %3',
                          Internal.db.path, currentVersion, version), showDialog=True)
     except sqlite3.Error as exc:
         logException(
             u'opening %s: %s' %
             (unicodeString(self.path), exc.message))
     finally:
         Internal.db.close(silent=True)
Exemple #20
0
 def tableChanged(self, table):
     """update table list"""
     oldTable, newTable = Client.tableChanged(self, table)
     if oldTable and oldTable == self.table:
         # this happens if a table has more than one human player and
         # one of them leaves the table. In that case, the other players
         # need this code.
         self.table = newTable
         if len(newTable.playerNames) == 3:
             # only tell about the first player leaving, because the
             # others will then automatically leave too
             for name in oldTable.playerNames:
                 if name != self.name and not newTable.isOnline(name):
                     def sorried(dummy):
                         """user ack"""
                         game = self.game
                         if game:
                             self.game = None
                             return game.close()
                     if self.beginQuestion:
                         self.beginQuestion.cancel()
                     Sorry(m18n('Player %1 has left the table', name)).addCallback(
                         sorried).addCallback(self.showTableList)
                     break
     self.__updateTableList()
Exemple #21
0
 def data(self, index, role=Qt.DisplayRole):
     """score table"""
     result = toQVariant()
     if role == Qt.TextAlignmentRole:
         if index.column() == 1:
             return toQVariant(int(Qt.AlignRight))
         else:
             return toQVariant(int(Qt.AlignLeft))
     if index.isValid() and (0 <= index.row() < len(self.chatLines)):
         chatLine = self.chatLines[index.row()]
         if role == Qt.DisplayRole and index.column() == 0:
             local = chatLine.localtimestamp()
             result = toQVariant('%02d:%02d:%02d' % (
                 local.hour,
                 local.minute,
                 local.second))
         elif role == Qt.DisplayRole and index.column() == 1:
             result = toQVariant(chatLine.fromUser)
         elif role == Qt.DisplayRole and index.column() == 2:
             result = toQVariant(m18n(chatLine.message))
         elif role == Qt.ForegroundRole and index.column() == 2:
             palette = KApplication.palette() # pylint: disable=no-member
             color = 'blue' if chatLine.isStatusMessage else palette.windowText(
             )
             result = toQVariant(QColor(color))
     return result
Exemple #22
0
 def headerData(self, section, orientation, role=Qt.DisplayRole):  # pylint: disable=no-self-use
     """show header"""
     if role == Qt.TextAlignmentRole:
         if orientation == Qt.Horizontal:
             if section == 1:
                 return toQVariant(int(Qt.AlignRight))
             else:
                 return toQVariant(int(Qt.AlignLeft))
     if orientation != Qt.Horizontal:
         return toQVariant(int(section + 1))
     if role != Qt.DisplayRole:
         return toQVariant()
     result = ''
     if section < self.columnCount():
         result = [m18n('Time'), m18n('Player'), m18n('Message')][section]
     return toQVariant(result)
Exemple #23
0
 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([m18n("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)
Exemple #24
0
 def __init__(self, scene=None, table=None):
     super(ChatWindow, self).__init__(None)
     self.scene = scene
     self.table = table or scene.game.client.table
     self.table.chatWindow = self
     self.setObjectName('chatWindow')
     title = m18n(
         'Chat on table %1 at %2',
         self.table.tableid,
         self.table.client.connection.url)
     decorateWindow(self, title)
     self.messageView = ChatView()
     self.messageView.setModel(ChatModel())
     self.messageView.setFocusPolicy(Qt.NoFocus)
     self.messageView.setShowGrid(False)
     self.messageView.setWordWrap(False)
     self.messageView.setSelectionMode(QAbstractItemView.NoSelection)
     if Debug.modelTest:
         self.debugModelTest = ModelTest(
             self.messageView.model(),
             self.messageView)
     self.edit = QLineEdit()
     layout = QVBoxLayout()
     layout.addWidget(self.messageView)
     layout.addWidget(self.edit)
     self.setLayout(layout)
     self.edit.returnPressed.connect(self.sendLine)
     self.edit.setFocus()
     self.show()
     StateSaver(self)
Exemple #25
0
 def renderer(self):
     """initialise the svg renderer with the selected svg file"""
     if self.__renderer is None:
         self.__renderer = QSvgRenderer(self.__graphicspath)
         if not self.__renderer.isValid():
             logException(TileException(
                 m18n(
                     'file <filename>%1</filename> contains no valid SVG'),
                 self.__graphicspath))
         distance = 0
         if self.desktopFileName == 'classic':
             distance = 2
         distanceSize = QSizeF(distance, distance)
         self.faceSize = self.__renderer.boundsOnElement(
             'BAMBOO_1').size() + distanceSize
         self.tileSize = self.__renderer.boundsOnElement(
             'TILE_2').size() + distanceSize
         if not Internal.scaleScene:
             self.faceSize /= 2
             self.tileSize /= 2
         shW = self.shadowWidth()
         shH = self.shadowHeight()
         self.__shadowOffsets = [
             [(-shW, 0), (0, 0), (0, shH), (-shH, shW)],
             [(0, 0), (shH, 0), (shW, shH), (0, shW)],
             [(0, -shH), (shH, -shW), (shW, 0), (0, 0)],
             [(-shW, -shH), (0, -shW), (0, 0), (-shH, 0)]]
     return self.__renderer
Exemple #26
0
 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 = m18n("Final scores for game <numid>%1</numid>", gameid)
     else:
         title = m18n("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)
     if usingQt5:
         self.viewRight.header().setSectionResizeMode(QHeaderView.Fixed)
     else:
         self.viewRight.header().setResizeMode(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)
Exemple #27
0
 def addManualRules(self):
     """those are actually winner rules but in the kajongg scoring mode they must be selected manually"""
     # applicable only if we have a concealed meld and a declared kong:
     self.winnerRules.createRule(
         'Last Tile Taken from Dead Wall',
         'FLastTileFromDeadWall||Olastsource=e', doubles=1,
         description=m18n('The dead wall is also called kong box: The last 16 tiles of the wall '
                          'used as source of replacement tiles'))
     self.winnerRules.createRule(
         'Last Tile is Last Tile of Wall',
         'FIsLastTileFromWall||Olastsource=z', doubles=1,
         description=m18n('Winner said Mah Jong with the last tile taken from the living end of the wall'))
     self.winnerRules.createRule(
         'Last Tile is Last Tile of Wall Discarded',
         'FIsLastTileFromWallDiscarded||Olastsource=Z', doubles=1,
         description=m18n('Winner said Mah Jong by claiming the last tile taken from the living end of the '
                          'wall, discarded by another player'))
     self.winnerRules.createRule(
         'Robbing the Kong', r'FRobbingKong||Olastsource=k', doubles=1,
         description=m18n('Winner said Mah Jong by claiming the 4th tile of a kong another player '
                          'just declared'), debug=True)
     self.winnerRules.createRule(
         'Mah Jongg with Original Call',
         'FMahJonggWithOriginalCall||Oannouncements=a', doubles=1,
         description=m18n(
             'Just before the first discard, a player can declare Original Call meaning she needs only one '
             'tile to complete the hand and announces she will not alter the hand in any way (except bonus tiles)'))
     self.winnerRules.createRule(
         'Dangerous Game', 'FDangerousGame||Opayforall',
         description=m18n('In some situations discarding a tile that has a high chance to help somebody to win '
                          'is declared to be dangerous, and if that tile actually makes somebody win, the discarder '
                          'pays the winner for all'))
     self.winnerRules.createRule(
         'Twofold Fortune', 'FTwofoldFortune||Oannouncements=t',
         limits=1, description=m18n('Kong after Kong: Declare Kong and a second Kong with the replacement '
                                    'tile and Mah Jong with the second replacement tile'))
     # limit hands:
     self.winnerRules.createRule(
         'Blessing of Heaven', 'FBlessingOfHeaven||Olastsource=1', limits=1,
         description=m18n('East says Mah Jong with the unmodified dealt tiles'))
     self.winnerRules.createRule(
         'Blessing of Earth', 'FBlessingOfEarth||Olastsource=1', limits=1,
         description=m18n('South, West or North says Mah Jong with the first tile discarded by East'))
     self.winnerRules.createRule(
         'East won nine times in a row', 'FEastWonNineTimesInARow||Orotate', limits=1,
         description=m18n('If that happens, East gets a limit score and the winds rotate'))
Exemple #28
0
 def itemChanged(self, item):
     """this must be new because editing is disabled for others"""
     currentName = unicode(item.text())
     if currentName in self._data:
         Sorry(m18n('Player %1 already exists', currentName))
         self.setFocus()
         del self._data[
             unicode(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(
             m18n(
                 'Error while adding player %1: %2',
                 currentName,
                 query.failure.message))
     self.updateTable(currentName=currentName)
Exemple #29
0
 def __noTilesetFound():
     """No tilesets found"""
     directories = '\n'.join(
         str(x) for x in KGlobal.dirs().resourceDirs("kmahjonggtileset"))
     directories = '\n\n' + directories
     logException(
         TileException(m18n(
             'cannot find any tileset in the following directories, '
             'is libkmahjongg installed?') + directories))
Exemple #30
0
 def __init__(self, scene):
     QListView.__init__(self)
     self.scene = scene
     decorateWindow(self, m18n("Explain Scores").replace("&", ""))
     self.setGeometry(0, 0, 300, 400)
     self.model = QStringListModel()
     self.setModel(self.model)
     StateSaver(self)
     self.refresh()