##################################################################
# Alessandro MIRONE 2001
# ESRF
##################################################################

#########################
##Disclaimer
##==========
##
## This  software is provided without warranty of any kind.
## No liability is taken for any loss or damages, direct or
## indirect, that may result through the use of it. No warranty
## is made with respect to this documentation, or the programs
## and functions therein.
## There are no warranties that the programs or their documentation
## are free of error, or that it is consistent with any standard,
## or that it will meet the requirement for a particular application.

## Copyright
## =========
##
## We have adopted the GNU LIBRARY GENERAL PUBLIC LICENSE to apply to
## the this software.
## For more information on the license terms, see
## http://www.gnu.org/copyleft/lgpl.txt
__version__="15/11/2002"
import sys
import pickle
from qt import *

# import pl
import beans
import glob
from threading import *
import threading
import Minimiser
from Numeric import *
import sys
import time
import math
# from GraphView  import *
from PyDVT.GraphView  import *

BLock=None

connectIcon=["16 14 5 1",
             "  c None",
             ". c black",
             "X c gray50",
             "o c red",
             "O c yellow",
             "                ",
             "          .     ",
             "       X .X     ",
             "      XooX  .   ",
             "     Xoooo .X   ",
             "    XooooooX    ",
             "    XooooooX    ",
             "    XoooooX.    ",
             "    XooooX.     ",
             "   XOXXXX.      ",
             "  XOXX...       ",
             " XOXX           ",
             "  XX            ",
             "  X             "
             ]
connectIcon=["16 15 7 1",
              " 	c None",
              ".	c #D5D6D5",
              "+	c #000000",
              "@	c #949594",
              "#	c #8B8D8B",
              "$	c #313031",
              "%	c #FFFFFF",
              "..        ......",

              ".+@       @+++#$",
              ".++@      @+++#$",
              ".+++@     @+++#$",
              ".++++@    @+++#$",
              ".+++++@   @+++#$",
              ".++++++@  @+++#$",
              ".++++++#% @+++#$",
              ".+++++#%  @+++#$",
              ".++++#%   @+++#$",
              ".+++#%    @+++#$",
              ".++#%     @+++#$",
              ".+#%      @+++#$",
              ".+%       @+###$",
              ".$        $$$$$$"
              ]

stopIcon= ["13 15 7 1",
           " 	c None",
           ".	c #D5D6D5",
           "+	c #000000",
           "@	c #8B8D8B",
           "#	c #FFFFFF",
           "$	c #949594",
           "%	c #313031",
           "...... ......",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+++@# $+++@%",
           ".+@@@# $+@@@%",
           ".%%%%% %%%%%%"
           ]
EmergencystopIcon= ["13 15 7 1",
           " 	c None",
           ".	c #FF0000",
           "+	c #000000",
           "@	c #8B8D8B",
           "#	c #FFFFFF",
           "$	c #949594",
           "%	c #313031",
           "     ..      ",
           "   ......    ",
           "  ........   ",
           " ..........  ",
           " ..........  ",
           "............ ",
           "............ ",
           "............ ",
           " ..........  ",
           " .........   ",
           "  ......     ",
           "    ..       ",
           "             ",
           "             ",
           "             ",
           ]

refreshIcon=["16 16 78 1",
             " 	c None",
             ".	c #ACA1AC",
             "+	c #9C9DAC",
             "@	c #ACAAB4",
             "#	c #B4B6C5",
             "$	c #DEDAF6",
             "%	c #B4B2D5",
             "&	c #9C95AC",
             "*	c #ACAAAC",
             "=	c #E6DEF6",
             "-	c #ACAACD",
             ";	c #ACA5B4",
             ">	c #B4B2DE",
             ",	c #6A6D9C",
             "'	c #8B8994",
             ")	c #C5C6E6",
             "!	c #B4AEDE",
             "~	c #9491AC",
             "{	c #ACA5AC",
             "]	c #BDBAE6",
             "^	c #7B759C",
             "/	c #7B7D8B",
             "(	c #948D9C",
             "_	c #9495A4",
             ":	c #9491C5",
             "<	c #9C99CD",
             "[	c #8B89BD",
             "}	c #94919C",
             "|	c #C5C2D5",
             "1	c #9C91CD",
             "2	c #8B8DC5",
             "3	c #8B89B4",
             "4	c #8B81A4",
             "5	c #9C9DA4",
             "6	c #CDC6EE",
             "7	c #73759C",
             "8	c #9495B4",
             "9	c #9C95CD",
             "0	c #737194",
             "a	c #B4AEC5",
             "b	c #B4B6DE",
             "c	c #A499B4",
             "d	c #9C9DCD",
             "e	c #62658B",
             "f	c #A4A5C5",
             "g	c #7B7D9C",
             "h	c #ACA5DE",
             "i	c #626183",
             "j	c #ACA1BD",
             "k	c #8381B4",
             "l	c #94959C",
             "m	c #ACA1B4",
             "n	c #6A698B",
             "o	c #9C99A4",
             "p	c #ACAADE",
             "q	c #9495D5",
             "r	c #B4B2CD",
             "s	c #9495C5",
             "t	c #ACA1DE",
             "u	c #A4A1A4",
             "v	c #C5BEE6",
             "w	c #626583",
             "x	c #9C959C",
             "y	c #8385B4",
             "z	c #9C95A4",
             "A	c #CDC6DE",
             "B	c #CDCAEE",
             "C	c #8381AC",
             "D	c #8381A4",
             "E	c #5A5D7B",
             "F	c #62618B",
             "G	c #949594",
             "H	c #ACA1CD",
             "I	c #7B79A4",
             "J	c #6A6983",
             "K	c #837D94",
             "L	c #7B799C",
             "M	c #838594",
             "                ",
             "     .+   @     ",
             "   #$%&  *=-    ",
             "   ;>,'  %)!~   ",
             "  {]^/(  _:<[}  ",
             "  |1'     }234  ",
             " 567       890  ",
             " ab^       cde  ",
             " f]g       +hi  ",
             " j>kl      mdn  ",
             " opq~      r[/  ",
             "  st:&   ;uvwx  ",
             "  &y[7z  ABC}   ",
             "   DEFG  HIJG   ",
             "    K/   LKM    ",
             "                "
             ]

diskIcon=["16 13 5 1",
             "  c None",
             ". c black",
             "X c gray50",
             "o c red",
             "O c yellow",
             "                ",
             "  .........     ",
             "  .OO.XXX.OX    ",
             "  .OOXXXX.OOX   ",
             "  .OOXXXX.OOO.  ",
             "  .OO.....OOO.  ",
             "  .OO.....OOO.  ",
             "  .OOOOOOOOOO.  ",
             "  .OOOOOOOOOO.  ",
             "  .OOooooooOO.  ",
             "  .OOooooooOO.  ",
             "  ...oooooo..   ",
             "                "
           ]

beanIcon=["16 13 3 1",
             "  c None",
             ". c green",
             "o c black",
             "                ",
             "         ...    ",
             "      .......   ",
             "     .........  ",
             "    ..........  ",
             "   ...........  ",
             "  ............  ",
             "  ............  ",
             "  ...........   ",
             "  ..........    ",
             "  .........     ",
             "   .......      ",
             "    ....        ",
             "                "
           ]

loadBeanIcon=["16 13 3 1",
             "  c None",
             ". c green",
             "o c black",
             "                ",
             "         ...    ",
             "      .......   ",
             "     .........  ",
             "    ..........  ",
             "   .....ooo...  ",
             "  ......oo....  ",
             "  ......o.o...  ",
             "  .........o.   ",
             "  .........o    ",
             "  ......... o   ",
             "   .......  o   ",
             "    ....    o   ",
             "                "
           ]
graphIcon=["18 18 96 2",
           "  	c None",
           ". 	c #FFFFFF",
           "+ 	c #AEA9A9",
           "@ 	c #110202",
           "# 	c #A7A2A2",
           "$ 	c #FAC8C8",
           "% 	c #F16262",
           "& 	c #F7A6A6",
           "* 	c #FEF8F8",
           "= 	c #5D5353",
           "- 	c #1C0F0F",
           "; 	c #342828",
           "> 	c #A5A0A0",
           ", 	c #FCFCFC",
           "' 	c #D9D7D7",
           ") 	c #E9E8E8",
           "! 	c #F37979",
           "~ 	c #FEF1F1",
           "{ 	c #F8B5B5",
           "] 	c #F47D7D",
           "^ 	c #FBD3D3",
           "/ 	c #9B9595",
           "( 	c #362929",
           "_ 	c #BCB8B8",
           ": 	c #B7B2B2",
           "< 	c #F8F8F8",
           "[ 	c #504545",
           "} 	c #3D3131",
           "| 	c #413535",
           "1 	c #BFBBBB",
           "2 	c #FDE9E9",
           "3 	c #FDEDED",
           "4 	c #F1F0F0",
           "5 	c #DAD8D8",
           "6 	c #918A8A",
           "7 	c #5B5151",
           "8 	c #B7B3B3",
           "9 	c #493E3E",
           "0 	c #DE6262",
           "a 	c #FBCFCF",
           "b 	c #DDDADA",
           "c 	c #534949",
           "d 	c #392C2C",
           "e 	c #D4D2D2",
           "f 	c #E6E5E5",
           "g 	c #BF6A6A",
           "h 	c #761919",
           "i 	c #A09A9A",
           "j 	c #332727",
           "k 	c #827A7A",
           "l 	c #4D4242",
           "m 	c #DEDCDC",
           "n 	c #372B2B",
           "o 	c #F26666",
           "p 	c #CCC3C3",
           "q 	c #7A7171",
           "r 	c #F5F4F4",
           "s 	c #3D3030",
           "t 	c #ABA6A6",
           "u 	c #433737",
           "v 	c #B1ACAC",
           "w 	c #473C3C",
           "x 	c #D9D6D6",
           "y 	c #352828",
           "z 	c #AFAAAA",
           "A 	c #3A2E2E",
           "B 	c #736A6A",
           "C 	c #D2CFCF",
           "D 	c #FCDEDE",
           "E 	c #E4E2E2",
           "F 	c #726969",
           "G 	c #D3D0D0",
           "H 	c #312424",
           "I 	c #6F6666",
           "J 	c #372A2A",
           "K 	c #EDECEC",
           "L 	c #B2ADAD",
           "M 	c #3A2D2D",
           "N 	c #8D8787",
           "O 	c #332626",
           "P 	c #D1CECE",
           "Q 	c #514747",
           "R 	c #1D0F0F",
           "S 	c #4B4040",
           "T 	c #3E3232",
           "U 	c #271A1A",
           "V 	c #140505",
           "W 	c #3F3434",
           "X 	c #B5B0B0",
           "Y 	c #2F2323",
           "Z 	c #D8D6D6",
           "` 	c #1C0E0E",
           " .	c #4A3F3F",
           "..	c #342727",
           "+.	c #CFCCCC",
           "@.	c #958E8E",
           ". . . . . . . . . . . . . . . . . . ",
           "+ @ # . . . . . . . . . $ % % & * . ",
           "= - ; > . . , ' ) . . $ ! ~ * { ] ^ ",
           "/ ( _ : . < [ } | 1 2 % 3 . . . . . ",
           "4 ( 5 . . 6 7 < 8 9 0 a b c ) . . . ",
           "4 d 5 . e } f . . g h i j k l . . . ",
           "m n 5 . 9 # . . $ o p q _ r s t . . ",
           "5 u 5 v w . . ^ % 3 . . . . x y z . ",
           "5 A B j C . D % 3 . . . . . . E F G ",
           "4 H I f . D % 2 . . . . . . . . . . ",
           "4 J 5 . ^ ! 2 . . . . . . . . . . . ",
           "K ( 4 . . . . . . . . . . . ) L < . ",
           "5 M 4 . . . . . . . . . . . . N O P ",
           "Q R S T y | | j j y y y y y y U V W ",
           "X Y v 5 4 . . . . . . . . . Z `  .< ",
           "m ... . . . . . . . . . . . +.@., . ",
           ". . . . . . . . . . . . . . . . . . ",
           ". . . . . . . . . . . . . . . . . . "
           ]

