SortableListCtrl.py 6.23 KB
# -*- coding: utf-8 -*-
import  threading
from PIL import Image

import i18n
_ = i18n.language.ugettext #use ugettext instead of getttext to avoid unicode errors

import  os.path
import  wx
import  wx.lib.mixins.listctrl  as  listmix
import subprocess

try:
    from agw import ultimatelistctrl as ULC
except ImportError: # if it's not there locally, try the wxPython lib.
    from wx.lib.agw import ultimatelistctrl as ULC
    
class SortableListCtrl(ULC.UltimateListCtrl, listmix.ColumnSorterMixin, listmix.ListCtrlAutoWidthMixin):
    def __init__(self, parent, log, superann, program, extension):
        
        self._lock = threading.Lock()
        
        self.program = program
        self.extension = extension
                
        ULC.UltimateListCtrl.__init__(self, parent, -1, agwStyle=ULC.ULC_REPORT | ULC.ULC_HAS_VARIABLE_ROW_HEIGHT | ULC.ULC_USER_ROW_HEIGHT)#|  wx.LC_HRULES | wx.LC_VRULES )
        listmix.ListCtrlAutoWidthMixin.__init__(self)
        
        self.log_ctrl = log
        
        self.il = wx.ImageList(16, 16)      
        up = wx.Image(os.path.join('img', 'up.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        down = wx.Image(os.path.join('img', 'down.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        if superann:
            textimg_1 = wx.Image(os.path.join('img', 'textimg_2.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        else:
            textimg_1 = wx.Image(os.path.join('img', 'textimg_1.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        ready = wx.Image(os.path.join('img', 'ready.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        self.sm_up = self.il.Add(up)
        self.sm_dn = self.il.Add(down)
        self.textimg_1 = self.il.Add(textimg_1)
        self.ready = self.il.Add(ready)
                
        self.AssignImageList(self.il, wx.IMAGE_LIST_SMALL)
        
        self.SetUserLineHeight(23)
        self.InsertColumn(0, _("File"))
        self.InsertColumn(1, _("Status"))
        self.InsertColumn(2, _("Ready"))
        self.InsertColumn(3, _("Stage"))
        self.InsertColumn(4, "")
        self.SetColumnWidth(0, 80)
        self.SetColumnWidth(1, 100)
        self.SetColumnWidth(2, 120)
        self.SetColumnWidth(3, 100)
                
        self.itemDataMap = {}
        
        listmix.ColumnSorterMixin.__init__(self, 5)
                
    # required by ColumnSorterMixin
    def GetListCtrl(self):
        return self
    
    def GetSortImages(self):
        return (self.sm_dn, self.sm_up)
    # required by ColumnSorterMixin - end
    
    def show(self, data):    
        self._lock.acquire()        
        try:
            # for some reason deleteAllItems() doesn't work with buttons inside ulc
            for item in range(self.GetItemCount()):
                self.DeleteItem(0)            
            self.itemDataMap.clear()
            for i, (file_name, status, is_ready, stage) in enumerate(data):
                img = self.textimg_1
                if is_ready == _("Yes"):
                    img = self.ready                    
                pos = self.InsertImageStringItem(i, file_name, img)
                self.SetStringItem(pos, 1, status)
                self.SetStringItem(pos, 2, is_ready)
                self.SetStringItem(pos, 3, stage)
                
                button = wx.Button(self, id=i, size=(80, 23), label=_("Open"))                        
                self.SetItemWindow(pos, col=4, wnd=button, expand=False)                
                button.Bind(wx.EVT_BUTTON, self.open_button)
                
                self.SetItemData(pos, i)
                
                self.itemDataMap[i] = (file_name, status, is_ready, stage, None)
        finally:
            self._lock.release()
            
    def shown_data(self):
        result = []
        for i in range(self.GetItemCount()):
            part_result = []
            for j in range(0, 4):
                part_result.append(self.GetItem(i, j).GetText())
            result.append(tuple(part_result))
        return result
    
    def SetReadyYes(self, pos):
        self.SetItemImage(pos, self.ready)
        return self._set_ready(pos, _("Yes"))
    
    def SetReadyNo(self, pos):
        self.SetItemImage(pos, self.textimg_1)
        return self._set_ready(pos, _("No"))

    def _set_ready(self, pos, val):
        file_name = self.GetItem(pos, 0).GetText()        
        for key, (filename, status, ready, stage, sth) in self.itemDataMap.iteritems():
            if filename == file_name:
                self.itemDataMap[key] = (filename, status, val, stage, sth)
                break
        return self.SetStringItem(pos, 2, val)
    
    def GetFilename(self, pos):
        return self.GetItem(pos, 0).GetText()
    
    def IsReady(self, pos):
        return self.GetItem(pos, 2).GetText() == _("Yes")
    
    def select_ready(self):
        return self._select(lambda list, pos : list.GetItem(pos, 2).GetText() == _("Yes"))

    def select_modified(self):
        return self._select(lambda list, pos : list.GetItem(pos, 1).GetText() == _("Modified"))
        
    def _select(self, cond):
        for i in range(self.GetItemCount()):
            if cond(self, i):
                self.Select(i, 1)
            else:
                self.Select(i, 0)
                
    def get_selected(self):
        fnames = []
        for i in range(self.GetItemCount()):
            if self.IsSelected(i):
                fnames.append(self.GetFilename(i))
        return fnames
        
    def open_button(self, event):
        file_name = self.GetFilename(event.GetEventObject().GetId())
        print event.GetEventObject().GetId()
        if file_name:            
            self.log_ctrl.AppendText(_("Starting ") + self.program + _(" for text") + " " + file_name + "...\n")                        
            app = os.path.join("..", self.program, self.program+".exe")
            app_bin = os.path.join("..", self.program, self.program)
            if not os.path.exists(app):
                app = app_bin
            text = os.path.join("..", "teksty", file_name + self.extension)
            try:
                subprocess.Popen([app, text])
            except Exception as ex:
                self.log_ctrl.AppendText(_("Error starting ") + self.program + ": " + unicode(str(ex), errors='replace') + "\n")