Ejemplo n.º 1
0
class TextMode(object):        
    def quit(self, widget):
        self.window = None
        del self

    def __init__(self, canvas, monitor):
        self.canvas = canvas
        self.monitor = monitor
        
        #Carrega a interface a partir do arquivo glade
        self.gui = gtk.glade.XML('gui/text.glade')
        self.window = self.gui.get_widget('mainWindow')  
        
        self.filename = None
        
        self.textviewLogoProcedures = self.gui.get_widget('textviewLogoProcedures')
        self.textviewByteCodes = self.gui.get_widget('textviewByteCodes')
        self.textviewByteCodes.modify_font(pango.FontDescription('monospace').set_size(1252))

        # Buffers das caixas de texto
        self.LogoProceduresBuffer = gtk.TextBuffer()
        self.ByteCodesBuffer = gtk.TextBuffer()
        self.textviewLogoProcedures.set_buffer(self.LogoProceduresBuffer)
        self.textviewByteCodes.set_buffer(self.ByteCodesBuffer)

        self.LogoProceduresBuffer.set_modified(False)
        
        self.radiobuttonDecimal = self.gui.get_widget("radiobuttonDecimal")
        
        self.statusbar = self.gui.get_widget('statusbar')
        self.statusbar_cid = self.statusbar.get_context_id(_("Logo Procedures Editor"))
        self.reset_default_status()
        
        #Conecta Sinais aos Callbacks:        
        dic = {"gtk_main_quit" : gtk.main_quit}
        self.gui.signal_autoconnect(dic)    
        self.gui.signal_autoconnect(self)
        
        self.window.connect("destroy", self.quit)
        
        #Exibe toda interface:
        self.window.show_all() 
        
