Ejemplo n.º 1
0
	def deleteAll(self, dataSource=None, message=None):
		"""Ask the primary bizobj to delete all records from the recordset."""
		self.dataSourceParameter = dataSource
		bizobj = self.getBizobj(dataSource)
		if bizobj is None:
			# Running in preview or some other non-live mode
			return
		self.activeControlValid()

		err = self.beforeDeleteAll()
		if err:
			self.notifyUser(err)
			return
		if not message:
			message = _("This will delete all records in the recordset, and cannot "
						"be canceled.\n\n Are you sure you want to do this?")

		if dabo.ui.areYouSure(message, defaultNo=True):
			try:
				bizobj.deleteAll()
				# Notify listeners that the row number changed:
				self.raiseEvent(dEvents.RowNumChanged)
			except dException.ConnectionLostException, e:
				msg = self._connectionLostMsg(ustr(e))
				self.notifyUser(msg, title=_("Data Connection Lost"), severe=True, exception=e)
				sys.exit()
			except dException.dException, e:
				dabo.log.error(_("Delete All failed with response: %s") % e)
				self.notifyUser(ustr(e), title=_("Deletion Not Allowed"), severe=True, exception=e)
Ejemplo n.º 2
0
    def _setValue(self, val):
        if self._constructed():
            # Must convert all to string for sending to wx, but our internal
            # _value will always retain the correct type.

            # TextCtrls in wxPython since 2.7 have a ChangeValue() method that is to
            # be used instead of the old SetValue().
            setter = self.SetValue
            if hasattr(self, "ChangeValue"):
                setter = self.ChangeValue

            # Todo: set up validators based on the type of data we are editing,
            # so the user can't, for example, enter a letter "p" in a textbox
            # that is currently showing numeric data.

            if self._inForceCase:
                # Value is changing internally. Don't update the oldval
                # setting or change the type; just set the value.
                setter(val)
                return
            else:
                dabo.ui.callAfter(self._checkForceCase)

            if self._inTextLength:
                # Value is changing internally. Don't update the oldval
                # setting or change the type; just set the value.
                setter(val)
                return
            else:
                dabo.ui.callAfter(self._checkTextLength)

            strVal = self.getStringValue(val)
            _oldVal = self.Value

            # save the actual value for return by _getValue:
            self._value = val

            if val is not None:
                # Save the type of the value, so that in the case of actual None
                # assignments, we know the datatype to expect.
                self._lastDataType = type(val)

            # Update the display if it is different from what is already displayed
            # (note that if we did it unconditionally, the user's selection could
            # be reset, which isn't very nice):
            if strVal != _oldVal:
                try:
                    setter(strVal)
                except ValueError as e:
                    #PVG: maskedtextedit sometimes fails, on value error..allow the code to continue
                    uv = ustr(strVal)
                    ue = ustr(e)
                    dabo.log.error(
                        _("Error setting value to '%(uv)s': "
                          "%(ue)s") % locals())

            if type(_oldVal) != type(val) or _oldVal != val:
                self._afterValueChanged()
        else:
            self._properties["Value"] = val
Ejemplo n.º 3
0
	def _setValue(self, val):
		if self._constructed():
			# Must convert all to string for sending to wx, but our internal
			# _value will always retain the correct type.

			# TextCtrls in wxPython since 2.7 have a ChangeValue() method that is to
			# be used instead of the old SetValue().
			setter = self.SetValue
			if hasattr(self, "ChangeValue"):
				setter = self.ChangeValue

			# Todo: set up validators based on the type of data we are editing,
			# so the user can't, for example, enter a letter "p" in a textbox
			# that is currently showing numeric data.

			if self._inForceCase:
				# Value is changing internally. Don't update the oldval
				# setting or change the type; just set the value.
				setter(val)
				return
			else:
				dabo.ui.callAfter(self._checkForceCase)

			if self._inTextLength:
				# Value is changing internally. Don't update the oldval
				# setting or change the type; just set the value.
				setter(val)
				return
			else:
				dabo.ui.callAfter(self._checkTextLength)

			strVal = self.getStringValue(val)
			_oldVal = self.Value

			# save the actual value for return by _getValue:
			self._value = val

			if val is not None:
				# Save the type of the value, so that in the case of actual None
				# assignments, we know the datatype to expect.
				self._lastDataType = type(val)

			# Update the display if it is different from what is already displayed
			# (note that if we did it unconditionally, the user's selection could
			# be reset, which isn't very nice):
			if strVal != _oldVal:
				try:
					setter(strVal)
				except ValueError as e:
					#PVG: maskedtextedit sometimes fails, on value error..allow the code to continue
					uv = ustr(strVal)
					ue = ustr(e)
					dabo.log.error(_("Error setting value to '%(uv)s': "
							"%(ue)s") % locals())

			if type(_oldVal) != type(val) or _oldVal != val:
				self._afterValueChanged()
		else:
			self._properties["Value"] = val
Ejemplo n.º 4
0
def setLanguage(lang=None, charset=None):
    """Change the language that strings get translated to, for all installed domains.
	NOTE: rather than call the install() method of the gettext.translation objects,
	which would globally bind the '_' name, we'll just set the '_currentTrans'
	name to the translation object.
	"""
    from dabo.lib.utils import ustr
    global _domains, _currentTrans
    lang = _languageAliases.get(lang.lower(), lang)

    if lang is not None and isinstance(lang, basestring):
        lang = [lang]

    daboTranslation = None
    daboLocaleDir = _domains.get("dabo", None)
    if daboLocaleDir:
        try:
            daboTranslation = gettext.translation("dabo",
                                                  daboLocaleDir,
                                                  languages=lang,
                                                  codeset=charset)
        except IOError:
            # No translation file found
            dabo.log.error("""
No translation file found for domain 'dabo'.
    Locale dir = %s
    Languages = %s
    Codeset = %s """ % (daboLocaleDir, ustr(lang), charset))
            # Default to US English
            daboTranslation = gettext.translation("dabo",
                                                  daboLocaleDir,
                                                  languages=["en"],
                                                  codeset=charset)
        _currentTrans = daboTranslation.ugettext

    for domain, localedir in _domains.items():
        if domain == "dabo":
            continue  ## already handled separately above
        try:
            translation = gettext.translation(domain,
                                              localedir,
                                              languages=lang,
                                              codeset=charset)
        except IOError:
            dabo.log.error(
                "No translation found for domain '%s' and language %s." %
                (domain, lang))
            dabo.log.error("""
No translation file found for domain '%s'.
    Locale dir = %s
    Languages = %s
    Codeset = %s """ % (domain, daboLocaleDir, ustr(lang), charset))
        if daboTranslation:
            translation.add_fallback(daboTranslation)
        _currentTrans = translation.ugettext