class pippo:
  pass
pippo.toavoidcrash=None

class DragableListView(QListView):
    """ This class is derived from QListView.
        it adds a few mechanisms:

        -- start dragging if the clicked items appears into
           InstructionsTable or CodeLinesTable. these two latter 
           are two classes defined below with static members "itemlist" 
           for the latter, and a dictionary named instruction_classes_Rev_dic 
           associating item-objects to class names(strings) for the former.

        -- Accept dragEvents if they are coming from the classes panels
           or from the codelines one.

        -- Accept drop event when they happen, and send the PYSIGNA dropped
           along with the clicked item and with the source   

        The appearence of what is inside ( teh items putted into)
        is managed by the object that contains the  DragableListView
    
    """
    
    def __init__(self,parent=None,name=None):
        QListView.__init__(self,parent,name)
        self.setAcceptDrops(1)
        self.setMouseTracking ( 0) 
        self.dragged=None
        
    def dragEnterEvent(self, event):
        print event.source()
        text = QString()
        if( QTextDrag.decode(event, text) ):
	        if( isinstance(event.source(),ClassesDragableListView)) :
        	    event.accept(QTextDrag.canDecode(event))

	        if( isinstance(event.source(),CodeLinesDragableListView)) :
        	    event.accept(QTextDrag.canDecode(event))
  
    def dropEvent(self, event):
        text = QString()
        if( QTextDrag.decode(event, text) ):
          pos = QPoint(event.pos().x(), event.pos().y() - self.header().height())
          item = self.itemAt(pos)
          # if(item is not None):
          print " DROPPED ", text
          self.emit(PYSIGNAL("dropped"), (text,item, event.source()      ))
 
    def mousePressEvent(self, event):
        pos = QPoint(event.pos().x(), event.pos().y() - self.header().height())
        item = self.itemAt(pos)
        print "item ===> ", item
        self.dragged=item
        if(item in InstructionsTable.instruction_classes_Rev_dic.keys()):
           self.startDrag(InstructionsTable.instruction_classes_Rev_dic[item])

        if(item in CodeLinesTable.itemlist):
          print event.button()
          if(event.button()==4):
            d = QTextDrag("codeline",self) # keep a reference to d
            d.dragCopy()
                
    def startDrag(self, text ):
        d = QTextDrag(text,self) # keep a reference to d
        d.dragCopy()


class ClassesDragableListView(DragableListView):
    """ Just inherits DragableListView

    """
    def __init__(self,parent=None,name=None):
        DragableListView.__init__(self,parent,name)


class CodeLinesDragableListView(DragableListView):
    """ Inherits DragableListView. 
        Virtual function dragMoveEvent from QLdragMoveEventistView
        is redefined to do autoscrolling. useful to create newlines
        beyond the top or bottom of the showed area.

    """
    def __init__(self,parent=None,name=None):
        DragableListView.__init__(self,parent,name)

    def dragMoveEvent(self,ev):
      print "mouseEvent"
      self.doAutoScroll ()
      # self.emit("scrolla")



class InstructionsTable(QSplitter):
    """ This widget manages the classes and functions that
        have been registered. They appear in a ListView
    """

    # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    # '' This offers a method to know which class we are dragging
    # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    instruction_classes_dic      =   {}
    instruction_superclasses_dic =   {}
    instruction_classes_Rev_dic  =   {}


    def __init__(self, *args):
	""" self is of type splitter.
            Self contains an instance of the class ClassesDragableListView
            that is derived from QListView.
            The QListView signal selectionChanged is connected to the function
            self.class_selected. This latter function emits the help corresponding to the
            selected class.
        """
        print (self,) + args
        apply(QSplitter.__init__, (self,) + args)
        self.split=self
        self.split =  QSplitter( self )
        self.inst_palette = ClassesDragableListView(self.split)


        self.connect(self.inst_palette, SIGNAL("selectionChanged ( QListViewItem * )"), self.class_selected)
    
    def class_selected(self,  target ):
        """ Receives the target that has been selected ( of the class QListViewItem).
            Check the name of the class linked to the target by the dictionary 
            instruction_classes_Rev_dic ( that gives strings).
            uses the obtained string as key to acced the self.bean.instruction_manager.instruction
            that gives for a given class name the instructions objects ( see bean documentation
            about the classe derived from instruction_base)
	"""
        if(target in self.instruction_classes_Rev_dic.keys()) :
              classe=self.instruction_classes_Rev_dic[target]
              # classe is a string
              classe=self.bean.instruction_manager.instruction[classe]
              self.emit(PYSIGNAL("class_emit_help"),(classe.help, ) )   

        

    def register(self,bean):
	"""
	    - creates the entry in the InstructionTable ViewList
            - keeps track of a dictionary self.instruction_classes_Rev_dic[items_c[c]]=c
              to retrieve the name of the class from the ListView item that is associated
              ( useful when clicking to get the class name)
            - Build another dictionary self.instruction_classes_dic  that gives the qt item
              associated to a given class name

            Classe are regrouped in super classes

	"""



        self.bean=bean
	inst_sc = bean.instruction_manager.instruction_classes
	inst_c  = bean.instruction_manager.instruction
 

        # instruction_classes_dic ={}  ==> instruction (string)  type to object of type QListViewItem
        #  instruction_superclasses_dic={}  ===>  supertype(string) to type instruction types

        self.instruction_classes_dic      =   {}
        self.instruction_superclasses_dic =   {}

        palette=self.inst_palette

        palette.addColumn(" Inst. names")
        palette.addColumn(" comments")
        palette.setRootIsDecorated(1)
        print " REGISTRO"
 
        items_c = self.instruction_classes_dic
        items_sc= self.instruction_superclasses_dic
         
        root=palette

        #####################################
        # superclass is a string

        for superclass in inst_sc.keys():

	   items_sc[superclass]=QListViewItem(root, superclass)

           for c in inst_sc[superclass]:

              items_c[c]     = QListViewItem(items_sc[superclass], c,inst_c[c].help)
              self.instruction_classes_Rev_dic[items_c[c]]=c
        pass




