Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /home/ift/52_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/ift/52_procpy/dataninja/graphmodel.py

#   coding:  utf8

import os,re,sys,time,math,random,tkinter,codecs,procpy

import procpy.block
import procpy.swimlane
import procpy.arrow
import procpy.rearr_grid
import pdb	
import procpy.procobj

try:
    import tkinter.ttk,Pmw,xmltodict,json,svgwrite  #  ,tkintertable
except:
    import pip
    pip.main(["install","pyttk"])
    pip.main(["install","Pmw"])
#    pip.main(["install","tkintertable"])
    pip.main(["install","xmltodict"])
    pip.main(["install","json"])
    pip.main(["install","svgwrite"])
    import tkinter.ttk,Pmw,xmltodict,json,svgwrite  #  ,tkintertable

import tkinter.filedialog
import tkinter.font

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

class Graphmodel (tkinter.Canvas):

    def __init__ (self,graphproc,*pars,**args):
    
        '''
        The class procpy.graphmodel.Graphmodel provides a Tkinter.Canvas which contains
        blocks and arrows. A special kind of blocks are swimlanes.

        Blocks can be highlighted.

        '''

        tkinter.Canvas.__init__(self,*pars,**args)
        self.config(background="white")

        self.bind("<Button-1>",        self.unhighlight_block)
        self.bind("<ButtonRelease-1>", self.release_button_event)
        self.bind("<B1-Motion>",       self.move_mouse_event)

        self.blocks             = []
        self.swimlanes          = []
        self.blockwidth         = args.setdefault('blockwidth',     70)
        self.blockheight        = args.setdefault('blockheight',    40)
        self.swimlane_width     = args.setdefault('swimlane_width', 15)
        self.zoom_factor        = 1
        self.hl_block           = [None,None,None]  # the high-lighted block, with history, contains None's or block objects
        self.graphproc          = graphproc         #  The calling widget, typically a Tkinter.Frame
        self.config(scrollregion = (0,0,3000,1000))
        self.hidden             = 0
        self.last_pressed       = -100   #   for computing doubleclicks

        self.wait_for_doubleclick_in_milliseconds = int(1000*procpy.config.WAIT_FOR_DOUBLECLICK)

        self.set_background_image(procpy.config.FILENAME)


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

    def mark (self,remark=""):
    
        t = time.clock()
        if 't0' in vars(self):
            print ( ("%9.2f" % ((t-self.t0)*1000)) + " ms for:  " + remark )
        self.t0 = t

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

    def hide (self,nr):

        nr = nr - self.hidden
        self.delete("reportitem")
        if not nr == 0:
            self.move("all",nr*99999,nr*99999)
            self.hidden = (nr+1)/2 

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

    def create_block_event (self,event):   #  the double mouseclick callback event

        overlapping_elements = self.find_overlapping(event.x,event.y,event.x,event.y)
        if overlapping_elements:
            for overlapping_element in overlapping_elements:
                if not self.type(overlapping_element) == "image":
                    return()

        x0 = self.canvasx(event.x) - 0.5 * self.blockwidth  * self.zoom_factor
        x1 = self.canvasx(event.x) + 0.5 * self.blockwidth  * self.zoom_factor
        y0 = self.canvasy(event.y) - 0.5 * self.blockheight * self.zoom_factor
        y1 = self.canvasy(event.y) + 0.5 * self.blockheight * self.zoom_factor

        self.create_block(x0,y0,x1,y1)


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

    def create_block (self,x0,y0,x1,y1):

#        if not self.new_block_is_possible():
#            return()

        self.after(self.wait_for_doubleclick_in_milliseconds,self.highlight_block,None)  #  wait: maybe we had a double-click
            
        if x0 < 0:  #  if the block creating event is very much at the left side
            w = self.swimlane_width * self.zoom_factor
            self.swimlanes.append(procpy.swimlane.Swimlane(self,[0,y0,w,y1]))
        else:
            self.blocks.append(procpy.block.Block(self,[x0,y0,x1,y1]))

        self.rearr_grid(procpy.config.MOVESPEED)
        
#***************************************************************************************        

    def xxnew_block_is_possible (self):

        if not self.blocks:   #   create the start block
            return(True)

        if self.hl_block[0]:   #   there is a highlighted block
            if self.hl_block[0].syntax_error() == 1:
                return(False)
            else:
                return(True)
        else:
            return(False)
            
#***************************************************************************************        
        
    def compute_block_level (self,loop_arrows=set(),block_to_delete=None):

        self.mark("start compute block level...")

        self.loop_arrows = loop_arrows

        zaehler = 1
        while (0 == 0):    #   run repeatingly, reducing looping arrows

            self.delete("debug")
            touched_blocks = []

            for block in self.blocks:
                block.nr   = 0
                block.level = []
                if len( set(block.arrows_in) - self.loop_arrows ) == 0:
                    if not block == block_to_delete:
                        touched_blocks.append(block)

            zaehler = 1        
            for block in touched_blocks[:]:
                if not block.compute_level(touched_blocks,zaehler):
                    return(False)
                zaehler = zaehler + 1
                

            loop_found = False
            for block in self.blocks:
             
                if not block.nr == 0:    #   investigate the blocks which could not be numbered, because
                    continue             #   predecessors where not be numbered
                
#                for arrow in block.arrows_out:        #  check all the arrows going out of the block.
#                    print ("LOOP",arrow,arrow.target_block.nr)
#                    if arrow.target_block.nr > 0:     #  if an arrow is connected to a numbered block,
#                        self.loop_arrows.add(arrow)   #  then it has to be treated as an loop-building arrow
#                        loop_found = True
                arrows_loop = set()
                arrows_tied = set()

                for arrow in ( set(block.arrows_in) - self.loop_arrows):   #   check whether there are incoming
                    if arrow.source_block.nr == 0:                         #   arrows coming from numbered blocks
                        arrows_loop.add(arrow)                             #   AND from unnumbered blocks
                    else:
                        arrows_tied.add(arrow)

                if len(arrows_loop) > 0 and len(arrows_tied) > 0:   
                    for arrow in arrows_loop:
                        if arrow.check_loop():
                            self.loop_arrows.add(arrow)
                            loop_found = True

            if not loop_found:
                break

#            print (zaehler," <---")
            zaehler = zaehler + 1
            
        self.mark("end compute block nr...")
        
        return(True)

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

    def highlight_block (self,block):

        if False and self.hl_block[1] == block and self.hl_block[0] == None:   ##  DISABLED
            print("BLIND CODE EXECUTED: 22222")
#            self.hl_block.pop(0)                                  
#            self.hl_block.insert(-1,None)
#        else:     #   shift to the right, normal behaviour
        self.hl_block.pop(-1)
        self.hl_block.insert(0,block)

