def __init__(self): self.net_hand = NetworkHandler(self.parse_message) #self.cursor_thread_run = True #self.cursor_thread = Thread(target=self.track_cursor) #self.cursor_thread.setDaemon(True) #self.u2_pos = None self.names = {} self.cursor_colors = ['red', 'green', 'blue', 'yellow', 'cyan'] self.autosave_thread = Thread(target=self.autosave_thread) self.autosave_thread.setDaemon(True) current_terminal_buffer_column = 0 current_terminal_buffer_line = 0 self.log = logging.getLogger('jumpy') self.mac = hex(uuid.getnode()) self.is_host = False self.have_perms = False self.mac_name = dict() self.workspace = Workspace() self.create()
def open(self, frame, page, buffer): Workspace.open(self, frame, page, buffer) frame.link(self.handle_key, self, 'kbd keydown') self._partial_command = None self._keybindings = {} self._mark = None self._paste_offset = 1 self.focus()
def __init__(self, semObject, className, modelPath=None): # Use the AToM3 Tkinter root window self.className = className root = self.rootInitilization(semObject, modelPath) if (not root): return self.root = root self.mainHandler = MainHandler.MainHandler(self) root.bind("<Key>", self.mainHandler.onKey) root.bind("<Shift-Key>", self.mainHandler.onShiftKey) root.bind("<Control-Key>", self.mainHandler.onControlKey) zoom = 1.0 self.menuBar = Tools.MenuBar(root, self, self.mainHandler) #goes to top by itself self.statusBar = Tools.StatusBar(root, "", zoom, 0, 0) #goes to bottom by itself self.colorSelector = Colors.ColorSelector( root, self.mainHandler) #goes to bottom by itself self.toolFrame = Tkinter.Frame(root, relief=Tkinter.RAISED, bd=1) self.toolSelector = Tools.ToolSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.outlineFillOptionSelector = Tools.OutlineFillOptionSelector( self.toolFrame, self.mainHandler, Tkinter.TOP) self.lineWidthSelector = Tools.LineWidthSelector( self.toolFrame, self.mainHandler, Tkinter.TOP) self.toolFrame.pack(side=Tkinter.LEFT) self.workspace = Workspace(self, self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.mainHandler, zoom) #goes to the right by itself self.workspace.setZoom(zoom, 0, 0) self.canvas = self.workspace.getCanvas() self.scripting = Scripting() ## self.GFs = self.open() self.GFs = [] self.extendedInitilization(semObject) self.clipboardList = [] self.undoStack = [] self.mainHandler.start() self.compositionVisitor = GFVisitors.CompositionVisitor(self) self.colorVisitor = GFVisitors.ColorVisitor() self.widthVisitor = GFVisitors.WidthVisitor() self.optionVisitor = GFVisitors.OptionVisitor(self) # Carefully try to load the GF model (may fail for random reasons) try: self.GFs = self.open() except: raise
def handle_list(args, configs): from Workspace import Workspace parser = argparse.ArgumentParser(description=cmd_description_list, usage=cmd_usage_list) if workspace_args is not None: [parser.add_argument(*arg[0], **arg[1]) for arg in workspace_args] my_args = parser.parse_args(args) wksp = Workspace(args=my_args, configs=configs) wksp.print_module_names()
def __init__(self, semObject, className, modelPath=None): # Use the AToM3 Tkinter root window self.className = className root = self.rootInitilization(semObject, modelPath) if( not root ): return self.root = root self.mainHandler = MainHandler.MainHandler(self) root.bind("<Key>", self.mainHandler.onKey) root.bind("<Shift-Key>", self.mainHandler.onShiftKey) root.bind("<Control-Key>", self.mainHandler.onControlKey) zoom = 1.0 self.menuBar = Tools.MenuBar(root, self, self.mainHandler) #goes to top by itself self.statusBar = Tools.StatusBar(root, "", zoom, 0, 0) #goes to bottom by itself self.colorSelector = Colors.ColorSelector(root, self.mainHandler) #goes to bottom by itself self.toolFrame = Tkinter.Frame(root, relief=Tkinter.RAISED, bd=1) self.toolSelector = Tools.ToolSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.outlineFillOptionSelector = Tools.OutlineFillOptionSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.lineWidthSelector = Tools.LineWidthSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.toolFrame.pack(side=Tkinter.LEFT) self.workspace = Workspace(self, self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.mainHandler, zoom) #goes to the right by itself self.workspace.setZoom(zoom, 0, 0) self.canvas = self.workspace.getCanvas() self.scripting = Scripting() ## self.GFs = self.open() self.GFs = [] self.extendedInitilization( semObject ) self.clipboardList = [] self.undoStack = [] self.mainHandler.start() self.compositionVisitor = GFVisitors.CompositionVisitor(self) self.colorVisitor = GFVisitors.ColorVisitor() self.widthVisitor = GFVisitors.WidthVisitor() self.optionVisitor = GFVisitors.OptionVisitor(self) # Carefully try to load the GF model (may fail for random reasons) try: self.GFs = self.open() except: raise
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from Portal import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) vr_lab_front = Workspace('VR-Lab-Front', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) video_visibility_table = { "dlp_wall" : {"lcd_wall" : True, "portal" : False} , "lcd_wall" : {"dlp_wall" : True, "portal" : False} , "portal" : {"dlp_wall" : True, "lcd_wall" : True} } vr_lab_rear.associate_video_3D("/opt/kinect-resources/kinect_surface_K_26_Fake.ks" , avango.gua.make_trans_mat(0.0, 0.043, 1.6) , video_visibility_table) vr_lab_front.associate_video_3D("/opt/kinect-resources/kinect_surface_K_23_24_25.ks" , avango.gua.make_trans_mat(0.0, 0.043, 1.6) , video_visibility_table)
def initUI(self): self.menuBar = MenuBar(self) self.setMenuBar(self.menuBar) self.workspace = Workspace(self) self.setCentralWidget(self.workspace)
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from Portal import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) workspaces = [vr_lab_rear] ## Create Navigation instances ## trace_visibility_list_table_nav = { "dlp_wall": False, "table": False, "portal": False } spacemouse_navigation = SteeringNavigation() spacemouse_navigation.my_constructor( STARTING_MATRIX = avango.gua.make_trans_mat(0, 0, 20) * \ avango.gua.make_rot_mat(0, 0, 1, 0) , STARTING_SCALE = 50.0 , INPUT_DEVICE_TYPE = 'Spacemouse'
# Create our Break Event event_winterbreak = Event( Name="Winter Break Development", Owner=mUser, sTime=dateTimeToMillis(event_winterbreak_sTime), eTime=dateTimeToMillis(event_winterbreak_eTime), ) # Create all the tasks that have to be done task_develop_calendar = Task(Name="Develop Calendar System", Status=STS_CLOSED) task_develop_task_system = Task(Name="Develop Task System", Status=STS_CLOSED) task_develop_workspace_system = Task(Name="Develop Workspace System", Status=STS_IN_PROG) task_develop_project_system = Task(Name="Develop Project System", Status=STS_OPEN) # Create our workspace and intranet project workspace_appteam = Workspace(Name="Applications Team") project_intranet = Project(Name="Intranet Project") # Set the description of our winterbreak project event_winterbreak.setDescription("Developing the Intranet to a useable state") # Set the description of our tasks task_develop_calendar.setDescription("Develop a working Calendar System to implement into the intranet") task_develop_task_system.setDescription("Develop a working task system to implement into the intranet") task_develop_workspace_system.setDescription("Develop a working workspace system to implement into the intranet") task_develop_project_system.setDescription( "Develop a working project system under workspace system in the intranet" ) # Add the Owner of each task (Who is going to fulfill the task) appCalendar.addOwner(mUser)
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from VirtualDisplay import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) video_visibility_table = { "dlp_wall" : {"table" : False, "portal" : False} , "table" : {"dlp_wall" : True, "portal" : False} , "portal" : {"dlp_wall" : True, "table" : False} } #vr_lab_rear.associate_video_3D("/opt/kinect-resources/kinect_surface_K_23_24_25.ks" # , avango.gua.make_trans_mat(0.0, 0.043, 1.6) # , video_visibility_table) workspaces = [vr_lab_rear] ## Create Navigation instances ## trace_visibility_list_dlp_wall_nav = { "dlp_wall" : False
class Editor: # Canvas size is used by the snap grid to determine how far to draw the grid # Actually, should be called the canvas bounding box :p # BTW: Using negative values, or values that are too small, doesn't work well :p CANVAS_SIZE_TUPLE = [0, 0, 2000, 2000] def __init__(self, semObject, className, modelPath=None): # Use the AToM3 Tkinter root window self.className = className root = self.rootInitilization(semObject, modelPath) if( not root ): return self.root = root self.mainHandler = MainHandler.MainHandler(self) root.bind("<Key>", self.mainHandler.onKey) root.bind("<Shift-Key>", self.mainHandler.onShiftKey) root.bind("<Control-Key>", self.mainHandler.onControlKey) zoom = 1.0 self.menuBar = Tools.MenuBar(root, self, self.mainHandler) #goes to top by itself self.statusBar = Tools.StatusBar(root, "", zoom, 0, 0) #goes to bottom by itself self.colorSelector = Colors.ColorSelector(root, self.mainHandler) #goes to bottom by itself self.toolFrame = Tkinter.Frame(root, relief=Tkinter.RAISED, bd=1) self.toolSelector = Tools.ToolSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.outlineFillOptionSelector = Tools.OutlineFillOptionSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.lineWidthSelector = Tools.LineWidthSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.toolFrame.pack(side=Tkinter.LEFT) self.workspace = Workspace(self, self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.mainHandler, zoom) #goes to the right by itself self.workspace.setZoom(zoom, 0, 0) self.canvas = self.workspace.getCanvas() self.scripting = Scripting() ## self.GFs = self.open() self.GFs = [] self.extendedInitilization( semObject ) self.clipboardList = [] self.undoStack = [] self.mainHandler.start() self.compositionVisitor = GFVisitors.CompositionVisitor(self) self.colorVisitor = GFVisitors.ColorVisitor() self.widthVisitor = GFVisitors.WidthVisitor() self.optionVisitor = GFVisitors.OptionVisitor(self) # Carefully try to load the GF model (may fail for random reasons) try: self.GFs = self.open() except: raise def rootInitilization(self, semObject, modelPathAndFile): """ Extension to the old initilization routine This directly sets up the editor for generating icons for AToM3 """ # Do we have everything we need? Check the minimum requirements: try: atom3i = semObject.parent TkRoot = atom3i.parent statusbar = atom3i.statusbar except: print "ERROR: Unable to start editor, lacking information (atom3i,TkRoot, or statusbar)" return None self.atom3i = atom3i # Do we have the fileName we'll be using to save the graphicalAppearence? if(not modelPathAndFile): modelPathAndFile = statusbar.getState(statusbar.MODEL)[1][0] self.modelPath = os.path.split(modelPathAndFile)[0] if( self.modelPath == '' ): tkMessageBox.showerror( "Icon-Editor model path error", "Please save your ER model before modifying graphical appearences.", parent=TkRoot) return None # Setup a new toplevel window for the editor root = Tkinter.Toplevel( TkRoot ) root.title("Icon Editor - AToM3") root.geometry("%dx%d%+d%+d" % (800, 600, 100, 0)) root.transient( TkRoot ) root.grab_set() return root def extendedInitilization( self, semObject ): # SnapGrid: since this is a singleton, must first disable old stuff self.snapGridInfoTuple = None self.snapGridInfoBackup = None SnapGrid.applyLayout( self, disableForPrinting = True ) SnapGrid.applyLayout( self ) # Useful binds self.root.bind("<Alt-x>", lambda event: self.mainHandler.onExit() ) self.root.bind("<F1>", lambda event: self.mainHandler.onSnapSetting() ) self.root.bind("<Control-e>", lambda event: self.mainHandler.onExport() ) self.root.protocol("WM_DELETE_WINDOW", self.mainHandler.onExit ) # AToM3 graphical appearence exporter self.exportVisitor = SaveGFVisitor.ATOM3_Export_Visitor(semObject, self) # Extra info: includes text attributes that change dynamically & named ports self.attributes = semObject.attributesToDraw() # Icon Positioning System (not quite GPS) self.iconPositioner = IconPositioner( self ) self.root.bind("<F2>", lambda event: self.iconPositioner.createDialog() ) def iconPlacer(self, anchor = 'nw' ): """ Places the graphical icon at a position determined by 'anchor' If anchor is 'nw', then the icon will be moved so that when the user creates an item with this icon, the top-left edge of the icon appears at the position the user clicked. If anchor is 'origin', then the icon appears exactly centered on origin. If anchor is of type 'float', then use the float value directly. """ x0,y0,x1,y1 = self.getBoundingBox( self.getGFs() ) # Top-Left positioning if( anchor == 'nw' ): dx = -x0 dy = -y0 # Center positioning elif( anchor == 'origin' ): dx = -x0 - ( x1 - x0 ) / 2 dy = -y0 - ( y1 - y0 ) / 2 # Manual offset elif( type( anchor ) == type( float() ) ): dx = dy = anchor # Invalid use else: raise Exception, "Wake up and smell the API you lopsided kitten burger! j/k" for gf in self.getGFs(): gf.translate( dx,dy ) self.addUndoTranslate( self.getGFs(), dx, dy ) def getAttributes( self ): return self.attributes def exit( self, event=None ): """ Exit point for the Icon-Editor """ # Clean up the snap grid SnapGrid.applyLayout( self, disableForPrinting = True ) # Did AToM3 want its snap grid back? :D self.atom3i.toggleSnapGrid() # Make this window go boom self.root.destroy() def getRoot(self): """get a reference to the root window of the editor""" return self.root def save(self, event=None): """ 1) Exports a graphical appearence file readable by AToM3 2) Saves everything in a pickled file (not cross-platform compatible) """ # Make sure that Text is at the end of the list gfListSorted = SaveGFVisitor.TextSortVisitor().sortGraphicalForms( self.getGFs() ) # Uber-cool save dialog :D if( 1 ): text = 'The following AToM3 file will be generated:\n\n'+\ os.path.normpath( os.path.join( self.modelPath, 'graph_' + self.className + '.py' ) ) +\ '\n\nIf you have not already done so, you should position the icon '+\ 'so that it appears where you expect it to in your models.' saveDialog = Dialog.Dialog(None, {'title': 'Saving graphical appearence file...', 'text': text,'bitmap': '', 'default': 0, 'strings': ('Position icon','Save','Save & Exit','Cancel')}) # Position icon if( saveDialog.num == 0 ): self.iconPositioner.createDialog() return self.save() # Save if( saveDialog.num == 1 ): self.exportVisitor.AToM3_export( gfListSorted ) return self.root.focus_force() # Save & Exit if( saveDialog.num == 2 ): self.exportVisitor.AToM3_export( gfListSorted ) return self.exit() # Cancel elif( saveDialog.num == 3 ): return self.root.focus_force() # Lousy Dialog save, m'kay elif( 0 ): self.exportVisitor.AToM3_export( gfListSorted ) tkMessageBox.showinfo( "Saving Graphical Appearence", "The following AToM3 file has been generated:\n\n" + os.path.normpath( os.path.join( self.modelPath, 'graph_' + self.className + '.py' ) ), parent=self.root) # Pickle save.... EWWWWWWWWWWWWW! elif( 0 ): gfList = self.getGFs() gfListCopy = [] for gf in gfList: gfListCopy.append(gf.copy()) for gf in gfListCopy: gf.setEventHandler(None) gf.setCanvas(None) gf.setZoom(1.0) # Store extra scripting info gfListCopy = [ self.scripting ] + gfListCopy fileName = os.path.normpath( os.path.join( self.modelPath, 'graph_' + self.className + '.gf1' ) ) file=open( fileName, "w") pickle.dump(gfListCopy, file) file.close() tkMessageBox.showinfo( "Saving Graphical Appearence", "The following icon-editor file has been generated:\n\n"+ fileName, parent=self.root) def export(self): filename = tkFileDialog.asksaveasfilename(title="Export",filetypes=[("Postscript","*.ps")]) if filename != "": self.canvas.postscript(file=filename) def debug(self): """ Many things can go wrong when openning a graphical file this gives the user more flexibility in figuring out wtf went wrong """ print "Error occured in importer", __file__ from tkMessageBox import askokcancel res = askokcancel("Import Error", "The existing graphical file could not be imported\n" \ "Press Ok to proceed normally, Cancel to dump error to console") # Raise the 'caught' error if(res == False): raise def open( self ): """ Tries to open an existing graphical form in the AToM3 format and to reproduce it on canvas """ fileName = os.path.normpath( os.path.join( self.modelPath, 'graph_' + self.className + '.py' ) ) if( not os.path.exists( fileName ) ): return [] nameClass = "graph_"+self.className dc = Tkinter.Canvas(self.root) # File is already loaded if nameClass in sys.modules.keys(): del sys.modules[nameClass] # Make sure we can reach the path and import from it sys.path.append( self.modelPath ) # Load it in memory try: exec "import graph_"+self.className+"\n" sys.path = sys.path[:-1] except SyntaxError: # class Name not valid sys.path = sys.path[:-1] print "Syntax Error, Could not open graphical file", self.className self.debug() return [] except IOError: # could not open file (?) sys.path = sys.path[:-1] print "IO Error, Could not open graphical file", self.className self.debug() return [] except ImportError: # could not open file... print "Import Error, Could not open graphical file", self.className self.debug() sys.path = sys.path[:-1] return [] try: # obtain the class object className = eval('graph_'+self.className+'.graph_'+self.className) except: print 'WARNING:', 'graph_'+self.className+'.graph_'+self.className, \ 'not found' return [] new_obj = className(0, 0) # create an instance of the new class new_obj.DrawObject(dc) # draw the object # Get the constraints constraintList = [] for constraint in new_obj.constraintList: constraintList.append( constraint.getValue() ) self.scripting.setConstraintList( constraintList ) self.scripting.setRunTimeChange( new_obj.ChangesAtRunTime ) GFlist = [] # List with the handles of all the shapes drawn handleList = [] for handle in dc.find_withtag(new_obj.tag): if( not handle in handleList): handleList.append(handle) # Get the connectors in self.connectors for handle in new_obj.connectors: x0, y0, x1, y1 = dc.coords(handle) if( new_obj.namedConnectors.has_key( handle) ): name = new_obj.namedConnectors[ handle ] gf = Graphics.NamedConnector(x0, y0, canvas=self.canvas, eventHandler=self.mainHandler, name=name) else: gf = Graphics.Connector(x0, y0, canvas=self.canvas, eventHandler=self.mainHandler) GFlist.append( gf ) # Get the drawn semantic attributes... handleAttributeDict = dict() for attribute in new_obj.attr_display.keys(): handleAttributeDict[ new_obj.attr_display[ attribute ] ] = attribute # Get the image dict, if any if( hasattr( new_obj, 'imageDict' ) ): Graphics.Image.IMAGE_DICT = new_obj.imageDict # Get the GraphicalForm objects objectNumberPattern = re.compile( '\Agf(\d*)\Z' ) for graphicalForm in new_obj.graphForms: handle = graphicalForm.getHandler() objectNumber = int( objectNumberPattern.search( graphicalForm.getName() ).group(1) ) coords = dc.coords( handle ) objectType = dc.type(handle) # Attribute --- Special Text if( handleAttributeDict.has_key( handle ) ): attribute = handleAttributeDict[ handle ] fontObject = graphicalForm.getFont() if( fontObject ): if( fontObject.cget( 'weight' ) == 'bold' ): bold = True else: bold = False if( fontObject.cget( 'slant' ) == 'bold' ): italic = True else: italic = False GFlist.append( Graphics.Attribute(coords[0],coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),text=attribute, anchor=dc.itemcget(handle, "anchor"), family=fontObject.cget( 'family' ), size=int(float(fontObject.cget( 'size' ))),bold=bold,savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))), italic=italic,underline=int(float(fontObject.cget( 'underline' )))) ) # Backward compatibility with graphical appearences that don't have # a font object. NOTE: Font type & size info is neccessarily lost. else: GFlist.append( Graphics.Attribute(coords[0],coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),text=attribute, width=int(float(dc.itemcget(handle, "width"))), anchor=dc.itemcget(handle, "anchor"), savedNumber=objectNumber ) ) elif( objectType == 'text' ): fontObject = graphicalForm.getFont() if( fontObject ): if( fontObject.cget( 'weight' ) == 'bold' ): bold = True else: bold = False if( fontObject.cget( 'slant' ) == 'bold' ): italic = True else: italic = False GFlist.append( Graphics.Text(coords[0],coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),text=dc.itemcget(handle, "text"), anchor=dc.itemcget(handle, "anchor"), family=fontObject.cget( 'family' ), size=int(float(fontObject.cget( 'size' ))),bold=bold,savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))), italic=italic,underline=int(float(fontObject.cget( 'underline' )))) ) # Backward compatibility with graphical appearences that don't have # a font object. NOTE: Font type & size info is neccessarily lost. else: GFlist.append( Graphics.Text(coords[0],coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),text=dc.itemcget(handle, "text"), width=int(float(dc.itemcget(handle, "width"))), anchor=dc.itemcget(handle, "anchor"), savedNumber=objectNumber ) ) elif( objectType == 'line' ): if( dc.itemcget(handle, "smooth") == 'bezier' ): smooth = True else: smooth = False GFlist.append( Graphics.Line( coords, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), stipple=dc.itemcget(handle, "stipple"), arrow=dc.itemcget(handle, "arrow"),capstyle=dc.itemcget(handle, "capstyle"), joinstyle=dc.itemcget(handle, "joinstyle"),smooth=smooth,savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))) ) ) elif( objectType == 'polygon' ): if( dc.itemcget(handle, "smooth") == 'bezier' ): smooth = True else: smooth = False GFlist.append( Graphics.Polygon( coords, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), stipple=dc.itemcget(handle, "stipple"), smooth=smooth,outline=dc.itemcget(handle, "outline"),savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))) ) ) elif( objectType == 'oval' ): x0,y0,x1,y1 = coords GFlist.append( Graphics.Oval( x0,y0,x1,y1, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),outline=dc.itemcget(handle, "outline"), width=int(float(dc.itemcget(handle, "width" ))), savedNumber=objectNumber, stipple=dc.itemcget(handle, "stipple") ) ) elif( objectType == 'rectangle' ): x0,y0,x1,y1 = coords GFlist.append( Graphics.Rectangle( x0,y0,x1,y1, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"),outline=dc.itemcget(handle, "outline"), width=int(float(dc.itemcget(handle, "width" ))), savedNumber=objectNumber, stipple=dc.itemcget(handle, "stipple") ) ) elif( objectType == 'image' ): fileName = graphicalForm.getImageFilename() if( not Graphics.Image.IMAGE_DICT.has_key( fileName ) ): print "ERROR: could not load image " + fileName + "... SKIPPED" continue ''' pathName = '' for path in sys.path: if( not os.path.isdir( path ) ): continue if( pathName ): break for file in os.listdir( path ): if( file == fileName ): pathName = os.path.join( path, fileName ) break if( not fileName ): print "ERROR: could not load image " + fileName + "... SKIPPED" continue ''' GFlist.append( Graphics.Image( coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, savedNumber=objectNumber, filename=fileName ) ) else: print "WARNING: Attempted to load unsupported objectType: " + str( objectType) #print GFlist dc.destroy() return GFlist def openOLD(self): if( 0 ): return [] elif( 1 ): fileName = os.path.join( self.modelPath, 'graph_' + self.className + '.gf1' ) if( os.path.exists( fileName ) ): f = open( fileName, 'r' ) else: return [] try: gfList = pickle.load(f) except ImportError: print "Failed to load pickled graphic data" return [] # Get the scripting stuff out of the way... self.scripting = gfList[0] if( self.scripting.getRunTimeChange() ): self.menuBar.getModelMenu().entryconfigure( 0, label = "Changes at run-time ENABLED" ) else: self.menuBar.getModelMenu().entryconfigure( 0, label = "Changes at run-time DISABLED" ) for gf in gfList[1:]: gf.setCanvas(self.canvas) gf.setEventHandler(self.mainHandler) return gfList[1:] elif( 0 ): return [Graphics.Rectangle(50, 50, 90, 90, canvas=self.canvas, outline="black", fill="blue", width=2, eventHandler=self.mainHandler), Graphics.Oval(50, 50, 90, 90, canvas=self.canvas, outline="black", fill="green", eventHandler=self.mainHandler), Graphics.Text(70, 90, canvas=self.canvas, zoom=1.00, eventHandler=self.mainHandler, text="text", fill="red"), Graphics.Connector(100, 100, canvas=self.canvas, zoom=1.00, eventHandler=self.mainHandler), Graphics.Polygon([50, 50, 90, 90, 32, 2], canvas=self.canvas, outline="green", fill="purple", width=2, eventHandler=self.mainHandler), Graphics.Line([50, 10, 50, 50, 132, 50], canvas=self.canvas, fill="black", eventHandler=self.mainHandler), Graphics.Composite([Graphics.Rectangle(50, 20, 140, 100, canvas=self.canvas, outline="black", fill="yellow", width=2, eventHandler=self.mainHandler), Graphics.Rectangle(50, 50, 100, 120, canvas=self.canvas, outline="black", fill="purple", width=2, eventHandler=self.mainHandler), Graphics.Oval(70, 20, 40, 90, canvas=self.canvas, outline="black", fill="green", width=2, eventHandler=self.mainHandler), Graphics.Oval(50, 50, 40, 20, canvas=self.canvas, outline="black", fill="gray", width=2, eventHandler=self.mainHandler)], canvas=self.canvas, zoom=100, eventHandler=self.mainHandler)] def cut(self, gfList): if len(gfList) > 0: previousClipboard = self.clipboardList self.clipboardList = gfList indexList = [] for gf in gfList: gf.setCanvas(None) indexList.append(self.removeGF(gf)) pairList = map(None, gfList, indexList) self.undoStack.append((self.undo_cut, [previousClipboard, pairList])) def copy(self, gfList): if len(gfList) > 0: previousClipboard = self.clipboardList self.clipboardList = [] for gf in gfList: cgf = gf.copy() self.clipboardList.append(cgf) cgf.setCanvas(None) def paste(self): clipboardCopy = [] for gf in self.clipboardList: c = gf.copy() c.setZoom(self.getZoom()) clipboardCopy.append(c) for gf in clipboardCopy: gf.translate(10, 10) gf.setCanvas(self.canvas) self.appendGF(gf) self.undoStack.append((self.undo_paste, [clipboardCopy])) return clipboardCopy #The GFs in gfList are not necessarily in the order in which they are drawn. #Since we want the relative order of the selection to be preserved, we first bring #to top the GF which is drawn first. def bringToTop(self, gfList): allGFs = self.getGFs() pairList = [] for gf in allGFs: if gf in gfList: pairList.append((gf, self.bringToTopGF(gf))) if len(pairList) > 0: self.undoStack.append((self.undo_bringPush, [pairList])) #(see bringToTop) Here we need to reverse the list to push the GFs in the right order. def pushToBottom(self, gfList): allGFs = self.getGFs() allGFs.reverse() pairList = [] for gf in allGFs: if gf in gfList: pairList.append((gf, self.pushToBottomGF(gf))) if len(pairList) > 0: self.undoStack.append((self.undo_bringPush, [pairList])) def compose(self, gfList): if len(gfList) > 1: # create a composite only if it's worth it allGFs = self.getGFs() sortedList = [] for gf in allGFs: if gf in gfList: sortedList.append(gf) indexList = [] for gf in sortedList: indexList.append(self.removeGF(gf)) composite = Graphics.Composite(sortedList, canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.insertGF(indexList[len(indexList)-1], composite) self.undoStack.append((self.undo_compose, [composite, indexList])) return [composite] else: return gfList def decompose(self, gfList): compositeList = [] for gf in gfList: componentList = self.compositionVisitor.decompose(gf) if len(componentList) > 0: #if gf was decomposed compositeList.append(gf) #add the composite to the list of composites self.undoStack.append((self.undo_decompose, [compositeList])) def delete(self, gfList): indexList = [] for gf in gfList: gf.setCanvas(None) indexList.append(self.removeGF(gf)) pairList = map(None, gfList, indexList) self.undoStack.append((self.undo_delete, [pairList])) def getBoundingBox(self, gfList): boxes = [] for gf in gfList: if gf.getCanvas() != None: boxes.append(gf.getApproxBoundingBox()) if len(boxes) == 0: raise TypeError, "gfList contains no active GF" xMin = boxes[0][0] yMin = boxes[0][1] xMax = boxes[0][2] yMax = boxes[0][3] for box in boxes: if box[0] < xMin: xMin = box[0] if box[1] < yMin: yMin = box[1] if box[2] > xMax: xMax = box[2] if box[3] > yMax: yMax = box[3] return [xMin, yMin, xMax, yMax] def setFillColor(self, gfList, color): undoList = self.colorVisitor.setFillColor(gfList, color) if len(undoList) > 0: self.undoStack.append((self.undo_setFillColor, [undoList])) def setOutlineColor(self, gfList, color): undoList = self.colorVisitor.setOutlineColor(gfList, color) if len(undoList) > 0: self.undoStack.append((self.undo_setOutlineColor, [undoList])) def setLineWidth(self, gfList, lineWidth): undoList = self.widthVisitor.setWidth(gfList, lineWidth) if len(undoList) > 0: self.undoStack.append((self.undo_setLineWidth, [undoList])) def setOutlineFillOption(self, gfList, option): undoList = self.optionVisitor.changeOption(gfList, option) if len(undoList) > 0: self.undoStack.append((self.undo_setOutlineFillOption, [undoList])) def createRectangle(self, xy): gf = Graphics.Rectangle(xy[0], xy[1], xy[2], xy[3], canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createOval(self, xy): gf = Graphics.Oval(xy[0], xy[1], xy[2], xy[3], canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createLine(self, xy, smooth=0): gf = Graphics.Line(xy, canvas=self.canvas, fill=self.getFillColor(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler, smooth = smooth) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createPolygon(self, xy, smooth=0): gf = Graphics.Polygon(xy, canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler, smooth = smooth) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createConnector(self, xy): gf = Graphics.Connector(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createImage(self, xy, filename): gf = Graphics.Image(xy[0], xy[1], filename, canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createText(self, xy, text): gf = Graphics.Text(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler, text=text, fill=self.getFillColor()) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createNamedConnector(self, xy): gf = Graphics.NamedConnector(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createAttribute(self, xy, text ): gf = Graphics.Attribute(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler, text=text ) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def isUndoStackEmpty(self): if len(self.undoStack) == 0: return 1 else: return 0 def isClipboardEmpty(self): if len(self.clipboardList) == 0: return 1 else: return 0 def translate(self, gfList, dx, dy): for gf in gfList: gf.translate(dx, dy) self.undoStack.append((self.undo_translate, [gfList, -dx,-dy])) def rotate(self, gfList, centerX, centerY, angle): for gf in gfList: gf.rotate(centerX, centerY, angle) self.undoStack.append((self.undo_rotate, [gfList, centerX, centerY, -angle])) def scale(self, gfList, centerX, centerY, factorX, factorY): for gf in gfList: gf.scale(centerX, centerY, factorX, factorY) self.undoStack.append((self.undo_scale, [gfList, centerX, centerY, 1/factorX, 1/factorY])) # the following method is used by the translation handler to add an undo command. # Instead of creating an undo for each small translation (by using the normal translate method of the editor), # the handler calls the "add undo translation" method of the editor when the translation is complete. def addUndoTranslate(self, gfList, dx, dy): if( not (dx == 0 and dy == 0) ): self.undoStack.append((self.undo_translate, [gfList, -dx,-dy])) # see addUndoTranslate def addUndoRotate(self, gfList, centerX, centerY, angle): self.undoStack.append((self.undo_rotate, [gfList, centerX, centerY, -angle])) # see addUndoTranslate def addUndoScale(self, gfList, centerX, centerY, factorX, factorY): self.undoStack.append((self.undo_scale, [gfList, centerX, centerY, 1/factorX, 1/factorY])) def addUndoSetCoords(self, gf, oldCoords): self.undoStack.append((self.undo_setCoords, [gf, oldCoords])) def undo(self): method, args = self.undoStack.pop() apply(method, args) ####################### # undo commands def undo_create(self, gfList): for gf in gfList: gf.setCanvas(None) self.removeGF(gf) def undo_delete(self, pairList): # pairList is a list of pairs, where each # pair contains an inactive GF and its position in the canvas. # pairList must be reversed because the index is valid # for the editor's list after the other gfs are deleted. pairList.reverse() for gf, index in pairList: gf.setCanvas(self.canvas) self.insertGF(index, gf) def undo_cut(self, previousClipboard, pairList): # pairList is a list of pairs, where each # pair contains an inactive GF and its position in the canvas. # pairList must be reversed because the index is valid # for the editor's list after the other gfs are deleted. pairList.reverse() for gf, index in pairList: gf.setCanvas(self.canvas) self.insertGF(index, gf) self.clipboardList = previousClipboard def undo_copy(self, previousClipboard): self.clipboardList = previousClipboard def undo_paste(self, pastedList): for gf in pastedList: gf.setCanvas(None) self.removeGF(gf) def undo_bringPush(self, pairList): pairList.reverse() for gf, index in pairList: self.removeGF(gf) self.insertGF(index, gf) def undo_compose(self, compositeGF, indexList): gfList = compositeGF.getComponents() self.removeGF(compositeGF) pairList = map(None, gfList, indexList) pairList.reverse() for gf, index in pairList: gf.setEventHandler(self.mainHandler) self.insertGF(index, gf) def undo_decompose(self, compositeList): for composite in compositeList: gfList = composite.getComponents() for gf in gfList: index = self.removeGF(gf) gf.setEventHandler(composite) self.insertGF(index, composite) def undo_translate(self, gfList, dx, dy): for gf in gfList: gf.translate(dx, dy) def undo_rotate(self, gfList, centerX, centerY, angle): for gf in gfList: gf.rotate(centerX, centerY, angle) def undo_scale(self, gfList, centerX, centerY, factorX, factorY): for gf in gfList: gf.scale(centerX, centerY, factorX, factorY) def undo_setCoords(self, gf, oldCoords): gf.setCoords(oldCoords) def undo_setFillColor(self, undoList): for gf, color in undoList: gf.setFillColor(color) def undo_setOutlineColor(self, undoList): for gf, color in undoList: gf.setOutlineColor(color) def undo_setLineWidth(self, undoList): for gf, width in undoList: gf.setWidth(width) def undo_setOutlineFillOption(self, undoList): for gf, (outlineOption, fillOption) in undoList: gf.setOutlineOption(outlineOption) gf.setFillOption(fillOption) ###################### def appendGF(self, gf): self.GFs.append(gf) def insertGF(self, index, gf): self.GFs.insert(index, gf) for gf in self.GFs: gf.bringToTop() def getIndex(self, gf): return self.GFs.index(gf) def removeGF(self, gf): index = self.GFs.index(gf) self.GFs.remove(gf) return index #return the index the gf had in the list (which was also its relative position on the canvas) # convention: the first gfs in the list are drawn first. # The order in which the GFs are drawn is useful when we want to save. def bringToTopGF(self, gf): gf.bringToTop() index = self.removeGF(gf) self.GFs.append(gf) return index def pushToBottomGF(self, gf): gf.pushToBottom() index = self.removeGF(gf) self.GFs.insert(0, gf) return index def getGFs(self): return self.GFs[:] def setGFs(self, gfList ): self.GFs = gfList def getEventHandler(self): return self.mainHandler def getCanvasWidth(self): return self.workspace.getCanvasWidth() def getCanvasHeight(self): return self.workspace.getCanvasHeight() def getCanvas(self): return self.workspace.getCanvas() def getZoom(self): return self.workspace.getZoom() def setZoom(self, zoom, x, y): self.workspace.setZoom(zoom, x, y) # update statusBar and GFs to the new zoom (whether it changed or not) newZoom = self.workspace.getZoom() self.statusBar.setZoom(newZoom) for gf in self.GFs: gf.setZoom(newZoom) def setToolSelector(self, tool): self.toolSelector.set(tool) def getLineWidth(self): return self.lineWidthSelector.get() def getOutlineColor(self): return self.colorSelector.getOutlineColor() def getFillColor(self): return self.colorSelector.getFillColor() def hasOutline(self): option = self.outlineFillOptionSelector.get() return option[0] def hasFill(self): option = self.outlineFillOptionSelector.get() return option[1]
def main(): name = os.path.basename(os.getcwd()) # Parse arguments parser = argparse.ArgumentParser( prog='Pygling', description='Pygling C++ workspace generator.', prefix_chars='--', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("action", type=str, help="Action", choices=["configure", "build", "install"]) parser.add_argument("-p", "--platform", default='all', type=str, help="Target platform") parser.add_argument("-s", "--source", default='.', type=str, help="Project source path") parser.add_argument("-o", "--output", default='projects', type=str, help="Output path") parser.add_argument("-n", "--name", default=name, type=str, help="Workspace (solution) name") parser.add_argument("-a", "--arch", default='default', type=str, help="Target build architecture") parser.add_argument("-x", "--std", default='cxx98', type=str, help="C++ standard", choices=['cxx99', 'cxx11']) parser.add_argument("-c", "--configuration", default='Release', type=str, help="Build configuration") parser.add_argument("--package", type=str, help="Application package identifier") parser.add_argument("--platformSdk", type=str, help="Platform SDK identifier") parser.add_argument("--xcteam", type=str, help="Xcode provisioning profile to be used") # Check action args, unknown = parser.parse_known_args() workspace = Workspace(args.name, args.source, args.output, args, unknown) if args.action == 'configure': workspace.configure(args.platform) elif args.action == 'build': workspace.build(args.platform) elif args.action == 'install': workspace.install(args.platform)
# test_prm.prm(10, start, goal, False) # #test_arm.generate_graphic() # #3 arm segments # start = (0, 0, 0) # goal = (3*math.pi/2, 3*math.pi/2, 0) # lengths = [2, 5, 2] # obstacles = [[0, 4, 1, 6], [4, 4, 2, 2]] # test_arm = Workspace(start, lengths, obstacles) # #test_arm.generate_graphic() # test_prm = PRM(test_arm) # #test_prm.print_prm() # test_prm.prm(40, start, goal, True) # #test_arm.generate_graphic() # #4 arm segments start = (0, 0, 0, 0) goal = (3 * math.pi / 2, 3 * math.pi / 2, 0, math.pi / 2) lengths = [2, 2, 2, 2] obstacles = [[-2, -1, 1, 6], [4, 4, 2, 2]] test_arm = Workspace(start, lengths, obstacles) #test_arm.generate_graphic() test_prm = PRM(test_arm) #test_prm.print_prm() test_prm.prm(40, start, goal, True) #test_arm.generate_graphic()
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from VirtualDisplay import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_tabletop = Workspace("VR-Lab-Tabletop", avango.gua.make_trans_mat(0.0, 0.043, 0.0)) video_visibility_table = {"table": {"portal": False}, "portal": {"table": False}} # vr_lab_rear.associate_video_3D("/opt/kinect-resources/kinect_surface_K_23_24_25.ks" # , avango.gua.make_trans_mat(0.0, 0.043, 1.6) # , video_visibility_table) workspaces = [vr_lab_tabletop] ## Create Navigation instances ## trace_visibility_list_table_nav = {"table": False, "portal": False} spacemouse_navigation = SteeringNavigation() spacemouse_navigation.my_constructor( STARTING_MATRIX=avango.gua.make_trans_mat(0.0, 0.0, 0.0),
def open(self, frame, page, buffer): Workspace.open(self, frame, page, buffer) frame.link(buffer.notify_changed, self, 'data') frame.link(buffer.handle_resize, self, 'resize')
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from Portal import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) workspaces = [vr_lab_rear] ## Create Navigation instances ## trace_visibility_list_dlp_wall_nav = { "dlp_wall": False, "table": True, "portal": False } trace_visibility_list_table_nav = { "dlp_wall": False, "table": False, "portal": False }
def add_workspace(self, name=""): self.workspace = Workspace(name) # create empty workspace return self.workspace
from SignalRegistry import get_registry from Workspace import Workspace from output import play_signal from util.frames import to_frames logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) fs = 44100 registry = get_registry() graph = SignalGraph() manager = SignalManager(SignalCache) workspace = Workspace("resources/signals.json", manager, graph, registry) workspace.initialize() signals = manager.signals restored_signal = manager.get_signal('dilated:2') dilated_signal = manager.get_signal('dilated:0.5') offset_signal = manager.get_signal('offset:2') base_signal = manager.get_signal('wav') var_offset_signal = manager.get_signal('var_offset') sine_signal = manager.get_signal('sine') selected_signal = var_offset_signal dur = to_frames(offset_signal.get_range(fs)[1])
from Workspace import Workspace from Project import Project w1 = Workspace() class ProjectManager(): def guiInfo(self, workspace_name, path, project_name, desc, layout, getter): project = Project() if (workspace_name != None): if (path != None): w1.setPath(path) w1.setName(workspace_name) Workspace.current = w1 else: print("Invalid1") return elif (project_name != None): if (desc != None): project.setName(project_name) project.setDesc(desc) project.createProject() Project.current = project else: project.loadProject(project_name) return #elif(layout != None): # Project.getLayout() else: if (getter == 0):
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from Portal import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) vr_lab_front = Workspace('VR-Lab-Front', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) video_visibility_table = { "dlp_wall": { "lcd_wall": True, "portal": False }, "lcd_wall": { "dlp_wall": True, "portal": False }, "portal": { "dlp_wall": True, "lcd_wall": True
class Editor: # Canvas size is used by the snap grid to determine how far to draw the grid # Actually, should be called the canvas bounding box :p # BTW: Using negative values, or values that are too small, doesn't work well :p CANVAS_SIZE_TUPLE = [0, 0, 2000, 2000] def __init__(self, semObject, className, modelPath=None): # Use the AToM3 Tkinter root window self.className = className root = self.rootInitilization(semObject, modelPath) if (not root): return self.root = root self.mainHandler = MainHandler.MainHandler(self) root.bind("<Key>", self.mainHandler.onKey) root.bind("<Shift-Key>", self.mainHandler.onShiftKey) root.bind("<Control-Key>", self.mainHandler.onControlKey) zoom = 1.0 self.menuBar = Tools.MenuBar(root, self, self.mainHandler) #goes to top by itself self.statusBar = Tools.StatusBar(root, "", zoom, 0, 0) #goes to bottom by itself self.colorSelector = Colors.ColorSelector( root, self.mainHandler) #goes to bottom by itself self.toolFrame = Tkinter.Frame(root, relief=Tkinter.RAISED, bd=1) self.toolSelector = Tools.ToolSelector(self.toolFrame, self.mainHandler, Tkinter.TOP) self.outlineFillOptionSelector = Tools.OutlineFillOptionSelector( self.toolFrame, self.mainHandler, Tkinter.TOP) self.lineWidthSelector = Tools.LineWidthSelector( self.toolFrame, self.mainHandler, Tkinter.TOP) self.toolFrame.pack(side=Tkinter.LEFT) self.workspace = Workspace(self, self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.CANVAS_SIZE_TUPLE[2], self.CANVAS_SIZE_TUPLE[3], self.mainHandler, zoom) #goes to the right by itself self.workspace.setZoom(zoom, 0, 0) self.canvas = self.workspace.getCanvas() self.scripting = Scripting() ## self.GFs = self.open() self.GFs = [] self.extendedInitilization(semObject) self.clipboardList = [] self.undoStack = [] self.mainHandler.start() self.compositionVisitor = GFVisitors.CompositionVisitor(self) self.colorVisitor = GFVisitors.ColorVisitor() self.widthVisitor = GFVisitors.WidthVisitor() self.optionVisitor = GFVisitors.OptionVisitor(self) # Carefully try to load the GF model (may fail for random reasons) try: self.GFs = self.open() except: raise def rootInitilization(self, semObject, modelPathAndFile): """ Extension to the old initilization routine This directly sets up the editor for generating icons for AToM3 """ # Do we have everything we need? Check the minimum requirements: try: atom3i = semObject.parent TkRoot = atom3i.parent statusbar = atom3i.statusbar except: print "ERROR: Unable to start editor, lacking information (atom3i,TkRoot, or statusbar)" return None self.atom3i = atom3i # Do we have the fileName we'll be using to save the graphicalAppearence? if (not modelPathAndFile): modelPathAndFile = statusbar.getState(statusbar.MODEL)[1][0] self.modelPath = os.path.split(modelPathAndFile)[0] if (self.modelPath == ''): tkMessageBox.showerror( "Icon-Editor model path error", "Please save your ER model before modifying graphical appearences.", parent=TkRoot) return None # Setup a new toplevel window for the editor root = Tkinter.Toplevel(TkRoot) root.title("Icon Editor - AToM3") root.geometry("%dx%d%+d%+d" % (800, 600, 100, 0)) root.transient(TkRoot) root.grab_set() return root def extendedInitilization(self, semObject): # SnapGrid: since this is a singleton, must first disable old stuff self.snapGridInfoTuple = None self.snapGridInfoBackup = None SnapGrid.applyLayout(self, disableForPrinting=True) SnapGrid.applyLayout(self) # Useful binds self.root.bind("<Alt-x>", lambda event: self.mainHandler.onExit()) self.root.bind("<F1>", lambda event: self.mainHandler.onSnapSetting()) self.root.bind("<Control-e>", lambda event: self.mainHandler.onExport()) self.root.protocol("WM_DELETE_WINDOW", self.mainHandler.onExit) # AToM3 graphical appearence exporter self.exportVisitor = SaveGFVisitor.ATOM3_Export_Visitor( semObject, self) # Extra info: includes text attributes that change dynamically & named ports self.attributes = semObject.attributesToDraw() # Icon Positioning System (not quite GPS) self.iconPositioner = IconPositioner(self) self.root.bind("<F2>", lambda event: self.iconPositioner.createDialog()) def iconPlacer(self, anchor='nw'): """ Places the graphical icon at a position determined by 'anchor' If anchor is 'nw', then the icon will be moved so that when the user creates an item with this icon, the top-left edge of the icon appears at the position the user clicked. If anchor is 'origin', then the icon appears exactly centered on origin. If anchor is of type 'float', then use the float value directly. """ x0, y0, x1, y1 = self.getBoundingBox(self.getGFs()) # Top-Left positioning if (anchor == 'nw'): dx = -x0 dy = -y0 # Center positioning elif (anchor == 'origin'): dx = -x0 - (x1 - x0) / 2 dy = -y0 - (y1 - y0) / 2 # Manual offset elif (type(anchor) == type(float())): dx = dy = anchor # Invalid use else: raise Exception, "Wake up and smell the API you lopsided kitten burger! j/k" for gf in self.getGFs(): gf.translate(dx, dy) self.addUndoTranslate(self.getGFs(), dx, dy) def getAttributes(self): return self.attributes def exit(self, event=None): """ Exit point for the Icon-Editor """ # Clean up the snap grid SnapGrid.applyLayout(self, disableForPrinting=True) # Did AToM3 want its snap grid back? :D self.atom3i.toggleSnapGrid() # Make this window go boom self.root.destroy() def getRoot(self): """get a reference to the root window of the editor""" return self.root def save(self, event=None): """ 1) Exports a graphical appearence file readable by AToM3 2) Saves everything in a pickled file (not cross-platform compatible) """ # Make sure that Text is at the end of the list gfListSorted = SaveGFVisitor.TextSortVisitor().sortGraphicalForms( self.getGFs()) # Uber-cool save dialog :D if (1): text = 'The following AToM3 file will be generated:\n\n'+\ os.path.normpath( os.path.join( self.modelPath, 'graph_' + self.className + '.py' ) ) +\ '\n\nIf you have not already done so, you should position the icon '+\ 'so that it appears where you expect it to in your models.' saveDialog = Dialog.Dialog( None, { 'title': 'Saving graphical appearence file...', 'text': text, 'bitmap': '', 'default': 0, 'strings': ('Position icon', 'Save', 'Save & Exit', 'Cancel') }) # Position icon if (saveDialog.num == 0): self.iconPositioner.createDialog() return self.save() # Save if (saveDialog.num == 1): self.exportVisitor.AToM3_export(gfListSorted) return self.root.focus_force() # Save & Exit if (saveDialog.num == 2): self.exportVisitor.AToM3_export(gfListSorted) return self.exit() # Cancel elif (saveDialog.num == 3): return self.root.focus_force() # Lousy Dialog save, m'kay elif (0): self.exportVisitor.AToM3_export(gfListSorted) tkMessageBox.showinfo( "Saving Graphical Appearence", "The following AToM3 file has been generated:\n\n" + os.path.normpath( os.path.join(self.modelPath, 'graph_' + self.className + '.py')), parent=self.root) # Pickle save.... EWWWWWWWWWWWWW! elif (0): gfList = self.getGFs() gfListCopy = [] for gf in gfList: gfListCopy.append(gf.copy()) for gf in gfListCopy: gf.setEventHandler(None) gf.setCanvas(None) gf.setZoom(1.0) # Store extra scripting info gfListCopy = [self.scripting] + gfListCopy fileName = os.path.normpath( os.path.join(self.modelPath, 'graph_' + self.className + '.gf1')) file = open(fileName, "w") pickle.dump(gfListCopy, file) file.close() tkMessageBox.showinfo( "Saving Graphical Appearence", "The following icon-editor file has been generated:\n\n" + fileName, parent=self.root) def export(self): filename = tkFileDialog.asksaveasfilename(title="Export", filetypes=[("Postscript", "*.ps")]) if filename != "": self.canvas.postscript(file=filename) def debug(self): """ Many things can go wrong when openning a graphical file this gives the user more flexibility in figuring out wtf went wrong """ print "Error occured in importer", __file__ from tkMessageBox import askokcancel res = askokcancel("Import Error", "The existing graphical file could not be imported\n" \ "Press Ok to proceed normally, Cancel to dump error to console") # Raise the 'caught' error if (res == False): raise def open(self): """ Tries to open an existing graphical form in the AToM3 format and to reproduce it on canvas """ fileName = os.path.normpath( os.path.join(self.modelPath, 'graph_' + self.className + '.py')) if (not os.path.exists(fileName)): return [] nameClass = "graph_" + self.className dc = Tkinter.Canvas(self.root) # File is already loaded if nameClass in sys.modules.keys(): del sys.modules[nameClass] # Make sure we can reach the path and import from it sys.path.append(self.modelPath) # Load it in memory try: exec "import graph_" + self.className + "\n" sys.path = sys.path[:-1] except SyntaxError: # class Name not valid sys.path = sys.path[:-1] print "Syntax Error, Could not open graphical file", self.className self.debug() return [] except IOError: # could not open file (?) sys.path = sys.path[:-1] print "IO Error, Could not open graphical file", self.className self.debug() return [] except ImportError: # could not open file... print "Import Error, Could not open graphical file", self.className self.debug() sys.path = sys.path[:-1] return [] try: # obtain the class object className = eval('graph_' + self.className + '.graph_' + self.className) except: print 'WARNING:', 'graph_'+self.className+'.graph_'+self.className, \ 'not found' return [] new_obj = className(0, 0) # create an instance of the new class new_obj.DrawObject(dc) # draw the object # Get the constraints constraintList = [] for constraint in new_obj.constraintList: constraintList.append(constraint.getValue()) self.scripting.setConstraintList(constraintList) self.scripting.setRunTimeChange(new_obj.ChangesAtRunTime) GFlist = [] # List with the handles of all the shapes drawn handleList = [] for handle in dc.find_withtag(new_obj.tag): if (not handle in handleList): handleList.append(handle) # Get the connectors in self.connectors for handle in new_obj.connectors: x0, y0, x1, y1 = dc.coords(handle) if (new_obj.namedConnectors.has_key(handle)): name = new_obj.namedConnectors[handle] gf = Graphics.NamedConnector(x0, y0, canvas=self.canvas, eventHandler=self.mainHandler, name=name) else: gf = Graphics.Connector(x0, y0, canvas=self.canvas, eventHandler=self.mainHandler) GFlist.append(gf) # Get the drawn semantic attributes... handleAttributeDict = dict() for attribute in new_obj.attr_display.keys(): handleAttributeDict[new_obj.attr_display[attribute]] = attribute # Get the image dict, if any if (hasattr(new_obj, 'imageDict')): Graphics.Image.IMAGE_DICT = new_obj.imageDict # Get the GraphicalForm objects objectNumberPattern = re.compile('\Agf(\d*)\Z') for graphicalForm in new_obj.graphForms: handle = graphicalForm.getHandler() objectNumber = int( objectNumberPattern.search(graphicalForm.getName()).group(1)) coords = dc.coords(handle) objectType = dc.type(handle) # Attribute --- Special Text if (handleAttributeDict.has_key(handle)): attribute = handleAttributeDict[handle] fontObject = graphicalForm.getFont() if (fontObject): if (fontObject.cget('weight') == 'bold'): bold = True else: bold = False if (fontObject.cget('slant') == 'bold'): italic = True else: italic = False GFlist.append( Graphics.Attribute( coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), text=attribute, anchor=dc.itemcget(handle, "anchor"), family=fontObject.cget('family'), size=int(float(fontObject.cget('size'))), bold=bold, savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))), italic=italic, underline=int(float( fontObject.cget('underline'))))) # Backward compatibility with graphical appearences that don't have # a font object. NOTE: Font type & size info is neccessarily lost. else: GFlist.append( Graphics.Attribute( coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), text=attribute, width=int(float(dc.itemcget(handle, "width"))), anchor=dc.itemcget(handle, "anchor"), savedNumber=objectNumber)) elif (objectType == 'text'): fontObject = graphicalForm.getFont() if (fontObject): if (fontObject.cget('weight') == 'bold'): bold = True else: bold = False if (fontObject.cget('slant') == 'bold'): italic = True else: italic = False GFlist.append( Graphics.Text( coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), text=dc.itemcget(handle, "text"), anchor=dc.itemcget(handle, "anchor"), family=fontObject.cget('family'), size=int(float(fontObject.cget('size'))), bold=bold, savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))), italic=italic, underline=int(float( fontObject.cget('underline'))))) # Backward compatibility with graphical appearences that don't have # a font object. NOTE: Font type & size info is neccessarily lost. else: GFlist.append( Graphics.Text(coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), text=dc.itemcget(handle, "text"), width=int( float(dc.itemcget(handle, "width"))), anchor=dc.itemcget(handle, "anchor"), savedNumber=objectNumber)) elif (objectType == 'line'): if (dc.itemcget(handle, "smooth") == 'bezier'): smooth = True else: smooth = False GFlist.append( Graphics.Line(coords, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), stipple=dc.itemcget(handle, "stipple"), arrow=dc.itemcget(handle, "arrow"), capstyle=dc.itemcget(handle, "capstyle"), joinstyle=dc.itemcget(handle, "joinstyle"), smooth=smooth, savedNumber=objectNumber, width=int(float(dc.itemcget(handle, "width"))))) elif (objectType == 'polygon'): if (dc.itemcget(handle, "smooth") == 'bezier'): smooth = True else: smooth = False GFlist.append( Graphics.Polygon(coords, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), stipple=dc.itemcget(handle, "stipple"), smooth=smooth, outline=dc.itemcget(handle, "outline"), savedNumber=objectNumber, width=int( float(dc.itemcget(handle, "width"))))) elif (objectType == 'oval'): x0, y0, x1, y1 = coords GFlist.append( Graphics.Oval(x0, y0, x1, y1, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), outline=dc.itemcget(handle, "outline"), width=int(float(dc.itemcget(handle, "width"))), savedNumber=objectNumber, stipple=dc.itemcget(handle, "stipple"))) elif (objectType == 'rectangle'): x0, y0, x1, y1 = coords GFlist.append( Graphics.Rectangle(x0, y0, x1, y1, canvas=self.canvas, eventHandler=self.mainHandler, fill=dc.itemcget(handle, "fill"), outline=dc.itemcget(handle, "outline"), width=int( float(dc.itemcget(handle, "width"))), savedNumber=objectNumber, stipple=dc.itemcget(handle, "stipple"))) elif (objectType == 'image'): fileName = graphicalForm.getImageFilename() if (not Graphics.Image.IMAGE_DICT.has_key(fileName)): print "ERROR: could not load image " + fileName + "... SKIPPED" continue ''' pathName = '' for path in sys.path: if( not os.path.isdir( path ) ): continue if( pathName ): break for file in os.listdir( path ): if( file == fileName ): pathName = os.path.join( path, fileName ) break if( not fileName ): print "ERROR: could not load image " + fileName + "... SKIPPED" continue ''' GFlist.append( Graphics.Image(coords[0], coords[1], canvas=self.canvas, eventHandler=self.mainHandler, savedNumber=objectNumber, filename=fileName)) else: print "WARNING: Attempted to load unsupported objectType: " + str( objectType) #print GFlist dc.destroy() return GFlist def openOLD(self): if (0): return [] elif (1): fileName = os.path.join(self.modelPath, 'graph_' + self.className + '.gf1') if (os.path.exists(fileName)): f = open(fileName, 'r') else: return [] try: gfList = pickle.load(f) except ImportError: print "Failed to load pickled graphic data" return [] # Get the scripting stuff out of the way... self.scripting = gfList[0] if (self.scripting.getRunTimeChange()): self.menuBar.getModelMenu().entryconfigure( 0, label="Changes at run-time ENABLED") else: self.menuBar.getModelMenu().entryconfigure( 0, label="Changes at run-time DISABLED") for gf in gfList[1:]: gf.setCanvas(self.canvas) gf.setEventHandler(self.mainHandler) return gfList[1:] elif (0): return [ Graphics.Rectangle(50, 50, 90, 90, canvas=self.canvas, outline="black", fill="blue", width=2, eventHandler=self.mainHandler), Graphics.Oval(50, 50, 90, 90, canvas=self.canvas, outline="black", fill="green", eventHandler=self.mainHandler), Graphics.Text(70, 90, canvas=self.canvas, zoom=1.00, eventHandler=self.mainHandler, text="text", fill="red"), Graphics.Connector(100, 100, canvas=self.canvas, zoom=1.00, eventHandler=self.mainHandler), Graphics.Polygon([50, 50, 90, 90, 32, 2], canvas=self.canvas, outline="green", fill="purple", width=2, eventHandler=self.mainHandler), Graphics.Line([50, 10, 50, 50, 132, 50], canvas=self.canvas, fill="black", eventHandler=self.mainHandler), Graphics.Composite([ Graphics.Rectangle(50, 20, 140, 100, canvas=self.canvas, outline="black", fill="yellow", width=2, eventHandler=self.mainHandler), Graphics.Rectangle(50, 50, 100, 120, canvas=self.canvas, outline="black", fill="purple", width=2, eventHandler=self.mainHandler), Graphics.Oval(70, 20, 40, 90, canvas=self.canvas, outline="black", fill="green", width=2, eventHandler=self.mainHandler), Graphics.Oval(50, 50, 40, 20, canvas=self.canvas, outline="black", fill="gray", width=2, eventHandler=self.mainHandler) ], canvas=self.canvas, zoom=100, eventHandler=self.mainHandler) ] def cut(self, gfList): if len(gfList) > 0: previousClipboard = self.clipboardList self.clipboardList = gfList indexList = [] for gf in gfList: gf.setCanvas(None) indexList.append(self.removeGF(gf)) pairList = map(None, gfList, indexList) self.undoStack.append( (self.undo_cut, [previousClipboard, pairList])) def copy(self, gfList): if len(gfList) > 0: previousClipboard = self.clipboardList self.clipboardList = [] for gf in gfList: cgf = gf.copy() self.clipboardList.append(cgf) cgf.setCanvas(None) def paste(self): clipboardCopy = [] for gf in self.clipboardList: c = gf.copy() c.setZoom(self.getZoom()) clipboardCopy.append(c) for gf in clipboardCopy: gf.translate(10, 10) gf.setCanvas(self.canvas) self.appendGF(gf) self.undoStack.append((self.undo_paste, [clipboardCopy])) return clipboardCopy #The GFs in gfList are not necessarily in the order in which they are drawn. #Since we want the relative order of the selection to be preserved, we first bring #to top the GF which is drawn first. def bringToTop(self, gfList): allGFs = self.getGFs() pairList = [] for gf in allGFs: if gf in gfList: pairList.append((gf, self.bringToTopGF(gf))) if len(pairList) > 0: self.undoStack.append((self.undo_bringPush, [pairList])) #(see bringToTop) Here we need to reverse the list to push the GFs in the right order. def pushToBottom(self, gfList): allGFs = self.getGFs() allGFs.reverse() pairList = [] for gf in allGFs: if gf in gfList: pairList.append((gf, self.pushToBottomGF(gf))) if len(pairList) > 0: self.undoStack.append((self.undo_bringPush, [pairList])) def compose(self, gfList): if len(gfList) > 1: # create a composite only if it's worth it allGFs = self.getGFs() sortedList = [] for gf in allGFs: if gf in gfList: sortedList.append(gf) indexList = [] for gf in sortedList: indexList.append(self.removeGF(gf)) composite = Graphics.Composite(sortedList, canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.insertGF(indexList[len(indexList) - 1], composite) self.undoStack.append((self.undo_compose, [composite, indexList])) return [composite] else: return gfList def decompose(self, gfList): compositeList = [] for gf in gfList: componentList = self.compositionVisitor.decompose(gf) if len(componentList) > 0: #if gf was decomposed compositeList.append( gf) #add the composite to the list of composites self.undoStack.append((self.undo_decompose, [compositeList])) def delete(self, gfList): indexList = [] for gf in gfList: gf.setCanvas(None) indexList.append(self.removeGF(gf)) pairList = map(None, gfList, indexList) self.undoStack.append((self.undo_delete, [pairList])) def getBoundingBox(self, gfList): boxes = [] for gf in gfList: if gf.getCanvas() != None: boxes.append(gf.getApproxBoundingBox()) if len(boxes) == 0: raise TypeError, "gfList contains no active GF" xMin = boxes[0][0] yMin = boxes[0][1] xMax = boxes[0][2] yMax = boxes[0][3] for box in boxes: if box[0] < xMin: xMin = box[0] if box[1] < yMin: yMin = box[1] if box[2] > xMax: xMax = box[2] if box[3] > yMax: yMax = box[3] return [xMin, yMin, xMax, yMax] def setFillColor(self, gfList, color): undoList = self.colorVisitor.setFillColor(gfList, color) if len(undoList) > 0: self.undoStack.append((self.undo_setFillColor, [undoList])) def setOutlineColor(self, gfList, color): undoList = self.colorVisitor.setOutlineColor(gfList, color) if len(undoList) > 0: self.undoStack.append((self.undo_setOutlineColor, [undoList])) def setLineWidth(self, gfList, lineWidth): undoList = self.widthVisitor.setWidth(gfList, lineWidth) if len(undoList) > 0: self.undoStack.append((self.undo_setLineWidth, [undoList])) def setOutlineFillOption(self, gfList, option): undoList = self.optionVisitor.changeOption(gfList, option) if len(undoList) > 0: self.undoStack.append((self.undo_setOutlineFillOption, [undoList])) def createRectangle(self, xy): gf = Graphics.Rectangle(xy[0], xy[1], xy[2], xy[3], canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createOval(self, xy): gf = Graphics.Oval(xy[0], xy[1], xy[2], xy[3], canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createLine(self, xy, smooth=0): gf = Graphics.Line(xy, canvas=self.canvas, fill=self.getFillColor(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler, smooth=smooth) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createPolygon(self, xy, smooth=0): gf = Graphics.Polygon(xy, canvas=self.canvas, outline=self.getOutlineColor(), outlineOption=self.hasOutline(), fill=self.getFillColor(), fillOption=self.hasFill(), width=self.getLineWidth(), zoom=self.getZoom(), eventHandler=self.mainHandler, smooth=smooth) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createConnector(self, xy): gf = Graphics.Connector(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createImage(self, xy, filename): gf = Graphics.Image(xy[0], xy[1], filename, canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createText(self, xy, text): gf = Graphics.Text(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler, text=text, fill=self.getFillColor()) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createNamedConnector(self, xy): gf = Graphics.NamedConnector(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def createAttribute(self, xy, text): gf = Graphics.Attribute(xy[0], xy[1], canvas=self.canvas, zoom=self.getZoom(), eventHandler=self.mainHandler, text=text) self.appendGF(gf) self.undoStack.append((self.undo_create, [[gf]])) return gf def isUndoStackEmpty(self): if len(self.undoStack) == 0: return 1 else: return 0 def isClipboardEmpty(self): if len(self.clipboardList) == 0: return 1 else: return 0 def translate(self, gfList, dx, dy): for gf in gfList: gf.translate(dx, dy) self.undoStack.append((self.undo_translate, [gfList, -dx, -dy])) def rotate(self, gfList, centerX, centerY, angle): for gf in gfList: gf.rotate(centerX, centerY, angle) self.undoStack.append( (self.undo_rotate, [gfList, centerX, centerY, -angle])) def scale(self, gfList, centerX, centerY, factorX, factorY): for gf in gfList: gf.scale(centerX, centerY, factorX, factorY) self.undoStack.append( (self.undo_scale, [gfList, centerX, centerY, 1 / factorX, 1 / factorY])) # the following method is used by the translation handler to add an undo command. # Instead of creating an undo for each small translation (by using the normal translate method of the editor), # the handler calls the "add undo translation" method of the editor when the translation is complete. def addUndoTranslate(self, gfList, dx, dy): if (not (dx == 0 and dy == 0)): self.undoStack.append((self.undo_translate, [gfList, -dx, -dy])) # see addUndoTranslate def addUndoRotate(self, gfList, centerX, centerY, angle): self.undoStack.append( (self.undo_rotate, [gfList, centerX, centerY, -angle])) # see addUndoTranslate def addUndoScale(self, gfList, centerX, centerY, factorX, factorY): self.undoStack.append( (self.undo_scale, [gfList, centerX, centerY, 1 / factorX, 1 / factorY])) def addUndoSetCoords(self, gf, oldCoords): self.undoStack.append((self.undo_setCoords, [gf, oldCoords])) def undo(self): method, args = self.undoStack.pop() apply(method, args) ####################### # undo commands def undo_create(self, gfList): for gf in gfList: gf.setCanvas(None) self.removeGF(gf) def undo_delete(self, pairList): # pairList is a list of pairs, where each # pair contains an inactive GF and its position in the canvas. # pairList must be reversed because the index is valid # for the editor's list after the other gfs are deleted. pairList.reverse() for gf, index in pairList: gf.setCanvas(self.canvas) self.insertGF(index, gf) def undo_cut(self, previousClipboard, pairList): # pairList is a list of pairs, where each # pair contains an inactive GF and its position in the canvas. # pairList must be reversed because the index is valid # for the editor's list after the other gfs are deleted. pairList.reverse() for gf, index in pairList: gf.setCanvas(self.canvas) self.insertGF(index, gf) self.clipboardList = previousClipboard def undo_copy(self, previousClipboard): self.clipboardList = previousClipboard def undo_paste(self, pastedList): for gf in pastedList: gf.setCanvas(None) self.removeGF(gf) def undo_bringPush(self, pairList): pairList.reverse() for gf, index in pairList: self.removeGF(gf) self.insertGF(index, gf) def undo_compose(self, compositeGF, indexList): gfList = compositeGF.getComponents() self.removeGF(compositeGF) pairList = map(None, gfList, indexList) pairList.reverse() for gf, index in pairList: gf.setEventHandler(self.mainHandler) self.insertGF(index, gf) def undo_decompose(self, compositeList): for composite in compositeList: gfList = composite.getComponents() for gf in gfList: index = self.removeGF(gf) gf.setEventHandler(composite) self.insertGF(index, composite) def undo_translate(self, gfList, dx, dy): for gf in gfList: gf.translate(dx, dy) def undo_rotate(self, gfList, centerX, centerY, angle): for gf in gfList: gf.rotate(centerX, centerY, angle) def undo_scale(self, gfList, centerX, centerY, factorX, factorY): for gf in gfList: gf.scale(centerX, centerY, factorX, factorY) def undo_setCoords(self, gf, oldCoords): gf.setCoords(oldCoords) def undo_setFillColor(self, undoList): for gf, color in undoList: gf.setFillColor(color) def undo_setOutlineColor(self, undoList): for gf, color in undoList: gf.setOutlineColor(color) def undo_setLineWidth(self, undoList): for gf, width in undoList: gf.setWidth(width) def undo_setOutlineFillOption(self, undoList): for gf, (outlineOption, fillOption) in undoList: gf.setOutlineOption(outlineOption) gf.setFillOption(fillOption) ###################### def appendGF(self, gf): self.GFs.append(gf) def insertGF(self, index, gf): self.GFs.insert(index, gf) for gf in self.GFs: gf.bringToTop() def getIndex(self, gf): return self.GFs.index(gf) def removeGF(self, gf): index = self.GFs.index(gf) self.GFs.remove(gf) return index #return the index the gf had in the list (which was also its relative position on the canvas) # convention: the first gfs in the list are drawn first. # The order in which the GFs are drawn is useful when we want to save. def bringToTopGF(self, gf): gf.bringToTop() index = self.removeGF(gf) self.GFs.append(gf) return index def pushToBottomGF(self, gf): gf.pushToBottom() index = self.removeGF(gf) self.GFs.insert(0, gf) return index def getGFs(self): return self.GFs[:] def setGFs(self, gfList): self.GFs = gfList def getEventHandler(self): return self.mainHandler def getCanvasWidth(self): return self.workspace.getCanvasWidth() def getCanvasHeight(self): return self.workspace.getCanvasHeight() def getCanvas(self): return self.workspace.getCanvas() def getZoom(self): return self.workspace.getZoom() def setZoom(self, zoom, x, y): self.workspace.setZoom(zoom, x, y) # update statusBar and GFs to the new zoom (whether it changed or not) newZoom = self.workspace.getZoom() self.statusBar.setZoom(newZoom) for gf in self.GFs: gf.setZoom(newZoom) def setToolSelector(self, tool): self.toolSelector.set(tool) def getLineWidth(self): return self.lineWidthSelector.get() def getOutlineColor(self): return self.colorSelector.getOutlineColor() def getFillColor(self): return self.colorSelector.getFillColor() def hasOutline(self): option = self.outlineFillOptionSelector.get() return option[0] def hasFill(self): option = self.outlineFillOptionSelector.get() return option[1]
def menuNew_activate(widget, data): data.mainVBox.mainNotebook.add(Workspace())
class PDMLview(Gtk.Window): currentWorkspace = Workspace("", "") sessionNum = 1 def pdmlDesign(self, workspace, mainwindow): self.mainwindow = mainwindow self.currentWorkspace = workspace # Starting box for pdmlView pdmlBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) pdmlBox.set_homogeneous(True) # Starting list box for pdmlVire pdmlListBox = Gtk.ListBox() # Adding listbox to box pdmlBox.add(pdmlListBox) # title "PDML View" area titleBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) labelPDML = Gtk.Label("PDML View") titleBox.add(labelPDML) # child is packed into box (item, expand, fill, padding, packtype) titleBox.set_child_packing(labelPDML, True, True, 100, 0) # Homogeneous titleBox.set_homogeneous(True) # Adding into primary list box pdmlListBox.add(titleBox) self.field = FieldArea.FieldArea() # pdml menu menu = self.pdmlMenu() pdmlListBox.add(menu) # filter area filterTab = self.filterArea(self.currentWorkspace) pdmlListBox.add(filterTab) # grid.add(filterTab) # pdmlListBox.add(grid) # packet area self.pckt = PacketArea.PacketArea() self.packetArea = self.pckt.Tabs(self.currentWorkspace) #grid.add(packetArea) pdmlListBox.add(self.packetArea) bottomPart = self.bottomPDMLView() pdmlListBox.add(bottomPart) #thisListBox.add(packetTab) #thisListBox.add(bottomTab) return pdmlBox def pdmlMenu(self): header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) # WARNING THIS BREAKS LAYOUT #header.set_homogeneous(True) # text boxes self.newStateNameEntry = Gtk.Entry() self.newStateNameEntry.set_placeholder_text("New PDML State Name") renameCurrentEntry = Gtk.Entry() renameCurrentEntry.set_placeholder_text( "Rename Current PDML State Name") # buttons saveNewBtn = Gtk.Button(label="Save as New\nPDML State") saveCurrentBtn = Gtk.Button(label="Save Current\nPDML State") closeCurrentBtn = Gtk.Button(label="Close Current\nPDML State") deleteCurrentBtn = Gtk.Button(label="Delete Current\nPDML State") renameCurrentBtn = Gtk.Button(label="Rename Current\nPDML State") header.add(self.newStateNameEntry) header.add(saveNewBtn) header.add(saveCurrentBtn) header.add(closeCurrentBtn) header.add(deleteCurrentBtn) header.add(renameCurrentEntry) header.add(renameCurrentBtn) saveNewBtn.connect("clicked", self.on_save_clicked, self.currentWorkspace) saveCurrentBtn.connect("clicked", self.on_savecurrent_clicked, self.currentWorkspace) return header def filterArea(self, currentWorkspace): # Starting box for filter filterBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) filterBox.set_homogeneous(True) # Starting list box for title filterListBox = Gtk.ListBox() # Adding listbox to box filterBox.add(filterListBox) # title "PDML View" area titleBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) labelTitle = Gtk.Label() labelTitle.set_markup("<u>Filter Area</u>") labelTitle.set_justify(Gtk.Justification.LEFT) titleBox.add(labelTitle) # child is packed into box (item, expand, fill, padding, packtype) titleBox.set_child_packing(labelTitle, True, True, 0, 0) # Adding into primary list box filterListBox.add(titleBox) # Starting second row lineBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) #nameLabel.set_justify(Gtk.Justification.LEFT) filterLabel = Gtk.Label("Filter") # buttons applyNewBtn = Gtk.Button("Apply") clearBtn = Gtk.Button("Clear") saveBtn = Gtk.Button("Save") applyFilterBtn = Gtk.Button("Apply") # text box (entry) newFilter = Gtk.Entry() newFilter.set_placeholder_text("Filter Expression") # drop down # TODO HAVE TO ESTABLISH THE filters saved OF THE DROPDOWN filters = FilterContainer() filter_store = Gtk.ListStore(str) for filterT in filters.filterList: filter_store.append([filterT]) savedFilters = Gtk.ComboBox().new_with_model(filter_store) #savedFilters.connect("changed", self.on_filter_combo_changed) renderer_text = Gtk.CellRendererText() savedFilters.pack_start(renderer_text, True) savedFilters.add_attribute(renderer_text, "text", 0) # # adding second line into box lineBox.add(filterLabel) lineBox.pack_start(newFilter, True, True, 10) lineBox.pack_start(applyNewBtn, True, True, 0) lineBox.pack_start(clearBtn, True, True, 0) lineBox.pack_start(saveBtn, True, True, 0) lineBox.pack_start(savedFilters, True, True, 0) lineBox.pack_start(applyFilterBtn, True, True, 0) applyFilterBtn.connect("clicked", self.on_filter_apply_clicked, savedFilters, currentWorkspace) filterListBox.add(lineBox) return filterBox def on_filter_apply_clicked(self, widget, combo, workspace): tree_iter = combo.get_active_iter() if tree_iter is not None: model = combo.get_model() filterT = model[tree_iter][0] #print("Selected: filter=%s" % filterT) else: filterT = "-1" dissector = Dissector.Dissector("", "") pdml = PDML.PDML() namePDML = dissector.convert(workspace.pcap, workspace.path) pdml.setName(namePDML) pdml.parse(workspace.path, filterT) pdml.setName("State" + str(self.sessionNum)) workspace.sessions[0].addPDML(pdml) self.listSessions = self.getListSession() self.sessionNum = self.sessionNum + 1 self.mainwindow.on_session_update() print(self.pckt.createPDMLview(workspace.sessions[0].getLatest())) self.pckt.update_pdml() self.field.update_fields() def on_save_clicked(self, widget, workspace): textnew = self.newStateNameEntry.get_text() #print(textnew) dissector = Dissector.Dissector("", "") pdml = PDML.PDML() namePDML = dissector.convert(workspace.pcap, workspace.path) pdml.setName(namePDML) pdml.parse(workspace.path, "-1") pdml.setName(textnew) workspace.sessions[0].addPDML(pdml) self.listSessions = self.getListSession() #self.sessionNum = self.sessionNum + 1; self.mainwindow.on_session_update() def on_savecurrent_clicked(self, widget, workspace): dissector = Dissector.Dissector("", "") pdml = PDML.PDML() namePDML = dissector.convert(workspace.pcap, workspace.path) pdml.setName(namePDML) pdml.parse(workspace.path, "-1") pdml.setName("State" + str(self.sessionNum)) workspace.sessions[0].addPDML(pdml) self.listSessions = self.getListSession() self.sessionNum = self.sessionNum + 1 self.mainwindow.on_session_update() def bottomPDMLView(self): box = Gtk.Box() grid = Gtk.Grid() box.add(grid) # Field Area self.fieldArea = self.field.Tabs() grid.attach(self.fieldArea, 0, 1, 1, 1) # Message Type Area mta = MessageTypeArea.MessageTypeArea() messTypeArea = mta.Tabs() grid.attach(messTypeArea, 2, 1, 1, 1) buttonBox = Gtk.VBox() plusButton = Gtk.Button("+") minusButton = Gtk.Button("-") buttonBox.add(plusButton) buttonBox.add(minusButton) grid.attach(buttonBox, 1, 1, 1, 1) return box def getListSession(self): return self.currentWorkspace.getListSession()
# Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from DisplayGroup import * from PhysicalDisplay import * from Portal import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## vr_lab_rear = Workspace('VR-Lab-Rear', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) workspaces = [vr_lab_rear] ## Create Navigation instances ## trace_visibility_list_table_nav = { "dlp_wall" : False , "table" : False , "portal" : False } spacemouse_navigation = SteeringNavigation() spacemouse_navigation.my_constructor( STARTING_MATRIX = avango.gua.make_trans_mat(0, 0, 20) * \ avango.gua.make_rot_mat(0, 0, 1, 0) , STARTING_SCALE = 50.0
## @file # Contains workspace, display, navigation, display group and user configuration classes to be used by the framework. # import guacamole libraries import avango import avango.gua # import framework libraries from Display import * from Workspace import Workspace from SteeringNavigation import SteeringNavigation from StaticNavigation import StaticNavigation ## Create Workspaces first ## atalante = Workspace('atalante', avango.gua.make_trans_mat(0.0, 0.043, 0.0)) workspaces = [atalante] ## Create Navigation instances ## spacemouse_navigation = SteeringNavigation() spacemouse_navigation.my_constructor( STARTING_MATRIX = avango.gua.make_trans_mat(0, 0, 0) , STARTING_SCALE = 1.0 , INPUT_DEVICE_TYPE = 'Spacemouse' , INPUT_DEVICE_NAME = 'device-spacemouse' , NO_TRACKING_MAT = avango.gua.make_trans_mat(0.0, 1.2, 0.6) , GROUND_FOLLOWING_SETTINGS = [True, 0.75] , MOVEMENT_TRACES = True , INVERT = False , AVATAR_TYPE = 'joseph' , DEVICE_TRACKING_NAME = None)
def handle_test(args, configs): from Workspace import Workspace from Module import do_test_cycle parser = argparse.ArgumentParser(description=cmd_description_test, usage=cmd_usage_test) if workspace_args is not None: [parser.add_argument(*arg[0], **arg[1]) for arg in workspace_args] my_args = parser.parse_args(args) wksp = Workspace(my_args, configs=configs) if wksp.num_modules > 20: from Module import do_test_cycle # Start a parallel process queue start = time.time() multi_proc(do_test_cycle, wksp.module_objs) print(f'Time taken = {time.time() - start:.2f}') # run( do_test_cycle, wksp.module_objs ) else: # Runs tests with current process start = time.time() wksp.find_wksp_test_src_files() wksp.find_wksp_tests_and_groups() wksp.gen_wksp_test_runners() wksp.run_wksp_tests() wksp.calculate_test_result_totals() wksp.print_test_summary() print(f'Time taken = {time.time() - start:.10f}')
class Window: """ This class handles all display aspects of Jum.py. """ # tk root root = Tk() # menu bar menu_bar = Menu() # file sub-menu in the menu bar menu_file = Menu(tearoff=False) # connections sub-menu in the menu bar menu_connections = Menu(tearoff=False) # frames for UX top_frame = Frame(root) bottom_frame = Frame(root) files = Frame(top_frame) location = Frame(files) radio_frame = Frame(files) directory = Label(location) back = Button(location) # functional frames code = CodeFrame(top_frame) terminal = Text(bottom_frame) # other variables current_file_name = StringVar() current_file = None old_text = "" # the workspace used by the program workspace: Workspace = None def __init__(self): self.net_hand = NetworkHandler(self.parse_message) #self.cursor_thread_run = True #self.cursor_thread = Thread(target=self.track_cursor) #self.cursor_thread.setDaemon(True) #self.u2_pos = None self.names = {} self.cursor_colors = ['red', 'green', 'blue', 'yellow', 'cyan'] self.autosave_thread = Thread(target=self.autosave_thread) self.autosave_thread.setDaemon(True) current_terminal_buffer_column = 0 current_terminal_buffer_line = 0 self.log = logging.getLogger('jumpy') self.mac = hex(uuid.getnode()) self.is_host = False self.have_perms = False self.mac_name = dict() self.workspace = Workspace() self.create() def create(self) -> None: """ Creates the window. """ self.root.title("jum.py") self.root.bind('<Key>', self.handle_event) self.root.bind('<Button-1>', self.handle_event) # menu bar self.menu_bar.add_cascade(label='File', menu=self.menu_file) self.menu_bar.add_cascade(label='Connections', menu=self.menu_connections) # file sub-menu self.menu_file.add_command(label="Open", command=self.open_folder) self.menu_file.add_command(label="Save", command=self.save_file) self.menu_file.add_command(label="Help", command=self.open_help) # connections sub-menu # self.menu_connections.add_command(label='Connect', command=self.net_hand.establish_connection) def create(): if self.workspace.is_active: val = simpledialog.askstring("Lobby name", "Please name your lobby") username = simpledialog.askstring("Prompt", "Please input a username") self.mac_name.update({self.mac: username}) self.net_hand.join_lobby(val) self.is_host = True self.have_perms = True self.net_hand.establish_connection() self.back.config(state='disabled') else: messagebox.showerror("jumpy", "no active workspace") def join(): self.workspace.use_temp_workspace() self.open_folder(self.workspace.directory) self.code.text.config(state='disabled') val = simpledialog.askstring( "Lobby name", "Please input the lobby you want to join.") username = simpledialog.askstring("Prompt", "Please input a username") self.mac_name.update({self.mac: username}) self.net_hand.join_lobby(val) self.net_hand.establish_connection() self.is_host = False self.have_perms = False dprj = DataPacketRequestJoin() dprj.set_name(self.mac_name.get(self.mac)) self.net_hand.send_packet(dprj) def disconnect(): self.net_hand.close_lobby() self.back.config(state='normal') self.menu_connections.add_command(label='Disconnect', command=disconnect) self.menu_connections.add_command(label='Create lobby', command=create) self.menu_connections.add_command(label='Join lobby', command=join) # add menubar to root self.root.config(menu=self.menu_bar) # terminal default self.terminal.insert("1.0", "Console:\n>>>") self.current_terminal_buffer_column = 3 self.current_terminal_buffer_line = 2 # text default self.old_text = self.code.text.get("1.0", END) self.directory.config(width=20, text="Current Folder:\nNone") self.back.config(text="cd ..\\", command=self.previous_dir) # visual effects self.files.config(width=200, bg='light grey') self.terminal.config(height=10, borderwidth=5) # visual packs self.root.geometry("900x600") self.top_frame.pack(side="top", fill='both', expand=True) self.bottom_frame.pack(side="bottom", fill='both', expand=True) self.files.pack(side="left", fill='both') self.location.pack(side="top", fill='x') self.directory.pack(side="left", fill='x', expand=True) self.back.pack(side="right", fill='x', expand=True) self.code.pack(side="right", fill='both', expand=True) self.terminal.pack(fill='both', expand=True) def show(self) -> None: """ Shows the window. """ # self.autosave_thread.start() # TODO: fix for better placing #self.cursor_thread.start() self.root.mainloop() def previous_dir(self): if self.workspace.directory != "C:/" and self.workspace.directory: split = self.workspace.directory.split("/") new_dir = "/".join(split[0:-1]) if (new_dir == "C:"): new_dir += "/" self.open_folder(new_dir) def open_help(self): webbrowser.open_new( "https://docs.google.com/document/d/13AHTV3BVfS3ELmaW2cqfzgJ9YmOeBkkkMqViyU-0WDM/edit?usp=sharing" ) # TODO for folders with alot of files add a scrollbar def open_folder(self, folder=None): if self.net_hand.is_connected: self.back.config(state='disabled') else: self.back.config(state='normal') location = "" if folder: location = folder else: location = filedialog.askdirectory() if location != "": #clear text and delete current radio buttons self.workspace.open_directory(location) # clear text and delete current radio buttons self.code.text.delete("1.0", END) # folder = os.listdir(location) # for item in folder: # item_path = location+ "/" + item # # condition so that folders that start with "." are not displayed # if os.path.isfile(item_path) or not item.startswith("."): # Radiobutton(self.radio_frame, text = item, variable=self.current_file_name, command=self.open_item, value=item_path, indicator=0).pack(fill = 'x', ipady = 0) split = str(location).split("/") index = -1 folder_name = split[index] while folder_name == "": index -= 1 folder_name = split[index] self.directory.config(text="Current Folder:\n" + folder_name) # clear text and delete current radio buttons self.code.text.delete("1.0", END) self.radio_frame.destroy() self.radio_frame = Frame(self.files, width=self.files.cget("width")) self.radio_frame.pack(fill="both", expand=True) self.options = FilesFrame(self.radio_frame, window=self) self.options.populate(self.workspace) self.reset_terminal() # starts cursor tracking thread # TODO: uncomment # TODO add functionality to clicking on folders (change current folder to that folder, have a back button to go to original folder) (chad doesn't think this is needed anymore) def open_item(self): if os.path.isfile(self.current_file_name.get()): self.code.text.delete("1.0", END) file = open(self.current_file_name.get(), "r") self.current_file = file try: self.code.text.insert(1.0, file.read()) self.syntax_highlighting() self.old_text = self.code.text.get("1.0", END) except: self.code.text.insert(1.0, "Can not interperate this file") file.close() else: self.open_folder(self.current_file_name.get()) name = self.current_file_name.get().split("/")[-1] self.directory.config(text="Current Folder:\n" + name) def save_file(self) -> None: f = filedialog.asksaveasfilename(defaultextension=".py") to_save_file = open(f, 'w') to_save_file.write(self.code.text.get("1.0", END)) to_save_file.close() def update_text(self, action: Action, position: int, character: str): self.log.debug( 'updating text with action: \'{}\', position: \'{}\', character: \'{}\'' .format(action, position, repr(character))) text_current = self.code.text.get("1.0", END) text_new = text_current[1:position + 1] + character + text_current[position + 1:] self.log.debug( f"current text:{repr(text_current)} \n updated text {repr(text_new)}" ) self.code.text.delete("1.0", END) self.code.text.insert("1.0", text_new) # n = 1 # if action == Action.ADD: # # TODO: fix# # # # text_new = character # if text_new == "\n": # n+=1 # self.log.debug("%d.%d"%(n,position)) # #self.text.insert("%d.%d"%(n,position), text_new) # elif action == Action.REMOVE: # # TODO: implement # pass def set_text(self, new_text: str): """ Sets the text on the Text object directly. Author: Chad Args: new_text: string Returns: """ self.code.text.delete("1.0", END) self.code.text.insert("1.0", new_text) def handle_event(self, event): """ Interpret keypresses on the local machine and send them off to be processed as a data packet. Keeps track of one-edit lag. TODO: Don't interpret all keypress as somthing to be sent e.g. don't send _alt_ Authors: Chad, Ben Args: event: str unused? Returns: Interactions: sends DataPacketDocumentEdit """ # if self.net_hand.is_connected: # new_text = self.code.text.get("1.0", END) # packet = DataPacketDocumentEdit(old_text=self.old_text, new_text=new_text) # if packet.character == '' or new_text == self.old_text: # return # else: # self.net_hand.send_packet(packet) # self.syntax_highlighting() # self.old_text = self.code.text.get("1.0", END) if event.widget == self.terminal: # handle terminal event cursor_line, cursor_column = [ int(x) for x in self.terminal.index(INSERT).split('.') ] if event.char == '\r': command = self.terminal.get( str(self.current_terminal_buffer_line) + "." + str(self.current_terminal_buffer_column), END).strip("\n ").split(" ") print(command) if command[0] != "": if self.workspace.directory: os.chdir(self.workspace.directory) if "cd" in command: if not self.net_hand.is_connected: if len(command) >= 2: try: os.chdir(self.workspace.directory + "/" + " ".join(command[1::]).strip( '\'\"')) self.workspace.open_directory( os.getcwd().replace("\\", "/")) self.open_folder( self.workspace.directory) return except: self.current_terminal_buffer_line += 1 self.terminal.insert( END, "'" + " ".join( command[1::]).strip('\'\"') + "' does not exist as a subdirectory\n" ) else: os.chdir("C:/") self.workspace.open_directory(os.getcwd()) self.open_folder("C:/") return else: self.terminal.insert( END, "Can not change directories while in workspace.\n" ) self.current_terminal_buffer_line += 1 else: error = self.run_command(" ".join(command)) if error: self.terminal.insert(END, error) self.current_terminal_buffer_line += 1 else: self.terminal.insert( END, "Open a directory before using the console.\n") self.current_terminal_buffer_line += 1 if self.workspace.directory: self.terminal.insert(END, self.workspace.directory + ">") self.current_terminal_buffer_column = len( self.workspace.directory) + 1 else: self.terminal.insert(END, ">>>") self.terminal.see(END) self.current_terminal_buffer_line += 1 return if event.char == '\x03': self.reset_terminal() if cursor_column < self.current_terminal_buffer_column or cursor_line < self.current_terminal_buffer_line: if event.char == '\x08': self.terminal.insert(END, ">") self.terminal.mark_set( "insert", "%d.%d" % (self.current_terminal_buffer_line, self.current_terminal_buffer_column)) elif event.widget == self.code.text: # handle text event if self.net_hand.is_connected and self.current_file_name.get( ) != "None": to_send = DataPacketDocumentEdit() to_send.set_document( self.current_file_name.get().split('/')[-1]) to_send.set_text(self.code.text.get("1.0", END)) self.net_hand.send_packet(to_send) # send a DataPacketCursorUpdate position = self.code.text.index(INSERT) dpcu = DataPacketCursorUpdate() dpcu.set_position(position) dpcu.set_document(self.current_file_name.get().split('/')[-1]) self.net_hand.send_packet(dpcu) self.syntax_highlighting() # # TODO: chad thinks that this is the answere to hash mis-match sleep(0.1) def syntax_highlighting(self, lang='python'): """ Highlights key elements of syntax with a color as defined in the language's SyntaxHandler. Only 'python' is currently implemented, but more can easily be added in the future. Author: Ben Args: lang: string, which language to use Returns: TODO: fix so keywords inside another keyword aren't highlighted TODO: make so that it doesn't trigger after every character TODO: run on seperate thread at interval or trigger (perhaps at spacebar? would reduce work) """ for tag in self.code.text.tag_names(): self.code.text.tag_delete(tag) if lang == 'python': SyntaxHandler = Syntax() syntax_dict = SyntaxHandler.get_color_dict() for kw in SyntaxHandler.get_keywords(): idx = '1.0' color = syntax_dict[kw] self.code.text.tag_config(color, foreground=color) # search_term =#rf'\\y{kw}\\y' # ' '+ kw + ' ' while idx: idx = self.code.text.search('\\y' + kw + '\\y', idx, nocase=1, stopindex=END, regexp=True) if idx: # self.log.debug(idx) nums = idx.split('.') nums = [int(x) for x in nums] # self.log.debug(f"{left} { right}") lastidx = '%s+%dc' % (idx, len(kw)) self.code.text.tag_add(color, idx, lastidx) idx = lastidx self.code.text.tag_config("comments", foreground="olive drab") idx = '1.0' while idx != '': idx = self.code.text.search('#', idx, nocase=1, stopindex=END) #self.log.debug(idx) if idx == '': #self.log.debug(idx) continue #self.log.debug(idx) endl = self.code.text.search('\n', idx, stopindex=END) if endl == "": endl = END self.code.text.tag_add("comments", idx, endl) idx = endl def reset_terminal(self): self.terminal.delete("1.0", END) self.terminal.insert(END, "Console:\n") if self.workspace.directory: self.terminal.insert(END, self.workspace.directory + ">") self.current_terminal_buffer_column = len( self.workspace.directory) + 1 else: self.terminal.insert(END, ">>>") self.current_terminal_buffer_column = 3 self.current_terminal_buffer_line = 2 def run_command(self, command): try: process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) while True: output = process.stdout.readline() if output == bytes('', "utf-8") and process.poll() == 0: break if output: self.terminal.insert(END, output.strip() + bytes("\n", "utf-8")) self.current_terminal_buffer_line += 1 self.terminal.insert(END, "\n") self.current_terminal_buffer_line += 1 except: return "'" + command + "' is not a valid command\n" def parse_message(self, packet_str: DataPacket): data_dict = json.loads(packet_str) packet_name = data_dict.get('packet-name') if data_dict.get('mac-addr') == self.mac: self.log.debug('received packet from self, ignoring...') else: self.log.debug('Received a \'{}\''.format(packet_name)) print(data_dict) if packet_name == 'DataPacket': self.log.debug('Received a DataPacket') elif packet_name == 'DataPacketDocumentEdit': self.log.debug('Received a DataPacketDocumentEdit') cursor_index = self.code.text.index(INSERT) packet: DataPacketDocumentEdit = DataPacketDocumentEdit() packet.parse_json(packet_str) self.workspace.apply_data_packet_document_edit(packet) current_doc = self.current_file_name.get().split('/')[-1] if packet.get_document() == current_doc: self.code.text.delete("1.0", END) self.code.text.insert(END, packet.get_text()) self.syntax_highlighting() self.code.text.mark_set(INSERT, cursor_index) elif packet_name == 'DataPacketCursorUpdate': u2_pos = data_dict.get('position') name = data_dict.get('mac-addr') self.cursor_update(u2_pos, str(name)) elif packet_name == 'DataPacketRequestJoin': packet: DataPacketRequestJoin = DataPacketRequestJoin() packet.parse_json(packet_str) if self.is_host: result = messagebox.askyesno( "jumpy request", "Allow \'{}\' to join the lobby?".format( data_dict.get(DataPacketRequestJoin.KEY_NAME))) dprr = DataPacketRequestResponse() dprr.set_target_mac(packet.get_mac_addr()) dprr.set_can_join(result) self.net_hand.send_packet(dprr) if result: sleep(3) name_broadcast = DataPacketNameBroadcast() name_broadcast.set_name(self.mac_name.get(self.mac)) self.net_hand.send_packet(name_broadcast) to_send = self.workspace.get_save_dump() for packet in to_send: self.net_hand.send_packet(packet) elif packet_name == 'DataPacketRequestResponse': packet: DataPacketRequestResponse = DataPacketRequestResponse() packet.parse_json(packet_str) if packet.get_target_mac() == DataPacket.get_mac_addr_static(): self.log.debug('Received a DataPacketRequestResponse') can_join = packet.get_can_join() # todo: fix if can_join: self.log.debug('allowed into the lobby') self.workspace.use_temp_workspace() self.have_perms = True messagebox.showinfo( "jumpy", "You have been accepted into the lobby!") else: self.log.debug('rejected from the lobby') self.have_perms = False messagebox.showerror( "jumpy", "You have NOT been accepted into the lobby...") self.net_hand.close_connection() name_broadcast = DataPacketNameBroadcast() name_broadcast.set_name(self.mac_name.get(self.mac)) self.net_hand.send_packet(name_broadcast) elif packet_name == 'DataPacketSaveDump': packet: DataPacketSaveDump = DataPacketSaveDump() packet.parse_json(packet_str) self.workspace.apply_data_packet_save_dump(packet) if self.workspace.new_file_added: if len(self.workspace.files) == packet.get_workspace_size( ): self.log.debug( 'received whole workspace, setting code.text state to normal' ) self.code.text.config(state='normal') self.open_folder(self.workspace.directory) elif packet_name == 'DataPacketSaveRequest': to_send = self.workspace.get_save_dump_from_document( data_dict.get('document')) self.net_hand.send_packet(to_send) elif packet_name == 'DataPacketNameBroadcast': packet = DataPacketNameBroadcast() packet.parse_json(packet_str) self.log.debug('mac_name updating {} to {}'.format( packet.get_mac_addr(), packet.get_name())) self.mac_name.update( {packet.get_mac_addr(): packet.get_name()}) else: self.log.warning( 'Unknown packet type: \'{}\''.format(packet_name)) return False def get_words(self): """ Gets all words (definition: seperated by a space character) in the Text object. Author: Ben Args: Returns: words: list a list a words in the Text object """ words = self.code.text.get("1.0", END).split(" ") return words def cursor_update(self, pos, name): if name not in self.names: self.names[name] = self.cursor_colors.pop() color = self.names[name] print(color) self.code.text.tag_remove(color, "1.0", END) curs = self.code.text.tag_config(color, background=color) pos_int = [int(x) for x in pos.split(".")] end_pos = f'{pos_int[0]}.{pos_int[1]+1}' self.code.text.tag_add(color, pos, end_pos) def autosave_thread(self): while True: sleep(10) if self.is_host: self.log.debug("autosaving...") self.autosave() else: pass def autosave(self): if self.is_host: to_send = self.workspace.get_save_dump() for packet in to_send: self.net_hand.send_packet(packet)
def on_launch_clicked(self, widget, path, name): workspace = Workspace(name.get_text(), path.get_text()) from OpenPCAP import OpenPCAP win = OpenPCAP(workspace) win.show_all()
class MainWindow(Gtk.Window): currentWorkspace = Workspace("","") def __init__(self, workspace): Gtk.Window.__init__(self, title="NTSBG") self.currentWorkspace = workspace print("workspace name= " + self.currentWorkspace.name) self.pdml = PDMLview.PDMLview() self.set_border_width(10) # self.set_default_size(s.get_width(), s.get_height()) # initialize header bar header = self.header() # initialize listbox design listMain = Gtk.ListBox() listMain.set_selection_mode(Gtk.SelectionMode.NONE) self.add(listMain) # initialize stages buttons stages = self.stagesButtons() listMain.add(stages) # initialize views views = self.viewsDesign(self.currentWorkspace) listMain.add(views) def header(self): hb = Gtk.HeaderBar() hb.props.title = "Network Traffic Based Software Generation" self.set_titlebar(hb) button = Gtk.Button(label="x") button.set_relief(Gtk.ReliefStyle.NONE) button.connect("clicked", Gtk.main_quit) hb.pack_end(button) buttonBox = self.menuBox() hb.pack_end(buttonBox) return hb def menuBox(self): buttonBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) Gtk.StyleContext.add_class(buttonBox.get_style_context(), "linked") buttonBox.set_spacing(10) # init Header Buttons Menu createBtn = Gtk.Button(label="Create Session") openBtn = Gtk.Button(label="Open Session") closeBtn = Gtk.Button(label="Close Session") switchBtn = Gtk.Button(label="Switch Workspace") pcapBtn = Gtk.Button(label="Open PCAP") terminalBtn = Gtk.Button(label="Terminal") # Connecting buttons createBtn.connect("clicked", self.on_new_session_clicked) pcapBtn.connect("clicked", self.on_open_pcap_clicked) openBtn.connect("clicked", self.on_open_session_clicked) buttonBox.add(createBtn) buttonBox.add(openBtn) buttonBox.add(closeBtn) buttonBox.add(switchBtn) buttonBox.add(pcapBtn) buttonBox.add(terminalBtn) return buttonBox def stagesButtons(self): stages = Gtk.ListBoxRow() # initialize stages section stage1 = Gtk.Button(label="Stage 1: Configuration and Setup") stage2 = Gtk.Button(label="Stage 2: Message Analysis") stage3 = Gtk.Button(label="Stage 3: Sequencing") stage4 = Gtk.Button(label="Stage 4: Code Generation") stageBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) Gtk.StyleContext.add_class(stageBox.get_style_context(), "linked") stageBox.set_homogeneous(True) stageBox.set_spacing(10) stageBox.add(stage1) stageBox.add(stage2) stageBox.add(stage3) stageBox.add(stage4) stages.add(stageBox) return stages def viewsDesign(self, currentWorkspace): views = Gtk.ListBoxRow() sessionsView = self.sessionsDesign(currentWorkspace) pdmlView = self.pdml.pdmlDesign(currentWorkspace, self) print("THIS IS THE CURRENT LIST ALV") self.sessionList = self.pdml.getListSession() views.add(sessionsView) sessionsView.pack_start(pdmlView, True, True, 0) return views def sessionsDesign(self, currentWorkspace): sessionsViewCol = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) thisListBox = Gtk.ListBox() sessionsViewCol.add(thisListBox) # Title "Sessions View" box titleBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=50) labelSessions = Gtk.Label("Sessions View") titleBox.add(labelSessions) titleBox.set_child_packing(labelSessions, 1, 1, 80, 0) # Sessions View tab sessionsTab = self.sessionsArea() # Tag Area tagAreaTab = self.tagArea(currentWorkspace) thisListBox.add(titleBox) thisListBox.add(sessionsTab) thisListBox.add(tagAreaTab) return sessionsViewCol def sessionsArea(self): sessionsTab = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) # TODO DON'T KNOW HOW TO DO SESSIONS HELP grid = Gtk.Grid() sessionsTab.add(grid) grid.set_row_spacing(5) # workspaceLabel = Gtk.Button(label="Workspace X") # workspaceLabel.set_sensitive(False) # grid.add(workspaceLabel) self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) self.hbox.store = Gtk.TreeStore(str, bool) for i in range(len(work)): piter = self.hbox.store.append(None, [work[i][0], False]) j = 1 while j < len(work[i]): self.hbox.store.append(piter, work[i][j]) j += 1 self.view = Gtk.TreeView() self.view.set_model(self.hbox.store) renderer = Gtk.CellRendererToggle() column_in_size = Gtk.TreeViewColumn("", renderer, active=1) self.view.append_column(column_in_size) renderer_frame = Gtk.CellRendererText() column_frame = Gtk.TreeViewColumn(self.currentWorkspace.name, renderer_frame, text=0) self.view.append_column(column_frame) # initializing box where packet will be scroll_window = Gtk.ScrolledWindow() grid.add(scroll_window) scroll_window.add(self.view) scroll_window.set_min_content_width(200) scroll_window.set_min_content_height(200) return sessionsTab def tagArea(self, workspace): tagAreaTab = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) grid = Gtk.Grid() tagAreaTab.add(grid) grid.set_column_spacing(10) grid.set_row_spacing(5) # title tagLabel = Gtk.Label() tagLabel.set_markup("<u>Tag Area</u>") # labels savedLabel = Gtk.Label("Saved Tag") nameLabel = Gtk.Label("Tag Name") fieldLabel = Gtk.Label("Tag Field") descriptionLabel = Gtk.Label("Tag Description") # drop down menu self.tagListWorkspace = workspace.tagContainer self.tag_store = Gtk.ListStore(str) for currTag in self.tagListWorkspace.tagList: tagStr = currTag.name print(tagStr) self.tag_store.append([tagStr]) self.savedCombo = Gtk.ComboBox().new_with_model(self.tag_store) renderer_text = Gtk.CellRendererText() self.savedCombo.pack_start(renderer_text, True) self.savedCombo.add_attribute(renderer_text, "text", 0) self.savedCombo.connect("changed", self.on_tag_changed) # text boxes self.nameEntry = Gtk.Entry() self.fieldEntry = Gtk.Entry() self.descriptionEntry = Gtk.Entry() # buttons buttonBox = Gtk.Box() buttonBox.set_homogeneous(True) buttonBox.set_spacing(5) updateBtn = Gtk.Button(label="Update") cancelBtn = Gtk.Button(label="Cancel") buttonBox.pack_end(cancelBtn, True, True, 0) buttonBox.add(updateBtn) leftBox = Gtk.VBox() leftBox.add(savedLabel) leftBox.add(nameLabel) leftBox.add(fieldLabel) leftBox.add(descriptionLabel) rightBox = Gtk.VBox() rightBox.pack_start(self.savedCombo, True, True, 5) rightBox.pack_start(self.nameEntry, True, True, 0) rightBox.pack_start(self.fieldEntry, True, True, 0) rightBox.pack_start(self.descriptionEntry, True, True, 0) rightBox.pack_start(buttonBox, True, True, 0) # adding to grid grid.add(tagLabel) grid.attach_next_to(leftBox, tagLabel, Gtk.PositionType.BOTTOM, 1, 1) grid.attach_next_to(rightBox, leftBox, Gtk.PositionType.RIGHT, 1, 1) updateBtn.connect("clicked", self.on_tag_update) return tagAreaTab def on_new_session_clicked(self, widget): from NewSession import NewSession win = NewSession() win.show_all() def on_open_pcap_clicked(self, widget): from OpenPCAP import OpenPCAP win = OpenPCAP() win.show_all() def on_open_session_clicked(self, widget): from OpenSession import OpenSession win = OpenSession() win.show_all() def on_tag_changed(self, widget): tree_iter = widget.get_active_iter() if tree_iter is not None: model = widget.get_model() currTag = model[tree_iter][0] print("Selected: tag=%s" % currTag) taglist = self.currentWorkspace.tagContainer self.tagObj = taglist.getTag(currTag) self.nameEntry.set_text(self.tagObj.name) self.fieldEntry.set_text(self.tagObj.field) self.descriptionEntry.set_text(self.tagObj.annotation) def on_tag_update(self, widget): currName = self.nameEntry.get_text() currField = self.fieldEntry.get_text() currAnnot = self.descriptionEntry.get_text() self.tagObj.name = currName self.tagObj.field = currField self.tagObj.annotation = currAnnot self.tag_store.clear() for currTag in self.tagListWorkspace.tagList: tagStr = currTag.name self.tag_store.append([tagStr]) self.savedCombo = Gtk.ComboBox().new_with_model(self.tag_store) def on_session_update(self): work = self.pdml.getListSession() self.hbox.store.clear() for i in range(len(work)): piter = self.hbox.store.append(None, [work[i][0], False]) j = 1 while j < len(work[i]): self.hbox.store.append(piter, work[i][j]) j += 1 self.view = Gtk.TreeView() self.view.set_model(self.hbox.store)