""" Preferences is a collection of utilities to read and write preferences. To run preferences, install python 2.x on your machine, which is avaliable from http://www.python.org/download/ You'll also need Tkinter, which probably came with the python installation. If it did not, look for it at: www.tcl.tk/software/tcltk/ Then in the folder which preferences is in, type 'python' in a shell to run the python interpreter. Finally type 'from preferences import *' to import this program. Below is an example of preferences use. This example is run in a terminal in the folder which contains Hollow Square.gcode and preferences.py. >>> from preferences import * >>> getFileText('Hollow Square.gcode') '( GCode generated by April 17,2007 Skeinforge )\n( Extruder Initialization )\nM100 P210\nM103\nM105\nM108 P0.7\nM109 P0.654\nM110 P0.654\nG21\nG90\nG28\n( Extruder Movement )\n( Extruder paths for layer 0 of Hollow Square )\nM113\nG1 X2.727 Y-2.505 Z0.33 F600.0\n .. many lines of text .. """ import cStringIO import gcodec import os import webbrowser try: from Tkinter import * except: print( 'You do not have Tkinter, which is needed for the graphical interface, you will only be able to use the command line.' ) print( 'Information on how to download Tkinter is at:\nwww.tcl.tk/software/tcltk/' ) __author__ = "Enrique Perez (perez_enrique@yahoo.com)" __date__ = "$Date: 2008/23/04 $" __license__ = "GPL 3.0" def displayDialog( displayPreferences ): "Display the preferences dialog." readPreferences( displayPreferences ) root = Tk() preferencesDialog = PreferencesDialog( displayPreferences, root ) root.mainloop() def getArchiveText( preferences ): "Get the text representation of the archive." archiveWriter = cStringIO.StringIO() archiveWriter.write( 'Format is tab separated preferences.\n' ) for preference in preferences.archive: archiveWriter.write( preference.name + '\t' + preference.getValueString() + '\n' ) return archiveWriter.getvalue() def getPreferencesFilePath( filename, folderName = '' ): "Get the preferences file path, which is the home directory joined with the folder name and filename." directoryName = os.path.join( os.path.expanduser( '~' ), '.skeinforge' ) # if folderName != '': # directoryName = os.path.join( directoryName, folderName ) try: os.mkdir( directoryName ) except OSError: pass return os.path.join( directoryName, filename ) def readPreferences( preferences ): "Set an archive to the preferences read from a file." preferencesText = gcodec.getFileText( preferences.filenamePreferences ) if preferencesText == '': print( 'Since the preferences file:' ) print( preferences.filenamePreferences ) print( 'does not exist, the default preferences will be written to that file.' ) writePreferences( preferences ) lines = gcodec.getTextLines( preferencesText ) preferenceTable = {} for preference in preferences.archive: preferenceTable[ preference.name ] = preference for lineIndex in range( len( lines ) ): setArchiveToLine( lineIndex, lines, preferenceTable ) def setArchiveToLine( lineIndex, lines, preferenceTable ): "Set an archive to a preference line." line = lines[ lineIndex ] splitLine = line.split( '\t' ) if len( splitLine ) < 2: return filePreferenceName = splitLine[ 0 ] if filePreferenceName in preferenceTable: preferenceTable[ filePreferenceName ].setValueToSplitLine( lineIndex, lines, splitLine ) def writePreferences( preferences ): "Write the preferences to a file." gcodec.writeFileText( preferences.filenamePreferences, getArchiveText( preferences ) ) class BooleanPreference: "A class to display, read & write a boolean." def addToDialog( self, preferencesDialog ): "Add this to the dialog." self.var = IntVar() self.var.set( self.value ) self.checkbutton = Checkbutton( preferencesDialog.master, text = self.name, variable = self.var ) self.checkbutton.grid( row = preferencesDialog.row, columnspan = 4, sticky=W ) preferencesDialog.row += 1 def getFromValue( self, name, value ): "Initialize." self.value = value self.name = name return self def getValueString( self ): "Get the boolean as a string." return str( self.value ) def setToDisplay( self ): "Set the boolean to the checkbox." self.value = bool( self.var.get() ) def setValueToSplitLine( self, lineIndex, lines, splitLine ): "Set the value to the second word of a split line." self.setValueToString( splitLine[ 1 ] ) def setValueToString( self, valueString ): "Set the boolean to the string." self.value = ( valueString.lower() == 'true' ) class Filename( BooleanPreference ): def addToDialog( self, preferencesDialog ): "Add this to the dialog." preferencesDialog.executables.append( self ) "A class to display, read & write a filename." def execute( self ): try: import tkFileDialog summarized = gcodec.getSummarizedFilename( self.value ) filename = tkFileDialog.askopenfilename( filetypes = self.getFilenameFirstTypes(), initialdir = os.path.dirname( summarized ) + os.sep, initialfile = os.path.basename( summarized ), title = self.name ) if ( str( filename ) == '()' ): self.wasCancelled = True else: self.value = filename except: print( 'Oops, ' + self.name + ' could not get filename.' ) def getFromFilename( self, fileTypes, name, value ): "Initialize." self.getFromValue( name, value ) self.fileTypes = fileTypes self.wasCancelled = False return self def getFilenameFirstTypes( self ): "Get the file types with the file type of the filename moved to the front of the list." basename = os.path.basename( self.value ) splitFile = basename.split( '.' ) if len( splitFile ) < 1: return self.fileTypes baseExtension = splitFile[ - 1 ] for fileType in self.fileTypes: fileExtension = fileType[ 1 ].split( '.' )[ - 1 ] if fileExtension == baseExtension: filenameFirstTypes = self.fileTypes[ : ] filenameFirstTypes.remove( fileType ) return [ fileType ] + filenameFirstTypes return self.fileTypes def setToDisplay( self ): "Pass." pass def setValueToString( self, valueString ): "Set the filename to the string." self.value = valueString class FloatPreference( BooleanPreference ): "A class to display, read & write a float." def addToDialog( self, preferencesDialog ): "Add this to the dialog." self.entry = Entry( preferencesDialog.master ) self.entry.insert( 0, self.getValueString() ) self.entry.grid( row = preferencesDialog.row, column = 2, columnspan = 2, sticky=W ) self.label = Label( preferencesDialog.master, text = self.name ) self.label.grid( row = preferencesDialog.row, column = 0, columnspan = 2, sticky=W ) preferencesDialog.row += 1 def setToDisplay( self ): "Set the float to the entry field." valueString = self.entry.get() self.setValueToString( valueString ) def setValueToString( self, valueString ): "Set the boolean to the string." try: self.value = float( valueString ) except: print( 'Oops, can not read float' + self.name + ' ' + valueString ) class IntPreference( FloatPreference ): "A class to display, read & write an int." def setValueToString( self, valueString ): "Set the boolean to the string." dotIndex = valueString.find( '.' ) if dotIndex > - 1: valueString = valueString[ : dotIndex ] try: self.value = int( valueString ) except: print( 'Oops, can not read integer ' + self.name + ' ' + valueString ) class Radio( BooleanPreference ): "A class to display, read & write a boolean with associated radio button." def addToDialog( self, preferencesDialog ): "Add this to the dialog." self.radiobutton = Radiobutton( preferencesDialog.master, text = self.name, value = preferencesDialog.row, variable = self.getIntVar() ) self.radiobutton.grid( row = preferencesDialog.row, columnspan = 4, sticky=W ) if self.value: self.getIntVar().set( preferencesDialog.row ) preferencesDialog.row += 1 def getFromRadio( self, name, radio, value ): "Initialize." self.getFromValue( name, value ) self.radio = radio return self def getIntVar( self ): "Get the IntVar for this radio button group." if len( self.radio ) == 0: self.radio.append( IntVar() ) return self.radio[ 0 ] def setToDisplay( self ): "Set the boolean to the checkbox." self.value = ( self.getIntVar().get() == self.radiobutton[ 'value' ] ) class RadioLabel( Radio ): "A class to display, read & write a boolean with associated radio button." def addToDialog( self, preferencesDialog ): "Add this to the dialog." Label( preferencesDialog.master, text = self.labelText ).grid( row = preferencesDialog.row, column = 0, columnspan = 4, sticky=W ) self.radiobutton = Radiobutton( preferencesDialog.master, text = self.name, value = preferencesDialog.row, variable = self.getIntVar() ) self.radiobutton.grid( row = preferencesDialog.row + 1, columnspan = 4, sticky=W ) if self.value: self.getIntVar().set( preferencesDialog.row ) preferencesDialog.row += 2 def getFromRadioLabel( self, name, labelText, radio, value ): "Initialize." self.getFromRadio( name, radio, value ) self.labelText = labelText return self def getIntVar( self ): "Get the IntVar for this radio button group." if len( self.radio ) == 0: self.radio.append( IntVar() ) return self.radio[ 0 ] def setToDisplay( self ): "Set the boolean to the checkbox." self.value = ( self.getIntVar().get() == self.radiobutton[ 'value' ] ) class PreferencesDialog: def __init__( self, displayPreferences, master ): self.displayPreferences = displayPreferences self.executables = [] self.master = master self.row = 0 master.title( displayPreferences.title ) frame = Frame( master ) for preference in displayPreferences.archive: preference.addToDialog( self ) Label( master ).grid( row = self.row, column = 0 ) self.row += 1 saveButton = Button( master, text = "Save Preferences", command = self.savePreferencesDestroy ) saveButton.grid( row = self.row, column = 0 ) executeButton = Button( master, text = displayPreferences.executeTitle, command = self.execute ) executeButton.grid( row = self.row, column = 1 ) helpButton = Button( master, text = " ? ", command = self.openBrowser ) helpButton.grid( row = self.row, column = 2 ) cancelButton = Button( master, text = "Cancel", fg = "red", command = master.destroy ) cancelButton.grid( row = self.row, column = 3 ) def execute( self ): for executable in self.executables: executable.execute() self.savePreferences() self.displayPreferences.execute() self.master.destroy() def openBrowser( self ): webbrowser.open(os.path.abspath(os.path.join("doc", self.displayPreferences.filenameHelp))) # os.system( webbrowser.get().name + ' ' + self.displayPreferences.filenameHelp )#used this instead of webbrowser.open() to workaround webbrowser open() bug def savePreferences( self ): for preference in self.displayPreferences.archive: preference.setToDisplay() writePreferences( self.displayPreferences ) def savePreferencesDestroy( self ): self.savePreferences() self.master.destroy() """ class Dialog(Toplevel): def __init__(self, parent, title = None): Toplevel.__init__(self, parent) self.transient(parent) if title: self.title(title) self.parent = parent self.result = None body = Frame(self) self.initial_focus = self.body(body) body.pack(padx=5, pady=5) self.buttonbox() self.grab_set() if not self.initial_focus: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50)) self.initial_focus.focus_set() self.wait_window(self) def body(self, master): # create dialog body. return widget that should have # initial focus. this method should be overridden pass def buttonbox(self): # add standard button box. override if you don't want the # standard buttons box = Frame(self) w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE) w.pack(side=LEFT, padx=5, pady=5) w = Button(box, text="Cancel", width=10, command=self.cancel) w.pack(side=LEFT, padx=5, pady=5) self.bind("<Return>", self.ok) self.bind("<Escape>", self.cancel) box.pack() # # standard button semantics def ok(self, event=None): if not self.validate(): self.initial_focus.focus_set() # put focus back return self.withdraw() self.update_idletasks() self.apply() self.cancel() def cancel(self, event=None): # put focus back to the parent window self.parent.focus_set() self.destroy() # # command hooks def validate(self): return 1 # override def apply(self): pass # override class MyDialog(Dialog): def body(self, master): Label(master, text="First:").grid(row=0) Label(master, text="Second:").grid(row=1) self.e1 = Entry(master) self.e2 = Entry(master) self.e1.grid(row=0, column=1) self.e2.grid(row=1, column=1) return self.e1 # initial focus def apply(self): first = float(self.e1.get()) second = float(self.e2.get()) self.result = first, second def dialogTest(): root = Tk() d = MyDialog(root) print( d.result) root = Tk() w = Label(root, text="Hello, world!") w.pack() root.mainloop() """