################    
    # When the window is requested to be closed, we need to check if they have 
    # unsaved work. We use this callback to prompt the user to save their work 
    # before they exit the application. From the "delete-event" signal, we can 
    # choose to effectively cancel the close based on the value we return.
    def on_mainWindow_delete_event(self, widget, event, data=None):
    
        if self.check_for_save(): self.on_save_menu_item_activate(None, None)
        return False # Propogate event
    
    # Called when the user clicks the 'New' menu. We need to prompt for save if 
    # the file has been modified, and then delete the buffer and clear the  
    # modified flag.    
    def on_new_menu_activate(self, menuitem, data=None):
    
        if self.check_for_save(): self.on_save_menu_activate(None, None)
        
        # clear editor for a new file
        buff = self.textviewLogoProcedures.get_buffer()
        buff.set_text("")
        buff.set_modified(False)
        
        self.ByteCodesBuffer.set_text("")
        
        self.filename = None
        self.reset_default_status()
    
    # Called when the user clicks the 'Open' menu. We need to prompt for save if 
    # thefile has been modified, allow the user to choose a file to open, and 
    # then call load_file() on that file.    
    def on_open_menu_activate(self, menuitem, data=None):
        
        if self.check_for_save(): self.on_save_menu_activate(None, None)
        
        filename = self.get_open_filename()
        if filename: self.load_file(filename)
       
    # Called when the user clicks the 'Save' menu. We need to allow the user to choose 
    # a file to save if it's an untitled document, and then call write_file() on that 
    # file.
    def on_save_menu_activate(self, menuitem, data=None):
        
        if self.filename == None: 
            filename = self.get_save_filename()
            if filename: self.write_file(filename)
        else: self.write_file(None)
        
    # Called when the user clicks the 'Save As' menu. We need to allow the user 
    # to choose a file to save and then call write_file() on that file.
    def on_save_as_menu_activate(self, menuitem, data=None):
        
        filename = self.get_save_filename()
        if filename: self.write_file(filename)
    
    # Called when the user clicks the 'Quit' menu. We need to prompt for save if 
    # the file has been modified and then break out of the GTK+ main loop          
    def on_quit_menu_activate(self, menuitem, data=None):

        if self.check_for_save(): self.on_save_menu_activate(None, None)
        self.window.destroy()
    
    # Called when the user clicks the 'Cut' menu.
    def on_cut_menu_activate(self, menuitem, data=None):

        buff = self.textviewLogoProcedures.get_buffer();
        buff.cut_clipboard (gtk.clipboard_get(), True);
        
    # Called when the user clicks the 'Copy' menu.    
    def on_copy_menu_activate(self, menuitem, data=None):
    
        buff = self.textviewLogoProcedures.get_buffer();
        buff.copy_clipboard (gtk.clipboard_get());
    
    # Called when the user clicks the 'Paste' menu.    
    def on_paste_menu_activate(self, menuitem, data=None):
    
        buff = self.textviewLogoProcedures.get_buffer();
        buff.paste_clipboard (gtk.clipboard_get(), None, True);
    
    # Called when the user clicks the 'Delete' menu.    
    def on_delete_menu_activate(self, menuitem, data=None):
        
        buff = self.textviewLogoProcedures.get_buffer();
        buff.delete_selection (False, True);
   

    # We call error_message() any time we want to display an error message to 
    # the user. It will both show an error dialog and log the error to the 
    # terminal window.
    def error_message(self, message):
    
        # log to terminal window
        print message
        
        # create an error message dialog and display modally to the user
        dialog = gtk.MessageDialog(None,
                                   gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                   gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message)
        
        dialog.run()
        dialog.destroy()
        
    # This function will check to see if the text buffer has been
    # modified and prompt the user to save if it has been modified.
    def check_for_save (self):
    
        ret = False
        buff = self.textviewLogoProcedures.get_buffer()
        
        if buff.get_modified():

            # we need to prompt for save
            message = _("Do you want to save the changes you have made?")
            dialog = gtk.MessageDialog(self.window,
                                       gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                       gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 
                                       message)
            dialog.set_title(_("Save?"))
            
            if dialog.run() == gtk.RESPONSE_NO: ret = False
            else: ret = True
            
            dialog.destroy()
        
        return ret

    def check_for_overwrite (self):
    
        ret = False
        buff = self.textviewLogoProcedures.get_buffer()
        
        if buff.get_modified():

            # we need to prompt for save
            message = _("This file already exists. Want to overwrite?")
            dialog = gtk.MessageDialog(self.window,
                                       gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                       gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, 
                                       message)
            dialog.set_title(_("Overwrite?"))
            
            if dialog.run() == gtk.RESPONSE_NO: ret = False
            else: ret = True
            
            dialog.destroy()
        
        return ret         
    
    # We call get_open_filename() when we want to get a filename to open from the
    # user. It will present the user with a file chooser dialog and return the 
    # filename or None.    
    def get_open_filename(self):
        
        filename = None
        chooser = gtk.FileChooserDialog(_("Open File..."), self.window,
                                        gtk.FILE_CHOOSER_ACTION_OPEN,
                                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 
                                         gtk.STOCK_OPEN, gtk.RESPONSE_OK))

        filter = gtk.FileFilter()
        filter.add_pattern("*."+"logo")
        filter.set_name(_("project")+" logo")
        chooser.add_filter(filter)                                         
        try:
            os.path.exists(self.filename)
            chooser.set_current_folder( os.path.dirname(self.filename) )
        except:
            home = os.getenv('USERPROFILE') or os.getenv('HOME')
            chooser.set_current_folder(home)
                                         
        response = chooser.run()
        if response == gtk.RESPONSE_OK: filename = chooser.get_filename()
        chooser.destroy()
        
        return filename
    
    # We call get_save_filename() when we want to get a filename to save from the
    # user. It will present the user with a file chooser dialog and return the 
    # filename or None.    
    def get_save_filename(self):
    
        filename = None
        chooser = gtk.FileChooserDialog(_("Save File..."), self.window,
                                        gtk.FILE_CHOOSER_ACTION_SAVE,
                                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, 
                                         gtk.STOCK_SAVE, gtk.RESPONSE_OK))
                                         
                                         
        filter = gtk.FileFilter()
        filter.add_pattern("*."+"logo")
        filter.set_name(_("project")+" logo")
        chooser.add_filter(filter)                                         
        try:
            os.path.exists(self.filename)
            chooser.set_current_folder( os.path.dirname(self.filename) )
        except:
            home = os.getenv('USERPROFILE') or os.getenv('HOME')
            chooser.set_current_folder(home)
           
        response = chooser.run()
        if response == gtk.RESPONSE_OK: filename = chooser.get_filename()
        chooser.destroy()
        
        if os.path.exists(filename):
            if self.check_for_overwrite():
                return filename
        else:
            if not '.' in filename:
                return filename+".logo"
            else:
                message = _("The file may not have dot")
                self.error_message(message)
                
    # We call load_file() when we have a filename and want to load it into the 
    # buffer for the GtkTextView. The previous contents are overwritten.    
    def load_file(self, filename):
    
        # add Loading message to status bar and ensure GUI is current
        self.statusbar.push(self.statusbar_cid, _("Loading %s") % filename)
        while gtk.events_pending(): gtk.main_iteration()
        
        try:
            # get the file contents
            fin = open(filename, "r")
            text = fin.read()
            fin.close()
            
            # disable the text view while loading the buffer with the text
            self.textviewLogoProcedures.set_sensitive(False)
            buff = self.textviewLogoProcedures.get_buffer()
            buff.set_text(text)
            buff.set_modified(False)
            self.textviewLogoProcedures.set_sensitive(True)
            
            # now we can set the current filename since loading was a success
            self.filename = filename
            
        except:
            # error loading file, show message to user
            self.error_message (_("Could not open file: %s") % filename)
            
        # clear loading status and restore default 
        self.statusbar.pop(self.statusbar_cid)
        self.reset_default_status()

    def write_file(self, filename):
    
        # add Saving message to status bar and ensure GUI is current
        if filename: 
            self.statusbar.push(self.statusbar_cid, _("Saving %s") % filename)
        else:
            self.statusbar.push(self.statusbar_cid, _("Saving %s") % self.filename)
            
        while gtk.events_pending(): gtk.main_iteration()
        
        try:
            # disable text view while getting contents of buffer
            buff = self.textviewLogoProcedures.get_buffer()
            self.textviewLogoProcedures.set_sensitive(False)
            text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
            self.textviewLogoProcedures.set_sensitive(True)
            buff.set_modified(False)
            
            # set the contents of the file to the text from the buffer
            if filename: fout = open(filename, "w")
            else: fout = open(self.filename, "w")
            fout.write(text)
            fout.close()
            
            if filename: self.filename = filename

        except:
            # error writing file, show message to user
            self.error_message (_("Could not save file: %s") % filename)
        
        # clear saving status and restore default     
        self.statusbar.pop(self.statusbar_cid)
        self.reset_default_status()
        
    def reset_default_status(self):        
        if self.filename:
            status = _("File: %s") % os.path.basename(self.filename)
        else:
            status = _("File:")+"(UNTITLED)"
        
        self.statusbar.pop(self.statusbar_cid)
        self.statusbar.push(self.statusbar_cid, status)
        