#************************************************************************************
        
    def unhighlight_block (self,event):

        timeclock = time.clock()
        if timeclock - self.last_pressed < procpy.config.DOUBLECLICK:
            self.create_block_event(event)
            self.last_pressed = -100
            return()

        if not self.find_overlapping(event.x,event.y,event.x,event.y):
            self.highlight_block(None)
            
        self.last_pressed = timeclock

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

    def create_arrow (self):

        if self.hl_block[0] and self.hl_block[0].syntax_error() == 1:
            return()

        fkt  = None   #   find out the source (fkt) and target (jump) block
        jump = None
        for block in self.blocks:
            if not fkt  and block == self.hl_block[1]:
                fkt  = block
            if not jump and block == self.hl_block[0]:
                jump = block
            if fkt and jump:
                break
        
        if not fkt:
            fkt = jump
        if jump:
            if fkt:
                create_the_arrow = True

                if fkt == jump:    #   don t create the arrow if source and target are identical
                    create_the_arrow = False

                for arrow in fkt.arrows_out:        #  check all the out arrows from fkt whether there
                    if arrow.target_block == jump:  #  is already an arrow between fkt and jump. in case
                        create_the_arrow = False    #  don t provide any new arrow
                        break

                if create_the_arrow:

                    jump.hl_arrow      = procpy.arrow.Arrow(0,self,fkt,jump)
                    keep_the_new_arrow = self.compute_block_level()

                    if keep_the_new_arrow:
                        jump.fit_shape()
                        fkt.fit_shape()
                        self.rearr_grid(procpy.config.MOVESPEED)
                        for arrow in self.loop_arrows:
                            arrow.color = procpy.config.LOOPARROWCOLOR
                    else:
                        jump.hl_arrow.destroy()
                        jump.hl_arrow = None
                        self.compute_block_level()
                else:
                    self.highlight_block(None)
                    return()

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

    def xxfind_loop_start (self,end_loop):

        list1 = end_loop.all_blocks_before()
        list2 = end_loop.all_blocks_after()

        common = [x for x in list1 if x in list2]
        loop_start = [x for x in common if len(x.arrows_out) >= 2]

        return loop_start[0]

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

    def assign_elements_to_swimlanes (self):
    
        self.swimlanes.sort(key=lambda swimlane: swimlane.bbox[3])  #  order vertically
        
        topline = 0
        for swimlane in self.swimlanes:

            bottomline                = swimlane.bbox[3]
            swimlane.move_blocks      = []
            swimlane.move_arrowpoints = []

            for block in self.blocks:
                if topline <= block.bbox[1] < bottomline:
                    swimlane.move_blocks.append(block)

                for arrow in block.arrows_in:
                    zaehler = 0
                    for arrowline in arrow.arrowlines:
                        coords = self.coords(arrowline)
                        for i in (0,2):
                            if topline <= coords[i+1] < bottomline:
                                swimlane.move_arrowpoints.append([arrow,zaehler,i])
                        zaehler = zaehler + 1

            topline = bottomline

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

    def run_process (self,notifier=None):

        print("PROCESS_START")
        self.process_runs   = 1
        self.prgvars        = {}
        self.running_blocks = 0
        self.notifier       = notifier
        
        for block in self.starting_blocks():
            if not block in self.swimlanes:
                block.token = [ self.new_token() ]
                self.running_blocks += 1
                self.after(0,block.run)

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

    def end_process (self):
    
        print("PROCESS_END")
        self.repeats = self.repeats - 1
        if self.notifier:
            self.after(0,self.notifier.notify())
        if self.repeats > 0:
            self.after(0,self.run_process,self.notifier)
        else:
            del self.process_runs


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

    def move_mouse_event (self,event):
        
        if 'x0' in vars(self):

            (dx,dy) = (event.x-self.x0,event.y-self.y0)
            if self.i0 > 0:  #  changing of the grid dimensions
                (xquot,yquot) = (1.0/(self.x0-self.griddata['OFFSETX']),1.0/(self.y0-self.griddata['OFFSETY']))
            else:    #   changing of the offstes
                (dx_rel,dy_rel) = (dx,dy)
                
            for line in self.grid_lines:
                coords = self.graphcanvas.coords(line)
                if   coords[0] == coords[2]:  #  vertical line
                    if self.i0 > 0:
                        dx_rel = dx * (coords[2]-self.griddata['OFFSETX']) * xquot
                    self.graphcanvas.coords(line,coords[0]+dx_rel,coords[1],coords[2]+dx_rel,coords[3])
                elif coords[1] == coords[3]:  #  horizontal line
                    if self.j0 > 0:
                        dy_rel = dy * (coords[3]-self.griddata['OFFSETY']) * yquot
                    self.graphcanvas.coords(line,coords[0],coords[1]+dy_rel,coords[2],coords[3]+dy_rel)

            (self.x0,self.y0) = (event.x,event.y)

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

    def release_button_event (self,event):

        if self.find_overlapping(event.x,event.y,event.x,event.y):
            return()

        if self.hl_block[0] and self.hl_block[0].syntax_error() == 1:
            return()

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

    def xxrelease_line (self,event):

        if self.i0 == 0:
            self.griddata['OFFSETX'] = event.x
            self.griddata['OFFSETY'] = event.y
        else:
            self.griddata['X'] = (event.x - self.griddata['OFFSETX'])/self.i0
            self.griddata['Y'] = (event.y - self.griddata['OFFSETY'])/self.j0
        del self.x0
        del self.i0
        del self.y0
        del self.j0

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

    def delete_highlighted_element (self,event=None):

        if self.hl_block[0]:

            arrow = self.hl_block[0].hl_arrow
            
            if arrow:   #  delete arrow
                if self.compute_block_level(set([arrow])):
                    fkt  = arrow.source_block
                    jump = arrow.target_block
                    arrow.destroy()
                    fkt.fit_shape()
                    jump.fit_shape()
                    self.highlight_block(None)
            else:       #  delete block
                block_arrows = set( self.hl_block[0].arrows_in ) | set( self.hl_block[0].arrows_out )
                if self.compute_block_level(block_arrows,self.hl_block[0]):
                    self.hl_block[0].destroy()
                    self.blocks.remove(self.hl_block[0])
                    self.highlight_block(None)

            self.compute_block_level()

            for block in self.blocks:
                for arrow in block.arrows_out:
                    if arrow in self.loop_arrows:
                        if arrow.color == 'black':
                            arrow.color = procpy.config.LOOPARROWCOLOR
                            arrow.highlight()
                    else:
                        if arrow.color == procpy.config.LOOPARROWCOLOR:
                            arrow.color = 'black'
                            arrow.highlight()

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

    def load (self,text):

        for line in text.splitlines():

            try: exec("self.obj_info_exec="+line)
            except: continue
           
            if self.obj_info_exec[0] == "Block":
                # this part is for compatibility reasons (old saving concept); can be removed,
                # when all files are saved including block.looping
                if len(self.obj_info_exec)==3:
                    self.obj_info_exec.append(0)
                elif isinstance(self.obj_info_exec[3],str):
                    self.obj_info_exec.append(self.obj_info_exec[3])
                    self.obj_info_exec[3] = 0

                self.blocks.append(procpy.block.Block(self,self.obj_info_exec[1],self.obj_info_exec[2],self.obj_info_exec[3]))
                try:
                    self.blocks[-1].content.config(state=tkinter.NORMAL)
                    self.blocks[-1].content.insert("1.0",self.obj_info_exec[4])
                    self.content.config(state=tkinter.DISABLED)
                except:
                    pass
            elif self.obj_info_exec[0] == "Swimlane":          
                self.swimlanes.append(procpy.swimlane.Swimlane(self, self.obj_info_exec[1], self.obj_info_exec[2]))
                try:
                    self.swimlanes[-1].content.config(state=tkinter.NORMAL)
                    self.swimlanes[-1].content.insert("1.0",self.obj_info_exec[3])
                    self.content.config(state=tkinter.DISABLED)
                except:
                    pass
            elif self.obj_info_exec[0] == "Arrow":

                source = self.blocks[int(self.obj_info_exec[1])]
                target = self.blocks[int(self.obj_info_exec[2])]
                procpy.arrow.Arrow(0,self,source,target,cond_string=self.obj_info_exec[3],cond_pos=self.obj_info_exec[4],
                                     cond_anchor=self.obj_info_exec[5],arrow_points=[item for sublist in self.obj_info_exec[6] for item in sublist])

        self.compute_block_level()