class CodeLinesTable(QSplitter):
    # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    # '' This offers q method to know which instruction correspond to a line
    # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


    # given a QListViewItem tells you the corresponding object of 
    # class derived  from instruction ( beans module)
    #  
    item_instruction      =   {}

    # a list of QListViewItem represente dans la fenetre
    itemlist              =   []
 
    # les items dans la poubelle 
    itemlistPoubelle       =   []

    lastline = None


    count=1
    def __init__(self, instruction_classes_Rev_dic, *args):

        self.instruction_classes_Rev_dic = instruction_classes_Rev_dic

        apply(QSplitter.__init__, (self,) + args)
         
        self.split=self

        self.split =  QSplitter( self )

        self.codelines = CodeLinesDragableListView(self.split)

        # self.codelines.setMouseTracking(1)

        self.connect(self.codelines, PYSIGNAL("dropped"), self.receiveDrop)

        codelines = self.codelines 

        codelines.addColumn(" # ")

        codelines.addColumn(" Ass. Var.")

        codelines.addColumn(" Type")

        codelines.addColumn(" User comments")

        codelines.addColumn(" Option")

        codelines.addColumn(" Auto comments")

        codelines.setRootIsDecorated(1)

        self.lastline=QListViewItem(codelines )

        self.lastline.setText(5,"LAST LINE")

        self.lastline.setText(0,"9998")

        # self.itemlist .append(self.lastline)

        self.poubelle=QListViewItem(codelines )

        self.poubelle.setText(5, "POUBELLE")

        self.poubelle.setText(0, "9999")

        # self.itemlist .append(self.poubelle)



        self.connect(self, PYSIGNAL("order_changed"), self.renameNcolumnEntries)

        self.connect(self, PYSIGNAL("codelines_changed"), self.codelines_changed_action)

        self.connect(self.codelines, SIGNAL("selectionChanged()"), self.codelines_selected_action)

    def select_instr(self, instr):
        """ this is a slot that is called by the variables table.
            When a variable is selected, the instruction corresponding
            to that variable ( correspondence managed by beans library)
            is passed to this slot       
        """

        # reverse the dictionary
        values=self.item_instruction.values()
        index=values.index(instr)

        # item has to be higlighted
        item=self.item_instruction.keys()[index]

        # call to the basic Qt function 
        self.codelines.setSelected(item,1)


    def codelines_selected_action(self):
	""" slot called when a line is clicked
            It emits a signal  selectedline_changed passing 
            the corresponding instruction as argument.

            The emitted signal will be processed by EditLine 
            of the properties editor widget
            and by the show_codeline functions that shows the generated code

        """

        selected= self.codelines.currentItem()
        if(selected in self.item_instruction.keys()):
          instr = self.item_instruction[selected]
        else:
          instr=None
        self.emit( PYSIGNAL("selectedline_changed"),(instr,))


    def renameNcolumnEntries(self ):
        """
          set the orders of rows.
          Column 0 of QListViewItems appering in the window
          gives the order of lista

        """
        lista = self.itemlist
        print " RIORDINA"
        for i in range(len(lista)):
           tok=lista[i]
           ord_text = "%d"%i
           ord_text = "0"*(4-len(ord_text)) + ord_text
           tok.setText(0, ord_text)

    def receiveDrop(self, text, target, source ):
        """
            target is the qlistviewitem on which the event drops.
            Source is the panel of type QListView ( not item)
            starting the dragging.

            If source is self it will be a line moval event

            If it is a ClassesDragableListView it will be a creation of a newline

            Text will be usually the name of the class of which an object is going
            to be create ( if source is ClassesDragableListView )

        """
        text=str(text)
        print " RICEVUTO TIPO ", text, "  su ", target
        duplicati=[]
        if(target is not self.poubelle):


             if(isinstance(source,ClassesDragableListView))	:
               ###############################################
               # Creation

               if(text=="Duplicator"):
                 if( target in self.item_instruction.keys()):
                   duplicati = beans.duplication( self.item_instruction[target])
               else:  
                 inst_dic=self.bean.instruction_manager.instruction
                 newinst= inst_dic[text]()
                 # order of newitem will be set afterwards
                 newitem =QListViewItem(self.codelines )

             elif( isinstance( source, CodeLinesDragableListView)) :
               ################################################################
               # Move or destroy ( drop on poubelle) ?

               if(target is None):
                   return

               if(target==source.dragged): return

               if(source.dragged not in self.itemlist):
                   return

               self.itemlist.remove(source.dragged)
               self.emit(PYSIGNAL("order_changed"),() )
               self.codelines.insertItem(source.dragged)
               # order of newitem will be set afterwards
               newitem=source.dragged
               newinst=self.item_instruction[newitem]
               newinst.ischild=0


             ##################################################################
             # now ( if no duplications ) items are created. Ordering has to be done


             # where to put the item
             if(target is None):	
                where=0	
             else:	
               if(target in (self.itemlist ) ):
                 where = self.itemlist.index(target)
               elif(target is self.lastline):
                 where=len(self.itemlist)
               else:
                 where=0
                 
             if(len(duplicati)==0):
               self.itemlist.insert(where,newitem )
               self.item_instruction [newitem]=newinst
               print dir(self.item_instruction[newitem])
               instr=self.item_instruction[newitem]
               instr.set_active()
             else:
               #
               # a bunch of new instruction has to be dealt with
               #
               instcount=0
               for newinst in duplicati:
                 if (instcount==0):
                   #  
                   # a new item for the duplicated instruction is created
                   # Order will be done afterwards
                   #
                   newitem =QListViewItem(self.codelines )
                 else:
                   
                   # retrieves the name of the original copied instruction
                   copiedname  = newinst.get_varname()
                   copiedname  = copiedname[0:copiedname.rfind("_dup"  )]

                   # retieves the original instruction
                   copiedinstr = beans.map_varname_2_instruction( copiedname)
                   
                   # retieves the copied instruction item
                   copieditem  = self.item_instruction.keys()[ self.item_instruction.values().index(copiedinstr)      ]

                   # the copy item will be put somewhere in the list itemlist
                   where = self.itemlist.index( copieditem )+1
 
                   # finally the new copy item is created as child of the copied item
                   newitem =QListViewItem(copieditem )
                   newinst.ischild=1

                 instcount+=1

                 self.itemlist.insert(where,newitem )
                 self.item_instruction [newitem]=newinst
                 instr=self.item_instruction[newitem]
                 instr.set_active()
               
        else:
           # target is poubelle
           #  Some cleaning has to be done
           #
           if( isinstance( source, CodeLinesDragableListView)) :   
               if(source.dragged not in self.itemlist):
                   return

               if(source.dragged.firstChild() is not None):
                   return


               # check if the item is a child
               parent=source.dragged.parent()


               # the item must be taken from its parent 
               # or from the hosting QListView (self)
               #
               if(parent is None):
                 self.codelines.takeItem(source.dragged)
               else:
                 parent.takeItem(source.dragged)             


               #
               # qt signaling may be sometimes quite delicate
               # if object coming out of scope are destroied during
               # the signalling process
               # So we remember it ( we are going to throw it to the poubelle)
               #
               self.remember= source.dragged

               self.item_instruction[source.dragged].set_passive()
               del self.item_instruction[source.dragged]
               self.itemlist.remove(source.dragged)

               # that's connected to columns renaming routine
               self.emit(PYSIGNAL("order_changed"),() )

               # that's connected essentially to an updating routines
               # of the variables widget
               self.emit(PYSIGNAL("line_removed"),() )

     
        # that's connected to columns renaming routine
        self.emit(PYSIGNAL("order_changed"),() )
        #

        # that's connected an updating of the instruction lines
        self.emit(PYSIGNAL("codelines_changed"),() )

        # order columns accordin to the first column ( # )
        self.codelines.setSorting(0)
        self.codelines.sort()


    def keyPressEvent(self, e):
       """
           remove the selected line

       """
       if(e.type()== QEvent.KeyPress and e.key()== 0x1000):
	 selected=self.codelines.currentItem()
         if(selected is not None):
               if(selected not in self.itemlist):
                   return

               if(selected not in self.itemlist):
                   return
               if(selected.firstChild() is not None):
                   return
               parent=selected.parent()
               if(parent is None):
                 self.codelines.takeItem(selected)
               else:
                 parent.takeItem(selected)             


               self.remember= selected
               self.item_instruction[selected].set_passive()
               del self.item_instruction[selected]
               self.itemlist.remove(selected)

               self.emit(PYSIGNAL("order_changed"),() )
               self.emit(PYSIGNAL("line_removed"),() )


    def reload(self, instructionlist ):
       """
	 this function is called when a saved bean is loaded.
          All instruction in instructionlist are charged in the widget 
          ( and QListViewItem created accordingly )

       """
       for item in self.itemlist+ self.itemlistPoubelle:
            self.codelines.takeItem(item)
            if(item in self.itemlist):  self.itemlist.remove(item)
            if(item in self.itemlistPoubelle):  self.itemlistPoubelle.remove(item)
##        self.item_instruction      =   {}
       self.itemlistPoubelle       =   []
       for instr in instructionlist:
           newinst= instr
           
           newitem =QListViewItem(self.codelines )
           
           where=len(self.itemlist)
           self.itemlist.insert(where,newitem )
           
           self.item_instruction [newitem]=newinst
           instr.set_active()

       for instr in instructionlist:
            if(hasattr(instr,"ischild")==0): instr.ischild=0
            if (instr.ischild==1):
                  newinst=instr
                  copiedname  = newinst.get_varname()
                  copiedname  = copiedname[0:copiedname.rfind("_dup"  )]
                  copiedinstr = beans.map_varname_2_instruction( copiedname)
                  if(copiedinstr in self.item_instruction.values() ):
                    copieditem  = self.item_instruction.keys()[ self.item_instruction.values().index(copiedinstr)      ]
                    item        = self.item_instruction.keys()[ self.item_instruction.values().index(newinst)      ]
                    self.codelines.takeItem(item)
                    copieditem.insertItem(item)



       self.emit(PYSIGNAL("order_changed"),() )
       self.emit(PYSIGNAL("codelines_changed"),() )
       self.codelines.setSorting(0)
       self.codelines.sort()

    def codelines_changed_action(self):
        """ 
 	adds text to naked QListViewItems
        """
        print " AGGIORNO"
        for item in self.itemlist:

           instr = self.item_instruction[item]
           item.setText(1, instr.get_varname())
           item.setText(2, instr.get_type())
           item.setText(3, instr.get_properties_list_fixed()[1].get_value()   )
          
           comment=""
           for list in [ instr.get_properties_list_fixed()[2:],  instr.get_properties_list(instr.get_option())  ]: 
               for tok in list:
                  if(tok.get_argument_key()!="None"):
                     comment=comment+tok.get_argument_key() +" = " + tok.get_value()+"///"
                  else:
                     comment=comment+ tok.get_value()+" / "
           if(len(instr.get_option_dic())==1):
               item.setText(4, "----" )
           else:
               item.setText(4, instr.get_option_dic()[instr.get_option() ] )

		
           item.setText(5, comment )
        print " AGGIORNO OK"   
    def register(self,bean):
        self.bean=bean



