You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(45) |
May
(185) |
Jun
|
Jul
(36) |
Aug
(205) |
Sep
(98) |
Oct
(107) |
Nov
(6) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(1) |
Feb
(2) |
Mar
(19) |
Apr
(26) |
May
(18) |
Jun
|
Jul
(12) |
Aug
(16) |
Sep
(22) |
Oct
(7) |
Nov
(11) |
Dec
(74) |
2006 |
Jan
(14) |
Feb
(1) |
Mar
(3) |
Apr
(3) |
May
(14) |
Jun
(5) |
Jul
(20) |
Aug
(10) |
Sep
(1) |
Oct
|
Nov
(4) |
Dec
(1) |
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
(14) |
Aug
|
Sep
|
Oct
(6) |
Nov
(1) |
Dec
|
From: Kevin A. <ka...@us...> - 2004-10-04 19:03:47
|
Update of /cvsroot/pythoncard/PythonCard/samples/testNotebook In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4570/testNotebook Modified Files: widgets.rsrc.py Log Message: removed 'position' attribute in Background of resource Index: widgets.rsrc.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/samples/testNotebook/widgets.rsrc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** widgets.rsrc.py 14 Sep 2004 17:28:46 -0000 1.1 --- widgets.rsrc.py 4 Oct 2004 19:03:10 -0000 1.2 *************** *** 5,9 **** 'name':'bgWidgets', 'title':'Widgets Test', - 'position':(5, 5), 'size':(800, 600), --- 5,8 ---- |
From: Alex T. <ale...@us...> - 2004-10-04 00:06:41
|
Update of /cvsroot/pythoncard/PythonCard/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12027 Modified Files: changelog.txt Log Message: Record the addition of the experimental 'oneEditor' Index: changelog.txt =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/docs/changelog.txt,v retrieving revision 1.312 retrieving revision 1.313 diff -C2 -d -r1.312 -r1.313 *** changelog.txt 3 Oct 2004 18:53:21 -0000 1.312 --- changelog.txt 4 Oct 2004 00:06:27 -0000 1.313 *************** *** 8,11 **** --- 8,12 ---- Release 0.8.1 2004-10-?? + added work-in-progress version of tabbed code editor (tools/oneEditor) renamed ver to VERSION_STRING in __version__.py and added VERSION tuple added horizontalScrollbar flag to TextArea component |
From: Alex T. <ale...@us...> - 2004-10-04 00:04:36
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11506 Modified Files: tabcodeEditor.py Log Message: Remove debug print statement of 'page' Index: tabcodeEditor.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/oneEditor/tabcodeEditor.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** tabcodeEditor.py 3 Oct 2004 23:58:01 -0000 1.1 --- tabcodeEditor.py 4 Oct 2004 00:04:00 -0000 1.2 *************** *** 459,463 **** def doExit(self): for page in self.pages: - print page doc = page.components.document if doc.GetModify(): --- 459,462 ---- |
From: Alex T. <ale...@us...> - 2004-10-03 23:58:13
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/templates In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10092/templates Added Files: dialogTemplate.py dialogTemplate.rsrc.py template.py template.rsrc.py templateFullMenus.py templateFullMenus.rsrc.py templateNoMenus.py templateNoMenus.rsrc.py Log Message: Initial version of a tabbed code editor, with associated (future) resource editor --- NEW FILE: templateFullMenus.rsrc.py --- { 'application':{ 'type':'Application', 'name':'Template', 'backgrounds': [ { 'type':'Background', 'name':'bgTemplate', 'title':'Standard Template with full menus', 'size':( 400, 300 ), 'style':['resizeable'], 'statusBar':1, 'menubar': { 'type':'MenuBar', 'menus': [ { 'type':'Menu', 'name':'menuFile', 'label':'&File', 'items': [ { 'type':'MenuItem', 'name':'menuFileNew', 'label':'&New\tCtrl+N' }, { 'type':'MenuItem', 'name':'menuFileOpen', 'label':'&Open\tCtrl+O' }, { 'type':'MenuItem', 'name':'menuFileSave', 'label':'&Save\tCtrl+S' }, { 'type':'MenuItem', 'name':'menuFileSaveAs', 'label':'Save &As...' }, { 'type':'MenuItem', 'name':'fileSep1', 'label':'-' }, { 'type':'MenuItem', 'name':'menuFilePageSetup', 'label':'Page Set&up...' }, { 'type':'MenuItem', 'name':'menuFilePrint', 'label':'&Print...\tCtrl+P' }, { 'type':'MenuItem', 'name':'menuFilePrintPreview', 'label':'Print Pre&view' }, { 'type':'MenuItem', 'name':'fileSep2', 'label':'-' }, { 'type':'MenuItem', 'name':'menuFileExit', 'label':'E&xit\tAlt+X', 'command':'exit', } ] }, # most of the edit menu was copied from the searchexplorer sample {'type':'Menu', 'name':'Edit', 'label':'&Edit', 'items': [ { 'type':'MenuItem', 'name':'menuEditUndo', 'label':'&Undo\tCtrl+Z'}, { 'type':'MenuItem', 'name':'menuEditRedo', 'label':'&Redo\tCtrl+Y'}, { 'type':'MenuItem', 'name':'editSep1', 'label':'-' }, { 'type':'MenuItem', 'name':'menuEditCut', 'label':'Cu&t\tCtrl+X'}, { 'type':'MenuItem', 'name':'menuEditCopy', 'label':'&Copy\tCtrl+C'}, { 'type':'MenuItem', 'name':'menuEditPaste', 'label':'&Paste\tCtrl+V'}, { 'type':'MenuItem', 'name':'editSep2', 'label':'-' }, { 'type':'MenuItem', 'name':'menuEditClear', 'label':'Cle&ar\tDel'}, { 'type':'MenuItem', 'name':'menuEditSelectAll', 'label':'Select A&ll\tCtrl+A'} ] }, { 'type':'Menu', 'name':'menuHelp', 'label':'&Help', 'items': [ { 'type':'MenuItem', 'name':'menuHelpAbout', 'label':'&About ...', 'command':'doHelpAbout'}, ] }, ] }, 'components': [ ] } ] } } --- NEW FILE: template.py --- #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:02 $" """ from PythonCard import model class MyBackground(model.Background): def on_initialize(self, event): # if you have any initialization # including sizer setup, do it here pass if __name__ == '__main__': app = model.Application(MyBackground) app.MainLoop() --- NEW FILE: dialogTemplate.rsrc.py --- {'type':'CustomDialog', 'name':'Template', 'title':'Dialog Template', 'size':(300, 100), 'style':['resizeable'], 'components': [ {'type':'Button', 'name':'btnOK', 'position':(10, 35), 'label':'OK', 'id':5100, 'default':1, }, {'type':'Button', 'name':'btnCancel', 'position':(100, 35), 'label':'Cancel', 'id':5101, }, ] # end components } # end CustomDialog --- NEW FILE: templateNoMenus.py --- #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:02 $" """ from PythonCard import model class MyBackground(model.Background): def on_initialize(self, event): # if you have any initialization # including sizer setup, do it here pass if __name__ == '__main__': app = model.Application(MyBackground) app.MainLoop() --- NEW FILE: templateNoMenus.rsrc.py --- { 'application':{ 'type':'Application', 'name':'Template', 'backgrounds': [ { 'type':'Background', 'name':'bgTemplate', 'title':'Standard Template with no menus', 'size':( 400, 300 ), 'components': [ ] } ] } } --- NEW FILE: dialogTemplate.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:02 $" """ from PythonCard import model class MyDialog(model.CustomDialog): def __init__(self, parent, txt=''): model.CustomDialog.__init__(self, parent) # if some special setup is necessary, do it here # example from samples/dialogs/minimalDialog.py # self.components.field1.text = txt #def myDialog(parent, txt): def myDialog(parent): dlg = MyDialog(parent, txt) result = dlg.showModal() # stick your results into the result dictionary here # example from samples/dialogs/minimalDialog.py # result.text = dlg.components.field1.text dlg.destroy() return result --- NEW FILE: templateFullMenus.py --- #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:02 $" """ import os, sys import wx from wx.html import HtmlEasyPrinting from PythonCard import configuration, dialog, model def textToHtml(txt): # the wxHTML classes don't require valid HTML # so this is enough html = txt.replace('\n\n', '<P>') html = html.replace('\n', '<BR>') return html class MyBackground(model.Background): def on_initialize(self, event): # if you have any initialization # including sizer setup, do it here self.printer = HtmlEasyPrinting() # self.loadConfig() self.startTitle = self.title self.newFile() def loadConfig(self): pass def saveConfig(self): pass def saveChanges(self): # save configuration info in the app directory #filename = os.path.basename(self.documentPath) if self.documentPath is None: filename = "Untitled" else: filename = self.documentPath msg = "The text in the %s file has changed.\n\nDo you want to save the changes?" % filename result = dialog.messageDialog(self, msg, 'textEditor', wx.ICON_EXCLAMATION | wx.YES_NO | wx.CANCEL) return result.returnedString def doExit(self): if self.documentChanged: save = self.saveChanges() if save == "Cancel": return False elif save == "No": return True else: if self.documentPath is None: return self.on_menuFileSaveAs_select(None) else: self.saveFile(self.documentPath) return True else: return 1 def on_close(self, event): if self.doExit(): # self.saveConfig() self.fileHistory = None self.printer = None event.skip() def on_menuFileSave_select(self, event): if self.documentPath is None: # this a "new" document and needs to go through Save As... self.on_menuFileSaveAs_select(None) else: self.saveFile(self.documentPath) def on_menuFileSaveAs_select(self, event): wildcard = "Text files (*.txt)|*.TXT;*.txt|All files (*.*)|*.*" if self.documentPath is None: dir = '' filename = '*.txt' else: dir = os.path.dirname(self.documentPath) filename = os.path.basename(self.documentPath) result = dialog.saveFileDialog(None, "Save As", dir, filename, wildcard) if result.accepted: path = result.paths[0] self.saveFile(path) return True else: return False def newFile(self): # change the code below for # creating a new document # the commented line is from the textEditor tool # self.components.fldDocument.text = '' self.documentPath = None self.documentChanged = 0 self.title = 'Untitled - ' + self.startTitle self.statusBar.text = 'Untitled' def openFile(self, path): # change the code below for # opening an existing document # the commented lines are from the textEditor tool try: # f = open(path) # self.components.fldDocument.text = f.read().replace('\r\n','\n') # f.close() self.documentPath = path self.documentChanged = 0 self.title = os.path.split(path)[-1] + ' - ' + self.startTitle self.statusBar.text = path except: pass def saveFile(self, path): # change the code below for # saving an existing document # the commented lines are from the textEditor tool try: # f = open(path, 'w') # f.write(self.components.fldDocument.text) # f.close() self.documentPath = path self.documentChanged = False self.title = os.path.split(path)[-1] + ' - ' + self.startTitle self.statusBar.text = path except: pass def on_menuFileNew_select(self, event): if self.documentChanged: save = self.saveChanges() if save == "Cancel": # don't do anything, just go back to editing pass elif save == "No": # any changes will be lost self.newFile() else: if self.documentPath is None: if self.on_menuFileSaveAs_select(None): self.newFile() else: self.saveFile(self.documentPath) self.newFile() else: # don't need to save self.newFile() def on_menuFileOpen_select(self, event): # should probably have an alert dialog here # warning about saving the current file before opening another one if self.documentChanged: save = self.saveChanges() if save == "Cancel": # don't do anything, just go back to editing return elif save == "No": # any changes will be lost pass else: if self.documentPath is None: # if the user cancels out of the Save As then go back to editing if not self.on_menuFileSaveAs_select(None): return else: self.saveFile(self.documentPath) # split this method into several pieces to make it more flexible wildcard = "Text files (*.txt)|*.txt;*.TXT|All files (*.*)|*.*" result = dialog.openFileDialog(wildcard=wildcard) if result.accepted: path = result.paths[0] # an error will probably occur here if the text is too large # to fit in the wxTextCtrl (TextArea) or the file is actually # binary. Not sure what happens with CR/LF versus CR versus LF # line endings either self.openFile(path) def on_menuFilePrint_select(self, event): # put your code here for print # the commented code below is from the textEditor tool # and is simply an example #source = textToHtml(self.components.fldDocument.text) #self.printer.PrintText(source) pass def on_menuFilePrintPreview_select(self, event): # put your code here for print preview # the commented code below is from the textEditor tool # and is simply an example #source = textToHtml(self.components.fldDocument.text) #self.printer.PreviewText(source) pass def on_menuFilePageSetup_select(self, event): self.printer.PageSetup() # the following was copied and pasted from the searchexplorer sample def on_menuEditUndo_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.canUndo(): widget.undo() def on_menuEditRedo_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.canRedo(): widget.redo() def on_menuEditCut_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.canCut(): widget.cut() def on_menuEditCopy_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.canCopy(): widget.copy() def on_menuEditPaste_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.canPaste(): widget.paste() def on_menuEditClear_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable'): if widget.canCut(): # delete the current selection, # if we can't do a Cut we shouldn't be able to delete either # which is why i used the test above sel = widget.replaceSelection('') else: ins = widget.getInsertionPoint() try: widget.replace(ins, ins + 1, '') except: pass def on_menuEditSelectAll_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable'): widget.setSelection(0, widget.getLastPosition()) def on_doHelpAbout_command(self, event): # put your About box here pass if __name__ == '__main__': app = model.Application(MyBackground) app.MainLoop() --- NEW FILE: template.rsrc.py --- { 'application':{ 'type':'Application', 'name':'Template', 'backgrounds': [ { 'type':'Background', 'name':'bgTemplate', 'title':'Standard Template with File->Exit menu', 'size':( 400, 300 ), 'style':['resizeable'], 'statusBar':0, 'menubar': { 'type':'MenuBar', 'menus': [ { 'type':'Menu', 'name':'menuFile', 'label':'&File', 'items': [ { 'type':'MenuItem', 'name':'menuFileExit', 'label':'E&xit', 'command':'exit', } ] } ] }, 'components': [ ] } ] } } |
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10092/modules Added Files: __init__.py backgroundInfoDialog.py backgroundInfoDialog.rsrc.py colorizer.py dialogInfoDialog.py dialogInfoDialog.rsrc.py menuDialog.py menuDialog.rsrc.py newComponentDialog.py newComponentDialog.rsrc.py propertyEditor.py propertyEditor.rsrc.py resourceOutput.py scriptutils.py stackInfoDialog.py stackInfoDialog.rsrc.py stringDialog.py stringDialog.rsrc.py Log Message: Initial version of a tabbed code editor, with associated (future) resource editor --- NEW FILE: backgroundInfoDialog.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ from PythonCard import dialog, model, util import os class BackgroundInfoDialog(model.CustomDialog): def __init__(self, aBg, rsrc): model.CustomDialog.__init__(self, aBg) self.parent = aBg # if some special setup is necessary, do it here self.components.fldName.text = rsrc.name self.components.fldTitle.text = rsrc.title self.components.fldPosition.text = str(rsrc.position) self.components.fldSize.text = str(rsrc.size) self.components.chkStatusBar.checked = rsrc.statusBar if rsrc.foregroundColor is not None: #self.components.fldForegroundColor.text = colorDescription(rsrc.foregroundColor) self.components.fldForegroundColor.text = str(rsrc.foregroundColor) if rsrc.backgroundColor is not None: #self.components.fldBackgroundColor.text = colorDescription(rsrc.backgroundColor) self.components.fldBackgroundColor.text = str(rsrc.backgroundColor) if rsrc.image is not None: self.components.fldImage.text = rsrc.image self.components.chkTiled.checked = rsrc.tiled self.components.chkVisible.checked = rsrc.visible self.components.chkResizeable.checked = (rsrc.style != []) if rsrc.icon is not None: self.components.fldIcon.text = rsrc.icon def on_btnForegroundColor_mouseClick(self, event): result = dialog.colorDialog(self, color=util.colorFromString(self.components.fldForegroundColor.text)) if result.accepted: self.components.fldForegroundColor.text = str(result.color) def on_btnBackgroundColor_mouseClick(self, event): result = dialog.colorDialog(self, color=util.colorFromString(self.components.fldBackgroundColor.text)) if result.accepted: self.components.fldBackgroundColor.text = str(result.color) def on_btnFile_mouseClick(self, event): result = dialog.openFileDialog() if result.accepted: path = result.paths[0] filename = util.relativePath(self.parent.filename, path) self.components.fldImage.text = filename def on_btnIconFile_mouseClick(self, event): wildcard = "Icon Files (*.ico)|*.ico|XPM Files (*.xpm)|*.xpm|All Files (*.*)|*.*" result = dialog.openFileDialog(wildcard=wildcard) if result.accepted: path = result.paths[0] filename = util.relativePath(self.parent.filename, path) self.components.fldIcon.text = filename def backgroundInfoDialog(parent, rsrc): dlg = BackgroundInfoDialog(parent, rsrc) result = dlg.showModal() if result.accepted: result.name = dlg.components.fldName.text result.title = dlg.components.fldTitle.text result.position = eval(dlg.components.fldPosition.text) result.size = eval(dlg.components.fldSize.text) result.statusBar = dlg.components.chkStatusBar.checked result.foregroundColor = util.colorFromString(dlg.components.fldForegroundColor.text) result.backgroundColor = util.colorFromString(dlg.components.fldBackgroundColor.text) if dlg.components.fldImage.text != '': result.image = dlg.components.fldImage.text else: result.image = None result.tiled = dlg.components.chkTiled.checked result.visible = dlg.components.chkVisible.checked if dlg.components.chkResizeable.checked: result.style = ['resizeable'] else: result.style = [] if dlg.components.fldIcon.text != '': result.icon = dlg.components.fldIcon.text else: result.icon = None dlg.destroy() return result --- NEW FILE: scriptutils.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" modified version of Pythonwin scriptutils.py """ import os, sys import traceback # KEA 2002-05-08 # should probably refactor this so we're not passing around the background def CheckFile(background, pathName): what = "check" background.statusBar.text = what.capitalize()+'ing module...' try: f = open(pathName) except IOError, details: background.statusBar.text = "Cant open file '%s' - %s" % (pathName, details) return try: code = f.read() + "\n" finally: f.close() try: codeObj = compile(code, pathName,'exec') if RunTabNanny(background, pathName): #win32ui.SetStatusText("Python and the TabNanny successfully checked the file '"+os.path.basename(pathName)+"'") background.statusBar.text = "Python and the TabNanny successfully checked the file '"+os.path.basename(pathName)+"'" except SyntaxError: #background.statusBar.text = 'SyntaxError' _HandlePythonFailure(background, what, pathName) def RunTabNanny(background, filename): import cStringIO import tabnanny # Capture the tab-nanny output newout = cStringIO.StringIO() old_out = sys.stderr, sys.stdout sys.stderr = sys.stdout = newout try: tabnanny.check(filename) finally: # Restore output sys.stderr, sys.stdout = old_out data = newout.getvalue() if data: try: lineno = data.split()[1] lineno = int(lineno) _JumpToPosition(background, filename, lineno) try: # Try and display whitespace #GetActiveEditControl().SCISetViewWS(1) pass except: pass #win32ui.SetStatusText("The TabNanny found trouble at line %d" % lineno) background.statusBar.text = "The TabNanny found trouble at line %d" % lineno except (IndexError, TypeError, ValueError): background.statusBar.text = "The tab nanny complained, but I cant see where!" print data return 0 return 1 def _JumpToPosition(background, fileName, lineno, col = 1): #JumpToDocument(fileName, lineno, col) #print fileName, lineno, col doc = background.components.document doc.GotoLine(lineno - 1) if col == 1: pos = doc.PositionFromLine(lineno - 1) doc.SetSelection(pos, doc.GetLineEndPosition(lineno - 1)) doc.SetCurrentPos(pos) else: pos = doc.PositionFromLine(lineno - 1) + col - 1 doc.SetSelection(pos, pos) doc.SetCurrentPos(pos) def _HandlePythonFailure(background, what, syntaxErrorPathName = None): typ, details, tb = sys.exc_info() if typ == SyntaxError: try: msg, (fileName, line, col, text) = details if (not fileName or fileName =="<string>") and syntaxErrorPathName: fileName = syntaxErrorPathName _JumpToPosition(background, fileName, line, col) except (TypeError, ValueError): msg = str(details) #win32ui.SetStatusText('Failed to ' + what + ' - syntax error - %s' % msg) background.statusBar.text = 'Failed to ' + what + ' - syntax error - %s' % msg else: traceback.print_exc() #win32ui.SetStatusText('Failed to ' + what + ' - ' + str(details) ) # KEA 2002-06-03 # this needs to be more robust, but it is better than nothing for # simple indentation errors #try: # see if we have something of the form # (line 10) # for an error message that indicates the line number # the proper solution is to probably get the line number from the # traceback stack frame but I don't know how to do that #print traceback.tb_lineno(tb) try: msg, (fileName, line, col, text) = details _JumpToPosition(background, fileName, line, col) except: pass background.statusBar.text = 'Failed to ' + what + ' - ' + str(details) tb = None # Clean up a cycle. --- NEW FILE: stringDialog.rsrc.py --- {'type':'CustomDialog', 'name':'stringDialog', 'title':'String Editor', 'size':(480, 300), 'components': [ {'type':'List', 'name':'listStrings', 'position':(0, 0), 'size':(185, 185), 'items':[], }, {'type':'Button', 'name':'btnNew', 'position':(5, 190), 'label':'New', }, {'type':'Button', 'name':'btnDelete', 'position':(108, 191), 'label':'Delete', }, {'type':'StaticText', 'name':'stcName', 'position':(200, 10), 'text':'Name:', }, {'type':'StaticText', 'name':'stcValue', 'position':(200, 35), 'text':'Value:', }, {'type':'TextField', 'name':'fldListIndex', 'position':(460, 5), 'visible':0, }, {'type':'TextField', 'name':'fldName', 'position':(260, 5), 'size':(188, -1), }, {'type':'TextArea', 'name':'fldValue', 'position':(260, 35), 'size':(188, 197), }, {'type':'Button', 'name':'btnOK', 'position':(10, 240), 'label':'OK', 'default':1, 'id':5100, }, {'type':'Button', 'name':'btnCancel', 'position':(115, 240), 'label':'Cancel', 'id':5101, }, ] # end components } # end CustomDialog --- NEW FILE: menuDialog.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ from PythonCard import log, model, resource import os import wx MENULIST_PADDING = '....' def menuItemAttributes(menuItem): desc = " {'type':'MenuItem',\n" desc += " 'name':'%s',\n" % menuItem['name'] # KEA 2002-05-16 # work on string repr to get strings with mixed ' and " to work correctly if menuItem['shortcut'] == '': desc += """ 'label':%s,\n""" % repr(menuItem['label']) else: desc += """ 'label':%s,\n""" % repr(menuItem['label'] + '\t' + menuItem['shortcut']) try: if menuItem['command'] is not None: desc += " 'command':'%s',\n" % menuItem['command'] except: pass try: if not menuItem['enabled']: desc += " 'enabled':0,\n" except: pass try: if menuItem['checkable']: desc += " 'checkable':1,\n" if menuItem['checked']: desc += " 'checked':1,\n" except: pass desc += " },\n" return desc def menuAttributes(menu): desc = " {'type':'Menu',\n" desc += " 'name':'%s',\n" % menu['name'] desc += """ 'label':%s,\n""" % repr(menu['label']) desc += " 'items': [\n" return desc def menuResourceFromList(menuList): #desc = " 'menubar': {'type':'MenuBar',\n" desc = "{'type':'MenuBar',\n" desc += " 'menus': [\n" inMenu = 0 for m in menuList: if m['type'] == 'Menu': if inMenu: # close Menu desc += " ]\n" desc += " },\n" desc += menuAttributes(m) inMenu = 1 else: desc += menuItemAttributes(m) # close Menu desc += " ]\n" desc += " },\n" # close MenuBar desc += " ]\n" desc += "}\n" d = eval(desc) return resource.Resource(d) class MenuDialog(model.CustomDialog): def __init__(self, aBg, rsrc): model.CustomDialog.__init__(self, aBg) self.parent = aBg # if some special setup is necessary, do it here if rsrc is not None: #aBg.printMenubar(rsrc) self.menuList = self.parseMenus(rsrc) else: self.menuList = [] for m in self.menuList: if m['type'] == 'Menu': self.components.listMenus.append(m['label']) else: self.components.listMenus.append(MENULIST_PADDING + m['label']) #self.components.listMenus.items = self.parseMenus(rsrc) # Esc doesn't seem to work, it ends up closing the dialog # so need to work on that self.keyCodes = {wx.WXK_ESCAPE:'ESC', wx.WXK_SPACE:'Space', wx.WXK_DELETE:'Del', wx.WXK_F1:'F1', wx.WXK_F2:'F2', wx.WXK_F3:'F3', wx.WXK_F4:'F4', wx.WXK_F5:'F5', wx.WXK_F6:'F6', wx.WXK_F7:'F7', wx.WXK_F8:'F8', wx.WXK_F9:'F9', wx.WXK_F10:'F10', wx.WXK_F11:'F11', wx.WXK_F12:'F12', } #self.components.fldName.text = rsrc.application.name #self.components.fldTitle.text = rsrc.application.title #self.components.fldPosition.text = str(rsrc.application.position) #self.components.fldSize.text = str(rsrc.application.size) #self.components.chkStatusBar.checked = rsrc.application.statusBar def buildMenu(self, name, label): m = {} m['type'] = 'Menu' m['name'] = name m['label'] = label return m def buildMenuItem(self, name, label, shortcut, command, enabled, checkable, checked): m = {} m['type'] = 'MenuItem' m['name'] = name m['label'] = label m['shortcut'] = shortcut m['command'] = command m['enabled'] = enabled m['checkable'] = checkable m['checked'] = checked return m def parseMenus(self, menubar): menuList = [] for menu in menubar.menus: #menuList.append(menu.label) #print menu.type, menu.name, menu.label menuList.append(self.buildMenu(menu.name, menu.label)) for menuItem in menu.items: itemParts = menuItem.label.split("\t") label = itemParts[0] try: shortcut = itemParts[1] except: shortcut = '' #menuList.append("....%s" % itemParts[0]) #print menuItem.type, menuItem.name, itemParts, menuItem.command, menuItem.enabled, menuItem.checkable, menuItem.checked menuList.append(self.buildMenuItem(menuItem.name, label, shortcut, menuItem.command, menuItem.enabled, menuItem.checkable, menuItem.checked)) return menuList def on_fldShortcut_keyDown(self, event): # this should handle the special key codes keyCode = event.keyCode if keyCode > 32 and keyCode < 127: keyStr = chr(keyCode).upper() elif keyCode in self.keyCodes: keyStr = self.keyCodes[keyCode] else: event.target.text = '' return if event.shiftDown: keyStr = 'Shift+' + keyStr if event.altDown: keyStr = 'Alt+' + keyStr if event.controlDown: keyStr = 'Ctrl+' + keyStr if len(keyStr) > 1: # don't allow just a number or letter # without a modifier # might also need a leading Ctrl or Alt event.target.text = keyStr def on_fldShortcut_keyPress(self, event): pass def on_fldName_loseFocus(self, event): sel = self.components.listMenus.selection try: self.menuList[sel]['name'] = event.target.text log.info(self.menuList[sel]) except: pass def on_fldLabel_loseFocus(self, event): def normalize(label): name = label.replace("&", "").replace(".", "").replace(" ", "") return name sel = self.components.listMenus.selection try: label = event.target.text if self.menuList[sel]['type'] == 'Menu' and self.menuList[sel]['label'] == 'New Menu': oldname = self.menuList[sel]['name'] if oldname == 'menuNewMenu': name = 'menu'+normalize(label) self.menuList[sel]['name'] = name self.components.fldName.text = name elif self.menuList[sel]['type'] == 'MenuItem' and self.menuList[sel]['label'] == 'New Item': oldname = self.menuList[sel]['name'] menuname = 'menuMenu' for i in range(sel+1): if self.menuList[sel-i]['type'] == 'Menu': menuname = self.menuList[sel-i]['name'] break if oldname == menuname+'NewItem': name = menuname+normalize(label) self.menuList[sel]['name'] = name self.components.fldName.text = name self.menuList[sel]['label'] = label if self.menuList[sel]['type'] == 'MenuItem': label = MENULIST_PADDING + label self.components.listMenus.setString(sel, label) log.info(self.menuList[sel]) except: pass def on_fldShortcut_loseFocus(self, event): sel = self.components.listMenus.selection try: if self.menuList[sel]['type'] == 'MenuItem': self.menuList[sel]['shortcut'] = event.target.text log.info(self.menuList[sel]) except: pass def on_fldCommand_loseFocus(self, event): sel = self.components.listMenus.selection try: if self.menuList[sel]['type'] == 'MenuItem': if event.target.text == '': self.menuList[sel]['command'] = None else: self.menuList[sel]['command'] = event.target.text log.info(self.menuList[sel]) except: pass def on_chkEnabled_mouseClick(self, event): sel = self.components.listMenus.selection try: if self.menuList[sel]['type'] == 'MenuItem': self.menuList[sel]['enabled'] = event.target.checked log.info(self.menuList[sel]) except: pass def on_chkCheckable_mouseClick(self, event): sel = self.components.listMenus.selection try: if self.menuList[sel]['type'] == 'MenuItem': self.menuList[sel]['checkable'] = event.target.checked log.info(self.menuList[sel]) except: pass def on_chkChecked_mouseClick(self, event): sel = self.components.listMenus.selection try: if self.menuList[sel]['type'] == 'MenuItem': self.menuList[sel]['checked'] = event.target.checked log.info(self.menuList[sel]) except: pass def displayItemAttributes(self, sel): m = self.menuList[sel] self.components.fldListIndex.text = str(sel) self.components.fldName.text = m['name'] self.components.fldLabel.text = m['label'] if m['type'] == 'MenuItem': self.components.fldShortcut.text = m['shortcut'] if m['command'] is None: self.components.fldCommand.text = '' else: self.components.fldCommand.text = m['command'] self.components.chkEnabled.checked = m['enabled'] self.components.chkCheckable.checked = m['checkable'] self.components.chkChecked.checked = m['checked'] self.components.stcShortcut.visible = 1 self.components.stcCommand.visible = 1 self.components.fldShortcut.visible = 1 self.components.fldCommand.visible = 1 self.components.chkEnabled.visible = 1 self.components.chkCheckable.visible = 1 self.components.chkChecked.visible = 1 else: self.components.stcShortcut.visible = 0 self.components.stcCommand.visible = 0 self.components.fldShortcut.visible = 0 self.components.fldCommand.visible = 0 self.components.chkEnabled.visible = 0 self.components.chkCheckable.visible = 0 self.components.chkChecked.visible = 0 def on_listMenus_select(self, event): self.displayItemAttributes(event.target.selection) def rebuildListMenus(self, sel=-1): self.components.listMenus.clear() for m in self.menuList: if m['type'] == 'Menu': self.components.listMenus.append(m['label']) else: self.components.listMenus.append(MENULIST_PADDING + m['label']) if sel != -1: self.components.listMenus.selection = sel def on_btnUp_mouseClick(self, event): sel = self.components.listMenus.selection # a selection of -1 means no selection # a selection of 0 is the first item in the list if sel > 0: temp = self.menuList[sel] self.menuList[sel] = self.menuList[sel - 1] self.menuList[sel - 1] = temp self.rebuildListMenus(sel - 1) def on_btnDown_mouseClick(self, event): sel = self.components.listMenus.selection if sel != -1 and sel < len(self.menuList) - 1: temp = self.menuList[sel] self.menuList[sel] = self.menuList[sel + 1] self.menuList[sel + 1] = temp self.rebuildListMenus(sel + 1) def on_btnDelete_mouseClick(self, event): sel = self.components.listMenus.selection if sel != -1: del self.menuList[sel] self.components.listMenus.delete(sel) if len(self.menuList) > 0: if sel > 0: sel = sel - 1 self.components.listMenus.selection = sel self.displayItemAttributes(sel) def on_btnNewMenu_mouseClick(self, event): sel = self.components.listMenus.selection self.menuList.append(" ") # extend list if sel == -1: sel = len(self.menuList) - 1 else: self.menuList[sel+1:] = self.menuList[sel:-1] sel = sel+1 self.menuList[sel] = self.buildMenu('menuNewMenu', 'New Menu') self.rebuildListMenus(sel) self.displayItemAttributes(sel) def on_btnNewMenuItem_mouseClick(self, event): sel = self.components.listMenus.selection self.menuList.append(" ") # extend list if sel == -1: sel = len(self.menuList) - 1 else: self.menuList[sel+1:] = self.menuList[sel:-1] sel = sel+1 name = 'menuMenu' for i in range(1, sel+1): if self.menuList[sel-i]['type'] == 'Menu': name = self.menuList[sel-i]['name'] break self.menuList[sel] = self.buildMenuItem(name+'NewItem', 'New Item', '', None, 1, 0, 0) self.rebuildListMenus(sel) self.displayItemAttributes(sel) def menuDialog(parent, rsrc): dlg = MenuDialog(parent, rsrc) result = dlg.showModal() if result.accepted: if len(dlg.menuList) == 0: result.menubar = None else: result.menubar = menuResourceFromList(dlg.menuList) dlg.destroy() return result --- NEW FILE: __init__.py --- # turn modules into a package --- NEW FILE: propertyEditor.py --- #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ from PythonCard import dialog, font, model, registry, util from PythonCard.event import ChangeListener import resourceOutput import time import os import string import wx # KEA this is a load of dingos' kidneys and needs to be rewritten # 2002-02-22 # now I'm compounding the problem by porting from the original # Property Editor to a PythonCard background class PropertyEditor(model.Background, ChangeListener): def on_initialize(self, event): self._parent = self.GetParent() self._comp = self._parent.components self._updatingComponent = 0 self.autoAttributeUpdate = True ##self.components.addChangeEventListener(self) self._comp.addChangeEventListener(self) self.editItems = [self.components.wField, self.components.wColor, self.components.wFont, self.components.wTextArea, self.components.wChecked, self.components.wPop, self.components.wFile,] # KEA 2001-08-14 # this was causing an assertion error with the hybrid wxPython #self.components.wComponentList.SetSelection(0) if self.components.wComponentList.stringSelection == "": wClass = "" else: wName, wClass = self.components.wComponentList.stringSelection.split(" : ") self.setValidProps(wClass) #self.displayComponents(self.components) self.displayComponents(self._comp) self.visible = True # KEA 2004-08-23 # support updating of attributes without the need # for clicking the Update button def on_wField_closeField(self, event): if self.autoAttributeUpdate: self.updateComponent() def on_wTextArea_closeField(self, event): if self.autoAttributeUpdate: self.updateComponent() def on_wChecked_mouseClick(self, event): if self.autoAttributeUpdate: self.updateComponent() def on_wPop_select(self, event): if self.autoAttributeUpdate: self.updateComponent() def on_wColor_mouseClick(self, event): result = dialog.colorDialog(self, color=util.colorFromString(self.components.wField.text)) if result.accepted: self.components.wField.text = str(result.color) if self.autoAttributeUpdate: self.updateComponent() def on_wFont_mouseClick(self, event): wName, wClass = self.components.wComponentList.stringSelection.split(" : ") ##widget = self.components[wName] widget = self._comp[wName] f = widget.font if f is None: desc = font.fontDescription(widget.GetFont()) f = font.Font(desc) result = dialog.fontDialog(self, f) if result.accepted: #color = dlg.getColor() f = result.font #self.components.wField.SetValue("%s;%s" % (f, color)) self.components.wField.text = "%s" % f if self.autoAttributeUpdate: self.updateComponent() def on_wFile_mouseClick(self, event): path, filename = os.path.split(self.components.wField.text) result = dialog.openFileDialog(self, directory=path, filename=filename) if result.accepted: self.components.wField.text = util.relativePath(self._parent.filename, result.paths[0]) if self.autoAttributeUpdate: self.updateComponent() def addWidgetToComponentList(self, widget): wName = widget.name # KEA 2004-01-25 # just use __name__, the other code must have been something from wxPython 2.3 #wClass = str(widget.__class__).split('.') #self.components.wComponentList.Append(wName + " : " + wClass[len(wClass) - 1]) wClass = widget.__class__.__name__ self.components.wComponentList.Append(wName + " : " + wClass) # KEA 2002-02-23 # need to redo the logic below to avoid asserts in hybrid # versions of wxPython, but also be cleaner def deleteWidgetFromComponentList(self, wName, wClass): i = self.components.wComponentList.GetSelection() j = self.components.wComponentList.FindString(wName + " : " + wClass) if i == -1 or i != j: if j != -1: self.components.wComponentList.Delete(j) else: if j > 0: self.components.wComponentList.SetSelection(j - 1) if j != -1: self.components.wComponentList.Delete(j) if self.components.wComponentList.GetSelection() == -1: self.setValidProps("") self.hideAllBut(self.components.wField) else: wName, wClass = self.components.wComponentList.stringSelection.split(" : ") # deselect the name from properties list self.setValidProps(wClass) propName = self.components.wPropertyList.stringSelection if propName == "": propName = "name" self.components.wPropertyList.stringSelection = "name" self.displayProperty(wName, wClass, propName) def selectComponentList(self, wName, wClass): self.components.wComponentList.stringSelection = wName + " : " + wClass self.setValidProps(wClass) propName = self.components.wPropertyList.stringSelection #print propName if propName == "": propName = "name" self.components.wPropertyList.stringSelection = "name" self.displayProperty(wName, wClass, propName) c = self._parent.components[wName] self._parent.setToolTipDrag(wName, c.position, c.size) def changed(self, event): ##comp = self.components if self._updatingComponent: # KEA 2003-01-04 # hack to speed up updates in place return comp = self._comp wName, wClass = event.getOldValue().split(",") if wName in comp: # new item added self.addWidgetToComponentList(comp[wName]) else: # item deleted self.deleteWidgetFromComponentList(wName, wClass) """ def on_wCopy_mouseClick(self, event): wName, wClass = self.components.wComponentList.stringSelection.split(" : ") # what needs to happen here is to have a method for the Widget class that # will provide a valid resource description, each subclass of widget would # override the method to deal with their specific resource attributes # the Widget class should provide some ordering so that 'type', # 'position', 'size' comes before less commonly used items, the actual # ordering could just be defined in a list, so it is easy to change # also, if the current values match the defaults for a widget attribute # then that attribute should not be provided as part of the output print "this is just a placeholder method right now," print "the resource is not actually copied to the clipboard yet" pprint.pprint(self._comp[wName]) """ def on_wUpdate_mouseClick(self, event): self.updateComponent() def updateComponent(self): # make these attributes of self, since they are duplicated below in displayProperty checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules', 'labels', 'ticks', 'horizontalScrollbar'] popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] cantmodify = ['id', 'name', 'alignment', 'layout', 'style', 'border', 'horizontalScrollbar', \ 'min', 'max', 'columns', 'rules', 'labels', 'ticks'] wName, wClass = self.components.wComponentList.stringSelection.split(" : ") propName = self.components.wPropertyList.stringSelection # KEA 2002-02-23 ##if propName not in cantmodify: #print "updating", wName if propName in checkItems: value = self.components.wChecked.checked elif propName in popItems: value = self.components.wPop.stringSelection elif propName in ('items', 'userdata') or (wClass == 'TextArea' and propName == 'text'): value = self.components.wTextArea.text else: #value = self.components.wField.GetValue() value = self.components.wField.text if propName not in ['label', 'stringSelection', 'text', 'toolTip']: try: value = eval(value) except: pass # KEA 2004-05-10 # need to figure out where to stick validation code # but for now just need to make sure that if we're changing the name # attribute that it is valid, but similar checks will be necessary for # integer fields, a list of items, etc. # also maybe each attribute should have a doc or help string displayed # saying what the attribute does, example values, etc. if propName == 'name': badValue = False # if it isn't valid then display an alert and exit # must start with a letter and only contain alphanumeric characters if value == "" or value[0] not in string.ascii_letters: badValue = True else: alphanumeric = string.ascii_letters + string.digits for c in value: if c not in alphanumeric: badValue = True break if badValue: dialog.alertDialog(None, "Name must start with a letter and only contain letters and numbers.", 'Error: Name is invalid') self.components.wField.setFocus() self.components.wField.setSelection(-1, -1) return # check for duplicate names is done below ##widget = self.components[wName] widget = self._comp[wName] # KEA 2002-02-23 # I can't remember why this is actually necessary if propName == 'size': width, height = value if wClass not in ['BitmapCanvas', 'HtmlWindow']: bestWidth, bestHeight = widget.GetBestSize() if width == -1: width = bestWidth if height == -1: height = bestHeight widget.size = (width, height) #setattr(widget, propName, (width, height)) #print widget.size, propName, width, height else: if (propName in cantmodify) or \ (propName == 'items' and wClass == 'RadioGroup'): order = self._comp.order.index(wName) desc = resourceOutput.widgetAttributes(self._parent, widget) if desc.endswith(',\n'): desc = eval(desc[:-2]) else: desc = eval(desc) if propName == 'name': if value == wName: # user didn't actually change the name return elif value in self._comp: # we already have a component with that name dialog.alertDialog(self, 'Another component already exists with the name ' + value, 'Error: unable to rename component') return if value is None: desc[propName] = 'none' elif propName in ['min', 'max']: desc[propName] = int(value) else: desc[propName] = value # need to experiment with freeze and thaw to avoid # a lot of update events startTime = time.time() # this is going to trigger a changed event # as we delete the old component self._updatingComponent = True del self._comp[wName] if propName == 'name': wName = value # this is going to trigger another changed event # as we create a new component with the changed attribute self._comp[wName] = desc c = self._comp[wName] wx.EVT_LEFT_DOWN(c, self._parent.on_mouseDown) wx.EVT_LEFT_UP(c, self._parent.on_mouseUp) wx.EVT_MOTION(c, self._parent.on_mouseDrag) # now restore the order of the component # have to update the startName in case the name was updated if propName == 'name': self._parent.startName = wName self._comp.order.remove(wName) self._comp.order.insert(order, wName) self._parent.fixComponentOrder(wName) self._updatingComponent = False endTime = time.time() #print "attribute change took:", endTime - startTime else: if wClass in ['Image', 'ImageButton'] and propName == 'file': cwd = os.getcwd() try: os.chdir(self._parent.filename) except: pass setattr(widget, propName, value) os.chdir(cwd) else: setattr(widget, propName, value) #print propName, value # KEA 2002-02-23 self._parent.showSizingHandles(wName) def setValidProps(self, wClass): #print "setValidProps", wClass oldProp = self.components.wPropertyList.stringSelection if wClass == "": self.components.wPropertyList.Clear() else: ##props = self.propList + self.optionalProps[wClass] ##props.sort() ##print "props", props # get the property (attribute) list from the spec klass = registry.Registry.getInstance().getComponentClass(wClass) props = klass._spec.getAttributes().keys() # KEA 2002-03-24 # only show the 'id' attribute for Button # and only when displaying dialog properties if not (self._parent.editingDialog and wClass == 'Button'): props.remove('id') props.sort() ##print "spec props", specProps self.components.wPropertyList.Clear() self.components.wPropertyList.InsertItems(props, 0) if oldProp in props: self.components.wPropertyList.stringSelection = oldProp def hideAllBut(self, widget): for w in self.editItems: if widget.id != w.id: w.visible = False def displayProperty(self, wName, wClass, propName): checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules', 'labels', 'ticks', 'horizontalScrollbar'] popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] self.components.wName.text = propName + ":" ##widget = self.components[wName] widget = self._comp[wName] if propName in ['label', 'stringSelection', 'text', 'toolTip'] or propName in checkItems: value = getattr(widget, propName) else: value = str(getattr(widget, propName)) if propName in checkItems: self.hideAllBut(self.components.wChecked) self.components.wChecked.visible = True self.components.wChecked.checked = value elif propName in popItems: self.hideAllBut(self.components.wPop) self.components.wPop.visible = True self.components.wPop.Clear() if propName == 'stringSelection': for v in widget.items: self.components.wPop.Append(v) else: for v in widget._spec.getAttributes()[propName].values: self.components.wPop.Append(v) try: self.components.wPop.stringSelection = value except: # if value is empty or doesn't already exist pass elif propName in ('items', 'userdata') or (wClass == 'TextArea' and propName == 'text'): #print 'displaying TextArea' self.hideAllBut(self.components.wTextArea) self.components.wTextArea.visible = True self.components.wTextArea.text = value else: self.hideAllBut(self.components.wField) self.components.wField.visible = True if propName == 'foregroundColor' or propName == 'backgroundColor': self.components.wColor.visible = True elif propName == 'font': self.components.wFont.visible = True elif propName == 'file': self.components.wFile.visible = True self.components.wName.text = propName + ":" # KEA 2002-02-23 # I can't remember why this is actually necessary if propName == 'size': width, height = getattr(widget, propName) if wClass not in ['BitmapCanvas', 'HtmlWindow']: bestWidth, bestHeight = widget.GetBestSize() if width == bestWidth: width = -1 if height == bestHeight: height = -1 size = (width, height) value = str(size) self.components.wField.text = value # this should only display if the attribute is settable # so name, alignment, and others are read-only # KEA 2002-02-23 # wUpdate is always visible now self.components.wUpdate.visible = True def on_wComponentList_select(self, event): #print 'selectComponentListEvent: %s\n' % event.GetString() wName, wClass = event.GetString().split(" : ") # change the wPropertiesList to only show relevant properties # either display the name by default or try and preserve the # wPropertiesList selection and display that item, so for example # you could look at size for all widgets, simply by going up and down # the components list self.setValidProps(wClass) propName = self.components.wPropertyList.stringSelection #print propName if propName == "": propName = "name" self.components.wPropertyList.stringSelection = "name" self.displayProperty(wName, wClass, propName) self._parent.showSizingHandles(wName) c = self._parent.components[wName] self._parent.setToolTipDrag(wName, c.position, c.size) def on_wPropertyList_select(self, event): propName = event.GetString() wName, wClass = self.components.wComponentList.stringSelection.split(" : ") if wName != "": self.displayProperty(wName, wClass, propName) def clearComponentList(self): self.components.wComponentList.Clear() self.statusBar.text = '' def clearPropertyList(self): self.components.wPropertyList.Clear() def displayComponents(self, components): self.components.wComponentList.Freeze() self.components.wComponentList.Clear() self._comp = components for c in components.order: if c not in self._parent.sizingHandleNames: self.addWidgetToComponentList(components[c]) self.components.wComponentList.Thaw() self.components.wComponentList.Refresh() self.components.wComponentList.Update() def on_close(self, event): self.visible = False parent = self.GetParent() parent.menuBar.setChecked('menuViewPropertyEditor', 0) --- NEW FILE: propertyEditor.rsrc.py --- {'application':{'type':'Application', 'name':'Template', 'backgrounds': [ {'type':'Background', 'name':'bgTemplate', 'title':'resourceEditor Property Editor', 'size':(405, 270), 'visible':0, 'statusBar':1, 'components': [ {'type':'Button', 'name':'wUpdate', 'position':(320, 195), 'label':'Update', 'visible':0, 'default':1, }, {'type':'Choice', 'name':'wPop', 'position':(130, 130), 'size':(-1, 21), 'items':[], 'visible':0, }, {'type':'CheckBox', 'name':'wChecked', 'position':(130, 132), 'visible':0, 'label':'', }, {'type':'TextArea', 'name':'wTextArea', 'position':(130, 130), 'size':(260, 50), 'visible':0, }, {'type':'Button', 'name':'wFont', 'position':(320, 130), 'label':'Font...', 'visible':0, }, {'type':'Button', 'name':'wColor', 'position':(320, 130), 'label':'Color...', 'visible':0, }, {'type':'Button', 'name':'wFile', 'position':(320, 130), 'label':'File...', 'visible':0, }, {'type':'TextField', 'name':'wField', 'position':(130, 130), 'size':(180, -1), }, {'type':'StaticText', 'name':'wName', 'position':(5, 135), 'size':(120, -1), 'alignment':'right', 'text':'name:', }, {'type':'List', 'name':'wPropertyList', 'position':(225, 20), 'size':(165, 100), 'items':[], }, {'type':'List', 'name':'wComponentList', 'position':(5, 20), 'size':(200, 100), 'items':[], }, {'type':'StaticText', 'name':'Properties', 'position':(228, 3), 'text':'Properties', }, {'type':'StaticText', 'name':'stcNameClass', 'position':(5, 3), 'text':'Name : Class', }, ] # end components } # end background ] # end backgrounds } } --- NEW FILE: stringDialog.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ from PythonCard import log, model, resource import os import wx NEWSTRING = 'newString' SPACER = ' : ' def stringResourceFromList(stringList): desc = " {\n" for s in stringList: desc += """ %s:%s,\n""" % (repr(s), repr(stringList[s])) # close strings desc += " }\n" d = eval(desc) return resource.Resource(d) class StringDialog(model.CustomDialog): def __init__(self, aBg, stringList): model.CustomDialog.__init__(self, aBg) self.parent = aBg """ # KEA 2004-08-22 # workaround/hack to make sure closeField message # is processed prior to the dialog being closed # this occurs when one of the fields are edited and then # the user clicks Ok # this hack works because we don't process on_close # the first time, but rather delay it by posting a second close message self.closeDialog = False """ # if some special setup is necessary, do it here self.stringList = stringList sortedStrings = self.stringList.keys() sortedStrings.sort() for s in sortedStrings: label = self.getLabelFromKey(s) self.components.listStrings.append(label) def parseStrings(self, rsrc): stringList = {} for s in rsrc.__dict__: stringList[s] = rsrc.__dict__[s] return stringList def getLabelFromKey(self, key): return key + SPACER + self.stringList[key].split('\n')[0] def updateItemLabel(self, n, key): label = self.getLabelFromKey(key) self.components.listStrings.setString(n, label) def getStringSelectionKey(self): return self.components.listStrings.stringSelection.split()[0] def on_fldName_closeField(self, event): print "closeField fldName", event.target.text newName = event.target.text previousName = self.getStringSelectionKey() # if the name changes then we have to check to see # if the dictionary already has a key with the new # name if newName in self.stringList: # replace? pass else: sel = self.components.listStrings.selection self.stringList[newName] = self.stringList[previousName] del self.stringList[previousName] #self.components.listStrings.setString(sel, newName) self.updateItemLabel(sel, newName) def on_fldValue_closeField(self, event): print "closeField fldValue", event.target.text sel = self.components.listStrings.selection name = self.getStringSelectionKey() self.stringList[name] = event.target.text self.updateItemLabel(sel, name) def displayItemAttributes(self, s): self.components.fldName.text = s self.components.fldValue.text = self.stringList[s] def on_listStrings_select(self, event): self.displayItemAttributes(self.getStringSelectionKey()) def on_btnDelete_mouseClick(self, event): sel = self.components.listStrings.selection name = self.getStringSelectionKey() if sel != -1: del self.stringList[name] self.components.listStrings.delete(sel) if len(self.stringList) > 0: if sel > len(self.stringList) - 1: sel = sel - 1 self.components.listStrings.selection = sel self.displayItemAttributes(self.getStringSelectionKey()) def on_btnNew_mouseClick(self, event): s = NEWSTRING if s in self.stringList: self.components.listStrings.stringSelection = self.getLabelFromKey(s) else: self.stringList[s] = '' sel = len(self.stringList) - 1 self.components.listStrings.append(s) self.components.listStrings.stringSelection = s self.updateItemLabel(sel, s) self.displayItemAttributes(self.getStringSelectionKey()) """ # KEA 2004-08-22 # experiment to workaround Mac closeField bug # ignore for now along with the extra debug print statements in closeField # event handlers above def on_mouseClick(self, event): try: print self.closeDialog print event.target.name print event.target.id except: pass if self.closeDialog: event.skip() else: self.closeDialog = True wx.PostEvent(self, event) """ def stringDialog(parent, rsrc): dlg = StringDialog(parent, rsrc) result = dlg.showModal() if result.accepted: result.stringList = stringResourceFromList(dlg.stringList) dlg.destroy() return result --- NEW FILE: menuDialog.rsrc.py --- {'type':'CustomDialog', 'name':'menuDialog', 'title':'Menu Editor', 'size':(480, 300), 'components': [ {'type':'List', 'name':'listMenus', 'position':(0, 0), 'size':(185, 185), 'items':[], }, {'type':'Button', 'name':'btnUp', 'position':(5, 190), 'size':(50, -1), 'label':'Up', }, {'type':'Button', 'name':'btnDown', 'position':(60, 190), 'size':(60, -1), 'label':'Down', }, {'type':'Button', 'name':'btnDelete', 'position':(125, 190), 'size':(60, -1), 'label':'Delete', }, {'type':'StaticText', 'name':'stcName', 'position':(200, 10), 'text':'Name:', }, {'type':'StaticText', 'name':'stcLabel', 'position':(200, 35), 'text':'Label:', }, {'type':'StaticText', 'name':'stcShortcut', 'position':(200, 60), 'text':'Shortcut:', }, {'type':'StaticText', 'name':'stcCommand', 'position':(200, 85), 'text':'Command:', }, {'type':'TextField', 'name':'fldListIndex', 'position':(460, 5), 'visible':False, }, {'type':'TextField', 'name':'fldName', 'position':(275, 5), 'size':(188, -1), }, {'type':'TextField', 'name':'fldLabel', 'position':(275, 30), 'size':(188, -1), }, {'type':'TextField', 'name':'fldShortcut', 'position':(275, 55), 'size':(188, -1), }, {'type':'TextField', 'name':'fldCommand', 'position':(275, 80), 'size':(188, -1), }, {'type':'CheckBox', 'name':'chkEnabled', 'position':(275, 110), 'checked':True, 'label':'Enabled', }, {'type':'CheckBox', 'name':'chkCheckable', 'position':(275, 135), 'label':'Checkable', }, {'type':'CheckBox', 'name':'chkChecked', 'position':(275, 160), 'label':'Checked', }, {'type':'Button', 'name':'btnNewMenu', 'position':(220, 190), 'label':'New Menu', }, {'type':'Button', 'name':'btnNewMenuItem', 'position':(320, 190), 'label':'New MenuItem', }, {'type':'Button', 'id':5100, 'name':'btnOK', 'position':(10, 240), 'default':1, 'label':'OK', }, {'type':'Button', 'id':5101, 'name':'btnCancel', 'position':(115, 240), 'label':'Cancel', }, ] # end components } # end CustomDialog --- NEW FILE: backgroundInfoDialog.rsrc.py --- {'type':'CustomDialog', 'name':'backgroundInfo', 'title':'Background Info', 'size':(370, 380), 'components': [ {'type':'StaticText', 'name':'stcName', 'position':(10, 10), 'text':'Name:', }, {'type':'StaticText', 'name':'stcTitle', 'position':(10, 35), 'text':'Title:', }, {'type':'StaticText', 'name':'stcPosition', 'position':(10, 60), 'text':'Position:', }, {'type':'StaticText', 'name':'stcSize', 'position':(10, 85), 'text':'Size:', }, {'type':'StaticText', 'name':'stcForegroundColor', 'position':(10, 110), 'text':'Foreground color:', }, {'type':'StaticText', 'name':'stcBackgroundColor', 'position':(10, 135), #'size':(90, -1), 'text':'Background color:', }, {'type':'StaticText', 'name':'stcImage', 'position':(10, 160), 'text':'Image:', }, {'type':'StaticText', 'name':'stcIcon', 'position':(10, 210), 'text':'Icon:', }, {'type':'TextField', 'name':'fldName', 'position':(130, 5), }, {'type':'TextField', 'name':'fldTitle', 'position':(130, 30), 'size':(188, -1), }, {'type':'TextField', 'name':'fldPosition', 'position':(130, 55), 'size':(80, -1), }, {'type':'TextField', 'name':'fldSize', 'position':(130, 80), 'size':(80, -1), }, {'type':'TextField', 'name':'fldForegroundColor', 'position':(130, 110), 'size':(100, -1), }, {'type':'Button', 'name':'btnForegroundColor', 'position':(250, 110), 'label':'Color...', }, {'type':'TextField', 'name':'fldBackgroundColor', 'position':(130, 135), 'size':(100, -1), }, {'type':'Button', 'name':'btnBackgroundColor', 'position':(250, 135), 'label':'Color...', }, {'type':'TextField', 'name':'fldImage', 'position':(130, 160), 'size':(100, -1), }, {'type':'Button', 'name':'btnFile', 'position':(250, 160), 'label':'File...', }, {'type':'CheckBox', 'name':'chkTiled', 'position':(130, 185), 'size':(135, -1), 'checked':0, 'label':'Tile image', }, {'type':'TextField', 'name':'fldIcon', 'position':(130, 210), 'size':(100, -1), }, {'type':'Button', 'name':'btnIconFile', 'position':(250, 210), 'label':'File...', }, {'type':'CheckBox', 'name':'chkStatusBar', 'position':(130, 235), 'checked':0, 'label':'Status bar on window', }, {'type':'CheckBox', 'name':'chkVisible', 'position':(130, 260), 'size':(135, -1), 'checked':1, 'label':'Visible at startup', }, {'type':'CheckBox', 'name':'chkResizeable', 'position':(130, 285), 'size':(135, -1), 'checked':0, 'label':'Resizeable', }, {'type':'Button', 'name':'btnOK', 'position':(10, 320), 'label':'OK', 'default':1, 'id':5100, }, {'type':'Button', 'name':'btnCancel', 'position':(115, 320), 'label':'Cancel', 'id':5101, }, ] # end components } # end CustomDialog --- NEW FILE: stackInfoDialog.py --- """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ from PythonCard import model import os class StackInfoDialog(model.CustomDialog): def __init__(self, aBg, rsrc): model.CustomDialog.__init__(self, aBg) self.parent = aBg # if some special setup is necessary, do it here self.components.fldName.text = rsrc.application.name def stackInfoDialog(parent): dlg = StackInfoDialog(parent, parent.rsrc) result = dlg.showModal() result.text = dlg.components.fldName.text dlg.destroy() return result --- NEW FILE: stackInfoDialog.rsrc.py --- {'type':'CustomDialog', 'name':'stackInfo', 'title':'Stack Info', 'size':(270, 100), 'components': [ {'type':'StaticText', 'name':'stcName', 'position':(10, 10), 'size':(45, -1), 'text':'Name:', }, {'type':'TextField', 'name':'fldName', 'position':(60, 5), 'size':(188, -1), }, {'type':'Button', 'name':'btnOK', 'position':(10, 40), 'label':'OK', 'default':1, 'id':5100, }, {'type':'Button', 'name':'btnCancel', 'position':(115, 40), 'label':'Cancel', 'id':5101, }, ] # end components } # end CustomDialog --- NEW FILE: newComponentDialog.rsrc.py --- {'type':'CustomDialog', 'name':'Template', 'title':'Dialog Template', 'size':(300, 170), 'components': [ {'type':'TextField', 'name':'fldName', 'position':(60, 9), 'size':(230, -1), }, {'type':'TextField', 'name':'fldLabelOrText', 'position':(60, 40), 'size':(230, -1), }, {'type':'CheckBox', 'name':'chkHorizontal', 'position':(10, 80), 'label':'Offset Horizontally', }, {'type':'CheckBox', 'name':'chkVertical', 'position':(170, 80), 'label':'Offset Vertically', }, {'type':'Button', 'id':5100, 'name':'btnOK', 'position':(30, 110), 'label':'OK', }, {'type':'Button', 'id':5101, 'name':'btnCancel', 'position':(130, 110), 'label':'Cancel', }, {'type':'StaticText', 'name':'lblLabelOrText', 'position':(5, 40), 'size':(50, -1), 'alignment':'right', 'text':'Label:', }, {'type':'StaticText', 'name':'lblName', 'position':(5, 10), 'size':(50, -1), 'alignment':'right', 'text':'Name:', }, ] # end components } # end CustomDialog --- NEW FILE: dialogInfoDialog.rsrc.py --- {'type':'CustomDialog', 'name':'dialogInfo', 'title':'Dialog Info', 'size':(370, 170), 'components': [ {'type':'StaticText', 'name':'stcName', 'position':(10, 10), 'size':(45, -1), 'text':'Name:', }, {'type':'StaticText', 'name':'stcTitle', 'position':(10, 35), 'size':(45, -1), 'text':'Title:', }, {'type':'StaticText', 'name':'stcPosition', 'position':(10, 60), 'size':(45, -1), 'text':'Position:', }, {'type':'StaticText', 'name':'stcSize', 'position':(10, 85), 'size':(45, -1), 'text':'Size:', }, {'type':'TextField', 'name':'fldName', 'position':(110, 5), 'size':(188, -1), }, {'type':'TextField', 'name':'fldTitle', 'position':(110, 30), 'size':(188, -1), }, {'type':'TextField', 'name':'fldPosition', 'position':(110, 55), 'size':(68, -1), }, {'type':'TextField', 'name':'fldSize', 'position':(110, 80), 'size':(68, -1), }, {'type':'Button', 'name':'btnOK', 'position':(10, 110), 'label':'OK', 'default':1, 'id':5100, }, {'type':'Button', 'name':'btnCancel'... [truncated message content] |
From: Alex T. <ale...@us...> - 2004-10-03 23:58:11
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10092/images Added Files: sizingHandle.bmp Log Message: Initial version of a tabbed code editor, with associated (future) resource editor --- NEW FILE: sizingHandle.bmp --- (This appears to be a binary file; contents omitted.) |
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/scriptlets In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10092/scriptlets Added Files: documentWordCount.py insertDateAndTime.py insertDialog.py selectionWordCount.py testIgnore.py unorderedList.py Log Message: Initial version of a tabbed code editor, with associated (future) resource editor --- NEW FILE: documentWordCount.py --- import wx from PythonCard import dialog, util def wordCount(text): chars = len(text) words = len(text.split()) # this doesn't always match the getNumberOfLines() method # so this should probably be changed lines = len(text.splitlines()) return chars, words, lines if bg.documentPath is None: filename = 'Untitled' else: filename = os.path.basename(bg.documentPath) dialog.MessageDialog(bg, "Document: %s\n" % filename + "%d chars, %d words, %d lines" % wordCount(util.normalizeEOL(bg.components.document.text)), 'Word Count', wx.ICON_INFORMATION | wx.OK) --- NEW FILE: unorderedList.py --- # inserts "\t* " before each line in the selection text = bg.components.document.GetSelectedText() unorderedList = "" for i in text.splitlines(1): unorderedList += "\t* " + i bg.components.document.ReplaceSelection(unorderedList) --- NEW FILE: insertDateAndTime.py --- import time now = time.localtime(time.time()) dateStr = time.strftime("%A, %B %d, %Y, %I:%M %p", now) comp.document.ReplaceSelection(dateStr) --- NEW FILE: insertDialog.py --- from PythonCard import dialog alertDialogTemplate = """result = dialog.alertDialog(self, 'a message', 'a title') if result.accepted: returned = result.returnedString """ colorDialogTemplate = """result = dialog.colorDialog(self) if result.accepted: color = result.color """ directoryDialogTemplate = """result = dialog.directoryDialog(self, 'Choose a directory', '') if result.accepted: path = result.path """ findDialogTemplate = """result = dialog.findDialog(self) if result.accepted: searchText = result.searchText wholeWordsOnly = result.wholeWordsOnly caseSensitive = result.caseSensitive """ fontDialogTemplate = """result = dialog.fontDialog(self) if result.accepted: color = result.color font = result.font """ messageDialogTemplate = """result = dialog.messageDialog(self, 'a message', 'a title', wx.ICON_INFORMATION | wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL) if result.accepted: returned = result.returnedString """ multipleChoiceDialogTemplate = """result = dialog.multipleChoiceDialog(self, "message", "title", ['one', 'two', 'three']) if result.accepted: sel = result.selection """ openFileDialogTemplate = """wildcard = "JPG files (*.jpg;*.jpeg)|*.jpg;*.jpeg;*.JPG;*.JPEG|GIF files (*.gif)|*.gif;*.GIF|All Files (*.*)|*.*" result = dialog.openFileDialog(self, 'Open', '', '', wildcard ) if result.accepted: path = result.paths[0] """ saveFileDialogTemplate = """wildcard = "JPG files (*.jpg;*.jpeg)|*.jpg;*.jpeg;*.JPG;*.JPEG|GIF files (*.gif)|*.gif;*.GIF|All Files (*.*)|*.*" result = dialog.saveFileDialog(self, 'Save', '', '', wildcard ) if result.accepted: path = result.paths[0] """ scrolledMessageDialogTemplate = """dialog.scrolledMessageDialog(self, 'message', 'title') if result.accepted: # you don't really need the accepted test, since there isn't a result # to check for a scrolledMessageDialog pass """ singleChoiceDialogTemplate = """result = dialog.singleChoiceDialog(self, "message", "title", ['one', 'two', 'three']) if result.accepted: sel = result.selection """ textEntryDialogTemplate = """result = dialog.textEntryDialog(self, 'message', 'title', 'text') if result.accepted: returned = result.returnedString text = result.text """ dialogsList = ['alertDialog', 'colorDialog', 'directoryDialog', 'findDialog', 'fontDialog', 'messageDialog', 'multipleChoiceDialog', 'openFileDialog', 'saveFileDialog', 'scrolledMessageDialog', 'singleChoiceDialog', 'textEntryDialog'] dialogsList.sort() result = dialog.singleChoiceDialog(None, "Pick a dialog:", "Dialogs", dialogsList) if result.accepted: dialogText = eval(result.selection + 'Template') # could get the current indent and insert the appropriate # number of spaces before each line of the template here comp.document.ReplaceSelection(dialogText) --- NEW FILE: selectionWordCount.py --- import wx from PythonCard import dialog, util def wordCount(text): chars = len(text) words = len(text.split()) # this doesn't always match the getNumberOfLines() method # so this should probably be changed lines = len(text.splitlines()) return chars, words, lines if bg.documentPath is None: filename = 'Untitled' else: filename = os.path.basename(bg.documentPath) text = util.normalizeEOL(bg.components.document.GetSelectedText()) dialog.MessageDialog(bg, "Document: %s\n" % filename + "%d chars, %d words, %d lines" % wordCount(text), 'Word Count', wx.ICON_INFORMATION | wx.OK) --- NEW FILE: testIgnore.py --- # ignore is a regular expression that will match the filenames # for the modules to exclude. ignore = '.*\.py$' |
From: Alex T. <ale...@us...> - 2004-10-03 23:58:10
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10092 Added Files: Info.plist codePage.py codePage.rsrc.py macbuild.py readme.txt resourceEditor.py resourceEditor.rsrc.py restEditor.py restEditor.rsrc.py snippet.py tabcodeEditor.py tabcodeEditor.rsrc.py todo.txt Log Message: Initial version of a tabbed code editor, with associated (future) resource editor --- NEW FILE: snippet.py --- from docutils import core from docutils.writers.html4css1 import Writer,HTMLTranslator from docutils.utils import SystemMessage class NoHeaderHTMLTranslator(HTMLTranslator): def __init__(self, document): HTMLTranslator.__init__(self,document) self.head_prefix = ['','','','',''] self.body_prefix = [] self.body_suffix = [] self.stylesheet = [] _w = Writer() _w.translator_class = NoHeaderHTMLTranslator def restify(string): # return core.publish_string(string,writer=_w) try: result = core.publish_string(string,writer=_w, settings_overrides={'traceback': True}) except SystemMessage, e: result = None print "barf" return result if __name__ == '__main__': test = """ Test example of reST__ document. __ http://docutils.sf.net/rst.html - item 1 - item 2 - item 3 """ print restify(test) --- NEW FILE: Info.plist --- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> <string>c</string> <string>cgi</string> <string>c++</string> <string>cp</string> <string>cpp</string> <string>cs</string> <string>css</string> <string>csv</string> <string>dtd</string> <string>h</string> <string>htm</string> <string>html</string> <string>log</string> <string>plist</string> <string>py</string> <string>python</string> <string>pyw</string> <string>sgml</string> <string>sh</string> <string>shtm</string> <string>shtml</string> <string>text</string> <string>txt</string> <string>xhtml</string> <string>xml</string> <string>xsl</string> <string>xslt</string> <string>yaml</string> <string>*</string> </array> <key>CFBundleTypeMIMETypes</key> <array> <string>text/plain</string> </array> <key>CFBundleTypeName</key> <string>Python Module</string> <key>CFBundleTypeOSTypes</key> <array> <string>TEXT</string> <string>****</string> </array> <key>CFBundleTypeRole</key> <string>Editor</string> </dict> </array> <key>CFBundleExecutable</key> <string>CodeEditor</string> <key>CFBundleName</key> <string>CodeEditor</string> <key>CFBundleIdentifier</key> <string>CodeEditor</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleGetInfoString</key> <string>0.8</string> <key>CFBundleShortVersionString</key> <string>0.8</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>0.8 (v1.124)</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> </dict> </plist> --- NEW FILE: todo.txt --- - figure out initial sizing issues - close button / menu item to close current page - add menu and command items to drop-downs - key / shortcut to take you to the drop-down (if possible) ? --- NEW FILE: resourceEditor.rsrc.py --- {'application':{'type':'Application', 'name':'ResEdit', 'backgrounds': [ {'type':'Background', 'name':'bgDrag', 'title':'Resource Editor', 'size':(316, 166), 'style':['resizeable'], 'menubar': {'type':'MenuBar', 'menus': [ {'type':'Menu', 'name':'menuFile', 'label':'&File', 'items': [ {'type':'MenuItem', 'name':'menuFileNew', 'label':'&New...\tCtrl+N', }, {'type':'MenuItem', 'name':'menuFileOpen', 'label':'&Open...\tCtrl+O', }, {'type':'MenuItem', 'name':'menuFileSave', 'label':'Save\tCtrl+S', }, {'type':'MenuItem', 'name':'menuFileSaveAs', 'label':'Save &As...', }, {'type':'MenuItem', 'name':'menuFileRevert', 'label':'Revert', }, {'type':'MenuItem', 'name':'fileSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuFileRun', 'label':'&Run\tCtrl+R', 'command':'fileRun', }, {'type':'MenuItem', 'name':'menuFileRunWithInterpreter', 'label':'Run with &interpreter\tCtrl+Shift+R', 'command':'fileRunWithInterpreter', }, {'type':'MenuItem', 'name':'menuFileRunOptions', 'label':'Run Options...', 'command':'fileRunOptions', }, {'type':'MenuItem', 'name':'menuFilePreviewDialog', 'label':'Preview Dialog', 'command':'filePreviewDialog', }, {'type':'MenuItem', 'name':'fileSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuFileExit', 'label':'E&xit\tAlt+X', 'command':'exit', }, ] }, {'type':'Menu', 'name':'menuEdit', 'label':'&Edit', 'items': [ {'type':'MenuItem', 'name':'menuEditCut', 'label':'Cu&t\tCtrl+X', }, {'type':'MenuItem', 'name':'menuEditCopy', 'label':'&Copy\tCtrl+C', }, {'type':'MenuItem', 'name':'menuEditPaste', 'label':'&Paste\tCtrl+V', }, {'type':'MenuItem', 'name':'editSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuComponentDuplicate', 'label':'&Duplicate', 'command':'componentDuplicate', }, {'type':'MenuItem', 'name':'menuComponentDelete', 'label':'Delete\tDel', 'command':'componentDelete', }, {'type':'MenuItem', 'name':'componentSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditBackgroundInfo', 'label':'Background Info...', 'command':'editBackgroundInfo', }, {'type':'MenuItem', 'name':'menuEditMenubar', 'label':'Menu Editor...', 'command':'editMenubar', }, {'type':'MenuItem', 'name':'menuEditStrings', 'label':'String Editor...', 'command':'editStrings', }, {'type':'MenuItem', 'name':'menuEditDialogInfo', 'label':'Dialog Info...', 'command':'editDialogInfo', }, ] }, {'type':'Menu', 'name':'menuComponent', 'label':'&Component', 'items': [] }, {'type':'Menu', 'name':'menuOptions', 'label':'&Options', 'items': [ {'type':'MenuItem', 'name':'menuOptionsGridSize', 'label':'Grid Size...', 'command':'optionGridSize', }, {'type':'MenuItem', 'name':'menuOptionsAlignToGrid', 'label':'Align Components to Grid\tCtrl+G', 'checkable':1, }, {'type':'MenuItem', 'name':'menuOptionsShowGridLines', 'label':'Show Grid Lines', 'checkable':1, 'checked':0, }, {'type':'MenuItem', 'name':'componentSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuComponentSendBack', 'label':'Send to Back\tCtrl+1', 'command':'componentSendBack', }, {'type':'MenuItem', 'name':'menuComponentMoveBack', 'label':'Move Backward\tCtrl+2', 'command':'componentMoveBack', }, {'type':'MenuItem', 'name':'menuComponentMoveForward', 'label':'Move Forward\tCtrl+3', 'command':'componentMoveForward', }, {'type':'MenuItem', 'name':'menuComponentBringFront', 'label':'Bring to Front\tCtrl+4', 'command':'componentBringFront', }, ] }, {'type':'Menu', 'name':'menuView', 'label':'&View', 'items': [ {'type':'MenuItem', 'name':'menuViewAttributes', 'label':'&Resource...', 'command':'displayAttributes', }, {'type':'MenuItem', 'name':'menuViewSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuViewPropertyEditor', 'label':'Property Editor\tCtrl+P', 'checkable':1, 'checked':1, }, ] }, {'type':'Menu', 'name':'menuHelp', 'label':'&Help', 'items': [ {'type':'MenuItem', 'name':'menuResourceEditorDocumentation', 'label':'&resourceEditor Documentation...\tF1', 'command':'showResourceEditorDocumentation', }, {'type':'MenuItem', 'name':'menuPythonCardDocumentation', 'label':'&PythonCard Documentation...', 'command':'showPythonCardDocumentation', }, {'type':'MenuItem', 'name':'helpSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuHelpAbout', 'label':'&About resourceEditor...', }, {'type':'MenuItem', 'name':'menuHelpAboutPythonCard', 'label':'About PythonCard...', 'command':'doHelpAboutPythonCard', }, ] }, ] }, 'components': [ ] # end components } # end background ] # end backgrounds } } --- NEW FILE: tabcodeEditor.rsrc.py --- {'application':{'type':'Application', 'name':'codeEditor', 'backgrounds': [ {'type':'Background', 'name':'bgCodeEditor', 'title':'tabbed Code Editor PythonCard Application', 'position':(22, 22), 'size':(400, 300), 'statusBar':1, 'visible':0, 'style':['resizeable'], 'menubar': {'type':'MenuBar', 'menus': [ {'type':'Menu', 'name':'menuFile', 'label':'&File', 'items': [ {'type':'MenuItem', 'name':'menuFileNew', 'label':'&New\tCtrl+N', }, {'type':'MenuItem', 'name':'menuFileOpen', 'label':'&Open\tCtrl+O', }, {'type':'MenuItem', 'name':'menuFileSave', 'label':'&Save\tCtrl+S', }, {'type':'MenuItem', 'name':'menuFileSaveAs', 'label':'Save &As...', }, {'type':'MenuItem', 'name':'fileSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuFileCheckSyntax', 'label':'&Check Syntax (Module)\tAlt+F5', 'command':'checkSyntax', }, {'type':'MenuItem', 'name':'menuFileRun', 'label':'&Run\tCtrl+R', 'command':'fileRun', }, {'type':'MenuItem', 'name':'menuFileRunWithInterpreter', 'label':'Run with &interpreter\tCtrl+Shift+R', 'command':'fileRunWithInterpreter', }, {'type':'MenuItem', 'name':'menuFileRunOptions', 'label':'Run Options...', 'command':'fileRunOptions', }, {'type':'MenuItem', 'name':'fileSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuFilePageSetup', 'label':'Page Set&up...', }, {'type':'MenuItem', 'name':'menuFilePrint', 'label':'&Print...\tCtrl+P', }, {'type':'MenuItem', 'name':'menuFilePrintPreview', 'label':'Print Pre&view', }, {'type':'MenuItem', 'name':'fileSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuFileExit', 'label':'E&xit\tAlt+X', 'command':'exit', }, ] }, {'type':'Menu', 'name':'Edit', 'label':'&Edit', 'items': [ {'type':'MenuItem', 'name':'menuEditUndo', 'label':'&Undo\tCtrl+Z', }, {'type':'MenuItem', 'name':'menuEditRedo', 'label':'&Redo\tCtrl+Y', }, {'type':'MenuItem', 'name':'editSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditCut', 'label':'Cu&t\tCtrl+X', }, {'type':'MenuItem', 'name':'menuEditCopy', 'label':'&Copy\tCtrl+C', }, {'type':'MenuItem', 'name':'menuEditPaste', 'label':'&Paste\tCtrl+V', }, {'type':'MenuItem', 'name':'editSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditFind', 'label':'&Find...\tCtrl+F', 'command':'doEditFind', }, {'type':'MenuItem', 'name':'menuEditFindNext', 'label':'&Find Next\tF3', 'command':'doEditFindNext', }, {'type':'MenuItem', 'name':'menuEditFindFiles', 'label':'Find in Files...\tAlt+F3', 'command':'findFiles', }, {'type':'MenuItem', 'name':'menuEditReplace', 'label':'&Replace...\tCtrl+H', 'command':'doEditFindReplace', }, {'type':'MenuItem', 'name':'menuEditGoTo', 'label':'&Go To...\tCtrl+G', 'command':'doEditGoTo', }, {'type':'MenuItem', 'name':'editSep3', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditReplaceTabs', 'label':'&Replace tabs with spaces', 'command':'doEditReplaceTabs', }, {'type':'MenuItem', 'name':'editSep3', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditClear', 'label':'Cle&ar\tDel', }, {'type':'MenuItem', 'name':'menuEditSelectAll', 'label':'Select A&ll\tCtrl+A', }, {'type':'MenuItem', 'name':'editSep4', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditIndentRegion', 'label':'&Indent Region', 'command':'indentRegion', }, {'type':'MenuItem', 'name':'menuEditDedentRegion', 'label':'&Dedent Region', 'command':'dedentRegion', }, {'type':'MenuItem', 'name':'menuEditCommentRegion', 'label':'Comment &out region\tAlt+3', 'command':'commentRegion', }, {'type':'MenuItem', 'name':'menuEditUncommentRegion', 'label':'U&ncomment region\tShift+Alt+3', 'command':'uncommentRegion', }, ] }, {'type':'Menu', 'name':'menuView', 'label':'&View', 'items': [ {'type':'MenuItem', 'name':'menuViewWhitespace', 'label':'&Whitespace', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewIndentationGuides', 'label':'Indentation &guides', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewRightEdgeIndicator', 'label':'&Right edge indicator', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewEndOfLineMarkers', 'label':'&End-of-line markers', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewFixedFont', 'label':'&Fixed Font', 'enabled':0, 'checkable':1, }, {'type':'MenuItem', 'name':'viewSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuViewLineNumbers', 'label':'&Line Numbers', 'checkable':1, 'checked':1, }, {'type':'MenuItem', 'name':'menuViewCodeFolding', 'label':'&Code Folding', 'checkable':1, }, ] }, {'type':'Menu', 'name':'menuFormat', 'label':'F&ormat', 'items': [ {'type':'MenuItem', 'name':'menuFormatStyles', 'label':'&Styles...', 'command':'doSetStyles', }, {'type':'MenuItem', 'name':'menuFormatWrap', 'label':'&Wrap Lines', 'checkable':1, }, ] }, {'type':'Menu', 'name':'menuScriptlet', 'label':'&Shell', 'items': [ {'type':'MenuItem', 'name':'menuScriptletShell', 'label':'&Shell Window\tF5', }, {'type':'MenuItem', 'name':'menuScriptletNamespace', 'label':'&Namespace Window\tF6', }, {'type':'MenuItem', 'name':'menuScriptletSaveUserConfiguration', 'label':'Save &Configuration', }, {'type':'MenuItem', 'name':'menuShellChangeDirectory', 'label':'Change &Directory...', }, {'type':'MenuItem', 'name':'scriptletSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuScriptletSaveShellSelection', 'label':'Save Shell Selection...', }, {'type':'MenuItem', 'name':'menuScriptletRunScriptlet', 'label':'Run Scriptlet...', }, ] }, {'type':'Menu', 'name':'menuHelp', 'label':'&Help', 'items': [ {'type':'MenuItem', 'name':'menuShellDocumentation', 'label':'&Shell Documentation...', 'command':'showShellDocumentation', }, {'type':'MenuItem', 'name':'menuPythonCardDocumentation', 'label':'&PythonCard Documentation...\tF1', 'command':'showPythonCardDocumentation', }, {'type':'MenuItem', 'name':'menuPythonDocumentation', 'label':'Python &Documentation...', 'command':'showPythonDocumentation', }, {'type':'MenuItem', 'name':'helpSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuHelpAbout', 'label':'&About codeEditor...', 'command':'doHelpAbout', }, {'type':'MenuItem', 'name':'menuHelpAboutPythonCard', 'label':'About PythonCard...', 'command':'doHelpAboutPythonCard', }, ] }, ] }, 'strings': { 'saveAs':'Save As', 'openFile':'Open file', 'chars':'chars', 'gotoLine':'Goto line', 'gotoLineNumber':'Goto line number:', 'sample':'codeEditor sample', 'codeEditor':'codeEditor', 'words':'words', 'documentChangedPrompt':'The text in the %s file has changed.\n\nDo you want to save the changes?', 'saveAsWildcard':'All files (*.*)|*.*|Python scripts (*.py;*.pyw)|*.pyw;*.PY;*.PYW;*.py|Text files (*.txt;*.text)|*.text;*.TXT;*.TEXT;*.txt|HTML and XML files (*.htm;*.html;*.xml)|*.htm;*.xml;*.HTM;*.HTML;*.XML;*.html', 'about':'About codeEditor...', 'document':'Document', 'lines':'lines', 'untitled':'Untitled', 'replaced':'Replaced %d occurances', 'scriptletWildcard':'Python files (*.py)|*.py|All Files (*.*)|*.*', }, 'components': [ {'type':'Notebook', 'name':'notebook', 'position':(10, 30), 'size':(274, 105), }, {'type':'Choice', 'name':'popComponentNames', 'position':(6, 6), 'items':[], }, {'type':'Choice', 'name':'popComponentEvents', 'position':(152, 6), 'items':[], }, ] # end components } # end background ] # end backgrounds } } --- NEW FILE: codePage.rsrc.py --- {'application':{'type':'Application', 'name':'codeEditor', 'backgrounds': [ {'type':'Background', 'name':'bgCodeEditor', 'title':'Code Page PythonCard Application', 'position':(132, 132), 'size':(407, 308), 'statusBar':1, 'visible':0, 'style':['resizeable'], 'strings': { 'saveAs':'Save As', 'openFile':'Open file', 'chars':'chars', 'gotoLine':'Goto line', 'gotoLineNumber':'Goto line number:', 'sample':'codeEditor sample', 'codeEditor':'codeEditor', 'words':'words', 'documentChangedPrompt':'The text in the %s file has changed.\n\nDo you want to save the changes?', 'saveAsWildcard':'All files (*.*)|*.*|Python scripts (*.py;*.pyw)|*.pyw;*.PY;*.PYW;*.py|Text files (*.txt;*.text)|*.text;*.TXT;*.TEXT;*.txt|HTML and XML files (*.htm;*.html;*.xml)|*.htm;*.xml;*.HTM;*.HTML;*.XML;*.html', 'about':'About codeEditor...', 'document':'Document', 'lines':'lines', 'untitled':'Untitled', 'replaced':'Replaced %d occurances', 'scriptletWildcard':'Python files (*.py)|*.py|All Files (*.*)|*.*', }, 'components': [ {'type':'CodeEditor', 'name':'document', 'position':(2, 2), 'size':(386, 246), 'backgroundColor':(255, 255, 255), }, ] # end components } # end background ] # end backgrounds } } --- NEW FILE: codePage.py --- #!/usr/bin/env python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" PythonCard Editor (codeEditor) wiki page http://wiki.wxpython.org/index.cgi/PythonCardEditor wxStyledTextCtrl documentation http://wiki.wxpython.org/index.cgi/wxStyledTextCtrl """ from PythonCard import about, configuration, dialog, log, menu, model, resource, util, registry from PythonCard.templates.dialogs import runOptionsDialog from modules import scriptutils import os, sys import wx from wx import stc from wx.html import HtmlEasyPrinting import pprint from PythonCard import STCStyleEditor from modules import colorizer import cStringIO import webbrowser class CodePage(model.PageBackground): def on_initialize(self, event): self.initSizers() self.setDefaultStyles() self.lastStatus = None self.lastPos = None def initSizers(self): sizer1 = wx.BoxSizer(wx.VERTICAL) sizer1.Add(self.components.document, 1, wx.EXPAND) sizer1.Fit(self) sizer1.SetSizeHints(self) self.panel.SetSizer(sizer1) self.panel.SetAutoLayout(1) self.panel.Layout() def setDefaultStyles(self): config = configuration.getStyleConfigPath() # KEA 2002-05-28 # STCStyleEditor doesn't work yet on OS X if config is not None: STCStyleEditor.initSTC(self.components.document, config, 'python') if self.application.shell is not None: STCStyleEditor.initSTC(self.application.shell, config, 'python') def setEditorStyle(self): try: self.components.document.setEditorStyle(os.path.splitext(self.documentPath)[-1]) except: self.components.document.setEditorStyle('python') def newFile(self): self.components.document.text = '' self.documentPath = None self.setEditorStyle() self.components.document.SetSavePoint() self.statusBar.text = self.resource.strings.untitled self.lastStatus = None # KEA 2003-07-26 # reset EOL to match platform # this may not actually be what the user expects # so perhaps this should be an option in a dialog?! self.autoSetEOL() self.topLevelParent.setTitleBar(self.resource.strings.untitled) def openFile(self, path): try: self.components.document.SetUndoCollection(0) self.components.document.ClearAll() f = open(path, 'rb') try: self.components.document.text = f.read() finally: f.close() self.documentPath = path os.chdir(os.path.dirname(self.documentPath)) self.components.document.EmptyUndoBuffer() self.components.document.SetUndoCollection(1) self.components.document.SetSavePoint() #self.statusBar.text = path self.lastStatus = None self.topLevelParent.fileHistory.AddFileToHistory(path) # KEA 2002-06-29 # just as a test, let's see how the XML and/or HTML styles # look self.setEditorStyle() self.autoSetEOL() self.topLevelParent.setTitleBar(os.path.split(path)[-1]) except: pass def saveFile(self, path): try: f = open(path, 'wb') try: f.write(self.components.document.text) finally: f.close() self.documentPath = path os.chdir(os.path.dirname(self.documentPath)) self.components.document.SetSavePoint() self.title = os.path.split(path)[-1] + ' - ' + self.startTitle #self.statusBar.text = path self.lastStatus = None self.setEditorStyle() except: pass # KEA 2003-07-26 def autoSetEOL(self): """ when opening an existing file automatically set the EOL mode to match the current line endings for the file if the document is empty then set EOL to the original EOL state """ doc = self.components.document if doc.GetLength(): line = doc.GetLine(0) else: line = os.linesep if line.endswith('\r\n'): doc.SetEOLMode(stc.STC_EOL_CRLF) elif line.endswith('\n'): doc.SetEOLMode(stc.STC_EOL_LF) elif line.endswith('\r'): doc.SetEOLMode(stc.STC_EOL_CR) # Edit menu def on_menuEditUndo_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.CanUndo(): widget.Undo() def on_menuEditRedo_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.CanRedo(): widget.Redo() def on_menuEditCut_select(self, event): widget = self.findFocus() # KEA 2002-05-03 # no CanCut() method? if hasattr(widget, 'editable'): widget.Cut() def on_menuEditCopy_select(self, event): widget = self.findFocus() # KEA 2002-05-03 # no CanCopy() method? if hasattr(widget, 'editable'): widget.Copy() def on_menuEditPaste_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable') and widget.CanPaste(): widget.Paste() def on_menuEditClear_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable'): widget.ClearSelection() def on_menuEditSelectAll_select(self, event): widget = self.findFocus() if hasattr(widget, 'editable'): widget.SelectAll() def on_document_keyDown(self, event): #print "keyPress", event.keyCode, event.shiftDown, event.controlDown, event.altDown # smart auto-indent on Return # this is brute force and currently assumes 4 space # Guido indentation style keyCode = event.keyCode target = event.target if keyCode == wx.WXK_RETURN: # since we won't be calling skip, insert a newline manually self.components.document.CmdKeyExecute(stc.STC_CMD_NEWLINE) # why isn't GetCurrentLine 0 based? line = target.GetCurrentLine() - 1 txt = target.GetLine(line) stripped = txt.rstrip() # auto-indent block indent = target.GetLineIndentation(line) padding = " " * indent pos = target.GetCurrentPos() if len(stripped) > 0 and stripped[-1] == ':': # KEA 2002-05-06 to do # should use GetStyleAt() on the actual pos of # the : to make sure the style is not wxSTC_P_COMMENTLINE... # actually this is more complex and really when the style # we need to walk backwards until we find a colon not in # one of the comment styles before doing an auto-indent # but I don't feel like getting it all working before 0.6.6 # so this is left as an exercise for the reader ;-) ## whitespace = len(txt) - len(stripped) ## colonPos = target.GetLineEndPosition(line) - whitespace + 1 ## if target.GetStyleAt(colonPos) not in \ ## [stc.STC_P_COMMENTLINE, ## stc.STC_P_COMMENTBLOCK, ## stc.STC_P_TRIPLEDOUBLE ]: padding += " " * 4 target.InsertText(pos, padding) newpos = pos + len(padding) target.SetCurrentPos(newpos) target.SetSelection(newpos, newpos) else: event.skip() # AGT 2004/10/03 # why have this here - just do in top level ??? # but keep this here as a placeholder to remind me to change it def becomeFocus(self): if self.documentPath: self.topLevelParent.setTitleBar(self.documentPath) else: self.topLevelParent.setTitleBar("") # This is no longer a stand-alone - need to add a simple wrapper to test #if __name__ == '__main__': #app = model.Application(CodePage) #app.MainLoop() --- NEW FILE: macbuild.py --- import os, sys import bundlebuilder import plistlib # I set this to make adding subfolders into the package easier # KEA 2004-07-22 # rather than hard-coding the path # we'll just get the path from this module ##packageroot = "/Users/kevino/oss/eclass/eclass_builder" packageroot = os.path.abspath(os.path.dirname(__file__)) # for the purposes of building the standalone # change to the directory the build script is in to simplify imports os.chdir(packageroot) # Create the AppBuilder myapp = bundlebuilder.AppBuilder(verbosity=1) # Tell it where to find the main script - the one that loads on startup myapp.mainprogram = os.path.join(packageroot, "codeEditor.py") # drag&dropped filenames show up in sys.argv # this doesn't seem to work, need to add additional # import argvemulator in my code? #myapp.argv_emulation=1 # make this app self contained myapp.standalone = 1 myapp.name = "CodeEditor" myapp.plist = plistlib.Plist.fromFile(os.path.join(packageroot, "Info.plist")) # includePackages forces certain packages to be added to the app bundle ##myapp.includePackages.append("encodings") ##myapp.includePackages.append("_xmlplus") # Here you add supporting files and/or folders to your bundle myapp.resources.append(os.path.join(packageroot, "scriptlets")) myapp.resources.append(os.path.join(packageroot, "codeEditor.rsrc.py")) myapp.resources.append(os.path.join(packageroot, "..", "..", "templates", "dialogs", "runOptionsDialog.rsrc.py")) myapp.resources.append(os.path.join(packageroot, "..", "..", "pythoncard_config.txt")) myapp.resources.append(os.path.join(packageroot, "..", "..", "stc-styles.cfg")) # bundlebuilder does not yet have the capability to detect what shared libraries # are needed by your app - so in this case I am adding the wxPython libs manually myapp.libs.append("/usr/local/lib/wxPython-2.5.2.7/lib/libwx_macd-2.5.2.dylib") myapp.libs.append("/usr/local/lib/wxPython-2.5.2.7/lib/libwx_macd-2.5.2.rsrc") myapp.libs.append("/usr/local/lib/wxPython-2.5.2.7/lib/libwx_macd_stc-2.5.2.dylib") # Here we build the app! myapp.setup() myapp.build() --- NEW FILE: tabcodeEditor.py --- #!/usr/bin/env python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" PythonCard Editor (codeEditor) wiki page http://wiki.wxpython.org/index.cgi/PythonCardEditor wxStyledTextCtrl documentation http://wiki.wxpython.org/index.cgi/wxStyledTextCtrl """ from PythonCard import about, configuration, dialog, log, menu, model, resource, util, registry from PythonCard.templates.dialogs import runOptionsDialog import codePage from modules import scriptutils import os, sys import wx [...1172 lines suppressed...] self.currentPage.becomeFocus() self.updateStatusBar() self.updateTitleBar() self.setResourceFile() event.skip() # KEA 2004-08-18 # I'll probably move this functionality into model.Application # and just call a macOpenFile method in the current background class MyApplication(model.Application): # support drag and drop on the application icon on the Mac def MacOpenFile(self, filename): # code to load filename goes here self.backgrounds[0].openFile(filename) if __name__ == '__main__': app = MyApplication(TabCodeEditor) app.MainLoop() --- NEW FILE: restEditor.rsrc.py --- {'application':{'type':'Application', 'name':'codeEditor', 'backgrounds': [ {'type':'Background', 'name':'bgCodeEditor', 'title':'Code Editor PythonCard Application', 'size':(400, 300), 'statusBar':1, 'visible':0, 'style':['resizeable'], 'visible':0, 'menubar': {'type':'MenuBar', 'menus': [ {'type':'Menu', 'name':'menuFile', 'label':'&File', 'items': [ {'type':'MenuItem', 'name':'menuFileNewWindow', 'label':'New Window', }, {'type':'MenuItem', 'name':'menuFileNew', 'label':'&New\tCtrl+N', }, {'type':'MenuItem', 'name':'menuFileOpen', 'label':'&Open\tCtrl+O', }, {'type':'MenuItem', 'name':'menuFileSave', 'label':'&Save\tCtrl+S', }, {'type':'MenuItem', 'name':'menuFileSaveAs', 'label':'Save &As...', }, {'type':'MenuItem', 'name':'menuFileSaveHtml', 'label':'Save HTML As...', 'command':'saveHtml', }, {'type':'MenuItem', 'name':'fileSep1', 'label':'-', }, ## {'type':'MenuItem', ## 'name':'menuFileCheckSyntax', ## 'label':'&Check Syntax (Module)\tAlt+F5', ## 'command':'checkSyntax', ## }, ## {'type':'MenuItem', ## 'name':'menuFileRun', ## 'label':'&Run\tCtrl+R', ## 'command':'fileRun', ## }, ## {'type':'MenuItem', ## 'name':'menuFileRunWithInterpreter', ## 'label':'Run with &interpreter\tCtrl+Shift+R', ## 'command':'fileRunWithInterpreter', ## }, ## {'type':'MenuItem', ## 'name':'menuFileRunOptions', ## 'label':'Run Options...', ## 'command':'fileRunOptions', ## }, ## {'type':'MenuItem', ## 'name':'fileSep2', ## 'label':'-', ## }, {'type':'MenuItem', 'name':'menuFilePageSetup', 'label':'Page Set&up...', }, {'type':'MenuItem', 'name':'menuFilePrint', 'label':'&Print...\tCtrl+P', }, {'type':'MenuItem', 'name':'menuFilePrintPreview', 'label':'Print Pre&view', }, {'type':'MenuItem', 'name':'fileSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuFileExit', 'label':'E&xit\tAlt+X', 'command':'exit', }, ] }, {'type':'Menu', 'name':'Edit', 'label':'&Edit', 'items': [ {'type':'MenuItem', 'name':'menuEditUndo', 'label':'&Undo\tCtrl+Z', }, {'type':'MenuItem', 'name':'menuEditRedo', 'label':'&Redo\tCtrl+Y', }, {'type':'MenuItem', 'name':'editSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditCut', 'label':'Cu&t\tCtrl+X', }, {'type':'MenuItem', 'name':'menuEditCopy', 'label':'&Copy\tCtrl+C', }, {'type':'MenuItem', 'name':'menuEditPaste', 'label':'&Paste\tCtrl+V', }, {'type':'MenuItem', 'name':'editSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditFind', 'label':'&Find...\tCtrl+F', 'command':'doEditFind', }, {'type':'MenuItem', 'name':'menuEditFindNext', 'label':'&Find Next\tF3', 'command':'doEditFindNext', }, {'type':'MenuItem', 'name':'menuEditFindFiles', 'label':'Find in Files...\tAlt+F3', 'command':'findFiles', }, {'type':'MenuItem', 'name':'menuEditReplace', 'label':'&Replace...\tCtrl+H', 'command':'doEditFindReplace', }, {'type':'MenuItem', 'name':'menuEditGoTo', 'label':'&Go To...\tCtrl+G', 'command':'doEditGoTo', }, {'type':'MenuItem', 'name':'editSep3', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditReplaceTabs', 'label':'&Replace tabs with spaces', 'command':'doEditReplaceTabs', }, {'type':'MenuItem', 'name':'editSep3', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditClear', 'label':'Cle&ar\tDel', }, {'type':'MenuItem', 'name':'menuEditSelectAll', 'label':'Select A&ll\tCtrl+A', }, {'type':'MenuItem', 'name':'editSep4', 'label':'-', }, {'type':'MenuItem', 'name':'menuEditIndentRegion', 'label':'&Indent Region', 'command':'indentRegion', }, {'type':'MenuItem', 'name':'menuEditDedentRegion', 'label':'&Dedent Region', 'command':'dedentRegion', }, {'type':'MenuItem', 'name':'menuEditCommentRegion', 'label':'Comment &out region\tAlt+3', 'command':'commentRegion', }, {'type':'MenuItem', 'name':'menuEditUncommentRegion', 'label':'U&ncomment region\tShift+Alt+3', 'command':'uncommentRegion', }, ] }, {'type':'Menu', 'name':'menuView', 'label':'&View', 'items': [ {'type':'MenuItem', 'name':'menuViewWhitespace', 'label':'&Whitespace', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewIndentationGuides', 'label':'Indentation &guides', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewRightEdgeIndicator', 'label':'&Right edge indicator', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewEndOfLineMarkers', 'label':'&End-of-line markers', 'checkable':1, }, {'type':'MenuItem', 'name':'menuViewFixedFont', 'label':'&Fixed Font', 'enabled':0, 'checkable':1, }, {'type':'MenuItem', 'name':'viewSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuViewLineNumbers', 'label':'&Line Numbers', 'checkable':1, 'checked':1, }, {'type':'MenuItem', 'name':'menuViewCodeFolding', 'label':'&Code Folding', 'checkable':1, 'checked':0, }, {'type':'MenuItem', 'name':'viewSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuViewPreviewHTML', 'label':'&Preview HTML\tCtrl+1', 'command':'previewPost', }, {'type':'MenuItem', 'name':'menuViewSourceIsHtml', 'label':'Source is HTML', 'checkable':1, 'checked':0, }, ] }, {'type':'Menu', 'name':'menuFormat', 'label':'F&ormat', 'items': [ {'type':'MenuItem', 'name':'menuFormatStyles', 'label':'&Styles...', 'command':'doSetStyles', }, {'type':'MenuItem', 'name':'menuFormatWrap', 'label':'&Wrap Lines', 'checkable':1, }, {'type':'MenuItem', 'name':'formatSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuFormatRender', 'label':'Render Page\tCtrl+R', 'command':'previewPost', }, {'type':'MenuItem', 'name':'menuFormatRenderOnReturn', 'label':'Render on Return', 'checkable':1, 'checked':1, }, ] }, {'type':'Menu', 'name':'menuScriptlet', 'label':'&Shell', 'items': [ {'type':'MenuItem', 'name':'menuScriptletShell', 'label':'&Shell Window\tF5', }, {'type':'MenuItem', 'name':'menuScriptletNamespace', 'label':'&Namespace Window\tF6', }, {'type':'MenuItem', 'name':'menuScriptletSaveUserConfiguration', 'label':'Save &Configuration', }, {'type':'MenuItem', 'name':'menuShellChangeDirectory', 'label':'Change &Directory...', }, {'type':'MenuItem', 'name':'scriptletSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuScriptletSaveShellSelection', 'label':'Save Shell Selection...', }, {'type':'MenuItem', 'name':'menuScriptletRunScriptlet', 'label':'Run Scriptlet...', }, ] }, {'type':'Menu', 'name':'menuHelp', 'label':'&Help', 'items': [ {'type':'MenuItem', 'name':'menuShellDocumentation', 'label':'&Shell Documentation...', 'command':'showShellDocumentation', }, {'type':'MenuItem', 'name':'menuPythonCardDocumentation', 'label':'&PythonCard Documentation...\tF1', 'command':'showPythonCardDocumentation', }, {'type':'MenuItem', 'name':'menuPythonDocumentation', 'label':'Python &Documentation...', 'command':'showPythonDocumentation', }, {'type':'MenuItem', 'name':'helpSep1', 'label':'-', }, {'type':'MenuItem', 'name':'menuHelpRest', 'label':'reStructuredText Home Page', 'command':'doHelpRest', }, {'type':'MenuItem', 'name':'menuHelpRestQuickReference', 'label':'reStructuredText Quick Reference', 'command':'doHelpRestQuickReference', }, {'type':'MenuItem', 'name':'helpSep2', 'label':'-', }, {'type':'MenuItem', 'name':'menuHelpAbout', 'label':'&About codeEditor...', 'command':'doHelpAbout', }, {'type':'MenuItem', 'name':'menuHelpAboutPythonCard', 'label':'About PythonCard...', 'command':'doHelpAboutPythonCard', }, ] }, ] }, 'strings': { 'saveAs':'Save As', 'about':'About codeEditor...', 'saveAsWildcard':'All files (*.*)|*.*|Python scripts (*.py;*.pyw)|*.pyw;*.PY;*.PYW;*.py|Text files (*.txt;*.text)|*.text;*.TXT;*.TEXT;*.txt|HTML and XML files (*.htm;*.html;*.xml)|*.htm;*.xml;*.HTM;*.HTML;*.XML;*.html', 'chars':'chars', 'gotoLine':'Goto line', 'lines':'lines', 'gotoLineNumber':'Goto line number:', 'documentChangedPrompt':'The text in the %s file has changed.\n\nDo you want to save the changes?', 'untitled':'Untitled', 'sample':'codeEditor sample', 'codeEditor':'codeEditor', 'replaced':'Replaced %d occurances', 'words':'words', 'openFile':'Open file', 'scriptletWildcard':'Python files (*.py)|*.py|All Files (*.*)|*.*', 'document':'Document', }, 'components': [ {'type':'CodeEditor', 'name':'document', 'position':(0, 0), 'size':(250, 100), }, ] # end components } # end background ] # end backgrounds } } --- NEW FILE: resourceEditor.py --- #!/usr/bin/python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ # TODO: Start using exceptions! import os, sys import pprint import webbrowser import wx from PythonCard import about, clipboard, configuration, dialog, graphic, log from PythonCard import menu, model, registry, resource, util from PythonCard.templates.dialogs import runOptionsDialog [...1652 lines suppressed...] event.skip() except: event.skip() def on_showPythonCardDocumentation_command(self, event): global pythoncard_url webbrowser.open(pythoncard_url) def on_showResourceEditorDocumentation_command(self, event): global resourceeditor_url webbrowser.open(resourceeditor_url) if __name__ == '__main__': # now force the property editor to be enabled #configuration('showPropertyEditor', 1) #configuration('showShell', 1) app = model.Application(ResourceEditor) app.MainLoop() --- NEW FILE: restEditor.py --- #!/usr/bin/env python """ __version__ = "$Revision: 1.1 $" __date__ = "$Date: 2004/10/03 23:58:01 $" """ import os from PythonCard import dialog, model from codeEditor import CodeEditor from wx import stc import webbrowser # reST from PythonCard.templates.htmlpreview import HtmlPreview from snippet import restify class RestEditor(CodeEditor): def on_initialize(self, event): super(RestEditor, self).on_initialize(event) self.renderOnReturn = self.menuBar.getChecked('menuFormatRenderOnReturn') self.previewWindow = model.childWindow(self, HtmlPreview) #self.previewWindow.position = (425, -1) self.previewWindow.visible = True self.html = '' # reST def on_previewPost_command(self, event): self.previewWindow.Show() txt = self.components.document.text if self.menuBar.getChecked('menuViewSourceIsHtml'): firstLine = txt[:10].lower() if firstLine.startswith('<!doctype') or firstLine.startswith('<html'): # assume full HTML document html = txt else: html = '<html>\n<head>\n</head>\n<body>\n' + txt + '\n</body>\n</html>\n' else: # KEA 2004-08-15 # snippet.restify is returning None when there is a reST error # what's a better way to provide feedback to the user without barfing # all over the output? rest = restify(txt) if rest: html = '<html>\n<head>\n</head>\n<body>\n' + rest + '\n</body>\n</html>\n' else: html = self.previewWindow.components.html.text # do make sure stylesheets and relative image references can be found # might need to chdir here # won't work until there is a document path curdir = os.getcwd() self.previewWindow.components.html.text = html self.html = html os.chdir(curdir) def on_document_keyDown(self, event): if event.keyCode == 13 and self.renderOnReturn: # since we won't be calling skip, insert a newline manually self.components.document.CmdKeyExecute(stc.STC_CMD_NEWLINE) self.on_previewPost_command(None) else: event.skip() def saveHtmlFile(self, path): try: f = open(path, 'wb') try: f.write(self.html) finally: f.close() except: pass def on_saveHtml_command(self, event): wildcard = "HTML files (*.html)|*.html|All files (*.*)|*.*" #wildcard = self.resource.strings.saveAsWildcard if self.documentPath is None: dir = '' filename = '*.html' else: dir = os.path.dirname(self.documentPath) filename = os.path.splitext(os.path.basename(self.documentPath))[0] + '.html' result = dialog.saveFileDialog(None, self.resource.strings.saveAs, dir, filename, wildcard) if result.accepted: path = result.paths[0] self.saveHtmlFile(path) def on_menuFormatRenderOnReturn_select(self, event): self.renderOnReturn = self.menuBar.getChecked('menuFormatRenderOnReturn') def on_doHelpRest_command(self, event): webbrowser.open('http://docutils.sourceforge.net/rst.html') def on_doHelpRestQuickReference_command(self, event): webbrowser.open('http://docutils.sourceforge.net/docs/user/rst/quickref.html') if __name__ == '__main__': app = model.Application(RestEditor) app.MainLoop() --- NEW FILE: readme.txt --- Last updated: 2002-04-13 This represents the beginnings of a GUI resource (layout) editor for PythonCard. You can view the attributes for all components and menus by selecting the Resource... menu item in the View menu prior to doing a Save or Save As... under the File menu to output a new file. Known Bugs and Issues: There are no constraints applied when the shift key is held down, but there is there a grid for the widgets to "snap to". You can only select one widget at a time. Sizers and anchors are not supported. It is likely anchors will be supported before sizers. Some of the components don't move or resize correctly all the time, you should report problems to the mailing list. The Choice component seems prone to this movement problem. If a component is difficult to select or move, you can always select it via the Property Editor and then change its position attribute via the Property Editor rather than trying to drag the control itself; the sizing handles should also work. There is a bug that causes the top three sizing handles to appear incorrectly, usually when the widget y position is at -1. I am trying to determine if this is actually a problem with wxPython or some rare interaction in the resourceEditor code. [I think this is fixed as of release 0.6.2 -ka] When editing a dialog or other window that doesn't have a menubar, you'll probably need to increase the vertical size of the window by 20 or 30 pixels to compensate for the resourceEditor menubar. Once your layout looks the way you want it you can subtract the pixel padding you added earlier. On Microsoft Windows, the menubar may wrap if the width of the window is not wide enough, in which case you'll need to add even more padding. The next revision of the resourceEditor will use a separate window for doing layout so that the size of a window is always accurate and shows the menubar of the app you're editing. |
From: Alex T. <ale...@us...> - 2004-10-03 23:55:21
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/templates In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9685/templates Log Message: Directory /cvsroot/pythoncard/PythonCard/tools/oneEditor/templates added to the repository |
From: Alex T. <ale...@us...> - 2004-10-03 23:54:39
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/scriptlets In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9531/scriptlets Log Message: Directory /cvsroot/pythoncard/PythonCard/tools/oneEditor/scriptlets added to the repository |
From: Alex T. <ale...@us...> - 2004-10-03 23:53:48
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9342/modules Log Message: Directory /cvsroot/pythoncard/PythonCard/tools/oneEditor/modules added to the repository |
From: Alex T. <ale...@us...> - 2004-10-03 23:53:14
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9194/images Log Message: Directory /cvsroot/pythoncard/PythonCard/tools/oneEditor/images added to the repository |
From: Alex T. <ale...@us...> - 2004-10-03 23:52:07
|
Update of /cvsroot/pythoncard/PythonCard/tools/oneEditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8962/oneEditor Log Message: Directory /cvsroot/pythoncard/PythonCard/tools/oneEditor added to the repository |
From: Kevin A. <ka...@us...> - 2004-10-03 19:43:26
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12233 Modified Files: __version__.py Log Message: switched to list comprehension to avoid duplicating version numbers Index: __version__.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/__version__.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** __version__.py 3 Oct 2004 18:53:22 -0000 1.37 --- __version__.py 3 Oct 2004 19:42:08 -0000 1.38 *************** *** 14,16 **** VERSION = (0, 8, 1) ! VERSION_STRING = '0.8.1' --- 14,16 ---- VERSION = (0, 8, 1) ! VERSION_STRING = ".".join([str(digit) for digit in VERSION]) |
From: Kevin A. <ka...@us...> - 2004-10-03 19:23:15
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7256 Modified Files: debug.py Log Message: renamed cantmodify to cantModify made checkItems, popItems, cantModify attributes of self to avoid duplicate lists added userdata to list of items not to eval, userdata is just a string Index: debug.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/debug.py,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** debug.py 3 Oct 2004 18:53:22 -0000 1.133 --- debug.py 3 Oct 2004 19:21:33 -0000 1.134 *************** *** 181,184 **** --- 181,191 ---- bg = self.parentApp.getCurrentBackground() bg.components.addChangeEventListener(self) + + + self.checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules', 'labels', 'ticks', 'horizontalScrollbar'] + self.popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] + self.cantModify = ['id', 'name', 'alignment', 'layout', 'style', 'border', 'horizontalScrollbar', \ + 'min', 'max', 'columns', 'rules', 'labels', 'ticks'] + wx.EVT_CLOSE(self, self.onCloseMe) wx.StaticText(panel, -1, 'Name : Class', wx.Point(3, 3)) *************** *** 293,308 **** # could be used at runtime? def onSelectUpdate(self, evt): - # make these attributes of self, since they are duplicated below in displayProperty - checkItems = ['enabled', 'visible', 'editable', 'checked', 'default'] - popItems = ['layout', 'border', 'style', 'alignment'] - cantmodify = ['id', 'name', 'alignment', 'layout', 'style', 'border' ] - wName, wClass = self.wComponentList.GetStringSelection().split(" : ") propName = self.wPropertyList.GetStringSelection() ! if propName not in cantmodify: ! if propName in checkItems: value = self.wChecked.GetValue() ! elif propName in popItems: value = self.wPop.GetStringSelection() elif wClass == 'TextArea' and propName == 'text': --- 300,310 ---- # could be used at runtime? def onSelectUpdate(self, evt): wName, wClass = self.wComponentList.GetStringSelection().split(" : ") propName = self.wPropertyList.GetStringSelection() ! if propName not in self.cantModify: ! if propName in self.checkItems: value = self.wChecked.GetValue() ! elif propName in self.popItems: value = self.wPop.GetStringSelection() elif wClass == 'TextArea' and propName == 'text': *************** *** 368,387 **** def displayProperty(self, wName, wClass, propName): - checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules'] - popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] - cantmodify = ['id', 'name', 'alignment', 'layout', 'style', 'border' ] - self.wName.SetLabel(propName + ":") widget = self.parentApp.getCurrentBackground().components[wName] ! if propName in ['label', 'text', 'toolTip'] or propName in checkItems: value = getattr(widget, propName) else: value = str(getattr(widget, propName)) ! if propName in checkItems: self.hideAllBut(self.wChecked) self.wChecked.Show(1) self.wChecked.SetValue(int(value)) ! elif propName in popItems: self.hideAllBut(self.wPop) self.wPop.Show(1) --- 370,385 ---- def displayProperty(self, wName, wClass, propName): self.wName.SetLabel(propName + ":") widget = self.parentApp.getCurrentBackground().components[wName] ! if propName in ['label', 'text', 'toolTip'] or propName in self.checkItems: value = getattr(widget, propName) else: value = str(getattr(widget, propName)) ! if propName in self.checkItems: self.hideAllBut(self.wChecked) self.wChecked.Show(1) self.wChecked.SetValue(int(value)) ! elif propName in self.popItems: self.hideAllBut(self.wPop) self.wPop.Show(1) *************** *** 417,421 **** # this should only display if the attribute is settable # so name, alignment, and others are read-only ! self.wUpdate.Show((propName not in cantmodify) and not (propName == 'items' and wClass == 'RadioGroup')) def onSelectComponentListEvent(self, evt): --- 415,419 ---- # this should only display if the attribute is settable # so name, alignment, and others are read-only ! self.wUpdate.Show((propName not in self.cantModify) and not (propName == 'items' and wClass == 'RadioGroup')) def onSelectComponentListEvent(self, evt): |
From: Kevin A. <ka...@us...> - 2004-10-03 19:22:58
|
Update of /cvsroot/pythoncard/PythonCard/tools/resourceEditor/modules In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7256/tools/resourceEditor/modules Modified Files: propertyEditor.py Log Message: renamed cantmodify to cantModify made checkItems, popItems, cantModify attributes of self to avoid duplicate lists added userdata to list of items not to eval, userdata is just a string Index: propertyEditor.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/resourceEditor/modules/propertyEditor.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** propertyEditor.py 30 Sep 2004 23:04:53 -0000 1.55 --- propertyEditor.py 3 Oct 2004 19:21:34 -0000 1.56 *************** *** 29,32 **** --- 29,38 ---- self._comp.addChangeEventListener(self) + self.checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', \ + 'rules', 'labels', 'ticks', 'horizontalScrollbar'] + self.popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] + self.cantModify = ['id', 'name', 'alignment', 'layout', 'style', 'border', \ + 'horizontalScrollbar', 'min', 'max', 'columns', 'rules', 'labels', 'ticks'] + self.editItems = [self.components.wField, self.components.wColor, self.components.wFont, self.components.wTextArea, *************** *** 183,201 **** def updateComponent(self): - # make these attributes of self, since they are duplicated below in displayProperty - checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules', 'labels', 'ticks', 'horizontalScrollbar'] - popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] - cantmodify = ['id', 'name', 'alignment', 'layout', 'style', 'border', 'horizontalScrollbar', \ - 'min', 'max', 'columns', 'rules', 'labels', 'ticks'] - wName, wClass = self.components.wComponentList.stringSelection.split(" : ") propName = self.components.wPropertyList.stringSelection ! # KEA 2002-02-23 ! ##if propName not in cantmodify: ! #print "updating", wName ! if propName in checkItems: value = self.components.wChecked.checked ! elif propName in popItems: value = self.components.wPop.stringSelection elif propName in ('items', 'userdata') or (wClass == 'TextArea' and propName == 'text'): --- 189,198 ---- def updateComponent(self): wName, wClass = self.components.wComponentList.stringSelection.split(" : ") propName = self.components.wPropertyList.stringSelection ! if propName in self.checkItems: value = self.components.wChecked.checked ! elif propName in self.popItems: value = self.components.wPop.stringSelection elif propName in ('items', 'userdata') or (wClass == 'TextArea' and propName == 'text'): *************** *** 205,209 **** value = self.components.wField.text ! if propName not in ['label', 'stringSelection', 'text', 'toolTip']: try: value = eval(value) --- 202,206 ---- value = self.components.wField.text ! if propName not in ['label', 'stringSelection', 'text', 'toolTip', 'userdata']: try: value = eval(value) *************** *** 254,258 **** #print widget.size, propName, width, height else: ! if (propName in cantmodify) or \ (propName == 'items' and wClass == 'RadioGroup'): order = self._comp.order.index(wName) --- 251,255 ---- #print widget.size, propName, width, height else: ! if (propName in self.cantModify) or \ (propName == 'items' and wClass == 'RadioGroup'): order = self._comp.order.index(wName) *************** *** 358,377 **** def displayProperty(self, wName, wClass, propName): - checkItems = ['enabled', 'visible', 'editable', 'checked', 'default', 'rules', 'labels', 'ticks', 'horizontalScrollbar'] - popItems = ['layout', 'border', 'style', 'alignment', 'stringSelection'] - self.components.wName.text = propName + ":" ##widget = self.components[wName] widget = self._comp[wName] ! if propName in ['label', 'stringSelection', 'text', 'toolTip'] or propName in checkItems: value = getattr(widget, propName) else: value = str(getattr(widget, propName)) ! if propName in checkItems: self.hideAllBut(self.components.wChecked) self.components.wChecked.visible = True self.components.wChecked.checked = value ! elif propName in popItems: self.hideAllBut(self.components.wPop) self.components.wPop.visible = True --- 355,371 ---- def displayProperty(self, wName, wClass, propName): self.components.wName.text = propName + ":" ##widget = self.components[wName] widget = self._comp[wName] ! if propName in ['label', 'stringSelection', 'text', 'toolTip'] or propName in self.checkItems: value = getattr(widget, propName) else: value = str(getattr(widget, propName)) ! if propName in self.checkItems: self.hideAllBut(self.components.wChecked) self.components.wChecked.visible = True self.components.wChecked.checked = value ! elif propName in self.popItems: self.hideAllBut(self.components.wPop) self.components.wPop.visible = True |
From: Kevin A. <ka...@us...> - 2004-10-03 18:55:25
|
Update of /cvsroot/pythoncard/PythonCard/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1099/docs Modified Files: changelog.txt Log Message: renamed ver to VERSION_STRING and added VERSION tuple Index: changelog.txt =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/docs/changelog.txt,v retrieving revision 1.311 retrieving revision 1.312 diff -C2 -d -r1.311 -r1.312 *** changelog.txt 30 Sep 2004 23:04:52 -0000 1.311 --- changelog.txt 3 Oct 2004 18:53:21 -0000 1.312 *************** *** 8,11 **** --- 8,12 ---- Release 0.8.1 2004-10-?? + renamed ver to VERSION_STRING in __version__.py and added VERSION tuple added horizontalScrollbar flag to TextArea component added appendText ScrollLines workaround to TextArea component on Windows |
From: Kevin A. <ka...@us...> - 2004-10-03 18:55:16
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1099 Modified Files: about.py __version__.py debug.py setup.py Log Message: renamed ver to VERSION_STRING and added VERSION tuple Index: debug.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/debug.py,v retrieving revision 1.132 retrieving revision 1.133 diff -C2 -d -r1.132 -r1.133 *** debug.py 12 Aug 2004 19:11:13 -0000 1.132 --- debug.py 3 Oct 2004 18:53:22 -0000 1.133 *************** *** 13,17 **** import font import registry - import __version__ import pprint import configuration --- 13,16 ---- Index: __version__.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/__version__.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** __version__.py 20 Aug 2004 00:20:49 -0000 1.36 --- __version__.py 3 Oct 2004 18:53:22 -0000 1.37 *************** *** 13,15 **** """ ! ver = '0.8.1' --- 13,16 ---- """ ! VERSION = (0, 8, 1) ! VERSION_STRING = '0.8.1' Index: setup.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/setup.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** setup.py 18 Aug 2004 23:08:01 -0000 1.21 --- setup.py 3 Oct 2004 18:53:22 -0000 1.22 *************** *** 84,88 **** setup(name=APPLICATION_NAME, ! version=__version__.ver, description="PythonCard GUI-builder", author="PythonCard Developers", --- 84,88 ---- setup(name=APPLICATION_NAME, ! version=__version__.VERSION_STRING, description="PythonCard GUI-builder", author="PythonCard Developers", Index: about.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/about.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** about.py 1 Oct 2004 00:00:13 -0000 1.5 --- about.py 3 Oct 2004 18:53:22 -0000 1.6 *************** *** 19,23 **** """ ! txt += "PythonCard version: %s\n" % __version__.ver txt += "wxPython version: %s\n" % wx.VERSION_STRING txt += "Python version: %s\n" % sys.version --- 19,23 ---- """ ! txt += "PythonCard version: %s\n" % __version__.VERSION_STRING txt += "wxPython version: %s\n" % wx.VERSION_STRING txt += "Python version: %s\n" % sys.version |
From: Kevin A. <ka...@us...> - 2004-10-03 18:20:47
|
Update of /cvsroot/pythoncard/PythonCard/samples/dialogs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25446/samples/dialogs Modified Files: dialogs.py Log Message: added fitToComponents test until it is part of auto-layout code Index: dialogs.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/samples/dialogs/dialogs.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** dialogs.py 18 Sep 2004 18:20:30 -0000 1.26 --- dialogs.py 3 Oct 2004 18:16:55 -0000 1.27 *************** *** 12,15 **** --- 12,17 ---- class Dialogs(model.Background): + def on_initialize(self, event): + self.fitToComponents(None, 5) def on_listDialogs_select(self, event): |
From: Kevin A. <ka...@us...> - 2004-10-02 15:51:24
|
Update of /cvsroot/pythoncard/PythonCard/components In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24785/components Modified Files: floatcanvas.py Log Message: added try/except block to deal with missing NumPy Index: floatcanvas.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/components/floatcanvas.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** floatcanvas.py 14 Sep 2004 23:16:46 -0000 1.1 --- floatcanvas.py 2 Oct 2004 15:49:57 -0000 1.2 *************** *** 7,59 **** import wx from PythonCard import widget - # I have to do this rename to avoid a name collision - from wx.lib.floatcanvas import FloatCanvas as FCanvas - - class FloatCanvasSpec(widget.WidgetSpec): - def __init__(self): - events = [] - attributes = { - 'size' : { 'presence' : 'optional', 'default' : [ 50, 50 ] }, - } - widget.WidgetSpec.__init__(self, 'FloatCanvas', 'Widget', events, attributes ) - - - class FloatCanvas(widget.Widget, FCanvas.FloatCanvas): - - _spec = FloatCanvasSpec() - - def __init__( self, aParent, aResource ) : - - FCanvas.FloatCanvas.__init__( - self, - aParent, - widget.makeNewId(aResource.id), - #wx.wxPoint(aResource.position[0], aResource.position[1]), - size=aResource.size, - #aResource.items, - #style = wx.wxCLIP_SIBLINGS, - #name = aResource.name, - ProjectionFun = None, - BackgroundColor = "WHITE", - Debug = False, - ) ! widget.Widget.__init__( self, aParent, aResource ) ! # if there are any events to bind this is where we would do it ! #self._bindEvents(event.WIDGET_EVENTS + CanvasEvents) ! # I don't think we need this anymore ! """ ! def __getattr__(self, name): ! if name[:3] == "Add": ! return FloatCanvas.FloatCanvas.__getattr__(self, name) ! else: ! return widget.Widget.__getattr__(self, name) ! """ ! ! import sys ! from PythonCard import registry ! registry.Registry.getInstance().register(sys.modules[__name__].FloatCanvas) --- 7,71 ---- import wx from PythonCard import widget ! try: ! # I have to do this rename to avoid a name collision ! from wx.lib.floatcanvas import FloatCanvas as FCanvas ! FLOATCANVAS_LOADED = True ! # what is a better way of dealing with this error ! # caused by NumPy not being installed? ! # we don't want the component showing up in the resourceEditor ! # but the error message you get if you try and use an ! # application that requires the component isn't very meaningful ! class FloatCanvasSpec(widget.WidgetSpec): ! def __init__(self): ! events = [] ! attributes = { ! 'size' : { 'presence' : 'optional', 'default' : [ 50, 50 ] }, ! } ! widget.WidgetSpec.__init__(self, 'FloatCanvas', 'Widget', events, attributes ) ! ! class FloatCanvas(widget.Widget, FCanvas.FloatCanvas): ! ! _spec = FloatCanvasSpec() ! ! def __init__( self, aParent, aResource ) : ! ! FCanvas.FloatCanvas.__init__( ! self, ! aParent, ! widget.makeNewId(aResource.id), ! #wx.wxPoint(aResource.position[0], aResource.position[1]), ! size=aResource.size, ! #aResource.items, ! #style = wx.wxCLIP_SIBLINGS, ! #name = aResource.name, ! ProjectionFun = None, ! BackgroundColor = "WHITE", ! Debug = False, ! ) ! ! widget.Widget.__init__( self, aParent, aResource ) ! ! # if there are any events to bind this is where we would do it ! #self._bindEvents(event.WIDGET_EVENTS + CanvasEvents) ! ! # I don't think we need this anymore ! ! """ ! def __getattr__(self, name): ! if name[:3] == "Add": ! return FloatCanvas.FloatCanvas.__getattr__(self, name) ! else: ! return widget.Widget.__getattr__(self, name) ! """ ! ! ! import sys ! from PythonCard import registry ! registry.Registry.getInstance().register(sys.modules[__name__].FloatCanvas) ! except ImportError: ! FLOATCANVAS_LOADED = False |
From: Kevin A. <ka...@us...> - 2004-10-01 00:05:09
|
Update of /cvsroot/pythoncard/PythonCard/tools/findfiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31045 Modified Files: findfiles.py Log Message: just open the files with the codeEditor Index: findfiles.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/findfiles/findfiles.py,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** findfiles.py 12 Aug 2004 19:14:21 -0000 1.81 --- findfiles.py 1 Oct 2004 00:05:00 -0000 1.82 *************** *** 372,383 **** # the list of extensions and associated programs to # open with should be user settable ! if os.path.splitext(filename)[-1] in ['.py', '.pyw']: ! program = os.path.join("..", "codeEditor", "codeEditor.pyw") ! if not os.path.exists(program): ! program = os.path.join("..", "codeEditor", "codeEditor.py") ! else: ! program = os.path.join("..", "textEditor", "textEditor.pyw") ! if not os.path.exists(program): ! program = os.path.join("..", "textEditor", "textEditor.py") # throw an exception if textEditor can't be found? log.debug('program: ' + program) --- 372,387 ---- # the list of extensions and associated programs to # open with should be user settable ! ## if os.path.splitext(filename)[-1] in ['.py', '.pyw']: ! # KEA 2004-09-30 ! # just use the codeEditor, it is a better text editor anyway ! # though I will probably add an option to open the file with ! # the resourceEditor as well ! program = os.path.join("..", "codeEditor", "codeEditor.pyw") ! if not os.path.exists(program): ! program = os.path.join("..", "codeEditor", "codeEditor.py") ! ## else: ! ## program = os.path.join("..", "textEditor", "textEditor.pyw") ! ## if not os.path.exists(program): ! ## program = os.path.join("..", "textEditor", "textEditor.py") # throw an exception if textEditor can't be found? log.debug('program: ' + program) |
From: Kevin A. <ka...@us...> - 2004-10-01 00:00:54
|
Update of /cvsroot/pythoncard/PythonCard/docs/html In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30279/html Modified Files: faq.html Log Message: bumped requirements reference to 2.5.2.8 Index: faq.html =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/docs/html/faq.html,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** faq.html 23 Sep 2004 21:16:32 -0000 1.12 --- faq.html 1 Oct 2004 00:00:45 -0000 1.13 *************** *** 33,37 **** A. Yes. We've added a <a href="learning_python.html">Learning Python</a> page to get you started.</p> <p>Q. What do I need to use PythonCard?<br /> ! A. Python 2.3 or higher and wxPython 2.5.2.7 or higher.</p> <p>Q. What Operating Systems are supported?<br /> A. PythonCard runs on every platform that both Python and wxPython are --- 33,37 ---- A. Yes. We've added a <a href="learning_python.html">Learning Python</a> page to get you started.</p> <p>Q. What do I need to use PythonCard?<br /> ! A. Python 2.3 or higher and wxPython 2.5.2.8 or higher.</p> <p>Q. What Operating Systems are supported?<br /> A. PythonCard runs on every platform that both Python and wxPython are |
From: Kevin A. <ka...@us...> - 2004-10-01 00:00:53
|
Update of /cvsroot/pythoncard/PythonCard/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30279 Modified Files: migration_guide.txt Log Message: bumped requirements reference to 2.5.2.8 Index: migration_guide.txt =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/docs/migration_guide.txt,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** migration_guide.txt 26 Aug 2004 18:36:52 -0000 1.6 --- migration_guide.txt 1 Oct 2004 00:00:44 -0000 1.7 *************** *** 14,18 **** Minimum Requirements -------------------- ! Python 2.3 or later and wxPython 2.5.2.7 or later. --- 14,18 ---- Minimum Requirements -------------------- ! Python 2.3 or later and wxPython 2.5.2.8 or later. |
From: Kevin A. <ka...@us...> - 2004-10-01 00:00:22
|
Update of /cvsroot/pythoncard/PythonCard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30108 Modified Files: about.py Log Message: bumped requirements reference to 2.5.2.8 Index: about.py =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/about.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** about.py 18 Aug 2004 16:25:55 -0000 1.4 --- about.py 1 Oct 2004 00:00:13 -0000 1.5 *************** *** 39,43 **** http://lists.sourceforge.net/lists/listinfo/pythoncard-users ! PythonCard requires Python 2.3 or later and wxPython 2.5.2.7 or later. """ dialog.scrolledMessageDialog(parent, txt, aboutTitle) --- 39,43 ---- http://lists.sourceforge.net/lists/listinfo/pythoncard-users ! PythonCard requires Python 2.3 or later and wxPython 2.5.2.8 or later. """ dialog.scrolledMessageDialog(parent, txt, aboutTitle) |
From: Kevin A. <ka...@us...> - 2004-09-30 23:59:15
|
Update of /cvsroot/pythoncard/PythonCard/tools/textEditor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29912/tools/textEditor Modified Files: textEditor.pyw Log Message: fixed findDialog reference Index: textEditor.pyw =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/tools/textEditor/textEditor.pyw,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** textEditor.pyw 15 Aug 2004 17:35:00 -0000 1.75 --- textEditor.pyw 30 Sep 2004 23:59:06 -0000 1.76 *************** *** 388,392 **** """ ! result = findDialog(self, lastFind['searchText'], lastFind['wholeWordsOnly'], lastFind['caseSensitive']) --- 388,392 ---- """ ! result = findDialog.findDialog(self, lastFind['searchText'], lastFind['wholeWordsOnly'], lastFind['caseSensitive']) |