<filename>src/hello.py
#!bin/python

##CODE GENERATED by gladizer 1.2

#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.



#python
import sys
import os, os.path
import urllib
import subprocess as sb
import mimetypes


#gtk
import pygtk
pygtk.require('2.0')
import gtk, gtk.glade
import pango
import gtksourceview2 as sv




from widgets import FileBrowserTV, SidePaneBrowser, BottomPane, TabWidget, LeftSidePane, PythonSourcePlugin, WC, BracketCompletionViewHelper

#from gregextoolkitdialog import RegexToolkitDialog
from gregextoolkitdialog import RegexToolkit

#FIXME: language mapping.
def guess_file_type(filepath):
    t=mimetypes.guess_type(filepath)
    print "T:", t
    s=t[0]
    if "cs" in s:
        return "c-sharp"
    elif "c++" in s:
        return "cpp"
    elif "/x-" in s:
        return s[s.find("/x-")+len("/x-"):]
    else:
        return s[s.find('/')+1:]
        
TARGET_TYPE_URI_LIST = 80
dnd_list = [ ( 'text/uri-list', 0, TARGET_TYPE_URI_LIST ) ]

class MainWindow(object):

    def __init__(self):

        self.closequotesbraces=False
        #self.symbmapping={"(":")", "{":"}", "[":"]", "'":"'", "\"":"\""} 
        #Widget tree..
        self.wTree=gtk.glade.XML(os.path.join(os.path.dirname(__file__), 'ui', 'hello.glade'))

        #connect signals and handlers.
        self.wTree.signal_autoconnect(self)

        self._window1=self.wTree.get_widget('window1')
        self._table1=self.wTree.get_widget('table1')
        self._menubar1=self.wTree.get_widget('menubar1')
        self._menuitemfile=self.wTree.get_widget('menuitemfile')
        self._menu1=self.wTree.get_widget('menu1')
        self._menuitemnew=self.wTree.get_widget('menuitemnew')
        self._menuitemopen=self.wTree.get_widget('menuitemopen')
        self._menuitemsave=self.wTree.get_widget('menuitemsave')
        self._menuitemsaveas=self.wTree.get_widget('menuitemsaveas')
        self._separatormenuitem1=self.wTree.get_widget('separatormenuitem1')
        self._menuitemquit=self.wTree.get_widget('menuitemquit')
        self._menuitemedit=self.wTree.get_widget('menuitemedit')
        self._menu2=self.wTree.get_widget('menu2')
        self._menuitemcut=self.wTree.get_widget('menuitemcut')
        self._menuitemcopy=self.wTree.get_widget('menuitemcopy')
        self._menuitempaste=self.wTree.get_widget('menuitempaste')
        self._menuitemview=self.wTree.get_widget('menuitemview')
        self._menuiteabout=self.wTree.get_widget('menuiteabout')
        self._menu3=self.wTree.get_widget('menu3')
        self._menuitemabout=self.wTree.get_widget('menuitemabout')
        self._menuitemlanguage=self.wTree.get_widget('menuitemlanguage')
        
        self._menuitemfindreplace=self.wTree.get_widget('menuitemfindreplace')
        self._dialogfindreplace=self.wTree.get_widget('dialogfindreplace')
        self._dfrentrysearch=self.wTree.get_widget('entrysearch')
        self._dfrentryreplace=self.wTree.get_widget('entryreplace')
        #self._dialogfindreplace.connect("close", self.on_dialogfindreplace_close)
        #self._dialogfindreplace.connect("response", self.on_dialogfindreplace_response)
        self._dialogfindreplace.connect("delete-event", self.on_dialogfindreplace_delete_event)
        
        self._dialogwc=self.wTree.get_widget('dialogwc')
        self.lblgwcrange=self.wTree.get_widget('lblgwcrange')
        self.lblgwclines=self.wTree.get_widget('lblgwclines')
        self.lblgwcwords=self.wTree.get_widget('lblgwcwords')
        self.lblgwcchars=self.wTree.get_widget('lblgwcchars')
        self.lblgwccharsnospaces=self.wTree.get_widget('lblgwccharsnospaces')
        
        self.wc=WC() #wordcounter service
        
        
        self.dialoggotoline=self.wTree.get_widget('dialoggotoline')
        self.entrygotoline=self.wTree.get_widget('entrygotoline')
        
        self._maintoolbar=self.wTree.get_widget("maintoolbar")
        self._statusbar=self.wTree.get_widget('statusbar')
        self._scrolledwindoweditor=gtk.ScrolledWindow()
        self._scrolledwindoweditor.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self._hpaned1=self.wTree.get_widget('hpaned1')
        self._vpaned1=self.wTree.get_widget('vpaned1')
        self._tvpath=self.wTree.get_widget('tvpath')
        
        
        self._languagemanager=sv.LanguageManager()
        self._buflang=None
        
                
        #problem with glade..
        self._window1.connect("delete-event", self.on_window1_delete_event)
        self._window1.connect("destroy", self.on_window1_destroy)
        
        #DRAG AND DROP
        self._window1.connect('drag_data_received', self. on_drag_data_received)
        self._window1.drag_dest_set( gtk.DEST_DEFAULT_MOTION |
                  gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP,
                  dnd_list, gtk.gdk.ACTION_COPY)
        
        self._filename="" #current file.
        self._dirty=False #changed?
    
        self._prep_languages()
        self._prepare_toolbar()
        
        self._create_leftsidepane()
        self._init_editor()
        self._create_bottom_pane()
                
        self._window1.show_all()

        
    def on_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp):
        
        if target_type == TARGET_TYPE_URI_LIST:
            uri = selection.data.strip('\r\n\x00')
            print 'uri', uri
            uri_splitted = uri.split() # we may have more than one file dropped
            for uri in uri_splitted:
                path = self.get_file_path_from_dnd_dropped_uri(uri)
                print 'path to open', path
                if os.path.isfile(path): # is it file?
                    self.forkme(path)
            
    def get_file_path_from_dnd_dropped_uri(self, uri):
        
        # get the path to file
        path = ""
        if uri.startswith('file:\\\\\\'): # windows
            path = uri[8:] # 8 is len('file:///')
        elif uri.startswith('file://'): # nautilus, rox
            path = uri[7:] # 7 is len('file://')
        elif uri.startswith('file:'): # xffm
            path = uri[5:] # 5 is len('file:')
        
        path = urllib.url2pathname(path) # escape special chars
        path = path.strip('\r\n\x00') # remove \r\n and NULL
        
        return path



    def on_window1_delete_event(self, widget, event, data=None):
        return False
        
    def on_window1_destroy(self, widget, data=None):
        gtk.main_quit()
    
    def on_menuitemfindreplace_activate(self, dialog, *args):
        self._dialogfindreplace.show_all()
        
        #resp=self._dialogfindreplace.run()
        #if resp in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
            #self._dialogfindreplace.response(resp) #hide_all()
            
        #self._dialogfindreplace.show_all()
        #resp=self._dialogfindreplace.run()
        #print resp.real

    
    #def on_dialogfindreplace_response(self, dialog, respid):
        #print "RESPID: ", respid
        #if respid in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
        #    dialog.hide_all()
        #return respid
        ##else:
        ##    return respid
        
        ##if resp in [gtk.RESPONSE_OK, gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
        ##    print "OK_CLOSE_DELETE"
        ##    buf=self._sv.get_buffer()
        ##    if buf.get_tag_table().lookup("search_results"):
        ##        buf.remove_tag_by_name("search_results", buf.get_start_iter(), buf.get_end_iter())
            ##self._dialogfindreplace.destroy()
        
        ##res=self._dialogwc.run()
        ##if res in [gtk.RESPONSE_OK, gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
        ##    self._dialogwc.hide()

    def on_dialogfindreplace_delete_event(self, widget, *args):
        self._dialogfindreplace.hide_all()
        return True
        
    #def on_dialogfindreplace_close(self, widget, *args):
        #pass
        ##print "Closing.."
        ##self.on_btnfindreplaceclose_clicked(widget, *args)
        
    def on_btnfindreplaceclose_clicked(self, widget, *args):
        buf=self._sv.get_buffer()
        if buf.get_tag_table().lookup("search_results"):
                buf.remove_tag_by_name("search_results", buf.get_start_iter(), buf.get_end_iter())
        self._dialogfindreplace.hide_all()
        
    def _prepare_toolbar(self):
        
        newtbitem=gtk.ToolButton("gtk-new")
        newtbitem.connect("clicked", self.on_menuitemnew_activate)
        
        opentbitem=gtk.ToolButton("gtk-open")
        opentbitem.connect("clicked", self.on_menuitemopen_activate)
        
        savetbitem=gtk.ToolButton("gtk-save")
        savetbitem.connect("clicked", self.on_menuitemsave_activate)
        
        saveastbitem=gtk.ToolButton("gtk-save-as")
        saveastbitem.connect("clicked", self.on_menuitemsaveas_activate)
                
        reverttbitem=gtk.ToolButton("gtk-revert-to-saved")
        reverttbitem.connect("clicked", self._on_revert)
        
        colorchoosertbitem=gtk.ToolButton("gtk-select-color")
        colorchoosertbitem.connect("clicked", self._on_choose_color)
        
        tbitems=[newtbitem, opentbitem, savetbitem, saveastbitem, gtk.SeparatorToolItem(), \
        reverttbitem, gtk.SeparatorToolItem(), colorchoosertbitem]
        
        for i, tbitem in enumerate(tbitems):
            self._maintoolbar.insert(tbitem, i)
        #self._maintoolbar.insert(newtbitem, 0)
        #self._maintoolbar.insert(opentbitem, 1)
        #self._maintoolbar.insert(savetbitem, 2)
        #self._maintoolbar.insert(saveastbitem, 3)
        #self._maintoolbar.insert(gtk.SeparatorToolItem(), 4)
        #self._maintoolbar.insert(reverttbitem, 5)
        #self._maintoolbar.insert(gtk.SeparatorToolItem(), 6)
        #self._maintoolbar.insert(colorchoosertbitem, 7)
    
    def _on_revert(self, widget, *args):
        if self._filename:
            self.set_current_file(self._filename)
        
    def _on_choose_color(self, widget, *args):
        cdia = gtk.ColorSelectionDialog("Select color")
        
        resp = cdia.run()
        if resp == gtk.RESPONSE_OK:
            colorsel = cdia.colorsel
            color = colorsel.get_current_color()
            self._sv.get_buffer().insert_at_cursor(color.to_string())
        
        cdia.destroy()

        
    def _prep_languages(self):
        langsmenu=gtk.Menu()
        adarmitem=gtk.RadioMenuItem(None, "ada")
        adarmitem.connect("toggled", self._on_languagepicked, "ada")
        langsmenu.append(adarmitem)
        langs_ids=self._languagemanager.get_language_ids()
        langs_ids.sort()
        
        for lang in langs_ids:
            if lang=="ada": 
                continue
            else:
                mitem=gtk.RadioMenuItem(adarmitem, lang)
                mitem.connect("toggled", self._on_languagepicked, lang)
                langsmenu.append(mitem)
        self._menuitemlanguage.set_submenu(langsmenu)

        
    def _on_languagepicked(self, widget, langname) :#*args):
 
        #print langname #pretty lame, but how to access the radiomenuitem.
        self._set_highlight_lang(langname)
    
    def _set_highlight_lang(self, lang):
        if lang in self._languagemanager.get_language_ids():
            self._sv.get_buffer().set_language(self._languagemanager.get_language(lang))
            self._buflang=lang
    
    def on_chkmenuitemspacesinsteadoftabs_toggled(self, widget, *args):
        self._sv.set_insert_spaces_instead_of_tabs(widget.get_active())
    
    def on_chkmenuitemshowlinenumbers_toggled(self, widget, *args):
        self._sv.set_show_line_numbers(widget.get_active())
        
    def on_chkmenuitemdrawspaces_toggled(self, widget, *args):
        self._sv.set_draw_spaces(widget.get_active())
        
    def on_chkmenuitemfullscreen_toggled(self, widget, *args):
        if widget.get_active():
            #set fullscreen.
            self._window1.fullscreen()
        else:
            #unfullscreen.
            self._window1.unfullscreen()
            
    def set_current_file(self, filename):
        self.trysave()
        f=None
        if filename and os.path.exists(filename):
            self._filename=filename
            try:
                f=open(filename, 'r')
                self._sv.get_buffer().set_text(f.read())
                lang=guess_file_type(filename)
                if "xml" in lang.lower():
                    self.leftsidetabs.xmlviewer.set_xml(self.buftext())
                if "py" in lang.lower():
                    self.langplugin=PythonSourcePlugin(filename)
                    self.leftsidetabs.sourceviewer.set_language(self.langplugin)
                self._set_highlight_lang(lang)
                
            except Exception, ex:
                print ex
            
            finally:
                if f:
                    f.close()
                
            self._window1.set_title(self._filename +" --helloED")
            self._dirty=False
            
    def on_open_tv_fileitem(self, filepath):
        newwindow=self.yesnomsg("Open in a new window?")
        if newwindow:
            self.forkme(filepath)
        else:
            self.set_current_file(filepath)
        #f=None
        #try:
            #f=file(filepath, "r")
            #self._sv.get_buffer().set_text(f.read())
            #lang=guess_file_type(filepath)
            #self.set_current_file(filepath)
            #self._set_highlight_lang(lang)
        #except Exception, ex:
            #print ex
        #finally:
            #if f:
                #f.close()
                
    def on_menuitemchangefont_activate(self, widget, *args):
        
        fdia = gtk.FontSelectionDialog("Select font")
        response = fdia.run()
              
        if response == gtk.RESPONSE_OK:
            print "Font selected: "+fdia.get_font_name()
            font_desc = pango.FontDescription(fdia.get_font_name())
            if font_desc:
                self._sv.modify_font(font_desc)
        
        fdia.destroy()

    def push_to_statusbar(self, cid, message):
        self._statusbar.push(cid, message)
    
    def pop_from_statusbar(self, cid):
        self._statusbar.pop(cid)
        
    def on_copy(self, widget, *args):
        self._sv.emit("copy-clipboard")
        
    def on_cut(self, widget, *args):
        self._sv.emit("cut-clipboard")
        
    def on_paste(self, widget, *args):
        self._sv.emit("paste-clipboard")
    
    def get_text_from_buffer(self, buffer):
        siter=buffer.get_start_iter()
        eiter=buffer.get_end_iter()
        return buffer.get_text(siter, eiter)
        
    def buftext(self):
        return self.get_text_from_buffer(self._sv.get_buffer())
    
    def yesnomsg(self, msg="Save"):
        md = gtk.MessageDialog(self._window1,
            gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, 
            gtk.BUTTONS_YES_NO, msg)
        resp=md.run()
        md.destroy()
        
        if resp == gtk.RESPONSE_YES:
            return True
        else:
            return False
    
    def on_menuitemregextoolkit_activate(self, widget, *args):
        rtd=RegexToolkit().get_dialog()
        #rtd.set_default_response(gtk.RESPONSE_OK)
        res=rtd.run()
        print res.real
        if res in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
            rtd.hide()
        #rtd.destroy()
        
    def on_menuitemwc_activate(self, widget, *args):
        self.wc.text=self.buftext()    
        self.lblgwcrange.set_label('Document')
        self.lblgwclines.set_label(str(self.wc.nlines()))
        self.lblgwcwords.set_label(str(self.wc.nwords()))
        self.lblgwcchars.set_label(str(self.wc.nchars()))
        self.lblgwccharsnospaces.set_label(str(self.wc.ncharsnospaces()))

        res=self._dialogwc.run()
        if res in [gtk.RESPONSE_OK, gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
            self._dialogwc.hide()
    
    def on_menuitemgotoline_activate(self, widget, *args):
        res=self.dialoggotoline.run()
        #if res==gtk.RESPONSE_OK or gtk.RESPONSE_CLOSE:
        #    self.dialoggotoline.hide()
        
        #print res.real
        if res in [gtk.RESPONSE_OK, gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
            self.dialoggotoline.hide()
        
    def on_btngotoline_clicked(self, widget, *args):
        try:
            etext=self.entrygotoline.get_text()
            lineno, offset=0, 0
            if ":" in etext:
                line, coffset=etext.split(":")
                lineno=int(line) -1
                offset=int(coffset)-1
            else:
                lineno=int(etext)-1
            buf=self._sv.get_buffer()
            iter=buf.get_iter_at_line_offset(lineno, offset)
            buf.place_cursor(iter)
            self._sv.scroll_to_mark(buf.get_insert(), 0);
        except:
            pass
            
    def get_saveas_filename(self):
        f=None
        sel = gtk.FileChooserDialog("Save as", self._window1,
                            gtk.FILE_CHOOSER_ACTION_SAVE,
                            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                            gtk.STOCK_OPEN, gtk.RESPONSE_OK)) 

        sel.set_default_response(gtk.RESPONSE_OK)
        res=sel.run()
        
        if res==gtk.RESPONSE_OK:
            f=sel.get_filename()
        sel.destroy()
        
        return f
        
    def shouldsave(self):
        if self._dirty:
            return self.yesnomsg("Save?")
        else:
            return False

    def save_to(self, filename):
        f=None
        try:
            f=file(filename, "w")
            f.write(self.buftext())
            print "saved to: ", filename
            self._dirty=False
        finally:
            if f is not None:
                f.close()
                
    def save_as(self):
        f=self.get_saveas_filename()
        if f:
            self.save_to(f)
            
                
    def trysave(self):
        if self.shouldsave(): 
            if self._filename:
                self.save_to(self._filename)
            else: 
                self.save_as()
            

        
    def open_file(self):
        f=None
        sel = gtk.FileChooserDialog("Select File",
                                    self._window1,
                                    gtk.FILE_CHOOSER_ACTION_OPEN,
                                     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                        gtk.STOCK_OPEN, gtk.RESPONSE_OK)
                                     )

        sel.set_default_response(gtk.RESPONSE_OK)

        res=sel.run()
        if res==gtk.RESPONSE_OK:
            f=sel.get_filename()

        sel.destroy()
        return f
        
    
    #FILEMENUITEMS
        
    def on_menuitemnew_activate(self, widget, *args):
        if self._dirty:
            self.trysave()    
        self._window1.set_title("*Untitled")
        
        
    def forkme(self, path=""):
        helloedpath=__file__
        sb.Popen(["python", helloedpath, path])
        
    #FIXME: support to openfile from argv
    def on_menuitemnewwindow_activate(self, widget, *args):
        self.forkme(self._filename)
            
        
    def on_menuitemopen_activate(self, widget, *args):
        f=self.open_file()
        if f:
            self.set_current_file(f)
                    
    def on_menuitemsave_activate(self, widget, *args):
        self.trysave()
        
    def on_menuitemsaveas_activate(self, widget, *args):
        self.save_as()
        
    def on_menuitemquit_activate(self, widget, *args):
        self.trysave()
        gtk.main_quit()
        
    def _on_textchanged(self, widget, *args):
        self._dirty=True
        
        #   self.symbmapping={"(":")", "{":"}", "[":"]", "'":"'", "\"":"\""} 
        #if self.closequotesbraces==True:
            #iter=widget.get_end_iter()
            #iter.backward_char()
            #c=iter.get_char()
            #iter.forward_char()
            #print "C: ", c
            #widget.place_cursor(iter)
            #if c in self.symbmapping:
                #widget.insert(iter, self.symbmapping.get(c)) 

            
    def _create_leftsidepane(self):
        #spb=SidePaneBrowser()
        self.leftsidetabs=LeftSidePane()
        self.leftsidetabs.filebrowser.set_openfilecallback(self.on_open_tv_fileitem)
        self.leftsidetabs.sourceviewer.connect("row-activated", self.on_tv_item_clicked_search)
        self.leftsidetabs.xmlviewer.connect("row-activated", self.on_tv_item_clicked_search)

        self._hpaned1.add1(self.leftsidetabs)
        #spb.show()
 
    def on_tv_item_clicked_search(self, w, *args):
        selection=w.get_selection()
        model, selection_iter=selection.get_selected()
        try:
            iterp=model.iter_parent(selection_iter)
            itemparent=model.get_value(iterp, 0)
            print itemparent
            self.search_text(itemparent)
        except Exception, ex:
            #print ex
            pass #mostly not found --main root --source or imported.
        if selection_iter:
            item=model.get_value(selection_iter, 0) #iter, column
            self.search_text(item)
    
    def set_autoclose_quotes_braces(self, to=True):
        self.closequotesbraces=to
        if self.closequotesbraces==True:
            self.bcvh.update_active()
        else:
            self.bcvh.deactivate()
        

    #INIT the EDITOR
    def _init_editor(self):
        
        self._vpaned1=gtk.VPaned()
        self._hpaned1.add2(self._vpaned1)
        
        #self._hpaned1.add2(self._vpaned1)
        
        self._vpaned1.add1(self._scrolledwindoweditor)
        
        self._sv=sv.View(sv.Buffer())
        self.bcvh=BracketCompletionViewHelper(self._sv)
        self._scrolledwindoweditor.add(self._sv)
        #set default font.
        font_desc = pango.FontDescription("Monospace 10")
        if font_desc:
            self._sv.modify_font(font_desc)
            
        
        #gtksourceview
        self._sv.set_auto_indent(True)
        self._sv.get_buffer().connect("mark-set", self._handlemarkset)
        self._sv.get_buffer().connect("changed", self._on_textchanged)
        self._sv.set_draw_spaces(False)
        self._sv.set_insert_spaces_instead_of_tabs(True)
        self._sv.set_show_line_numbers(True)
        self._sv.set_show_line_marks(True)
        self._sv.set_highlight_current_line(True)
        self._sv.set_indent_width(4)
        self._sv.set_tab_width(4)
        self._sv.get_buffer().set_highlight_syntax(True)
        #self._set_highlight_lang("python")
        
        #self._scrolledwindoweditor.show()
        #self._sv.show()
        
        #Hook it up.
        self._window1.connect("size-request", self.on_window1_size_request)
        
        
    def on_window1_size_request(self, *args):
        w, h=self._window1.size_request()
        self._scrolledwindoweditor.set_size_request(w-150, h-200)
        
    def _create_bottom_pane(self):
        self._vpaned1.add2(BottomPane())
        
    def _handlemarkset(self, widget, *args):
        
        cid=self._statusbar.get_context_id("pos")
    
        iter=widget.get_iter_at_mark(widget.get_mark("insert"))
        r=iter.get_line()+1
        c=iter.get_line_offset()+1
        
        self._statusbar.pop(cid)
        pos=str(r)+":"+str(c)
        langmsg="\tLanguage: %s"%self._buflang
        self._statusbar.push(cid, pos+langmsg)
        
        
            

    #FINDREPLACE action_area
    def on_btnfindnext_clicked(self, widget, *args):
        searchtext=self._dfrentrysearch.get_text()
        self.search_text(searchtext)
        
    def on_btnfindall_clicked(self, widget, *args):
        searchtext=self._dfrentrysearch.get_text()
        self.search_text(searchtext, all=True)
        
        
    def on_btnprev_clicked(self, widget, *args):
        searchtext=self._dfrentrysearch.get_text()
        self.search_text(searchtext, backward=True)
        
        
    def on_btnreplace_clicked(self, widget, *args):
        searchtext=self._dfrentrysearch.get_text()
        replacetext=self._dfrentryreplace.get_text()
        self.replace_text(searchtext, replacetext)
        
    def on_btnreplaceall_clicked(self, widget, *args):
        searchtext=self._dfrentrysearch.get_text()
        replacetext=self._dfrentryreplace.get_text()
        self.replace_text(searchtext, replacetext, True)
        
    def search_text(self, text, backward=False, all=False):
        #print "searching for: %s"%text
        #print "backward: ", backward
        #print "search all: ", all
        
        buf=self._sv.get_buffer()
        if buf.get_tag_table().lookup("search_results"):
            buf.remove_tag_by_name("search_results", buf.get_start_iter(), buf.get_end_iter())
       
        if text:
            if all:
                self.find_all_in_range(buf, text,buf.create_mark(None,buf.get_start_iter()), buf.create_mark(None,buf.get_end_iter()))
            if not backward:
                try:
                    find_iter = buf.get_iter_at_mark(buf.get_selection_bound());
                    ins, bound = find_iter.forward_search(text, flags=0, limit=None);
                except:
                    find_iter = buf.get_start_iter()
                    ins, bound = find_iter.forward_search(text, flags=0, limit=None);

                buf.select_range(ins, bound);
                self._sv.scroll_to_mark(buf.get_selection_bound(), 0);
            else: #if backward
                try:
                    find_iter = buf.get_iter_at_mark(buf.get_insert());
                    ins, bound = find_iter.backward_search(text, flags=0, limit=None);
                except:
                    find_iter = buf.get_end_iter()
                    ins, bound = find_iter.backward_search(text, flags=0, limit=None);

                buf.select_range(ins, bound);
                self._sv.scroll_to_mark(buf.get_insert(), 0);
            
        
    def find_all_in_range(self, buf, search_string, start_mark, end_mark):
        start_iter = buf.get_iter_at_mark(start_mark)
        end_iter = buf.get_iter_at_mark(end_mark)
        search_results = self.search_for_text(buf, search_string,start_iter,end_iter)

        if search_results:
            if not buf.get_tag_table().lookup("search_results"):
                preview_tag = buf.create_tag("search_results", background_set="True",background="yellow")
            buf.remove_tag_by_name('search_results', start_iter, end_iter)
            for range in search_results:
                buf.apply_tag_by_name("search_results",range[0],range[1])

    def search_for_text(self, txtbuf, text, begin, end):

        found_matches = []
        from gtk import TEXT_SEARCH_VISIBLE_ONLY
        while True:
            result = begin.forward_search(text, TEXT_SEARCH_VISIBLE_ONLY, end)
            if result:
                found_matches.append((result[0], result[1]))
                begin = result[1]
            else:
                break
        return found_matches
        
    def replace_text(self, s1, s2, all=False):
        #print "replace: %s => %s , All: %s"%(s1, s2, all)
        if all:
            self._sv.get_buffer().set_text(self.buftext().replace(s1, s2))
        else:
            #print "one replace: %s => %s"%(s1, s2)
            if s2:
                buf = self._sv.get_buffer();

                find_iter = buf.get_iter_at_mark(buf.get_selection_bound());
                next_occurence = find_iter.forward_search(s1, flags=0, limit=None)

                if not next_occurence:
                    #try to move to the start_iter
                    if s1 in self.buftext():
                        res=self.yesnomsg("Place cursor at start iter?")
                        if res:
                            buf.place_cursor(buf.get_start_iter())
                    return #silently
                    
                next_begin = buf.create_mark(None,next_occurence[0])
                next_end = buf.create_mark(None,next_occurence[1])
                next_list = [(next_begin,next_end)]
                self.doreplace_text(buf,s2,next_list)
                self._sv.scroll_to_mark(next_end,0)
                self.find_all_in_range(buf,s1,next_end,buf.create_mark(None,buf.get_end_iter()))


    def doreplace_text(self, txtbuf, text, positions):

        for marks in positions:
            begin = txtbuf.get_iter_at_mark(marks[0])
            end = txtbuf.get_iter_at_mark(marks[1])
            txtbuf.delete(begin, end)
            begin = txtbuf.get_iter_at_mark(marks[0])
            txtbuf.insert(begin, text) 
    
    
    #ABOUT DIALOG 
    def on_menuitemabout_activate(self, widget, *args):
        aboutdialog=gtk.AboutDialog()
        aboutdialog.set_program_name("helloED")
        aboutdialog.set_version("6.0")
        aboutdialog.set_copyright("Copyright (c) 2006-2008 <NAME> <<EMAIL>>")
        aboutdialog.set_website("http://programming-fr34ks.net")
        aboutdialog.set_license("""This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.""")
        aboutdialog.run()
        aboutdialog.destroy()

        

#run mainloop
def main():
            
    mainwindow = MainWindow()
    mainwindow.set_autoclose_quotes_braces(True)
    if len(sys.argv)>1:
        if os.path.exists(sys.argv[1]) and os.path.isfile(sys.argv[1]):
            mainwindow.set_current_file(sys.argv[1])
    #mainwindow.window1.show()
    gtk.main()

if __name__ == "__main__":
    main()
    
