#!/usr/bin/env python

"""    It is our KODA's project, started and finished in 2005 year. 
        We wrote simple graphic interface for bzip2 library in python 
        language, using PyGTK library. In our great team are: 
        Teresa Madej, Michal Szpadzik, Lukasz Szandecki, Sebastian 
        Zdunek and Michal Bialowas. Please feel free to upgrade this 
        program.
"""
#import pygtk
#pygtk.require('2.0')
import os, gtk, gtk.glade, sys, gtk.gdk, gobject
import locale, time
from os.path import join, isdir
import myTar, myGz, myBz2, myProgress
import locale

locale.setlocale(locale.LC_ALL, 'C')


# If you want to add new supported archive add a dictionary element
# in this format: {"Name of filter":(2 elements tuple; first is mime_type,
#                            second is filename extension)}
archives_dict = {"*.tar"   : ("tar/tar","*.tar"),
                 "*.tar.gz"  : ("gzip/gz","*.tar.gz"), 
                 "*.tar.bz2" : ("bzip2/bz2","*.tar.bz2")
                 }

class myPacker:
    
    # Creates new archive file in given format
    def myNew(self, widget):
        def new_response(dialog, response):
            forbidden_list=['\\', '/', '*', ':', '?', '"', '<', '>', "|"]
        
            if response == gtk.RESPONSE_OK:
                current_filter = dlgSave.get_filter()
                self.new_archive_name=dlgSave.get_filename()+current_filter.get_name()[1:]
                excl_counter=0
                (d_path, f_name) = os.path.split(self.new_archive_name)
                for for_exl in forbidden_list:
                    excl_counter = excl_counter + f_name.count(for_exl)
                if excl_counter==0:
                    if os.path.isfile(self.new_archive_name.encode(self.sysfsenc)) == False:
                        self.icomnuadd.set_sensitive(True)
                        self.icobtnadd.set_sensitive(True)
                        self.icomnuadddir.set_sensitive(True)
                        self.icobtnadddir.set_sensitive(True)
                        self.icomnuremove.set_sensitive(True)
                        self.icobtnremove.set_sensitive(True)
                        self.icomnucompress.set_sensitive(True)
                        self.icobtncompress.set_sensitive(True)
                        self.icomnuextract.set_sensitive(False)
                        self.icobtnextract.set_sensitive(False)
                    
                        (dir_path, file_name) = os.path.split(self.new_archive_name)
                        sts_message = "You will be creating \"%s\" archive in \"%s\" directory" \
                                                                                                % (file_name, dir_path) 
                        self.message_id = self.status_bar.push(self.context_id, sts_message)
                        self.new_archive_name = self.new_archive_name.encode(self.sysfsenc)
                        dlgSave.destroy()
                    elif os.path.isfile(self.new_archive_name.encode(self.sysfsenc)) == True:
                        errMsg = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_QUESTION, 
                                                   gtk.BUTTONS_YES_NO, 
                                                  "That file exists. Overwrite ??")
                        resp = errMsg.run()
                        errMsg.hide()
                        if resp == gtk.RESPONSE_YES:
                            self.icomnuadd.set_sensitive(True)
                            self.icobtnadd.set_sensitive(True)
                            self.icomnuadddir.set_sensitive(True)
                            self.icobtnadddir.set_sensitive(True)
                            self.icomnuremove.set_sensitive(True)
                            self.icobtnremove.set_sensitive(True)
                            self.icomnucompress.set_sensitive(True)
                            self.icobtncompress.set_sensitive(True)
                            self.icomnuextract.set_sensitive(False)
                            self.icobtnextract.set_sensitive(False)
                        
                            (dir_path, file_name) = os.path.split(self.new_archive_name)
                            sts_message = "You will be creating \"%s\" archive in \"%s\" directory" \
                                                                                                    % (file_name, dir_path) 
                            self.message_id = self.status_bar.push(self.context_id, sts_message)
                            self.new_archive_name = self.new_archive_name.encode(self.sysfsenc)
                            errMsg.destroy()
                            dlgSave.destroy()
                        else:
                            self.icomnuextract.set_sensitive(False)
                            self.icobtnextract.set_sensitive(False)
                            errMsg.destroy()
                else:
                    errMsg = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_ERROR, 
                                                   gtk.BUTTONS_CLOSE, 
                                                  "You can't use following chars: / \\ * : ? \" < > |")
                    resp = errMsg.run()
                    errMsg.hide()
                    if resp == gtk.RESPONSE_CLOSE:
                        errMsg.destroy()
                    else:
                        errMsg.destroy()
                        
            elif response == gtk.RESPONSE_CANCEL:
                self.icomnuadd.set_sensitive(False)
                self.icobtnadd.set_sensitive(False)
                self.icomnuadddir.set_sensitive(False)
                self.icobtnadddir.set_sensitive(False)
                self.icomnuremove.set_sensitive(False)
                self.icobtnremove.set_sensitive(False)
                self.icomnucompress.set_sensitive(False)
                self.icobtncompress.set_sensitive(False)
                self.icomnuextract.set_sensitive(False)
                self.icobtnextract.set_sensitive(False)
                dlgSave.destroy()
        
        self.status_bar.pop(self.context_id)
        self.treestore1.clear()
        self.treestore2.clear()
        self.FilesAbs = []
        self.FilesTar = []
        self.FilesAbs.append(self.sep)
        self.FilesTar.append(self.sep)
        dlgSave = gtk.FileChooserDialog("Create an archive file", self.wndMain, 
                gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, 
                gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        dlgSave.set_default_response(gtk.RESPONSE_OK)
        dlgSave.set_transient_for(self.wndMain)
        dlgSave.set_modal(True)
        for dataType, (mime, extension) in archives_dict.items():
            myfilter = gtk.FileFilter()
            myfilter.set_name(dataType)
            myfilter.add_mime_type(mime)
            myfilter.add_pattern(extension)
            dlgSave.add_filter(myfilter)
        #response = dlgSave.run()
        dlgSave.connect('response', new_response)
        dlgSave.show()

    
    # Opens an existing archive file    
    def myOpen(self, widget):
        self.status_bar.pop(self.context_id)
        self.treestore1.clear()
        self.treestore2.clear()
        self.new_archive_name == None
        dlgOpen = gtk.FileChooserDialog("Open archive file", self.wndMain, 
                gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, 
                gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dlgOpen.set_default_response(gtk.RESPONSE_OK)
        #dlgOpen.set_modal(True)
        for dataType, (mime, extension) in archives_dict.items():
            myfilter = gtk.FileFilter()
            myfilter.set_name(dataType)
            myfilter.add_mime_type(mime)
            myfilter.add_pattern(extension)
            dlgOpen.add_filter(myfilter)
        response = dlgOpen.run()

        if response == gtk.RESPONSE_OK:
            self.icomnuadd.set_sensitive(False)
            self.icobtnadd.set_sensitive(False)
            self.icomnuadddir.set_sensitive(False)
            self.icobtnadddir.set_sensitive(False)
            self.icomnuremove.set_sensitive(False)
            self.icobtnremove.set_sensitive(False)
            self.icomnucompress.set_sensitive(False)
            self.icobtncompress.set_sensitive(False)
            self.icomnuextract.set_sensitive(True)
            self.icobtnextract.set_sensitive(True)
            
            
            if sys.platform == 'win32':
                nameOpen=dlgOpen.get_filename().encode(self.sysfsenc)
            else:
                nameOpen = dlgOpen.get_filename()
                
            self.new_archive_name = None
            dlgOpen.destroy()
            (path, fname) = os.path.split(nameOpen)
            (sfname, extension) = os.path.splitext(fname)
            progress = myProgress.myProgressbar(self.wndMain)
            while gtk.events_pending():
                    gtk.main_iteration(False)
            try:
                subclass = "my%s" % extension[1:].title()
                exec "from %s import %s as paker" % (subclass, subclass)
                self.archive = paker(nameOpen)
                self.FilesTar = self.archive.FilesList
                self.myOpenTreeView()
            except:
                dlgOpen.destroy()
                dlgRError = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_ERROR, 
                                           gtk.BUTTONS_CLOSE, 
                                          "There was an error during archive reading")
                dlgRError.set_transient_for(self.wndMain)
                dlgRError.set_modal(True)
                response = dlgRError.run()
                dlgRError.hide()
                if response == gtk.RESPONSE_CLOSE:
                    dlgRError.destroy()
            progress.destroy_progress()    
            sts_message = "You opened \"%s\" archive" % self.myUniconv(fname)
            self.message_id = self.status_bar.push(self.context_id, sts_message)

        elif response == gtk.RESPONSE_CANCEL:
            self.icomnuextract.set_sensitive(False)
            self.icobtnextract.set_sensitive(False)
            dlgOpen.destroy()

    # Gives an opportunity to add any file to archive
    def myAdd(self, widget):
        self.status_bar.pop(self.context_id)    
        dlgAdd = gtk.FileChooserDialog("Add file to archive", self.wndMain, 
                gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, 
                gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dlgAdd.set_default_response(gtk.RESPONSE_OK)
        dlgAdd.set_select_multiple(True)
        #dlgAdd.set_modal(True)
        response = dlgAdd.run()    

        if response == gtk.RESPONSE_OK:
            given_filenames = dlgAdd.get_filenames()
            dlgAdd.destroy() 
            if len(self.FilesTar) == 0:
                self.FilesAbs.append(self.sep)
                self.FilesTar.append(self.sep)
            while gtk.events_pending():
                    gtk.main_iteration(False)
            lstList = self.xml.get_widget("lstList")
            selection = lstList.get_selection()
            selection.set_mode(gtk.SELECTION_SINGLE)
            (model, iterator) = selection.get_selected()
            if model != None and iterator != None:
                relPath=model.get_value(iterator, 5)
                if relPath.endswith(self.sep) == False:
                    relPath = os.path.split(relPath)[0]
            else:
                relPath=self.sep
                
            for i in given_filenames:
               while gtk.events_pending():
                    gtk.main_iteration(False) 
               self.FilesAbs.append(i)
               (temp, filename)=os.path.split(i)
               self.FilesTar.append(join(relPath, filename))
            self.mySaveTreeView()
            self.message_id = self.status_bar.push(self.context_id,
                                                     "You have just added file (or files) to archive ...")
        elif response == gtk.RESPONSE_CANCEL:
            dlgAdd.destroy()

            
    def myAddDir(self, widget):
        self.status_bar.pop(self.context_id)
        dlgAdd = gtk.FileChooserDialog("Add dir to archive", self.wndMain, 
                gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, 
                gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        dlgAdd.set_default_response(gtk.RESPONSE_OK)
        #dlgAdd.set_modal(True)
        response = dlgAdd.run()    

        if response == gtk.RESPONSE_OK:
            if len(self.FilesTar) == 0:
                self.FilesAbs.append(self.sep)
                self.FilesTar.append(self.sep)
                
            lstList = self.xml.get_widget("lstList")
            selection = lstList.get_selection()
            selection.set_mode(gtk.SELECTION_SINGLE)
            (model, iterator) = selection.get_selected()
            if model != None and iterator != None:
                relPath=model.get_value(iterator, 5)
                if relPath.endswith(self.sep) == False:
                    relPath = os.path.split(relPath)[0]
                    if relPath == self.sep:
                        relPath = ""
                else:
                    relPath = relPath[:-1]
            else:
                relPath = ""
                
            start=dlgAdd.get_filenames()[0]
            dlgAdd.destroy()
            progress = myProgress.myProgressbar(self.wndMain)
            str_len =  len(start)
            for root, dirs, files in os.walk(start):
                while gtk.events_pending():
                    gtk.main_iteration(False)
                for name in files:
                    try:
                        os.stat(join(root, name))
                        self.FilesTar.append(relPath + join(root, name)[str_len:])
                        self.FilesAbs.append(join(root, name))
                    except:
                        pass
                for name in dirs:
                    try:
                        os.stat(join(root, name) + self.sep)
                        self.FilesTar.append(relPath + join(root, name)[str_len:] + self.sep)
                        self.FilesAbs.append(join(root, name) + self.sep)
                    except:
                        pass

            self.mySaveTreeView()
            progress.destroy_progress()
            sts_message = "You have just added directory to archive"
            self.message_id = self.status_bar.push(self.context_id, sts_message)
        elif response == gtk.RESPONSE_CANCEL:
            pass  
        dlgAdd.destroy()

    # Gives an opportunity to remove any file from TreeView
    def myRemove(self, widget):
        self.status_bar.pop(self.context_id)
        lstList = self.xml.get_widget("lstList")
        selection = lstList.get_selection()
        (model, iterator) = selection.get_selected()
        if iterator != None:
            dlgMsg = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_QUESTION, 
                                           gtk.BUTTONS_YES_NO, 
                                          "Do you really want to delete this item?")
            resp = dlgMsg.run()
            dlgMsg.hide()
            if iterator != None and resp == gtk.RESPONSE_YES:
                L=[]
                relPath=model.get_value(iterator, 5)
                L.append(relPath)
                model.remove(iterator)
                self.RemoveObj(L)
                sts_message = "\"%s\" has been removed form archive" % relPath       
                self.message_id = self.status_bar.push(self.context_id, sts_message)        
                    
    def myPopup(self, widget, event):
        if event.button == 3:                                                                                     
            file_menu = gtk.Menu()                                                                              
            if self.new_archive_name != None:                                                            
                self.popupNew.show_all()
                self.popupNew.popup(None, None, None, event.button, event.time)
            elif self.new_archive_name == None:
               self.popupOpen.show_all()
               self.popupOpen.popup(None, None, None, event.button, event.time)
        else:
            pass
    
    def RemoveObj(self, objects):
        for obj in objects:
            ind = self.FilesTar.index(obj)
            if obj == self.sep:
                del self.FilesAbs[:]
                del self.FilesTar[:]
                self.treestore1.clear()
            elif isdir(self.FilesAbs[ind]):
                for i in range(len(self.FilesTar), 1, -1):
                    if self.FilesTar[i-1].startswith(obj):
                        del self.FilesAbs[i-1]
                        del self.FilesTar[i-1]
            else:
                del self.FilesAbs[ind]
                del self.FilesTar[ind]
        
    def myCreate(self, widget):
        self.status_bar.pop(self.context_id)
        def myOK(widget):
            name = dlgCreateEntry.get_text()        
            
            lstList = self.xml.get_widget("lstList")
            selection = lstList.get_selection()
            (model, iterator) = selection.get_selected()
            if model != None and iterator != None:
                    relPath=model.get_value(iterator, 5)
                    if relPath.endswith(self.sep) == False:
                        relPath = os.path.split(relPath)[0]
                    else:
                        relPath = relPath[0:-1]
            else:
                    relPath=self.sep
            
            self.FilesAbs.append(".")
            self.FilesTar.append(relPath + self.sep + name.encode(self.sysfsenc) + self.sep)
            dlgCreate.destroy()
            self.mySaveTreeView()
        
            sts_message = "\"%s\" directory has been created in archive" % name
            self.message_id = self.status_bar.push(self.context_id, sts_message)
            
        def myCancel(widget):
            dlgCreate.destroy()
            
        xml = gtk.glade.XML(self.gladedir , "dlgCreate")
        dlgCreate = xml.get_widget("dlgCreate")
        dlgCreateEntry = xml.get_widget("dlgCreateEntry")
        #dlgCreateEntry.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        dlgCreate.set_transient_for(self.wndMain)
        dlgCreate.set_modal(True)
        dlgCreate.set_icon_from_file(self.mainicon)
        
        mysignals = {"on_dlgCreateCancel_clicked": myCancel,
                     "on_dlgCreateOK_clicked": myOK
                      }
        xml.signal_autoconnect(mysignals)

        
    def myCompress(self, widget):
        if os.path.isfile(self.new_archive_name.encode(self.sysfsenc)) == True:
                errMsg = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_QUESTION, 
                                           gtk.BUTTONS_YES_NO, 
                                          "That file exists. Overwrite ??")
                resp = errMsg.run()
                errMsg.hide()
                if resp == gtk.RESPONSE_YES:
                    self.status_bar.pop(self.context_id)
                    errMsg.destroy()
                    while gtk.events_pending():
                            gtk.main_iteration(False)
                    (sfname, extension) = os.path.splitext(self.new_archive_name)
                    try:
                        subclass = "my%s" % extension[1:].title()
                        exec "from %s import %s as paker" % (subclass, subclass)
                        paker().mySave(self.new_archive_name, self.FilesAbs, 
                                                                   self.FilesTar, self.wndMain)
                        self.message_id = self.status_bar.push(self.context_id,
                                                                 "Archive file has been created ...")
                    except:
                        dlgRError = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_ERROR, 
                                                   gtk.BUTTONS_CLOSE, 
                                                  "There was an error during archive creation")
                        dlgRError.set_transient_for(self.wndMain)
                        dlgRError.set_modal(True)
                        response = dlgRError.run()
                        dlgRError.hide()
                        if response == gtk.RESPONSE_CLOSE:
                            dlgRError.destroy()    
                else:
                    errMsg.destroy()
        else:
            self.status_bar.pop(self.context_id)
            (sfname, extension) = os.path.splitext(self.new_archive_name)
            while gtk.events_pending():
                gtk.main_iteration(False)
            try:
                subclass = "my%s" % extension[1:].title()
                exec "from %s import %s as paker" % (subclass, subclass)
                paker().mySave(self.new_archive_name, self.FilesAbs,
                                                            self.FilesTar, self.wndMain)
                self.message_id = self.status_bar.push(self.context_id,
                                                         "Archive file has been created ...")
            except:
                dlgRError = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_ERROR, 
                                           gtk.BUTTONS_CLOSE, 
                                          "There was an error during archive creation")
                dlgRError.set_transient_for(self.wndMain)
                dlgRError.set_modal(True)
                response = dlgRError.run()
                dlgRError.hide()
                if response == gtk.RESPONSE_CLOSE:
                    dlgRError.destroy()
        
    def myExtract(self, widget):
        self.status_bar.pop(self.context_id)
        dlgExtract = gtk.FileChooserDialog("Extract an archive file", self.wndMain, 
                gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, 
                gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
        dlgExtract.set_default_response(gtk.RESPONSE_CANCEL)
        response = dlgExtract.run()
        path = ""    
        if response == gtk.RESPONSE_OK:
            path = dlgExtract.get_filename()
            
            lstList = self.xml.get_widget("lstList")
            selection = lstList.get_selection()
            (model, pathlist) = selection.get_selected_rows()
            
            dlgExtract.destroy()
            progress = myProgress.myProgressbar(self.wndMain)
            while gtk.events_pending():
                    gtk.main_iteration(False)
            if model != None and pathlist != None:
                relPath = []
                for i in range(0, len(pathlist)):
                    while gtk.events_pending():
                       gtk.main_iteration(False)
                    relPath.append(model.get_value(model.get_iter(pathlist[i]), 6))
            else:
                relPath = []  
            try:
                self.archive.myOpen(path, relPath)
            except:
                dlgExtract.destroy()
                dlgRError = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_ERROR, 
                                           gtk.BUTTONS_CLOSE, 
                                          "There was an error during archive extraction")
                dlgRError.set_transient_for(self.wndMain)
                dlgRError.set_modal(True)
                response = dlgRError.run()
                dlgRError.hide()
                if response == gtk.RESPONSE_CLOSE:
                    dlgRError.destroy()
            progress.destroy_progress()    
        elif response == gtk.RESPONSE_CANCEL:
            dlgExtract.destroy()
        
        sts_message = "All or part of archive has been extracted to %s" % path
        self.message_id = self.status_bar.push(self.context_id, sts_message)
        
    def  myHelp(self, widget):
        self.status_bar.pop(self.context_id)
        xml = gtk.glade.XML(self.gladedir , "dlgHelp")
        dlgHelp = xml.get_widget("dlgHelp")
        dlgHelp.set_transient_for(self.wndMain)
        dlgHelp.set_modal(True)
        dlgHelp.set_icon_from_file(self.mainicon)
    
    def  myAbout(self, widget):
        self.status_bar.pop(self.context_id)
        def myOK(widget):
            dlgInfo.destroy()
            
        xml = gtk.glade.XML(self.gladedir , "dlgInfo")
        dlgInfo = xml.get_widget("dlgInfo")
        dlgInfoImage = xml.get_widget("dlgInfoImage")
        dlgInfoImage.set_from_file(self.iconinfo)
        dlgInfo.set_transient_for(self.wndMain)
        dlgInfo.set_modal(True)
        dlgInfo.set_icon_from_file(self.mainicon)
        mysignals = {"on_btnCloseInfo_clicked": myOK}
        xml.signal_autoconnect(mysignals)
    
    def myQuit(self, widget):
        dlgMsg = gtk.MessageDialog(self.wndMain, 0, gtk.MESSAGE_QUESTION, 
                                           gtk.BUTTONS_YES_NO, 
                                          "Do you really want to Quit?")
        resp = dlgMsg.run()
        dlgMsg.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        dlgMsg.hide()
        
        if resp == gtk.RESPONSE_YES:
            gtk.main_quit()
        else:
            dlgMsg.destroy()
    
    def myUniconv(self, i):
        unistr = unicode(i, self.sysfsenc)
        utfstr = unistr.encode("utf-8")
        return utfstr
    
    def mySaveTreeView(self):
        self.treestore1.clear()
        self.treestore2.clear()
        absPaths=self.FilesAbs[:]
        relPaths=self.FilesTar[:]
        relPaths.sort()
        lstList = self.xml.get_widget("lstList")
        lstList.set_model(self.treestore1)
        renderer = gtk.CellRendererText()
        renderer_pb = gtk.CellRendererPixbuf()
        column_names = ("Name", "Type", "Last Modified", "Path")
        for k in range(0, len(lstList.get_columns())+1):
            givenTree = lstList.get_column(0)
            if givenTree != None:
                lstList.remove_column(givenTree)
        
        (COL_PIXBUF, COL_STRING) = (0, 4)
        column = gtk.TreeViewColumn()
        column.set_title(column_names[0])
        lstList.insert_column(column, 0)

        column.pack_start(renderer_pb, expand=False)
        column.add_attribute(renderer_pb, 'pixbuf', COL_PIXBUF)
        column.pack_start(renderer, expand=True)
        column.add_attribute(renderer, 'text', COL_STRING)
        
        for i in range(1, len(column_names)):
            lstList.insert_column(gtk.TreeViewColumn(column_names[i], 
                                             renderer, text=i), i)
                                              
        nods = []
        nods_nr = []
        nods_nr.append(0)
        nods_nr.append(0)
        prev_nr = -1
        
        
        for i in relPaths:
            while gtk.events_pending():
                    gtk.main_iteration(False)
            nod_nr = i.count(self.sep)
            
            if nod_nr == 1:
               if i.endswith(self.sep) == False:
                    self.treestore1.append(None, (self.filepb, "File", 
                                   time.ctime(os.stat(self.myAbsPath(i)).st_mtime), 
                                   self.myUniconv(self.myAbsPath(i)), 
                                   self.myUniconv(os.path.basename(i)), i))
               else:
                   nods.append(self.treestore1.append(None, (None, None, None, 
                                                None, self.myUniconv(i), i)))
                   nods_nr.append(0)
               prev_nr = nod_nr
            elif i.endswith(self.sep) == False:
                self.treestore1.append(nods[nods_nr[nod_nr]], (self.filepb, "File", 
                                        time.ctime(os.stat(self.myAbsPath(i)).st_mtime), 
                                        self.myUniconv(self.myAbsPath(i)), 
                                        self.myUniconv(os.path.basename(i)), i))
            else: 
                if prev_nr < nod_nr:
                    nr = nods_nr[nod_nr - 1]
                    if nod_nr >= len(nods_nr):
                        nods_nr.append(len(nods))
                    else:
                        nods_nr[nod_nr] = len(nods)
                    nods.append(self.treestore1.append(nods[nr], (self.folderpb, "<Dir>", 
                                 time.ctime(os.stat(self.myAbsPath(i)).st_mtime), 
                                 self.myUniconv(self.myAbsPath(i)), 
                                 self.myUniconv(i.split(self.sep)[-2]), i)))
                else:
                    nr = nods_nr[nod_nr - 1]
                    nods_nr[nod_nr] = len(nods)
                    nods.append(self.treestore1.append(nods[nr], (self.folderpb,"<Dir>", 
                                 time.ctime(os.stat(self.myAbsPath(i)).st_mtime), 
                                 self.myUniconv(self.myAbsPath(i)), 
                                 self.myUniconv(i.split(self.sep)[-2]), i)))
                    
                prev_nr = nod_nr
        lstList.expand_all()        
                
    def myAbsPath(self, path):
        return self.FilesAbs[self.FilesTar.index(path)]
    
                           
    def myOpenTreeView(self):
        self.treestore1.clear()
        self.treestore2.clear()
        relPaths=self.FilesTar[:]
        relPaths.sort()
        lstList = self.xml.get_widget("lstList")
        lstList.set_model(self.treestore2)
        selection = lstList.get_selection()
        selection.set_mode(gtk.SELECTION_MULTIPLE)
        renderer = gtk.CellRendererText()
        renderer_pb = gtk.CellRendererPixbuf()
        column_names = ("Name", "Type", "Last Modified", "Mode", "Size")
        for k in range(0, len(lstList.get_columns())+1):
            givenTree = lstList.get_column(0)
            if givenTree != None:
                lstList.remove_column(givenTree)
        
        (COL_PIXBUF, COL_STRING) = (0, 5)
        column = gtk.TreeViewColumn()
        column.set_title(column_names[0])
        lstList.insert_column(column, 0)

        column.pack_start(renderer_pb, expand=False)
        column.add_attribute(renderer_pb, 'pixbuf', COL_PIXBUF)
        column.pack_start(renderer, expand=True)
        column.add_attribute(renderer, 'text', COL_STRING)
        
        for i in range(1, len(column_names)):
            lstList.insert_column(gtk.TreeViewColumn(column_names[i], 
                                             renderer, text=i), i)
                                             
        nods = []
        nods_nr = []
        nods_nr.append(0)
        nods_nr.append(0)
        prev_nr = -1
        
        relPaths = self.myCheckTarList(relPaths)
        
        for i in relPaths:
            while gtk.events_pending():
                    gtk.main_iteration(False)
            nod_nr = i.count("/")
                       
            if nod_nr == 1:
               if i.endswith("/") == False:
                   self.treestore2.append(None, (self.filepb, "File", 
                                           time.ctime(self.archive.tar.getmember(i[1:]).mtime),
                                            oct(self.archive.tar.getmember(i[1:]).mode), 
                                            self.archive.tar.getmember(i[1:]).size, 
                                            self.myUniconv(os.path.basename(i)), i))
               else:
                   nods.append(self.treestore2.append(None, (None, None, None, None, 
                                                    None, self.myUniconv(i), i)))
                   nods_nr.append(0)
               prev_nr = nod_nr
            elif i.endswith("/") == False:
                self.treestore2.append(nods[nods_nr[nod_nr]], (self.filepb, "File", 
                                        time.ctime(self.archive.tar.getmember(i[1:]).mtime),
                                         oct(self.archive.tar.getmember(i[1:]).mode), 
                                         self.archive.tar.getmember(i[1:]).size, 
                                         self.myUniconv(os.path.basename(i)), i))
            else: 
                if prev_nr < nod_nr:
                    nr = nods_nr[nod_nr - 1]
                    if nod_nr >= len(nods_nr):
                        nods_nr.append(len(nods))
                    else:
                        nods_nr[nod_nr] = len(nods)
                    try:
                        nods.append(self.treestore2.append(nods[nr], (self.folderpb, "<Dir>",
                                  time.ctime(self.archive.tar.getmember(i[1:]).mtime),
                                  oct(self.archive.tar.getmember(i[1:]).mode), 
                                  self.archive.tar.getmember(i[1:]).size, 
                                  self.myUniconv(i.split("/")[-2]), i)))
                    except KeyError:
                        nods.append(self.treestore2.append(nods[nr], (self.folderpb, "<Dir>",
                                  None, None, None, self.myUniconv(i.split("/")[-2]), i)))
                else:
                    nr = nods_nr[nod_nr - 1]
                    nods_nr[nod_nr] = len(nods)
                    try:
                        nods.append(self.treestore2.append(nods[nr], (self.folderpb, "<Dir>", 
                                 time.ctime(self.archive.tar.getmember(i[1:]).mtime),
                                  oct(self.archive.tar.getmember(i[1:]).mode), 
                                  self.archive.tar.getmember(i[1:]).size, 
                                  self.myUniconv(i.split("/")[-2]), i)))
                    except KeyError:
                        nods.append(self.treestore2.append(nods[nr], (self.folderpb, "<Dir>", 
                                 None, None, None, self.myUniconv(i.split("/")[-2]), i)))
                    
                prev_nr = nod_nr
        lstList.expand_all()
        
        
    # Wprowadzenie poprawek do listy plikow tar
    def myCheckTarList(self, list):
        list2 = []
        prev = 0
        ind = 0
        for i in list:
            while gtk.events_pending():
                gtk.main_iteration(False)
            current = i.count("/")
            if i.endswith("/") == True:
                list2.append(i)
            else:
                if current == 1:
                    list2.append(i)
                else:
                    try:
                        list2.index(os.path.dirname(i) + "/")
                    except ValueError:
                        list2.append(os.path.dirname(i) + "/")
                        list2.append(i)                            
                    else:                      
                        list2.append(i)    
                
        return list2
        
    
    #############################
    #  Main window constructor  #
    #############################  
    def __init__(self): 
   
        if sys.platform == 'win32':
            self.sep = '\\'
        else:
            self.sep = "/"
    
        self.sysfsenc = sys.getfilesystemencoding()
        self.new_archive_name = None
        self.treestore1 = gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, str, str) 
        self.treestore2 = gtk.TreeStore(gtk.gdk.Pixbuf, str, str, str, str, str, str) 
        
        self.gladedir = ".%sglade%spaker.glade" % (self.sep, self.sep)
        self.icondir1 = ".%sicon%sfolder.png" % (self.sep, self.sep)
        self.icondir2 = ".%sicon%sfiles.png" % (self.sep, self.sep)
        self.iconinfo = ".%sicon%skoda48.png" % (self.sep, self.sep)
        self.mainicon = ".%sicon%skoda16.png" % (self.sep, self.sep)
        
        self.xml = gtk.glade.XML(self.gladedir , "wndMain")
        self.wndMain = self.xml.get_widget("wndMain")
        self.wndMain.set_icon_from_file(self.mainicon)
        self.status_bar = self.xml.get_widget("stsBar")
        self.xml2 = gtk.glade.XML(self.gladedir , "popupNew")
        self.popupNew = self.xml2.get_widget("popupNew")
        self.xml3 = gtk.glade.XML(self.gladedir , "popupOpen")
        self.popupOpen = self.xml3.get_widget("popupOpen")
        
        self.icomnuadd = self.xml.get_widget("mnuAdd")
        self.icobtnadd = self.xml.get_widget("btnAdd")
        self.icomnuadddir = self.xml.get_widget("mnuAddDir")
        self.icobtnadddir = self.xml.get_widget("btnAddDir")
        self.icomnuremove = self.xml.get_widget("mnuRemove")
        self.icobtnremove = self.xml.get_widget("btnRemove")
        self.icomnucompress = self.xml.get_widget("mnuCompress")
        self.icobtncompress = self.xml.get_widget("btnCompress")
        self.icomnuextract = self.xml.get_widget("mnuExtract")
        self.icobtnextract = self.xml.get_widget("btnExtract")
        
        self.icomnuadd.set_sensitive(False)
        self.icobtnadd.set_sensitive(False)
        self.icomnuadddir.set_sensitive(False)
        self.icobtnadddir.set_sensitive(False)
        self.icomnuremove.set_sensitive(False)
        self.icobtnremove.set_sensitive(False)
        self.icomnucompress.set_sensitive(False)
        self.icobtncompress.set_sensitive(False)
        self.icomnuextract.set_sensitive(False)
        self.icobtnextract.set_sensitive(False)
        
        mysignals = { "on_mnuNew_activate": self.myNew,
                "on_btnNew_clicked": self.myNew,         
                "on_mnuOpen_activate": self.myOpen,
                "on_btnOpen_clicked": self.myOpen,
                "on_mnuQuit_activate": self.myQuit,
                "on_btnQuit_clicked": self.myQuit,
                "on_wndMain_destroy":self.myQuit,
                "on_mnuAdd_activate": self.myAdd,
                "on_btnAdd_clicked": self.myAdd,
                "on_mnuAddDir_activate": self.myAddDir,
                "on_btnAddDir_clicked": self.myAddDir,
                "on_mnuRemove_activate": self.myRemove,
                "on_btnRemove_clicked": self.myRemove,
                "on_mnuCompress_activate": self.myCompress,
                "on_btnCompress_clicked": self.myCompress,
                "on_mnuExtract_activate": self.myExtract,
                "on_btnExtract_clicked": self.myExtract,
                "on_mnuHelp_activate": self.myHelp,
                "on_btnHelp_clicked": self.myHelp,
                "on_mnuAbout_activate": self.myAbout,
                "on_lstList_button_press_event": self.myPopup,
                "on_wndMain_destroy": self.myQuit }
        
        mysignals2 = {"on_popAddFiles_activate": self.myAdd, 
                               "on_popAddDir_activate": self.myAddDir, 
                               "on_popCreateDir_activate": self.myCreate, 
                               "on_popRemove_activate": self.myRemove
                               }    
                               
        mysignals3 = {"on_popExtract_activate": self.myExtract}
        
        self.xml.signal_autoconnect(mysignals)
        self.xml2.signal_autoconnect(mysignals2)
        self.xml3.signal_autoconnect(mysignals3)
        self.wndMain.show_all()
        
        self.context_id = self.status_bar.get_context_id("All status messages")
        self.folderpb = gtk.gdk.pixbuf_new_from_file(self.icondir1)
        self.filepb = gtk.gdk.pixbuf_new_from_file(self.icondir2)
   
        
###########################
#  It's standard Python start section       #
###########################
def main():
    gtk.main()
    return 0
    
if __name__ == "__main__":
    rootwindow = myPacker() 
    main()