class VarTable(QListView):
    """
        Widget to show the existing variable.
        Derived from the class QListView.
        Items ( of the type QListViewItem ) are stored in itemlist
        Variable names as function of item are stored in dictionary  tem_variable.

        When a variable item is clicked, the variable corresponding to the clicked item
        is retrieved by  item_variable,  knowing the name of the variable 
        the instruction generating such variable is retrieved through beans module
         method and the signal and a signal vartable_selected is emitted along 
         with the selected instruction as argument

        When enter is pressed on a selected item, the instruction is reuunned and the resulting
        value is printed ( see keyPressEvent(self, e) )

    """
    item_variable={}
    itemlist=[]
    def __init__(self, *args):
        apply(QListView.__init__, (self,) + args)
        self.vartable = self
        vartable=self.vartable

        vartable.addColumn(" Var.")
        vartable.addColumn(" Type")
        vartable.addColumn(" Values ??? ")


        self.connect(self, SIGNAL("selectionChanged()"), self.vartable_selected_action)


    def vartable_selected_action(self):
        selected= self.vartable.currentItem()
        if(selected in self.item_variable.keys()):
          var = self.item_variable[selected]
          self.emit( PYSIGNAL("vartable_selected"),(self.bean.map_varname_2_instruction(var),))
        else:
          var = None



    def keyPressEvent(self, e):
       if(e.type()== QEvent.KeyPress and e.key()== 4100 ):
	 selected=self.vartable.currentItem()
         if(selected is  None):
             return

         s=self.bean.headers+"\n"
         lineslist = self.CodeLines_win.itemlist
         instrs = self.CodeLines_win.item_instruction
         instcomp=None
         for tok in lineslist:
           instr = instrs[tok]
           if(instr.get_type()!="Minimiser"):
              s=s+instr.get_code()+"\n"
           if(instr.get_type() in ["Comparison", "KK_ForPlot", "Beta_Comparison"]):
              instcomp=instr
           if(instcomp is not None):
              print instcomp.get_varname()
              s=s+instcomp.get_varname()+".error()\n"
           
           dictio={}
         exec(s,dictio,dictio)
         print dictio.keys()
         selected.setText(2,str(dictio[ str(selected.text(0))  ]))
         

    def bean_changed(self):
       for item in self.itemlist:
          self.takeItem(item)
       self.itemlist=[]
       self.item_variable={}
        
       print " ECCO LE VARIABILI ", self.bean.get_varnames()
       for var in self.bean.get_varnames():
	   newitem=QListViewItem(self, var)
           self.itemlist.append(newitem)
           self.item_variable[newitem] = var
       self.vartable_changed_action()

    def vartable_changed_action(self):
        for item in self.itemlist:
           varia = self.item_variable[item]
           item.setText(0, varia)
           instr = self.bean.map_varname_2_instruction(varia)
           item.setText(1, instr.get_type() )

    def register(self,bean):
        self.bean=bean



class PWidget(QComboBox):
  """
         PWidget is derived from QComboBox and is used 
         to show and edit properties of a bean instruction.
         It is initialised with a property of the class
         property_container of the module beans.

         

  
  """
  def __init__(self, prop,bean, *args):
     self.property=prop
     varlist=prop.get_good_options()
     if(isinstance(varlist, type(()) ) ):
          apply(QComboBox.__init__ ,   (self,0,)     + args )  # ro
     else:
          apply(QComboBox.__init__ ,   (self,1,)     + args )  # rw
     tipo=prop.get_type()
     ## self.setStyle(Qt.QWindowStyle())
     for tok in list(varlist):
       self.insertItem(  tok  )
     self.connect(self, SIGNAL("activated (const QString&) "),
                  prop.set_value )

     self.setInsertionPolicy(QComboBox.NoInsertion)
     self.setEditText(prop.get_value())
     # self.installEventFilter(self)    
	

  def eventFilter(self,o, e ):
        #
        #  TODO : some color management : store old text self.oldtext
        #   if text has changed changed color in a non-verified color
        #
        if(e.type()== QEvent.MouseButtonPress):
          print " emetto help per la proprieta "
          self.emit(PYSIGNAL("prop_emit_help"), (self.property.get_help() ,))
       #
        # escape on a list item property will remove the property 
        #    ( management by bean )
        #
        elif(e.type()== QEvent.KeyPress and e.key()== 0x1000):
	     self.property.instruction.remove_property( self.property)
             pippo.avoidcrash2=self
             self.owner.changed()
        elif(e.type()== QEvent.FocusOut):
            print "CLEARFOCUS"
            self.property.set_value(self.currentText())
            self.emit( SIGNAL("activated (const QString&) " ),     (str(self.currentText()),) )      
        QComboBox.eventFilter(self,o, e )
        return 0

  def verify(self, text):
        #
        # something better could be done here
        # accessing propertie of self.property
        # Actually this is called when enter is pressed
        #
        #  TODO : some color management : store old text self.oldtext
        print " VERIFICO   "
        if(str(text)==""):
           self.setEditText("None")



class PropertiesEditor(QScrollView):
    """
         A scrollable window that show a list of PWdiget items
         plus a QVBox for the selection of the option
    """


    def __init__(self,*args):
        apply(QScrollView.__init__, (self,) + args)
        self.editedInstruction=None
        self.widgets=[]
        
    def register(self,bean):
        self.bean=bean

    def changed(self):
        print " EMETTO "
        self.emit(PYSIGNAL("changed"),(self.editedInstruction, ))

    def option_changed(self, op):
        op=str(op)
        values=self.op_dic.values()
        keys  =self.op_dic.keys()

        print self.op_dic
        print op
        index=values.index(op)
        key  = keys[index]

        print " SIGNAL ACTIVATED "
        
        self.editedInstruction.set_option(key)
        self.EditLine( self.editedInstruction, optionhasechanged=1)
        print " EMETTO SIGNA "
        self.emit(PYSIGNAL("option_changed"),()) 
	pippo.avoidcrash=None
        print " EMETTO SIGNA OK "
        self.changed()

    def propEmitHelp(self, help):
        self.emit(PYSIGNAL("prop_emit_help"), (help ,))   
         

    def EditLine(self, instruction, optionhasechanged=0):
        print  " sono in editline "	
        if(instruction is None):
          self.editedInstruction=instruction
          for widget in self.widgets:
             print " cavo ", widget
             self.removeChild( widget )
          self.widgets=[]
          return          
        if(instruction is not self.editedInstruction or  optionhasechanged==1): 
          self.editedInstruction=instruction
          # self.widgets.reverse()
          if (optionhasechanged==1): pippo.toavoidcrash=self.widgets[0]
          for widget in self.widgets:
             print " cavo ", widget
             self.removeChild( widget )
          self.widgets=[]

          ############################
          # add the options
          y=0
          qbox=QVBox(self.viewport())
          self.widgets.append(qbox)
          self.addChild(qbox)

          newLabel =  QLabel( "Option" ,   qbox )
          newWidget = QComboBox(0, qbox)
          QLabel( "----" ,   qbox )
          self.op_dic = instruction.get_option_dic()
          self.op     = instruction.get_option() 
          print " OPZIONI ", self.op_dic.values()
          print " opzione  ", self.op

          for tok in self.op_dic.values():       
              newWidget.insertItem( tok  )

          newWidget.setCurrentItem( self.op_dic.keys().index( self.op   )   )
          newWidget.connect(newWidget, SIGNAL("activated (const QString&) "),self.option_changed )
          
          newLabel.setAutoResize(1)

          newWidget.show()
          newLabel.show()
 
          ############################
          # add the properties 
          for plist in [instruction.get_properties_list_fixed() , instruction.get_properties_list(instruction.get_option())      ]:
           for p in plist:
             print " aggiungo in ", y
             newLabel =  QLabel( p.get_property_name() ,  qbox )
             newWidget = PWidget(p,self.bean, qbox)
             newWidget.owner=self
             QLabel( "----" ,  qbox )
             newWidget.connect(newWidget, SIGNAL("textChanged (const QString&) "),
                  newWidget.verify )
             newWidget.connect(newWidget, SIGNAL("activated (const QString&) "),
                  self.changed )
             newWidget.connect(newWidget, PYSIGNAL("prop_emit_help "),self.propEmitHelp)

             newLabel.setAutoResize(1)

             newWidget.show()
	     varlist=p.get_good_options()
	     if(p.get_value() in varlist):
                  newWidget.setCurrentItem (list(varlist).index( p.get_value()))

             newLabel.show()

          print " LISTA ORA ", self.widgets
          qbox.show()
          self.show()
          # pippo.toavoidcrash=None


class BeanThread(Thread):

    def __init__(self, foo, s):
        self.foo=foo
        self.s=s
        apply(Thread.__init__, (self, ))
        
    def run(self):
         self.foo(self.s)
         
	
class EditPar_QTextEdit(qt.QTextEdit):
	def __init__(self,*args,**keys):
		qt.QTextEdit.__init__(self,*args,**keys)
        def keyPressEvent( self,  e ):
		tx=  e.ascii()
		sta = e.state()
		if( sta ==qt.Qt.ShiftButton  and tx==13):
			s=self.selectedText()
			if(str(s)==""):
				(para,inde)=self.getCursorPosition()
				s=self.text(para)
			self.emit(qt.PYSIGNAL("cmdln_QTextEdit_execute_sgnl()"),(s,))
		else:
			qt.QTextEdit.keyPressEvent(self,e)


