###
# Application: pyFind
# File:        appMain.py
# Description: Main window callbacks
# Copyright (c) 2001   Andy Balcombe <kinematics _at_ ntlworld.com>
###
#
# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#standard python modules
import os

#project modules
from LoadGlade import *
import dlgPreferences
import config
import match_files

class appMain(LoadGlade):
    """
    The main pyfind gui class
    """
    def init_appMain(self, p_sPath="/"):
        #init config db
        self.confPrefs = config.GnomeConfig("pyFind")

        #signal connect
        self.appMain.connect("destroy", mainquit)

        #set inital values
        self.apbMain.set_status("Started")
        self.txeSearchIn.set_text( p_sPath )
        self.cmdStop.set_sensitive(FALSE)

        #load histories
        self.entFileSpec.load_history()
        self.entContaining.load_history()
        self.fentSearchIn.gnome_entry().load_history()

        #init toolbars and result cols, etc
        self.set_config_preferences()
        
        #flags, etc
        self.bStopPressed = 0

    #process gtk / gnome events
    def process_gtk_events(self):
        while events_pending():
            mainiteration()

    def set_config_preferences(self):
        #init toolbars
        self.tbrMain.set_style( int(self.confPrefs.get_value( "config", "tbrMain", str(TOOLBAR_BOTH))))
        self.tbrFile.set_style( int(self.confPrefs.get_value( "config", "tbrFile", str(TOOLBAR_BOTH))))

        #set columns
        sCols = self.confPrefs.get_value( "config", "ResultCols", "011100101" )
        iColNum = -1
        for sColVisible in sCols:
            iColNum = iColNum + 1
            self.clstFiles.set_column_visibility( iColNum, (sColVisible=="1") )

        #sync config file
        self.confPrefs.sync()

    ### Main Toolbar
    # Find
    def on_cmdFind_clicked(self, *args):
        #sanity checking
        if self.txeFileSpec.get_text() == "" or \
           self.fentSearchIn.get_full_path(1) == None:
            #stop here
            self.apbMain.set_status( "Enter a path and file spec" )
            return
            
        #search for files!
        self.entFileSpec.prepend_history(1,self.txeFileSpec.get_text())
        self.entContaining.prepend_history(1,self.txeContaining.get_text())
        self.fentSearchIn.gnome_entry().prepend_history(1,self.fentSearchIn.get_full_path(1))

        #set progress bar to 0 and clear list
        self.cmdStop.set_sensitive(TRUE)
        self.apbMain.set_progress(0.0)
        self.clstFiles.clear()
        self.process_gtk_events()

        #reset flags
        self.bStopPressed = 0

        #build parameter list
        if self.txeFileSize.get_text() == "At Least":
            sSizeType = ">"
        else:
            sSizeType = "<"

        #call search module
        lFiles = []
        lFiles, sFindCmd = match_files.find_matching_files(
            self,
            self.fentSearchIn.get_full_path(1),        #search path
            not(self.chkSubDirectories.get_active()),  #search sub-directories
            self.chkSearchMountedVols.get_active(),    #search mounted volumes
            self.txeFileSpec.get_text(),               #file spec 
            self.chkFileCase.get_active(),             #case sensitive filenames
            self.chkPreviousDays.get_active(),         #search previous 
            self.txeMDays.get_text(),                  #num previous type (weeks, days, etc)
            self.spnPreviousDays.get_value_as_int(),   #num previous val
            self.txeContaining.get_text() != "",       #search contents
            self.chkContCase.get_active(),             #case sensitive contents
            self.txeContaining.get_text(),             #search contents val
            self.chkFileSize.get_active(),             #search by size
            sSizeType,                                 #size type (< or >)
            self.spnFileSize.get_value_as_int() * 1024,#size in kb
            self.chkBetween.get_active(),              #search on mod date
            self.dteBetweenStart.get_date(),           #start date
            self.dteBetweenEnd.get_date() + 86400,     #end date +1 day (to make date inclusive) 
            self.chkReplace.get_active(),              #search and replace text within files
            self.txeRepSearch.get_text(),              #replace - search text
            self.txeRepReplace.get_text(),             #        - replace text
            self.chkRegExp.get_active(),               #        - use regular expressions
            self.chkRepCaseSensitive.get_active()      #        - case senstive search for regular expressions
        )

        #done search
        self.txeFindCmd.set_text(sFindCmd) #fill in find cmd line
        self.cmdStop.set_sensitive(FALSE)
        
    # Clear search parameters
    def on_cmdReset_clicked(self, *args):
        #clear all search options
        self.txeFileSpec.set_text("")
        self.txeContaining.set_text("")
        self.txeSearchIn.set_text("/")

    #stop search
    def on_cmdStop_clicked(self, *args):
        #set flag (checked in match_files.py)
        self.bStopPressed = 1

    # display Preferences dialog
    def on_preferences_activate(self, *args):
        dlgPrefs = dlgPreferences.dlgPreferences("pyfind.glade","dlgPreferences", self.sMode)
        dlgPrefs.init_Preferences(self)
        
    # display About dialog 
    def on_about_activate(self, *args):
        #set glade file name
        if self.sMode == "development":
            #development version
            sPixmap = os.path.join("pixmaps", "pyFind3.png")
        else:
            #production version
            sPixmap = gnome.util.datadir_file( os.path.join("pyFind/pixmaps", "pyFind3.png")) 
        dlgAbout = GnomeAbout( config.app_name, \
                               config.app_version, \
                               "GPL (c) 2001 Andy Balcombe", \
                               config.authors, \
                               "pyFind - a simple Gnome file find utility", \
                               sPixmap )
        dlgAbout.show()

    # Open selected files
    def on_cmdFOpen_clicked(self, *args):
        #get the name of the Gnome editor
        confEditor = config.GnomeConfig("editor")
        sEditor="/usr/bin/" + confEditor.get_value( "Editor", "EDITOR", "nope" ) #assume it's in usr/bin for now
        lisSelected = self.clstFiles.__getattr__("selection")
        #print "lisSelected=",lisSelected
        for iRow in lisSelected:
            lFile=[""] #empty list, 1st arg is ignored
            sFilename = self.clstFiles.get_text(iRow,2) + "/" + \
                        self.clstFiles.get_text(iRow,1) 
            lFile.append(sFilename)
            #spawn a process, don't wait for it to finish
            os.spawnv( os.P_NOWAIT, sEditor, lFile )

    # Delete selected files
    def on_cmdFDelete_clicked(self, *args):
        lisSelected = self.clstFiles.__getattr__("selection")
        #print "lisSelected=",lisSelected
        self.lDelFiles=[] #empty list
        for iRow in lisSelected:
            sFilename = self.clstFiles.get_text(iRow,2) + "/" + \
                        self.clstFiles.get_text(iRow,1) 
            self.lDelFiles.append(sFilename)
        #print "Delete Files=",self.lDelFiles
        if self.lDelFiles != []:
            sMsg = "Are you sure you want to delete the selected files?"
            ctlMsgBox = GnomeQuestionDialog( sMsg, self.on_ctlMsgBox_question, self.appMain)

    #callback for delete files question box
    def on_ctlMsgBox_question(self, button, *args):
        #print "on_ctlMsgBox_question=",button
        if button == 0: #yes
            #print "self.lDelFiles=",self.lDelFiles
            for sFile in self.lDelFiles:
                try:
                    os.remove( sFile )
                except:
                    sErrMsg = "Error - Cannot remove file:\n " + sFile
                    ctlMsgBox = GnomeErrorDialog(sErrMsg, self.appMain)

    # Execute? selected files
    #def on_CmdFExecute_clicked(self, *args):
        #pass
        #sErrMsg = "Error - Cannot remove\n " + "hnnn"
        #ctlMsgBox = GnomeMessageBox("Hello",MESSAGE_BOX_QUESTION,STOCK_BUTTON_OK,STOCK_BUTTON_CANCEL)
        #ctlMsgBox.show()
        #print "dir=",ctlMsgBox.__dict__
        #sMsg = "Do you want to delete: abcdef?"
        #ctlMsgBox = GnomeQuestionDialog( sMsg, self.msgbox_cb_test, self.appMain)

    #file list (column heading)
    def on_clstFiles_click_column(self, ctlCList, iCol, *args):
        #sort the results list
        #print "col clicked:", iCol
        self.clstFiles.set_sort_column(iCol)
        self.clstFiles.sort()

    #file list (row selected)
    #def on_clstFiles_select_row(self, ctlCList, iRow, iCol, iX, *args):
        #row selected
        #print "row=",iRow," ,Col=",iCol,"  iX=",iX
        #sFilename = self.clstFiles.get_text(iRow,2) + "/" + \
        #            self.clstFiles.get_text(iRow,1) 
        #print "row=",sFilename

    #def on_clstFiles_button_release_event(self, ctlCList,iX, *args):
        #print "button_release_event: iX=",iX

    # file filter tab
    # File Size
    def on_chkFileSize_toggled(self, *args):
        bEnabled = self.chkFileSize.get_active()
        self.cboFileSize.set_sensitive( bEnabled )
        self.spnFileSize.set_sensitive( bEnabled )
        self.lblKb.set_sensitive( bEnabled )

    # Previous
    def on_chkPreviousDays_toggled(self, *args):
        bEnabled = self.chkPreviousDays.get_active()
        self.spnPreviousDays.set_sensitive( bEnabled )
        self.cboMDays.set_sensitive( bEnabled )
        
    # Date Range
    def on_chkBetween_toggled(self, *args):
        bEnabled = self.chkBetween.get_active()
        self.dteBetweenStart.set_sensitive( bEnabled )
        self.dteBetweenEnd.set_sensitive( bEnabled )
        self.lblPrevious.set_sensitive( bEnabled )

    # Replace Tab
    # search and replace
    def on_chkReplace_toggled(self, *args):
        bEnabled = self.chkReplace.get_active()        
        self.chkRegExp.set_sensitive( bEnabled )
        self.lblRepSearch.set_sensitive( bEnabled )
        self.txeRepSearch.set_sensitive( bEnabled )
        self.lblRepReplace.set_sensitive( bEnabled )
        self.txeRepReplace.set_sensitive( bEnabled )

    # case sensitive reg exp matching
    def on_chkRegExp_toggled(self, *args):
        bEnabled = self.chkRegExp.get_active()        
        self.chkRepCaseSensitive.set_sensitive( bEnabled )

    #done, quit the application
    def on_appMain_destroy (self, *args):
        #print "quitting..., args=", args
        mainquit()