#        self.rearr_grid(0.0)


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

    def save (self): 

        text = ""

        # Auslesen der Bloecke
        for block in self.blocks:
            text = text + str(["Block"] + block.dump()) + "\n"

        # Auslesen der Swimlanes
        for block in self.swimlanes:
            text = text + str(["Swimlane"] + block.dump()) + "\n"

        # Auslesen der Pfeile
        for block in self.blocks:
            for arrow in block.arrows_out:
                text = text + str(["Arrow"] + arrow.dump()) + "\n"
                
        return text

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

    def new_token (self):
    
        while (0 == 0):
            token = random.randint(100000000000000,900000000000000)
            if not token in self.tokens:
                self.tokens[token] = 0
                return(token)

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

    def name_blocks (self,export_list=False):

        block_names = {}
        counter = 0

        if export_list:
            self.blocks_by_names = {}

        for block in self.blocks:    #  First run through the blocks
            counter += 1
            rand    = random.randint(10,99)
            name    = "block"+str(counter)+str(rand)
            block_names[block]         = name
            if export_list:
                self.blocks_by_names[name] = block

        return(block_names)

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

    def starting_blocks (self):
    
        result = []
        for block in self.blocks:
            if len(block.arrows_in) == 0:
                result.append(block)
                
        return(result)

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

    def xxinitiate_class (self,classname):


        print("INITIATE_CLASS")
        text = '''

from random import randint

class ''' + classname + ''' ():


    def __init__ (self):
        self.JUMP = ''' + "['---FUNC---']" + '''
        
'''

        bed = True
        for block in self.blocks:
            if block.nr < 2 and bed: 
                starting_block = block
                text = re.sub(r"---FUNC---","Block"+str(self.blocks.index(block)),text) 
                if block.content.get("1.0",tkinter.END).strip():
                    text = "import " + block.content.get("1.0",tkinter.END).strip() + "\n" + text
                bed = False
      
        # add function for every block

        for block in self.blocks:    #  Second run through the blocks.
            text  = text + '''

    def ''' + "Block"+str(self.blocks.index(block)) + ''' (self):
        exec ( "\\n".join(map(lambda x: x + " = self." + x,self.__dict__.keys())) )
'''    #   this code is for getting all variables local

            
            if block.arrows_out:    # add jump blocks if existing
                text1 = "        JUMP = []\n"
                for arrow in block.arrows_out:
                    jump_name = "Block"+str(self.blocks.index(arrow.target_block))
                    jump_cond = arrow.text.get("1.0",'end-1c')
                    if (not jump_cond or jump_cond.isspace()) and len(block.arrows_out) == 1:
                        text1 = "        JUMP = '" + jump_name + "'\n"
                    else:
                        if jump_cond and not jump_cond.isspace():
                            text1 = text1 + "        if "+ jump_cond +":\n    " 
                        text1 = text1 + "        JUMP.append('" + jump_name + "')\n"
                        
                if block.looping == 2:
                    text2 = '''
        if len(JUMP)>1:
            no = random.randint(0,len(JUMP)-1)
        else:
            no = 0
        JUMP = JUMP[no]

'''
                    text1 = text1 + text2
                text = text + text1

            if block.arrows_in and len(block.arrows_in) > 1 and not block.looping==1:
                text = text + "        __WAIT__ = max(1,__WAIT__)\n"

            # add text (python code) of the block 

            if not block == starting_block:

                try:
                    text = text + "\n        exec ('''" + block.content.get("1.0",tkinter.END)+ "\n''')\n"
                except Exception as e:
                    pass
            print (text) 
#            text = text + "\n        print locals()\n\n"
            text = text + "\n        self.__dict__.update(locals())\n"
#            text = text + "\n        del self.self\n"

        text = re.sub(r"\"([\d\.]+)\"","\\1",text,999999)
        
        self.graphproc.storeproc.list_of_variables = {}   # Statically found variables with their possible aggregate functions
        
        open("model_prog.log","w").write(text)
        return(text)

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

    def parser(self,blocktext):
        '''
        makes the text of the block readable in the program context
        '''

        if not blocktext:
            return()

        text = ""
        for line in blocktext.splitlines():
            text0 = line.split("=")
            if not "self." in text0[0]:
                text0[0]="self."+ text0[0]
            text = text + "try:"+text0[0]+"+="+text0[1]+"\n"
            text = text + "except:"+text0[0]+"="+text0[1]+"\n"

        return text

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

    def xxnum_blocks (self,jump):    #   numerate a block

        self.num_blocks_0(jump,999999)   #  1.  set the block and all ancestors to highest level
        self.num_blocks_0(jump,0)        #  2.  now compute lower levels by arrows
        if jump.nr == 999999:
            self.num_blocks_0(jump,1)    #  3.  if jump.nr remains highest level, then number it with 1.

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

    def xxnum_blocks_0 (self,block,nr,touched_blocks={}):   #   determines the minimum level of a block

        for arrow in block.arrows_in:
            if nr == 0:
                nr = 999999
            nr = min(arrow.source_block.nr+1,nr)

        if not block in touched_blocks:
            touched_blocks[block] = block.nr
            block.nr              = nr
#            block.fit_content("x")
            for arrow in block.arrows_out:
                jump = arrow.target_block
                self.num_blocks_0(jump,min(nr+1,999999),touched_blocks)
                
#************************************************************************************

#    def check_whether_point_is_inside_of_a_block (self,x=-1,y=-1):
#    
#        '''
#        Returns the maximal width and height of all blocks,
#        if the point (x,y) is not inside of any block.
#        Otherwise it returns the fkt of the block.
#        '''
#        
#        bbox_w = 0
#        bbox_h = 0
#        
#        for block in self.blocks:
#            if block.bbox[0] < x and x < block.bbox[2] and block.bbox[1] < y and y < block.bbox[3]:
#                return(None,block)
#            bbox_w = max(bbox_w,block.bbox[2]-block.bbox[0])
#            bbox_h = max(bbox_h,block.bbox[3]-block.bbox[1])
#
#        return(bbox_w,bbox_h)        


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

    def xxtoggle_show_grid (self):
    
        if self.griddata['SHOW']:
        
            for line in self.grid_lines:
                self.graphcanvas.delete(line)
            self.grid_lines       = []
            self.griddata['SHOW'] = False
        
        else:

#            bbox = self.get_bounding_box()
            maxx = max(bbox[2],self.graphcanvas.winfo_width())
            maxy = max(bbox[3],self.graphcanvas.winfo_width())
            self.grid_lines = []
        
            x = self.griddata['X']
            while x < maxx:
                self.grid_lines.append(self.graphcanvas.create_line(x,0,x,maxy,width=1,fill="magenta",dash=(2,5)))
                x = x + self.griddata['X']
        
            y = self.griddata['Y']
            while y < maxy:
                self.grid_lines.append(self.graphcanvas.create_line(0,y,maxx,y,width=1,fill="magenta",dash=(2,5)))
                y = y + self.griddata['Y']

            for line in self.grid_lines:
                self.graphcanvas.tag_bind(line,"<ButtonPress-1>",   self.press_button)
                self.graphcanvas.tag_bind(line,"<B1-Motion>",       self.move_mouse)
                self.graphcanvas.tag_bind(line,"<ButtonRelease-1>", self.release_line)
            
            self.griddata['SHOW'] = True

        self.gui.switch_tab()        
        

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

    def xxgrid_select (self,l,event):

        (x,y) = self.check_whether_point_is_inside_of_a_block()
        if x:
            (self.gx,self.gy) = (event.x,event.y)
        else:
            self.gx = None    


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

    def xxgrid_move (self,event):

        dx = event.x - self.gx
        dy = event.y - self.gy

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

    def xxtoggle_snap_grid (self):
        if self.griddata['SNAP']:
            self.griddata['SNAP'] = False
        else:
            self.griddata['SNAP'] = True
        self.gui.switch_tab()        
                    