from mdi import *
class MainWindow(QMainWindow):
# class MainWindow(ApplicationWindow):

    def __init__(self, *args):
        apply(QMainWindow.__init__, (self,) + args)
        # apply(ApplicationWindow.__init__, (self,) + args)
        self.setCaption("Scripting  Interface")


        self.splitV =  QSplitter( self )
        self.splitV.setOrientation( Qt.Vertical )

        self.splitH1 =  QSplitter( self.splitV )
        self.splitH1.setOrientation( Qt.Horizontal )

        self.splitH2 =  QSplitter( self.splitV )
        self.splitH2.setOrientation( Qt.Horizontal )


        self.InstMled_win = QMultiLineEdit(self.splitV)

	self.InstTable_win = InstructionsTable(self.splitH1)
        self.CodeLines_win = CodeLinesTable   (self.InstTable_win.instruction_classes_Rev_dic ,self.splitH2)


        self.PropertiesEditor = PropertiesEditor(self.splitH1)
        self.varTable = VarTable(self.splitH1)
        self.varTable.CodeLines_win = self.CodeLines_win

        self.classHelpMled_win = QMultiLineEdit(self.splitH1)
        self.propHelpMled_win  = QMultiLineEdit(self.splitH1)

        self.connect(self.CodeLines_win,PYSIGNAL("selectedline_changed"), self.PropertiesEditor.EditLine)
        self.connect(self.PropertiesEditor, PYSIGNAL("changed"), self.CodeLines_win.codelines_changed_action )
        self.connect(self.PropertiesEditor, PYSIGNAL("changed"), self.varTable.bean_changed )
        self.connect(self.CodeLines_win, PYSIGNAL("line_removed"), self.varTable.bean_changed )
        self.connect(self.varTable, PYSIGNAL("vartable_selected"), self.CodeLines_win.select_instr )
        self.connect(self.PropertiesEditor, PYSIGNAL("option_changed"),    self.CodeLines_win.codelines_changed_action )
        self.connect(self.CodeLines_win,PYSIGNAL("selectedline_changed"), self.show_codeline)
        self.connect(self.PropertiesEditor, PYSIGNAL("changed"),  self.show_codeline)

        self.connect(self.PropertiesEditor, PYSIGNAL("prop_emit_help"),  self.propHelpMled_win.setText     )
        self.connect(self.InstTable_win, PYSIGNAL("class_emit_help"),  self.classHelpMled_win.setText     )


        self.splitH1.setResizeMode (self.InstTable_win, QSplitter.Stretch )
        self.splitH2.setResizeMode (self.CodeLines_win, QSplitter.Stretch )
        self.splitH1.setResizeMode (self.PropertiesEditor, QSplitter.Stretch )
        self.splitV.setResizeMode (self.splitH1, QSplitter.Stretch )
        self.splitH1.setResizeMode (self.classHelpMled_win, QSplitter.Stretch )
        self.splitH1.setResizeMode (self.propHelpMled_win, QSplitter.Stretch )

        self.setCentralWidget(self.splitV)

        self.plots=[]
        self.plots_track=[]
        self.running=0
	BLock=None
        # Define actions


        self.actionSaveCode=QAction(self, "savecode")
        self.actionSaveCode.setText("Save as code")
        self.actionSaveCode.setMenuText("Save as &code")
        self.actionSaveCode.setToolTip("Generate the code and save it ot a file")
        self.actionSaveCode.setWhatsThis("Generate the code and save it ot a file")
        self.actionSaveCode.setStatusTip("Generate the code and save it ot a file")
        self.actionSaveCode.setAccel(Qt.CTRL + Qt.Key_C)
        self.actionSaveCode.setIconSet(QIconSet(QPixmap(diskIcon)))

        self.connect(self.actionSaveCode,
                     SIGNAL("activated()"),
                     self.saveCodeAction)


        self.actionSaveBean=QAction(self, "savebean")
        self.actionSaveBean.setText("Save as bean")
        self.actionSaveBean.setMenuText("Save as &bean")
        self.actionSaveBean.setToolTip("Save bean to  file")
        self.actionSaveBean.setWhatsThis("Save bean to  file")
        self.actionSaveBean.setStatusTip("Save bean to  file")
        self.actionSaveBean.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionSaveBean.setIconSet(QIconSet(QPixmap(beanIcon)))

        self.connect(self.actionSaveBean,
                     SIGNAL("activated()"),
                     self.saveBeanAction)


        self.actionExecute=QAction(self, "Run")
        self.actionExecute.setText("Run")
        self.actionExecute.setMenuText("&Run the bean")
        self.actionExecute.setToolTip("Run the bean")
        self.actionExecute.setWhatsThis("Run the bean")
        self.actionExecute.setStatusTip("Run the bean")
        self.actionExecute.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionExecute.setIconSet(QIconSet(QPixmap(connectIcon)))

        self.connect(self.actionExecute,
                     SIGNAL("activated()"),
                     self.executeAction)


        self.actionEmergencyStopThread=QAction(self, "EmergencyStopThread")
        self.actionEmergencyStopThread.setText("EmergencyStopThread")
        self.actionEmergencyStopThread.setMenuText("&EmergencyStopThread")
        self.actionEmergencyStopThread.setToolTip("EmergencyStopThread")
        self.actionEmergencyStopThread.setWhatsThis("EmergencyStopThread")
        self.actionEmergencyStopThread.setStatusTip("EmergencyStopThread")
##         self.actionStopThread.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionEmergencyStopThread.setIconSet(QIconSet(QPixmap(EmergencystopIcon)))

        self.connect(self.actionEmergencyStopThread,
                     SIGNAL("activated()"),
                     self.EmergencystopThreadAction)


        self.actionStopThread=QAction(self, "StopThread")
        self.actionStopThread.setText("StopThread")
        self.actionStopThread.setMenuText("&StopThread")
        self.actionStopThread.setToolTip(" Delayed Stop Thread")
        self.actionStopThread.setWhatsThis("StopThread")
        self.actionStopThread.setStatusTip("StopThread")
##         self.actionStopThread.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionStopThread.setIconSet(QIconSet(QPixmap(stopIcon)))

        self.connect(self.actionStopThread,
                     SIGNAL("activated()"),
                     self.stopThreadAction)


        self.actionCheckThread=QAction(self, "CheckThread")
        self.actionCheckThread.setText("CheckThread")
        self.actionCheckThread.setMenuText("&CheckThread")
        self.actionCheckThread.setToolTip("CheckThread")
        self.actionCheckThread.setWhatsThis("CheckThread")
        self.actionCheckThread.setStatusTip("CheckThread")
        ##  self.actionCheckThread.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionCheckThread.setIconSet(QIconSet(QPixmap(refreshIcon)))
        self.connect(self.actionCheckThread,
                     SIGNAL("activated()"),
                     self.checkThreadAction)


        self.actionLoadBean=QAction(self, "LoadBean")
        self.actionLoadBean.setText("Load bean")
        self.actionLoadBean.setMenuText("&Load Bean")
        self.actionLoadBean.setToolTip("Load Bean")
        self.actionLoadBean.setWhatsThis("Load Bean")
        self.actionLoadBean.setStatusTip("Load Bean")
        self.actionLoadBean.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionLoadBean.setIconSet(QIconSet(QPixmap(loadBeanIcon)))

        self.connect(self.actionLoadBean,
                     SIGNAL("activated()"),
                     self.loadBeanAction)


        self.actionGraph=QAction(self, "JustView")
        self.actionGraph.setText("JustView")
        self.actionGraph.setMenuText("&JustView")
        self.actionGraph.setToolTip("JustView")
        self.actionGraph.setWhatsThis("JustView")
        self.actionGraph.setStatusTip("JustView")