##############     
    def button_get_from_blocks_clicked_cb(self, widget):
        if self.LogoProceduresBuffer.get_char_count() > 1:
            if message(_("The procedures will be overwritten, are you sure you want to proceed?"), gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO) == gtk.RESPONSE_YES:
                self.LogoProceduresBuffer.set_text(self.canvas.get_code())
        else:
            self.LogoProceduresBuffer.set_text(self.canvas.get_code())
            
    def button_compile_clicked_cb(self, widget):
        from pyLogoCompiler.Communication import GoGoComms
        
        if self.monitor:
            self.GoGo = self.monitor.GoGo
        else:
            self.GoGo = GoGoComms()
        
        text = self.LogoProceduresBuffer.get_text(self.LogoProceduresBuffer.get_start_iter(),self.LogoProceduresBuffer.get_end_iter())
        result, ERCP = self.GoGo.compile(text)

        if result:
            byteCodes = self.GoGo.returnByteCode()
            
            if self.radiobuttonDecimal.get_active():
                self.ByteCodesBuffer.set_text(str(byteCodes))
            else:
                temp = []
                for  x in byteCodes:
                    temp.append(hex(x))
                self.ByteCodesBuffer.set_text(str(temp).upper().replace('X', 'x'))
        else:
            text = "ERROR->Look for a text containing one of the words: "+ERCP[0]
            message(_(text), gtk.MESSAGE_WARNING, gtk.BUTTONS_OK)
        return result
        
    def button_download_clicked_cb(self, widget):
        if self.button_compile_clicked_cb(widget):
            if not self.monitor:
                self.GoGo.autoConnect()
            
            self.GoGo.download()
            
            if not self.monitor:
                self.GoGo.closePort()