#************************************************************************************

    def xxfit_blocks_to_grid (self):

        g = self.griddata
        for block in self.blocks:
            x  = g['X'] * int((block.bbox[0] - g['OFFSETX'] + 0.5*g['X'])/g['X'])
            y  = g['Y'] * int((block.bbox[1] - g['OFFSETY'] + 0.5*g['Y'])/g['Y'])
            dx = block.bbox[0] - x - g['OFFSETX']
            dy = block.bbox[1] - y - g['OFFSETY'] 
            block.newbbox = [ block.bbox[0] - dx, block.bbox[1] - dy,
                              block.bbox[2] - dx, block.bbox[3] - dy ]

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

    def xxrearrange_blocks(self): # arranges block without overlap
        block_coordinates = []
        for block in self.blocks:
            i,j = block.gridpos()
            while self.check_gridpos_empty(i,j,block_coordinates)==False:
                i,j = block.gridpos(i,j+1)
            block_coordinates.append([i,j])
            
#************************************************************************************

    def xxcheck_gridpos_empty(self,coord1,coord2,block_coordinates):
        i = coord1
        j = coord2
        return not([i,j] in block_coordinates or [i+1,j] in block_coordinates or [i-1,j] in block_coordinates)
        
#************************************************************************************

    def rearr_grid (self,move_interval,b=0):

        if 'semaphore_positioning_in_progress' in vars(self):
            return()
            
        for block in self.blocks:
            block.newbbox    = block.bbox[:]

        sw = {}
        for swimlane in self.swimlanes:
            sw[ ("%09.4f" % swimlane.bbox[1]) + "-" + ("%09.4f" % swimlane.bbox[3]) ] = swimlane
        swkeys = list(sw.keys())
        swkeys.sort()
        
        dy   = 0  #  shift to down
        miny = 0  #  limit in height for swimlane
                
        for swkey in swkeys:
            swimlane            = sw[swkey]
            dy                  = max(0,miny - swimlane.bbox[1])
            swimlane.newbbox    = [0,0,0,0,0]
            swimlane.newbbox[1] = swimlane.bbox[1] + dy
            swimlane.newbbox[2] = swimlane.bbox[2] - swimlane.bbox[0]
            swimlane.newbbox[3] = swimlane.bbox[3] + dy
            miny                = swimlane.newbbox[3]

            if hasattr(swimlane,'move_blocks'):
                for block in swimlane.move_blocks:
                    block.newbbox[1] = block.newbbox[1] + dy
                    block.newbbox[3] = block.newbbox[3] + dy
#        self.rearrange_blocks() 

        procpy.rearr_grid.Rearr_grid(self).newbends_for_arrows()

        self.positioning(move_interval)
#        self.fit_scrollbar()

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

    def xxrearr_grid_arrows_with_sugiyama (self,move_interval):

#        for block in self.blocks:
#            block.gridpos()
        procpy.rearr_sugiyama.Rearr_sugiyama(self,0).arrows_sugiyama_fit()
        self.positioning(move_interval)

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

    def xxrearr_sugiyama (self,move_interval):

        procpy.rearr_sugiyama.Rearr_sugiyama(self,0).blocks_sugiyama_fit()
        procpy.rearr_sugiyama.Rearr_sugiyama(self,0).arrows_sugiyama_fit()
        self.positioning(move_interval)

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

    def xxrearr_circle (self,move_interval):
        print("xxrearr_circle---nxs");
        (maxw,maxh) = (0,0)
        for block in self.blocks:
            (maxw,maxh) = (max(maxw,block.bbox[2]-block.bbox[0]),
                           max(maxh,block.bbox[3]-block.bbox[1]))
        anzahl      = float(len(self.blocks))
        radiusx     = maxw * math.log(anzahl) * 1.5
        radiusy     = maxh * math.log(anzahl) * 1.5
        zaehler     = anzahl
               
        self.blocks.sort(key=lambda block: block.nr)
        for block in self.blocks:
            block.newbbox    = [0,0,0,0]
            block.newbbox[0] = radiusx * (1.1+math.cos(math.pi*zaehler/anzahl))
            block.newbbox[1] = radiusy * (1.1+math.sin(math.pi*zaehler/anzahl))
            block.newbbox[2] = block.newbbox[0] + block.bbox[2] - block.bbox[0]
            block.newbbox[3] = block.newbbox[1] + block.bbox[3] - block.bbox[1]
            zaehler          = zaehler + 2
            for arrow in block.arrows_out:
                arrow.newbends   = []
                arrow.anchorline = 0
        self.positioning(move_interval)

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

    def xxrearr_swimlane (self,move_interval):

        swimlanes = {}           #  Collecting and sorting the swimlanes
        for swimlane in self.swimlanes:
            swimlanes[ ("%09.4f" % swimlane.bbox[1]) + "-" + ("%09.4f" % swimlane.bbox[3]) ] = swimlane
        swkeys = list(swimlanes.keys())
        swkeys.sort()
        
        dy   = 0  #  shift to down
        miny = 0  #  limit in height for swimlane
        
        all_arrows = []
        for block in self.blocks:
            block.newbbox = block.bbox[:]
            for arrow in block.arrows_in:
                all_arrows.append(arrow)
                arrow.newbends = []
                for arrowline in arrow.arrowlines[:-1]:
                    coords = self.graphcanvas.coords(arrowline)
                    arrow.newbends.append([coords[2],coords[3]])
                
        for swkey in swkeys:
            swimlane            = swimlanes[swkey]
            dy                  = max(0,miny - swimlane.bbox[1])
            swimlane.newbbox    = [0,0,0,0,0]
            swimlane.newbbox[1] = swimlane.bbox[1] + dy
            swimlane.newbbox[2] = swimlane.bbox[2] - swimlane.bbox[0]
            swimlane.newbbox[3] = swimlane.bbox[3] + dy
            miny                = swimlane.newbbox[3]
#            (blocks,arrows,singlepoints) = swimlane.blocks_and_arrows_in_swimlane()
            (blocks,arrows,singlepoints) = (swimlane.move_blocks,swimlane.move_arrows,swimlane.move_singlepoints)
            for block in blocks:
                block.newbbox[1] = block.bbox[1] + dy
                block.newbbox[3] = block.bbox[3] + dy
            for arrow in arrows:
                all_arrows.remove(arrow)
                zaehler = 0
                for arrowline in arrow.arrowlines[:-1]:
                    arrow.newbends[zaehler][1] = arrow.newbends[zaehler][1] + dy
                    zaehler = zaehler + 1
            for point in singlepoints:
                if point[2] == 0 and point[1] > 0:
                    arrow = point[0]
                    arrow.newbends[point[1]-1][1] = arrow.newbends[point[1]-1][1] + dy

        self.positioning(move_interval)

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

    def set_background_image(self, filename, fac=None):

        try:
            self.delete(self.bg)
            self.bg = None
        except Exception as e:
            pass

        try:
            image_pil = Image.open(filename)
            if fac:
                w,h = image_pil.size
                image_pil = image_pil.resize((int(w*fac), int(h*fac)),Image.ANTIALIAS)
            self.im = ImageTk.PhotoImage(image_pil)
                                 
        except Exception as e:
            return()

        self.bg = self.create_image(0,0, image=self.im, anchor="nw")
        self.tag_lower(self.bg)

        self.tag_bind(self.bg, "<Button-1>",        self.unhighlight_block)
        self.tag_bind(self.bg, "<ButtonRelease-1>", self.release_button_event)
        self.tag_bind(self.bg, "<B1-Motion>",       self.move_mouse_event)

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

    def create_arrow_line (self,*pars,**args):

        args1          = args.copy()
        args1['fill']  = "white"
        args1['width'] = args['width'] + 10