##         self.actionStopThread.setAccel(Qt.CTRL + Qt.Key_B)
        self.actionGraph.setIconSet(QIconSet(QPixmap(graphIcon)))

        self.connect(self.actionGraph,
                     SIGNAL("activated()"),
                     self.graphAction)






        self.CmdLine=QAction(self, "CommandLine")
        self.CmdLine.setText("CommandLine")
        self.CmdLine.setMenuText("&CommandLine")
        self.CmdLine.setToolTip("CommandLine")
        self.CmdLine.setWhatsThis("CommandLine")
        self.CmdLine.setStatusTip("CommandLine")
        # self.CmdLine.setIconSet(QIconSet(QPixmap(graphIcon)))

        self.connect(self.CmdLine,
                     SIGNAL("activated()"),
                     self.CmdLineAction)









        # Statusbar
        self.statusBar=QStatusBar(self)

        # Define menu
        self.menu=QPopupMenu()

        self.actionSaveCode.addTo(self.menu)
        self.actionSaveBean.addTo(self.menu)
        self.actionExecute.addTo(self.menu)
        self.actionLoadBean.addTo(self.menu)
        self.actionStopThread.addTo(self.menu)
        self.actionCheckThread.addTo(self.menu)
        self.actionGraph.addTo(self.menu)
        self.CmdLine.addTo(self.menu)
        self.menuBar().insertItem("&File", self.menu)

        # Define menu

        self.actionAboutSoft=QAction(self, "About this soft")
        self.actionAboutSoft.setText("About this soft")
        self.actionAboutSoft.setMenuText("&About this soft")
        self.actionAboutSoft.setToolTip("About this soft")
        self.actionAboutSoft.setWhatsThis("About this soft")
        self.actionAboutSoft.setStatusTip("About this soft")
        # self.actionAboutSoft.setIconSet(QIconSet(QPixmap(loadBeanIcon)))

        self.connect(self.actionAboutSoft,
                     SIGNAL("activated()"),
                     self.OnactionAboutSoft)




        self.menuHelp=QPopupMenu()

        self.actionAboutSoft.addTo(self.menuHelp)
        # self.actionAboutQt.addTo(self.menuHelp)
        self.menuBar().insertItem("&Help", self.menuHelp)





        # Define toolbar
        self.toolBar=QToolBar(self, 'Main')

        self.actionSaveCode.addTo(self.toolBar)

        self.actionSaveBean.addTo(self.toolBar)

        self.actionExecute.addTo(self.toolBar)
        
        self.actionStopThread.addTo(self.toolBar)
        self.actionEmergencyStopThread.addTo(self.toolBar)

        self.actionCheckThread.addTo(self.toolBar)
        
        self.actionLoadBean.addTo(self.toolBar)
        self.actionGraph.addTo(self.toolBar)

        timer =  QTimer( self )
        self.intrack=0
        self.connect( timer, SIGNAL("timeout()"), self.graphTrackAction )
        timer.start(100)


    def OnactionAboutSoft(self):
        msg=""
        print sys.modules.keys()
        if( "ppmtens" in sys.modules.keys()):
          msg =msg + " PPM tensorial : Version " +  sys.modules["ppmtens"].__version__ +"\n" 
        else:
          if( "ppm" in sys.modules.keys()):
            msg =msg + " PPM scalar : Version " +  sys.modules["ppm"].__version__ +"\n"
        msg = msg +"beansgui scripting interface : Version " +  sys.modules["beansgui"].__version__ +"\n"
        msg=msg+'\nAUTHOR: Alessandro MIRONE mirone@esrf.fr '     
        qt.QMessageBox.about(self,  "PPM"      ,msg)
        qt.QMessageBox.aboutQt(self)
        msg="This program uses PyDVT as plotting tool\n"
        msg=msg+"PyDVT has been written by Alexandre GOBBO during a short stay at ESRF\n"
        qt.QMessageBox.about(self,  "PyDVT"      ,msg)
        
        msg="This program uses also www.python.org  and www.numpy.org\n"
        msg="Some inner loop is coded in C using the numpy-API and the GNU gcc compiler\n"
        qt.QMessageBox.about(self,  "GNU"      ,msg)


    def  graphAction(self):
      print " graph action "
      s=self.bean.headers+"\n"
      lineslist = self.CodeLines_win.itemlist
      instrs = self.CodeLines_win.item_instruction
      instcomp=None
      for tok in lineslist:
        instr = instrs[tok]
        if( instr.get_varname() is not None):
          if(instr.get_type()!="Minimiser" ):
            s=s+instr.get_code()+"\n"
          if(instr.get_type()=="Comparison" or instr.get_type()=="KK_ForPlot"
             or instr.get_type()=="Beta_Comparison"):
            instcomp=instr
            if(instr.get_type()=="Beta_Comparison"):
               Type="ED"
            else:
               Type="WAD"

      if(instcomp is not None):
        vn=instcomp.get_varname()
        if(vn==""):
          for i in range(1000): print " YOU HAVE TO NAME THE OBJECT TO PLOT !!!!!!!!!!!!!!!! \n"
          return
        s=s+instcomp.get_varname() + ".error()\n"
      else:
          for i in range(1000): print " FOUND NO OBJECT TO PLOT !!!!!!!!!!!!!!!! \n"

      if(self.running==0):
              print " ESEGUO2"
              print s
	      self.executeString2(s)
	      namespace = self.threadDictio2
      else:
	      namespace = self.threadDictio

      if("show_var" in dir(self)):
	   self.show_var.Update("Graph ==> \n")

      fitobject= namespace[instcomp.get_varname()]

      scanstoplot=[]

      count=0
      if(len(self.plots)==0):
	self.plots.append( beansView_Multiple())
        self.plots[-1].show()
        self.plots[-1].setCaption("Graph #%d  "%count)
      p=self.plots[0]
      for count in range(len(fitobject.calculatedscan ) ) :
        calculated=fitobject.calculatedscan[count]
        if(Type=="WAD"):
          if(fitobject.scanlist[count][2] is not None):
              data= fitobject.scanlist[count][2]
          else:
              data=fitobject.calculatedscan[count]
          scanstoplot.append(( fitobject.scanlist[count][0],  
                                fitobject.scanlist[count][1],
                                fitobject.calculatedscan[count],
                                data
                       ))
        elif(Type=="ED"):

            if(fitobject.scanlist[count][1] is not None):
              data= fitobject.scanlist[count][1]
            else:
              if( fitobject.secondmodel !=[] ):
                 data = fitobject.secondmodel[count]
              else:
                 data=fitobject.calculatedscan[count]
                 
            scanstoplot.append(( fitobject.scanlist[count][0],  
                                fitobject.calculatedscan[count],
                                data
                       ))
      if(Type=="WAD"):
            p.TakeCalculatedScanWAD( scanstoplot )
      elif(Type=="ED"):
            p.TakeCalculatedScanEd( scanstoplot )
      p.Rescale()
      p.plot()



    def  graphTrackAction(self):


      if(self.intrack==1):
         return

      self.intrack=1
      if(self.running==0 or hasattr(self, "threadDictio")==0):
              self.intrack=0
              return
      else:	
	      namespace = self.threadDictio


      if(hasattr(self,"instcomp")==0):
        self.intrack=0
	return

      instr = self.instcomp


      if(instr.get_type() not in ["Comparison" , "KK_ForPlot", "Beta_Comparison"]):
         self.intrack=0
         return

      

      if(instr.get_type()=="Beta_Comparison"):
               Type="ED"
      else:
               Type="WAD"

      if( self.instcomp.get_varname() not in namespace.keys() ):
           self.intrack=0
           return
      fitobject= namespace[self.instcomp.get_varname()]


      if( hasattr(fitobject, "calculatedscan")==0 ): 
           self.intrack=0
           return


      if(hasattr(self,"old_calculated")==0):
         self.old_calculated=None

      if( self.old_calculated is fitobject.calculatedscan):
           self.intrack=0
           return
      else:
           self.old_calculated =  fitobject.calculatedscan

      BLock.acquire()

      count=0
      if(len(self.plots_track)==0):
	   self.plots_track.append( beansView_Multiple())
           self.plots_track[-1].show()
           self.plots_track[-1].setCaption("Tracker #%d  "%count)
      p=self.plots_track[0]

      scanstoplot=[]

      if(Type=="WAD"):
      	if( hasattr(fitobject, "calculatedscan")==0 ): 
    		self.intrack=0
      		BLock.release()
		return

      for count in range(len(fitobject.calculatedscan ) ) :

        calculated=fitobject.calculatedscan[count]
        scan_1 = fitobject.scanlist[count][0]
        scan_2 = fitobject.scanlist[count][1]
        scan = fitobject.scanlist[count][2]
        if(scan is None):
          scan=calculated
        if(Type=="WAD"):
          if(fitobject.scanlist[count][2] is not None):
             data= fitobject.scanlist[count][2]
          else:
             data=fitobject.calculatedscan[count]
          scanstoplot.append(( fitobject.scanlist[count][0],  
                                fitobject.scanlist[count][1],
                                fitobject.calculatedscan[count],
                                data
                       ))
        elif(Type=="ED"):
            if(fitobject.scanlist[count][1] is not None):
              data= fitobject.scanlist[count][1]
            else:
              if( hasattr(fitobject, "secondmodel")==0 ): 
	        self.intrack=0
      		BLock.release()
		return
              if( fitobject.secondmodel !=[] ):
                 data = fitobject.secondmodel[count]
              else:
                 data=fitobject.calculatedscan[count]

            scanstoplot.append(( fitobject.scanlist[count][0],  
                                fitobject.calculatedscan[count],
                                data
                       ))

 


      if(Type=="WAD"):
          p.TakeCalculatedScanWAD( scanstoplot)
      elif(Type=="ED"):
          p.TakeCalculatedScanED( scanstoplot )

      p.Rescale()
      self.intrack=0  
      BLock.release()

    def checkThreadAction(self):
        varnames=self.bean.map_typename_2_varnames("Variable")
        for name in varnames:
          instr=self.bean.map_varname_2_instruction(name)
          prop = instr.get_properties_list_fixed()[2]
          threadevar=self.threadDictio[name]
          print  threadevar
          prop.set_value( "%s" % threadevar.value)
          self.CodeLines_win.codelines_changed_action()



    def GetVariablesText(self): 
      varnames=self.bean.map_typename_2_varnames("Variable")
      print " la lista di variabili est ", vars
      s=""
      varnames.sort()
      for name in varnames:
         instr=self.bean.map_varname_2_instruction(name)
         print instr,name
         prop = instr.get_properties_list_fixed()
       	 s= s + "\n" + name + ("=   " +"Variable") 
         entry1=prop[2].get_value() 
         entry2=prop[3].get_value()
         entry3=prop[4].get_value()
         s=s+ (" (%s ,%s, %s )  ; " %  ( entry1 , entry2 , entry3 ) )
      return s


    def CmdLineAction(self):
  	  qml=EditPar_QTextEdit()
          qml.show()
	  s = self.GetVariablesText()
          qml.setText(s)
	  qml.connect(qml,
					qt.PYSIGNAL("cmdln_QTextEdit_execute_sgnl()"),
					self.CmdLineExecute)
	  self.qml1=qml


    def CmdLineExecute(self, s):
        import Minimiser
        variables = {"Variable":Minimiser.Variable}
	print globals().keys()
        print variables.keys()
	exec(str(s), globals(), variables )

        varnames=self.bean.map_typename_2_varnames("Variable")
        for name in varnames:
          if name in  variables.keys():
           threadevar=variables[name]
           instr=self.bean.map_varname_2_instruction(name)
           prop = instr.get_properties_list_fixed()[2]
           print  threadevar
           prop.set_value( "%s" % threadevar.value)
        self.CodeLines_win.codelines_changed_action()

    def EmergencystopThreadAction(self):
        global BLock
        Minimiser.minimiser.stoppa[0]=1
        self.running=0
	BLock=None
        # self.thread.stop()
    def stopThreadAction(self):
        global BLock
        Minimiser.minimiser.stoppa[1]=1
        self.running=0
	BLock=None
        # self.thread.stop()
        
    def loadBeanAction(self):
       filename=QFileDialog.getOpenFileName("", "*.bean", self, "FileDialog")
       filename=str(filename)
       f=open(str(filename),"r")
       saved=pickle.load( f)
       self.bean.property_container.space_of_variables = saved.space_of_variables 
       self.bean.property_container.instruction_for_variable = saved.instruction_for_variable  
       self.CodeLines_win.reload(saved.instructionlist) 
       self.varTable.bean_changed()
       
    def executeString(self,s):
      # self.threadDictio={}



      exec(s,self.threadDictio,self.threadDictio)

    def executeString2(self,s):
      self.threadDictio2={}



      exec(s,self.threadDictio2,self.threadDictio2)

    def executeAction(self):
      global BLock
      if(self.running):
          return
      s=self.bean.headers+"\n"
      lineslist = self.CodeLines_win.itemlist
      instrs = self.CodeLines_win.item_instruction
      for tok in lineslist:
        instr = instrs[tok]
        if(instr.get_type() in ["Comparison", "KK_ForPlot", "Beta_Comparison"]):
          self.instcomp=instr
        s=s+instr.get_code()+"\n"
      self.thread=BeanThread(self.executeString,s)
      Minimiser.minimiser.stoppa[0]=0
      Minimiser.minimiser.stoppa[1]=0
      self.running=1
      BLock = threading.Lock()



      ### @@@@@@ lanciare qui la finestra di update 
      self.threadDictio={}
      self.show_var     = (Show_Variables(self.bean,self.threadDictio, self.CodeLines_win ) )
      self.show_history = (Show_History(self.bean,self.threadDictio, self.CodeLines_win ) )

      self.thread.start()

      

    def saveCodeAction(self):
      filename=QFileDialog.getSaveFileName("", "*.auto.py", self, "FileDialog")
      filename=str(filename)
      if(glob.glob(filename)!=[]):
         QMessageBox.information( self, "BeansGUI",
                            "File exists. I will not overwrite it. Please choose another filename." );
         return
      if(filename==""): return
      if(filename.rfind("auto.py")==-1):
        filename=filename+".auto.py"
      f=open(str(filename),"w")
      s=self.bean.headers+"\n"
      lineslist = self.CodeLines_win.itemlist
      instrs = self.CodeLines_win.item_instruction
      for tok in lineslist:
        instr = instrs[tok]