Ejemplo n.º 5
0
	def getConnection(self, connectInfo, **kwargs):
		import MySQLdb as dbapi

		port = connectInfo.Port
		if not port:
			port = 3306

		kwargs = {}
		# MySQLdb doesn't provide decimal converter by default, so we do it here
		from MySQLdb import converters
		from MySQLdb import constants

		DECIMAL = constants.FIELD_TYPE.DECIMAL
		conversions = converters.conversions.copy()
		conversions[DECIMAL] = decimal.Decimal

		def dec2str(dec, dic):
			return str(dec)

		conversions[decimal.Decimal] = dec2str
		kwargs["conv"] = conversions

		# Determine default charset
		charset = None
		db = connectInfo.Database
		if db:
			try:
				cn = dbapi.connect(host=connectInfo.Host, user=connectInfo.User,
						passwd=connectInfo.revealPW(), port=port)
				crs =  cn.cursor()
				# Params don't work here; need direct string to execute
				crs.execute("show create database %s" % (db, ))
				charset = crs.fetchone()[1].split("DEFAULT CHARACTER SET")[1].split()[0]
				self.Encoding = charset
			except IndexError:
				pass
		if charset is None:
			# Use the default Dabo encoding
			charset = dabo.getEncoding()
			charset = charset.lower().replace("-", "")

		try:
			self._connection = dbapi.connect(host=connectInfo.Host,
					user = connectInfo.User, passwd = connectInfo.revealPW(),
					db=connectInfo.Database, port=port, charset=charset, **kwargs)
		except Exception as e:
			try:
				errMsg = ustr(e).decode(self.Encoding)
			except UnicodeError:
				errMsg = ustr(e)
			if "access denied" in errMsg.lower():
				raise dException.DBNoAccessException(errMsg)
			else:
				raise dException.DatabaseException(errMsg)
		return self._connection
Ejemplo n.º 6
0
Archivo: dPref.py Proyecto: CarlFK/dabo
	def _encodeType(self, val, typ):
		"""Takes various value types and converts them to a string formats that
		can be converted back when needed.
		"""
		if typ == "date":
			ret = ustr((val.year, val.month, val.day))
		elif typ == "datetime":
			ret = ustr((val.year, val.month, val.day, val.hour, val.minute, val.second, val.microsecond))
		else:
			ret = ustr(val)
		return ret
Ejemplo n.º 7
0
Archivo: dPref.py Proyecto: xfxf/dabo
    def _encodeType(self, val, typ):
        """Takes various value types and converts them to a string formats that
		can be converted back when needed.
		"""
        if typ == "date":
            ret = ustr((val.year, val.month, val.day))
        elif typ == "datetime":
            ret = ustr((val.year, val.month, val.day, val.hour, val.minute,
                        val.second, val.microsecond))
        else:
            ret = ustr(val)
        return ret
Ejemplo n.º 8
0
	def getConnection(self, connectInfo, **kwargs):
		# kinterbasdb will barf with unicode strings for user nad password:
		host = ustr(connectInfo.Host)
		port = connectInfo.Port
		if port:
			host = "%s/%s" % (host, port)
		user = str(connectInfo.User)
		password = str(connectInfo.revealPW())
		database = ustr(connectInfo.Database)

		self._connection = self.dbapi.connect(host=host, user=user,
				password=password, database=database, **kwargs)
		return self._connection
Ejemplo n.º 9
0
def setLanguage(lang=None, charset=None):
    """Change the language that strings get translated to, for all installed domains.
	NOTE: rather than call the install() method of the gettext.translation objects,
	which would globally bind the '_' name, we'll just set the '_currentTrans'
	name to the translation object.
	"""
    from dabo.lib.utils import ustr

    global _domains, _currentTrans
    lang = _languageAliases.get(lang.lower(), lang)

    if lang is not None and isinstance(lang, str):
        lang = [lang]

    daboTranslation = None
    daboLocaleDir = _domains.get("dabo", None)
    if daboLocaleDir:
        try:
            daboTranslation = gettext.translation("dabo", daboLocaleDir, languages=lang, codeset=charset)
        except IOError:
            # No translation file found
            dabo.log.error(
                """
No translation file found for domain 'dabo'.
    Locale dir = %s
    Languages = %s
    Codeset = %s """
                % (daboLocaleDir, ustr(lang), charset)
            )
            # Default to US English
            daboTranslation = gettext.translation("dabo", daboLocaleDir, languages=["en"], codeset=charset)
        _currentTrans = daboTranslation.ugettext

    for domain, localedir in list(_domains.items()):
        if domain == "dabo":
            continue  ## already handled separately above
        try:
            translation = gettext.translation(domain, localedir, languages=lang, codeset=charset)
        except IOError:
            dabo.log.error("No translation found for domain '%s' and language %s." % (domain, lang))
            dabo.log.error(
                """
No translation file found for domain '%s'.
    Locale dir = %s
    Languages = %s
    Codeset = %s """
                % (domain, daboLocaleDir, ustr(lang), charset)
            )
        if daboTranslation:
            translation.add_fallback(daboTranslation)
        _currentTrans = translation.ugettext
Ejemplo n.º 10
0
Archivo: dForm.py Proyecto: xfxf/dabo
    def delete(self, dataSource=None, message=None, prompt=True):
        """Ask the bizobj to delete the current record."""
        self.dataSourceParameter = dataSource
        bizobj = self.getBizobj(dataSource)
        if bizobj is None:
            # Running in preview or some other non-live mode
            return

        ds = bizobj.DataSource
        biz_caption = bizobj.Caption
        if not biz_caption:
            biz_caption = ds

        self.activeControlValid()

        if not bizobj.RowCount > 0:
            # Nothing to delete!
            self.setStatusText(_("Nothing to delete!"))
            return

        err = self.beforeDelete()
        if err:
            self.notifyUser(err)
            return
        if message is None:
            message = _(
                "This will delete the current record from %s, and cannot "
                "be canceled.\n\n Are you sure you want to do this?"
            ) % biz_caption
        if not prompt or dabo.ui.areYouSure(
                message, defaultNo=True, cancelButton=False):
            try:
                bizobj.delete()
                self.setStatusText(_("Record Deleted."))
                # Notify listeners that the row number changed:
                self.raiseEvent(dEvents.RowNumChanged)
            except dException.ConnectionLostException, e:
                msg = self._connectionLostMsg(ustr(e))
                self.notifyUser(msg,
                                title=_("Data Connection Lost"),
                                severe=True,
                                exception=e)
                sys.exit()
            except dException.dException, e:
                msg = ustr(e)
                dabo.log.error(_("Delete failed with response: %s") % msg)
                self.notifyUser(msg,
                                title=_("Deletion Not Allowed"),
                                severe=True,
                                exception=e)