#        args1['state'] = "hidden"
        bg_line        = self.create_line(*pars,**args1) # background line for binding application
        arrowline      = self.create_line(*pars,**args)

        self.tag_lower(bg_line)
        return([arrowline,bg_line])

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

    def coords (self,*pars,**args):
    
        if len(pars) > 0 and type(pars[0]) == type([]):
            erg = []
            for item in pars[0]:
                erg.append(tkinter.Canvas.coords(self,item,*tuple(list(pars)[1:]),**args))
            return(erg[0])
        else:
            return( tkinter.Canvas.coords(self,*pars,**args) )

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

    def itemconfig (self,*pars,**args):
    
        if len(pars) > 0 and type(pars[0]) == type([]):
            for item in pars[0]:
                tkinter.Canvas.itemconfig(self,item,*tuple(list(pars)[1:]),**args)
                args['fill'] = 'white'
        else:
            tkinter.Canvas.itemconfig(self,*pars,**args)

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

    def tag_bind (self,*pars,**args):
    
        if len(pars) > 0 and type(pars[0]) == type([]):
           for item in pars[0]:
                tkinter.Canvas.tag_bind(self,item,*tuple(list(pars)[1:]),**args)
        else:
            tkinter.Canvas.tag_bind(self,*pars,**args)

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

    def tag_lower (self,*pars,**args):

        for obj in pars:
            tkinter.Canvas.tag_lower(self,obj)
            if self.type(obj) == "image" or not str(self.itemcget(obj,'fill'))=='white': # white object should be lowest
                try:
                    while self.itemcget(self.find_above(obj),"fill") == "white" :
                        self.tag_raise(obj,self.find_above(obj))
                except: break

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

    def delete (self,*pars,**args):
    
        if len(pars) > 0 and type(pars[0]) == type([]):
           for item in pars[0]:
                tkinter.Canvas.delete(self,item,*tuple(list(pars)[1:]),**args)
        else:
            tkinter.Canvas.delete(self,*pars,**args)

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

    def positioning (self,move_interval=10.0,max_rounds=100):

        duetime      = time.clock() + move_interval
        zaehler      = 0
        gesamt_time  = 0
        nr           = max_rounds
        
        if 'semaphore_positioning_in_progress' in vars(self):
            if time.clock() - self.semaphore_positioning_in_progress > 10 * move_interval:
                print("WARNING","Semaphore could not be deleted")
                del self.semaphore_positioning_in_progress
            else:
                return()
            
        self.semaphore_positioning_in_progress = time.clock()

# 1. Preparation: Absolute to relative values, extend arrows if necessary

        maxshift = 0
        for block in self.blocks + self.swimlanes:   #  shift the absolute coordinates to relative
            if 'newbbox' in vars(block):
                block.newbbox = [block.newbbox[0]-block.bbox[0],block.newbbox[1]-block.bbox[1],
                                 block.newbbox[2]-block.bbox[2],block.newbbox[3]-block.bbox[3]]
            else:
                block.newbbox = [0,0,0,0]                                
            maxshift     = max(maxshift,abs(block.newbbox[0]),abs(block.newbbox[1]),
                                        abs(block.newbbox[2]),abs(block.newbbox[3]))

            for arrow in block.arrows_out:
                if not 'newbends' in vars(arrow):
                    continue
                bends   = arrow.newbends
                lines   = arrow.arrowlines
                print("----------bends:%s" % bends)
                print("----------lines:%s" % lines)
                zaehler = 1
                for bend in bends:
                    if len(lines) == 1:   #  if no bend is in arrow
                        (x,y)  = arrow.get_shapes_mid_point()
                        coords = self.coords(lines[0])
                        self.coords(lines[0],x,y,coords[2],coords[3])
                        lines.insert(-1,self.create_arrow_line(coords[0],coords[1],x,y,
                                            fill='black',width=procpy.config.ARROWTHICKNESS))
                    while len(lines) < zaehler+1:   #  extend arrow bends to match the count of new bends
                        coords = self.coords(lines[-1])
                        lines.insert(-1,self.create_arrow_line(coords[0],coords[1],coords[0],coords[1],
                                                fill='black',width=procpy.config.ARROWTHICKNESS))
                    coords   = self.coords(lines[zaehler])
                    bend[0]  = bend[0] - coords[0]
                    bend[1]  = bend[1] - coords[1]
                    maxshift = max(maxshift,abs(bend[0]),abs(bend[1]))
                    zaehler  = zaehler + 1

#        self.gui.mark("B")

#  2.  Morphing arrows in a loop step by step
        while nr > 0:

            time0 = time.clock()
            
            for block in self.blocks + self.swimlanes:
                if 'newbbox'in vars(block):
                    (dx0,dy0,dx1,dy1) = ( block.newbbox[0]/nr, block.newbbox[1]/nr, block.newbbox[2]/nr, block.newbbox[3]/nr )
                    block.newbbox = [ block.newbbox[0] - dx0, block.newbbox[1] - dy0,
                                      block.newbbox[2] - dx1, block.newbbox[3] - dy1 ] 
                    block.bbox    = [ block.bbox[0] + dx0, block.bbox[1] + dy0, block.bbox[2] + dx1, block.bbox[3] + dy1 ]
                    block.format_shape()

            for block in self.blocks:
                for arrow in block.arrows_out:
                    if not 'newbends' in vars(arrow):
                        continue
                    zaehler1 = 0
                    while (0 == 0):
                        px       = None
                        try:
                            c_line1 = self.coords(arrow.arrowlines[zaehler1+1])
                        except:
                            break
                        c_line0  = self.coords(arrow.arrowlines[zaehler1])
                        try:
                            bend    = arrow.newbends[zaehler1]
                            (dx,dy) = ( bend[0]/nr, bend[1]/nr )
                            bend[0] = bend[0] - dx
                            bend[1] = bend[1] - dy
                            (px,py) = ( c_line1[0], c_line1[1] )
                        except Exception as e:   #  if no new bend definition is available anymore
                            if not px:
                                (px,py) = arrow.get_shapes_mid_point()
                            (dx,dy) = ( (px-c_line0[2])/nr, (py-c_line0[3])/nr ) 
                        self.coords(arrow.arrowlines[zaehler1],
                                                c_line0[0],    c_line0[1],    c_line0[2]+dx, c_line0[3]+dy)
                        self.coords(arrow.arrowlines[zaehler1+1],
                                                c_line1[0]+dx, c_line1[1]+dy, c_line1[2],     c_line1[3]  )
                        zaehler1 = zaehler1 + 1
#                    bbox = self.get_bounding_box()
                    arrow.fit_block_connections()
                    arrow.fit_description()  #  self.griddata)
            
            self.update()
#            bbox = self.get_bounding_box()
            xdim = self.winfo_width()
            ydim = self.winfo_height()

#            self.gui.mark(str(nr))
            zaehler      = zaehler + 1              #   count runs
            time0        = time.clock() - time0      #   time for this loop run
            gesamt_time  = gesamt_time + time0      
            rest_time    = duetime - time.clock()    #   Computing runs /waittime to match
            avg_time     = gesamt_time/zaehler      #   the interval for this action
            if rest_time > 0 :
                wait_time = rest_time/nr - avg_time
                if wait_time > 0:
                    time.sleep(wait_time)
                    nr = nr-1
                else:
                    nr = min( int(rest_time/avg_time), nr-1 )
                    nr = max(1,nr)
            else:
                nr = min(2,nr-1)

#        self.gui.mark("C")

#        bbox = self.get_bounding_box()
        xdim = self.winfo_width()
        ydim = self.winfo_height()
#        self.config(scrollregion=(0,0,max(xdim,bbox[2]),max(ydim,bbox[3])))


#  3.  Deleting superfluous bends in arrows at end of moving

        for block in self.blocks:
            for arrow in block.arrows_out:
                if not 'newbends' in vars(arrow):
                    continue
                lines = arrow.arrowlines
                try:
                    soll_len = len(arrow.newbends) + 1
                except:
                    continue
                c_line0  = None
                while soll_len < len(lines):
                    c_line0 = self.coords(lines[-2])
                    self.delete(lines.pop(-2))
                if c_line0:
                    c_line1 = self.coords(lines[-1])
                    self.coords(lines[-1],c_line0[0],c_line0[1],c_line1[2],c_line1[3])
                arrow.fit_description()   # self.griddata)
                del arrow.newbends
            try:
                del block.newbbox
            except:
                pass
                