##         if(instr.type=="Dabax_f1f2_Table"):
##            instr.constructor[1]="Dabax_f1f2_Table"
        s=s+instr.get_code()+"\n"
        print s
      f.write(s)
      f.close()
      pass

    def saveBeanAction(self):
      # da salvare tutto insieme in un solo oggetto
      # self.bean.space_of_variables
      # self.bean.instruction_for_variable
#    instruction_classes_dic      =   {}
#    instruction_superclasses_dic =   {}
#    instruction_classes_Rev_dic  =   {}
#    item_instruction      =   {}
#    itemlist              =   []
#    itemlistPoubelle       =   []
#    lastline = None
      salvando=dasalvare()
      salvando.space_of_variables       =  self.bean.property_container.space_of_variables
      salvando.instruction_for_variable =  self.bean.property_container.instruction_for_variable
      instructionlist=[self.CodeLines_win.item_instruction[item] for item in   self.CodeLines_win.itemlist      ]
      salvando.instructionlist      =  instructionlist


 


      filename=QFileDialog.getSaveFileName("", "*.bean", self, "FileDialog")
      filename=str(filename)
      if(glob.glob(filename)!=[]):
         QMessageBox.information( self, "BeansGUI",
                            "File exists. I will not overwrite it. Please choose another filename." );
         return
      
      if(filename==""): return
      if(filename.rfind("bean")==-1):
        filename=filename+"bean"
      f=open(str(filename),"w")
      pickle.dump( salvando,f)
      pass

    def show_codeline(self, instr):
        print instr
        if(instr is None): return
        print instr.get_code()
        self.InstMled_win.setText(instr.get_code())
        
    def register(self,bean):
        self.bean=bean
        self.InstTable_win.register(bean)
        self.CodeLines_win.register(bean)
        self.PropertiesEditor.register(bean)
        self.varTable.register(bean)

class dasalvare:
    pass





















class Show_Variables(QSplitter):
	def __init__(self,bean, dictio, codelines_win ):
                QSplitter.__init__(self, None, "Parameters")
		self.setOrientation( Qt.Vertical )

                self.cmdw = QWidget(self)
		self.updB = QPushButton("Update",self.cmdw,)
		self.mle=QMultiLineEdit(self)
                self.mle. setWordWrap(0)
		self.bean=bean
		self.dictio=dictio
		self.cdlw=codelines_win
                self.show()
		self.cmdw .show()
		self.updB.show()

                self.connect(self.updB,SIGNAL("clicked()"), self.Update)
        
        def Update(self, prefix=""): 
            ### @@@@@@ lanciare qui la finestra di update
            varnames=self.bean.map_typename_2_varnames("Variable")

            instrs = self.cdlw.item_instruction.values()
            instMin=None
            for  instr in instrs:
              if(instr.get_type()=="Minimiser"):
                 instMin=instr
            if( instMin is None):
               return


            vars = instMin.get_properties_list_fixed()[3].get_value()

            print " la lista di variabili est ", vars
            varsobjs= self.dictio[vars]
            s=prefix
            for name in varnames:
                instr=self.bean.map_varname_2_instruction(name)
                print instr,name
                prop = instr.get_properties_list_fixed()
                threadevar=self.dictio[name]
                if( threadevar  in varsobjs):

                  if(isinstance(threadevar , Minimiser.Variable   )):
       	            s= s + " " + name + ("=   " + str(threadevar.getvalue()) ) 
                    entry1=eval(prop[2].get_value() ,self.dictio, self.dictio)
                    entry2=eval(prop[3].get_value(),self.dictio, self.dictio)
                    entry3=eval(prop[4].get_value(),self.dictio, self.dictio)
                    s=s+ (" (%s ,%s, %s )  ; " %  ( entry1 , entry2 , entry3 ) )

                  else:
                    s= s + " " + name + ("=   " + str(threadevar) )

            s=s+"\n"
 
            self.mle.setText(str(self.mle.text())+s)


class Show_History(QSplitter):
	def __init__(self,bean, dictio, codelines_win ):
                QSplitter.__init__(self, None, "Parameters")
		self.setOrientation( Qt.Vertical )

                self.cmdw = QWidget(self)
		self.updB = QPushButton("Update",self.cmdw,)
		self.mle=QMultiLineEdit(self)
                self.mle. setWordWrap(0)
		self.bean=bean
		self.dictio=dictio
		self.cdlw=codelines_win
                self.show()
		self.cmdw .show()
		self.updB.show()

                self.connect(self.updB,SIGNAL("clicked()"), self.Update)
                self.setCaption("History of local minima")
                
        def Update(self, prefix=""): 
            ### @@@@@@ lanciare qui la finestra di update
            varnames=self.bean.map_typename_2_varnames("Variable")

            instrs = self.cdlw.item_instruction.values()
            instMin=None
            instComp=None
            for  instr in instrs:
              if(instr.get_type()=="Minimiser"):
                 instMin=instr
              if(instr.get_type() in ["Comparison",  "KK_ForPlot", "Beta_Comparison"]):
                 instComp=instr
            if( instMin is None):
               return
            if( instComp is None):
               return


            vars = instMin.get_properties_list_fixed()[3].get_value()
            # comp = instComp.get_properties_list_fixed()[0].get_value()
            # mini = instMin.get_properties_list_fixed()[0].get_value()

            print " la lista di variabili est ", vars
            # miniobj = self.dictio[mini]
            varsobjs= self.dictio[vars]

            s=""
            # print miniobj
            history=Minimiser.minimiser.history
            print " history est  ",  history
            for token in history:
              for name in varnames:
                  instr=self.bean.map_varname_2_instruction(name)
                  print instr,name
                  prop = instr.get_properties_list_fixed()
                  threadevar=self.dictio[name]
                  if( threadevar  in varsobjs):
     	            s= s + " " + name + "  " 
              s=s+"\n"
              s=s+str(token)+"\n"

            self.mle.setText(s)

  

def main(bean, args):
    print " ATTENZIONE 2"
   
    app=QApplication(args)
    mw=MainWindow()
    mw.application=app
    mw.show()
    app.setMainWidget(mw)
    app.connect(app, SIGNAL("lastWindowClosed()"),
                app, SLOT("quit()"))
    print " ?? NONE "
    if(bean is not None):
      mw.register(bean)
    app.exec_loop()

lanciagui=main