Ejemplo n.º 11
0
	def insertTraceback(self, lst, traceback):
		#Add the traceback data
		for tbNum in range(len(traceback)):
			data = traceback[tbNum]
			lst.append( (os.path.basename(data[0]), ustr(data[1]), ustr(data[2]), ustr(data[3])))

			# Check whether this entry is from the demo module
			pth = os.path.split(data[0])[0]
			codeDirs = (DemoModules.getOrigDir(), DemoModules.getModDir())
			if pth in codeDirs:
				lst.setItemData(tbNum, int(data[1]))	 # Store line number for easy access
				# Give it a blue colour
				lst.setItemForeColor(tbNum, "blue")
			else:
				lst.setItemData(tbNum, -1)		# Editor can't jump into this one's code
Ejemplo n.º 12
0
	def updatePropVal(self, prop, val, typ):
		obj = self.Selection
		if obj is None:
			return
		if typ is bool:
			val = bool(val)
		if isinstance(val, str):
			strVal = val
		else:
			strVal = str(val)
		if typ in (str, str) or ((typ is list) and isinstance(val, str)):
			# Escape any single quotes, and then enclose
			# the value in single quotes
			strVal = "u'" + self.escapeQt(strVal) + "'"
		try:
			exec("obj.%s = %s" % (prop, strVal) )
		except Exception as e:
			raise PropertyUpdateException(ustr(e))
		self.PropForm.updatePropGrid()
		# This is necessary to force a redraw when some props change.
		self.select(obj)
		try:
			obj.setWidth()
		except AttributeError:
			pass
		self.layout()
Ejemplo n.º 13
0
    def getStringValue(self, value):
        """
		Given a value of any data type, return a string rendition.

		Used internally by _setValue and flushValue, but also exposed to subclasses
		in case they need specialized behavior. The value returned from this
		function will be what is displayed in the UI textbox.
		"""
        if isinstance(value, basestring):
            # keep it unicode instead of converting to str
            strVal = value
        elif isinstance(value, datetime.datetime):
            strVal = dabo.lib.dates.getStringFromDateTime(value)
        elif isinstance(value, datetime.date):
            strVal = dabo.lib.dates.getStringFromDate(value)
        elif isinstance(value, datetime.time):
            # Use the ISO 8601 time string format
            strVal = value.isoformat()
        elif value is None:
            strVal = self.NoneDisplay
        else:
            # convert all other data types to string:
            strVal = ustr(value)  # (floats look like 25.55)
            #strVal = repr(value) # (floats look like 25.55000000000001)
        return strVal
Ejemplo n.º 14
0
	def showSquare(self, square):
		i = self._boardDict[square]
		o = i["obj"]
		o.State = "UnMarked"
		if i["mine"]:
			if self._firstHit:
				# Don't blow them up on their first click.
				self._makeBoardDict()
				self._resetBoard()
				self.showSquare(square)
				return
			o.FontBold = True
			o.FontItalic = True
			self.showAllSquares()
			self._GameInProgress = False
#			dabo.ui.stop("You lose!")
			self.Form.StatusText = "KaBoom!"
		else:
			a = i["adjacent"]
			if a == 0:
				# recursively clear all adjacent 0 squares
				self.clearZeros(o.square)
			else:
				o.Caption = ustr(a)
				o.Enabled = False
		o.unbindEvent(dabo.dEvents.Hit)
		self._firstHit = False
Ejemplo n.º 15
0
def logPoint(msg="", levels=None):
	if levels is None:
		# Default to 6, which works in most cases
		levels = 6
	stack = inspect.stack()
	# get rid of logPoint's part of the stack:
	stack = stack[1:]
	stack.reverse()
	output = StringIO()
	if msg:
		output.write(ustr(msg) + "\n")

	stackSection = stack[-1*levels:]
	for stackLine in stackSection:
		frame, filename, line, funcname, lines, unknown = stackLine
		if filename.endswith("/unittest.py"):
			# unittest.py code is a boring part of the traceback
			continue
		if filename.startswith("./"):
			filename = filename[2:]
		output.write("%s:%s in %s:\n" % (filename, line, funcname))
		if lines:
			output.write("	%s\n" % "".join(lines)[:-1])
	s = output.getvalue()
	# I actually logged the result, but you could also print it:
	return s
Ejemplo n.º 16
0
 def formatDateTime(self, val):
     """We need to wrap the value in quotes."""
     #### TODO: Make sure that the format for DateTime
     ####    values is returned correctly
     sqt = "'"  # single quote
     val = ustr(val)
     return "%s%s%s" % (sqt, val, sqt)
Ejemplo n.º 17
0
 def onProfileChoice(self, evt=None):
     choice = self.ddProfile.Value
     dbdefs = self.dbDefaults[choice]
     embedded = dbdefs["DbType"] in self.embeddedDbTypes
     if embedded:
         showFields = self.embeddedFields
     else:
         showFields = self.serverFields
     for fld in self.fieldNames:
         ctl = getattr(self, "ctl%s" % fld)
         if fld in showFields:
             val = dbdefs[fld]
             try:
                 ctl.Value = val
             except ValueError, e:
                 if "string must be present in the choices" in ustr(
                         e).lower():
                     # Not sure why the saved profile dbType is empty. No time to
                     # find out why now, but at least the AW won't crash anymore.
                     pass
                 else:
                     raise
             ctl.Visible = True
         else:
             # Not a field used for this db type
             ctl.Value = None
             ctl.Visible = False
Ejemplo n.º 18
0
	def _setWindowState(self, value):
		if self._constructed():
			lowvalue = ustr(value).lower().strip()
			vis = self.Visible
			if lowvalue == "normal":
				if self.IsFullScreen():
					self.ShowFullScreen(False)
				elif self.IsMaximized():
					self.Maximize(False)
				elif self.IsIconized():
					self.Iconize(False)
				else:
					# window already normal, but just in case:
					self.Maximize(False)
			elif lowvalue == "minimized":
				self.Iconize()
			elif lowvalue == "maximized":
				self.Maximize()
			elif lowvalue == "fullscreen":
				self.ShowFullScreen(True)
			else:
				self.unlockDisplay()
				raise ValueError("The only possible values are "
								"'Normal', 'Minimized', 'Maximized', and 'FullScreen'")
		else:
			self._properties["WindowState"] = value
Ejemplo n.º 19
0
    def getConnection(self, connectInfo, **kwargs):
        # kinterbasdb will barf with unicode strings for user nad password:
        host = ustr(connectInfo.Host)
        port = connectInfo.Port
        if port:
            host = "%s/%s" % (host, port)
        user = str(connectInfo.User)
        password = str(connectInfo.revealPW())
        database = ustr(connectInfo.Database)

        self._connection = self.dbapi.connect(host=host,
                                              user=user,
                                              password=password,
                                              database=database,
                                              **kwargs)
        return self._connection
Ejemplo n.º 20
0
Archivo: dForm.py Proyecto: xfxf/dabo
    def save(self, dataSource=None):
        """Ask the bizobj to commit its changes to the backend."""
        self.dataSourceParameter = dataSource
        bizobj = self.getBizobj(dataSource)
        if bizobj is None:
            # Running in preview or some other non-live mode
            return
        self.activeControlValid()

        err = self.beforeSave()
        if err:
            self.notifyUser(err)
            return False

        try:
            if self.SaveAllRows:
                bizobj.saveAll(saveTheChildren=self.SaveChildren)
            else:
                bizobj.save(saveTheChildren=self.SaveChildren)

            self.setStatusText(
                _("Changes to %s saved.") %
                (self.SaveAllRows and "all records" or "current record", ))

        except dException.ConnectionLostException, e:
            msg = self._connectionLostMsg(ustr(e))
            self.notifyUser(msg,
                            title=_("Data Connection Lost"),
                            severe=True,
                            exception=e)
            sys.exit()
Ejemplo n.º 21
0
	def _setWindowState(self, value):
		if self._constructed():
			lowvalue = ustr(value).lower().strip()
			vis = self.Visible
			if lowvalue == "normal":
				if self.IsFullScreen():
					self.ShowFullScreen(False)
				elif self.IsMaximized():
					self.Maximize(False)
				elif self.IsIconized():
					self.Iconize(False)
				else:
					# window already normal, but just in case:
					self.Maximize(False)
			elif lowvalue == "minimized":
				self.Iconize()
			elif lowvalue == "maximized":
				self.Maximize()
			elif lowvalue == "fullscreen":
				self.ShowFullScreen(True)
			else:
				self.unlockDisplay()
				raise ValueError("The only possible values are "
								"'Normal', 'Minimized', 'Maximized', and 'FullScreen'")
		else:
			self._properties["WindowState"] = value
Ejemplo n.º 22
0
    def __init__(self, exc_info):
        import copy

        excType, excValue = exc_info[:2]
        # traceback list entries: (filename, line number, function name, text)
        self.traceback = traceback.extract_tb(exc_info[2])

        # --Based on traceback.py::format_exception_only()--
        if type(excType) == types.ClassType:
            self.exception_type = excType.__name__
        else:
            self.exception_type = excType

        # If it's a syntax error, extra information needs
        # to be added to the traceback
        if excType is SyntaxError:
            try:
                msg, (filename, lineno, self.offset, line) = excValue
            except StandardError:
                pass
            else:
                if not filename:
                    filename = "<string>"
                if line is not None:
                    line = line.strip()
                self.traceback.append((filename, lineno, "", line))
                excValue = msg
        try:
            self.exception_details = ustr(excValue)
        except StandardError:
            self.exception_details = "<unprintable %s object>" & type(
                excValue).__name__

        del exc_info
Ejemplo n.º 23
0
	def _setSzRowSpan(self, val):
		if val == self._getSzRowSpan():
			return
		try:
			self.ControllingSizer.setItemProp(self, "RowSpan", val)
		except dui.GridSizerSpanException as e:
			raise PropertyUpdateException(ustr(e))
Ejemplo n.º 24
0
 def showSquare(self, square):
     i = self._boardDict[square]
     o = i["obj"]
     o.State = "UnMarked"
     if i["mine"]:
         if self._firstHit:
             # Don't blow them up on their first click.
             self._makeBoardDict()
             self._resetBoard()
             self.showSquare(square)
             return
         o.FontBold = True
         o.FontItalic = True
         self.showAllSquares()
         self._GameInProgress = False
         #			dabo.ui.stop("You lose!")
         self.Form.StatusText = "KaBoom!"
     else:
         a = i["adjacent"]
         if a == 0:
             # recursively clear all adjacent 0 squares
             self.clearZeros(o.square)
         else:
             o.Caption = ustr(a)
             o.Enabled = False
     o.unbindEvent(dabo.dEvents.Hit)
     self._firstHit = False
Ejemplo n.º 25
0
    def makePageFrame(self, parent, pageData, properties=None):
        """
		:param parent: dabo object that is the parent of the controls, normally a panel or form
		:param tuple pageData: a tuple of dictionaries, see below
		:param dict properties: optional dictionary of properties for the control
		:rtype: dabo.ui.dPageFrame

		pageData tuple:
			========== ================
			pageData   object that is the page.  Normally a dPage or Panel
			caption	   optional if defined image, string that is the tab label
			image      optional, dabo image that is the tab label
			========== ================

		"""
        pageFrame = dabo.ui.dPageFrame(parent, properties=properties)

        for page in pageData:
            if page.get("image"):
                page["imgKey"] = ustr(pageFrame.PageCount)
                pageFrame.addImage(page["image"], imgKey=page["imgKey"])
            elif not page.get("caption"):
                caption = "Page%i" % (pageFrame.PageCount, )

            pageFrame.appendPage(pgCls=page.get("page"),
                                 caption=page.get("caption"),
                                 imgKey=page.get("imgKey"))

        return pageFrame
Ejemplo n.º 26
0
def logPoint(msg="", levels=None):
    if levels is None:
        # Default to 6, which works in most cases
        levels = 6
    stack = inspect.stack()
    # get rid of logPoint's part of the stack:
    stack = stack[1:]
    stack.reverse()
    output = StringIO()
    if msg:
        output.write(ustr(msg) + "\n")

    stackSection = stack[-1 * levels:]
    for stackLine in stackSection:
        frame, filename, line, funcname, lines, unknown = stackLine
        if filename.endswith("/unittest.py"):
            # unittest.py code is a boring part of the traceback
            continue
        if filename.startswith("./"):
            filename = filename[2:]
        output.write("%s:%s in %s:\n" % (filename, line, funcname))
        if lines:
            output.write("	%s\n" % "".join(lines)[:-1])
    s = output.getvalue()
    # I actually logged the result, but you could also print it:
    return s
Ejemplo n.º 27
0
	def formatForQuery(self, val, fieldType=None):
		if isinstance(val, (datetime.date, datetime.datetime)):
			# Some databases have specific rules for formatting date values.
			return self.formatDateTime(val)
		elif isinstance(val, (int, long, float)):
			return ustr(val)
		elif isinstance(val, decimal.Decimal):
			return ustr(val)
		elif isinstance(val, dNoEscQuoteStr):
			return val
		elif fieldType == "L":
			return val
		elif val is None:
			return self.formatNone()
		else:
			return self.escQuote(val)
Ejemplo n.º 28
0
Archivo: dFont.py Proyecto: CarlFK/dabo
	def _getDescription(self):
		ret = self.Face + " " + ustr(self.Size)
		if self.Bold:
			ret += " B"
		if self.Italic:
			ret += " I"
		return ret
Ejemplo n.º 29
0
	def __init__(self, exc_info):
		import copy

		excType, excValue = exc_info[:2]
		# traceback list entries: (filename, line number, function name, text)
		self.traceback = traceback.extract_tb(exc_info[2])

		# --Based on traceback.py::format_exception_only()--
		if type(excType) == types.ClassType:
			self.exception_type = excType.__name__
		else:
			self.exception_type = excType

		# If it's a syntax error, extra information needs
		# to be added to the traceback
		if excType is SyntaxError:
			try:
				msg, (filename, lineno, self.offset, line) = excValue
			except StandardError:
				pass
			else:
				if not filename:
					filename = "<string>"
				if line is not None:
					line = line.strip()
				self.traceback.append( (filename, lineno, "", line) )
				excValue = msg
		try:
			self.exception_details = ustr(excValue)
		except StandardError:
			self.exception_details = "<unprintable %s object>" & type(excValue).__name__

		del exc_info
Ejemplo n.º 30
0
	def makePageFrame(self, parent, pageData, properties=None):
		"""
		:param parent: dabo object that is the parent of the controls, normally a panel or form
		:param tuple pageData: a tuple of dictionaries, see below
		:param dict properties: optional dictionary of properties for the control
		:rtype: dabo.ui.dPageFrame

		pageData tuple:
			========== ================
			pageData   object that is the page.  Normally a dPage or Panel
			caption	   optional if defined image, string that is the tab label
			image      optional, dabo image that is the tab label
			========== ================

		"""
		pageFrame = dabo.ui.dPageFrame(parent, properties=properties)

		for page in pageData:
			if page.get("image"):
				page["imgKey"] = ustr(pageFrame.PageCount)
				pageFrame.addImage(page["image"], imgKey=page["imgKey"])
			elif not page.get("caption"):
				caption = "Page%i" % (pageFrame.PageCount,)

			pageFrame.appendPage(pgCls=page.get("page"), caption=page.get("caption"), imgKey=page.get("imgKey"))

		return pageFrame
Ejemplo n.º 31
0
	def getStringValue(self, value):
		"""
		Given a value of any data type, return a string rendition.

		Used internally by _setValue and flushValue, but also exposed to subclasses
		in case they need specialized behavior. The value returned from this
		function will be what is displayed in the UI textbox.
		"""
		if isinstance(value, basestring):
			# keep it unicode instead of converting to str
			strVal = value
		elif isinstance(value, datetime.datetime):
			strVal = dabo.lib.dates.getStringFromDateTime(value)
		elif isinstance(value, datetime.date):
			strVal = dabo.lib.dates.getStringFromDate(value)
		elif isinstance(value, datetime.time):
			# Use the ISO 8601 time string format
			strVal = value.isoformat()
		elif value is None:
			strVal = self.NoneDisplay
		else:
			# convert all other data types to string:
			strVal = ustr(value)   # (floats look like 25.55)
			#strVal = repr(value) # (floats look like 25.55000000000001)
		return strVal
Ejemplo n.º 32
0
    def _setBorderStyle(self, style):
        self._delWindowStyleFlag(wx.NO_BORDER)
        self._delWindowStyleFlag(wx.SIMPLE_BORDER)
        self._delWindowStyleFlag(wx.SUNKEN_BORDER)
        self._delWindowStyleFlag(wx.RAISED_BORDER)
        self._delWindowStyleFlag(wx.DOUBLE_BORDER)
        self._delWindowStyleFlag(wx.STATIC_BORDER)

        style = ustr(style)

        if style == 'None':
            self._addWindowStyleFlag(wx.NO_BORDER)
        elif style == 'Simple':
            self._addWindowStyleFlag(wx.SIMPLE_BORDER)
        elif style == 'Sunken':
            self._addWindowStyleFlag(wx.SUNKEN_BORDER)
        elif style == 'Raised':
            self._addWindowStyleFlag(wx.RAISED_BORDER)
        elif style == 'Double':
            self._addWindowStyleFlag(wx.DOUBLE_BORDER)
        elif style == 'Static':
            self._addWindowStyleFlag(wx.STATIC_BORDER)
        elif style == 'Default':
            pass
        else:
            raise ValueError("The only possible values are 'None', "
                             "'Simple', 'Sunken', and 'Raised.'")
Ejemplo n.º 33
0
	def save(self, dataSource=None):
		"""Ask the bizobj to commit its changes to the backend."""
		self.dataSourceParameter = dataSource
		bizobj = self.getBizobj(dataSource)
		if bizobj is None:
			# Running in preview or some other non-live mode
			return
		self.activeControlValid()

		err = self.beforeSave()
		if err:
			self.notifyUser(err)
			return False

		try:
			if self.SaveAllRows:
				bizobj.saveAll(saveTheChildren=self.SaveChildren)
			else:
				bizobj.save(saveTheChildren=self.SaveChildren)

			self.setStatusText(_("Changes to %s saved.") % (
					self.SaveAllRows and "all records" or "current record",))

		except dException.ConnectionLostException, e:
			msg = self._connectionLostMsg(ustr(e))
			self.notifyUser(msg, title=_("Data Connection Lost"), severe=True, exception=e)
			sys.exit()
Ejemplo n.º 34
0
 def _setTabStyle(self, val):
     self._delWindowStyleFlag(fnb.FNB_VC8)
     self._delWindowStyleFlag(fnb.FNB_VC71)
     self._delWindowStyleFlag(fnb.FNB_FANCY_TABS)
     self._delWindowStyleFlag(fnb.FNB_FF2)
     lowval = ustr(val).lower()
     flags = {
         "default": "",
         "vc8": fnb.FNB_VC8,
         "vc71": fnb.FNB_VC71,
         "fancy": fnb.FNB_FANCY_TABS,
         "firefox": fnb.FNB_FF2
     }
     cleanStyles = {
         "default": "Default",
         "vc8": "VC8",
         "vc71": "VC71",
         "fancy": "Fancy",
         "firefox": "Firefox"
     }
     try:
         flagToSet = flags[lowval]
         self._tabStyle = cleanStyles[lowval]
     except KeyError:
         raise ValueError(
             _("The only possible values are 'Default' and 'VC8', 'VC71', 'Fancy', or 'Firefox'"
               ))
     if flagToSet:
         self._addWindowStyleFlag(flagToSet)
Ejemplo n.º 35
0
	def onSetTabAreaColor(self, evt):
		curr = self.pgf.TabAreaColor
		newcolor = self.getColorName(curr)
		if newcolor:
			self.pgf.TabAreaColor = newcolor
			self.update()
			self.Form.logit("TabAreaColor changed to '%s'" % ustr(newcolor))
Ejemplo n.º 36
0
	def formatDateTime(self, val):
		"""We need to wrap the value in quotes."""
		#### TODO: Make sure that the format for DateTime
		####    values is returned correctly
		sqt = "'"		# single quote
		val = ustr(val)
		return "%s%s%s" % (sqt, val, sqt)
Ejemplo n.º 37
0
	def onSetInactiveTabTextColor(self, evt):
		curr = self.pgf.InactiveTabTextColor
		newcolor = self.getColorName(curr)
		if newcolor:
			self.pgf.InactiveTabTextColor = newcolor
			self.update()
			self.Form.logit("InactiveTabTextColor changed to '%s'" % ustr(newcolor))
Ejemplo n.º 38
0
 def onSetTabAreaColor(self, evt):
     curr = self.pgf.TabAreaColor
     newcolor = self.getColorName(curr)
     if newcolor:
         self.pgf.TabAreaColor = newcolor
         self.update()
         self.Form.logit("TabAreaColor changed to '%s'" % ustr(newcolor))
Ejemplo n.º 39
0
	def _setBorderStyle(self, style):
		self._delWindowStyleFlag(wx.NO_BORDER)
		self._delWindowStyleFlag(wx.SIMPLE_BORDER)
		self._delWindowStyleFlag(wx.SUNKEN_BORDER)
		self._delWindowStyleFlag(wx.RAISED_BORDER)
		self._delWindowStyleFlag(wx.DOUBLE_BORDER)
		self._delWindowStyleFlag(wx.STATIC_BORDER)

		style = ustr(style)

		if style == 'None':
			self._addWindowStyleFlag(wx.NO_BORDER)
		elif style == 'Simple':
			self._addWindowStyleFlag(wx.SIMPLE_BORDER)
		elif style == 'Sunken':
			self._addWindowStyleFlag(wx.SUNKEN_BORDER)
		elif style == 'Raised':
			self._addWindowStyleFlag(wx.RAISED_BORDER)
		elif style == 'Double':
			self._addWindowStyleFlag(wx.DOUBLE_BORDER)
		elif style == 'Static':
			self._addWindowStyleFlag(wx.STATIC_BORDER)
		elif style == 'Default':
			pass
		else:
			raise ValueError("The only possible values are 'None', "
							"'Simple', 'Sunken', and 'Raised.'")
Ejemplo n.º 40
0
	def onProfileChoice(self, evt=None):
		choice = self.ddProfile.Value
		dbdefs = self.dbDefaults[choice]
		embedded = dbdefs["DbType"] in self.embeddedDbTypes
		if embedded:
			showFields = self.embeddedFields
		else:
			showFields = self.serverFields
		for fld in self.fieldNames:
			ctl = getattr(self, "ctl%s" % fld)
			if fld in showFields:
				val = dbdefs[fld]
				try:
					ctl.Value = val
				except ValueError, e:
					if "string must be present in the choices" in ustr(e).lower():
						# Not sure why the saved profile dbType is empty. No time to
						# find out why now, but at least the AW won't crash anymore.
						pass
					else:
						raise
				ctl.Visible = True
			else:
				# Not a field used for this db type
				ctl.Value = None
				ctl.Visible = False
Ejemplo n.º 41
0
 def formatForQuery(self, val, fieldType=None):
     if isinstance(val, (datetime.date, datetime.datetime)):
         # Some databases have specific rules for formatting date values.
         return self.formatDateTime(val)
     elif isinstance(val, (int, long, float)):
         return ustr(val)
     elif isinstance(val, decimal.Decimal):
         return ustr(val)
     elif isinstance(val, dNoEscQuoteStr):
         return val
     elif fieldType == "L":
         return val
     elif val is None:
         return self.formatNone()
     else:
         return self.escQuote(val)
Ejemplo n.º 42
0
	def _setToolTipText(self, value):
		t = self.GetToolTip()
		if t:
			t.SetTip(value)
		else:
			if value:
				t = wx.ToolTip(ustr(value))
				self.SetToolTip(t)
Ejemplo n.º 43
0
 def onSetInactiveTabTextColor(self, evt):
     curr = self.pgf.InactiveTabTextColor
     newcolor = self.getColorName(curr)
     if newcolor:
         self.pgf.InactiveTabTextColor = newcolor
         self.update()
         self.Form.logit("InactiveTabTextColor changed to '%s'" %
                         ustr(newcolor))
Ejemplo n.º 44
0
 def _setToolTipText(self, value):
     t = self.GetToolTip()
     if t:
         t.SetTip(value)
     else:
         if value:
             t = wx.ToolTip(ustr(value))
             self.SetToolTip(t)
Ejemplo n.º 45
0
	def commitTransaction(self, cursor):
		"""Commit a SQL transaction."""
		opError = self.dbapi.OperationalError
		try:
			cursor.execute("COMMIT", errorClass=opError)
			dabo.dbActivityLog.info("SQL: commit")
			return True
		except opError as e:
			# There is no transaction active in this case, so ignore the error.
			pass
		except Exception as e:
			try:
				errMsg = ustr(e).decode(self.Encoding)
			except UnicodeError:
				errMsg = ustr(e)
			dabo.dbActivityLog.info("SQL: commit failed: %s" % errMsg)
			raise dException.DBQueryException(errMsg)
Ejemplo n.º 46
0
def getDateTimeFromString(strVal, formats=None):
	"""Given a string in a defined format, return a datetime object or None."""
	global _dtregex

	dtFormat = dabo.dateTimeFormat
	ret = None

	if formats is None:
		formats = ["ISO8601"]

	if dtFormat is not None:
		formats.append(dtFormat)

	for format in formats:
		regex = _dtregex.get(format, None)
		if regex is None:
			regex = _getDateTimeRegex(format)
			if regex is None:
				continue
			_dtregex[format] = regex
		m = regex.match(strVal)
		if m is not None:
			groups = m.groupdict()
			for skip_group in ["ms", "second", "minute", "hour"]:
				if (skip_group not in groups) or not groups[skip_group]:
					# group not in the expression: default to 0
					groups[skip_group] = 0
			if "year" not in groups:
				curYear = datetime.date.today().year
				if "shortyear" in groups:
					groups["year"] = int("%s%s" % (ustr(curYear)[:2],
							groups["shortyear"]))
				else:
					groups["year"] = curYear

			try:
				return datetime.datetime(int(groups["year"]),
					int(groups["month"]),
					int(groups["day"]),
					int(groups["hour"]),
					int(groups["minute"]),
					int(groups["second"]),
					int(groups["ms"]))
			except ValueError:
				raise
				# Could be that the day was out of range for the particular month
				# (Sept. only has 30 days but the regex will allow 31, etc.)
				pass
		if ret is not None:
			break
	if ret is None:
		if dtFormat is None:
			# Fall back to the current locale setting in user's os account:
			try:
				ret = datetime.datetime(*time.strptime(strVal, "%x %X")[:7])
			except ValueError:  ## ValueError from time.strptime()
				pass
	return ret
Ejemplo n.º 47
0
Archivo: dates.py Proyecto: xfxf/dabo
def getDateTimeFromString(strVal, formats=None):
    """Given a string in a defined format, return a datetime object or None."""
    global _dtregex

    dtFormat = dabo.dateTimeFormat
    ret = None

    if formats is None:
        formats = ["ISO8601"]

    if dtFormat is not None:
        formats.append(dtFormat)

    for format in formats:
        regex = _dtregex.get(format, None)
        if regex is None:
            regex = _getDateTimeRegex(format)
            if regex is None:
                continue
            _dtregex[format] = regex
        m = regex.match(strVal)
        if m is not None:
            groups = m.groupdict()
            for skip_group in ["ms", "second", "minute", "hour"]:
                if (skip_group not in groups) or not groups[skip_group]:
                    # group not in the expression: default to 0
                    groups[skip_group] = 0
            if "year" not in groups:
                curYear = datetime.date.today().year
                if "shortyear" in groups:
                    groups["year"] = int(
                        "%s%s" % (ustr(curYear)[:2], groups["shortyear"]))
                else:
                    groups["year"] = curYear

            try:
                return datetime.datetime(int(groups["year"]),
                                         int(groups["month"]),
                                         int(groups["day"]),
                                         int(groups["hour"]),
                                         int(groups["minute"]),
                                         int(groups["second"]),
                                         int(groups["ms"]))
            except ValueError:
                raise
                # Could be that the day was out of range for the particular month
                # (Sept. only has 30 days but the regex will allow 31, etc.)
                pass
        if ret is not None:
            break
    if ret is None:
        if dtFormat is None:
            # Fall back to the current locale setting in user's os account:
            try:
                ret = datetime.datetime(*time.strptime(strVal, "%x %X")[:7])
            except ValueError:  ## ValueError from time.strptime()
                pass
    return ret
Ejemplo n.º 48
0
	def SetValue(self, val):
		val = self._getWxValue(val)
		try:
			super(dDatePicker, self).SetValue(val)
		except ValueError as e:
			nm = self.Name
			ue = ustr(e)
			dabo.log.error(_(u"Object '%(nm)s' has the following error: %(ue)s")
					% locals())
Ejemplo n.º 49
0
Archivo: dForm.py Proyecto: CarlFK/dabo
	def delete(self, dataSource=None, message=None, prompt=True):
		"""Ask the bizobj to delete the current record."""
		self.dataSourceParameter = dataSource
		bizobj = self.getBizobj(dataSource)
		if bizobj is None:
			# Running in preview or some other non-live mode
			return

		ds = bizobj.DataSource
		biz_caption = bizobj.Caption
		if not biz_caption:
			biz_caption = ds

		self.activeControlValid()

		if not bizobj.RowCount > 0:
			# Nothing to delete!
			self.setStatusText(_("Nothing to delete!"))
			return

		err = self.beforeDelete()
		if err:
			self.notifyUser(err)
			return
		if message is None:
			message = _("This will delete the current record from %s, and cannot "
					"be canceled.\n\n Are you sure you want to do this?") % biz_caption
		if not prompt or dabo.ui.areYouSure(message, defaultNo=True, cancelButton=False):
			try:
				bizobj.delete()
				self.setStatusText(_("Record Deleted."))
				# Notify listeners that the row number changed:
				self.raiseEvent(dEvents.RowNumChanged)
			except dException.ConnectionLostException as e:
				msg = self._connectionLostMsg(ustr(e))
				self.notifyUser(msg, title=_("Data Connection Lost"), severe=True, exception=e)
				sys.exit()
			except dException.dException as e:
				msg = ustr(e)
				dabo.log.error(_("Delete failed with response: %s") % msg)
				self.notifyUser(msg, title=_("Deletion Not Allowed"), severe=True, exception=e)
			self.update()
			self.afterDelete()
			self.refresh()
Ejemplo n.º 50
0
Archivo: dForm.py Proyecto: xfxf/dabo
    def requery(self, dataSource=None):
        """Ask the bizobj to requery."""
        self.dataSourceParameter = dataSource
        ret = False
        bizobj = self.getBizobj(dataSource)
        if bizobj is None:
            # Running in preview or some other non-live mode
            return
        oldRowNumber = bizobj.RowNumber
        self.activeControlValid()

        err = self.beforeRequery()
        if err:
            self.notifyUser(err)
            return
        if not self.confirmChanges(bizobjs=bizobj):
            # A False from confirmChanges means "don't proceed"
            return

        ## A user-initiated requery should expire the cache on child bizobjs too:
        bizobj.expireCache()

        try:
            self.StatusText = _("Please wait... requerying dataset...")
            #			busy = dabo.ui.busyInfo(_("Please wait... requerying dataset..."))
            self.stopWatch.Start()
            #			response = dProgressDialog.displayAfterWait(self, 2, bizobj.requery)
            response = bizobj.requery()
            self.stopWatch.Pause()
            elapsed = round(self.stopWatch.Time() / 1000.0, 3)
            #			del busy
            self.update()

            newRowNumber = bizobj.RowNumber
            if newRowNumber != oldRowNumber:
                # Notify listeners that the row number changed:
                self.raiseEvent(dEvents.RowNumChanged,
                                newRowNumber=newRowNumber,
                                oldRowNumber=oldRowNumber,
                                bizobj=bizobj)

            # We made it through without errors
            ret = True
            rc = bizobj.RowCount
            plcnt = bizobj.RowCount == 1 and " " or "s "
            plelap = elapsed == 1 and "." or "s."
            self.StatusText = (_(
                "%(rc)s record%(plcnt)sselected in %(elapsed)s second%(plelap)s"
            ) % locals())

        except dException.MissingPKException, e:
            self.notifyUser(ustr(e),
                            title=_("Requery Failed"),
                            severe=True,
                            exception=e)
            self.StatusText = ""
Ejemplo n.º 51
0
 def SetValue(self, val):
     val = self._getWxValue(val)
     try:
         super(dDatePicker, self).SetValue(val)
     except ValueError as e:
         nm = self.Name
         ue = ustr(e)
         dabo.log.error(
             _(u"Object '%(nm)s' has the following error: %(ue)s") %
             locals())
Ejemplo n.º 52
0
    def insertTraceback(self, lst, traceback):
        #Add the traceback data
        for tbNum in range(len(traceback)):
            data = traceback[tbNum]
            lst.append(
                (os.path.basename(data[0]), ustr(data[1]), ustr(data[2]),
                 ustr(data[3])))

            # Check whether this entry is from the demo module
            pth = os.path.split(data[0])[0]
            codeDirs = (DemoModules.getOrigDir(), DemoModules.getModDir())
            if pth in codeDirs:
                lst.setItemData(tbNum, int(
                    data[1]))  # Store line number for easy access
                # Give it a blue colour
                lst.setItemForeColor(tbNum, "blue")
            else:
                lst.setItemData(tbNum,
                                -1)  # Editor can't jump into this one's code
Ejemplo n.º 53
0
Archivo: dMenu.py Proyecto: xfxf/dabo
	def _getItemID(self,typ):
		typ = ustr(typ).lower()
		ret = wx.ID_DEFAULT
		if typ == "exit":
			ret = wx.ID_EXIT
		elif typ == "about":
			ret = wx.ID_ABOUT
		elif typ in ("pref", "prefs"):
			ret = wx.ID_PREFERENCES
		return ret
Ejemplo n.º 54
0
		def _setTabPosition(self, val):
			lowval = ustr(val).lower()[0]
			self._delWindowStyleFlag(self._tabposBottom)

			if lowval == "t":
				pass
			elif lowval == "b":
				self._addWindowStyleFlag(self._tabposBottom)
			else:
				raise ValueError(_("The only possible values are 'Top' and 'Bottom'"))
Ejemplo n.º 55
0
    def _redefine(self):
        """Combine the Caption and HotKey into the format needed by wxPython."""
        cap = self.Caption
        hk = self.HotKey
        if not cap:
            return
        if hk:
            cap = "%s\t%s" % (cap, hk)
        curr = self.GetItemLabel()
        ## pkm: On Windows at least, setting the Icon needs to happen before setting the caption.
        self.SetBitmap(self.Icon)

        if ustr(cap) != ustr(curr):
            ## Win32 seems to need to clear the caption first, or funkiness
            ## can arise. And win32 in wx2.8 needs for the caption to never be
            ## an empty string, or you'll get an invalid stock id assertion.
            self.SetItemLabel(" ")
            if cap == "":
                cap = " "
            self.SetItemLabel(cap)
Ejemplo n.º 56
0
 def updateSelection(self, style=None):
     if style is None:
         style = self.getCurrentStyle()
     cff, cfs, cfb, cfi, cfu, bc, fc = style
     self.tbFontFace.Value = cff
     self.tbFontSize.Value = ustr(cfs)
     self.tbbBold.Value = cfb
     self.tbbItalic.Value = cfi
     self.tbbUnderline.Value = cfu
     self.tbBackColor.BackColor = bc
     self.tbForeColor.BackColor = fc
Ejemplo n.º 57
0
 def bubbleClick(self, bubble):
     ret = 0
     if bubble.Selected:
         ret = self.popBubbles()
         self.unselectBubbles()
         self.Message = _("You scored %s points!" % ret)
     else:
         self.unselectBubbles()
         self.selectBubbles(bubble)
         self.Message = _("Bubble Points: ") + ustr(self.BubbleScore)
     return ret
Ejemplo n.º 58
0
    def _getClassName(self, cls):
        """Takes a string representation of the form:
			<class 'dabo.ui.uiwx.dTextBox.dTextBox'>
		and returns just the actual class name (i.e., in this
		case, 'dTextBox').
		"""
        ret = ustr(cls)
        if ret.startswith("<class 'dabo."):
            # Just include the class name
            ret = ret.split("'")[1].split(".")[-1]
        return ret
Ejemplo n.º 59
0
        def _setTabPosition(self, val):
            lowval = ustr(val).lower()[0]
            self._delWindowStyleFlag(self._tabposBottom)

            if lowval == "t":
                pass
            elif lowval == "b":
                self._addWindowStyleFlag(self._tabposBottom)
            else:
                raise ValueError(
                    _("The only possible values are 'Top' and 'Bottom'"))