#   4.  now at last a re-fitting is necessary
        for block in self.blocks:
            for arrow in block.arrows_out:
                arrow.fit_block_connections()
                arrow.elem_bindings()

        self.update()
        del self.semaphore_positioning_in_progress
        return(True)

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

    def reset_speed (self):
        self.speedruler.set(950)

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

    def get_bounding_box (self):

        bbox = []
        for block in self.blocks:
            block.bounding_box(bbox)
            
            for jump in block.arrows_in:
                jump.bounding_box(bbox)
        
        return(bbox)
                    
#************************************************************************************

    def set_zoomfaktor (self,fac):   #   fac: factor to zoom, if = -1/ -2/ -3: fit to width, height resp. canvas

        xdim0 = self.winfo_width()
        ydim0 = self.winfo_height()

        if fac < 0 and fac > -4:  #  fit to page width resp. height resp. canvas

            self.graphcanvas.update()
            bbox = self.get_bounding_box()
            fakx = float(xdim) / float(bbox[2]) # - bbox[0])
            faky = float(ydim) / float(bbox[3]) # - bbox[1])
            
            if fac == -3 and fakx < faky:
                fac = -1
            elif fac == -3:
                fac = -2
            fac = 0.96 * [fakx,faky][-fac-1]
  	  

        if self.hl_block[0] and not self.hl_block[0].shape == "a":  #  Textgroesse erhalten bei Highlighting
            self.hl_block[0].fontsize = self.hl_block[0].fontsize / fac

        self.zoom_factor = self.zoom_factor * fac
        for block in self.blocks + self.swimlanes:
            block.scale(fac)

        bbox             = self.get_bounding_box()
        xdim             = max(xdim0,bbox[2])
        ydim             = max(ydim0,bbox[3])
        self.config(scrollregion=(0,0,xdim,ydim))

        if self.hl_block[0] and not self.hl_block[0].shape == "a":  #  Textgroesse erhalten bei Highlighting
            xdim0 = self.winfo_width()
            ydim0 = self.winfo_height()
            (x0,x1,y0,y1,x,y,w,h)     = self.hl_block[0].box_coord()
            self.xview_moveto(abs(float(x-xdim0/2)/float(xdim)))
            self.yview_moveto(abs(float(y-ydim0/2)/float(ydim)))

        # zoom background-image
        self.set_background_image(procpy.config.FILENAME, self.zoom_factor)

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

    def sortcols (self,event):	
    
        canvas = event.widget
        x = canvas.canvasx(event.x)
        y = canvas.canvasy(event.y)
        
        fieldnr = int(x)/160
        field   = self.actual_report_columns[fieldnr]
        if self.sortfield == field:
            self.sortupper = (self.sortupper + 1) % 4
        else:
            self.sortupper = 0
            
        self.sortfield = field
        self.draw_report_bars()
        
#**************************************************************************

    def compute_report_data (self,entry):
        
        try:
            group0 = entry.SUMVALUES[self.groupby]
        except:
            pass #group0 =

        try:
            group0 = str(float(group))
        except:	
            pass
        
        for group in [group0,"__gesamt__"]:
            try:
                self.counts[group]   += 1
            except:
                
                self.counts[group]    = 1
                self.sumvalues[group] = {}
            if not group == "__gesamt__":
                self.maxcount = max(self.counts[group],self.maxcount)

            for field in self.report_fields:
                if field == "COUNT":
                    continue
                if field == "":
                    continue
                try:
                    self.sumvalues[group]
                except:
                    self.sumvalues[group] = {}
                try:
                    self.sumvalues[group][field]
                except:
                    self.sumvalues[group][field] = 0
                try:
                    self.maxvalues[field]
                except:
                    self.maxvalues[field] = 0
                try:
                    val = entry.SUMVALUES[field]
                except:
                    val = "0"
                try:
                    val = float(val)
                    self.sumvalues[group][field] += val
                    if not group == "__gesamt__":
                        self.maxvalues[field] = max(self.maxvalues[field],val)
                except:
                    self.sumvalues[group][field]  = val

        self.draw_data = []
        for group in self.sumvalues:
            data_row = {}
            for field in self.report_fields:
                if field == "COUNT":
                    data_row[field] = [self.counts[group],self.maxcount]
                else:
                    val = self.sumvalues[group][field]
                    try:
                        val = float(val) / self.counts[group]
                    except Exception as e:
                        pass
                    data_row[field] = [val,self.maxvalues[field]]
            if group == "__gesamt__":
                self.draw_data_gesamt = data_row
            else:
                self.draw_data.append(data_row)


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

    def draw_report_headers (self,reason_for_call=1):
    
        new_columns = []
        for header_combobox in self.header_comboboxes:
            header_text = header_combobox.get()
            if not header_text == "":
                new_columns.append(header_text)
        new_columns.append("")
        
        if not self.actual_report_columns == new_columns:

            o1 = len(self.actual_report_columns)
            o2 = len(new_columns)
            if not o2 == o1:
                if o2 < o1:
                    while o2 < len(self.header_comboboxes):
                        self.header_comboboxes[-1].destroy()
                        del self.header_comboboxes[-1]
                else:
                    newcombo = tkinter.ttk.Combobox(self.reportcanvas,width=12,font=("Arial",8))
                    self.reportcanvas.create_window((o2-1)*160+20,5,anchor=tkinter.NW,window=newcombo)
                    if o1 == 0:
                        newcombo.insert(0,'PATH')
                        newcombo.config(state='readonly')
                    if o1 == 1:
                        newcombo.insert(0,'COUNT')
                        newcombo.config(state='readonly')
                    else:
                        newcombo.config(postcommand=self.draw_report_headers)
#                    newcombo.config(validatecommand=self.draw_report,validate='all')
                    self.header_comboboxes.append(newcombo)
                    self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,10))

            self.actual_report_columns = new_columns
            zaehler = 0
            option_values = self.vars + [""]
            for column_text in self.actual_report_columns:
                self.header_comboboxes[zaehler].delete(0,9999)
                self.header_comboboxes[zaehler].insert(0,column_text)
                if column_text in ['PATH','COUNT']:
                    self.header_comboboxes[zaehler].config(values=[])
                else:
                    self.header_comboboxes[zaehler].config(values=option_values)
                zaehler = zaehler + 1
            if 'draw_data' in vars(self):
                self.draw_report_bars()

        self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,10))
        if len(self.actual_report_columns) < 3:
            return(self.draw_report_headers())


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

    def draw_report_bars (self):
    
