Skip to content

Instantly share code, notes, and snippets.

@SpaceManiac
Created December 27, 2012 11:33
Show Gist options
  • Save SpaceManiac/4387574 to your computer and use it in GitHub Desktop.
Save SpaceManiac/4387574 to your computer and use it in GitHub Desktop.
Utils.py from Profile Master for use in formats
# utils.py
# common utilities for profile master format files
from construct import *
from PyQt4 import QtCore, QtGui
import functools
# qt utilities
class Dialog(QtGui.QDialog):
def __init__(self, ui):
QtGui.QDialog.__init__(self)
self.ui = ui()
self.ui.setupUi(self)
self.show()
qconnect = QtGui.QWidget.connect
qsignal = QtCore.SIGNAL
# constructs
class MysteryCounter():
def __init__(self):
self.num = 0
def __call__(self, len):
self.num += 1
return Field("mystery_%d" % self.num, len)
def Finish(self):
self.num += 1
return FinishAdapter(OptionalGreedyRepeater(Field("mystery_%d" % self.num, 1)))
class FinishAdapter(Adapter):
def _decode(self, obj, ctx):
return ''.join(obj)
def _encode(self, obj, ctx):
return list(obj)
class WithContext(Construct):
def __init__(self, func):
Construct.__init__(self, "_WithContext")
self.func = func
def _parse(self, stream, context):
self.func(context)
class NullTerminateAdapter(Adapter):
def _encode(self, obj, ctx):
return obj
def _decode(self, obj, ctx):
idx = obj.find('\x00')
if idx >= 0:
return obj[:obj.find('\x00')]
else:
return obj
def echo(x): print x
def PrintContext():
return WithContext(echo)
def PrintContextItem(field):
return WithContext(lambda ctx: echo(ctx[field]))
def PackedString(name, len=32):
return NullTerminateAdapter(String(name, len, padchar="\x00"))
# editables
class Editable(object):
text = ""
children = None
notes = ""
def edit(self, callback):
return
def construct(self, ctx):
return None
class EditableAdapter(Adapter):
def __init__(self, type, sub):
Adapter.__init__(self, sub)
self.type = type
def _decode(self, obj, ctx):
return self.type(obj, ctx)
def _encode(self, obj, ctx):
return obj.construct(ctx)
class NonEditable(Editable):
def __init__(self, val):
self.val = val
self.text = str(val)
self.notes = "Cannot edit values of type: %s" % type(val).__name__
def edit(self, callback):
return
# base should be some variety of editable, func takes value & ctx, ctx may be None
def NoteWrapper(base, func):
class result(base):
def __init__(self, obj, ctx):
self.dict = {'value': obj}
base.__init__(self, self.dict, 'value')
self.notes = func(obj, ctx)
def edit(self, callback):
self.w_callback_ = callback
base.edit(self, self.w_callback)
def w_callback(self):
self.notes = func(self.dict['value'], None)
self.w_callback_()
def construct(self, ctx):
return self.dict['value']
return result
# enumerations
#class EditEnum(Editable):
# def __init__(self, obj, ctx):
#def EnumWrapper(
# default editables
class DefaultEditable(Editable):
def __init__(self, cont, key):
self.cont = cont
self.key = key
@property
def text(self):
return self.cont[self.key]
class EditBoolean(DefaultEditable):
def edit(self, callback):
self.cont[self.key] = not self.cont[self.key]
callback()
class EditNumber(DefaultEditable):
def edit(self, callback):
from ui.editnumber import Ui_EditNumber
self.type = type(self.cont[self.key])
self.callback = callback
self.dialog = Dialog(Ui_EditNumber)
self.dialog.ui.varLabel.setText(str(self.key))
self.dialog.ui.lineEdit.setText(str(self.cont[self.key]))
self.dialog.ui.errorLabel.setText("")
qconnect(self.dialog.ui.buttonBox, qsignal("accepted()"), self.accept)
def accept(self):
value = str(self.dialog.ui.lineEdit.text())
try:
if self.type == float:
result = self.type(value)
else: # int or long
base = 10
if value.startswith("0x"):
base = 16
value = value[2:]
result = int(value, base)
self.cont[self.key] = result
self.dialog.accept()
self.callback()
except ValueError:
self.dialog.ui.errorLabel.setText("Invalid value")
from texteditor import EditText
defaultEditors = {
bool: EditBoolean,
int: EditNumber,
float: EditNumber,
long: EditNumber,
str: EditText
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment