1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
|
## Fonty Python Copyright (C) 2006, 2007, 2008, 2009 Donn.C.Ingle
## Contact: donn.ingle@gmail.com - I hope this email lasts.
##
## This file is part of Fonty Python.
## Fonty Python 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 3 of the License, or
## (at your option) any later version.
##
## Fonty Python 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 Fonty Python. If not, see <http://www.gnu.org/licenses/>.
import wx, locale
## June 25th 2016
## Remarking these two lines because they are causing a segfault:
## ../src/common/stdpbase.cpp(62): assert "traits" failed in Get():
## create wxApp before calling this
## Segmentation fault (core dumped)
##
## I do not know how to test or fix this, hence simply removing it.
## AFAICT, stock buttons will be in the system language.
##
## Setup wxPython to access translations : enables the stock buttons.
##langid = wx.LANGUAGE_DEFAULT # Picks this up from $LANG
##mylocale = wx.Locale( langid )
from pubsub import *
from wxgui import ps
import fpsys # Global objects
import fontcontrol
import fontybugs
class PogChooser(wx.ListCtrl) :
"""
Basic list control for pogs - instanced by TargetPogChooser and NoteBook
This single class (being used twice) causes terrible conceptual hardships
and forces all kinds of twisty tests. I'm sorry for this, we need a better
solution.
"""
## CLASS LEVEL variables - special things these.
__poglistCopy = {} # To help in sorting.
__TARGET = None
__VIEW = None
def __init__(self, parent, whoami, select = None) :
self.indexselected = 0
self.lastindexselected = -1
self.parent = parent
self.whoami = whoami
## Use Class-level attributes to record the history of
## the instantiation of this class. These vars do not
## belong to the instances, but to this one class.
## We keep refs to the two parents of this class.
if whoami == "SOURCEPOG" :#isinstance( self.parent, wx.Panel ):
PogChooser.__VIEW = self
style = wx.LC_LIST | wx.LC_AUTOARRANGE | wx.LC_SORT_ASCENDING | wx.LC_SINGLE_SEL
else:
PogChooser.__TARGET = self.parent
style = wx.LC_LIST | wx.LC_AUTOARRANGE | wx.LC_SORT_ASCENDING
il = wx.ImageList(16,16,True)
png = wx.Bitmap(fpsys.mythingsdir + "/pog16x16.png",wx.BITMAP_TYPE_PNG)
il.Add(png)
png = wx.Bitmap(fpsys.mythingsdir + "/pog16x16.installed.png",wx.BITMAP_TYPE_PNG)
il.Add(png)
## Dec 2007 : target icon
png = wx.Bitmap( fpsys.mythingsdir + "/pog16x16.target.png", wx.BITMAP_TYPE_PNG )
il.Add( png )
wx.ListCtrl.__init__( self,parent,-1, style=style | wx.SUNKEN_BORDER )
self.AssignImageList(il, wx.IMAGE_LIST_SMALL)
self.__PC = fpsys.iPC # reuse the global pathcontrol object
self.fillPogList()
## Highlight the pog selected (the last one, or the cli chosen one)
if select:
i = self.FindItem(-1, select)
self.indexselected = i # Set this to help initial icon settings.
self.Select(i, True)
elif self.__poglistCopy:
self.Select(0, False)
self.indexselected = -1
self.ClearBackground()
self.items = None
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect)
## This one is a double click event
## self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.__onActivate )
#self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
## This subscribe line here will register TWICE since this PogChooser object is instanced
## twice by the app...
ps.sub(change_pog_icon, self.ChangeIcon) ##DND: class PogChooser
def Sorter(self, key1, key2):
"""
Fetch the strings from our CLASS LEVEL copy of the pognames
so that we can compare them via locale.
"""
s1,s2 = PogChooser.__poglistCopy[key1], PogChooser.__poglistCopy[key2]
## Since the gui is unicode, I *think* I don't have to worry about errors here.
return locale.strcoll( s1, s2 )
def onSelect(self, e):
wx.BeginBusyCursor()
self.indexselected = e.m_itemIndex
pognochange = False
if self.indexselected == self.lastindexselected:
## We have clicked on the same Pog as last time - ergo do nothing.
pognochange = True
self.lastindexselected = self.indexselected # Record this for next time around
textpogname = self.GetItemText(self.indexselected) # Gets UNICODE !!!
if self.whoami=="SOURCEPOG":
ps.pub(source_pog_has_been_selected, textpogname, pognochange)
else:
ps.pub(target_pog_has_been_selected, textpogname, pognochange)
self.SortOutTheDamnImages( pognochange )
wx.EndBusyCursor()
def SortOutTheDamnImages( self, pognochange ):
"""
Dec 2007 : This took me an entire day to figure out. Man...
Determines the images of the list items.
Is called from TargetPogChooser as well (when clear button is clicked)
"""
if pognochange is ():
pognochange = True
c = self.GetItemCount()
sel = self.indexselected # the actual selection index, does not go to -1
## Which kind of a McList am I?
iAmTargetList = self.whoami=="TARGETPOG" #isinstance( self.parent, TargetPogChooser )
## If there is an active selection?
if sel > -1:
for x in xrange(0, c):
i = self.GetItem(x, 0)
## Must make a tmp Pog before I can test installed status.
tmpPog = fontcontrol.Pog(i.GetText())
if tmpPog.isInstalled():
self.SetItemImage(x, 1)
else:
## Handle the other icons (in the target list only)
## that are not installed.
if iAmTargetList:
if x == sel:
## No change means it *was* selected
## and now it's been selected again
## thus it can't be the target anymore.
if pognochange: n = 0
else: n = 2
self.SetItemImage(x, n ) # new target icon
else:
self.SetItemImage(x, 0)
## Tell the VIEW to imitate this picture.
for x in xrange(0,c):
ti = self.__TARGET.pogTargetlist.GetItem(x, 0) # the 0 is 'column'. Ignore.
CLONE = ti.GetImage()# gets the image index, not an image bitmap.
self.__VIEW.SetItemImage(x, CLONE)
def __del__(self) :
del self.items
def fillPogList(self):
"""
This is among the very FIRST things we do.
Fill the list with pogs.
This will CULL any bad pogs (i.e. those with malformed content)
Thus the PogInvalid error should not happen any more after a run.
"""
pl = self.__PC.getPogNames() # pl will always be a BYTE STRING list
for p in pl: # 'p' is a byte string.
ipog = fontcontrol.Pog(p)
try: #catch pogs that are not properly formed
if ipog.isInstalled(): i = 1 # isInstalled opens the pog file.
else: i = 0
except fontybugs.PogInvalid, eInst:
## An "invalid" pog is one that does not have
## installed/not installed on the first line.
print _(u"(%s) skipped. It's an invalid pog.") % [p]
continue
## Let's try to make a unicode of p so li.SetText(p) can display it:
try:
p = fpsys.LSP.to_unicode( p )
except UnicodeDecodeError:
## We can't convert it under this locale
print _(u"(%s) skipped. I can't display this name under your locale.") % [p]
continue
## Okay, we have a valid pog name to use:
li = wx.ListItem()
li.SetImage(i)
li.SetText(p)
## June 25, 2016: Something in wxPython changed and li now needs an Id>0
li.Id = 1
id = wx.NewId()
PogChooser.__poglistCopy[id] = p # record the pog name
row = self.InsertItem( li )
self.SetItemData( row, id ) # associate back to __poglistCopy
self.SortItems( self.Sorter )
def AddItem(self, pogname):
"""
Add a pogname to myself, then sort.
"""
li = wx.ListItem()
li.SetImage(0)
li.SetText(pogname)
#July 5th, 2016 - wxPython Id fix
li.Id = 1
id = wx.NewId()
self.__poglistCopy[id] = pogname
row = self.InsertItem(li)
self.SetItemData( row, id )
self.SortItems( self.Sorter )
def RemoveItem(self, pogname):
row = self.FindItem(-1, pogname)
id = self.GetItemData(row)
self.DeleteItem(row)
del( PogChooser.__poglistCopy[id] ) # cull from our private store too.
def ClearSelection(self):
# removes all selections, even for multi-selections
for x in range(self.GetSelectedItemCount()):
self.Select(self.GetFirstSelected(), False)
self.lastindexselected = -1
def ChangeIcon(self):
"""
Change a single Pog's icon to installed/uninstalled.
ONLY called from InstallPog and UninstallPog.
"""
T = fpsys.state.targetobject
pn = T.name
index = self.FindItem(0, pn)
if T.isInstalled(): n = 1
else: n = 0
self.SetItemImage(index, n) ## Found in wxWidgets documentation!
def ClearLastIndex(self):
"""
We need to reset the lastindexselected so that a click on the
same item as last time will register. This is used in the Notebook
when the page changes back to page 1, we want the user to
be able to re-click the item that was clicked last time.
"""
self.lastindexselected = -1
|