#        nr = self.report_fields_nr[self.sortfield]
        if self.sortfield == 'COUNT':
            self.draw_data.sort(key=lambda x: x['COUNT']+x['PATH'], reverse=(self.sortupper%2==0))
        else:
            self.draw_data.sort(key=lambda x: x[self.sortfield], reverse=(self.sortupper%2==0))
        self.draw_data1 = [self.draw_data_gesamt] + self.draw_data

        self.reportcanvas.delete("reportbar")

        row       = 1
        cellh     = 12
        cellw     = 160

        x0 = 0
        y0 = 2*cellh
        y0 = 3*cellh

        gesamtzeile = True  #  first line is the total/average data line
        for ergrow in self.draw_data1:
            x0 = 0
            y0 = y0 + cellh
            for field in self.actual_report_columns[0:-1]:
                if gesamtzeile and field == self.sortfield:
                    xpos = x0+2
                    ypos = y0-int(2.7*cellh)
                    color_sort = "yellow"
                    if self.sortupper%2 == 0:    #  compute and draw sort marker
                        ypos       = ypos - 10
                        color_sort = "red"
                    self.reportcanvas.create_oval(xpos,ypos,xpos+4,ypos+4,fill=color_sort,tag='reportbar')
                fillcolor = procpy.config.COLOR_REPORTBAR
                val       = ergrow[field][0]
                gval      = ergrow[field][1]
                if gesamtzeile:
                    fillcolor = 'grey'
                    if field == 'PATH':
                        val = "TOTAL / AVERAGE"
                try:
                    val1 = float(val)/float(gval)
                    if not (gesamtzeile and field == "COUNT"):
                        o = self.reportcanvas.create_rectangle(x0+5,
                                                     y0-12,
                                                     x0+5+val1*(cellw-40),
                                                     y0-2,
                                                     fill=fillcolor,tag='reportbar')
                        self.reportcanvas.tag_bind(o,'<ButtonPress-1>',lambda event: self.sortcols(event) )
                    val = int(val)
                except:
                    pass
                if field == 'COUNT' and self.sortupper > 1:
                    if gesamtzeile:
                        relative_val = val
                    else:
                        val = '%3.1f' % (100 * float(val) / float(relative_val) ) + '%'
                o = self.reportcanvas.create_text(x0+6,y0,text=str(val),anchor='sw',font=("Arial",8),
                                       tag=['reportbar',field])
                self.reportcanvas.tag_bind(o,'<ButtonPress-1>',lambda event: self.sortcols(event) )
                x0 = x0 + cellw
            gesamtzeile = False

        self.reportcanvas.config(scrollregion=(0,0,len(self.header_comboboxes)*160,y0+15))

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

    def start_process(self):
       
        if self.saved_yet  == 0:
            self.save_graphics()

        self.startbutton.config(state='disable')
        self.hl_block = None
        o = self.runcounter.get()
        self.runcounter.delete(0,10)
        if int(o) < 1:
            self.runcounter.insert(0,"1")
            self.startbutton.config(state='normal')
            return(0)
        self.runcounter.insert(0,str(int(o)-1))

        o = self.resetbutton.config('text')[-1]
        self.resetbutton.config(text=str(int(o)+1))

        self.block_list = {}
        self.hl_blocks  = {}
        self.steps      = {}
        for block in self.blocks:
            self.graphcanvas.itemconfig(block.elems['SHAPE'],fill=self.color_blocks)
#            if block.shape == 'a':# swimlanes are not counted in block_list
#                pass
#            else:
#                self.block_list[block.fkt] = block
        
        if not self.block_list: # if there are no blocks, stop process
            self.stop_process()
            return()	
        self.loopobj.after(0,self.proceed_process,self.__module__+".PROC")
        
#***************************************************************************************

    def proceed_process (self,mode="START",pars=[]):
        
        proc_instance = procpy.prcmanager.Prcmanager(self.db).run_process(mode,pars)
        speedfactor   = 5**(int(self.speedruler.get())/100-1)

        if proc_instance:

            self.entry = proc_instance
            obj        = proc_instance.OBJID
            fkt        = proc_instance.__func__
            sleeptime  = str(proc_instance.TIME)

            if obj in self.hl_blocks:
                id = self.hl_blocks[obj]
                self.block_list[id].content.config(bg=self.color_blocks,highlightcolor=self.color_blocks)
                self.block_list[id].contentframe.config(background=self.color_blocks,bg=self.color_blocks,
                highlightcolor=self.color_blocks) 
                self.graphcanvas.itemconfig(self.block_list[id].elems['SHAPE'],fill=self.color_blocks)    #   <----

            try:
                fillcolor1 = "red"
                self.block_list[fkt].content.config(bg=fillcolor1,highlightcolor=fillcolor1)        # color the content
                self.block_list[fkt].contentframe.config(background=fillcolor1,bg=fillcolor1,
                highlightcolor=fillcolor1)                                                          # color the contentframe
                self.graphcanvas.itemconfig(self.block_list[fkt].elems['SHAPE'],fill=fillcolor1)    # color the outer rectangle
                
                self.hl_blocks[obj] = fkt
            except Exception as e:
                pass
                print(str(e))
            if int(sleeptime) < 9999999900:   #   Prozess laeuft weiter
                self.loopobj.after(max( 50,int(sleeptime)*1000/speedfactor),self.proceed_process,'___dryrun___')
                return()


        self.compute_report_data(self.entry)   #  Daten des beendeten Prozesses gehen
        self.draw_report_headers()             #  in das Reporting ein
        self.draw_report_bars()
#        self.runobj = procpy.caller.Scripts()
        self.loopobj.after(max(35,int(1000/speedfactor)),self.del_all_highlighting)
        self.loopobj.after(max(70,int(2000/speedfactor)),self.start_process)
            
#****************************************************

    def stop_process (self):

        o = self.runcounter.get()
        self.runcounter.delete(0,10)
        self.runcounter.insert(0,"1")
        self.del_all_highlighting()
        self.startbutton.config(state='normal')

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

    def reset_process_data (self):
    
        self.reset_drawdata()
        self.reportcanvas.delete('reportbar')

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

    def reset_drawdata (self):

        self.resetbutton.config(text='0')
        self.report_fields    = ['PATH','COUNT'] + self.vars
        self.counts           = {}
        self.maxcount         = 0
        self.sumvalues        = {}
        self.maxvalues        = {}
        self.draw_report_headers()
#        self.field_expression = {}
#        for field in self.report_fields:
#            if re.search(r"[^A-Za-z0-9\_]",field):
#                self.field_expression[field] = re.sub(r"([A-Z][A-Za-z0-9\_]*)","float(entry.\\1)",field,99999999)
#            else:
#                self.field_expression[field] = "entry." +field
#        

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

    def del_all_highlighting (self):

        self.saved_yet          = 0
        fillcolor1 = self.color_blocks

        for block in self.blocks:
            block.content.config(bg=fillcolor1,highlightcolor=fillcolor1)                            # color the content
            block.contentframe.config(background=fillcolor1,bg=fillcolor1,highlightcolor=fillcolor1) # color the contentframe
            self.graphcanvas.itemconfig(block.elems['SHAPE'],fill=fillcolor1)                        # color the outer rectangle

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

    def show_menu(self, event,):
        if self.allow_context_menu:
            type = self.graphcanvas.type(event.widget.find_withtag("current"))
            if self.click_target == None or type == None:
                background_menu = tkinter.Menu(self.graphcanvas, tearoff=0)
                background_menu.add_command(label="New block", command= lambda :self.create_block(event.x_root, event.y_root))
                background_menu.post(event.x_root, event.y_root)

            elif self.click_target.__class__ is procpy.block.Block:
                block_menu = tkinter.Menu(self.graphcanvas, tearoff=0)
                block_menu.add_command(label="New arrow", command=lambda : self.create_arrow(self.click_target))
                block_menu.post(event.x_root, event.y_root)


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

    def xxscale_texts (self,fac):    #  scale texts

        for block in self.blocks:
            block.scale_texts(fac)
            for arrow in block.arrows_out:
                arrow.scale_texts(fac)

        self.current_zoom_factor = self.current_zoom_factor * fac

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

    def xxset_zoomfaktor (self,fac,draw_new=True):

        xdim = self.graphcanvas.winfo_width()
        ydim = self.graphcanvas.winfo_height()
        
        if fac < 0 and fac > -4:  #  fit to page width resp. height resp. canvas

            self.graphcanvas.update()
            
            bbox = self.get_bounding_box()
            fakx = xdim / (bbox[2] - bbox[0])
            faky = ydim / (bbox[3] - bbox[1])
            if   fac == -1:
                fak = fakx
            elif fac == -2:
                fak = faky
            else:
                fak = min(fakx,faky)

            self.graphcanvas.scale("all",0,0,fak,fak)

            """for fkt in self.blocks[fkt]:
                block = self.blocks[fkt]
                old_size = self.graphcanvas.itemcget(block.text,'text')
                new_size = self.graphcanvas.itemconfig(block.text,font=('Arial',old_size*fak)
            for fkt in self.arrows:
                 for jump in self.arrows[fkt][jump]"""
            bbox = self.get_bounding_box()
            self.graphcanvas.config(scrollregion=(bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim)+1,max(bbox[3],bbox[1]+ydim)+1))


#            for fkt in self.blocks[fkt]:
#                block = self.blocks[fkt]
#                old_size = self.graphcanvas.itemcget(block.text,'text')
#                new_size = self.graphcanvas.itemconfig(block.text,font=('Arial',old_size*fak)
#            for fkt in self.arrows:
#                for jump in self.arrows[fkt][jump]

#        elif fac == -5:
#            if self.fak == -1:
#                fac = -7
#            else:
#                fac = -9
##        if fac == -7:           #  toggle back to graph view
#            self.fak = self.fit
#
#        elif fac == -9:           #  presentation as a textfield for the pycode
#            self.fak = -1
#
        elif fac > 0:
            bbox = self.get_bounding_box()
            self.graphcanvas.scale("all",0,0,fac,fac)
            bbox = self.get_bounding_box()
#            bx   = bbox[2] - bbox[0] + 20
#            by   = bbox[3] - bbox[1] + 20
#            bbox = self.get_bounding_box()
#            print (bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim),max(bbox[3],bbox[1]+ydim))
            self.graphcanvas.config(scrollregion=(bbox[0],bbox[1],max(bbox[2],bbox[0]+xdim)-1,max(bbox[3],bbox[1]+ydim)-1))
#            self.graphcanvas.config(scrollregion=(0,0,bbox[2]+20,bbox[3]+15))

#            faknew = self.fak * fac
#            if True:
##            if (faknew > fakx or faknew > faky) and faknew < 10*max(fakx,faky):
#                self.fak = faknew
#                self.fit = faknew
#            else:
#                return()
#
#        try:
#            if self.fak < self.fak0 * (1 + 0.00001) and self.fak > self.fak0 * (1 - 0.00001):
#                return
#        except:
#            pass
#        self.fak0 = self.fak        

#        self.draw_bpm()


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

    def xxdraw_miniview (self):
    
        fakx = self.miniview_w / (self.pd.w())
        faky = self.miniview_h / (self.pd.h())
        self.draw_graphics(self.miniview,min(fakx,faky),self.moffset,False)

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

    def xxdraw_bpm (self):

        if self.fak < 0:
            pycode = self.pd.text
        else:
            self.graphcanvas_w  = self.fak * (self.pd.w())
            self.graphcanvas_h  = self.fak * (self.pd.h())
            print(self.graphcanvas_w)
            print(self.graphcanvas_h)
 
        try:
            self.graphcanvas.destroy()
        except:
            pass
        try:
            self.xscroll.destroy()
        except:
            pass
        try:
            self.yscroll.destroy()
        except:
            pass

        if self.fak < 0:
            self.graphcanvas = tkinter.Frame(self.graphframe)
            self.graphcanvas.pack(expand=tkinter.TRUE,fill=tkinter.BOTH)
            self.graphtext   = tkinter.Text(self.graphcanvas,wrap=tkinter.NONE,width=10,height=10)
            self.graphtext.pack(expand=True,fill=tkinter.BOTH)
            self.graphtext.insert(tkinter.END,pycode)
        else:
            self.graphcanvas = tkinter.Canvas(self.graphframe)
            self.graphcanvas.config(scrollregion=(0,0,self.graphcanvas_w,self.graphcanvas_h))
            self.xscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.HORIZONTAL)
            self.yscroll = tkinter.Scrollbar(self.graphframe,orient=tkinter.VERTICAL)
            self.xscroll.config(command=self.graphcanvas.xview,width=8)
            self.yscroll.config(command=self.graphcanvas.yview,width=8)
            self.graphcanvas.config(xscrollcommand=self.xscroll.set)
            self.graphcanvas.config(yscrollcommand=self.yscroll.set)
            self.xscroll.pack(side=tkinter.BOTTOM,fill=tkinter.X)
            self.yscroll.pack(side=tkinter.RIGHT,fill=tkinter.Y)
            self.graphcanvas.pack(side=tkinter.LEFT,expand=True,fill=tkinter.BOTH)

            # create a menu
            #self.initUI()

            #Moving canvas with mouse not working at the moment with moving with items
            #self.graphcanvas.bind("<ButtonPress-1>", self.move_start)
            #self.graphcanvas.bind("<B1-Motion>", self.move_move)

            #Add zoom function with mousewheel
            # linux
            self.graphcanvas.bind("<Button-4>", self.zoomerP)
            self.graphcanvas.bind("<Button-5>", self.zoomerM)
            # windows
            self.graphcanvas.bind("<MouseWheel>", self.zoomer)

        if self.fak > 0:
            self.draw_graphics(self.graphcanvas,self.fak,self.offset,True)

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

    def xxdraw_graphics (self,graph_widget,fak,offset,with_text=False):

        graph_widget.config(background='white')

        self.sources = {}  #  The arrow lists of the blocks where the arrows are sources
        self.targets = {}  #  The arrow lists of the blocks where the arrows are targets

        for fkt in self.pd.funcs:  #  process all the blocks
            self.sources[fkt] = []
            self.targets[fkt] = []
            x   = fak * ( self.pd.x(fkt) - self.pd.x0() ) + offset
            y   = fak * ( self.pd.y(fkt) - self.pd.y0() ) + offset
            w   = fak * self.pd.w(fkt)
            h   = fak * self.pd.h(fkt)
           # self.blocks[fkt] = graph_widget.create_rectangle(
           #         int(x-w/2),int(y-h/2),
           #         int(x+w/2),int(y+h/2),fill=self.color_blocks)
            block_size = (int(x-w/2),int(y-h/2),int(x + w / 2),int(y+h/2))
            self.blocks[fkt] = Box(graph_widget,fkt,self.color_blocks,block_size)
            if with_text:
                #o1 = self.graphcanvas.create_text(int(x-w/2),int(y-h/2),anchor=Tkinter.NW,
                #                text=fkt,font=("ARIAL",6))
                #o2 = self.graphcanvas.create_text(int(x),int(y),anchor=Tkinter.CENTER,
                #                text=self.pd.prg(fkt),font=("ARIAL",7))
                self.blocks[fkt].create_text((int(x-w/2),int(y-h/2)),tkinter.NW,fkt,6)
                self.blocks[fkt].create_text((int(x),int(y)), tkinter.CENTER, self.pd.prg(fkt), 7)
#                self.graphcanvas.tag_bind(o,'<ButtonPress-1>',self.make_text_fkt(node) )
            self.colors[fkt] = self.color_blocks


        for fkt in self.pd.funcs:   #   draw the arrows:
            for ziel in self.pd.data[fkt]['JUMP']:  #  process all the edges
                self.pd.data[fkt]['JUMP'][ziel][1:]
                arrow = [self.pd.x(fkt),self.pd.y(fkt)] + self.pd.data[fkt]['JUMP'][ziel][1:] + [self.pd.x(ziel),self.pd.y(ziel)]
                p0    = None
                zaehler = 0
                while (0 == 0):
                    try:
                        p = [ arrow[zaehler], arrow[zaehler+1] ]
                    except:
                        break
                    zaehler = zaehler + 2
                    x   = fak * ( p[0] - self.pd.x0() ) + offset
                    y   = fak * ( p[1] - self.pd.y0() ) + offset
                    if p0:
                        #o = graph_widget.create_line(int(p0[0]),int(p0[1]),int(x),int(y),fill='black')
                        arrow_size = (int(p0[0]),int(p0[1]),int(x),int(y))
                        self.blocks[fkt].create_arrow(arrow_size,"black",ziel)
                        self.blocks[ziel].set_arrow_from(fkt+":"+ziel)
                        #self.sources[fkt].append(o)
                        #self.targets[fkt].append(o)
                    p0  = [x,y]
                #if with_text:
                    #graph_widget.create_oval(x-1.5,y-1.5,x+1.5,y+1.5,fill="black")


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