Ejemplo n.º 2
0
class Main( object ):
    """
    Classe principal
    """

    def __init__(self):
        
        #----------------
        #atributos
        #----------------
        
        self.maxblockwidth = 0    # Tamanho horizontal do bloco mais largo
        self.project = None        # Nome do projeto atual aberto
        self.menu = {}            # Contém os tipos de blocos
        self.monitor = None
        self.textmode = None
        self.codegui = None
        
        self.load_widgets()
        
        self.generate_blocklist()
        
        self.get_lastproject()
        
        #Conecta Sinais aos Callbacks:        
        dic = {"gtk_main_quit" : self.quit}
        self.maingui.signal_autoconnect(dic)
        self.mainwindow.connect("delete-event", self.close)
        
    def quit_by_menu(self,widget):
        val=self.close(self,widget)
        if not val :
            self.quit(self)
        
    def close(self,widget,event = None):
    
        def showdialog(text, type):      
            dialog = gtk.MessageDialog(None, gtk.DIALOG_NO_SEPARATOR, type, gtk.BUTTONS_NONE, text)
            button_ok = dialog.add_button("OK",gtk.RESPONSE_OK)
            button_save = dialog.add_button("Save",gtk.RESPONSE_YES)
            button_cancel = dialog.add_button("Cancel",gtk.RESPONSE_CLOSE)
            
            value = dialog.run()
            dialog.hide()
            return value
        
        if not self.canvas.is_saved():   #o metodo is_saved() mostra se houve alguma alteração no programa.
            text = _("There are unsaved alterations in your project, press OK to close without saving, Save to save and close, or Cancel.")
            response = showdialog(text, gtk.DIALOG_DESTROY_WITH_PARENT)
            
            if response == gtk.RESPONSE_OK:
                return False
            elif response == gtk.RESPONSE_CLOSE:
                return True
            elif response == gtk.RESPONSE_YES:
                self.save_proj(self)
                return False
            
                    
    def quit(self, widget):
        """
        Sai do programa
        """

        gtk.main_quit()
        #salva o projeto atual para
        #abrir na próxima execução
        f = open("user.dat","w")
        f.write(self.project)
        f.close()

    def get_lastproject(self):
        """
        lê qual foi o último projeto e abre
        """
        
        try:
            if os.path.exists("user.dat"):
                f = open("user.dat","r+")
            else:
                f = open("user.dat","w+")
        except:
            self.set_project("")
            return
            
        projectfile = f.read()
        
        print projectfile
        
        if os.path.exists(projectfile):
            
            self.canvas.load_proj(projectfile)
            
            self.set_project(projectfile)
        
        else:

            self.set_project("")
                
        f.close()

    def set_project(self, name):

        self.project = name
        
        if self.project != "":
            self.mainwindow.set_title(self.project+" - "+NAME)
        else:
            self.mainwindow.set_title(_("<no title project>")+" - "+NAME)

    def hide_generatedCode(self, widget):
        self.wincode.destroy()
        self.codegui = None

    def show_generatedCode(self, widget):
        
        """
        mostra uma janela com o código gerado pelos blocos
        """

        if self.codegui:
            self.wincode.present()
        else:
            self.codegui = gtk.glade.XML(config.glade_dir+"code.glade" )
            self.wincode = self.codegui.get_widget("winCode")
            exitbutton = self.codegui.get_widget("btnExit")
            exitbutton.connect("clicked", self.hide_generatedCode)
            txtcode = self.codegui.get_widget("txtCode")        
            
            self.wincode.set_title(_("Code"))
            
            txtbuffer = gtk.TextBuffer()
            txtbuffer.set_text(self.canvas.get_code())
            
            txtcode.set_buffer(txtbuffer)

            self.wincode.show_all()
    
    def close_monitor(self, widget):
        self.monitor = None
        if self.textmode:
            self.textmode.monitor = None
        
    def show_monitor(self, widget):
        from monitor import BoardMonitor
        if self.monitor:
            self.monitor.window.present()
        else:
            self.monitor = BoardMonitor()
            if self.monitor.window:
                self.monitor.window.connect("destroy", self.close_monitor)
            else:
                self.monitor = None
                
            if self.textmode:
                self.textmode.monitor = self.monitor

    def close_textmode(self, widget):
        self.textmode = None
        
    def show_textmode(self, widget):
        if self.textmode:
            self.textmode.window.present()
        else:
            from textmode import TextMode
            self.textmode = TextMode(self.canvas, self.monitor)
            if self.textmode.window:
                self.textmode.window.connect("destroy", self.close_textmode)
            else:
                self.textmode = None
    
    def about(self, *args):
        """
        Mostra uma janela com informações sobre o programa
        """
        
        aboutgui = gtk.AboutDialog()        
        aboutgui.set_name(NAME)
        aboutgui.set_version(VERSION)
        #aboutgui.set_copyright(copyright)
        #aboutgui.set_comments(comments)
        #aboutgui.set_license(license)
        #aboutgui.set_wrap_license(license)
        #aboutgui.set_website(website)
        #aboutgui.set_website_label(website_label)
        aboutgui.set_authors(AUTHORS)
        #aboutgui.set_documenters(documenters)
        #aboutgui.set_artists(artists)
        #aboutgui.set_translator_credits(translator_credits)    
        aboutgui.set_logo(gtk.gdk.pixbuf_new_from_file("gui/splash.png"))
        #aboutgui.set_logo(self.gui.get_widget('imageMonitor').get_pixbuf())
        #aboutgui.set_logo_icon_name(icon_name)        
        aboutgui.run()
        aboutgui.destroy()

    def help(self, *args):
        import webbrowser
        webbrowser.open('http://br-gogo.sourceforge.net/')

    def load_widgets(self):
        
        def undo(*args):
            self.canvas.undo()
        
        """
        Carrega e configura a maioria dos widgets do programa
        """
        
        #janela principal
        self.maingui = gtk.glade.XML(config.glade_dir+"main.glade" )
        self.mainwindow = self.maingui.get_widget( "mainwindow" )
        self.mainwindow.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        self.mainwindow.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
        self.mainwindow.connect("destroy", self.quit)
        self.maingui.get_widget( "statusbarVersion" ).push(0,_("Version")+' '+VERSION)
        #self.mainwindow.maximize()
        
        #labels das tabs de seleção de blocos
        label = [None]*8
        label[0] = self.maingui.get_widget( "lblControl"   )
        label[1] = self.maingui.get_widget( "lblFlow"      )
        label[2] = self.maingui.get_widget( "lblCondition" )
        label[3] = self.maingui.get_widget( "lblNumbers"   )
        label[4] = self.maingui.get_widget( "lblTime"      )
        label[5] = self.maingui.get_widget( "lblOthers"    )
        label[6] = self.maingui.get_widget( "lblProcedure" )
        label[7] = self.maingui.get_widget( "lblDisp" )
        
        map(lambda lbl: lbl.modify_font(pango.FontDescription("sans 13")), label)
        
        #em cada tab existe uma tree com seus respectivos blocos
        self.tree    = [None]*8
        self.tree[0] = self.maingui.get_widget("treecontrol")
        self.tree[1] = self.maingui.get_widget("treecond")
        self.tree[2] = self.maingui.get_widget("treeflow")
        self.tree[3] = self.maingui.get_widget("treenumbers")
        self.tree[4] = self.maingui.get_widget("treetime")
        self.tree[5] = self.maingui.get_widget("treeothers")
        self.tree[6] = self.maingui.get_widget("treeproc")
        self.tree[7] = self.maingui.get_widget("treedisp")
        
        #cria a treelist e a treefilter associada a cada tree
        self.treeList   = [None]*8
        self.treeList   = map( lambda i: gtk.TreeStore(gtk.gdk.Pixbuf), self.treeList )
        self.treeFilter = [None]*8
        self.treeFilter = map( lambda list: list.filter_new(), self.treeList )
        
        for i in xrange( len(self.tree) ):
            self.tree[i].set_model( self.treeFilter[i] )
            self.tree[i].get_selection().set_mode(gtk.SELECTION_SINGLE)
            
            column = gtk.TreeViewColumn(_("Tools"), gtk.CellRendererPixbuf() , pixbuf=0)
            self.tree[i].append_column(column)
            
            self.tree[i].connect("cursor-changed", self.treeblock_select, self.treeList[i] )
        
        self.downbutton = self.maingui.get_widget("downloadbutton")
        self.downbutton.connect("clicked", self.download)        
        
        #Nesse box serão colocadas as propriedades dos blocos
        self.PropBox = self.maingui.get_widget("BoxProperties")
        
        self.scrollCanvas = self.maingui.get_widget("scrollCanvas")
        self.canvas = Canvas(self.PropBox)
        self.scrollCanvas.add(self.canvas)
        
        self.menu_new = self.maingui.get_widget("menu_new")
        self.menu_new.connect("activate", self.new_proj)
        self.button_new = self.maingui.get_widget("button_new")
        self.button_new.connect("clicked", self.new_proj)
        
        self.menu_quit = self.maingui.get_widget("menu_quit")
        self.menu_quit.connect("activate", self.quit_by_menu)
        
        self.menu_save = self.maingui.get_widget("menu_save")
        self.menu_save.connect("activate", self.save_proj)
        self.button_save = self.maingui.get_widget("button_save")
        self.button_save.connect("clicked", self.save_proj)
        
        self.menu_saveas = self.maingui.get_widget("menu_saveas")
        self.menu_saveas.connect("activate", self.saveas_proj)
        
        self.menu_load = self.maingui.get_widget("menu_load")
        self.menu_load.connect("activate", self.load_proj)
        self.button_load = self.maingui.get_widget("button_load")
        self.button_load.connect("clicked", self.load_proj)
        
        self.menu_code = self.maingui.get_widget("menu_code")
        self.menu_code.connect("activate", self.show_generatedCode)
        self.button_code = self.maingui.get_widget("button_code")
        self.button_code.connect("clicked", self.show_generatedCode)
        
        self.menu_monitor = self.maingui.get_widget("menu_monitor")
        self.menu_monitor.connect("activate", self.show_monitor)
        self.button_monitor = self.maingui.get_widget("button_monitor")
        self.button_monitor.connect("clicked", self.show_monitor)        

        self.button_textmode = self.maingui.get_widget("button_textmode")
        self.button_textmode.connect("clicked", self.show_textmode) 
        
        self.menu_cut = self.maingui.get_widget("menu_cut")
        self.menu_cut.connect("activate", self.cut)
        
        self.menu_copy = self.maingui.get_widget("menu_copy")
        self.menu_copy.connect("activate", self.copy)
        
        self.menu_paste = self.maingui.get_widget("menu_paste")
        self.menu_paste.connect("activate", self.paste)
        
        self.menu_clear = self.maingui.get_widget("menu_clear")
        self.menu_clear.connect("activate", self.clear)
        
        self.menu_about = self.maingui.get_widget("menu_about")
        self.menu_about.connect("activate", self.about)
        
        self.menu_about = self.maingui.get_widget("menu_help")
        self.menu_about.connect("activate", self.help)

        self.menu_undo = self.maingui.get_widget("menu_undo")
        self.menu_undo.connect("activate", undo)
        
        self.mainwindow.show_all()
        
        self.movebar1 = self.maingui.get_widget("movebar1")
        self.movebar2 = self.maingui.get_widget("movebar2")
        

    def download(self, widget):
        
        """
        Envia o código gerado para a gogoBoard
        """
        
        from pyLogoCompiler import pyYacc
        from pyLogoCompiler.Communication import GoGoComms
 
        def showdialog(text, type):
           dialog = gtk.MessageDialog(None, gtk.DIALOG_NO_SEPARATOR, type, gtk.BUTTONS_NONE, text)
           #dialog.add_button("OK",gtk.RESPONSE_CLOSE)
           dialog.show()
           #dialog.destroy()
            
        v = self.canvas.code_ok()
        if v == 0:
            if self.monitor:
                self.GoGo = self.monitor.GoGo
            else:    
                self.GoGo = GoGoComms()
                self.GoGo.autoConnect()
                
            if self.GoGo.compile(self.canvas.get_code()):
                self.GoGo.download()
                if not self.monitor:
                    self.GoGo.closePort()
            else:
                if self.GoGo.returnByteCode() == None:
                    showdialog(_("Empty program."), gtk.MESSAGE_WARNING)
                else:
                    showdialog(_("There was a problem with the connection\nVerify that the board is properly connected with your computer"), gtk.MESSAGE_ERROR)
                    self.GoGo.closePort()
                return
            showdialog(_("Code successfully sent!\nClick the 'x' above to close"),gtk.MESSAGE_INFO)
            
        elif v == 1:
           showdialog(_("Some connections are missing in selected blocks"),gtk.MESSAGE_WARNING)
           
        elif v == 2:
           showdialog(_("Set Variable block only accepts variables"),gtk.MESSAGE_WARNING)      
    
    def cut(self, *args):
        """
        Evento de recortar blocos
        """
        self.canvas.cut()

    def copy(self, *args):
        """
        Evento de copiar blocos
        """
        self.canvas.copy()

    def paste(self, *args):
        """
        Evento de colar blocos
        """
        self.canvas.paste()

    def clear(self, *args):
        """
        Apaga todos os blocos da tela
        """
        self.canvas.clear()

    def add_block_tree(self, treelist, node, block):
        """
        Adiciona um ícone de bloco em uma treeview
        """
        pixbuf = block.get_menu_image()
        
        iter = treelist.append( node, [pixbuf,] )
        
        #Assim através de onde o mouse clicou
        #e de que lista está sendo usada, temos
        #o tipo de bloco que deve ser criado
        self.menu[(treelist, iter)] = block
        
        #atualiza a máxima largura de bloco
        if block.get_width() > self.maxblockwidth:
            self.maxblockwidth = block.get_width()
        
        return iter

    def del_block_tree(self, treelist, node):
        """
        Remove um ícone de bloco em uma treeview
        """
        treelist.remove( node )
        del self.menu[(treelist,node)]

    def generate_blocklist(self):
        
        """
        Cria árvores com listas de tipos de blocos
        para criar blocos do respectivo tipo
        """
        
        #newprocedure_block precisa saber qual é a
        #sua árvore, pois ele vai adicionar um ícone
        #para cada procedimento novo
        newprocedure_block.set_tree( self.treeList[6], self.add_block_tree, self.del_block_tree )
        
        #controle
        self.add_block_tree( self.treeList[0], None, on_block() )
        self.add_block_tree( self.treeList[0], None, off_block() )
        self.add_block_tree( self.treeList[0], None, brake_block() )
        self.add_block_tree( self.treeList[0], None, thisway_block() )
        self.add_block_tree( self.treeList[0], None, thatway_block() )
        self.add_block_tree( self.treeList[0], None, reverse_block() )
        self.add_block_tree( self.treeList[0], None, onfor_block() )
        self.add_block_tree( self.treeList[0], None, setpower_block() )
        self.add_block_tree( self.treeList[0], None, setposition_block() )
        
        #fluxo
        self.add_block_tree( self.treeList[2], None, if_block() )
        self.add_block_tree( self.treeList[2], None, ifelse_block() )
        self.add_block_tree( self.treeList[2], None, loop_block() )
        self.add_block_tree( self.treeList[2], None, repeat_block() )
        self.add_block_tree( self.treeList[2], None, wait_until_block() )
        self.add_block_tree( self.treeList[2], None, stop_block() )
        self.add_block_tree( self.treeList[2], None, while_block() )
       
        #comparação
        self.add_block_tree( self.treeList[1], None, comp_block() )
        self.add_block_tree( self.treeList[1], None, and_block() )
        self.add_block_tree( self.treeList[1], None, or_block() )
        self.add_block_tree( self.treeList[1], None, xor_block() )
        self.add_block_tree( self.treeList[1], None, not_block() )
        self.add_block_tree( self.treeList[1], None, switch_block() )
        
        #números
        self.add_block_tree( self.treeList[3], None, number_block() )
        self.add_block_tree( self.treeList[3], None, random_block() )
        self.add_block_tree( self.treeList[3], None, sensor_block() )
        self.add_block_tree( self.treeList[3], None, variable_block() )
        self.add_block_tree( self.treeList[3], None, set_variable_block() )
        self.add_block_tree( self.treeList[3], None, op_add_block() )
        self.add_block_tree( self.treeList[3], None, op_sub_block() )
        self.add_block_tree( self.treeList[3], None, op_mul_block() )
        self.add_block_tree( self.treeList[3], None, op_div_block() )
        self.add_block_tree( self.treeList[3], None, op_mod_block() )
        
        #outros
        self.add_block_tree( self.treeList[5], None, beep_block() )
        self.add_block_tree( self.treeList[5], None, comm_block() )
        self.add_block_tree( self.treeList[5], None, ledon_block() )
        self.add_block_tree( self.treeList[5], None, ledoff_block() )
        self.add_block_tree( self.treeList[5], None, show_block() )
        self.add_block_tree( self.treeList[5], None, send_block() ) 
        self.add_block_tree( self.treeList[5], None, recall_block() ) 
        self.add_block_tree( self.treeList[5], None, record_block() )  
        self.add_block_tree( self.treeList[5], None, resetdp_block() )  
      
        #tempo
        self.add_block_tree( self.treeList[4], None, time_block() )        
        self.add_block_tree( self.treeList[4], None, wait_block() )
        self.add_block_tree( self.treeList[4], None, resett_block() )
        self.add_block_tree( self.treeList[4], None, timer_block() )
        
        #procedimentos
        self.add_block_tree( self.treeList[6], None, newprocedure_block() )
        self.add_block_tree( self.treeList[6], None, endprocedure_block() )
        
        #disposicao
        self.add_block_tree( self.treeList[7], None, null_block() )
        self.add_block_tree( self.treeList[7], None, null2_block() )
        self.add_block_tree( self.treeList[7], None, null3_block() )
        
        #Posiciona as barras de acordo com o maior largura de bloco
        self.movebar1.set_position(self.maxblockwidth+100)
        self.movebar2.set_position(gtk.gdk.screen_width()*1/3-self.maxblockwidth+100)
        #self.canvas.set_size_request( gtk.gdk.screen_width()*2/3 - (self.maxblockwidth+100), 0 )

    def treeblock_select(self, tree, treelist):
        
        """
        Verifica qual é o tipo de bloco clicado na árvore
        e faz o canvas pedir a posição para a criação
        """
        (model, _iter) = tree.get_selection().get_selected()
        if _iter == None: return
        p = model.get_string_from_iter(_iter)        
        
        self.canvas.grab_focus()
        
        #descobre o tipo do bloco
        #através do caminho e da árvore
        for (t, it) in self.menu.keys():
            if t == treelist and p == t.get_string_from_iter(it):
                
                self.canvas.set_create_block( self.menu[ (t, it) ] )
                
                cursor = gtk.gdk.Cursor(gtk.gdk.display_get_default(), gtk.gdk.CROSS)
                self.mainwindow.window.set_cursor( cursor )
                break

    def new_proj(self, widget):
        
        """
        Tela para o usuário criar
        um novo projeto
        """
        
        dialog = gtk.FileChooserDialog("", None,
                                        gtk.FILE_CHOOSER_ACTION_SAVE,
                                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_NEW, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)
        proj = self.do_dialog(dialog)
        if proj and ((os.path.exists(proj) and warning_message(_("File %s will be overwritten, are you sure you want to proceed?") % proj) == gtk.RESPONSE_OK) or not os.path.exists(proj)):
           self.canvas.restart()
           self.canvas.save_proj( proj )
           self.set_project( proj )
                    
    def save_proj(self, widget):
        
        """
        Se o projeto nunca tiver sido salvo,
        pergunta onde salva, senão, salva em
        cima da versão antiga
        """
        
        if self.project == "":
            self.saveas_proj(None)
        else:
            self.canvas.save_proj(self.project)
            
    def saveas_proj(self, widget):
        
        """
        Tela para o usuário salvar
        o projeto em uso
        """
        
        dialog = gtk.FileChooserDialog(_("Save..."), None,
                                       gtk.FILE_CHOOSER_ACTION_SAVE,
                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)
        proj = self.do_dialog(dialog)
        
        if proj and ((os.path.exists(proj) and warning_message(_("File %s will be overwritten, are you sure you want to proceed?") % proj) == gtk.RESPONSE_OK) or not os.path.exists(proj)):
           self.canvas.save_proj( proj )
           self.set_project( proj )

    def load_proj(self, widget):
        
        """
        Tela para o usuário carregar
        um novo projeto e fechar o que
        estiver em uso
        """
        
        dialog = gtk.FileChooserDialog(_("Open..."), None,
                                        gtk.FILE_CHOOSER_ACTION_OPEN,
                                        (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dialog.set_default_response(gtk.RESPONSE_OK)
        proj = self.do_dialog(dialog)
        
        if os.path.exists(proj):
            self.canvas.load_proj(proj)
            self.set_project(proj)

    def do_dialog(self, dialog):
        
        """
        Abre uma tela de seleção
        de arquivo
        """
        
        result = ""
        filter = gtk.FileFilter()
        filter.add_pattern("*."+config.EXT)
        filter.set_name(_("project")+" "+config.EXT)
        dialog.add_filter(filter)
        
        if os.path.exists(self.project):
           dialog.set_current_folder( os.path.dirname(self.project) )
        else:
           home = os.getenv('USERPROFILE') or os.getenv('HOME')
           dialog.set_current_folder(home)
           
        response = dialog.run()
        if response == gtk.RESPONSE_OK: 
            result = dialog.get_filename()
            if result and os.path.splitext(result)[1] == "":
               result+="."+config.EXT 
        else:
            result = ""
        
        dialog.destroy()
        
        return result