2
# This file is part of GNU Enterprise.
4
# GNU Enterprise is free software; you can redistribute it
5
# and/or modify it under the terms of the GNU General Public
6
# License as published by the Free Software Foundation; either
7
# version 2, or (at your option) any later version.
9
# GNU Enterprise is distributed in the hope that it will be
10
# useful, but WITHOUT ANY WARRANTY; without even the implied
11
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
# PURPOSE. See the GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public
15
# License along with program; see the file COPYING. If not,
16
# write to the Free Software Foundation, Inc., 59 Temple Place
17
# - Suite 330, Boston, MA 02111-1307, USA.
19
# Copyright 2001-2005 Free Software Foundation
29
from gnue.common.apps import GDebug
30
from FormatExceptions import *
34
# locale.nl_langinfo( option)
36
# Return some locale-specific information as a string. This function is
37
# not available on all systems, and the set of possible options might
38
# also vary across platforms. The possible argument values are numbers,
39
# for which symbolic constants are available in the locale module.
42
# Return name of the n-th day of the week.
45
# Return abbreviated name of the n-th day of the week.
48
# Return name of the n-th month.
50
# ABMON_1 ... ABMON_12
51
# Return abbreviated name of the n-th month.
54
# This is a class for a mask literal element
56
def __init__(self, literal):
57
self.literal = literal
59
def getFormattedValue(self, value):
62
def isValidEntry(self, value):
63
return value == self.literal
65
def isCompleteEntry(self, value):
74
predefinedLiterals = ""
77
literalClass = Literal
79
def __init__(self, outputMask, inputMask=None, outputMask2=None):
81
self.outputHandlers = self.parseMask(outputMask)
82
print "Creating mask handler: %s;%s" % (outputMask,inputMask)
83
print self.outputHandlers
86
self.inputHandlers = self.parseMask(inputMask)
87
if outputMask2 != None:
88
self.output2Handlers = self.parseMask(outputMask2)
90
# Calculate our array lengths once to speed up
91
# our code. This should always be equivalent to:
92
# len(self.inputHandlers)
93
# len(self.inputMaskPos)
94
# len(self.inputMaskLen)
95
# len(self.inputDisplayLen)
96
self.inputCount = len(self.inputHandlers)
103
# Holds the starting positions of each element section...
104
self.inputMaskPos = [0] * self.inputCount
106
# Holds the length of each element section...
107
self.inputMaskLen = [0] * self.inputCount
109
# Holds the length of each formatted element section...
110
self.inputDisplayLen = [0] * self.inputCount
111
# .. including padding
112
self.inputFormattedLen = [0] * self.inputCount
121
# Take a mask string and break it into its elements and map it to handlers
122
def parseMask(self, mask, edit=0):
123
GDebug.printMesg(7,'parseMask("%s")' % mask)
126
# Load a predefined mask, if that's what user specified
127
# TODO: Should predefined masks be pulled from other than gnue.conf?
128
if len(mask) > 1 and mask[0] == '&':
129
for i in range(edit+1):
130
edstr = ('edit','')[i]
131
if mask[1:] == self.basetype:
133
mask = gConfig('%s%smask' % (self.basetype, edstr), self.defaultmask)
138
mask = gConfig('%smask_%s' % (self.basetype, edstr, mask[1:]))
142
tmsg = u_('The requested format mask "%(mask)s" is not defined for '
144
% {'mask': mask [1:],
145
'type': self.basetype}
146
raise PredefinedMaskNotFound, tmsg
148
# Process each character in mask at a time
153
elif isLiteral or ch in self.predefinedLiterals:
155
maskHandler.append(self.literalClass(ch))
156
elif self.maskMappings.has_key(ch):
157
maskHandler.append(self.maskMappings[ch])
159
tmsg = u_('Unexpected character "%(char)s" in %(type)s mask.') \
161
'type': self.basetype}
162
raise InvalidCharInMask, tmsg
166
# If secondary is true, then use secondary mask (outputMask2)
167
def getFormattedOutput(self, secondary=0):
170
def getFormattedInput(self):
174
def setText(self, text):
182
# Returns (value, formatted text, cursor)
183
def addText(self, value, text, pos, replaces=0, padding="_"):
186
for size in self.inputDisplayLen:
189
print "Starting cursor: %s; shift: %s" % (cursor, shift)
192
value = self.processEdit(value, text, pos, replaces)
193
formatted = self.getFormattedInput(value,padding=padding)
195
for size in self.inputDisplayLen:
198
self.cursor = cursor + shift
199
self.moveCursorRelative(0)
201
print "Ending cursor: %s; shift: %s" % (self.cursor, shift)
203
return (value, formatted, self.cursor)
207
# Returns (value, formatted text, cursor)
208
def deleteText(self, text, pos, characters):
214
# Given a display cursor, calculate the index into the string
216
def cursorToIndex(self, cursor):
221
while ( i < self.inputCount - 1 ) and \
222
( cursor < pos + self.inputDisplayLen[i] ) :
223
pos += self.inputDisplayLen[i]
227
diff = cursor - pos - self.inputDisplayLen[i]
228
if diff > self.inputMaskLen[i]:
229
diff = self.inputMaskLen[i]
231
return max(self.inputMaskPos[i] + diff,0)
235
# Given an index into the string, calculate the display cursor,
237
def indexToCursor(self, index):
240
while ( i < self.inputCount - 1 ) and \
241
( index < self.inputMaskPos[i] ) :
244
pos = self.inputMaskPos[i]
246
diff = index - pos - self.inputMaskLen[i]
249
return max(pos + diff,0)
253
# Move cursor using relative units
255
# If relative > 0, move cursor to the right <relative> units
256
# If relative < 0, move cursor to the left |<relative>| units
257
# This takes into account Literals, etc.
259
def moveCursorRelative(self, relative):
261
print "*** moveCursorRelative(%s)" % relative
263
# Direction = -1 (left) or 1 (right).
264
direction = relative == 0 or int(relative/abs(relative))
266
print "relative=%s" % relative
267
print "direction=%s" % direction
269
self.cursor = self.cursor + relative
271
print "cursor #1: %s" % self.cursor
276
elif self.cursor > len(self.display):
277
self.cursor = len(self.display)
280
print "cursor #2: %s" % self.cursor
284
while section < self.inputCount and \
285
((pos + self.inputDisplayLen[section]) < self.cursor):
287
pos += self.inputDisplayLen[section]
288
print "%s; %s" %(section, pos)
293
print "section=%s" % pos
295
if pos + self.inputFormattedLen[section] == self.cursor:
296
print "cursor #2b: %s" % self.cursor
299
print "section=%s" % section
301
if section == self.inputCount:
302
# self.cursor = pos + self.inputDisplayLen[-1]
303
print "cursor #3: %s" % self.cursor
308
print "section=%s" % section
309
if isinstance(self.inputHandlers[section], Literal):
310
self.moveCursorRelative(direction)
311
print "cursor #4: %s" % self.cursor
313
self.index = self.cursorToIndex(self.cursor)
315
print "New cursor position: %s" % self.cursor
321
# Move cursor to the beginning of the field
323
def moveCursorToBegin(self):
325
# Reset cursor to beginning
329
# This will handle if the first character is a literal
330
# (e.g., for phone numbers (999) 999-9999, this will move
331
# to the first '9', not the '('
332
return self.moveCursorRelative(0)
336
# Move cursor to the beginning of the field
338
def moveCursorToEnd(self):
340
# Reset cursor to beginning
341
self.cursor = self.indexToCursor(self.lastInputPos)
343
return self.moveCursorRelative(0)
350
def processEdit (self, value, str, pos=0, replaces=0):
352
GDebug.printMesg(7,'processEdit(%s,%s,%s,%s)' % (value,str,pos,replaces))
358
nv = "%s%s%s" % (nv[:pos],str,nv[pos+replaces:])
360
GDebug.printMesg(7,"inputMaskPos=%s" % self.inputMaskPos)
365
while section < self.inputCount and \
366
self.inputMaskPos[section] < pos and \
367
self.inputMaskPos[section] > 0:
376
if not self.inputHandlers[section]\
377
.isValidEntry(nv[self.inputMaskPos[section]:i+1]):
378
if i == self.inputMaskPos[section] and \
379
not isinstance(self.inputHandlers[section],Literal):
380
self.inputMaskLen[section] = i - self.inputMaskPos[section]
383
self.inputMaskLen[section] = i - self.inputMaskPos[section]
384
if section == self.inputCount - 1:
391
self.inputMaskPos[section] = i
392
self.inputMaskLen[section] = 0
396
self.inputMaskLen[section] = i - self.inputMaskPos[section]
398
for i in range(section+1, self.inputCount):
399
self.inputMaskLen[i] = 0
401
self.index = pos + len(value)
402
self.cursor = self.indexToCursor(self.index)
403
print "after processEdit, index=%s;cursor=%s" % (self.index, self.cursor)
405
GDebug.printMesg(7,"<< %s" % nv)
410
# This is a base class for mask elements
418
self.intersperseString = ","
419
self.intersperseRepeat = 1
422
def getFormattedValue(self):
425
def isValidEntry(self, value):
428
def isCompleteEntry(self, value):
429
return len(value) == self.maxLength