Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /home/cgabriel/20_dev/12_procpy/dataninja/

Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
Upload File :
Current File : //home/cgabriel/20_dev/12_procpy/dataninja/swimlane.py

import os,sys,re,tkinter,procpy

try:
    import tkinter.ttk,Pmw   #  ,tkintertable
except:
    import pip
    pip.main(["install","pyttk"])
    pip.main(["install","Pmw"]) 
#    pip.main(["install","tkintertable"])
    import tkinter.ttk,Pmw   #  ,tkintertable
import tkinter.scrolledtext
import procpy.config
import procpy.block

#************************************************************************

class Swimlane (procpy.block.Block):


    def generate_shape (self,shape):

        (x0,y0,x1,y1,x,y,w,h) = self.box_coord()
        self.elems        = { "SHAPE": self.canvas.create_rectangle(0,0,0,0,fill=self.color) }
        self.contentframe =  tkinter.Frame(self.canvas,background=self.color,bg=self.color,bd=0)
        self.content      =  tkinter.Text(self.contentframe,wrap="char",font=("Courier",int(self.fontsize)),
                                   borderwidth=0,insertborderwidth=0,bg=self.color,highlightcolor=self.color)
        self.window       = self.canvas.create_window(x,y,window=self.contentframe)
        self.contentframe.grid_propagate(False)
        self.content.config(state=tkinter.DISABLED)
        self.elems['X1']  = self.canvas.create_line(0,0,0,0,fill='black',width=2)
        self.elems['X2']  = self.canvas.create_line(0,0,0,0,fill='black',width=2)
        self.canvas.tag_lower(self.elems['X1'], self.elems['X2'])
        self.content.config(font=("Courier",int(self.fontsize)))

        if 'content' in vars(self) and 'content_backup' in vars(self):
            self.content.config(state=tkinter.NORMAL)
            self.content.insert("1.0",self.content_backup)     # text can be inserted only in NORMAL mode
            self.content.config(state=tkinter.DISABLED)

        self.elem_bindings()
        self.shape = 'a'

 #************************************************************************

    def format_shape (self):
    
        (x0,y0,x1,y1,x,y,w,h) = self.box_coord()

        if self.shape in "rs":
            if 'oldbbox' in vars(self):
                self.bbox = self.oldbbox
                del self.oldbbox
            try:
                self.elems['SHAPE'].setRect(x0,y0,w,h)
            except:
                self.elems['TEXT'].setGeometry(x0,y0,w,h)

        self.canvas.coords(self.elems['SHAPE'],x0,y0,x1,y1)               
        self.contentframe.config(width=int(0.9*w),height=int(0.9*h))
        self.content.place(x=0,y=0,width=int(0.9*w),height=int(0.9*h))
        (x9,y9) = self.canvas.coords(self.window)
        self.canvas.move(self.window,x-x9,y-y9)
        self.canvas.coords(self.elems['X1'],     x-0.5*w,y-0.5*h,99999999,y-0.5*h)
        self.canvas.coords(self.elems['X2'],     x-0.5*w,y+0.5*h,99999999,y+0.5*h)
        self.content.config(font=("Courier",int(self.fontsize)))


#************************************************************************

    def syntax_error (self):

        text = self.content.get("1.0",tkinter.END)
        if re.search(r"^[A-Za-z0-9\–\_]+\s*$", self.content.get("1.0",tkinter.END) ,re.DOTALL):
            return(0)
        return(1)
        
#************************************************************************

    def press_button (self,px,py,x_root,y_root):

        self.canvas.configure(cursor='sizing')    #  Alternative mouse pointers: arrow circle 
                                                  #  clock cross dotbox exchange fleur heart
        self.resize_box            = ""           #  man mouse pirate plus shuttle sizing spider
                                                  #  spraycan star target tcross trek watch
        self.x_root                = x_root
        self.y_root                = y_root
        (x0,y0,x1,y1,x,y,w,h)      = self.box_coord()
        
        if abs(y1 - py) < 4:            #  if pressing point is near the border of the box
             self.resize_box = self.resize_box + "S"    #  mark the direction for resizing
        if abs(y0 - py) < 4: 
             self.resize_box = self.resize_box + "N"

        self.canvas.assign_elements_to_swimlanes()

        self.last_event   = 1
        self.mouse_moves  = 0
        self.last_pressed = timeclock

#**********************************************************

    def move (self,dx,dy,move_as_a_depending_swimlane=None):

#   1.   ----  Check whether x-position of swimlane has to be moved

        bed                = False
        depending_swimlane = None

        for swimlane in self.canvas.swimlanes:
            
            if swimlane == self:   #  Check whether there is an intersection with any other swimlane
                continue
            if (swimlane.bbox[1] < self.bbox[1] < swimlane.bbox[3] or swimlane.bbox[1] < self.bbox[3] < swimlane.bbox[3]
                  or self.bbox[1] < swimlane.bbox[1] < self.bbox[3] or self.bbox[1] < swimlane.bbox[3] < self.bbox[3]):
                if move_as_a_depending_swimlane or self == self.canvas.hl_block[0]:
                    if (swimlane.bbox[1] - self.bbox[1]) * dy > 0:
                        depending_swimlane = swimlane
                        bed     = True
                        break
                else:
                    bed     = True   #  block intersection
                    break
                        
        if bed:
            if depending_swimlane:
                depending_swimlane.move(dx,dy,1)
            elif self.bbox[0] == 0:
                self.bbox[0] = self.bbox[0] + self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
                self.bbox[2] = self.bbox[2] + self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
        else:
            if not self.bbox[0] == 0:
                self.bbox[0] = self.bbox[0] - self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
                self.bbox[2] = self.bbox[2] - self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
      
        self.bbox[1] = self.bbox[1] + dy
        self.bbox[3] = self.bbox[3] + dy
        self.format_shape()

        for block in self.move_blocks:
            block.move(0,dy)
        for point in self.move_arrowpoints:
            arrow       = point[0]
            arrowline   = arrow.arrowlines[point[1]]
            coords      = self.canvas.coords(arrowline)
            coords[point[2]]   = coords[point[2]]   + 0
            coords[point[2]+1] = coords[point[2]+1] + dy
            self.canvas.coords(arrowline,tuple(coords))
            arrow.fit_description() 

#************************************************************************
#************************************************************************
#************************************************************************
#************************************************************************
#************************************************************************
#************************************************************************

class Block1 (object):

    def __init__ (self,mode,frame,obj):
    
        self.mode           = mode                 #  no functionality
        self.frame         = frame                 #  the gui_file-object
        self.graphcanvas    = frame.graphcanvas    #  the canvas
        self.vars           = []                   #  the variables of the block
        self.text_invisible = []                   #  the hiddenvariables
        self.arrows_in      = []                   #  arrows coming in
        self.arrows_out     = []                   #  arrows going out
        self.nr             = 0                    #  the level of the block respecting the ancestor series
        self.elems          = {}                   #  actual elems of the block (rectangle, triangle, rhombe, circle ...)
        self.shape          = "x"                  #  the shape of the block
        self.syntax_error   = 0                    #  indicates whether text insinde block is valid python syntax
        self.fontsize       = self.canvas.zoom_factor * procpy.config.TEXT_SIZE  #  size of inside text
        self.fkt            = obj._FKT_
        (x,y,w,h)           = obj.BLOCK[1:5]
        self.bbox           = [x-w/2,y-h/2,x+w/2,y+h/2]
        self.color          = procpy.config.COLOR_BLOCK
        self.sync_variables_to_text(obj.__dict__,obj.BLOCK[5:])
        self.text           = re.sub(r"$","",self.text,99999999)
        if len(obj.BLOCK) > 5 and not obj.BLOCK[5] == "":
            self.color = obj.BLOCK[5]

        m = re.search(r"^([A-Za-z]+)([0]+)$",self.fkt)   #   choose a new name
        if m:
            zaehler    = 0
            formheader = "%0"+str(len(m.group(2)))+"u"
            while (0 == 0):
                zaehler  = zaehler + 1 
                self.fkt = m.group(1) + (formheader % zaehler)
                for block in self.canvas.blocks:
                   if self.fkt == block.fkt:
                       self.fkt = ""
                       break 
                if not self.fkt == "":
                    break   
        
        if self.bbox[0] <= 0:    #  make a swimlane          #  --> 078-SWIM
            self.color   = procpy.config.COLOR_SWIMLANE
            self.bbox[0] = 0
            self.bbox[2] = self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
            if self.bbox[3]-self.bbox[1]==40: # only make different size, if the block size 40 is given; 
                self.bbox[1] = max(0, y - 3 * self.bbox[2]) # this indicates, that the block was not predefined by the user
                self.bbox[3] =        y + 3 * self.bbox[2]  # but it is defined for the first time (not save/open)
                                                            #   <-- 078-SWIM

            for block in self.canvas.blocks:  #  check whether there is a proper space for the swimlane


                if block.shape == "a":
                    if block.bbox[3] < y:
                        self.bbox[1] = max(self.bbox[1],block.bbox[3])
                    elif block.bbox[1] > y:
                        self.bbox[3] = min(self.bbox[3],block.bbox[1])
                    else:
                        self.not_valid = 1    #  Clickpoint is inside of an existing swimlane
                        return()
				
            self.fit_content("a")
        else:
            self.fit_content("x")
            
            
#************************************************************************

    def sync_variables_to_text (self,varslist,varsorder):
   
        blockvars = {}
        maxv      = 0
        for v in varslist:   #  check all variables of the block object
            if re.search(r"^(BLOCK|pars|JUMP|_FKT_)$",v):
                continue
            varskey = v
            for v1 in varsorder:   #   special ordering
                if v.find(v1) == 0:
                    varskey = "AAAAAAAA" + v
                    break
            blockvars[varskey] = v
            maxv = max(maxv,len(v))   #   align '=' at left

        blockvarskeys = list(blockvars.keys())
        blockvarskeys.sort()

        self.text = ""
        for vkey in blockvarskeys:
            v    = blockvars[vkey]
            self.text = self.text + "$" + (v+" "*maxv)[0:maxv] + " = " + str(obj.__dict__[v]) + "\n"

#************************************************************************

    def sync_text_to_varslist (self,text=None):  
                                          
        if not text:
            text = self.text
        varslist  = re.sub(r"[\n ]*([a-zA-Z\_][a-zA-Z0-9\_]*)[ =].*?(\n[\n ]*|$)","\\1,",text,99999999,re.DOTALL)
        if re.sub(r"(^|,)[a-zA-\_][a-zA-Z0-9\_]*","",varslist,99999999,re.DOTALL) == ",":
            return(varslist.split(","))
        return(None)

#************************************************************************

#    def sync_varslist_to_varsorder (self,varslist):  
#                                          
#        varsorder = []
#        var0      = ""
#        for var in varslist:  #  Makes a sorting order array for the variables in varslist
#            if var == "":     #  where sorting order patterns are as short as possible
#                continue
#            zaehler = 0
#            while (0 == 0):
#                zaehler = zaehler + 1
#                var1    = var0[:zaehler]
#                if not var0.find(var1) == 0:
#                    varsorder.append(var1)
#                    var0 = var
#                    break
#                if var1 == var0:
#                    break
#                    
#        return(varsorder)

#************************************************************************

    def sync_content_to_fkt_and_text (self):   #  synchronize the content of the Text Area with fkt and text
    
        if not 'content' in vars(self):
            return(0)
            
        fkt  = self.content.get("1.0",tkinter.END)
#        fkt  = re.sub(r"\n([a-zA-Z])","\n\\1",fkt,re.DOTALL,99999999)    #  seems to be superfluous
        text = ""
        m    = re.search(r"^(.*?)\n(.*?) *$",fkt,flags=re.DOTALL)
        if m:
            fkt  = m.group(1)
            text = m.group(2)
        if not re.search(r"^[a-zA-Z][a-zA-Z\_0-9]+$",fkt):
            return(-1)                       #   not a valid fkt
        if re.search(r"\S",text):
            if self.shape == "a":
                return(-1)                   #   a swimlane should only carry a fkt, text shall be empty
            
            if not self.sync_text_to_varslist(text):   #   no valid program code
                return(-1)
            try:              #  check also validity as python program code
                exec(text)
            except:
                return(-1)   
        self.fkt  = fkt
        self.text = text        
        return(1)
            
#************************************************************************

    def destroy (self,destroy_arrows=True):
    
        for elem in list(self.elems.values()):
            self.graphcanvas.delete(elem)
            
        if 'content' in vars(self):
            self.content.place_forget()
            del self.content
            del self.contentframe
            self.graphcanvas.delete(self.window)
            del self.window

        if destroy_arrows:
            for arrow in self.arrows_in:
                arrow.source_block.arrows_out.remove(arrow)
                arrow.destroy()
            for arrow in self.arrows_out:
                arrow.target_block.arrows_in.remove(arrow)
                arrow.destroy()
            
#************************************************************************

    def scale (self,fac):
    
        for i in (0,1,2,3):
            self.bbox[i] = self.bbox[i] * fac
        for arrow in self.arrows_out:
            arrow.scale(fac)

        self.fontsize = self.fontsize * fac

        self.fit_content(self.shape)

        
#************************************************************************

#    def zoom_text (self,fac):
#    
#        self.fontsize = self.fontsize * fac
#        self.fit_content(self.shape)
        
#************************************************************************


    def fit_content (self,set_shape=None):


        
        '''
        Fits all contents of the block so that all is fitted
        properly into the shape.
        
        shape not None: includes checking and reformating header and text
        
        Shapes:
        
        r: Normale rectangle block
        s: Subprocess (rectangle)
        i: Case switch (diamond with X)
        f: Forking block (diamond with cross)
        m: Multiple switch (diamond with star)
        w: Wait Block (diamond with circle)
        c: Start Block (circle)
        e: End Block (circle)
        a: Swim lane
        '''

        if set_shape:

            if set_shape in "rceifmwsa":   #  explicit definition of block shape
                shape = set_shape
            else:                          #  implicit definiton of block shape by counting
                shape = { "00": "r",       #  in and out arrows
                          "01": "c",
                          "02": "c",
                          "10": "r",   #  e
                          "11": "r",
                          "12": "ifm",
                          "20": "r",   #  e
                          "21": "ws",
                          "22": "s" } [ str(min(len(self.arrows_in),2)) + str(min(len(self.arrows_out),2)) ]

            if shape == "ifm":   #  split off paths: shape depends on splitting case constraints
                shape         = "i"
                wertebereiche = []
                for arrow in self.arrows_out:
                    text = self.graphcanvas.itemcget(arrow.text,'text')
                    m    = re.search(r"(\d+?),?(\d*)",text)
                    if m:
                        try:
                            val   = [int(m.group(1)),int(m.group(2))]
                            shape = "f"
                        except:
                            val   = [int(m.group(1)),int(m.group(1))]
                        for val1 in wertebereiche:
                            if val1[1] > val[0] or val[1] > val1[0]:
                                shape = "m"
                                break
                        if shape == "m":
                            break                        
                        wertebereiche.append(val)

            if shape == "ws":
                shape = "w"

            if self.shape in shape:
                shape = self.shape

            if not shape == self.shape:
                self.destroy(destroy_arrows=False)

            x = (self.bbox[0]+self.bbox[2])/2
            y = (self.bbox[1]+self.bbox[3])/2
            self.content_text = self.fkt + "\n" + self.text

            if shape in "ars":  #  Rectangle, normal block
                if not shape == self.shape:  #  Shape has changed
                    self.elems        = { "SHAPE":   self.graphcanvas.create_rectangle(0,0,0,0,fill=self.color) }

                    self.contentframe =  tkinter.Frame(self.graphcanvas,background=self.color,bg=self.color,bd=0)
                    self.content      =  tkinter.Text(self.contentframe,wrap={"r":"none","s":"none","a":"char"}[shape],
                                          borderwidth=0,insertborderwidth=0,bg=self.color,highlightcolor=self.color)
                    self.window       = self.graphcanvas.create_window(x,y,window=self.contentframe)
                    self.contentframe.grid_propagate(False)
                    self.content.insert("0.0",self.fkt + "\n" + self.text)
                    self.content.config(state=tkinter.DISABLED)
                    if shape in "s":
                        self.elems['EXPAND'] = self.graphcanvas.create_rectangle(0,0,0,0,width=1)
                    if shape in "s":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=1)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=1)

                    if shape in "a":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=2)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=2)
                        
                        #Solution part 2: move the swim lane behind the blocks. Part 1 in the module Gui_file.
                        self.graphcanvas.tag_lower(self.elems['X1'])
                        self.graphcanvas.tag_lower(self.elems['X2'])						
#                        self.elems['X3']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                self.content.config(font=({"r":"Arial","s":"Arial","a":"Courier New Bold"}[shape],int(self.fontsize)))

            elif shape in "iwfm":    #   Diamond
                if not shape == self.shape:  #  Shape has changed
                    self.elems = { "SHAPE":  self.graphcanvas.create_polygon(0,0,0,0,0,0,0,0,fill=self.color,outline='black'),
                                   "HEADER": self.graphcanvas.create_text(0,0,anchor=tkinter.N,text=self.fkt),
                                   "TEXT":   self.graphcanvas.create_text(0,0,anchor=tkinter.CENTER,text=self.text)
                                 }
                    if shape in "im":
                        self.elems['CROSS1'] = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                        self.elems['CROSS2'] = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                    if shape in "fm":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                    if shape == "w":
                        self.elems['CIRCLE'] = self.graphcanvas.create_oval(0,0,0,0,outline='black',width=3)
                self.graphcanvas.itemconfig(self.elems['HEADER'],font=('Arial',int(self.fontsize)))
                self.graphcanvas.itemconfig(self.elems['TEXT'],  font=('Arial',int(self.fontsize)))

            elif shape in "ce":  #  Circle
                if not shape == self.shape:  #  Shape has changed
                    self.elems        = { "SHAPE":  self.graphcanvas.create_oval(0,0,0,0,fill=self.color,outline='black') }
                    self.contentframe =  tkinter.Frame(self.graphcanvas,background=self.color,bg=self.color)
                    self.content      =  tkinter.Text(self.contentframe,wrap="none",bg=self.color,
                                                      highlightcolor=self.color,borderwidth=0,insertborderwidth=0)
                    self.window       = self.graphcanvas.create_window(158,99,window=self.contentframe)
                    self.contentframe.grid_propagate(False)
                    self.content.insert("0.0",self.fkt + "\n" + self.text)
                    self.content.config(state=tkinter.DISABLED)
                self.content.config(font=('Arial',int(self.fontsize)))

                    
            elif shape in "t":  #  Triangle
                if not shape == self.shape:  #  Shape has changed
                    self.elems = { "SHAPE":  self.graphcanvas.create_polygon(0,0,0,0,0,0,fill=self.color,outline='black') }
                    self.content = tkinter.Text(self.graphcanvas,wrap="none",bg=self.color,highlightcolor=self.color,
                                                borderwidth=0,insertborderwidth=0)
                    self.content.insert("0.0",self.fkt + "\n" + self.text)
                    self.content.config(state=tkinter.DISABLED)
                self.content.config(font=('Arial',int(self.fontsize)))


            if not shape == self.shape:    #  Shape has changed
                self.shape = shape
                if 'content' in vars(self):
                    self.content.bind("<ButtonPress-1>",   lambda event: self.press_button(event))
                    self.content.bind("<ButtonRelease-1>", self.release_button_event)
                    self.content.bind("<B1-Motion>",       self.move_mouse_event)
                    self.content.bind("<Double-Button-1>", self.double_click_button_event)
                for elem in list(self.elems.values()):
                    self.graphcanvas.tag_bind(elem,"<ButtonPress-1>",   lambda event: self.press_button_event(event))
                    self.graphcanvas.tag_bind(elem,"<ButtonRelease-1>", self.release_button_event)
                    self.graphcanvas.tag_bind(elem,"<B1-Motion>",       self.move_mouse_event)
                    self.graphcanvas.tag_bind(elem,"<Double-Button-1>", self.double_click_button_event)


        x = (self.bbox[0]+self.bbox[2])/2
        y = (self.bbox[1]+self.bbox[3])/2
        w = self.bbox[2] - self.bbox[0]        
        h = self.bbox[3] - self.bbox[1]        
        

        if self.shape in "iwfmce":                  #  reduce the bounding box to a square 
            if w > h:                               #  because diamond shapes shall be always rectangular,
                self.bbox[0] = x - h/2              #  and circles should be circles, not ovals
                self.bbox[2] = x + h/2
                w = h
            else:
                self.bbox[1] = y - w/2
                self.bbox[3] = y + w/2
                h = w

        if self.shape in "ars":
            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[1],self.bbox[2],self.bbox[3])               
            self.contentframe.config(width=int(0.9*w),height=int(0.9*h))
            self.content.place(x=0,y=0,width=int(0.9*w),height=int(0.9*h))
            (x1,y1) = self.graphcanvas.coords(self.window)
            self.graphcanvas.move(self.window,x-x1,y-y1)
            if self.shape == "s":
                self.graphcanvas.coords(self.elems['EXPAND'], x-0.09*w,y+0.32*h,x+0.09*w,y+0.5*h)
                self.graphcanvas.coords(self.elems['X1'],     x-0.09*w,y+0.32*h,x+0.09*w,y+0.32*h)
                self.graphcanvas.coords(self.elems['X2'],     x,y+0.4*h,x,y+0.5*h)
            if self.shape == "a":
                self.graphcanvas.coords(self.elems['X1'],     x-0.5*w,y-0.5*h,99999999,y-0.5*h)
                #self.graphcanvas.coords(self.elems['X2'],     x-0.5*w,y+0.5*h,99999999,y+0.5*h)
                self.graphcanvas.coords(self.elems['X2'],     x-0.5*w,y+0.5*h,99,y+0.5*h)
#                self.graphcanvas.coords(self.elems['X3'],     x-0.5*w,y-0.5*h,x-0.5*w,y+0.5*h)

        elif self.shape in "iwfm":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],y,x,self.bbox[1],self.bbox[2],y,x,self.bbox[3])               
            self.graphcanvas.coords(self.elems['HEADER'],x,self.bbox[1])
            self.graphcanvas.coords(self.elems['TEXT'],  x,y)
            if self.shape in "im":
                self.graphcanvas.coords(self.elems['CROSS1'], x-0.17*w,y-0.17*h,x+0.17*w,y+0.17*h)
                self.graphcanvas.coords(self.elems['CROSS2'], x+0.17*w,y-0.17*h,x-0.17*w,y+0.17*h)
            if self.shape in "fm":
                self.graphcanvas.coords(self.elems['X1'], x-0.17*w,y,x+0.17*w,y)
                self.graphcanvas.coords(self.elems['X2'], x,y-0.17*h,x,y+0.17*h)
            if self.shape == "w":
                self.graphcanvas.coords(self.elems['CIRCLE'], x-0.19*w,y-0.19*h,x+0.19*w,y+0.19*h)

        elif self.shape in "ce":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[1],self.bbox[2],self.bbox[3])               
            self.contentframe.config(width=int(0.7*w),height=int(0.7*h))
            self.content.place(x=0,y=0,width=int(0.7*w),height=int(0.7*h))
            (x1,y1) = self.graphcanvas.coords(self.window)
            self.graphcanvas.move(self.window,x-x1,y-y1)

        elif self.shape in "t":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[3],x,self.bbox[1],self.bbox[2],self.bbox[3])               
            self.content.place(x=int(x-0.28*w),y=int(y-0.28*h),width=int(0.56*w),height=int(0.56*h))


        for arrow in self.arrows_in + self.arrows_out:
            arrow.fit_block_connections()
            arrow.fit_description()

        if set_shape:

            if set_shape in "rceifmwsa":   #  explicit definition of block shape
                shape = set_shape
            else:                          #  implicit definiton of block shape by counting
                shape = { "00": "r",       #  in and out arrows
                          "01": "c",
                          "02": "c",
                          "10": "r",   #  e
                          "11": "r",
                          "12": "ifm",
                          "20": "r",   #  e
                          "21": "ws",
                          "22": "s" } [ str(min(len(self.arrows_in),2)) + str(min(len(self.arrows_out),2)) ]

            if shape == "ifm":   #  split off paths: shape depends on splitting case constraints
                shape         = "i"
                wertebereiche = []
                for arrow in self.arrows_out:
                    text = self.graphcanvas.itemcget(arrow.text,'text')
                    m    = re.search(r"(\d+?),?(\d*)",text)
                    if m:
                        try:
                            val   = [int(m.group(1)),int(m.group(2))]
                            shape = "f"
                        except:
                            val   = [int(m.group(1)),int(m.group(1))]
                        for val1 in wertebereiche:
                            if val1[1] > val[0] or val[1] > val1[0]:
                                shape = "m"
                                break
                        if shape == "m":
                            break                        
                        wertebereiche.append(val)

            if shape == "ws":
                shape = "w"

            if self.shape in shape:
                shape = self.shape

            if not shape == self.shape:
                self.destroy(destroy_arrows=False)

            x = (self.bbox[0]+self.bbox[2])/2
            y = (self.bbox[1]+self.bbox[3])/2
            self.content_text = self.fkt + "\n" + self.text

            if shape in "ars":  #  Rectangle, normal block
                if not shape == self.shape:  #  Shape has changed
                    self.elems        = { "SHAPE":   self.graphcanvas.create_rectangle(0,0,0,0,fill=self.color) }
                    self.contentframe =  tkinter.Frame(self.graphcanvas,background=self.color,bg=self.color)
                    self.content      =  tkinter.Text(self.contentframe,wrap={"r":"none","s":"none","a":"char"}[shape],
                                          bg=self.color,highlightcolor=self.color,borderwidth=0,insertborderwidth=0)
                    self.window       = self.graphcanvas.create_window(x,y,window=self.contentframe)
                    self.contentframe.grid_propagate(False)
                    self.content.insert("0.0",self.fkt + "\n" + self.text)
                    self.content.config(state=tkinter.DISABLED)
                    if shape in "s":
                        self.elems['EXPAND'] = self.graphcanvas.create_rectangle(0,0,0,0,width=1)
                    if shape in "s":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=1)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=1)
                    if shape in "a":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=2)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=2)
                        
                        #Solution part 2: move the swim lane behind the blocks. Part 1 in the module Gui_file.
                        self.graphcanvas.tag_lower(self.slems['X1'])
                        self.graphcanvas.tag_lower(self.slems['X2'])
#                        self.elems['X3']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                self.content.config(font=({"r":"Arial","s":"Arial","a":"Courier New Bold"}[shape],int(self.fontsize)))


            elif shape in "iwfm":    #   Diamond
                if not shape == self.shape:  #  Shape has changed
                    self.elems = { "SHAPE":  self.graphcanvas.create_polygon(0,0,0,0,0,0,0,0,fill=self.color,outline='black'),
                                   "HEADER": self.graphcanvas.create_text(0,0,anchor=tkinter.N,text=self.fkt),
                                   "TEXT":   self.graphcanvas.create_text(0,0,anchor=tkinter.CENTER,text=self.text)
                                 }
                    if shape in "im":
                        self.elems['CROSS1'] = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                        self.elems['CROSS2'] = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                    if shape in "fm":
                        self.elems['X1']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                        self.elems['X2']     = self.graphcanvas.create_line(0,0,0,0,fill='black',width=3)
                    if shape == "w":
                        self.elems['CIRCLE'] = self.graphcanvas.create_oval(0,0,0,0,outline='black',width=3)

                self.graphcanvas.itemconfig(self.elems['HEADER'],font=('Arial',int(self.fontsize)))
                self.graphcanvas.itemconfig(self.elems['TEXT'],  font=('Arial',int(self.fontsize)))


            elif shape in "ce":  #  Circle
                if not shape == self.shape:  #  Shape has changed
                    self.elems        = { "SHAPE":  self.graphcanvas.create_oval(0,0,0,0,fill=self.color,outline='black') }

                    self.contentframe =  tkinter.Frame(self.graphcanvas,background=self.color,bg=self.color)

                    self.content      =  tkinter.Text(self.contentframe,wrap="none",bg=self.color,
                                                      highlightcolor=self.color,borderwidth=0,insertborderwidth=0)
                    self.window       = self.graphcanvas.create_window(158,99,window=self.contentframe)
                    self.contentframe.grid_propagate(False)

                    self.content.insert("0.0",self.fkt + "\n" + self.text)

                    self.content.config(state=tkinter.DISABLED)
                self.content.config(font=('Arial',int(self.fontsize)))

                    
            elif shape in "t":  #  Triangle
                if not shape == self.shape:  #  Shape has changed
                    self.elems = { "SHAPE":  self.graphcanvas.create_polygon(0,0,0,0,0,0,fill=self.color,outline='black') }
                    self.content = tkinter.Text(self.graphcanvas,wrap="none",bg=self.color,highlightcolor=self.color,
                                                borderwidth=0,insertborderwidth=0)

                    self.content.insert("0.0",self.fkt + "\n" + self.text)
                    self.content.config(state=tkinter.DISABLED)
                self.content.config(font=('Arial',int(self.fontsize)))



            if not shape == self.shape:    #  Shape has changed
                self.shape = shape
                if 'content' in vars(self):
                    self.content.bind("<ButtonPress-1>",   lambda event: self.press_button(event))
                    self.content.bind("<ButtonRelease-1>", self.release_button)
                    self.content.bind("<B1-Motion>",       self.move_mouse)
                    self.content.bind("<Double-Button-1>", self.double_click_button)
                for elem in list(self.elems.values()):
                    self.graphcanvas.tag_bind(elem,"<ButtonPress-1>",   lambda event: self.press_button(event))
                    self.graphcanvas.tag_bind(elem,"<ButtonRelease-1>", self.release_button)
                    self.graphcanvas.tag_bind(elem,"<B1-Motion>",       self.move_mouse)
                    self.graphcanvas.tag_bind(elem,"<Double-Button-1>", self.double_click_button)


        x = (self.bbox[0]+self.bbox[2])/2
        y = (self.bbox[1]+self.bbox[3])/2
        w = self.bbox[2] - self.bbox[0]        
        h = self.bbox[3] - self.bbox[1]        
        

        if self.shape in "iwfmce":                  #  reduce the bounding box to a square 
            if w > h:                               #  because diamond shapes shall be always rectangular,
                self.bbox[0] = x - h/2              #  and circles should be circles, not ovals
                self.bbox[2] = x + h/2
                w = h
            else:
                self.bbox[1] = y - w/2
                self.bbox[3] = y + w/2
                h = w

        if self.shape in "ars":
            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[1],self.bbox[2],self.bbox[3])               
            self.contentframe.config(width=int(0.9*w),height=int(0.9*h))
            self.content.place(x=0,y=0,width=int(0.9*w),height=int(0.9*h))
            (x1,y1) = self.graphcanvas.coords(self.window)
            self.graphcanvas.move(self.window,x-x1,y-y1)
            if self.shape == "s":
                self.graphcanvas.coords(self.elems['EXPAND'], x-0.09*w,y+0.32*h,x+0.09*w,y+0.5*h)
                self.graphcanvas.coords(self.elems['X1'],     x-0.09*w,y+0.32*h,x+0.09*w,y+0.32*h)
                self.graphcanvas.coords(self.elems['X2'],     x,y+0.4*h,x,y+0.5*h)
            if self.shape == "a":
                self.graphcanvas.coords(self.elems['X1'],     x-0.5*w,y-0.5*h,99999999,y-0.5*h)
                self.graphcanvas.coords(self.elems['X2'],     x-0.5*w,y+0.5*h,99999999,y+0.5*h)
#                self.graphcanvas.coords(self.elems['X3'],     x-0.5*w,y-0.5*h,x-0.5*w,y+0.5*h)

        elif self.shape in "iwfm":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],y,x,self.bbox[1],self.bbox[2],y,x,self.bbox[3])               
            self.graphcanvas.coords(self.elems['HEADER'],x,self.bbox[1])
            self.graphcanvas.coords(self.elems['TEXT'],  x,y)
            if self.shape in "im":
                self.graphcanvas.coords(self.elems['CROSS1'], x-0.17*w,y-0.17*h,x+0.17*w,y+0.17*h)
                self.graphcanvas.coords(self.elems['CROSS2'], x+0.17*w,y-0.17*h,x-0.17*w,y+0.17*h)
            if self.shape in "fm":
                self.graphcanvas.coords(self.elems['X1'], x-0.17*w,y,x+0.17*w,y)
                self.graphcanvas.coords(self.elems['X2'], x,y-0.17*h,x,y+0.17*h)
            if self.shape == "w":
                self.graphcanvas.coords(self.elems['CIRCLE'], x-0.19*w,y-0.19*h,x+0.19*w,y+0.19*h)

        elif self.shape in "ce":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[1],self.bbox[2],self.bbox[3])               
            self.contentframe.config(width=int(0.7*w),height=int(0.7*h))
            self.content.place(x=0,y=0,width=int(0.7*w),height=int(0.7*h))
            (x1,y1) = self.graphcanvas.coords(self.window)
            self.graphcanvas.move(self.window,x-x1,y-y1)

        elif self.shape in "t":

            self.graphcanvas.coords(self.elems['SHAPE'], self.bbox[0],self.bbox[3],x,self.bbox[1],self.bbox[2],self.bbox[3])               
            self.content.place(x=int(x-0.28*w),y=int(y-0.28*h),width=int(0.56*w),height=int(0.56*h))


        for arrow in self.arrows_in + self.arrows_out:
            arrow.fit_block_connections()
            arrow.fit_description()


#************************************************************************


    def sync_content_to_text_and_header (self):
    
        if 'content' in vars(self):
            header = self.content.get("1.0",tkinter.END)
            text   = ""
            m = re.search(r"^(.*?)\n(.*)$",header,re.DOTALL)
            if m:
                header = m.group(1)
                text   = m.group(2)
            if not re.search(r"^[a-z][a-zA-Z\_0-9]+$",header):
                return(-1)                   #   not a valid header
            try:
                exec(text)
            except:
                return(-1)                   #   no valid program code
            self.header = header
            self.text   = text
            return(1)                        #   self.content successful synced
            
        return(0)                            #   no self.content variable
                

#************************************************************************

    def get_shape_connection_point (self,p1):

        '''
        Computes the point on the the border of the surrounding shape of the block
        which connects an outer point p to the block
        '''

        p = [ min(max(self.bbox[0], p1[0]), self.bbox[2]), min(max(self.bbox[1], p1[1]), self.bbox[3]) ]

        
        #  p2: touches the bounding box. This basic point has to be extended into the bounding box depending on the shape:


        if not self.shape in "rs":
            x  = (self.bbox[0]+self.bbox[2])/2
            y  = (self.bbox[1]+self.bbox[3])/2
            p2 = p[:]
            if p2[0] == p1[0]:
                p2[1] = y
            if p2[1] == p1[1]:
                p2[0] = x

        if self.shape in "iwfm":    #   diamond
         
            fac = 1
            if p1[0] < x:
                p3 = [self.bbox[0],y]
            else:           
                p3 = [self.bbox[2],y]
                fac = -fac
            if p1[1] < y:
                p4 = [x,self.bbox[1]]
            else:           
                p4 = [x,self.bbox[3]]
                fac = -fac

            try:
                m = ( p4[0] - p2[0] + fac * (p4[1] - p2[1]) ) / ( p1[0] - p2[0] + fac * (p1[1] - p2[1]) ) 
                p = [ p1[0] * m + p2[0] * (1-m), p1[1] * m + p2[1] * (1-m) ]
            except:  # in this case, the outer point points to the closest edge 
                pass

        elif self.shape in "ce":   #   circle
         
            a  = (p1[0]-p2[0])**2 + (p1[1]-p2[1])**2   #  a * m*m - 2 * b * m + c = 0, quadratic equation to solve  
            b  = (p1[0]-p2[0])*(x-p2[0]) + (p1[1]-p2[1])*(y-p2[1])
            c  = (x-p2[0])**2 + (y-p2[1])**2 - ((self.bbox[0]-self.bbox[2])/2)**2

            try:
                m = ( b + (b**2 - a*c)**0.5 ) / a
                p = [ p1[0] * m + p2[0] * (1-m), p1[1] * m + p2[1] * (1-m) ]
            except:  # in this case, the outer point points to the most west, east, north or south point of the circle 
                pass

        elif self.shape in "t":   #   triangle
         
            if p1[1] > self.bbox[3]:     #   point is underneath the bottom of the triangle.
                pass                     #   Nothing to do -> the same behaviour as in rectangle shape mode
            else:
                p3 = [x,self.bbox[1]]
                if p1[0] < x:
                    p4 = [self.bbox[0],self.bbox[3]]
                else:           
                    p4 = [self.bbox[2],self.bbox[3]]

                a = (p2[0]-p4[0])*(p3[1]-p4[1]) - (p2[1]-p4[1])*(p3[0]-p4[0]) 
                b = (p2[0]-p1[0])*(p3[1]-p4[1]) - (p2[1]-p1[1])*(p3[0]-p4[0])
            
                try:
                    m = a / b
                    p = [ p1[0] * m + p2[0] * (1-m), p1[1] * m + p2[1] * (1-m) ]
                except:  # in this case, the outer point points to the closest edge 
                    pass
                    
        return(p)


#************************************************************************

    def gridpos (self,i=None,j=None):



  #      if 'newbbox' in vars(self):
  #          return(tuple(self.ij))
        px = (1-self.canvas.snap['OBJX']) * self.bbox[0] + self.canvas.snap['OBJX'] * self.bbox[2]
        py = (1-self.canvas.snap['OBJY']) * self.bbox[1] + self.canvas.snap['OBJY'] * self.bbox[3]
        if not i:
            i = int((px - self.canvas.griddata['OFFSETX'] + (0.5+self.canvas.snap['GRIDX'])*self.canvas.griddata['X'])/self.canvas.griddata['X'])
            j = int((py - self.canvas.griddata['OFFSETY'] + (0.5+self.canvas.snap['GRIDY'])*self.canvas.griddata['Y'])/self.canvas.griddata['Y'])
        x = self.canvas.griddata['OFFSETX'] + (i + self.canvas.snap['GRIDX']) * self.canvas.griddata['X'] 
        y = self.canvas.griddata['OFFSETY'] + (j + self.canvas.snap['GRIDY']) * self.canvas.griddata['Y']

        if self.shape == "a":
            self.newbbox = self.bbox[:]
        else:
            self.newbbox = [ self.bbox[0] + (x-px), self.bbox[1] + (y-py), self.bbox[2] + (x-px), self.bbox[3] + (y-py) ]

        self.ij      = [i,j]

        return(i,j)

#************************************************************************

    def get_varlen (self):
    
        '''
        Gives the maximal length of variable names.
        Given as a value lower than 0 if no arrows exist where
        the block is target. E.g. if the block is the starting node.
        '''
    
        maxv = 5
        for textline in self.graphcanvas.itemcget(self.text,'text').split("\n"):
            m = re.search(r"^(.*?)[ \=]",textline)
            if m:
                maxv = max(maxv,len(m.group(1)))
        
        if not self.arrows_out:
            maxv = -maxv
            
        return(maxv)

#************************************************************************

    def get_vars (self):
    
        '''
        Gives the variables with their actual values.
        '''
        block  = [ self.graphcanvas.itemcget(self.fkt,'text') ]   #hier stand: self.header  collecting block informations
        m = re.search(r"^ *(.*?)( *\/ *)(.*?) *$",block[0])
        if m:
            block = [ m.group(1), m.group(3) ]
        coords = self.bbox
        block.append( "%3.1f" % ((coords[0]+coords[2])/2) )
        block.append( "%3.1f" % ((coords[1]+coords[3])/2) )
        block.append( "%3.1f" % (coords[2]-coords[0]) )
        block.append( "%3.1f" % (coords[3]-coords[1]) )

        varsval  = [ ['BLOCK',block] ]

        varsval1 = {}        #  collecting other visible variables
        for textline in self.graphcanvas.itemcget(self.text,'text').split("\n"):
            m = re.search(r"^(.*?)( *\= *)(.*?) *$",textline)
            if m:
                varsval1[m.group(1)] = m.group(3)
        varsval1_keys = list(varsval1.keys())
        varsval1_keys.sort()
        for item in varsval1_keys:
            varsval.append([item,varsval1[item]])
            
        jump = {}           #   collecting infos where to jump:
        for arrow in self.arrows_out: 
            jumpinfo = [ self.graphcanvas.itemcget(arrow.text,'text') ]
            for arrowline in arrow.arrowlines[1:]:
                for c in self.graphcanvas.coords(arrowline)[:2]:
                    jumpinfo.append("%3.1f" % c)
            jump[arrow.target_block] = jumpinfo
                
        varsval.append( ['JUMP',jump] )
            
        return(varsval)

#************************************************************************

    def bounding_box (self,extbox=None):
    
        '''
        Returns the bounding box of the block.
        If an optional 4-elem array is given, this
        will be extended to the bounding box.
        ''' 

        if extbox == None:
            extbox = []

        if len(extbox) == 0:
            extbox.append(self.bbox[0])
            extbox.append(self.bbox[1])
            extbox.append(self.bbox[2])
            extbox.append(self.bbox[3])
        else:
            extbox[0] = min(extbox[0],self.bbox[0])
            extbox[1] = min(extbox[1],self.bbox[1])
            extbox[2] = max(extbox[2],self.bbox[2])
            extbox[3] = max(extbox[3],self.bbox[3])

        return(extbox)

#************************************************************************

    def press_button (self,event=[]):

        if type(event) == type([]):  #  Testschnittstelle
            try:
                self.x0 = event[0]
            except:
                self.x0 = self.bbox[0] + self.bbox[2]/2
            try:
                self.y0 = event[1]
            except:
                self.y0 = self.bbox[1] + self.bbox[3]/2
            (self.x1,self.y1) = (self.x0,self.y0)
        else:
            (self.x0,self.y0) = (event.x,event.y)
            (self.x1,self.y1) = (event.x_root,event.y_root)

        

        self.graphcanvas.configure(cursor='sizing')    #  Alternative mouse pointers: arrow circle 
                                                       #  clock cross dotbox exchange fleur heart
        self.resize_box            = ""                #  man mouse pirate plus shuttle sizing spider
        self.move_blocks           = []                #  spraycan star target tcross trek watch
        self.move_arrows           = {}
        self.move_arrowlines_start = {}
        self.move_arrowlines_end   = {}
        self.bbox_press            = self.bbox[:]
        self.w                     = self.bbox[2] - self.bbox[0]
        self.h                     = self.bbox[3] - self.bbox[1]

        if self.shape in "ars":

            if abs(self.y0 - self.bbox[3]) < 4:             #  if pressing point is near the border of the box
                 self.resize_box = self.resize_box + "S"    #  mark the direction for resizing
            if abs(self.y0 - self.bbox[1]) < 4: 
                 self.resize_box = self.resize_box + "N"
        
        if self.shape in "rs":
            if abs(self.x0 - self.bbox[0]) < 4:
                 self.resize_box = self.resize_box + "W"
            if abs(self.x0 - self.bbox[2]) < 4: 
                 self.resize_box = self.resize_box + "E"


        if self.resize_box == "" and self.shape == "a":  #  Shifting a swimlane means also shifting all blocks in its area 
        
            (self.move_blocks,self.move_arrows,self.move_arrowpoints) = self.blocks_and_arrows_in_swimlane()
            for block in self.canvas.blocks:
                if not self == block and block.shape == "a":
                    (block.move_blocks,block.move_arrows,block.move_arrowpoints) = block.blocks_and_arrows_in_swimlane()

        self.last_event = 1

        return "break"

#**********************************************************

    def blocks_and_arrows_in_swimlane (self,mode=0):   #  Returns the blocks which are in the swimlane if i am swimlane
        
        erg = []
        for block in self.canvas.blocks:
            if self.bbox[1] <= block.bbox[1] <= self.bbox[3]:
                if not block.shape == "a":
                    erg.append(block)
        
        arrows = []
        for block in erg:
            for arrow in block.arrows_in:
                if arrow.source_block in erg:
                    arrows.append(arrow)
                    
        if mode > 0:
            return(arrows)

        exclude_arrows = self.arrows_covered_by_some_swimlane()

        singlepoints = []
        for block in self.canvas.blocks:
            for arrow in block.arrows_in:
                if not arrow in exclude_arrows:
                    zaehler = 0
                    for arrowline in arrow.arrowlines:
                        coords = self.graphcanvas.coords(arrowline)
                        for i in (0,2):
                            if self.bbox[1] <= coords[i+1] <= self.bbox[3]:
                                singlepoints.append([arrow,zaehler,i])
                        zaehler = zaehler + 1
                                                            
        return(erg,arrows,singlepoints)
			 
#**********************************************************		

    def arrows_covered_by_some_swimlane (self):
    
        erg = []
        for swimlane in self.canvas.blocks:
            if swimlane.shape == "a":
                erg = erg + swimlane.blocks_and_arrows_in_swimlane(1)
                pass
        return(erg)

#**********************************************************

    def blocks_in_swimlane (self,mode=0):   #  Returns the blocks which are in the swimlane if self is a swimlane
    
        if not self.shape == "a":
            return([])
            
        erg = { 'BLOCKS':           [],    #  Blocks in the swimlane
                'ARROWLINES_BEGIN': {},    #  Starting arrow lines in the swimlane
                'ARROWLINES_END'  : {},    #  Ending arrow lines in the swimlane
                'ARROWS'          : {} }   #  Arrows from one block in the swimlane to another
               
        sub_swimlanes = []
        for block in self.canvas.blocks:
            if self.bbox[1] <= block.bbox[1] <= self.bbox[3]:
                if self.bbox[0] <= block.bbox[0]:
                    if not block.shape == "a":
                        erg['BLOCKS'].append(block)
                    elif not block == self and ( not self.bbox[0] == block.bbox[0] or
                                                 self.bbox[1] < block.bbox[1]      or
                                  ( self.bbox[1] == block.bbox[1]   and self.bbox[3] < block.bbox[3] ) ):
                            sub_swimlanes.append(block)

        for block in erg['BLOCKS']:
            for arrow in block.arrows_in + block.arrows_out:
                erg['ARROWS'][arrow] = 1
                
                for arrowline in arrow.arrowlines:
                    coords = self.graphcanvas.coords(arrowline)
                    
                    bed1   = arrow in block.arrows_in  and arrow.source_block in self.move_blocks
                    bed2   = arrow in block.arrows_out and arrow.target_block in self.move_blocks
                    if bed1 or bed2 or self.bbox[1] < coords[1] and coords[1] < self.bbox[3]:
                        erg['ARROWLINES_BEGIN'][arrowline] = 1
                    if bed1 or bed2 or self.bbox[1] < coords[3] and coords[3] < self.bbox[3]:
                        erg['ARROWLINES_END'][arrowline] = 1
                    
                    for arrow in block.arrows_out:
                        erg['ARROWLINES_BEGIN'][arrow.arrowlines[0]] = 1
                    for arrow in block.arrows_in:
                        erg['ARROWLINES_END'][arrow.arrowlines[-1]] = 1

        return(erg)


        self.last_event = 1


#**********************************************************

    def double_click_button (self,event):

        (self.x0,self.y0) = (event.x,event.y)
        (self.x1,self.y1) = (event.x_root,event.y_root)
        self.last_event   = 2
        return "break"

#****************************************************

    def release_button (self,event=None):

          
        if (abs(self.bbox[0] - self.bbox_press[0]) + abs(self.bbox[1] - self.bbox_press[1]) +
            abs(self.bbox[2] - self.bbox_press[2]) + abs(self.bbox[3] - self.bbox_press[3]) > 10):
            self.last_event = 4

        if self.shape == "a" and self.last_event ==3: #before: in (3,4):  old version creates error with changing size of the swimlane
            self.canvas.rearr_swimlane(0.2)
            
        if self.last_event in (1,3):

            self.resize_box = ""
            self.graphcanvas.configure(cursor='arrow')

            if self.canvas.hl_block == self:
                self.syntax_error = 0
            if not self.canvas.hl_block == None:
                if self.canvas.hl_block.sync_content_to_fkt_and_text() == -1:
                    if not self.canvas.hl_block == self:
                        self.canvas.hl_block.syntax_error = 1
                        return()
                self.canvas.hl_block.syntax_error = 0
            bed = None
            if not self.canvas.hl_block == self:  #  if I am not yet highlighted, un-highlight the former highlighted block
                self.canvas.hl_block_0 = self.canvas.hl_block  #  and set it to the last highlighted block,
                self.canvas.hl_block   = self                  #  and set myself to highlighted
                self.hl_arrow          = None
                for arrow in self.arrows_in:                           #   now check all incoming arrows. The one where its
                    if arrow.source_block == self.canvas.hl_block_0:   #   source_block is the last highlighted block,
                        self.hl_arrow = arrow                          #   has also to be highlighted
                if False and self.hl_arrow == None:   ##  DISABLED         #   check also inverted direction
                    for arrow in self.arrows_out:            
                        if arrow.target_block == self.canvas.hl_block_0:  
                            self.hl_arrow = arrow                             
                self.highlight_block(0)
            else:
                self.syntax_error = 0


        elif self.last_event == 2:    #  last event was a double click
            self.canvas.create_arrow()

        elif self.canvas.griddata['SNAP']:
            self.canvas.rearr_grid(0.2)
        else:
            self.canvas.rearr_grid(0.2,1)

        self.last_event = 1
        return "break"

