From 4a9608453a6010979e3c99edabeaf2061edd8c49 Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 24 Jul 2012 04:18:54 +0200 Subject: finished up the UI for editing unlocks, and the parser --- src/editorui/paths.py | 11 ++++++--- src/unlock.py | 65 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/editorui/paths.py b/src/editorui/paths.py index a0e65d6..43a1465 100644 --- a/src/editorui/paths.py +++ b/src/editorui/paths.py @@ -593,10 +593,15 @@ class KPEditorPath(QtGui.QGraphicsLineItem): # modify the unlock settings from unlock import KPUnlockSpecDialog - # todo: set the existing thing there - result = KPUnlockSpecDialog.exec_() + dlg = KPUnlockSpecDialog('path', 'unlocked') + + if hasattr(self._pathRef(), 'unlockSpec'): + dlg.setSpec(self._pathRef().unlockSpec) + + result = dlg.exec_() if result == QtGui.QDialog.Accepted: - print "OK!" + print "New spec:", dlg.spec + self._pathRef().unlockSpec = dlg.spec def updatePosition(self): diff --git a/src/unlock.py b/src/unlock.py index 0f954d6..16063ca 100644 --- a/src/unlock.py +++ b/src/unlock.py @@ -54,7 +54,7 @@ def _parseUnlockBit(text): m = COMBINER_RE.match(text, index + 1) if not m: - raise UnlockParseError('something unexpected at %d' % (index+1)) + raise UnlockParseError('something unexpected at position %d' % (index+1)) # what is it? nextCombiner = m.group(1) @@ -64,23 +64,52 @@ def _parseUnlockBit(text): # go right past this, to the next subterm skip = len(m.group(0)) + if (index + skip) == endAt: + raise UnlockParseError('%s what?!' % (whatCombiner.upper())) else: if pLevel == 0: - raise UnlockParseError('something unexpected at %d' % index) + if index == 0: + raise UnlockParseError('that\'s not right') + else: + raise UnlockParseError('something unexpected at position %d' % index) + + if pLevel > 0: + raise UnlockParseError('unclosed parenthesis') # now that we're here, we must have parsed these subterms # do we have a combiner? if whatCombiner is None: - assert len(subTerms) == 1 + if len(subTerms) != 1: + raise UnlockParseError('unclosed parenthesis') return _parseUnlockBit(subTerms[0][2]) else: return (whatCombiner, map(lambda x: _parseUnlockBit(x[2]), subTerms)) +def stringifyUnlockData(data): + kind = data[0] + + if kind == 'always': + return '' + elif kind == 'level': + return '%02d-%02d%s' % (data[1], data[2], (' secret' if data[3] else '')) + elif kind == 'and' or kind == 'or': + return (' %s ' % kind).join(map(lambda x: '(%s)' % stringifyUnlockData(x), data[1])) + if __name__ == '__main__': - print repr(parseUnlockText('((01-01 secret) and (01-02)) or (02-99 secret) or (01-01)')) + p1 = parseUnlockText('((01-01 secret) and (01-02)) or (02-99 secret) or (01-01)') + p2 = parseUnlockText('(1-1 secret) or ((1-2) and (1-3 secret)) or (2-1)') + + print + print repr(p1) + print + print stringifyUnlockData(p1) + print + print repr(p2) + print + print stringifyUnlockData(p2) from sys import exit exit() @@ -109,7 +138,8 @@ class KPUnlockSpecDialog(QtGui.QDialog):
  • (01-01 secret) and (01-02) - combine two criteria
  • ((01-01 secret) or (01-02)) and (01-04) - nested criteria
  • - Each criterion used on the sides of AND and OR must be surrounded by parentheses.
    + Each criterion used on the sides of AND and OR must be surrounded by parentheses. + You may use more than one, for example: (01-01) or (02-02) or (03-03)

    To leave this {0} permanently unlocked, leave the box blank. """.format(forWhat, unlockAdjective) @@ -120,19 +150,38 @@ class KPUnlockSpecDialog(QtGui.QDialog): self.textBox = QtGui.QLineEdit() self.textBox.textChanged.connect(self.checkInputValidity) + self.statusLabel = QtGui.QLabel() + self.statusLabel.setWordWrap(True) + self.buttons = QtGui.QDialogButtonBox( QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) - self.layout = QtGui.VBoxLayout() + self.layout = QtGui.QVBoxLayout() self.layout.addWidget(self.label) self.layout.addWidget(self.textBox) + self.layout.addWidget(self.statusLabel) self.layout.addWidget(self.buttons) self.setLayout(self.layout) + def setSpec(self, spec): + self.textBox.setText(stringifyUnlockData(spec)) + def checkInputValidity(self, text): - self.parsed = parseUnlockText(text) - self.buttons.button(QtGui.QDialogButtonBox.Ok).setEnabled(not (self.parsed is None)) + valid = True + try: + self.spec = parseUnlockText(str(text)) + except UnlockParseError as e: + valid = False + error = str(e) + self.spec = None + + self.buttons.button(QtGui.QDialogButtonBox.Ok).setEnabled(valid) + + if valid: + self.statusLabel.setText('Your input is valid.') + else: + self.statusLabel.setText('[!] %s' % error) -- cgit v1.2.3