class beansView(GraphView):
  def __init__(self):
    GraphView.__init__(self)
    self.type=None
    raise "OK"
    print " FISSO Custom"

    self.Xtoplot="numbers" # "angles"  "wavel" "energy"
    self.AddMenuPopupItem("X=Numbers",self.setNumX)
    self.AddMenuPopupItem("Fit the scale",self.Rescale)

    self.AddMenuPopupItem("Write the data",self.writeData)


    self.AddMenuPopupItem("Toggle the zoom lock",self.fixZoom)
    self.rescale=1

    self.dicoItem={}
    self.dicoItem["X=Angles"]=self.AddMenuPopupItem("X=Angles",self.setAngX)
    self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
    self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)

  def writeData(self):
      filename=QFileDialog.getSaveFileName("", "*.data", self, "FileDialog")
      filename=str(filename)
      if(glob.glob(filename)!=[]):
         QMessageBox.information( self, "BeansGUI",
                            "File exists. I will not overwrite it. Please choose another filename." );
      data =  self.GetSource()


      count=0

      for tok in data:

        count=count+1

        file = open(filename+str(count),"w") 

        x = tok . GetOutput()['xdata']
        y = tok . GetOutput()['data']
 
        for i in range(len(x)):
            file.write("%e %e\n" %(x[i], y[i] ) )
      
        file.close()

        

  def removeType(self):

    if(self.type=="WAD"):
      pass
      self.DeleteMenuItem(self.dicoItem["X=Angles"])
      # self.DeleteMenuItem(self.dicoItem["X=Wavel"])
      # self.DeleteMenuItem(self.dicoItem["X=Energy"])
    elif(self.type=="ED"):
       pass
       # self.DeleteMenuItem(self.dicoItem["X=Wavel"])
       # self.DeleteMenuItem(self.dicoItem["X=Energy"])

    self.type=None

  def setType(self, type):

    self.removeType()

    if(type=="WAD"):
      self.dicoItem["X=Angles"]=self.AddMenuPopupItem("X=Angles",self.setAngX)
      # self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
      # self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)
    elif(type=="ED"):
      # self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
      # self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)
      pass
    else:

      raise " Wrong type in beansView.__init__ "

    self.type=type


  def SetYScaleLog(self,minval=1.0e-20):
        """
        Sets log scale for y axis
        Parameters:
           minvalue: all values less than or equals to 0 are set to it
        """
        self.Drawable.SetLogY(1,minval)
    

  def fixZoom(self):
    self.LockPosition(self.rescale)
    self.rescale=1-self.rescale
      

  def setNumX(self):
    self.Xtoplot="numbers"
    self.TakeCalculatedScan(self.scan)
    self.Rescale()

  def setAngX(self):
    self.Xtoplot="angles"
    self.TakeCalculatedScan(self.scan)
    self.Rescale()

  def setWavelX(self):
    self.Xtoplot="wavel"
    self.TakeCalculatedScan(self.scan)
    self.Rescale()

  def setEnergyX(self):
    self.Xtoplot="energy"
    self.TakeCalculatedScan(self.scan)
    self.Rescale()


  def TakeCalculatedScan(self, scan): 
      if(self.type=="WAD"):
         self.TakeCalculatedScanWAD( scan)
      elif(self.type=="ED"):
         self.TakeCalculatedScanED( scan)
      else:
         raise " WRONG self.type in TakeCalculatedScan "


  def TakeCalculatedScanWAD(self, scan): 

      self.setType("WAD")

      self.scan=scan

      if(self.Xtoplot=="numbers"):

        self.X=range(len(scan[0]))

      elif(self.Xtoplot=="angles"):
  	   self.X=self.scan[1]*180/math.pi

      elif(self.Xtoplot=="wavel"):
 	  self.X=self.scan[0]

      elif(self.Xtoplot=="energy"):
	  self.X=12398.52/self.scan[0]

      else:
          raise " Unknown self.Xtoplot in beansView"
 
      self.Y=self.scan[2]
      self.Y1=self.scan[3]


  def TakeCalculatedScanED(self, scan):
 
      self.setType("ED")

      self.scan=scan

      if(self.Xtoplot=="numbers"):
        self.X=range(len(scan[1]))

      elif(self.Xtoplot=="angles"):
          raise "Wrong combination of type/self.Xtoplot in beansView.TakeCalculatedScan"

      elif(self.Xtoplot=="wavel"):
	  self.X=12398.52/self.scan[0]

      elif(self.Xtoplot=="energy"):
  	  self.X=self.scan[0]

      else:
          raise " Unknown self.Xtoplot in beansView"
 
      self.Y =self.scan[1]
      self.Y1=self.scan[2]


  def Rescale(self):
      # print self.X
      # print " ############################## "
      # print self.Y1
      # print self.Y

      minx=reduce(min,self.X)
      miny=min (reduce(min,self.Y),reduce(min,self.Y1) )       
      maxx=reduce(max,self.X)
      maxy=max(reduce(max,self.Y), reduce(max,self.Y1))
      
      if(self.rescale):
        self.SetXAxis((minx,maxx))
        self.SetYAxis((miny,maxy))

      self.plot()

  def plot(self):

      tok1=Graph( self.Y ,pen=Pen( (255,0,0),1,"line"),xdata=self.X)
      tok2=Graph( self.Y1 ,pen=Pen( (0,255,255),1,"line"),xdata=self.X)
      self.SetSource((tok1,tok2  ))





class beansView_Multiple(GraphView):
  def __init__(self):
    GraphView.__init__(self)
    self.type=None
    self.Drawable.CustomEditText="""
# select the code you want to execute and the press <shift>+<Enter>
# the defined variables/functions are remembered
# so that subsequent times you use that you will
# probably have just to execute the "select" line
# To run a mono line just press <shift>+<eneter> while
# being there with your cursor
def select(ob,n):
  ob.parent.Source[0].Select(n)
  ob.parent.Source[1].Select(n)
  ob.parent.Refresh()

select(self, 0)
"""    

    self.AddMenuPopupItem("Choose graph",self.Drawable.EditPropertiesCustom)



    self.Xtoplot="numbers" # "angles"  "wavel" "energy"
    self.AddMenuPopupItem("X=Numbers",self.setNumX)
    self.AddMenuPopupItem("Fit the scale",self.Rescale)

    self.AddMenuPopupItem("Write the data",self.writeData)


    self.AddMenuPopupItem("Toggle the zoom lock",self.fixZoom)
    self.rescale=1

    self.dicoItem={}
    self.dicoItem["X=Angles"]=self.AddMenuPopupItem("X=Angles",self.setAngX)
    self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
    self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)



  def writeData(self):
      filename=QFileDialog.getSaveFileName("", "*.data", self, "FileDialog")
      filename=str(filename)
      if(glob.glob(filename)!=[]):
         QMessageBox.information( self, "BeansGUI",
                            "File exists. I will not overwrite it. Please choose another filename." );
      data =  self.GetSource()


      count=0

      for tok in data:

        count=count+1

        file = open(filename+str(count),"w") 

        x = tok . GetOutput()['xdata']
        y = tok . GetOutput()['data']
 
        for i in range(len(x)):
            file.write("%e %e\n" %(x[i], y[i] ) )
      
        file.close()

        

  def removeType(self):

    if(self.type=="WAD"):
      pass
      self.DeleteMenuItem(self.dicoItem["X=Angles"])
      # self.DeleteMenuItem(self.dicoItem["X=Wavel"])
      # self.DeleteMenuItem(self.dicoItem["X=Energy"])
    elif(self.type=="ED"):
       pass
       # self.DeleteMenuItem(self.dicoItem["X=Wavel"])
       # self.DeleteMenuItem(self.dicoItem["X=Energy"])

    self.type=None

  def setType(self, type):

    self.removeType()

    if(type=="WAD"):
      self.dicoItem["X=Angles"]=self.AddMenuPopupItem("X=Angles",self.setAngX)
      # self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
      # self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)
    elif(type=="ED"):
      # self.dicoItem["X=Wavel"]=self.AddMenuPopupItem("X=Wavel",self.setWavelX)
      # self.dicoItem["X=Energy"]=self.AddMenuPopupItem("X=Energy",self.setEnergyX)
      pass
    else:

      raise " Wrong type in beansView.__init__ "

    self.type=type


  def SetYScaleLog(self,minval=1.0e-20):
        """
        Sets log scale for y axis
        Parameters:
           minvalue: all values less than or equals to 0 are set to it
        """
        self.Drawable.SetLogY(1,minval)
    

  def fixZoom(self):
    self.LockPosition(self.rescale)
    self.rescale=1-self.rescale
      

  def setNumX(self):
    self.Xtoplot="numbers"
    self.TakeCalculatedScan(self.scans)
    self.Rescale()

  def setAngX(self):
    self.Xtoplot="angles"
    self.TakeCalculatedScan(self.scans)
    self.Rescale()

  def setWavelX(self):
    self.Xtoplot="wavel"
    self.TakeCalculatedScan(self.scans)
    self.Rescale()

  def setEnergyX(self):
    self.Xtoplot="energy"
    self.TakeCalculatedScan(self.scans)
    self.Rescale()


  def TakeCalculatedScan(self, scans): 
      if(self.type=="WAD"):
         self.TakeCalculatedScanWAD( scans)
      elif(self.type=="ED"):
         self.TakeCalculatedScanED( scans)
      else:
         raise " WRONG self.type in TakeCalculatedScan "


  def TakeCalculatedScanWAD(self, scans): 

      self.setType("WAD")

      self.scans=scans

      self.X=[]
      self.Y=[]
      self.Y1=[]
      for scan in scans:

        if(self.Xtoplot=="numbers"):

          self.X.append(range(len(scan[0])))

        elif(self.Xtoplot=="angles"):
    	   self.X.append(scan[1]*180/math.pi)

        elif(self.Xtoplot=="wavel"):
            self.X.append(scan[0])

        elif(self.Xtoplot=="energy"):
            self.X.append(12398.52/scan[0])

        else:
            raise " Unknown self.Xtoplot in beansView"
 
        self.Y.append(scan[2])
        self.Y1.append(scan[3])


  def TakeCalculatedScanED(self, scan):
 
      self.setType("ED")
      self.scans=scans

      self.X=[]
      self.Y=[]
      self.Y1=[]
      for scan in scans:

        if(self.Xtoplot=="numbers"):
          self.X.append(range(len(scan[1])))

        elif(self.Xtoplot=="angles"):
            raise "Wrong combination of type/self.Xtoplot in beansView.TakeCalculatedScan"

        elif(self.Xtoplot=="wavel"):
            self.X.append(12398.52/self.scan[0])

        elif(self.Xtoplot=="energy"):
            self.X.append(self.scan[0])
        else:
            raise " Unknown self.Xtoplot in beansView"
 
        self.Y.append(scan[1])
        self.Y1.append(scan[2])


  def Rescale(self):
      # print self.X
      # print " ############################## "
      # print self.Y1
      # print self.Y
      try:
        Nselected = self.Source[0].Nselected
      except:
        Nselected = 0

      X=array(self.X[Nselected],"d")
      Y=self.Y[Nselected]
      Y1=self.Y1[Nselected]

      
      minx=reduce(min,X)
      miny=min (reduce(min,Y),reduce(min,Y1) )       
      maxx=reduce(max,X)
      maxy=max(reduce(max,Y), reduce(max,Y1))

      if(self.rescale):
        self.SetXAxis((minx,maxx))
        self.SetYAxis((miny,maxy))

      self.plot()

  def plot(self):
      list1=[]
      list2=[]
      try:
        Nselected = self.Source[0].Nselected
      except:
        Nselected = 0
      for i in range(len(self.X)):
        list1.append(Graph( self.Y [i] ,pen=Pen( (255,0,0),1,"line"),xdata=self.X[i]))
        list2.append(Graph( self.Y1[i] ,pen=Pen( (0,255,255),1,"line"),xdata=self.X[i]))
      glist1=GraphList(list1)
      glist2=GraphList(list2)
      try:
        glist1.Select(Nselected)
        glist2.Select(Nselected)
      except:
        pass
      self.SetSource((glist1 ,glist2  ))



if __name__=="__main__":
    print " ATTENZIONE "
    main(None, sys.argv)
     















