From elguavas@users.sourceforge.net Fri Feb 1 01:32:03 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Thu, 31 Jan 2002 17:32:03 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.30,1.31 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv30594 Modified Files: configDialog.py Log Message: more work on configuration saving Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -r1.30 -r1.31 *** configDialog.py 2002/01/29 08:34:41 1.30 --- configDialog.py 2002/02/01 01:32:01 1.31 *************** *** 37,50 **** 'Shell Stdout Text':('stdout','10'), 'Shell Stderr Text':('stderr','11')} ! #changedItems. When any config item is changed in this dialog, an entry ! #should be made in the relevant section (config type) of this ! #dictionary. The key should be the config file section name and the ! #value a dictionary, whose key:value pairs are item=value pairs for ! #that config file section. ! self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} ! # #defaultItems. This dictionary is loaded with the values from the ! # #default config files. It is used for comparison with self.changedItems ! # #to decide which changed items actually need saving. ! # self.defaultItems=self.GetDefaultItems() self.CreateWidgets() self.resizable(height=FALSE,width=FALSE) --- 37,41 ---- 'Shell Stdout Text':('stdout','10'), 'Shell Stderr Text':('stderr','11')} ! self.ResetChangedItems() #load initial values in changed items dict self.CreateWidgets() self.resizable(height=FALSE,width=FALSE) *************** *** 445,449 **** element=self.themeElements[self.highlightTarget.get()][0] self.AddChangedItem('highlight',theme,element,value) - print params def VarChanged_keyBinding(self,*params): --- 436,439 ---- *************** *** 451,457 **** keySet=self.customKeys.get() event=self.listBindings.get(ANCHOR).split()[0] ! self.AddChangedItem('keys',keySet,event,value) ! print params ! def VarChanged_winWidth(self,*params): value=self.winWidth.get() --- 441,452 ---- keySet=self.customKeys.get() event=self.listBindings.get(ANCHOR).split()[0] ! if idleConf.IsCoreBinding(event): ! #this is a core keybinding ! self.AddChangedItem('keys',keySet,event,value) ! else: #this is an extension key binding ! extName=idleConf.GetExtnNameForEvent(event) ! extKeybindSection=extName+'_cfgBindings' ! self.AddChangedItem('extensions',extKeybindSection,event,value) ! def VarChanged_winWidth(self,*params): value=self.winWidth.get() *************** *** 472,475 **** --- 467,478 ---- self.AddChangedItem('extensions',extension,'enabled',value) + def ResetChangedItems(self): + #changedItems. When any config item is changed in this dialog, an entry + #should be made in the relevant section (config type) of this + #dictionary. The key should be the config file section name and the + #value a dictionary, whose key:value pairs are item=value pairs for + #that config file section. + self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + def AddChangedItem(self,type,section,item,value): value=str(value) #make sure we use a string *************** *** 477,481 **** self.changedItems[type][section]={} self.changedItems[type][section][item]=value - print type,section,item,value def GetDefaultItems(self): --- 480,483 ---- *************** *** 553,562 **** else: keySetName=self.customKeys.get() - prevKeySet=idleConf.GetKeySet(keySetName) #add the new key set to changedItems ! for event in prevKeySet.keys(): eventName=event[2:-2] #trim off the angle brackets self.AddChangedItem('keys',newKeySetName,eventName, ! prevKeySet[event]) #change gui over to the new key set customKeyList=idleConf.GetSectionList('user','keys') --- 555,564 ---- else: keySetName=self.customKeys.get() #add the new key set to changedItems ! prevCoreKeys=idleConf.GetCoreKeys(keySetName) ! for event in prevCoreKeys.keys(): #add core key set to changed items eventName=event[2:-2] #trim off the angle brackets self.AddChangedItem('keys',newKeySetName,eventName, ! string.join(prevCoreKeys[event])) #change gui over to the new key set customKeyList=idleConf.GetSectionList('user','keys') *************** *** 564,568 **** if newName not in customKeyList: customKeyList.append(newName) customKeyList.sort() - print newKeySetName,customKeyList,self.changedItems['keys'][newKeySetName] self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) self.keysAreDefault.set(0) --- 566,569 ---- *************** *** 611,615 **** if newName not in customThemeList: customThemeList.append(newName) customThemeList.sort() - print newThemeName,customThemeList,newTheme self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) self.themeIsBuiltin.set(0) --- 612,615 ---- *************** *** 761,765 **** else: self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) ! else: #user theme selected itemList=idleConf.GetSectionList('user','keys') itemList.sort() --- 761,765 ---- else: self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) ! else: #user key set selected itemList=idleConf.GetSectionList('user','keys') itemList.sort() *************** *** 814,818 **** def SetUserValue(self,configType,section,item,value): - print idleConf.defaultCfg[configType].Get(section,item),value if idleConf.defaultCfg[configType].has_option(section,item): if idleConf.defaultCfg[configType].Get(section,item)==value: --- 814,817 ---- *************** *** 831,840 **** for item in self.changedItems[configType][section].keys(): value=self.changedItems[configType][section][item] - print configType,section,item,value if self.SetUserValue(configType,section,item,value): cfgTypeHasChanges=1 if cfgTypeHasChanges: idleConf.userCfg[configType].Save() ! def Cancel(self): self.destroy() --- 830,839 ---- for item in self.changedItems[configType][section].keys(): value=self.changedItems[configType][section][item] if self.SetUserValue(configType,section,item,value): cfgTypeHasChanges=1 if cfgTypeHasChanges: idleConf.userCfg[configType].Save() ! self.ResetChangedItems() #clear the changed items dict ! def Cancel(self): self.destroy() From elguavas@users.sourceforge.net Fri Feb 1 01:33:38 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Thu, 31 Jan 2002 17:33:38 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.15,1.16 config-keys.def,1.4,1.5 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv30909 Modified Files: configHandler.py config-keys.def Log Message: more work on configuration saving Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** configHandler.py 2002/01/29 08:35:29 1.15 --- configHandler.py 2002/02/01 01:33:36 1.16 *************** *** 347,355 **** return names def GetExtensionKeys(self,extensionName): """ returns a dictionary of the configurable keybindings for a particular extension,as they exist in the dictionary returned by GetCurrentKeySet; ! that is, where previously re-used bindings are disabled. """ keysName=extensionName+'_cfgBindings' --- 347,371 ---- return names + def GetExtnNameForEvent(self,virtualEvent): + """ + Returns the name of the extension that virtualEvent is bound in, or + None if not bound in any extension. + virtualEvent - string, name of the virtual event to test for, without + the enclosing '<< >>' + """ + extName=None + vEvent='<<'+virtualEvent+'>>' + for extn in self.GetExtensions(activeOnly=0): + for event in self.GetExtensionKeys(extn).keys(): + if event == vEvent: + extName=extn + print extName + return extName + def GetExtensionKeys(self,extensionName): """ returns a dictionary of the configurable keybindings for a particular extension,as they exist in the dictionary returned by GetCurrentKeySet; ! that is, where previously used bindings are disabled. """ keysName=extensionName+'_cfgBindings' *************** *** 433,436 **** --- 449,460 ---- return keySet + def IsCoreBinding(self,virtualEvent): + """ + returns true if the virtual event is bound in the core idle keybindings. + virtualEvent - string, name of the virtual event to test for, without + the enclosing '<< >>' + """ + return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys() + def GetCoreKeys(self, keySetName=None): """ *************** *** 443,449 **** """ keyBindings={ ! '<>': ['', ''], ! '<>': ['', ''], ! '<>': ['', ''], '<>': ['', ''], '<>': [''], --- 467,473 ---- """ keyBindings={ ! '<>': ['', ''], ! '<>': ['', ''], ! '<>': ['', ''], '<>': ['', ''], '<>': [''], Index: config-keys.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-keys.def,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** config-keys.def 2002/01/19 00:29:54 1.4 --- config-keys.def 2002/02/01 01:33:36 1.5 *************** *** 7,13 **** [IDLE Classic Windows] ! Copy= ! Cut= ! Paste= beginning-of-line= center-insert= --- 7,13 ---- [IDLE Classic Windows] ! copy= ! cut= ! paste= beginning-of-line= center-insert= *************** *** 41,47 **** [IDLE Classic Unix] ! Copy= ! Cut= ! Paste= beginning-of-line= center-insert= --- 41,47 ---- [IDLE Classic Unix] ! copy= ! cut= ! paste= beginning-of-line= center-insert= From elguavas@users.sourceforge.net Fri Feb 1 03:02:40 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Thu, 31 Jan 2002 19:02:40 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.16,1.17 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv16137 Modified Files: configHandler.py Log Message: improve user config dir handling Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** configHandler.py 2002/02/01 01:33:36 1.16 --- configHandler.py 2002/02/01 03:02:37 1.17 *************** *** 153,177 **** #build idle install path if __name__ != '__main__': # we were imported ! idledir=os.path.dirname(__file__) else: # we were exec'ed (for testing only) ! idledir=os.path.abspath(sys.path[0]) ! #print idledir ! try: #build user home path ! userdir = os.environ['HOME'] #real home directory ! except KeyError: ! userdir = os.getcwd() #hack for os'es without real homedirs ! userdir=os.path.join(userdir,'.idlerc') ! #print userdir ! if not os.path.exists(userdir): ! os.mkdir(userdir) configTypes=('main','extensions','highlight','keys') defCfgFiles={} usrCfgFiles={} for cfgType in configTypes: #build config file names ! defCfgFiles[cfgType]=os.path.join(idledir,'config-'+cfgType+'.def') ! usrCfgFiles[cfgType]=os.path.join(userdir,'config-'+cfgType+'.cfg') for cfgType in configTypes: #create config parsers self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) def GetOption(self, configType, section, option, default=None, type=None): --- 153,195 ---- #build idle install path if __name__ != '__main__': # we were imported ! idleDir=os.path.dirname(__file__) else: # we were exec'ed (for testing only) ! idleDir=os.path.abspath(sys.path[0]) ! userDir=self.GetUserCfgDir() configTypes=('main','extensions','highlight','keys') defCfgFiles={} usrCfgFiles={} for cfgType in configTypes: #build config file names ! defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def') ! usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg') for cfgType in configTypes: #create config parsers self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) + + def GetUserCfgDir(self): + """ + Creates (if required) and returns a filesystem directory for storing + user config files. + """ + cfgDir='.idlerc' + userDir=os.path.expanduser('~') + if userDir != '~': #'HOME' exists as a key in os.environ + if not os.path.exists(userDir): + warn=('\n Warning: HOME environment variable points to\n '+ + userDir+'\n but the path does not exist.\n') + sys.stderr.write(warn) + userDir='~' + if userDir=='~': #we still don't have a home directory + #traditionally idle has defaulted to os.getcwd(), is this adeqate? + userDir = os.getcwd() #hack for no real homedir + userDir=os.path.join(userDir,cfgDir) + if not os.path.exists(userDir): + try: #make the config dir if it doesn't exist yet + os.mkdir(userDir) + except IOError: + warn=('\n Warning: unable to create user config directory\n '+ + userDir+'\n') + sys.stderr.write(warn) + return userDir def GetOption(self, configType, section, option, default=None, type=None): From elguavas@users.sourceforge.net Tue Feb 5 04:50:28 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Mon, 04 Feb 2002 20:50:28 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.31,1.32 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv28319 Modified Files: configDialog.py Log Message: further work on config system and config saving Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** configDialog.py 2002/02/01 01:32:01 1.31 --- configDialog.py 2002/02/05 04:50:26 1.32 *************** *** 11,14 **** --- 11,15 ---- from keybindingDialog import GetKeysDialog from configSectionNameDialog import GetCfgSectionNameDialog + from configHelpSourceEdit import GetHelpSourceDialog class ConfigDialog(Toplevel): """ *************** *** 214,218 **** self.fgHilite.set(1) buttonSaveCustomTheme=Button(frameCustom, ! text='Save as New Custom Theme') #frameTheme labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme') --- 215,219 ---- self.fgHilite.set(1) buttonSaveCustomTheme=Button(frameCustom, ! text='Save as New Custom Theme',command=self.SaveAsNewTheme) #frameTheme labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme') *************** *** 271,275 **** scrollTargetY=Scrollbar(frameTarget) scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) ! self.listBindings=Listbox(frameTarget) self.listBindings.bind('',self.KeyBindingSelected) scrollTargetY.config(command=self.listBindings.yview) --- 272,277 ---- scrollTargetY=Scrollbar(frameTarget) scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) ! self.listBindings=Listbox(frameTarget,takefocus=FALSE, ! exportselection=FALSE) self.listBindings.bind('',self.KeyBindingSelected) scrollTargetY.config(command=self.listBindings.yview) *************** *** 279,283 **** self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', command=self.GetNewKeys,state=DISABLED) ! buttonSaveCustomKeys=Button(frameCustom,text='Save as New Custom Key Set') #frameKeySets labelKeysTitle=Label(frameKeySets,text='Select a Key Set') --- 281,286 ---- self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', command=self.GetNewKeys,state=DISABLED) ! buttonSaveCustomKeys=Button(frameCustom, ! text='Save as New Custom Key Set',command=self.SaveAsNewKeySet) #frameKeySets labelKeysTitle=Label(frameKeySets,text='Select a Key Set') *************** *** 323,327 **** self.winHeight=StringVar(self) self.startupEdit=IntVar(self) ! self.extEnabled=IntVar(self) #widget creation #body --- 326,331 ---- self.winHeight=StringVar(self) self.startupEdit=IntVar(self) ! self.userHelpBrowser=BooleanVar(self) ! self.helpBrowser=StringVar(self) #widget creation #body *************** *** 330,334 **** frameRun=Frame(frame,borderwidth=2,relief=GROOVE) frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) ! frameExt=Frame(frame,borderwidth=2,relief=GROOVE) #frameRun labelRunTitle=Label(frameRun,text='Startup Preferences') --- 334,338 ---- frameRun=Frame(frame,borderwidth=2,relief=GROOVE) frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) ! frameHelp=Frame(frame,borderwidth=2,relief=GROOVE) #frameRun labelRunTitle=Label(frameRun,text='Startup Preferences') *************** *** 347,373 **** entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, width=3) ! #frameExt ! frameExtList=Frame(frameExt) ! frameExtSet=Frame(frameExt) ! labelExtTitle=Label(frameExt,text='Configure IDLE Extensions') ! labelExtListTitle=Label(frameExtList,text='Extension') ! scrollExtList=Scrollbar(frameExtList) ! self.listExt=Listbox(frameExtList,height=5) ! scrollExtList.config(command=self.listExt.yview) ! self.listExt.config(yscrollcommand=scrollExtList.set) ! self.listExt.bind('',self.ExtensionSelected) ! labelExtSetTitle=Label(frameExtSet,text='Settings') ! self.radioEnableExt=Radiobutton(frameExtSet,variable=self.extEnabled, ! value=1,text="enabled",state=DISABLED, ! command=self.ExtensionStateToggled) ! self.radioDisableExt=Radiobutton(frameExtSet,variable=self.extEnabled, ! value=0,text="disabled",state=DISABLED, ! command=self.ExtensionStateToggled) ! self.buttonExtConfig=Button(frameExtSet,text='Configure',state=DISABLED) #widget packing #body frameRun.pack(side=TOP,padx=5,pady=5,fill=X) frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) ! frameExt.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) #frameRun labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5) --- 351,381 ---- entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, width=3) ! #frameHelp ! labelHelpTitle=Label(frameHelp,text='Help Options') ! frameHelpList=Frame(frameHelp) ! frameHelpListButtons=Frame(frameHelpList) ! labelHelpListTitle=Label(frameHelpList,text='Additional (html) Help Sources:') ! scrollHelpList=Scrollbar(frameHelpList) ! self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE, ! exportselection=FALSE) ! scrollHelpList.config(command=self.listHelp.yview) ! self.listHelp.config(yscrollcommand=scrollHelpList.set) ! self.listHelp.bind('',self.HelpSourceSelected) ! self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit', ! state=DISABLED,width=8,command=self.HelpListItemEdit) ! self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add', ! width=8,command=self.HelpListItemAdd) ! self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove', ! state=DISABLED,width=8,command=self.HelpListItemRemove) ! checkHelpBrowser=Checkbutton(frameHelp,variable=self.userHelpBrowser, ! onvalue=1,offvalue=0,text='user specified (html) help browser:', ! command=self.OnCheckUserHelpBrowser) ! self.entryHelpBrowser=Entry(frameHelp,textvariable=self.helpBrowser, ! width=40) #widget packing #body frameRun.pack(side=TOP,padx=5,pady=5,fill=X) frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) ! frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) #frameRun labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5) *************** *** 381,395 **** entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) ! #frameExt ! labelExtTitle.pack(side=TOP,anchor=W,padx=5,pady=5) ! frameExtSet.pack(side=RIGHT,padx=5,pady=5,fill=Y) ! frameExtList.pack(side=RIGHT,padx=5,pady=5,expand=TRUE,fill=BOTH) ! labelExtListTitle.pack(side=TOP,anchor=W) ! scrollExtList.pack(side=RIGHT,anchor=W,fill=Y) ! self.listExt.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) ! labelExtSetTitle.pack(side=TOP,anchor=W) ! self.radioEnableExt.pack(side=TOP,anchor=W) ! self.radioDisableExt.pack(side=TOP,anchor=W) ! self.buttonExtConfig.pack(side=TOP,anchor=W,pady=5) return frame --- 389,404 ---- entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) ! #frameHelp ! labelHelpTitle.pack(side=TOP,anchor=W,padx=5,pady=5) ! frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) ! frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) ! labelHelpListTitle.pack(side=TOP,anchor=W) ! scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y) ! self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) ! self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5) ! self.buttonHelpListAdd.pack(side=TOP,anchor=W) ! self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5) ! checkHelpBrowser.pack(side=TOP,anchor=W,padx=5) ! self.entryHelpBrowser.pack(side=TOP,anchor=W,padx=5,pady=5) return frame *************** *** 476,479 **** --- 485,489 ---- def AddChangedItem(self,type,section,item,value): + print type,section,item,value value=str(value) #make sure we use a string if not self.changedItems[type].has_key(section): *************** *** 520,541 **** bindName=binding.split()[0] #first part, up to first space currentKeySequences=idleConf.GetCurrentKeySet().values() ! newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences) ! if newKeys.result: #new keys were specified if self.keysAreDefault.get(): #current key set is a built-in message=('Your changes will be saved as a new Custom Key Set. '+ 'Enter a name for your new Custom Key Set below.') ! usedNames=idleConf.GetSectionList('user','keys') ! for newName in self.changedItems['keys'].keys(): ! if newName not in usedNames: usedNames.append(newName) ! newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', ! message,usedNames) ! if not newKeySet.result: #user cancelled custom key set creation self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) return else: #create new custom key set based on previously active key set ! self.CreateNewKeySet(newKeySet.result) self.listBindings.delete(listIndex) ! self.listBindings.insert(listIndex,bindName+' - '+newKeys.result) self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) --- 530,548 ---- bindName=binding.split()[0] #first part, up to first space currentKeySequences=idleConf.GetCurrentKeySet().values() ! newKeys=GetKeysDialog(self,'Get New Keys',bindName, ! currentKeySequences).result ! if newKeys: #new keys were specified if self.keysAreDefault.get(): #current key set is a built-in message=('Your changes will be saved as a new Custom Key Set. '+ 'Enter a name for your new Custom Key Set below.') ! newKeySet=self.GetNewKeysName(message) ! if not newKeySet: #user cancelled custom key set creation self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) return else: #create new custom key set based on previously active key set ! self.CreateNewKeySet(newKeySet) self.listBindings.delete(listIndex) ! self.listBindings.insert(listIndex,bindName+' - '+newKeys) self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) *************** *** 545,548 **** --- 552,568 ---- self.listBindings.select_anchor(listIndex) + def GetNewKeysName(self,message): + usedNames=idleConf.GetSectionList('user','keys') + for newName in self.changedItems['keys'].keys(): + if newName not in usedNames: usedNames.append(newName) + newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', + message,usedNames).result + return newKeySet + + def SaveAsNewKeySet(self): + newKeysName=self.GetNewKeysName('New Key Set Name:') + if newKeysName: + self.CreateNewKeySet(newKeysName) + def KeyBindingSelected(self,event): self.buttonNewKeys.config(state=NORMAL) *************** *** 579,591 **** message=('Your changes will be saved as a new Custom Theme. '+ 'Enter a name for your new Custom Theme below.') ! usedNames=idleConf.GetSectionList('user','highlight') ! for newName in self.changedItems['highlight'].keys(): ! if newName not in usedNames: usedNames.append(newName) ! newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', ! message,usedNames) ! if not newTheme.result: #user cancelled custom theme creation return else: #create new custom theme based on previously active theme ! self.CreateNewTheme(newTheme.result) self.colour.set(colourString) self.frameColourSet.config(bg=colourString)#set sample --- 599,607 ---- message=('Your changes will be saved as a new Custom Theme. '+ 'Enter a name for your new Custom Theme below.') ! newTheme=self.GetNewThemeName(message) ! if not newTheme: #user cancelled custom theme creation return else: #create new custom theme based on previously active theme ! self.CreateNewTheme(newTheme) self.colour.set(colourString) self.frameColourSet.config(bg=colourString)#set sample *************** *** 595,598 **** --- 611,627 ---- (self.themeElements[target][0],),{plane:colourString}) + def GetNewThemeName(self,message): + usedNames=idleConf.GetSectionList('user','highlight') + for newName in self.changedItems['highlight'].keys(): + if newName not in usedNames: usedNames.append(newName) + newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', + message,usedNames).result + return newTheme + + def SaveAsNewTheme(self): + newThemeName=self.GetNewThemeName('New Theme Name:') + if newThemeName: + self.CreateNewTheme(newThemeName) + def CreateNewTheme(self,newThemeName): #creates new custom theme based on the previously active theme, *************** *** 667,670 **** --- 696,756 ---- (self.themeElements[element][0],),colours) + def OnCheckUserHelpBrowser(self): + if self.userHelpBrowser.get(): + self.entryHelpBrowser.config(state=NORMAL) + else: + self.entryHelpBrowser.config(state=DISABLED) + + def HelpSourceSelected(self,event): + self.SetHelpListButtonStates() + + def SetHelpListButtonStates(self): + if self.listHelp.size()<1: #no entries in list + self.buttonHelpListEdit.config(state=DISABLED) + self.buttonHelpListRemove.config(state=DISABLED) + else: #there are some entries + if self.listHelp.curselection(): #there currently is a selection + self.buttonHelpListEdit.config(state=NORMAL) + self.buttonHelpListRemove.config(state=NORMAL) + else: #there currently is not a selection + self.buttonHelpListEdit.config(state=DISABLED) + self.buttonHelpListRemove.config(state=DISABLED) + + def HelpListItemAdd(self): + helpSource=GetHelpSourceDialog(self,'New Help Source').result + if helpSource: + self.userHelpList.append( (helpSource[0],helpSource[1]) ) + self.listHelp.insert(END,helpSource[0]+' '+helpSource[1]) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def HelpListItemEdit(self): + itemIndex=self.listHelp.index(ANCHOR) + helpSource=self.userHelpList[itemIndex] + newHelpSource=GetHelpSourceDialog(self,'New Help Source', + menuItem=helpSource[0],filePath=helpSource[1]).result + if (not newHelpSource) or (newHelpSource==helpSource): + return #no changes + self.userHelpList[itemIndex]=newHelpSource + self.listHelp.delete(itemIndex) + self.listHelp.insert(itemIndex,newHelpSource[0]+' '+newHelpSource[1]) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def HelpListItemRemove(self): + itemIndex=self.listHelp.index(ANCHOR) + del(self.userHelpList[itemIndex]) + self.listHelp.delete(itemIndex) + self.UpdateUserHelpChangedItems() + self.SetHelpListButtonStates() + + def UpdateUserHelpChangedItems(self): + #clear and rebuild the HelpFiles secion in self.changedItems + if self.changedItems['main'].has_key('HelpFiles'): + del(self.changedItems['main']['HelpFiles']) + for num in range(1,len(self.userHelpList)+1): + self.AddChangedItem('main','HelpFiles',str(num), + string.join(self.userHelpList[num-1],';')) + def LoadFontCfg(self): ##base editor font selection list *************** *** 785,799 **** self.winWidth.set(idleConf.GetOption('main','EditorWindow','width')) self.winHeight.set(idleConf.GetOption('main','EditorWindow','height')) ! #extensions ! extns=idleConf.GetExtensions(activeOnly=0) ! apply(self.listExt.insert,(END,)+tuple(extns)) ! ! def ExtensionSelected(self,event): ! self.radioEnableExt.config(state=NORMAL) ! self.radioDisableExt.config(state=NORMAL) ! self.buttonExtConfig.config(state=NORMAL) ! extn=self.listExt.get(ANCHOR) ! self.extEnabled.set(idleConf.GetOption('extensions',extn,'enable', ! default=1,type='bool')) def LoadConfigs(self): --- 871,884 ---- self.winWidth.set(idleConf.GetOption('main','EditorWindow','width')) self.winHeight.set(idleConf.GetOption('main','EditorWindow','height')) ! #help browsing ! self.userHelpList=idleConf.GetExtraHelpSourceList('user') ! for helpItem in self.userHelpList: ! self.listHelp.insert(END,helpItem[0]+' '+helpItem[1]) ! self.SetHelpListButtonStates() ! self.userHelpBrowser.set(idleConf.GetOption('main','General', ! 'user-help-browser',default=0,type='bool')) ! self.helpBrowser.set(idleConf.GetOption('main','General', ! 'user-help-browser-command',default='')) ! self.OnCheckUserHelpBrowser() def LoadConfigs(self): *************** *** 809,813 **** ### keys page self.LoadKeyCfg() - ### help page ### general page self.LoadGeneralCfg() --- 894,897 ---- *************** *** 825,828 **** --- 909,915 ---- save configuration changes to user config files. """ + if self.changedItems['main'].has_key('HelpFiles'): + #this section gets completely replaced + idleConf.userCfg['main'].remove_section('HelpFiles') for configType in self.changedItems.keys(): cfgTypeHasChanges=0 From elguavas@users.sourceforge.net Tue Feb 5 04:51:37 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Mon, 04 Feb 2002 20:51:37 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.17,1.18 config-main.def,1.8,1.9 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv28577 Modified Files: configHandler.py config-main.def Log Message: further work on config system and config saving Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** configHandler.py 2002/02/01 03:02:37 1.17 --- configHandler.py 2002/02/05 04:51:35 1.18 *************** *** 9,14 **** # configuration problem notification and resolution. ! import os ! import sys from ConfigParser import ConfigParser, NoOptionError, NoSectionError --- 9,13 ---- # configuration problem notification and resolution. ! import os, sys, string from ConfigParser import ConfigParser, NoOptionError, NoSectionError *************** *** 45,49 **** Get an option list for given section """ ! if self.has_section: return self.options(section) else: #return a default value --- 44,48 ---- Get an option list for given section """ ! if self.has_section(section): return self.options(section) else: #return a default value *************** *** 517,521 **** '<>': [''], '<>': [''] } - if keySetName: for event in keyBindings.keys(): --- 516,519 ---- *************** *** 523,530 **** if binding: #otherwise will keep default keyBindings[event]=binding - return keyBindings ! def LoadCfgFiles(self): """ --- 521,564 ---- if binding: #otherwise will keep default keyBindings[event]=binding return keyBindings ! def GetExtraHelpSourceList(self,configSet): ! """ ! Returns a list of tuples containing the details of any additional ! help sources configured in the requested configSet ('user' or 'default') ! , or an empty list if there are none. Returned tuples are of the form ! form (menu_item , path_to_help_file , option). ! """ ! helpSources=[] ! if configSet=='user': ! cfgParser=self.userCfg['main'] ! elif configSet=='default': ! cfgParser=self.defaultCfg['main'] ! else: ! raise 'Invalid configSet specified' ! options=cfgParser.GetOptionList('HelpFiles') ! for option in options: ! value=cfgParser.Get('HelpFiles',option,default=';') ! if value.find(';')==-1: #malformed config entry with no ';' ! menuItem='' #make these empty ! helpPath='' #so value won't be added to list ! else: #config entry contains ';' as expected ! value=string.split(value,';') ! menuItem=value[0].strip() ! helpPath=value[1].strip() ! if menuItem and helpPath: #neither are empty strings ! helpSources.append( (menuItem,helpPath,option) ) ! return helpSources ! ! def GetAllExtraHelpSourcesList(self): ! """ ! Returns a list of tuples containing the details of all additional help ! sources configured, or an empty list if there are none. Tuples are of ! the format returned by GetExtraHelpSourceList. ! """ ! allHelpSources=( self.GetExtraHelpSourceList('default')+ ! self.GetExtraHelpSourceList('user') ) ! return allHelpSources ! def LoadCfgFiles(self): """ Index: config-main.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-main.def,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** config-main.def 2002/01/22 05:56:40 1.8 --- config-main.def 2002/02/05 04:51:35 1.9 *************** *** 29,50 **** [General] editor-on-startup= 1 ! #run-in-separate-process= 1 ! #help-browser= "" - [HelpFiles] - #idle="IDLE _Help","" - #python="_Python Documentation","" - #additional help sources - 1= - 2= - 3= - 4= - 5= - 6= - 7= - 8= - 9= - 10= - [EditorWindow] width= 80 --- 29,35 ---- [General] editor-on-startup= 1 ! user-help-browser= 0 ! user-help-browser-command= [EditorWindow] width= 80 *************** *** 67,80 **** name= IDLE Classic Windows ! [RecentFiles] ! 1= ! 2= ! 3= ! 4= ! 5= ! 6= ! 7= ! 8= ! 9= ! 10= ! --- 52,73 ---- name= IDLE Classic Windows ! [HelpFiles] ! #additional help sources, must be viewable by an html browser ! #will be listed on the Help/Other Help menu ! #option names are the sequence number of the option ! #values take the form: menu item;/path/to/help/source ! #obviously you can't use a semi-colon in a menu item or path and the path will ! #be platform specific because of path separators, drive specs etc. ! #eg.: ! #1= My Extra Help Source;/usr/share/doc/foo/index.html ! #2= Another Help Source;/path/to/another.html ! ! #[RecentFiles] ! #this section will only be present in the user config file idle-main.cfg ! #where it will record the most recently openned files in the form ! #IndexNum= /full/path/of/file , for display on the File/Recent Files menu ! #it is present here for reference only ! #eg.: ! #1=/most/recently/openned/file ! #2=/next/most/recently/openned/file ! #etc. From elguavas@users.sourceforge.net Tue Feb 5 04:52:34 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Mon, 04 Feb 2002 20:52:34 -0800 Subject: [Idle-dev] CVS: idle configHelpSourceEdit.py,NONE,1.1 configSectionNameDialog.py,1.1,1.2 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv28856 Modified Files: configSectionNameDialog.py Added Files: configHelpSourceEdit.py Log Message: further work on config system and config saving --- NEW FILE: configHelpSourceEdit.py --- """ Dialog that allows user to specify or edit the parameters for a user configured help source. """ from Tkinter import * import tkMessageBox import os class GetHelpSourceDialog(Toplevel): def __init__(self,parent,title,menuItem='',filePath=''): """ menuItem - string, the menu item to edit, if any filePath - string, the help file path to edit, if any """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) self.resizable(height=FALSE,width=FALSE) self.title(title) self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.Cancel) self.parent = parent self.result=None self.CreateWidgets() self.withdraw() #hide while setting geometry self.update_idletasks() #needs to be done here so that the winfo_reqwidth is valid self.geometry("+%d+%d" % ((parent.winfo_rootx()+((parent.winfo_width()/2) -(self.winfo_reqwidth()/2)), parent.winfo_rooty()+((parent.winfo_height()/2) -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent self.deiconify() #geometry set, unhide self.wait_window() def CreateWidgets(self): self.menu=StringVar(self) self.path=StringVar(self) self.fontSize=StringVar(self) self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN) self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH) labelMenu=Label(self.frameMain,anchor=W,justify=LEFT, text='Menu Item:') self.entryMenu=Entry(self.frameMain,textvariable=self.menu,width=30) self.entryMenu.focus_set() labelPath=Label(self.frameMain,anchor=W,justify=LEFT, text='Help File Path:') self.entryPath=Entry(self.frameMain,textvariable=self.path,width=40) self.entryMenu.focus_set() labelMenu.pack(anchor=W,padx=5,pady=3) self.entryMenu.pack(anchor=W,padx=5,pady=3) labelPath.pack(anchor=W,padx=5,pady=3) self.entryPath.pack(anchor=W,padx=5,pady=3) frameButtons=Frame(self) frameButtons.pack(side=BOTTOM,fill=X) self.buttonOk = Button(frameButtons,text='Ok', width=8,command=self.Ok) self.buttonOk.grid(row=0,column=0,padx=5,pady=5) self.buttonCancel = Button(frameButtons,text='Cancel', width=8,command=self.Cancel) self.buttonCancel.grid(row=0,column=1,padx=5,pady=5) def MenuOk(self): #simple validity check for a sensible #menu item name menuOk=1 menu=self.menu.get() menu.strip() if not menu: #no menu item specified tkMessageBox.showerror(title='Menu Item Error', message='No menu item specified.') self.entryMenu.focus_set() menuOk=0 elif len(menu)>30: #menu item name too long tkMessageBox.showerror(title='Menu Item Error', message='Menu item too long. It should be no more '+ 'than 30 characters.') self.entryMenu.focus_set() menuOk=0 return menuOk def PathOk(self): #simple validity check for menu file path pathOk=1 path=self.path.get() path.strip() if not path: #no path specified tkMessageBox.showerror(title='File Path Error', message='No help file path specified.') self.entryPath.focus_set() pathOk=0 elif not os.path.exists(path): tkMessageBox.showerror(title='File Path Error', message='Help file path does not exist.') self.entryPath.focus_set() pathOk=0 return pathOk def Ok(self, event=None): if self.MenuOk(): if self.PathOk(): self.result=( self.menu.get().strip(),self.path.get().strip() ) self.destroy() def Cancel(self, event=None): self.result=None self.destroy() if __name__ == '__main__': #test the dialog root=Tk() def run(): keySeq='' dlg=GetHelpSourceDialog(root,'Get Help Source') print dlg.result Button(root,text='Dialog',command=run).pack() root.mainloop() Index: configSectionNameDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configSectionNameDialog.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** configSectionNameDialog.py 2002/01/24 05:59:05 1.1 --- configSectionNameDialog.py 2002/02/05 04:52:32 1.2 *************** *** 66,73 **** message='No name specified.') nameOk=0 ! elif len(name)>60: #name too long tkMessageBox.showerror(title='Name Error', ! message='Name too long. Keep it to less than '+ ! '60 characters.') nameOk=0 elif name in self.usedNames: --- 66,73 ---- message='No name specified.') nameOk=0 ! elif len(name)>30: #name too long tkMessageBox.showerror(title='Name Error', ! message='Name too long. It should be no more than '+ ! '30 characters.') nameOk=0 elif name in self.usedNames: *************** *** 79,83 **** def Ok(self, event=None): if self.NameOk(): ! self.result=self.name.get() self.destroy() --- 79,83 ---- def Ok(self, event=None): if self.NameOk(): ! self.result=self.name.get().strip() self.destroy() From elguavas@users.sourceforge.net Mon Feb 11 02:19:53 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 10 Feb 2002 18:19:53 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.32,1.33 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv8151 Modified Files: configDialog.py Log Message: further work on config saving Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** configDialog.py 5 Feb 2002 04:50:26 -0000 1.32 --- configDialog.py 11 Feb 2002 02:19:51 -0000 1.33 *************** *** 4,8 **** from Tkinter import * import tkMessageBox, tkColorChooser, tkFont ! import string from configHandler import idleConf --- 4,8 ---- from Tkinter import * import tkMessageBox, tkColorChooser, tkFont ! import string, copy from configHandler import idleConf *************** *** 186,190 **** text.bind('',lambda e: 'break') text.bind('',lambda e: 'break') ! textAndTags=(('#you can click in here','comment'),('\n','normal'), ('#to choose items','comment'),('\n','normal'),('def','keyword'), (' ','normal'),('func','definition'),('(param):','normal'), --- 186,190 ---- text.bind('',lambda e: 'break') text.bind('',lambda e: 'break') ! textAndTags=(('#you can click here','comment'),('\n','normal'), ('#to choose items','comment'),('\n','normal'),('def','keyword'), (' ','normal'),('func','definition'),('(param):','normal'), *************** *** 258,262 **** self.builtinKeys=StringVar(self) self.customKeys=StringVar(self) ! self.keysAreDefault=BooleanVar(self) self.keyBinding=StringVar(self) ##widget creation --- 258,262 ---- self.builtinKeys=StringVar(self) self.customKeys=StringVar(self) ! self.keysAreBuiltin=BooleanVar(self) self.keyBinding=StringVar(self) ##widget creation *************** *** 286,292 **** labelKeysTitle=Label(frameKeySets,text='Select a Key Set') labelTypeTitle=Label(frameKeySets,text='Select : ') ! self.radioKeysBuiltin=Radiobutton(frameKeySets,variable=self.keysAreDefault, value=1,command=self.SetKeysType,text='a Built-in Key Set') ! self.radioKeysCustom=Radiobutton(frameKeySets,variable=self.keysAreDefault, value=0,command=self.SetKeysType,text='a Custom Key Set') self.optMenuKeysBuiltin=DynOptionMenu(frameKeySets, --- 286,292 ---- labelKeysTitle=Label(frameKeySets,text='Select a Key Set') labelTypeTitle=Label(frameKeySets,text='Select : ') ! self.radioKeysBuiltin=Radiobutton(frameKeySets,variable=self.keysAreBuiltin, value=1,command=self.SetKeysType,text='a Built-in Key Set') ! self.radioKeysCustom=Radiobutton(frameKeySets,variable=self.keysAreBuiltin, value=0,command=self.SetKeysType,text='a Custom Key Set') self.optMenuKeysBuiltin=DynOptionMenu(frameKeySets, *************** *** 411,419 **** self.indentBySpaces.trace_variable('w',self.VarChanged_indentBySpaces) self.colour.trace_variable('w',self.VarChanged_colour) self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) self.winWidth.trace_variable('w',self.VarChanged_winWidth) self.winHeight.trace_variable('w',self.VarChanged_winHeight) self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) ! def VarChanged_fontSize(self,*params): value=self.fontSize.get() --- 411,426 ---- self.indentBySpaces.trace_variable('w',self.VarChanged_indentBySpaces) self.colour.trace_variable('w',self.VarChanged_colour) + self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme) + self.customTheme.trace_variable('w',self.VarChanged_customTheme) + self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin) + self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget) self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) + self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys) + self.customKeys.trace_variable('w',self.VarChanged_customKeys) + self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin) self.winWidth.trace_variable('w',self.VarChanged_winWidth) self.winHeight.trace_variable('w',self.VarChanged_winHeight) self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) ! def VarChanged_fontSize(self,*params): value=self.fontSize.get() *************** *** 441,448 **** def VarChanged_colour(self,*params): ! value=self.colour.get() ! theme=self.customTheme.get() ! element=self.themeElements[self.highlightTarget.get()][0] ! self.AddChangedItem('highlight',theme,element,value) def VarChanged_keyBinding(self,*params): --- 448,470 ---- def VarChanged_colour(self,*params): ! self.OnNewColourSet() ! ! def VarChanged_builtinTheme(self,*params): ! value=self.builtinTheme.get() ! self.AddChangedItem('main','Theme','name',value) ! self.PaintThemeSample() ! ! def VarChanged_customTheme(self,*params): ! value=self.customTheme.get() ! self.AddChangedItem('main','Theme','name',value) ! self.PaintThemeSample() ! ! def VarChanged_themeIsBuiltin(self,*params): ! value=self.themeIsBuiltin.get() ! self.AddChangedItem('main','Theme','default',value) ! self.PaintThemeSample() ! ! def VarChanged_highlightTarget(self,*params): ! self.SetHighlightTarget() def VarChanged_keyBinding(self,*params): *************** *** 458,461 **** --- 480,501 ---- self.AddChangedItem('extensions',extKeybindSection,event,value) + def VarChanged_builtinKeys(self,*params): + value=self.builtinKeys.get() + self.AddChangedItem('main','Keys','name',value) + self.LoadKeysList(value) + + def VarChanged_customKeys(self,*params): + value=self.customKeys.get() + self.AddChangedItem('main','Keys','name',value) + self.LoadKeysList(value) + + def VarChanged_keysAreBuiltin(self,*params): + value=self.keysAreBuiltin.get() + self.AddChangedItem('main','Keys','default',value) + if value: + self.LoadKeysList(self.builtinKeys.get()) + else: + self.LoadKeysList(self.customKeys.get()) + def VarChanged_winWidth(self,*params): value=self.winWidth.get() *************** *** 470,479 **** self.AddChangedItem('main','General','editor-on-startup',value) - def ExtensionStateToggled(self): - #callback for the extension enable/disable radio buttons - value=self.extEnabled.get() - extension=self.listExt.get(ANCHOR) - self.AddChangedItem('extensions',extension,'enabled',value) - def ResetChangedItems(self): #changedItems. When any config item is changed in this dialog, an entry --- 510,513 ---- *************** *** 515,519 **** def SetKeysType(self): ! if self.keysAreDefault.get(): self.optMenuKeysBuiltin.config(state=NORMAL) self.optMenuKeysCustom.config(state=DISABLED) --- 549,553 ---- def SetKeysType(self): ! if self.keysAreBuiltin.get(): self.optMenuKeysBuiltin.config(state=NORMAL) self.optMenuKeysCustom.config(state=DISABLED) *************** *** 533,537 **** currentKeySequences).result if newKeys: #new keys were specified ! if self.keysAreDefault.get(): #current key set is a built-in message=('Your changes will be saved as a new Custom Key Set. '+ 'Enter a name for your new Custom Key Set below.') --- 567,571 ---- currentKeySequences).result if newKeys: #new keys were specified ! if self.keysAreBuiltin.get(): #current key set is a built-in message=('Your changes will be saved as a new Custom Key Set. '+ 'Enter a name for your new Custom Key Set below.') *************** *** 547,551 **** self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) ! self.keyBinding.set(newKeys.result) else: self.listBindings.select_set(listIndex) --- 581,585 ---- self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) ! self.keyBinding.set(newKeys) else: self.listBindings.select_set(listIndex) *************** *** 554,559 **** def GetNewKeysName(self,message): usedNames=idleConf.GetSectionList('user','keys') ! for newName in self.changedItems['keys'].keys(): ! if newName not in usedNames: usedNames.append(newName) newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', message,usedNames).result --- 588,593 ---- def GetNewKeysName(self,message): usedNames=idleConf.GetSectionList('user','keys') ! # for newName in self.changedItems['keys'].keys(): ! # if newName not in usedNames: usedNames.append(newName) newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', message,usedNames).result *************** *** 571,599 **** #creates new custom key set based on the previously active key set, #and makes the new key set active ! if self.keysAreDefault.get(): ! keySetName=self.builtinKeys.get() else: ! keySetName=self.customKeys.get() ! #add the new key set to changedItems ! prevCoreKeys=idleConf.GetCoreKeys(keySetName) ! for event in prevCoreKeys.keys(): #add core key set to changed items eventName=event[2:-2] #trim off the angle brackets ! self.AddChangedItem('keys',newKeySetName,eventName, ! string.join(prevCoreKeys[event])) #change gui over to the new key set customKeyList=idleConf.GetSectionList('user','keys') ! for newName in self.changedItems['keys'].keys(): ! if newName not in customKeyList: customKeyList.append(newName) customKeyList.sort() self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) ! self.keysAreDefault.set(0) self.SetKeysType() def GetColour(self): target=self.highlightTarget.get() rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, ! title='Pick new colour for : '+target, ! initialcolor=self.frameColourSet.cget('bg')) ! if colourString: #user didn't cancel if self.themeIsBuiltin.get(): #current theme is a built-in message=('Your changes will be saved as a new Custom Theme. '+ --- 605,695 ---- #creates new custom key set based on the previously active key set, #and makes the new key set active ! if self.keysAreBuiltin.get(): ! prevKeySetName=self.builtinKeys.get() else: ! prevKeySetName=self.customKeys.get() ! # #add the new core key set to changedItems ! # if prevKeySetName in self.changedItems['keys'].keys(): ! # #existing core key set hasn't been saved yet, copy from changedItems ! # self.changedItems['keys'][newKeySetName]=copy.deepcopy( ! # self.changedItems['keys'][prevKeySetName]) #copy core bindings ! # else: #get core key set from config ! prevKeys=idleConf.GetCoreKeys(prevKeySetName) ! ! newKeys={} ! for event in prevKeys.keys(): #add key set to changed items eventName=event[2:-2] #trim off the angle brackets ! binding=string.join(prevKeys[event]) ! newKeys[eventName]=binding ! # self.AddChangedItem('keys',newKeySetName,eventName,binding) ! ! #handle any unsaved changes to prev key set ! if prevKeySetName in self.changedItems['keys'].keys(): ! keySetChanges=self.changedItems['keys'][prevKeySetName] ! for event in keySetChanges.keys(): ! newKeys[event]=keySetChanges[event] ! ! #save the new theme ! self.SaveNewKeySet(newKeySetName,newKeys) ! ! #change gui over to the new key set customKeyList=idleConf.GetSectionList('user','keys') ! # for newName in self.changedItems['keys'].keys(): ! # if newName not in customKeyList: customKeyList.append(newName) customKeyList.sort() self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) ! self.keysAreBuiltin.set(0) self.SetKeysType() + def LoadKeysList(self,keySetName): + reselect=0 + newKeySet=0 + if self.listBindings.curselection(): + reselect=1 + listIndex=self.listBindings.index(ANCHOR) + # if keySetName in self.changedItems['keys'].keys(): + # #new key set, not yet in saved configuration + # newKeySet=1 + # keySet=self.changedItems['keys'][keySetName] #core keys + # for section in self.changedItems['extensions'].keys(): + # #add active extension bindings + # keySet + # else: #key set in existing configuration + + keySet=idleConf.GetKeySet(keySetName) + # print 'copy from new key set:',newKeySet + bindNames=keySet.keys() + bindNames.sort() + self.listBindings.delete(0,END) + for bindName in bindNames: + # if newKeySet: + # key=keySet[bindName] + + key=string.join(keySet[bindName]) #make key(s) into a string + bindName=bindName[2:-2] #trim off the angle brackets + + if keySetName in self.changedItems['keys'].keys(): + #handle any unsaved changes to this key set + if bindName in self.changedItems['keys'][keySetName].keys(): + key=self.changedItems['keys'][keySetName][bindName] + + # else: #convert existing config keys to list display string + # key=string.join(keySet[bindName]) #make key(s) into a string + + self.listBindings.insert(END, bindName+' - '+key) + + if reselect: + self.listBindings.see(listIndex) + self.listBindings.select_set(listIndex) + self.listBindings.select_anchor(listIndex) + def GetColour(self): target=self.highlightTarget.get() + prevColour=self.frameColourSet.cget('bg') rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, ! title='Pick new colour for : '+target,initialcolor=prevColour) ! if colourString and (colourString!=prevColour): ! #user didn't cancel, and they chose a new colour if self.themeIsBuiltin.get(): #current theme is a built-in message=('Your changes will be saved as a new Custom Theme. '+ *************** *** 604,618 **** else: #create new custom theme based on previously active theme self.CreateNewTheme(newTheme) ! self.colour.set(colourString) ! self.frameColourSet.config(bg=colourString)#set sample ! if self.fgHilite.get(): plane='foreground' ! else: plane='background' ! apply(self.textHighlightSample.tag_config, ! (self.themeElements[target][0],),{plane:colourString}) ! def GetNewThemeName(self,message): usedNames=idleConf.GetSectionList('user','highlight') - for newName in self.changedItems['highlight'].keys(): - if newName not in usedNames: usedNames.append(newName) newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', message,usedNames).result --- 700,722 ---- else: #create new custom theme based on previously active theme self.CreateNewTheme(newTheme) ! self.colour.set(colourString) ! else: #current theme is user defined ! self.colour.set(colourString) ! ! def OnNewColourSet(self): ! newColour=self.colour.get() ! self.frameColourSet.config(bg=newColour)#set sample ! if self.fgHilite.get(): plane='foreground' ! else: plane='background' ! sampleElement=self.themeElements[self.highlightTarget.get()][0] ! apply(self.textHighlightSample.tag_config, ! (sampleElement,),{plane:newColour}) ! theme=self.customTheme.get() ! themeElement=sampleElement+'-'+plane ! self.AddChangedItem('highlight',theme,themeElement,newColour) ! print self.changedItems['highlight'][theme] ! def GetNewThemeName(self,message): usedNames=idleConf.GetSectionList('user','highlight') newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', message,usedNames).result *************** *** 634,643 **** themeName=self.customTheme.get() newTheme=idleConf.GetThemeDict(themeType,themeName) ! #add the new theme to changedItems ! self.changedItems['highlight'][newThemeName]=newTheme #change gui over to the new theme customThemeList=idleConf.GetSectionList('user','highlight') - for newName in self.changedItems['highlight'].keys(): - if newName not in customThemeList: customThemeList.append(newName) customThemeList.sort() self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) --- 738,750 ---- themeName=self.customTheme.get() newTheme=idleConf.GetThemeDict(themeType,themeName) ! #apply any of the old theme's unsaved changes to the new theme ! if themeName in self.changedItems['highlight'].keys(): ! themeChanges=self.changedItems['highlight'][themeName] ! for element in themeChanges.keys(): ! newTheme[element]=themeChanges[element] ! #save the new theme ! self.SaveNewTheme(newThemeName,newTheme) #change gui over to the new theme customThemeList=idleConf.GetSectionList('user','highlight') customThemeList.sort() self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) *************** *** 658,664 **** weight=fontWeight,family=fontName) - def SetHighlightTargetBinding(self,*args): - self.SetHighlightTarget() - def SetHighlightTarget(self): if self.highlightTarget.get()=='Cursor': #bg not possible --- 765,768 ---- *************** *** 688,698 **** else: #a user theme theme=self.customTheme.get() ! for element in self.themeElements.keys(): ! colours=idleConf.GetHighlight(theme, self.themeElements[element][0]) ! if element=='Cursor': #cursor sample needs special painting colours['background']=idleConf.GetHighlight(theme, 'normal', fgBg='bg') ! apply(self.textHighlightSample.tag_config, ! (self.themeElements[element][0],),colours) def OnCheckUserHelpBrowser(self): --- 792,810 ---- else: #a user theme theme=self.customTheme.get() ! for elementTitle in self.themeElements.keys(): ! element=self.themeElements[elementTitle][0] ! colours=idleConf.GetHighlight(theme,element) ! if element=='cursor': #cursor sample needs special painting colours['background']=idleConf.GetHighlight(theme, 'normal', fgBg='bg') ! #handle any unsaved changes to this theme ! if theme in self.changedItems['highlight'].keys(): ! themeDict=self.changedItems['highlight'][theme] ! if themeDict.has_key(element+'-foreground'): ! colours['foreground']=themeDict[element+'-foreground'] ! if themeDict.has_key(element+'-background'): ! colours['background']=themeDict[element+'-background'] ! apply(self.textHighlightSample.tag_config,(element,),colours) ! self.SetColourSample() def OnCheckUserHelpBrowser(self): *************** *** 831,840 **** def LoadKeyCfg(self): ##current keys type radiobutton ! self.keysAreDefault.set(idleConf.GetOption('main','Keys','default', type='bool',default=1)) ##currently set keys currentOption=idleConf.CurrentKeys() ##load available keyset option menus ! if self.keysAreDefault.get(): #default theme selected itemList=idleConf.GetSectionList('default','keys') itemList.sort() --- 943,952 ---- def LoadKeyCfg(self): ##current keys type radiobutton ! self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default', type='bool',default=1)) ##currently set keys currentOption=idleConf.CurrentKeys() ##load available keyset option menus ! if self.keysAreBuiltin.get(): #default theme selected itemList=idleConf.GetSectionList('default','keys') itemList.sort() *************** *** 856,867 **** self.SetKeysType() ##load keyset element list ! keySet=idleConf.GetCurrentKeySet() ! bindNames=keySet.keys() ! bindNames.sort() ! for bindName in bindNames: ! key=string.join(keySet[bindName]) #make key(s) into a string ! bindName=bindName[2:-2] #trim off the angle brackets ! self.listBindings.insert(END, bindName+' - '+key) ! def LoadGeneralCfg(self): #startup state --- 968,974 ---- self.SetKeysType() ##load keyset element list ! keySetName=idleConf.CurrentKeys() ! self.LoadKeysList(keySetName) ! def LoadGeneralCfg(self): #startup state *************** *** 897,900 **** --- 1004,1031 ---- self.LoadGeneralCfg() + def SaveNewKeySet(self,keySetName,keySet): + """ + save a newly created core key set. + keySetName - string, the name of the new key set + keySet - dictionary containing the new key set + """ + if not idleConf.userCfg['keys'].has_section(keySetName): + idleConf.userCfg['keys'].add_section(keySetName) + for event in keySet.keys(): + value=keySet[event] + idleConf.userCfg['keys'].SetOption(keySetName,event,value) + + def SaveNewTheme(self,themeName,theme): + """ + save a newly created theme. + themeName - string, the name of the new theme + theme - dictionary containing the new theme + """ + if not idleConf.userCfg['highlight'].has_section(themeName): + idleConf.userCfg['highlight'].add_section(themeName) + for element in theme.keys(): + value=theme[element] + idleConf.userCfg['highlight'].SetOption(themeName,element,value) + def SetUserValue(self,configType,section,item,value): if idleConf.defaultCfg[configType].has_option(section,item): *************** *** 905,911 **** return idleConf.userCfg[configType].SetOption(section,item,value) ! def SaveConfigs(self): """ ! save configuration changes to user config files. """ if self.changedItems['main'].has_key('HelpFiles'): --- 1036,1042 ---- return idleConf.userCfg[configType].SetOption(section,item,value) ! def SaveAllChangedConfigs(self): """ ! save all configuration changes to user config files. """ if self.changedItems['main'].has_key('HelpFiles'): *************** *** 931,935 **** def Apply(self): ! self.SaveConfigs() def Help(self): --- 1062,1066 ---- def Apply(self): ! self.SaveAllChangedConfigs() def Help(self): From elguavas@users.sourceforge.net Mon Feb 11 02:20:55 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 10 Feb 2002 18:20:55 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.18,1.19 config-highlight.def,1.4,1.5 config-keys.def,1.5,1.6 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv8309 Modified Files: configHandler.py config-highlight.def config-keys.def Log Message: further work on config saving Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** configHandler.py 5 Feb 2002 04:51:35 -0000 1.18 --- configHandler.py 11 Feb 2002 02:20:53 -0000 1.19 *************** *** 207,211 **** elif self.defaultCfg[configType].has_option(section,option): return self.defaultCfg[configType].Get(section, option, type=type) ! else: warning=('\n Warning: configHandler.py - IdleConf.GetOption -\n'+ ' problem retrieving configration option '+`option`+'\n'+ --- 207,211 ---- elif self.defaultCfg[configType].has_option(section,option): return self.defaultCfg[configType].Get(section, option, type=type) ! else: #returning default, print warning warning=('\n Warning: configHandler.py - IdleConf.GetOption -\n'+ ' problem retrieving configration option '+`option`+'\n'+ *************** *** 312,316 **** 'console-background':'#ffffff' } for element in theme.keys(): ! colour=cfgParser.Get(type,themeName,element,default=theme[element]) theme[element]=colour return theme --- 312,325 ---- 'console-background':'#ffffff' } for element in theme.keys(): ! print 'themeName:',themeName,'theme exists:',cfgParser.has_section( ! themeName) ! if not cfgParser.has_option(themeName,element): ! #we are going to return a default, print warning ! warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict'+ ! ' -\n problem retrieving theme element '+`element`+ ! '\n from theme '+`themeName`+'.\n'+ ! ' returning default value: '+`theme[element]`+'\n') ! sys.stderr.write(warning) ! colour=cfgParser.Get(themeName,element,default=theme[element]) theme[element]=colour return theme *************** *** 324,328 **** def CurrentKeys(self): """ ! Returns the name of the currently active theme """ return self.GetOption('main','Keys','name',default='') --- 333,337 ---- def CurrentKeys(self): """ ! Returns the name of the currently active key set """ return self.GetOption('main','Keys','name',default='') Index: config-highlight.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-highlight.def,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** config-highlight.def 4 Jan 2002 03:06:08 -0000 1.4 --- config-highlight.def 11 Feb 2002 02:20:53 -0000 1.5 *************** *** 13,17 **** definition-foreground= #0000ff definition-background= #ffffff ! hilite-foreground= #ffffff hilite-background= gray break-foreground= #ff7777 --- 13,17 ---- definition-foreground= #0000ff definition-background= #ffffff ! hilite-foreground= #000000 hilite-background= gray break-foreground= #ff7777 *************** *** 32,37 **** [IDLE New] ! bold-foreground= #000000 ! bold-background= #ffffff keyword-foreground= #ff7700 keyword-background= #ffffff --- 32,37 ---- [IDLE New] ! normal-foreground= #000000 ! normal-background= #ffffff keyword-foreground= #ff7700 keyword-background= #ffffff *************** *** 42,46 **** definition-foreground= #0000ff definition-background= #ffffff ! hilite-foreground= #ffffff hilite-background= gray break-foreground= #ff7777 --- 42,46 ---- definition-foreground= #0000ff definition-background= #ffffff ! hilite-foreground= #000000 hilite-background= gray break-foreground= #ff7777 Index: config-keys.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-keys.def,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** config-keys.def 1 Feb 2002 01:33:36 -0000 1.5 --- config-keys.def 11 Feb 2002 02:20:53 -0000 1.6 *************** *** 10,14 **** cut= paste= ! beginning-of-line= center-insert= close-all-windows= --- 10,14 ---- cut= paste= ! beginning-of-line= center-insert= close-all-windows= *************** *** 61,64 **** --- 61,65 ---- python-context-help= redo= + remove-selection= save-copy-of-window-as-file= save-window-as-file= From elguavas@users.sourceforge.net Mon Feb 11 02:28:21 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 10 Feb 2002 18:28:21 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.33,1.34 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv9313 Modified Files: configDialog.py Log Message: further work on config saving Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -r1.33 -r1.34 *** configDialog.py 11 Feb 2002 02:19:51 -0000 1.33 --- configDialog.py 11 Feb 2002 02:28:19 -0000 1.34 *************** *** 588,593 **** def GetNewKeysName(self,message): usedNames=idleConf.GetSectionList('user','keys') - # for newName in self.changedItems['keys'].keys(): - # if newName not in usedNames: usedNames.append(newName) newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', message,usedNames).result --- 588,591 ---- *************** *** 609,620 **** else: prevKeySetName=self.customKeys.get() - # #add the new core key set to changedItems - # if prevKeySetName in self.changedItems['keys'].keys(): - # #existing core key set hasn't been saved yet, copy from changedItems - # self.changedItems['keys'][newKeySetName]=copy.deepcopy( - # self.changedItems['keys'][prevKeySetName]) #copy core bindings - # else: #get core key set from config prevKeys=idleConf.GetCoreKeys(prevKeySetName) - newKeys={} for event in prevKeys.keys(): #add key set to changed items --- 607,611 ---- *************** *** 622,627 **** binding=string.join(prevKeys[event]) newKeys[eventName]=binding - # self.AddChangedItem('keys',newKeySetName,eventName,binding) - #handle any unsaved changes to prev key set if prevKeySetName in self.changedItems['keys'].keys(): --- 613,616 ---- *************** *** 629,641 **** for event in keySetChanges.keys(): newKeys[event]=keySetChanges[event] - #save the new theme self.SaveNewKeySet(newKeySetName,newKeys) - - #change gui over to the new key set customKeyList=idleConf.GetSectionList('user','keys') - # for newName in self.changedItems['keys'].keys(): - # if newName not in customKeyList: customKeyList.append(newName) customKeyList.sort() self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) --- 618,625 ---- *************** *** 649,683 **** reselect=1 listIndex=self.listBindings.index(ANCHOR) - # if keySetName in self.changedItems['keys'].keys(): - # #new key set, not yet in saved configuration - # newKeySet=1 - # keySet=self.changedItems['keys'][keySetName] #core keys - # for section in self.changedItems['extensions'].keys(): - # #add active extension bindings - # keySet - # else: #key set in existing configuration - keySet=idleConf.GetKeySet(keySetName) - # print 'copy from new key set:',newKeySet bindNames=keySet.keys() bindNames.sort() self.listBindings.delete(0,END) for bindName in bindNames: - # if newKeySet: - # key=keySet[bindName] - key=string.join(keySet[bindName]) #make key(s) into a string bindName=bindName[2:-2] #trim off the angle brackets - if keySetName in self.changedItems['keys'].keys(): #handle any unsaved changes to this key set if bindName in self.changedItems['keys'][keySetName].keys(): key=self.changedItems['keys'][keySetName][bindName] - - # else: #convert existing config keys to list display string - # key=string.join(keySet[bindName]) #make key(s) into a string - self.listBindings.insert(END, bindName+' - '+key) - if reselect: self.listBindings.see(listIndex) --- 633,648 ---- From elguavas@users.sourceforge.net Mon Feb 11 02:51:20 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 10 Feb 2002 18:51:20 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.19,1.20 configDialog.py,1.34,1.35 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv12615 Modified Files: configHandler.py configDialog.py Log Message: base GetHighlight on GetThemeDict for better defaults Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** configHandler.py 11 Feb 2002 02:20:53 -0000 1.19 --- configHandler.py 11 Feb 2002 02:51:18 -0000 1.20 *************** *** 239,257 **** e.g., a tag_config call), otherwise fg or bg colour only as specified. """ ! #get some fallback defaults ! defaultFg=self.GetOption('highlight', theme, 'normal' + "-foreground", ! default='#000000') ! defaultBg=self.GetOption('highlight', theme, 'normal' + "-background", ! default='#ffffff') ! #try for requested element colours ! fore = self.GetOption('highlight', theme, element + "-foreground") ! back = None ! if element == 'cursor': #there is no config value for cursor bg ! back = None else: ! back = self.GetOption('highlight', theme, element + "-background") ! #fall back if required ! if not fore: fore=defaultFg ! if not back: back=defaultBg highlight={"foreground": fore,"background": back} if not fgBg: #return dict of both colours --- 239,251 ---- e.g., a tag_config call), otherwise fg or bg colour only as specified. """ ! if self.defaultCfg['highlight'].has_section(theme): ! themeDict=self.GetThemeDict('default',theme) ! else: ! themeDict=self.GetThemeDict('user',theme) ! fore=themeDict[element+'-foreground'] ! if element=='cursor': #there is no config value for cursor bg ! back=themeDict['normal-background'] else: ! back=themeDict[element+'-background'] highlight={"foreground": fore,"background": back} if not fgBg: #return dict of both colours *************** *** 264,268 **** else: raise 'Invalid fgBg specified' ! def GetThemeDict(self,type,themeName): """ --- 258,262 ---- else: raise 'Invalid fgBg specified' ! def GetThemeDict(self,type,themeName): """ *************** *** 312,317 **** 'console-background':'#ffffff' } for element in theme.keys(): - print 'themeName:',themeName,'theme exists:',cfgParser.has_section( - themeName) if not cfgParser.has_option(themeName,element): #we are going to return a default, print warning --- 306,309 ---- *************** *** 386,390 **** if event == vEvent: extName=extn - print extName return extName --- 378,381 ---- Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -r1.34 -r1.35 *** configDialog.py 11 Feb 2002 02:28:19 -0000 1.34 --- configDialog.py 11 Feb 2002 02:51:18 -0000 1.35 *************** *** 519,523 **** def AddChangedItem(self,type,section,item,value): - print type,section,item,value value=str(value) #make sure we use a string if not self.changedItems[type].has_key(section): --- 519,522 ---- *************** *** 680,684 **** themeElement=sampleElement+'-'+plane self.AddChangedItem('highlight',theme,themeElement,newColour) - print self.changedItems['highlight'][theme] def GetNewThemeName(self,message): --- 679,682 ---- From elguavas@users.sourceforge.net Mon Feb 11 03:45:24 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 10 Feb 2002 19:45:24 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.35,1.36 keybindingDialog.py,1.5,1.6 config-keys.def,1.6,1.7 config-extensions.def,1.4,1.5 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv22295 Modified Files: configDialog.py keybindingDialog.py config-keys.def config-extensions.def Log Message: improvement to keybinding re-use check Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -r1.35 -r1.36 *** configDialog.py 11 Feb 2002 02:51:18 -0000 1.35 --- configDialog.py 11 Feb 2002 03:45:22 -0000 1.36 *************** *** 562,566 **** binding=self.listBindings.get(listIndex) bindName=binding.split()[0] #first part, up to first space ! currentKeySequences=idleConf.GetCurrentKeySet().values() newKeys=GetKeysDialog(self,'Get New Keys',bindName, currentKeySequences).result --- 562,575 ---- binding=self.listBindings.get(listIndex) bindName=binding.split()[0] #first part, up to first space ! if self.keysAreBuiltin.get(): ! currentKeySetName=self.builtinKeys.get() ! else: ! currentKeySetName=self.customKeys.get() ! currentBindings=idleConf.GetCurrentKeySet() ! if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes ! keySetChanges=self.changedItems['keys'][currentKeySetName] ! for event in keySetChanges.keys(): ! currentBindings[event]=keySetChanges[event].split() ! currentKeySequences=currentBindings.values() newKeys=GetKeysDialog(self,'Get New Keys',bindName, currentKeySequences).result Index: keybindingDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/keybindingDialog.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** keybindingDialog.py 24 Jan 2002 06:01:43 -0000 1.5 --- keybindingDialog.py 11 Feb 2002 03:45:22 -0000 1.6 *************** *** 31,47 **** self.keyAlt=StringVar(self) self.keyAlt.set('') - # self.keyMeta=StringVar(self) - # self.keyMeta.set('') self.keyShift=StringVar(self) self.keyShift.set('') - # self.keyFinal1=StringVar(self) - # self.keyFinal1.set('') - # self.keyFinal2=StringVar(self) - # self.keyFinal2.set('') - # self.keyFn1=IntVar(self) - # self.keyFn2=IntVar(self) self.CreateWidgets() self.LoadFinalKeyList() - #self.buttonOk.focus_set() self.withdraw() #hide while setting geometry self.update_idletasks() --- 31,38 ---- *************** *** 92,99 **** text='Alt',variable=self.keyAlt,onvalue='Alt',offvalue='') checkAlt.grid(row=0,column=1,padx=2,sticky=W) - # checkMeta=Checkbutton(self.frameControlsBasic, - # command=self.BuildKeyString, - # text='Meta',variable=self.keyMeta,onvalue='Meta',offvalue='') - # checkMeta.grid(row=0,column=2,padx=2,sticky=W) checkShift=Checkbutton(self.frameControlsBasic, command=self.BuildKeyString, --- 83,86 ---- *************** *** 103,112 **** text="Select the desired modifier\n"+ "keys above, and final key\n"+ - # "keys above, and final key(s)\n"+ "from the list on the right.") labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W) self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10, selectmode=SINGLE) - # selectmode=MULTIPLE) self.listKeysFinal.bind('',self.FinalKeySelected) self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS) --- 90,97 ---- *************** *** 115,121 **** self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set) scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS) - # self.buttonAddNew=Button(self.frameControlsBasic, - # text='Accept Key Sequence',width=25,command=None) - # self.buttonAddNew.grid(row=2,column=0,columnspan=4) self.buttonClear=Button(self.frameControlsBasic, text='Clear Keys',command=self.ClearKeySeq) --- 100,103 ---- Index: config-keys.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-keys.def,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** config-keys.def 11 Feb 2002 02:20:53 -0000 1.6 --- config-keys.def 11 Feb 2002 03:45:22 -0000 1.7 *************** *** 3,75 **** # Where multiple keys are specified for an action: if they are separated # by a space (eg. action= ) then the keys are altenatives, if ! # there is no space (eg. action=key2>) then the keys comprise a ! # single 'emacs style' multi-keystoke binding. [IDLE Classic Windows] ! copy= ! cut= ! paste= ! beginning-of-line= ! center-insert= ! close-all-windows= ! close-window= ! end-of-file= ! python-docs= ! python-context-help= ! history-next= ! history-previous= ! interrupt-execution= ! open-class-browser= ! open-module= ! open-new-window= ! open-window-from-file= ! plain-newline-and-indent= ! redo= ! remove-selection= ! save-copy-of-window-as-file= ! save-window-as-file= ! save-window= ! select-all= ! toggle-auto-coloring= ! undo= ! find= ! find-again= ! find-in-files= ! find-selection= ! replace= ! goto-line= [IDLE Classic Unix] ! copy= ! cut= ! paste= ! beginning-of-line= ! center-insert= ! close-all-windows= ! close-window= ! do-nothing= ! end-of-file= ! history-next= ! history-previous= ! interrupt-execution= ! open-class-browser= ! open-module= ! open-new-window= ! open-window-from-file= ! plain-newline-and-indent= ! python-docs= ! python-context-help= ! redo= ! remove-selection= ! save-copy-of-window-as-file= ! save-window-as-file= ! save-window= ! select-all= ! toggle-auto-coloring= ! undo= ! find= ! find-again= ! find-in-files= ! find-selection= ! replace= ! goto-line= --- 3,77 ---- # Where multiple keys are specified for an action: if they are separated # by a space (eg. action= ) then the keys are altenatives, if ! # there is no space (eg. action=) then the keys comprise a ! # single 'emacs style' multi-keystoke binding. The tk event specifier 'Key' ! # is used in all cases, for consistency in auto key conflict checking in the ! # configuration gui. [IDLE Classic Windows] ! copy= ! cut= ! paste= ! beginning-of-line= ! center-insert= ! close-all-windows= ! close-window= ! end-of-file= ! python-docs= ! python-context-help= ! history-next= ! history-previous= ! interrupt-execution= ! open-class-browser= ! open-module= ! open-new-window= ! open-window-from-file= ! plain-newline-and-indent= ! redo= ! remove-selection= ! save-copy-of-window-as-file= ! save-window-as-file= ! save-window= ! select-all= ! toggle-auto-coloring= ! undo= ! find= ! find-again= ! find-in-files= ! find-selection= ! replace= ! goto-line= [IDLE Classic Unix] ! copy= ! cut= ! paste= ! beginning-of-line= ! center-insert= ! close-all-windows= ! close-window= ! do-nothing= ! end-of-file= ! history-next= ! history-previous= ! interrupt-execution= ! open-class-browser= ! open-module= ! open-new-window= ! open-window-from-file= ! plain-newline-and-indent= ! python-docs= ! python-context-help= ! redo= ! remove-selection= ! save-copy-of-window-as-file= ! save-window-as-file= ! save-window= ! select-all= ! toggle-auto-coloring= ! undo= ! find= ! find-again= ! find-in-files= ! find-selection= ! replace= ! goto-line= Index: config-extensions.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-extensions.def,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** config-extensions.def 19 Jan 2002 10:35:06 -0000 1.4 --- config-extensions.def 11 Feb 2002 03:45:22 -0000 1.5 *************** *** 11,14 **** --- 11,15 ---- # ExtensionName_cfgBindings defines virtual event bindings for the extension # that may be sensibly re-configured. + # See config-keys.def for notes on specifying keys. [FormatParagraph] From dyoo@hkn.eecs.berkeley.edu Tue Feb 12 22:39:34 2002 From: dyoo@hkn.eecs.berkeley.edu (Danny Yoo) Date: Tue, 12 Feb 2002 14:39:34 -0800 (PST) Subject: [Idle-dev] Re: [Python-Help] python 2.2 In-Reply-To: <15465.36982.256474.405475@beluga.mojam.com> Message-ID: On Tue, 12 Feb 2002, Skip Montanaro wrote: > Tom> How do I get IDLE to show the "..." as the secondary prompt instead > Tom> of nothing? > > Good question. I don't use IDLE, so I poked around a little. I > couldn't see anywhere it was gobbling sys.ps2, but it sure seems to be > doing that. Setting it explicitly seems to have no effect either. > Maybe one of the other helpers has encountered this before. I took a look at the source code; the PyShell.py file that defines how the interpreter works in IDLE doesn't appear use sys.ps2. I believe that IDLE ignores sys.ps2 because it really complicates matters in the GUI, especially when one can press backspace to get back to the original line. It also appears that the auto-indent feature might also suffer some problems if we're not careful. In short, getting sys.ps2 to work seems like a somewhat difficult GUI problem with lots of interactions. Let me forward this off to the IDLE-dev mailing list as well; perhaps it's not as bad as I think it might be... *grin* From guido@python.org Wed Feb 13 04:00:30 2002 From: guido@python.org (Guido van Rossum) Date: Tue, 12 Feb 2002 23:00:30 -0500 Subject: [Idle-dev] Re: [Python-Help] python 2.2 In-Reply-To: Your message of "Tue, 12 Feb 2002 14:39:34 PST." References: Message-ID: <200202130400.g1D40UR06012@pcp742651pcs.reston01.va.comcast.net> > I took a look at the source code; the PyShell.py file that defines how the > interpreter works in IDLE doesn't appear use sys.ps2. Um, why would you *want* IDLE to show the secondary prompt? IMO sys.ps2 is a crutch that you don't need if you have multi-line command editing as IDLE has. --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Wed Feb 13 14:22:54 2002 From: guido@python.org (Guido van Rossum) Date: Wed, 13 Feb 2002 09:22:54 -0500 Subject: [Idle-dev] Re: [Python-Help] python 2.2 In-Reply-To: Your message of "Wed, 13 Feb 2002 08:46:18 EST." <1BD91A8EE7B4D411A2C50002A513069EDC70A2@exc_wil06> References: <1BD91A8EE7B4D411A2C50002A513069EDC70A2@exc_wil06> Message-ID: <200202131422.g1DEMsw07885@pcp742651pcs.reston01.va.comcast.net> > I only thought it would help to keep the indents in line. For example: > >>> if x > 5: > y = 6 > else: y = 7 > > 'else' does not line up with 'if' because of the '>>>'. That doesn't bother the parser. If it bothers you, you can always set sys.ps1 to ">>>\n". --Guido van Rossum (home page: http://www.python.org/~guido/) From tim.one@comcast.net Wed Feb 13 06:49:37 2002 From: tim.one@comcast.net (Tim Peters) Date: Wed, 13 Feb 2002 01:49:37 -0500 Subject: [Idle-dev] Re: [Python-Help] python 2.2 In-Reply-To: <200202130400.g1D40UR06012@pcp742651pcs.reston01.va.comcast.net> Message-ID: [Guido] > Um, why would you *want* IDLE to show the secondary prompt? For me, primarily so that the code reads better: the first line after the initial line *appears* to be indented 4 spaces, while the next level of indentation *appears* to be indented 8 more. It's jarring both that the IDLE shell uses 8-space tabs for indents (all my other Python code uses 4 spaces), and that the indention wrt the rightmost non-whitspace character appears to vary across indentation level. It's also a lot easier to paste an IDLE session into doctest if sys.ps2 is "normal" . > IMO sys.ps2 is a crutch that you don't need if you have multi-line > command editing as IDLE has. Which is also a good point. From noreply@sourceforge.net Fri Feb 15 17:14:50 2002 From: noreply@sourceforge.net (Mailer) Date: Fri, 15 Feb 2002 09:14:50 -0800 Subject: [Idle-dev] SourceForge.net: Privacy/Terms and Conditions of Use Update Message-ID: Dear SourceForge.net User, You are receiving this message because you are registered on SourceForge.net. PRIVACY STATEMENT SourceForge.net takes privacy matters very seriously. We wish to advise you that our new Privacy Statement will take effect on March 5th, 2002 for all users of SourceForge.net. The new version reflects name changes from VA Linux Systems to VA Software and from SourceForge to SourceForge.net. Note that the most critical components of our previous Privacy Statement remain in effect. To help ensure that you have ample opportunity to compare our new Privacy Statement with our old, we provide links to both of these documents, below. Old version: http://sourceforge.net/docman/display_doc.php?docid=6049&group_id=1 New version: http://sourceforge.net/docman/display_doc.php?docid=9268&group_id=1 TERMS AND CONDITIONS OF USE We also want to alert you that the Terms and Conditions of Use for SourceForge.net has been updated; this new Terms and Conditions of Use Agreement will take effect on March 5th, 2002 for all users of SourceForge.net. The new document 1.) reflects name changes from VA Linux Systems to VA Software and from SourceForge to SourceForge.net and 2.) describes procedures for claims of copyright infringement. As with the Privacy Statement, the core components remain in effect. To ensure that you have ample opportunity to compare our new Terms of Conditions and Use with our old, we provide links to both of these documents, below. Old version: http://sourceforge.net/docman/display_doc.php?docid=6048&group_id=1 New version: http://sourceforge.net/docman/display_doc.php?docid=9269&group_id=1 Questions or concerns regarding these documents should be directed to Patrick McGovern, Site Director for SourceForge.net email: pat (at) sourceforge.net Thank you, Patrick McGovern Director, SourceForge.net If you believe you have received this message in error, please submit a support request with your email address at the following URL: https://sourceforge.net/tracker/?func=add&group_id=1&atid=200001 From elguavas@users.sourceforge.net Mon Feb 18 01:42:10 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 17 Feb 2002 17:42:10 -0800 Subject: [Idle-dev] CVS: idle configDialog.py,1.36,1.37 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv19166 Modified Files: configDialog.py Log Message: handle user theme and key set deletion Index: configDialog.py =================================================================== RCS file: /cvsroot/idlefork/idle/configDialog.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -r1.36 -r1.37 *** configDialog.py 11 Feb 2002 03:45:22 -0000 1.36 --- configDialog.py 18 Feb 2002 01:42:08 -0000 1.37 *************** *** 227,231 **** self.optMenuThemeCustom=DynOptionMenu(frameTheme, self.customTheme,None,command=None) ! self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme') ##widget packing #body --- 227,232 ---- self.optMenuThemeCustom=DynOptionMenu(frameTheme, self.customTheme,None,command=None) ! self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme', ! command=self.DeleteCustomTheme) ##widget packing #body *************** *** 294,298 **** self.optMenuKeysCustom=DynOptionMenu(frameKeySets, self.customKeys,None,command=None) ! self.buttonDeleteCustomKeys=Button(frameKeySets,text='Delete Custom Key Set') ##widget packing #body --- 295,300 ---- self.optMenuKeysCustom=DynOptionMenu(frameKeySets, self.customKeys,None,command=None) ! self.buttonDeleteCustomKeys=Button(frameKeySets,text='Delete Custom Key Set', ! command=self.DeleteCustomKeys) ##widget packing #body *************** *** 457,462 **** def VarChanged_customTheme(self,*params): value=self.customTheme.get() ! self.AddChangedItem('main','Theme','name',value) ! self.PaintThemeSample() def VarChanged_themeIsBuiltin(self,*params): --- 459,465 ---- def VarChanged_customTheme(self,*params): value=self.customTheme.get() ! if value != '- no custom themes -': ! self.AddChangedItem('main','Theme','name',value) ! self.PaintThemeSample() def VarChanged_themeIsBuiltin(self,*params): *************** *** 487,492 **** def VarChanged_customKeys(self,*params): value=self.customKeys.get() ! self.AddChangedItem('main','Keys','name',value) ! self.LoadKeysList(value) def VarChanged_keysAreBuiltin(self,*params): --- 490,496 ---- def VarChanged_customKeys(self,*params): value=self.customKeys.get() ! if value != '- no custom keys -': ! self.AddChangedItem('main','Keys','name',value) ! self.LoadKeysList(value) def VarChanged_keysAreBuiltin(self,*params): *************** *** 595,599 **** def GetNewKeysName(self,message): ! usedNames=idleConf.GetSectionList('user','keys') newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', message,usedNames).result --- 599,604 ---- def GetNewKeysName(self,message): ! usedNames=(idleConf.GetSectionList('user','keys')+ ! idleConf.GetSectionList('default','keys')) newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', message,usedNames).result *************** *** 658,661 **** --- 663,718 ---- self.listBindings.select_anchor(listIndex) + def DeleteCustomKeys(self): + keySetName=self.customKeys.get() + if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+ + 'to delete the key set '+`keySetName`+' ?'): + return + #remove key set from config + idleConf.userCfg['keys'].remove_section(keySetName) + if self.changedItems['keys'].has_key(keySetName): + del(self.changedItems['keys'][keySetName]) + #write changes + idleConf.userCfg['keys'].Save() + #reload user key set list + itemList=idleConf.GetSectionList('user','keys') + itemList.sort() + if not itemList: + self.radioKeysCustom.config(state=DISABLED) + self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -') + else: + self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + #revert to default key set + self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default')) + self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name')) + #user can't back out of these changes, they must be applied now + self.Apply() + self.SetKeysType() + + def DeleteCustomTheme(self): + themeName=self.customTheme.get() + if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+ + 'to delete the theme '+`themeName`+' ?'): + return + #remove theme from config + idleConf.userCfg['highlight'].remove_section(themeName) + if self.changedItems['highlight'].has_key(themeName): + del(self.changedItems['highlight'][themeName]) + #write changes + idleConf.userCfg['highlight'].Save() + #reload user theme list + itemList=idleConf.GetSectionList('user','highlight') + itemList.sort() + if not itemList: + self.radioThemeCustom.config(state=DISABLED) + self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -') + else: + self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + #revert to default theme + self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default')) + self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name')) + #user can't back out of these changes, they must be applied now + self.Apply() + self.SetThemeType() + def GetColour(self): target=self.highlightTarget.get() *************** *** 690,694 **** def GetNewThemeName(self,message): ! usedNames=idleConf.GetSectionList('user','highlight') newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', message,usedNames).result --- 747,752 ---- def GetNewThemeName(self,message): ! usedNames=(idleConf.GetSectionList('user','highlight')+ ! idleConf.GetSectionList('default','highlight')) newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', message,usedNames).result *************** *** 1026,1029 **** --- 1084,1098 ---- self.ResetChangedItems() #clear the changed items dict + def ActivateConfigChanges(self): + #things that need to be done to make + #applied config changes dynamic: + # + #update editor/shell font and repaint + #dynamically update indentation setttings + #update theme and repaint + #update keybindings and re-bind + #update user help sources menu + pass + def Cancel(self): self.destroy() *************** *** 1035,1038 **** --- 1104,1108 ---- def Apply(self): self.SaveAllChangedConfigs() + self.ActivateConfigChanges() def Help(self): From elguavas@users.sourceforge.net Mon Feb 18 01:43:13 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 17 Feb 2002 17:43:13 -0800 Subject: [Idle-dev] CVS: idle configHandler.py,1.20,1.21 config-keys.def,1.7,1.8 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv19706 Modified Files: configHandler.py config-keys.def Log Message: handle user theme and key set deletion Index: configHandler.py =================================================================== RCS file: /cvsroot/idlefork/idle/configHandler.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** configHandler.py 11 Feb 2002 02:51:18 -0000 1.20 --- configHandler.py 18 Feb 2002 01:43:11 -0000 1.21 *************** *** 519,526 **** for event in keyBindings.keys(): binding=self.GetKeyBinding(keySetName,event) ! if binding: #otherwise will keep default keyBindings[event]=binding return keyBindings ! def GetExtraHelpSourceList(self,configSet): """ --- 519,532 ---- for event in keyBindings.keys(): binding=self.GetKeyBinding(keySetName,event) ! if binding: keyBindings[event]=binding + else: #we are going to return a default, print warning + warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys'+ + ' -\n problem retrieving key binding for event '+ + `event`+'\n from key set '+`keySetName`+'.\n'+ + ' returning default value: '+`keyBindings[event]`+'\n') + sys.stderr.write(warning) return keyBindings ! def GetExtraHelpSourceList(self,configSet): """ Index: config-keys.def =================================================================== RCS file: /cvsroot/idlefork/idle/config-keys.def,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** config-keys.def 11 Feb 2002 03:45:22 -0000 1.7 --- config-keys.def 18 Feb 2002 01:43:11 -0000 1.8 *************** *** 11,15 **** copy= cut= ! paste= beginning-of-line= center-insert= --- 11,15 ---- copy= cut= ! paste= beginning-of-line= center-insert= From elguavas@users.sourceforge.net Mon Feb 18 01:45:46 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sun, 17 Feb 2002 17:45:46 -0800 Subject: [Idle-dev] CVS: idle EditorWindow.py,1.15,1.16 Bindings.py,1.8,1.9 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv20918 Modified Files: EditorWindow.py Bindings.py Log Message: further work on config system Index: EditorWindow.py =================================================================== RCS file: /cvsroot/idlefork/idle/EditorWindow.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** EditorWindow.py 19 Jan 2002 10:40:41 -0000 1.15 --- EditorWindow.py 18 Feb 2002 01:45:43 -0000 1.16 *************** *** 234,238 **** ("format", "F_ormat"), ("run", "_Run"), ! #("settings", "_Settings"), ("windows", "_Windows"), ("help", "_Help"), --- 234,238 ---- ("format", "F_ormat"), ("run", "_Run"), ! ("settings", "_Settings"), ("windows", "_Windows"), ("help", "_Help"), Index: Bindings.py =================================================================== RCS file: /cvsroot/idlefork/idle/Bindings.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** Bindings.py 19 Jan 2002 10:38:51 -0000 1.8 --- Bindings.py 18 Feb 2002 01:45:43 -0000 1.9 *************** *** 38,44 **** ('_Redo', '<>'), None, ! ('Cu_t', '<>'), ! ('_Copy', '<>'), ! ('_Paste', '<>'), ('Select _All', '<>'), None, --- 38,44 ---- ('_Redo', '<>'), None, ! ('Cu_t', '<>'), ! ('_Copy', '<>'), ! ('_Paste', '<>'), ('Select _All', '<>'), None, *************** *** 59,67 **** ('!_Auto-open stack viewer', '<>' ), ]), ! # ('settings', [ ! # ('_Configure Idle...', '<>'), ! # None, ! # ('Revert to _Default Settings', '<>'), ! # ]), ('help', [ ('_IDLE Help...', '<>'), --- 59,67 ---- ('!_Auto-open stack viewer', '<>' ), ]), ! ('settings', [ ! ('_Configure Idle...', '<>'), ! None, ! ('Revert to _Default Settings', '<>'), ! ]), ('help', [ ('_IDLE Help...', '<>'), From jessw@loop.com Mon Feb 18 06:27:37 2002 From: jessw@loop.com (Jesse W) Date: Sun, 17 Feb 2002 22:27:37 -0800 Subject: [Idle-dev] IDLE detection code snippet Message-ID: <3C702E59.7396.FDF741@localhost> Dear IDLE-devl members, A problem that has been faced by people many times is that of detecting when IDLE is running. I think this code is a solution to that problem. Please try it out and see if it works consistently. Jesse Weinstein def IDLEtest(): """Returns 1 when IDLE is running, 0 else. Please let me know (through the IDLE-devl list) if you find a situation where this gives the wrong answer.""" import sys try: if sys.stdin.__module__=='PyShell': return 1 else: return 0 except AttributeError: return 0 From fdrake@zope.com Mon Feb 18 16:06:44 2002 From: fdrake@zope.com (Fred Drake) Date: Mon, 18 Feb 2002 11:06:44 -0500 Subject: [Idle-dev] IDLE detection code snippet In-Reply-To: <3C702E59.7396.FDF741@localhost> Message-ID: On Sun, 17 Feb 2002 22:27:37 -0800 "Jesse W" wrote: > detecting when IDLE is running. I think this code is a > solution to > that problem. Please try it out and see if it works ... > def IDLEtest(): > """Returns 1 when IDLE is running, 0 else. > Please let me know (through the IDLE-devl list) if > you find > a situation where this gives the wrong answer.""" > import sys > try: > if sys.stdin.__module__=='PyShell': > return 1 > else: > return 0 > except AttributeError: > return 0 Simplify: def IDLEtest(): import sys try: return sys.stdin.__module__ == 'PyShell' except AttributeError: return 0 -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From bas@andrew.cmu.edu Sat Feb 23 14:45:12 2002 From: bas@andrew.cmu.edu (Bruce Sherwood) Date: Sat, 23 Feb 2002 09:45:12 -0500 Subject: [Idle-dev] Slow close? Message-ID: <845230364.1014457512@HYPERON.REM.CMU.EDU> I've now run idlefork-0.8.1 on both Red Hat Linux 7.2 on a Dell laptop and on X running on Mac OSX, and something seems wrong which is common to both environments. Click the close box on any of the IDLE windows (source, output, graphics), and it takes several seconds for the window to close. This is unnerving: you think that the click was lost. Is this something others have observed? Would the latest CVS version likely differ in this respect? (My impression is that most of the large amount of work that Stephen Gava has been doing is in the configuration area, which wouldn't seem to affect this window closure problem.) Bruce Sherwood P.S. Though I've not been able to follow the configuration work, I recently had occasion to see its importance. I tried a simple change to the key bindings locally while working on Linux and Unix to match those from Windows with which I'm more familiar (and to avoid collision between Alt-W for copy vs. Alt-W which opens the Window menu -- isn't this a general problem?). All I did was change keydefs.py, and it didn't do what I expected. So keep up the good work, Stephen! From elguavas@users.sourceforge.net Sat Feb 23 23:27:10 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Sat, 23 Feb 2002 15:27:10 -0800 Subject: [Idle-dev] CVS: idle OutputWindow.py,1.2,1.3 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv21617 Modified Files: OutputWindow.py Log Message: tracking changes to python idle: python Patch #520483: Make IDLE OutputWindow handle Unicode. Index: OutputWindow.py =================================================================== RCS file: /cvsroot/idlefork/idle/OutputWindow.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** OutputWindow.py 4 Jul 2001 03:15:10 -0000 1.2 --- OutputWindow.py 23 Feb 2002 23:27:08 -0000 1.3 *************** *** 135,139 **** def write(self, s, tags=(), mark="iomark"): self.text.mark_gravity(mark, RIGHT) ! self.text.insert(mark, str(s), tags) self.text.mark_gravity(mark, LEFT) self.text.see(mark) --- 135,139 ---- def write(self, s, tags=(), mark="iomark"): self.text.mark_gravity(mark, RIGHT) ! self.text.insert(mark, s, tags) self.text.mark_gravity(mark, LEFT) self.text.see(mark) From elguavas@users.sourceforge.net Sun Feb 24 00:13:03 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 24 Feb 2002 11:13:03 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <845230364.1014457512@HYPERON.REM.CMU.EDU> References: <845230364.1014457512@HYPERON.REM.CMU.EDU> Message-ID: <1014509584.464.38.camel@oberon> Bruce Sherwood wrote: > I've now run idlefork-0.8.1 on both Red Hat Linux 7.2 on a Dell laptop and > on X running on Mac OSX, and something seems wrong which is common to both > environments. Click the close box on any of the IDLE windows (source, > output, graphics), and it takes several seconds for the window to close. > This is unnerving: you think that the click was lost. > > Is this something others have observed? Would the latest CVS version likely > differ in this respect? (My impression is that most of the large amount of > work that Stephen Gava has been doing is in the configuration area, which > wouldn't seem to affect this window closure problem.) > I agree that this is unnerving, at the very least it looks sloppy, but it happens for me with all idle versions. I just checked running idlefork-0.7.1 (before the config. system changes), and then with python official idle as distributed with python2.2 and with python2.1, and in all cases I get this lengthy 'pregnant pause' on closing idle windows. I always assumed it was something to do with the code that unloads and frees all the extensions whenever a window instance is destroyed. It has been on one of my vague mental todo lists to look into this at some time in the hazy future, but if someone else would like investigate and possibly improve this problematic behaviour that would be great. > P.S. Though I've not been able to follow the configuration work, I recently >[...] > So keep up the good work, Stephen! Thanks Bruce. If people want to start playing with the new config. system in idlefork via a cvs checkout they will find that many aspects of it are vaguely working (how's that for a guarantee... ;p ) although one big caveat at this point is that config. changes are not yet dynamic (ie. you need to restart idle to make any changes you've made take effect properly), which is what the next stage of work on this will be mainly tacking. Of course it is unstable development code and there will likely still be implementation changes so all normal warnings apply; don't try to use it for real work, don't expect it not to be broken. When the dynamic change applying is working and a few other bits and pieces are tidied up and finished I'll begin making some releases for more general testing consumption. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Sun Feb 24 00:26:35 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 24 Feb 2002 11:26:35 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014509584.464.38.camel@oberon> References: <845230364.1014457512@HYPERON.REM.CMU.EDU> <1014509584.464.38.camel@oberon> Message-ID: <1014510395.2499.3.camel@oberon> > If people want to start playing with the new config. system in idlefork > ... Btw I should also point out if anyone wants to do this that you need to run it under python >= 2.2 . -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From fdrake@acm.org Sun Feb 24 02:18:32 2002 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sat, 23 Feb 2002 21:18:32 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014509584.464.38.camel@oberon> References: <845230364.1014457512@HYPERON.REM.CMU.EDU> <1014509584.464.38.camel@oberon> Message-ID: <15480.19832.121957.711034@grendel.zope.com> Stephen M. Gava writes: > I agree that this is unnerving, at the very least it looks sloppy, but > it happens for me with all idle versions. I just checked running > idlefork-0.7.1 (before the config. system changes), and then with python > official idle as distributed with python2.2 and with python2.1, and in > all cases I get this lengthy 'pregnant pause' on closing idle windows. I > always assumed it was something to do with the code that unloads and > frees all the extensions whenever a window instance is destroyed. I remember something very similar with Grail; closing a browser window came to take so long it appeared to have died. Eventually I added a call to withdraw() for the top-level window, and that made the window disappear from the display immediately. Of course, there was still a lot of object destruction going on, so any windows which remained open were non-responsive, or if it was the last window, control was not returned to the console. This could still be a little unnerving. ;-( -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From noreply@sourceforge.net Sat Feb 23 23:38:43 2002 From: noreply@sourceforge.net (noreply@sourceforge.net) Date: Sat, 23 Feb 2002 15:38:43 -0800 Subject: [Idle-dev] [ idlefork-Patches-521908 ] print Unicode strings in OutputWindow Message-ID: Patches item #521908, was opened at 2002-02-23 15:38 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=309579&aid=521908&group_id=9579 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Jason Orendorff (jorend) Assigned to: Nobody/Anonymous (nobody) Summary: print Unicode strings in OutputWindow Initial Comment: This one-line patch makes OutputWindow handle Unicode correctly. For example, >>> print u'\xbfQu\xe9 pas\xf3?' Without the patch this throws a UnicodeError, not because of any problem with Unicode handling in either Python or Tk, but because IDLE does str(s) on the Unicode string. I just took out the call to str(). Then I searched through IDLE to find where write() is called to make sure it is only called with string or unicode data. "loewis" has checked this in to the Python tip. I've been using it a while here with no ill effects. ---------------------------------------------------------------------- You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=309579&aid=521908&group_id=9579 From bas@andrew.cmu.edu Sun Feb 24 16:07:58 2002 From: bas@andrew.cmu.edu (Bruce Sherwood) Date: Sun, 24 Feb 2002 11:07:58 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014509584.464.38.camel@oberon> Message-ID: <936596224.1014548878@HYPERON.REM.CMU.EDU> Note that the delay in closing Idle windows does NOT afflict the Windows version. I see the delay only on Linux and Unix, which ought to give us a clue as to where to look for a solution. The reason the delay was so striking to me was that until very recently I had only used Idle on Windows, where the windows close instantly. Bruce Sherwood --On Sunday, February 24, 2002 11:13 AM +1100 "Stephen M. Gava" wrote: > I agree that this is unnerving, at the very least it looks sloppy, but > it happens for me with all idle versions. I just checked running > idlefork-0.7.1 (before the config. system changes), and then with python > official idle as distributed with python2.2 and with python2.1, and in > all cases I get this lengthy 'pregnant pause' on closing idle windows. I > always assumed it was something to do with the code that unloads and > frees all the extensions whenever a window instance is destroyed. From guido@python.org Sun Feb 24 22:45:04 2002 From: guido@python.org (Guido van Rossum) Date: Sun, 24 Feb 2002 17:45:04 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: Your message of "Sun, 24 Feb 2002 11:07:58 EST." <936596224.1014548878@HYPERON.REM.CMU.EDU> References: <936596224.1014548878@HYPERON.REM.CMU.EDU> Message-ID: <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> > Note that the delay in closing Idle windows does NOT afflict the Windows > version. I see the delay only on Linux and Unix, which ought to give us a > clue as to where to look for a solution. The reason the delay was so > striking to me was that until very recently I had only used Idle on > Windows, where the windows close instantly. It's also window manager specific. I used to use a very old window manager and my windows closed instantly. Now I use some newfangled thing (I don't even know what it's called, comes with KDE) and I have this problem. Maybe this is a clue? --Guido van Rossum (home page: http://www.python.org/~guido/) From elguavas@users.sourceforge.net Sun Feb 24 23:14:06 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 10:14:06 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> References: <936596224.1014548878@HYPERON.REM.CMU.EDU> <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> Message-ID: <1014592447.4611.16.camel@oberon> Guido van Rossum wrote: > It's also window manager specific. I used to use a very old window > manager and my windows closed instantly. Now I use some newfangled > thing (I don't even know what it's called, comes with KDE) and I have > this problem. Maybe this is a clue? Interesting. This made me vaguely recall that idle didn't used to behave like this for me either. For about the last year I've been mainly using Gnome with the Sawfish window manager, and as I reported previously I get this problem with all idle versions. So, I just tried it under my old fave WindowMaker and lo and behold, no delay at all, then I tried under BlackBox, no delay there either, so I tried it under what is generally considered not exactly a lightweight window manager, Enlightenment, and there was absolutely no delay there either. Since there is no problem under a range of light and heavy weight window managers, but there is a problem under both KDE and Gnome it might suggest that there is something other than the window manager itself in these full on 'operating environments' that is causing the problem (they are both full of object embedding frameworks, session managers, all sorts of stuff), or something in the new 'common window manager spec.' that both Gnome and KDE now support. One way to test this would be if someone could try this under Sawfish _without_ Gnome (I only have the sawfish version which integrates with gnome on my system), if it runs ok there then it is something else in 'operating environment' causing the problem. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Sun Feb 24 23:31:00 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 10:31:00 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014592447.4611.16.camel@oberon> References: <936596224.1014548878@HYPERON.REM.CMU.EDU> <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> <1014592447.4611.16.camel@oberon> Message-ID: <1014593460.8691.3.camel@oberon> > One way to test this would be if > someone could try this under Sawfish _without_ Gnome (I only have the > sawfish version which integrates with gnome on my system), if it runs ok > there then it is something else in 'operating environment' causing the > problem. Ok, I just set that up and tried it. Under plain Sawfish idle closes instantly, under Gnome/Sawfish we have the 'pregnant pause' problem. So it would seem that something other than the window manager itself in these 'desktop environments' is causing the problem. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From noreply@sourceforge.net Sun Feb 24 22:42:06 2002 From: noreply@sourceforge.net (noreply@sourceforge.net) Date: Sun, 24 Feb 2002 14:42:06 -0800 Subject: [Idle-dev] [ idlefork-Patches-521908 ] print Unicode strings in OutputWindow Message-ID: Patches item #521908, was opened at 2002-02-23 15:38 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=309579&aid=521908&group_id=9579 Category: None Group: None >Status: Closed >Resolution: Duplicate Priority: 5 Submitted By: Jason Orendorff (jorend) Assigned to: Nobody/Anonymous (nobody) Summary: print Unicode strings in OutputWindow Initial Comment: This one-line patch makes OutputWindow handle Unicode correctly. For example, >>> print u'\xbfQu\xe9 pas\xf3?' Without the patch this throws a UnicodeError, not because of any problem with Unicode handling in either Python or Tk, but because IDLE does str(s) on the Unicode string. I just took out the call to str(). Then I searched through IDLE to find where write() is called to make sure it is only called with string or unicode data. "loewis" has checked this in to the Python tip. I've been using it a while here with no ill effects. ---------------------------------------------------------------------- >Comment By: Stephen M. Gava (elguavas) Date: 2002-02-24 14:42 Message: Logged In: YES user_id=75867 I already applied this patch to idlefork when it was applied to the python idle tree, as part of the process of tracking changes to idle python. ---------------------------------------------------------------------- You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=309579&aid=521908&group_id=9579 From fdrake@acm.org Mon Feb 25 02:19:29 2002 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sun, 24 Feb 2002 21:19:29 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> References: <936596224.1014548878@HYPERON.REM.CMU.EDU> <200202242245.g1OMj4I10051@pcp742651pcs.reston01.va.comcast.net> Message-ID: <15481.40753.780532.244687@grendel.zope.com> Guido van Rossum writes: > It's also window manager specific. I used to use a very old window > manager and my windows closed instantly. Now I use some newfangled > thing (I don't even know what it's called, comes with KDE) and I have > this problem. Maybe this is a clue? I used to observe this on Grail using FVWM2, so while it may be specific to particular window managers, it may be more due to the preferred approaches to closing windows and ICCCM conformance. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From bas@andrew.cmu.edu Mon Feb 25 02:43:22 2002 From: bas@andrew.cmu.edu (Bruce Sherwood) Date: Sun, 24 Feb 2002 21:43:22 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014593460.8691.3.camel@oberon> Message-ID: <974720944.1014587002@HYPERON.REM.CMU.EDU> Good job! I too have been running Gnome/Sawfish on Linux. However, on the Mac where I also see slow closes I'm running raw X with the Oroborus window manager, not a Gnome or KDE environment. I'm using a "rootless" window manager, which means that windows appear as X windows on top of the Mac OSX graphics environment. (I have just begun to use Mac OSX, so I could be confused about my situation.) Note that it is only Idle that shows the problem. Other programs close instantly. And on Red Hat Linux I believe that many of those fast-closing programs are in fact Python-based (Python 1.5), presumably with tkinter. Odd. And definitely annoying. Bruce Sherwood --On Monday, February 25, 2002 10:31 AM +1100 "Stephen M. Gava" wrote: > Ok, I just set that up and tried it. Under plain Sawfish idle closes > instantly, under Gnome/Sawfish we have the 'pregnant pause' problem. So > it would seem that something other than the window manager itself in > these 'desktop environments' is causing the problem. From elguavas@users.sourceforge.net Mon Feb 25 03:32:17 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 14:32:17 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <974720944.1014587002@HYPERON.REM.CMU.EDU> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> Message-ID: <1014607937.9429.23.camel@oberon> Bruce Sherwood wrote: > I too have been running Gnome/Sawfish on Linux. However, on the Mac where I > also see slow closes I'm running raw X with the Oroborus window manager, > not a Gnome or KDE environment. I'm using a "rootless" window manager, > which means that windows appear as X windows on top of the Mac OSX graphics > environment. (I have just begun to use Mac OSX, so I could be confused > about my situation.) > > Note that it is only Idle that shows the problem. Other programs close > instantly. And on Red Hat Linux I believe that many of those fast-closing > programs are in fact Python-based (Python 1.5), presumably with tkinter. > Odd. And definitely annoying. Yes, I also find that although idle displays this problem here I run quite a few other tkinter apps with no problem on closing windows. Fred L. Drake, Jr. wrote: > I used to observe this on Grail using FVWM2, so while it may be > specific to particular window managers, it may be more due to the > preferred approaches to closing windows and ICCCM conformance. Hmmm. Well window managers under both Gnome and KDE are meant to abide by this 'common window manager spec.' they have, for window hints etc. (under Gnome you can use a variety of window managers, although most linux distros include sawfish by default, and the 'gnome compliant' window managers tend to only load their gnome comliance modules/code when they detect they are running under gnome; under kde 2+ the window manager tends to be the kde default kwm because it is so integrated into the environment), so maybe it could be something along these lines Fred. I have no idea about the X on Aqua situation though. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From fdrake@acm.org Mon Feb 25 03:51:34 2002 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sun, 24 Feb 2002 22:51:34 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014607937.9429.23.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> Message-ID: <15481.46278.52995.335840@grendel.zope.com> Stephen M. Gava writes: > linux distros include sawfish by default, and the 'gnome compliant' > window managers tend to only load their gnome comliance modules/code > when they detect they are running under gnome; under kde 2+ the window > manager tends to be the kde default kwm because it is so integrated into > the environment), so maybe it could be something along these lines Fred. It may be that what I observed with Grail was entirely different; there was certainly no Gnome or KDE in sight at the time. Hard to figure that out now, though. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From elguavas@users.sourceforge.net Mon Feb 25 04:59:36 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 15:59:36 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <15481.46278.52995.335840@grendel.zope.com> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> Message-ID: <1014613176.9839.7.camel@oberon> Fred L. Drake, Jr. wrote: > > It may be that what I observed with Grail was entirely different; > there was certainly no Gnome or KDE in sight at the time. Hard to > figure that out now, though. > Well there's a general vague similarity in the fact that both the grail windows you're talking about and the EditorWindow instances in idle are doing something non-trivial which may involve waiting to destroy objects at close time. Other minor windows in idle close instantly as expected. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Mon Feb 25 05:11:27 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 16:11:27 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014613176.9839.7.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> Message-ID: <1014613887.9835.12.camel@oberon> > Well there's a general vague similarity in the fact that both the grail > windows you're talking about and the EditorWindow instances in idle are > doing something non-trivial which may involve waiting to destroy objects > at close time. Other minor windows in idle close instantly as expected. In fact if you insert: self.top.quit() return at the top of the close() method in EditorWindow, the window closes straight away, which indicates that it's something in all the cleaning up that would normally happen after this that is causing the pause. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Mon Feb 25 05:25:56 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 25 Feb 2002 16:25:56 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014613887.9835.12.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> Message-ID: <1014614756.10111.8.camel@oberon> > In fact if you insert: > > self.top.quit() > return > > at the top of the close() method in EditorWindow, the window closes > straight away, which indicates that it's something in all the cleaning > up that would normally happen after this that is causing the pause. Actually I think I just found the problem. When I moved the above 'quit now' lines two lines down in close(), so that the lines self.top.wm_deiconify() self.top.tkraise() are allowed to execute, the pause returns! So just commenting those two lines like so: def close(self): #self.top.wm_deiconify() #self.top.tkraise() reply = self.maybesave() if reply != "cancel": self._close() return reply causes the EditorWindow instances to begin closing at normal speed (no pause). Can anyone with knowledge of the code base remember why these two seemingly redundant lines are there in the first place, and what the implications would be for just removing them? Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From fdrake@acm.org Mon Feb 25 12:50:08 2002 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Mon, 25 Feb 2002 07:50:08 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014613176.9839.7.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> Message-ID: <15482.13056.157299.721802@grendel.zope.com> Stephen M. Gava writes: > Well there's a general vague similarity in the fact that both the grail > windows you're talking about and the EditorWindow instances in idle are > doing something non-trivial which may involve waiting to destroy objects > at close time. Other minor windows in idle close instantly as expected. Yes. In fact, both involve heavily configured text widgets, in particular. Wonder if we're seeing the pathological behavior from the free() call that is sometimes observed on Linux when an interpreter shuts down and has an enormous number of objects to free. -Fred -- Fred L. Drake, Jr. PythonLabs at Zope Corporation From guido@python.org Mon Feb 25 14:17:07 2002 From: guido@python.org (Guido van Rossum) Date: Mon, 25 Feb 2002 09:17:07 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: Your message of "25 Feb 2002 16:25:56 +1100." <1014614756.10111.8.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> <1014614756.10111.8.camel@oberon> Message-ID: <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> > Actually I think I just found the problem. When I moved the above 'quit > now' lines two lines down in close(), so that the lines > > self.top.wm_deiconify() > self.top.tkraise() > > are allowed to execute, the pause returns! Good sleuthing! > So just commenting those two lines like so: > > def close(self): > #self.top.wm_deiconify() > #self.top.tkraise() > reply = self.maybesave() > if reply != "cancel": > self._close() > return reply > > causes the EditorWindow instances to begin closing at normal speed (no > pause). > > Can anyone with knowledge of the code base remember why these two > seemingly redundant lines are there in the first place, and what the > implications would be for just removing them? I think this is an attempt to make sure that when the dialog "do you want to save ... before closing" is displayed, the right window is on top. That dialog is presented (if necessary) by maybesave(). I'm sure you can figure out a better way to ensure this. To test this behavior, you should create a whole bunch of unsaved windows (but saved to files so you can tell them apart), reorder them randomly, iconify a few, and then hit control-Q. This should pop up the windows to match the "do you want to save" dialogs. For extra credit, make sure it works on Windows, too. --Guido van Rossum (home page: http://www.python.org/~guido/) From edream@tds.net Mon Feb 25 21:21:12 2002 From: edream@tds.net (Edward K. Ream) Date: Mon, 25 Feb 2002 15:21:12 -0600 Subject: [Idle-dev] Making breakpoints functional in IDLE on Windows Message-ID: <3C7AAAC8.C0E4E14C@tds.net> Hello all, I have also posted this on comp.lang.python. This morning Guido confirmed that breakpoints do not, in fact, work in IDLE on any Windows machine(!) The problem has to do with the case of file names. Here is how make breakpoints functional in IDLE. The fix required 2 additional lines of code. Both lines are marked with # EKR. Insert 1 line in Python\Tools\idle\Debugger.py. Change: def set_break(self, filename, lineno, temporary=0, cond = None): import linecache # Import as late as possible line = linecache.getline(filename, lineno) ... to: def set_break(self, filename, lineno, temporary=0, cond = None): import linecache # Import as late as possible filename = self.canonic(filename) # EKR line = linecache.getline(filename, lineno) ... Insert 1 line in Python\Lib\bdb.py. Change: def canonic(self, filename): canonic = self.fncache.get(filename) if not canonic: canonic = os.path.abspath(filename) self.fncache[filename] = canonic return canonic To: def canonic(self, filename): canonic = self.fncache.get(filename) if not canonic: canonic = os.path.abspath(filename) canonic = os.path.normcase(canonic) # EKR self.fncache[filename] = canonic return canonic This works for me on Windows XP and Python 2.1. I'll let you know if any problems come up. Edward -------------------------------------------------------------------- Edward K. Ream email: edream@tds.net Leo: Literate Editor with Outlines Leo: http://personalpages.tds.net/~edream/front.html -------------------------------------------------------------------- From gvanrossum@users.sourceforge.net Mon Feb 25 23:22:10 2002 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 25 Feb 2002 15:22:10 -0800 Subject: [Idle-dev] CVS: idle Debugger.py,1.3,1.4 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv17141 Modified Files: Debugger.py Log Message: Fix by Edward K Ream to make breakpoints work on Windows: insert a missing call to self.canonic(). Index: Debugger.py =================================================================== RCS file: /cvsroot/idlefork/idle/Debugger.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** Debugger.py 13 Jul 2001 00:07:42 -0000 1.3 --- Debugger.py 25 Feb 2002 23:22:08 -0000 1.4 *************** *** 298,301 **** --- 298,302 ---- def set_break(self, filename, lineno, temporary=0, cond = None): import linecache # Import as late as possible + filename = self.canonic(filename) line = linecache.getline(filename, lineno) if not line: From elguavas@users.sourceforge.net Tue Feb 26 00:01:45 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 26 Feb 2002 11:01:45 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> <1014614756.10111.8.camel@oberon> <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> Message-ID: <1014681706.477.14.camel@oberon> Guido van Rossum wrote: > I think this is an attempt to make sure that when the dialog "do you > want to save ... before closing" is displayed, the right window is on > top. That dialog is presented (if necessary) by maybesave(). I'm > sure you can figure out a better way to ensure this. To test this > behavior, you should create a whole bunch of unsaved windows (but > saved to files so you can tell them apart), reorder them randomly, > iconify a few, and then hit control-Q. This should pop up the windows > to match the "do you want to save" dialogs. Turns out that it is the call to tkraise() that's causing the problem, maybe something to do with the window manager barfing when being asked to move a window to the top of the stack that is already on top? I moved the 'make sure the relevant window is displayed' code into maybesave() since it only applies if we have a window we need a save query on, then I made sure we only deiconify() if required. I found a q&d way to make the tkraise() not choke things by simply lowering the window first so that the lift() always does something, ending up with this: def maybesave(self): if self.io: if self.top.state()!='normal': self.top.deiconify() self.top.lower() self.top.lift() return self.io.maybesave() This works well under X when tested as you suggested, but I haven't tested it on windows yet. Also I will see if I can find a way to test whether the desired window is already at the top of the stack, so that I can do away with that q&d lower(), if possible. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Tue Feb 26 00:37:12 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 26 Feb 2002 11:37:12 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014681706.477.14.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> <1014614756.10111.8.camel@oberon> <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> <1014681706.477.14.camel@oberon> Message-ID: <1014683833.1653.6.camel@oberon> > I moved > the 'make sure the relevant window is displayed' code into maybesave() > since it only applies if we have a window we need a save query on Even better, not only make sure we are an edit window, don't bother fiddling with window visibility if we don't have unsaved changes either, since we won't be asked about saving changes then: def maybesave(self): if self.io: if not self.get_saved(): if self.top.state()!='normal': self.top.deiconify() self.top.lower() self.top.lift() return self.io.maybesave() Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Tue Feb 26 02:25:38 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 26 Feb 2002 13:25:38 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014683833.1653.6.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> <1014614756.10111.8.camel@oberon> <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> <1014681706.477.14.camel@oberon> <1014683833.1653.6.camel@oberon> Message-ID: <1014690339.451.21.camel@oberon> Ok, I tested my bugfix candidate for the pause on closing problem under windows (windows 2000 only, I don't have any other windows here) and it works just fine there too. I can't find any way to test for a toplevel's place in the windowmanager's stacking order in tkinter, it's not in any of the zillions of winfo_*() methods or in any other method or attribute I can discover, so I guess the q&d call to lower() stays as it works fine. The only other thing I can think of to check is, Bruce Sherwood, if you're reading this can you try the fix under your rootless X on Aqua setup to see if it works there too, although I can't see why it wouldn't. So the fix is to edit the maybesave() method in EditorWindow.py so that it looks like the following: def maybesave(self): if self.io: if not self.get_saved(): if self.top.state()!='normal': self.top.deiconify() self.top.lower() self.top.lift() return self.io.maybesave() and remove these (first two) lines from the close() method: self.top.wm_deiconify() self.top.tkraise() I guess that's a bugfix candidate for python idle too if anyone with write access to the python tree wants to put it in cvs with a nice explanatory comment. Or do I need to submit it as a patch? Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Tue Feb 26 02:31:05 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: Mon, 25 Feb 2002 18:31:05 -0800 Subject: [Idle-dev] CVS: idle EditorWindow.py,1.16,1.17 Message-ID: Update of /cvsroot/idlefork/idle In directory usw-pr-cvs1:/tmp/cvs-serv1811 Modified Files: EditorWindow.py Log Message: bugfix for the problem where EditorWindow instances would appear to freeze for a few seconds on closing in some cases when running under X Index: EditorWindow.py =================================================================== RCS file: /cvsroot/idlefork/idle/EditorWindow.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** EditorWindow.py 18 Feb 2002 01:45:43 -0000 1.16 --- EditorWindow.py 26 Feb 2002 02:31:03 -0000 1.17 *************** *** 535,543 **** def maybesave(self): if self.io: return self.io.maybesave() def close(self): - self.top.wm_deiconify() - self.top.tkraise() reply = self.maybesave() if reply != "cancel": --- 535,546 ---- def maybesave(self): if self.io: + if not self.get_saved(): + if self.top.state()!='normal': + self.top.deiconify() + self.top.lower() + self.top.lift() return self.io.maybesave() def close(self): reply = self.maybesave() if reply != "cancel": From bas@andrew.cmu.edu Tue Feb 26 02:57:19 2002 From: bas@andrew.cmu.edu (Bruce Sherwood) Date: Mon, 25 Feb 2002 21:57:19 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014690339.451.21.camel@oberon> Message-ID: <1061957734.1014674239@HYPERON.REM.CMU.EDU> I will indeed try this, hopefully tomorrow. Awesome, Stephen! Thank you! Thank you! Bruce --On Tuesday, February 26, 2002 1:25 PM +1100 "Stephen M. Gava" wrote: > The only other thing I can think of to check is, Bruce Sherwood, > if you're reading this can you try the fix under your rootless X on Aqua > setup to see if it works there too, although I can't see why it > wouldn't. From guido@python.org Tue Feb 26 14:42:10 2002 From: guido@python.org (Guido van Rossum) Date: Tue, 26 Feb 2002 09:42:10 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: Your message of "26 Feb 2002 13:25:38 +1100." <1014690339.451.21.camel@oberon> References: <974720944.1014587002@HYPERON.REM.CMU.EDU> <1014607937.9429.23.camel@oberon> <15481.46278.52995.335840@grendel.zope.com> <1014613176.9839.7.camel@oberon> <1014613887.9835.12.camel@oberon> <1014614756.10111.8.camel@oberon> <200202251417.g1PEH7u11314@pcp742651pcs.reston01.va.comcast.net> <1014681706.477.14.camel@oberon> <1014683833.1653.6.camel@oberon> <1014690339.451.21.camel@oberon> Message-ID: <200202261442.g1QEgAf16089@pcp742651pcs.reston01.va.comcast.net> I see one strange side effect though. I'm using KDE. When I create a new window and make some changes to it and then quit IDLE, the new window is lowered to the bottom of the window stack for a good three seconds before it pops back up to the front. This is quite disconcerting! So I think there's still something bogus going on. A print confirms that the lift() call takes about 2-3 seconds. Why could this be? Who's waiting for whom at this point? --Guido van Rossum (home page: http://www.python.org/~guido/) From bas@andrew.cmu.edu Tue Feb 26 18:18:59 2002 From: bas@andrew.cmu.edu (Bruce Sherwood) Date: Tue, 26 Feb 2002 13:18:59 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: <1014690339.451.21.camel@oberon> Message-ID: <1117257546.1014729539@muon> Works on rootless X on top of Mac OSX Aqua. Windows close instantly. However, I didn't do all the tests that Guido did. Bruce --On Tuesday, February 26, 2002 1:25 PM +1100 "Stephen M. Gava" wrote: > The only other thing I can think of to check is, Bruce Sherwood, > if you're reading this can you try the fix under your rootless X on Aqua > setup to see if it works there too, although I can't see why it > wouldn't. From guido@python.org Tue Feb 26 21:28:50 2002 From: guido@python.org (Guido van Rossum) Date: Tue, 26 Feb 2002 16:28:50 -0500 Subject: [Idle-dev] Slow close? In-Reply-To: Your message of "Tue, 26 Feb 2002 13:18:59 EST." <1117257546.1014729539@muon> References: <1117257546.1014729539@muon> Message-ID: <200202262128.g1QLSpq20228@pcp742651pcs.reston01.va.comcast.net> I should note that the slow lift() or lower() calls are not specific to IDLE or even Tkinter. In pure Tcl/Tk using wish, the commands "raise ." and "lower ." also incur a delay of 2-3 seconds. Curiously, the *first* call to "raise .", and calls that actually raise the root window, don't incur the delay; but all calls to "lower ." incur a delay, and so do other calls to "raise ." (when the root window is already on top). Maybe it's time to get help from an expert... --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Tue Feb 26 21:46:00 2002 From: guido@python.org (Guido van Rossum) Date: Tue, 26 Feb 2002 16:46:00 -0500 Subject: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE Message-ID: <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> FYI. It appears a Tcl bug, fixed in Tcl 8.3.4. --Guido van Rossum (home page: http://www.python.org/~guido/) ------- Forwarded Message Date: Tue, 26 Feb 2002 13:39:20 -0800 From: "Jeff Hobbs" To: "'Guido van Rossum'" Subject: RE: Strange delays when using raise or lower in KDE Guido, I believe this was addressed in Tk bug 220260: http://sourceforge.net/tracker/?group_id=12997&atid=112997&func=detail&aid=220260 That means you shouldn't see the problem with 8.3.4, although you might with 8.3.3. I haven't gotten any recent email about this still being a problem, but can you verify what version of Tk these guys are running against? Thanks, Jeff > -----Original Message----- > From: guido@pcp742651pcs.reston01.va.comcast.net > [mailto:guido@pcp742651pcs.reston01.va.comcast.net]On Behalf Of Guido > van Rossum > Sent: February 26, 2002 1:34 PM > To: JeffH@ActiveState.com > Subject: Strange delays when using raise or lower in KDE > > > Hi Jeff, > > Can I point you to a recent discussion on idle-dev? > > The thread "Slow close?" started here > > http://mail.python.org/pipermail/idle-dev/2002-February/000872.html > > and ends inconclusively. It appears to me that there is a fundamental > problem in Tcl/Tk. My summary: when I start wish on Linux and execute > the command "lower ." (not having done anything else) this takes about > three seconds to return a command prompt. Ditto for "raise .", most > times (but not always -- when it actually moves the root window up, it > returns immediately). > > Apparently (it's not easy for me to test this) this only happens when > using KDE or GNOME. > > Can you shed any light on this? > > --Guido van Rossum (home page: http://www.python.org/~guido/) > ------- End of Forwarded Message From Nikolai Tue Feb 26 19:12:01 2002 From: Nikolai (Nikolai) Date: Tue, 26 Feb 2002 23:12:01 +0400 Subject: [Idle-dev] =?koi8-r?B?8NLP3tTJ1MUsIM3P1sXULCDc1M8g98HbINvBztMuIPXEwczJ1NggzsXJy8/H?= =?koi8-r?B?xMEgzsUg0M/axM7PLg==?= Message-ID: <147594609.20020226231201@honkong.com> SGVsbG8sDQoNCg0KICAgICDtxc7RINrP19XUIO7Jy8/MwcouIOna18nOydTFINrBIMLF09DPy8/K 09TXzywgzs8gzsUg1M/Sz9DJ1MXT2CDVxMHM0dTYINzUzyDQydPYzc8gLSDPzs8gzc/WxdQg09nH 0sHU2CDXwdbO1cAg0s/M2CDXDQr3wdvFyiDWydrOySEg6c3Fzs7PINTByyDQ0s/J2s/bzM8g088g zc7PyiDQz9PMxSDQz8zV3sXOydEgLSDOxcvP1M/Sz8Ug19LFzdEgzsHawcQgLSDUwcvPx88g1sUg 0MnT2M3BLiD2xczBwCDJIPfBzSDOxQ0K1dDV09TJ1Ngg09fPyiDbwc7TISDv4vH64fTl7Pju7yDz 7+jy4e7p9OUg/PTvIPDp8/jt7yDu4SD25fP06+/tIOkg5+ni6+noIOTp8+vh6CENCg0KICAgICD3 0NLP3sXNLCDF08zJIPfZIM7FIMjP1MnUxSDTz9fF0tvFzs7PINrBy8/Ozs8gxM/Qz8zOydTFzNjO zyDawdLBwsHU2dfB1NggzsXTy8/M2MvPINTZ09HeIMnMySDExdPR1MvP1yDU2dPR3iBVUyQg1w0K zcXT0cMgzsUgz9TIz8TRIM/UIM3F09TBLCDHxMUg09TPydQg98HbIMvPzdDYwNTF0iAoy8/Oy9LF 1M7B0SDT1c3NwSDC1cTF1CDawdfJ08XU2CDUz8zYy88gz9Qg19LFzcXOySwgy8/Uz9LPxSD32SDa wdPUwdfJ1MUNCtfB2yDLz83Q2MDUxdIgydPLwdTYIEUtbWFpbCjZKSDJIM/U0NLB18zR1Ngg0M8g zsnNIMTBzs7PxSDQydPYzc8sIMTB1sUgxdPMySD32SDTwc3JLCDQ0skg3NTPzSwgydrXyc7J1MUs INPQydTFIC0g1yDMwMLPzQ0K083Z08zFINzUz8fPINPMz9fBKSwg0M/Mzs/T1NjAIM7F2sHXydPJ zc8gz9Qgy8/HzyDC2SDUzyDOySDC2czPIMkg08/I0sHO0dEgKMXTzMkg98HNINzUzyDC1cTF1CDV x8/Ezs8pIMHOz87Jzc7P09TYLA0Kyc7XxdPUydLV0SDOwSDT1MHS1MUg19PFx88gMjAgVVMkICjL z9TP0tnFLCDLINTPzdUg1sUsIM/L1dDR1NPRIMLVy9fBzNjOzyDexdLF2iDOxcTFzMAgyczJIMTX xSksINPPyNLBztHRINDSySDX08XNINzUz80NCt7J09TVwCDTz9fF09TYICjULssuIPfBzSDOySDS wdrVIM7FINDSycTF1NPRIM7Jy8/HzyDPws3BztnXwdTYIC0g/PTvIO7lIPDp8uHt6eThIMEgzNEg 7e3tIMnMySwgxMHWxSwg58XSwsHMwcrGIC0g1NXUDQrPws/Hwd3BwNTT0SDX08UsIMvUzyDSxcHM 2M7PINLBws/UwcXUIMLF2iDcy9PQzNXB1MHDyckgItfF0sjBzckiLCDLz9TP0tnIINrExdPYINDS z9PUzyDOxdQsIM7PIMkgwsXaINXSwdfOyczP18vJLCDLz87F3s7PKSwNCtPQz8vPys7ZyiDTz84g ySDQz8TPwsHA3cXFINbFzMHOycUsINTPIM3P1sXUxSDIzMHEzs/L0s/Xzs8g1cLJ18HU2CDT18/A IO7h5OX25PUg7uEg9ez1/vvl7unlIOvh/uXz9PfhIPbp+u7pLCDVzsne1M/WwdEg3NTPDQrQydPY zc8hDQoNCiAgICAg98HWzs8g2sHNxdTJ1NgsIN7UzyDIz9TRINDPxM/CztnKINDSz8XL1CDawdLP xMnM09Eg1yDz++EsIPfBzSDQ0sXEzMHHwcXU09EgxcfPINfB0snBztQg8O/s7u/z9PjgIOHk4fD0 6fLv9+Hu7vnqIOsNCvPw5ePp5unr5SDy9fPz6+/x+vn+7u/qIP7h8/TpIOnu9OXy7uX04SAyMDAy IMfPxMEhDQoNCiAgKioqDQoNCiAg4SD05fDl8vggLSAg7/D59CDi+ffh7O/n7yDy7/Pz6erz6+/n 7yDw7+z4+u/34fTl7PEgDQoNCg0KDQogICAgIPzUwSDQ0s/H0sHNzcEgxMXK09TXydTFzNjOzyDE xcrT1NfVxdQuIPbJ19UgzsUg1yDhzcXSycvFLCDBINcg8s/T08nJLCDJINPOwd7BzMEg0SDCz9HM 09EsIM7FIMLZzCDV18XSxc4sIMTFytPU18nUxczYzs8NCszJINzUzyDExcrT1NfVxdQsIMEg0M/U z83VLCDOxSDP1M7P08nM09EgyyDc1M/N1SDTxdLYxdrOzy4g4SDQz9TPzSDTy8Hawcwg08XCxTog IuEg0M/exc3VIM7F1D8iLiDzz9rEwcwgy8/bxczFyywg0M/Qz8zOycwNCsXHzyAsIMkg08TFzMHM INDF0sXXz8QsINrBy8Hawdcg08XCxSDexdTZ0sUgyc7T1NLVy8PJyS4g9yDUxd7FzsnJIDUtySDE zsXKINDPzNXeycwgycgg19PFyCDQzyBlLW1haWwuIOTPzNjbxSDX08XHzyDQ0snbzM/T2A0K1sTB 1Nggyc7T1NLVy8PJySA0LiDuzyDc1M8gySDQz87R1M7PLCDXxcTYINUg0NLPxMHXw8Eg3NTPx88s INDP08zFxM7Fx88g1dLP187RLCDU2dPR3skg2sHLwdrP1y4g99PFINPExczBzCDUz97OzyDQzw0K yc7T1NLVy8PJySwg3tTPwtkgwtnU2CDV18XSxc7O2c0sIMXTzMkg3NTPIMTFzM8gzsUg2sHSwcLP 1MHF1Cwg1M8g3NTPIM7FINDSyd7JzsEgzc/FyiDP28nCy8kgySDWxMHMLiANCg0KICAgICDxINfO yc3B1MXM2M7PINDSz97J1MHMINfTxSDQz8zV3sXOztnFIMnO09TS1cvDycksIMEgy8/HxMEg1drO wcwsIMvByyDX08UgzsHEzyDExczB1NgsIM7B3sHMINPXz8ogwsnazsXTLiDxIMnTy8HMDQrBxNLF 08Eg18XaxMUgySDTxMXMwcwg08XCxSDEzMnOztnKINPQydPPyyAozc7FINzUzyDC2czPIMTFytPU 18nUxczYzs8gyc7UxdLF087PLCDc1M8gwtnMzyDLwcsgzs/Xz8UgyM/CwsksIMkg0SDOxSDNz8cg zsnexcfPDQrQz9TF0tHU2CksIMvByyDOxc7P0s3BzNjO2cog0SDOwd7BzCDQz9PZzMHU2CBlLW1h aWwgzMDE0c0g1yDDxczPzSDT18XUxS4g5MXMwcwg0SDc1M8g0M/T1M/Rzs7PLCDJIMvB1sTZyiDE xc7YIMvPztTSz8zJ0s/XwcwNCtPXz8ogy8/bxczFyy4g8NLJzcXSzs8g3sXSxdogxMXO2CDOwd7B zMkg0NLJyM/EydTYINrBy8Ha2S4g5M8g08nIINDP0iDQz83OwCDUz9Qgzc/Nxc7ULCDLz8fEwSDP ws7B0tXWycwg0MXS19nKINrBy8HaLg0K7sXLz9TP0s/FINfSxc3RINEg0NLP09TPINPUz9HMIMkg zsUgzc/HIMTXycfB1NjT0TogIvzUzyDSwcLP1MHF1CEg/NTBINvU1cvBINrB0sHCz9TBzMEgzcHU 2CDFxSDUwcshIi4g8NLP29Ug0NLP3cXOydEg2sENCtfZ0sHWxc7JxSwgzs8g8SDC2cwgz97Fztgg 097B09TMydcsIMkgzsHewcwg0M/T2czB1Nggxd3FIMLPzNjbxSBlLW1haWwsINDP0dfJzNPRINPJ zNjOxcrbycog09TJzdXMIMsg0sHCz9TFLiANCg0KICAgICDuwSDTzMXE1cDdycogxMXO2CAtINDV 09TPyiDR3cnLIMkg087P18Eg0SDQz8TVzcHMLCDe1M8g3NTPIM7FIMLVxMXUINLBws/UwdTYLCDO zyDPy8HawczP09ggzsHPws/Sz9QuIO7BINPMxcTVwN3JyiDExc7YDQrRINDPzNXeycwgMyDawcvB 2sEsINcg1M/UINbFIM3PzcXO1CDRINDP08zBzCDMwMTRzSDJyCDJztPU0tXLw8nJLCDe1M/C2SDN z8fMySDUz9bFIMLZ09TSzyDawdLBws/UwdTYIMTFztjHySAoxMzRINPFwtEgySDEzNENCs3FztEp LiD6wSDE18UgzsXExczJLCDLwdbE2cogxMXO2CDRINPJxMXMINDSyc3F0s7PIDMwIM3JztXUINUg y8/N0NjA1MXSwSDJINDP09nMwcwg2sHLwdrZLiD3INTF3sXOyckgxNfVyCDOxcTFzNgg0SDQz8zV 3snMDQoyOSDawcvB2s/XIM7BIMnO09TS1cvDycAgIzEuIPDP1M/NINrBy8Ha2SDT1MHMySDQ0snI z8TJ1Ngg3sHdxSDJIMLZ09TSxcUsIMvB1sTVwCDOxcTFzMAg0SDQz8zV3sHMIM/Lz8zPINPUwSDa wcvB2s/XLCBhDQrExc7Yx8kg19PFINDP09TV0MHMySDOwSDNz8og097F1C4g9yDDxczPzSDRINrB 0sHCz9TBzCDPy8/MzyA2NC4wMDAsLSBVU0QuIPcg/PTvIO7l9+/67e/27u8g4vns7yDw7/fl8un0 +CEg7sEg0NLP28zPyiDOxcTFzMUNCtEgy9XQycwg08XCxSDOz9fVwCDUwd7L1SDJINzUzyDCzMHH z8TB0tEg0NLPx9LBzc3FLiDl08zJIMkg1MXQxdLYIPfZIM7FINrOwcXUxSwg3tTPIMTFzMHU2Cwg 1MHLINEg98HNIMfP18/SwA0K8F/vX/Bf8l/vX+Jf9V/qX/Rf5SDJIM7FINDP1sHMxcXUxS4g/NTP IPfB2yDbwc7TLCDF08zJIMXHzyDV0NXT1MnUxSwg1MHLIMLVxMXUxSDWwczF1Nggz8Ig3NTPzSDE zyDLz87DwSDWydrOySENCg0KICDuLiDyxcLSz9csIPLP09PJ0S4NCg0KDQoNCiAgKioqDQoNCiAg 4SDUxdDF0tgg18XSzsXN09EgyyDz9f3l8/T39SDExczBLiD3IN7FzSDTz9PUz8nUINDSxcTMwcfB xc3B0SDy4eLv9OE/DQoNCg0KDQogICAgIPfZIO/k6e4g0sHaINDPy9XQwcXUxSA0IMnO09TS1cvD yckgKMXdxSDPxM7BIC0gIs7VzMXXwdEiIMTP09TBzMHT2CD3wc0gwsXT0MzB1M7PIC0g3NTPIM7B 09TP0d3FxSDQydPYzc8pINDPINzUz8og08HNz8oNCsTF0dTFzNjOz9PUySAozc7Px8/V0s/XzsXN 1SDTxdTF18/N1SDNwdLLxdTJzsfVINcg6c7UxdLOxdTFKSDXINzMxcvU0s/Ozs/NINfJxMUgKNDP IDUgVVMkINrBIMvB1sTPxSkg1SA0Lcgg0sHaztnIIMzAxMXKIC0NCvfB28nIINDSxcTbxdPU18XO zsnLz9cg0M8gyc7Gz9LNwcPJz87Oz8ogw8XQz97LxS4g+sHUxc0sIPfZIOzg4u/lIN7J08zPINLB 2iDQ0s/EwcXUxSDc1Mkgyc7T1NLVy8PJySDX08XNINbFzMHA3cnNDQrQz8zY2s/XwdTFzNHNIOnO 1MXSzsXUwS4NCg0KICAgICDrwdbE2cogxMXO2CDOwSDPxM7PzSDUz8zYy88gbWFpbC5ydSAtINPB zc/NIMna18XT1M7PzSDXIPLP09PJySwgzs8gxMHMxcvPIM7FINPBzdnNIMzV3tvJzSAi0M/T1MHX 3cnLz80iIMLF09DMwdTO2cgNCtHdycvP1ywg3snTzM8g0M/M2NrP18HUxczFyiDXz9rSwdPUwcXU IMLPzMXFIN7FzSDOwSA2INTZ09HeLiDr0s/NxSDUz8fPLCDXINLV09PLz9Ha2d7Oz8og3sHT1Mkg 6c7UxdLOxdTBIM7F08/Qz9PUwdfJzc8NCs3FztjbwdEgy8/Oy9XSxc7DydEg1yDSxcvMwc3FLCDe xc0gLSDXIMHOx8zP0drZ3s7PyiAozsEgIs7B28kiINHdycvJINcgx8/EINDSycjPxMnUIM3Fztjb xSDSxcvMwc3ZLCDexc0gzsEgIsnIIiAtINcgxMXO2CkhDQoNCiAgICAg8MXSxcQg1MXNIMvByyDS xdvB1NgsIMjP1MnUxSDc1MnNINrBzsnNwdTY09EgyczJIM7F1Cwg0NLP3snUwcrUxSDTzMXE1cDd ycUgxsHL1Nkgz8Ig3NTPyiDQ0s/H0sHNzcUgLSD32ToNCg0KICAxLiDw8u/k4eX05SDw8u/k9ev0 LCDw8u/p+vfv5PP09+8g6+/07/Lv5+8g9+HtIO7p/uXn7yDu5SDz9O/p9CENCg0KICAyLiDw8u/k 4eX05SDw8u/k9ev0LCD08uHu8/Dv8vTp8u/36+Eg6+/07/Lv5+8g9+HtIO7p/uXn7yDu5SDz9O/p 9CENCg0KICAzLiDw8u/k4eX05SDw8u/k9ev0LCDy5evs4e3hIOvv9O/y7+fvIPfh7SDu6f7l5+8g 7uUg8/Tv6fQhDQoNCiAgNC4g6fPw7+z4+vXl9OUg8+ns9SDp7vTl8u7l9OEg6SBNVUxUSS1MRVZF TCBNQVJLRVRJTkchDQoNCiAgNS4g9+H76e0g5eTp7vP09+Xu7vntIPfr7OHk7+0sIOvy7+3lIO7h /uHs+O7v6iDp7vfl8/Tp4+npINcgMjAgVVMkIPH37PHl9PPxIPTv7Pjr7yD34fvlIPfy5e3xICjL wcsgzMnezs/FLCDUwcsgyQ0K0M/Ey8zA3sXOydEgyyDpztTF0s7F1NUpIQ0KDQogIDYuIPfl8/gg +uHy4eLv9O/rLCDr7/Tv8vnqIPf5IPDv7PX+6fTlLCDx9+zx5fTz8SD+6fP07+og8PLp4vns+OAh DQoNCiAgNy4g/PThIPDy7+fy4e3t4SDu4ffz5efk4SDp+u3l7un0IPfh+/Ug9un67vghDQoNCiAg KioqDQoNCiAg9+/0LCD+9O8sIOvv7uvy5fTu7ywg7vX27u8g4vXk5fQg9+HtIPPk5ezh9PggKOnu 8/Ty9evj6fEgIzApOg0KDQogIDEuIPPLz9DJ0s/XwdTYINDP08zFxM7AwCDXxdLTycAgKM7FIM3F zsXFLCDexc0gMikg0NLPx9LBzc3ZIFdlYk1vbmV5IGtlZXBlciDOwSDTwcrUxSBodHRwOi8vd3d3 LndlYm1vbmV5LnJ1LyD0wc0g1sUg99kNCs7BysTF1MUgz9DJ08HOycUg0sHCz9TZINMgy8/bxczY y8/NIMkgyc7Gz9LNwcPJwCDPwiDc1M/KINPJ09TFzcUg0MzB1MXWxcouDQoNCiAgMi4g8M/Qz8zO ydTYIPP37+ogWiDLz9vFzMXLIDIwIFVTJCAoyczJINPOwd7BzMEgUiDLz9vFzMXLIC0gxdPMySDX IPfB28XNIMfP0s/ExSDOxdQg0NLFxNPUwdfJ1MXM2NPU18EgV2ViTW9uZXksIMEgwsHOy8kNCs/U y8Ha2dfBwNTT0SDP09XdxdPU18zR1Ngg0MXSxdfPxNkg1yBVUyQsIMEg2sHUxc0gz8LNxc7R1Ngg 0tXCzMkgzsEgVVMkINfO1dTSySDTwc3PyiDTydPUxc3ZICjULsUuINDF0sXT1MkgxMXO2MfJINPP INPXz8XHzw0KUi3Lz9vFzNjLwSDOwSBaICkuIPDPxNLPws7PxSDP0MnTwc7JxSDc1MnIIM/QxdLB w8nKIC0gzsEgaHR0cDovL3d3dy53ZWJtb25leS5ydS9ydXMvcGVyZXZvZHMuaHRtLw0KDQogIDMu IPDP08zFINDP09TV0MzFzsnRIMTFzsXHINcg98HbIMvP28XMxcssINrBy8HawdTYINPFwsUg19PF IN7F1NnSxSDJztPU0tXLw8nJLCDQ1dTFzSDQxdLF18/EwSBXZWJNb25leSDJ2iDT18/Fx88gy8/b xczYy8ENCtcgy8HWxNnKIMnaIDQtyCDLz9vFzNjLz9cg0NLPxMHXw8/XLCDT1c3N2SA0Ljk2IFdN WiAoMC44JSAtIMvPzcnT08nPzs7ZxSDTwc3PyiDTydPUxc3ZINrBIM/T1d3F09TXzMXOycUg0MXS xdfPxMEgxMXOxccpLCDawQ0Ky8HWxNXAIMnO09TS1cvDycAuIPfh9u7vISDl08zJIPfZINDP0M/M zsnUxSDT18/KIMvP28XMxcsg0s/Xzs8gMjAkIMkg0MXSxdfFxMXUxSDSz9fOzyDQzyA1JCDawSDJ ztPU0tXLw8nJIDEtMywg1M8g1SD3wdMNCs/LwdbF1NPRIM7FxM/T1MHUz97OzyDExc7FxyDEzNEg 0MXSxdfPxMEg2sEgyc7T1NLVy8PJwCAjNCENCg0KICAqIPDy6e3l/uHu6eU6DQoNCiAgKvcgy8/b xczYy8UsIMTFztjHySDI0sHO0dTT0SDXINfJxMUg1dPMz9fO2cggxcTJzsnDIChXZWJNb25leSku 8M8gy9XS09UgMVdNID0gMSDS1cIuIMTM0SBSLSDLz9vFzNjLwSwgMVdNID0gMSDEz8zMwdIg8/vh DQrEzNEgWi0gy8/bxczYy8EuDQoNCiAgKuvPx8TBINPExczBxdTFINPXz8og2sHLwdosINXCxcTJ 1MXT2Cwg3tTPINfZINrBy8HawczJINfTxSDJztPU0tXLw8nJLiD308Ugz87JINDPzsHEz8LR1NPR IMTM0SDUz8fPLCDe1M/C2SD32SDTz8jSwc7JzMkg1Q0K08XC0SDXIMvPzdDYwNTF0sUgKMkgzsEg xMnTy8XUxSwgxMzRIM7BxMXWzs/T1MkpIN7Uz8LZINDP1M/NIPfZIM3Px8zJINDSz8TB18HU2CDL z9DJyS4g98HNIMTFytPU18nUxczYzs8gztXWztkg19PFINzUyQ0Kyc7T1NLVy8PJyS4g5dPMySDV IPfB0yDOxSDC1cTF1CDI18HUwdTYIM/Ezs/KIMnaIM7JyCwg99kgzsUg083P1sXUxSDP09XdxdPU 18zR1Ngg0sHT09nMy9UuIPTF0MXS2CDc1M8g98HbINTP18HSLCDTINDSwdfPzQ0K0NLPxMHWySEg 78LR2sHUxczYzs8sINXLwdbJ1MUg1yDQz8zFIMvPzc3FztTB0snRIM7PzcXSIMnO09TS1cvDyckg ySDT18/KIEUtbWFpbCDBxNLF0y4NCg0KICDw0snNxdIg08/Pwt3FzsnRLCDQ0snMwcfBxc3Px88g yyDQxdLF18/E1SDExc7FxyDexdLF2iBXZWJNb25leTogIsnO09TS1cvDydEgIzE7IEUtbWFpbCB4 eHh4eHh4eHh4eHh4QHh4eHh4eC54eCINCg0KICD0wcLMycPBOg0KDQogIMnO09TS1cvDydEgIyAg ICAvICAgLiDLz9vFzMXLDQoNCiAgICAgICAgICAgICAgICAgICAxIC8gWjM0MTEzODQ2MjE3OA0K DQogMiAvIFo4MzE4MDA0MDQxMTgNCg0KICAgICAgICAgICAgICAgICAgIDMgLyBaODU1Njc4MzI2 NDQ1DQoNCiAgICAgICAgICAgICAgICAgICA0IC8gWjQ1MjkyNTA2NjExNA0KDQogDQoNCg0KDQog IPfu6e3h7unlISEhDQoNCiAg7sUgzsHQ0sHXzNHK1MUg98HbySDXz9DSz9PZIMkg0M/E1NfF0tbE xc7J0SDP0MzB1Nkg0yDQz83P3djAIMvOz9DLySAiz9TXxdTJ1Nggz9TQ0sHXydTFzMAiLCAiz9TX xdTJ1NggzsEg19nC0sHOzs/FDQrQydPYzc8iLCDJzMkgInJlcGx5IiDOwSDR3cnLLCDTIMvP1M/S z8fPIPfZINDPzNXeyczJIMTBzs7PxSDQydPYzc8gLSDXINDSz9TJ187PzSDTzNXewcUgz87PINDS z9PUzyDOxSDC1cTF1CDQ0s/eydTBzs8sIMENCsHE0sXT1crUxSDJyCD07+z46+8g1yDXycTFINPP z8Ldxc7J0SDXINPJ09TFzcUgV2ViTW9uZXkuDQoNCiAgNC4g9yD0wcLMycPFLCDVxMHMydTFINPU 0s/L1Swg08/P1NfF1NPU19XA3dXAIMnO09TS1cvDyckgIzQuIOnazcXOydTFIM7PzcXSwSDJztPU 0tXLw8nKIDMgLSDOwSA0LCAyIC0gzsEgMyDJIDEgLSDOwSAyLCDOxQ0KzcXO0dEgy8/bxczYy8/X INcg08/P1NfF1NPU19XA3cnIINPU0s/Lwcgg9MHCzMnD2S4g5M/CwdfY1MUg1yDUwcLMycPVICjT 18XSyNUpINPU0s/L1SAxINPPIPP37+ntIMvP28XM2MvPzS4g8M/Nxc7RytTFIM3PyiBXTQ0KycTF ztTJxsnLwdTP0iDOwSDz9+/qINcg0M/TzMXEzsXNINPPxMXS1sHUxczYzs/NIMHC2sHDxSDEwc7O z8fPINDJ09jNwS4g7sHLz87Fwywg2sHNxc7J1MUgzc/FIMnN0SDOwSD3wdvFINcg08HNz80gzsHe wczFIMkNCsvPzsPFINDJ09jNwS4g8MnT2M3PIMTM0SD3wdvFyiDSwdPT2czLySDHz9TP188hIPTF 0MXS2CD32SDT1MHMySDQ0s/EwdfDz80gyc7T1NLVy8PJySAjMS4NCg0KICD34fbu7yEhIQ0KDQog ICAgIO7FIM3FztHK1MUgzs/NxdLBIMvP28XM2MvP1ywgy8/Uz9LZxSDOwcjPxNHU09Eg1yD0wcLM ycPFLCDOycvBy8nNINPQz9PPws/NLCDL0s/NxSDP0MnTwc7Oz8fPINcg0NXOy9TFIDQsIMnOwd7F DQrQz9TF0tHF1MUgws/M2NvVwCDewdPU2CDT18/JyCDEz8jPxM/XLiDrz8fEwSDQz8rNxdTFLCDL wcsg3NTPIMTFytPU19XF1Cwg98HNINPSwdrVINPUwc7F1CDQz87R1M7PLCDQz97FzdUg3NTPINDF 0sXT1MHF1A0K0sHCz9TB1NgsIMvPx8TBIN7Uzy3OycLVxNggydrNxc7J29ggzsUg0M8g0NXOy9TV IDQgKNcgV2ViTW9uZXkgzc/Wzs8gzMXHy88g0NLP18XSydTYIM7FIMLZzMEgzMkg0NLPydrXxcTF zsEg0M/EzcXOwSkuDQoNCiAgICAg7sUgxMXMwcrUxSDOycvBy8nIIMnazcXOxc7JyiDXIOnu8/Ty 9evj6ekhISENCg0KICAgICD3wdsgxsnOwc7Tz9fZyiDXy8zBxCDXIMTBzs7PxSDQ0sXE0NLJ0dTJ xSDR18zRxdTT0SDQ0sHL1MnexdPLySDOyd7Uz9bO2c0uIO7FIM/QwdPBytTF09gsIN7UzyD3wc0g zsUg19nbzMDUIMnO09TS1cvDyckNCi0g3NTPIMLZzM8gwtkgx8zV0M8g088g09TP0s/O2SDQ0s/E wdfDz9cgLSDQ0sXE28XT1NfFzs7Jy8/XINcgyc7Gz9LNwcPJz87Oz8ogw8XQz97LxS4g787JICjL 0s/NxSDQ0s/EwdfDwSDJztPU0tXLw8nJICM0LCDOzw0Kz84g08HN2cogws/HwdTZyiDJIM/CzcHO 2dfB1Nggxc3VIM7F1CDTzdnTzMEpIMvSz9fOzyDawcnO1MXSxdPP18HO2SDXIM3By9PJzcHM2M7P zSDV09DFyMUg09fPycgg0M/TzMXEz9fB1MXMxcosINQuyy4gycgNCsvP28XM2MvJIMLVxNXUIMbJ x9XSydLP18HU2CDXINLB09PZzMHFzc/NIPfBzckg0MnT2M3FLiDr0s/NxSDUz8fPLCDQ0s/EwdfD 2SDJztPU0tXLw8nKIM7J3sXHzyDOxSDUxdLRwNQgz9TQ0sHXzNHRIMnIIPfBzS4g4Q0Kz8LNwc7V 1ywgz87JINLJ08vVwNQg0NLFy9LB1MnU2CDc1NUg09fPwCDExdHUxczYzs/T1Nggydot2sEg98Hb xcog1sHMz8LZINcgwcTNyc7J09TSwcPJwCBXZWJtb25leS4NCg0KICAgICDr1dDJ1yDX08UgNCDJ ztPU0tXLw8nJLCD32SDCxdPQzMHUzs8g0M/M1d7BxdTFIDIg08/XxdLbxc7OzyDOxc/CyM/Eyc3Z xSD3wc0g0NLPx9LBzc3ZINPCz9LBIMHE0sXTz9cgySDNwdPTz9fPyg0K0sHT09nMy8kgz8TJzsHL z9fZyCDQydPFzSwgy8/Uz9LZxSwgxdPMySD32SDC1cTF1MUgycgg0M/L1dDB1Ngg08HNz9PUz9HU xczYzs8sIM/Cz8rE1dTT0SD3wc0sIMvByyDNyc7JzdXNLCDXINTFINbFIDIwIFVTJCwNCt7UzyDJ INfTxSDJztPU0tXLw8nJLg0KDQogIO/i8frh9OXs+O7vIPDy7/fl8vj05SDw8uH36ez47u/z9Pgg 6frt5e7l7unxIPTh4uzp4/khISENCg0KICAgICDw0s/XxdLY1MUsIM/Tz8LFzs7PINfOyc3B1MXM 2M7PLCDQ0sHXyczYzs/T1Ngg1cvB2sHOydEgzs/NxdLBIMvP28XM2MvBINDSySDQxdLF18/ExS4g /NTPIM/exc7YINfB1s7PLCDUwcsgy8HLINDPy8EgzsUNCtrB0MzB1MnUxSDQ0sHXyczYzs8sINrB y8HaIM7FINDSycTF1CwgwSD32SDOxSDQz8zV3snUxSDT18/AIMnO09TS1cvDycAuIO7BysTJ1MUg 19LFzdEsIN7Uz8LZIPfZINPNz8fMySDTxMXMwdTYINfTxSDQ0sHXyczYzs8NCskgzsUg1M/Sz9DR 09gsINDP1M/N1SDe1M8g3NTPIM/Tzs/XwSD3wdvFx88g2sHSwcLP1MvBINcg3NTPzSDQ0s/Fy9TF Lg0KDQogICAgIPfTxcfEwSwgy8/HxMEg98HbIMvP28XMxcsg0NLPxNfJx8HF1NPRINfOydog0M8g 09DJ08vVLCD32SDQz8zV3sHF1MUg2sHLwdogzsEg08zFxNXA3dXAIMnO09TS1cvDycAsINDP3NTP zdUgzc/WxdTFDQrP1NPMxcTJ1Ngg09fPxSDQ0s/E18nWxc7JxSwg0M8g1M/N1Swgy8HL1cAgyc7T 1NLVy8PJwCDP1CD3wdMg2sHLwdrZ18HA1CDMwMTJISDw0skg3NTPzSDeydPMzyD3wdvJyCDQz8vV 0MHUxczFyiwgwSDT1MHMzyDC2dTYDQrJIMTPyM/ELCDXz9rSwdPUwcXUINcgx8XPzcXU0snexdPL z8og0NLPx9LF09PJySEg5dPMySDQz9bFzMHF1MUgxd3FINDP19nTydTYINPXz8ogxM/Iz8QsINTP INDSz9PUzyDQz9PZzMHK1MUgzsHT1M/R3cXFDQrQydPYzc8gKNMg1cvB2sHOztnNySDXINAuNCDF x88gyc7T1NLVy8PJySAjMCDJ2s3FzsXOydHNySwgy8/Oxd7Ozykg0M8gzs/Xz83VINPQydPL1SDB xNLF08/XLiD0wcsg99kgzsHezsXUxSDXxdPYINDSz8PF09MNCtPOwd7BzMEuDQoNCiAgICAg5dPM ySDQz9PMxSDXzsnNwdTFzNjOz8fPINDSz97Uxc7J0SDOwdPUz9HdxcfPINDJ09jNwSDVIPfB0yDP 09TBzMnT2CDXz9DSz9PZIC0g2sHEwdfBytTFIMnILCDOzyDQydvJ1MUgzsUgzsEgRS1tYWlsLCDP 1A0Ky8/Uz9LPx88g99kg0M/M1d7JzMkgxMHOzs/FINDJ09jNzyAoz84gyyDUz83VINfSxc3Fzskg 0M/e1MkgzsHXxdLO0cvBIMLVxMXUIMzJy9fJxMnSz9fBziksIMEg9O/s+OvvIM7BIFdlYk1vbmV5 DQoo0M/TzMXEz9fB1MXM2M7PIN3FzMvO1dTYINDPICLNxc7AIiwgItPPz8Ldxc7J0SIgySAiz9TQ 0sHXydTYIikgySwg1sXMwdTFzNjOzywg9O/s+OvvINDSz8TB18PVIMnO09TS1cvDyckgIzEgKM/T 1MHM2M7ZxSDU0s/FDQotINcgx8/SwdrEzyDCz8zY28XKINPUxdDFzskgLSDXz9rSwdPUwcDdxcog 1yDHxc/NxdTSyd7F08vPyiDQ0s/H0sXT08nJIC0g0MXSxcfS1dbFztkgz9TQ0sHXy8/KIMnO09TS 1cvDycopLCDOxSDawcLZ18HRDQrVy8HawdTYIPP37+ogRS1tYWlsIMTM0SDT19HayS4g7c/KIFdN IMnExc7UycbJy8HUz9IgKN7Uz8LZIPfBzSDT0MXDycHM2M7PIM7FINXazsHXwdTYIMXHzyAi08nN 1czJ0tXRIiDQxdLF18/EIMTFzsXHKSAtDQoyNzEzMDIxNzM2MjUuDQoNCiAgICAg8SDPwtHawdTF zNjOzyDP1NfF3tUuDQoNCiAgICAg9sXMwcAg19PFx88gzsHJzNXe28XHzyEg9sTVINrBy8Haz9cg ySDXz9DSz9PP1yENCg0KICDzIMnTy9LFzs7JzSDV18HWxc7Jxc0sDQoNCiAg7snLz8zByg0KICAN Cg0KLS0gDQpCZXN0IHJlZ2FyZHMsDQogTmlrb2xhaSAgICAgICAgICAgICAgICAgICAgICAgICAg bWFpbHRvOnRyYXN0bWVAaG9ua29uZy5jb20= From elguavas@users.sourceforge.net Tue Feb 26 23:06:14 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 27 Feb 2002 10:06:14 +1100 Subject: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE In-Reply-To: <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> References: <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> Message-ID: <1014764775.4498.43.camel@oberon> Guido van Rossum wrote: > It appears a Tcl bug, fixed in Tcl 8.3.4. Ah, since I was working under Gnome/Sawfish, and Gnome/Sawfish,KDE and Ouroboros/rootless X on Aqua, were the only places the bug could be reproduced, it didn't occur to me to re-test on KDE as I was thinking that it must be the same problem... My own testing on Gnome/Sawfish and Bruce Sherwood's testing on X on OSX confirm that the workaround I discovered of putting in an extra lower() works in those two out of the three known problem domains, but I just ran it on KDE here (I have tcl/tk 8.3.3 installed) and can confirm also that the problem still appears on KDE alone. So it appears that the final fix for the underlying problem in tcl/tk may the only answer under KDE (unless there is a way to test whether a toplevel is at the top of the window stack in tkinter, see later in this message for details). I still feel that the changes to EditorWindow closing I came up with are useful to consider including in python idle (I think I will leave the changes in idlefork) for the following reasons: firstly; making the fiddling around with window focus only occur if absolutely nescessary, ie. if we are closing an editor window that has unsaved changes and only deiconfy()'ing if required, is a much cleaner implementation, and secondly; putting in the extra call to lower() works around the 'freezing' problem on both X on OSX and on Gnome without ill effect. It may be that the fix in tcl/tk 8.3.4 obviates the need for that extra lower() in X on Aqua and Gnome too, but that doesn't change the fact that idle will be being run on those platforms under tcl/tk < 8.3.4 for quite some time into the future and it would be nice if there at least this simple trick could save people from that problematic behaviour. It may still also be possible to provide a work around for people using KDE with tcl/tk < 8.3.4 too. I never could find a way in tkinter to test wheter a toplevel was already at the top of the stack of open windows, if there is a way to test for this then the lower() lift() can be changed to if (window at top of stack test returns true): lift() which would most likely work for kde too since your tcl/tk tests there confirmed my suspicion that it is lift()'ing a toplevel when it isn't required that triggers the problem in the first place. So, Guido, do you have any exalted tkinter experts on tap the way you do with tcl/tk experts? 8^) If you do, and they know a way of testing for such a condition under tkinter, then we can extend the workaround for Gnome/X on Aqua users with tcl/tk < 8.3.4 to KDE users with tcl/tk < 8.3.4 too. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Tue Feb 26 23:21:45 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 27 Feb 2002 10:21:45 +1100 Subject: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE In-Reply-To: <1014764775.4498.43.camel@oberon> References: <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> <1014764775.4498.43.camel@oberon> Message-ID: <1014765705.4498.47.camel@oberon> Stephen M. Gava wrote: > if (window at top of stack test returns true): > lift() Oops, that should obviously be: if not (window at top of stack test returns true): lift() -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From mats@laplaza.org Tue Feb 26 23:28:59 2002 From: mats@laplaza.org (Mats Wichmann) Date: Tue, 26 Feb 2002 16:28:59 -0700 Subject: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE In-Reply-To: <1014764775.4498.43.camel@oberon> References: < <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> Message-ID: <5.1.0.14.1.20020226162645.01c79cd8@204.151.72.2> At 10:06 AM 2/27/2002 +1100, Stephen M. Gava wrote: >Guido van Rossum wrote: >> It appears a Tcl bug, fixed in Tcl 8.3.4. > >It may be that the fix in tcl/tk 8.3.4 obviates the need for that extra >lower() in X on Aqua and Gnome too, but that doesn't change the fact >that idle will be being run on those platforms under tcl/tk < 8.3.4 for >quite some time into the future and it would be nice if there at least >this simple trick could save people from that problematic behaviour. A quick hunt with rpmfind.net indicates that no current "major" Linux distribution is on 8.3.4 yet, even the ones that are in beta right now. From elguavas@users.sourceforge.net Tue Feb 26 23:42:29 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 27 Feb 2002 10:42:29 +1100 Subject: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE In-Reply-To: <5.1.0.14.1.20020226162645.01c79cd8@204.151.72.2> References: < <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> <5.1.0.14.1.20020226162645.01c79cd8@204.151.72.2> Message-ID: <1014766949.4954.3.camel@oberon> Mats Wichmann wrote: > A quick hunt with rpmfind.net indicates that no current "major" > Linux distribution is on 8.3.4 yet, even the ones that are in > beta right now. I run debian, which I've always considered a 'major' distribution, ;p , but which won't be found on rpmfind.net, and even debian unstable (the bleeding edge) doesn't have tlc/tk 8.3.4 yet. Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy " From elguavas@users.sourceforge.net Thu Feb 28 00:08:09 2002 From: elguavas@users.sourceforge.net (Stephen M. Gava) Date: 28 Feb 2002 11:08:09 +1100 Subject: [Idle-dev] Slow close? In-Reply-To: <1014765705.4498.47.camel@oberon> References: <200202262146.g1QLk0s20373@pcp742651pcs.reston01.va.comcast.net> <1014764775.4498.43.camel@oberon> <1014765705.4498.47.camel@oberon> Message-ID: <1014854891.480.74.camel@oberon> We now have two threads on this subject: 'Re: [Idle-dev] Slow close?' and, 'Re: [Idle-dev] "Jeff Hobbs": RE: Strange delays when using raise or lower in KDE' , let's go back to just using the 'Slow close?' thread. I just tested my proposed bugfix/patch to idle on a range of window manager platforms that I have available and I can summarise the results we have so far as follows: Under ms windows and the following X window managers; WindowMaker, BlackBox, Enlightenment, Sawfish (without Gnome): the problem never existed, and the tcl/tk bug work-around of putting in an extra call to lower() before the lift() has no ill effect. The other aspects of the patch are still beneficial here because we now don't mess with edit window stacking level or visibility unless we absolutely need to. Under Gnome/Sawfish, KDE and Oroborus/rootless X on Aqua: the problem did exist; the benefits of the patch limiting the times the problem can be triggered, mentioned above, mean that even without the extra lower() work-around there will be less cases when the tcl/tk bug is triggered, and so less cases where the user will notice a problem (ie there will now only be a 'delay on closing' problem for edit windows that have unsaved changes). The extra lower() successfully works around the delay on closing problem in both the Gnome and X on OSX cases, however, on KDE only, it merely changes the nature of the problem, making the pause occur after the initial lower() instead. I've had another good look through Tkinter.py (particularly the winfo_* methods) and I still don't see any way of finding out if a toplevel is already on top, so unless we get unexpected good news on that topic we are really left with two choices in working around, or at least limiting the problem, in the places we know it currently occurs: If the patch were applied to idle _without_ the work-around lower(), then the pausing problem will be limited, on any platform it affects, to occurring only when closing an edit window with unsaved changes. If the patch is applied _with_ the work-around then we know it solves the problem in the Gnome and X on Aqua cases, but it also simply changes the nature of the problem under KDE to one which I agree perhaps looks even uglier. Since it is likely that idle will continue to be run under tcl/tk < 8.3.4 for quite some time into the future I feel that at least the minimal form of the patch (without the tcl/tk bug work-around lower()) should be put into python idle. Without that work-around the patch is beneficial to idle's behaviour in all cases. I don't know whether working around the problem under Gnome and X on Aqua is justifiable in the light of the change in the nature of the problem it causes under KDE or not. Anyone? One important point that hasn't yet been addressed though is, since tcl/tk 8.3.4 seems to be pretty unavailable (on linux at least) yet, has anyone confirmed that the undesirable behaviour goes away with tcl/tk >= 8.3.4, epsecially under KDE?? Stephen. -- Stephen M. Gava IDLEfork ( http://idlefork.sourceforge.net ) " just like IDLE, only crunchy "