#****************************************************

    def highlight_block (self,nr,mode=0):    #   mode == 1: blinking

        fillcolor1 = [procpy.config.COLOR_HIGHLIGHT_ALT[0],procpy.config.COLOR_HIGHLIGHT_ALT[0],

                      procpy.config.COLOR_HIGHLIGHT[0],procpy.config.COLOR_HIGHLIGHT[0]
                     ][nr+mode]

        
        self.graphcanvas.itemconfig(self.elems['SHAPE'],fill=fillcolor1)
        if 'content' in vars(self):
            self.content.config(bg=fillcolor1,highlightcolor=fillcolor1)
           
            self.contentframe.config(background=fillcolor1,bg=fillcolor1,highlightcolor=fillcolor1)

        if self.hl_arrow:
            fillcolor2 = [procpy.config.COLOR_HIGHLIGHT[0],self.color,self.color,self.color][nr+mode]
            if len(self.canvas.blocks) < 6:
#                fillcolor2 = fillcolor1
                fillcolor2 = procpy.config.COLOR_HIGHLIGHT[0]
            self.hl_arrow.highlight(fillcolor2)
        else:
            if 'content' in vars(self):
                if self.content.cget('state') == tkinter.DISABLED:
                    self.content.config(state=tkinter.NORMAL)
                    self.content.focus_set()
                    self.content.mark_set("insert",tkinter.END)
        

        if self.sync_content_to_fkt_and_text() == -1:

            self.syntax_error = 1
        else:
            self.syntax_error = 0

        delay = -nr
        if self.canvas.hl_block == self:
            delay = 180 + mode*120
        if delay > -1:
            self.canvas.loopobj.after(delay,self.highlight_block,1-nr,2*self.syntax_error)
        else:
            self.graphcanvas.itemconfig(self.elems['SHAPE'],fill=self.color)
            if 'content' in vars(self):
                self.content.config(bg=self.color,highlightcolor=self.color)

                self.contentframe.config(background=self.color,bg=self.color,highlightcolor=self.color)

            if self.hl_arrow:
                self.hl_arrow.highlight()
                self.hl_arrow = None
            if 'content' in vars(self):
                self.content.config(state=tkinter.DISABLED)
        
#************************************************************************

    def move_mouse (self,event):
 
        dx = event.x_root - self.x1
        dy = event.y_root - self.y1

        self.last_event = 3

        if self.resize_box == "":
            self.move(dx,dy)
        else:
            self.resize(dx,dy)

        self.x1 = event.x_root
        self.y1 = event.y_root
        return "break"

#****************************************************

    def xxmove (self,dx,dy):

        if ( self.bbox[0]+dx < 0 or False and self.bbox[2]+dx > self.graphcanvas.winfo_width() or
             self.bbox[1]+dy < 0 or False and self.bbox[3]+dy > self.graphcanvas.winfo_height() ) :
            return()    #  keine gute Loesung, um zu verhindern, dass die Objekte aus dem Zeichenbereich
                        #  gehen. Insbesondere die rechte und untere Grenze wird mit dem obigen Code
                        #  beim Scalen zu stark geschuetzt. Hier muss eine bessere Loesung her. Am besten
                        #  waere es, den Mauszeiger auf das Gebiet des graphcanvas zu beschraenken, das scheint
                        #  aber schwierig zu sein.  --> task_001
                        

        if self.shape == "a":
            bed                = False
            depending_swimlane = None   #  the depending swimlane also to have been moved (when a block or ancesters block is highlighted)
            for swimlane in self.canvas.swimlanes:
                if swimlane == self or not swimlane.shape == "a":
                    continue
                if (swimlane.bbox[1] < self.bbox[1] < swimlane.bbox[3] or swimlane.bbox[1] < self.bbox[3] < swimlane.bbox[3]
                      or self.bbox[1] < swimlane.bbox[1] < self.bbox[3] or self.bbox[1] < swimlane.bbox[3] < self.bbox[3]):
                    if move_as_a_depending_swimlane or self == self.canvas.hl_block:
                        if (swimlane.bbox[1] - self.bbox[1]) * dy > 0:
                            if move_as_a_depending_swimlane or self == self.canvas.hl_block:
                                depending_swimlane = swimlane
                                bed     = True
                            break
                    else:
                        bed     = True   #  block intersection
                        break
                        
            if bed:
                if depending_swimlane:
                    depending_swimlane.move(dx,dy,1)
                elif self.bbox[0] == 0:
                    self.bbox[0] = self.bbox[0] + self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
                    self.bbox[2] = self.bbox[2] + self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
            else:
                if not self.bbox[0] == 0:
                    self.bbox[0] = self.bbox[0] - self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
                    self.bbox[2] = self.bbox[2] - self.canvas.zoom_factor * procpy.config.SWIMLANE_WIDTH
      

        self.bbox[1] = self.bbox[1] + dy
        self.bbox[3] = self.bbox[3] + dy


        if not self.shape == "a":
            self.bbox[0] = self.bbox[0] + dx
            self.bbox[2] = self.bbox[2] + dx
        else:
            for block in self.move_blocks:
                block.move(0,dy)
            for arrow in self.move_arrows:
                arrow.move(0,dy)
            for point in self.move_arrowpoints:
                arrow       = point[0]
                arrowline   = arrow.arrowlines[point[1]]
                coords      = self.graphcanvas.coords(arrowline)
                coords[point[2]]   = coords[point[2]]   + 0
                coords[point[2]+1] = coords[point[2]+1] + dy
                self.graphcanvas.coords(arrowline,tuple(coords))
                arrow.fit_description() 

        self.fit_content()

#**********************************************************

    def resize (self,dx,dy):


        if   re.search(r"N",self.resize_box):
            self.bbox[1] = self.bbox[1] + dy
        elif re.search(r"S",self.resize_box):
            self.bbox[3] = self.bbox[3] + dy
        if   re.search(r"W",self.resize_box):
            self.bbox[0] = self.bbox[0] + dx
        elif re.search(r"E",self.resize_box):
            self.bbox[2] = self.bbox[2] + dx
         
        self.fit_content(self.shape)

        for arrow in self.arrows_in + self.arrows_out:
            arrow.fit_block_connections()
            arrow.fit_description()
	
    def __repr__(self):
        return repr(self.arrows_in)+'-->['+repr(self.bbox)+']'+'--> '+repr(self.arrows_out)+'['+repr(self.elems)+']'

#****************************************************


bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped)
Email: contact@elmoujehidin.net bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped) Email: contact@elmoujehidin.net