commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

r6657 - in trunk: gnue-common/src/datasources/drivers/interbase/interbas


From: johannes
Subject: r6657 - in trunk: gnue-common/src/datasources/drivers/interbase/interbase gnue-common/src/datasources/drivers/mysql/mysql gnue-common/src/datasources/drivers/oracle/Base gnue-common/src/datasources/drivers/postgresql/Base gnue-common/src/datasources/drivers/sqlite/sqlite gnue-forms/samples/zipcode gnue-forms/src/uidrivers/wx
Date: Tue, 9 Nov 2004 02:10:01 -0600 (CST)

Author: johannes
Date: 2004-11-09 02:10:00 -0600 (Tue, 09 Nov 2004)
New Revision: 6657

Modified:
   trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
   trunk/gnue-common/src/datasources/drivers/mysql/mysql/Connection.py
   trunk/gnue-common/src/datasources/drivers/oracle/Base/Connection.py
   trunk/gnue-common/src/datasources/drivers/postgresql/Base/Connection.py
   trunk/gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py
   trunk/gnue-forms/samples/zipcode/zipcode.gsd
   trunk/gnue-forms/src/uidrivers/wx/UILoginHandler.py
Log:
Login-fields are always unicode.


Modified: 
trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py 
2004-11-09 08:02:58 UTC (rev 6656)
+++ trunk/gnue-common/src/datasources/drivers/interbase/interbase/Connection.py 
2004-11-09 08:10:00 UTC (rev 6657)
@@ -43,8 +43,9 @@
 
 from string import upper, lower, rstrip
 import sys
+import types
 from gnue.common.datasources import GDataObjects, GConditions, GConnections
-from gnue.common.apps import errors
+from gnue.common.apps import errors, i18n
 from gnue.common.datasources.drivers import DBSIG2
 from DataObject import *
 from gnue.common.datasources.drivers.interbase.Schema.Discovery.Introspection 
import Introspection
@@ -100,11 +101,19 @@
                  % {'new': ib_encoding, 'old': self._encoding})
 
     try:
+      username = connectData ['_username']
+      password = connectData ['_password']
+
+      if isinstance (username, types.UnicodeType):
+        username = username.encode (i18n.getencoding ())
+      if isinstance (password, types.UnicodeType):
+        password = password.encode (i18n.getencoding ())
+
       self.native = SIG2api.connect ( \
-                            user     = str (connectData ['_username']), \
-                            password = str (connectData ['_password']), \
-                            charset  = ib_encoding,                     \
-                            database = connectData ['dbname'],          \
+                            user     = username,
+                            password = password,
+                            charset  = ib_encoding,
+                            database = connectData ['dbname'],
                             host     = connectData ['host'])
 
       # automatically start a new transaction

Modified: trunk/gnue-common/src/datasources/drivers/mysql/mysql/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/mysql/mysql/Connection.py 
2004-11-09 08:02:58 UTC (rev 6656)
+++ trunk/gnue-common/src/datasources/drivers/mysql/mysql/Connection.py 
2004-11-09 08:10:00 UTC (rev 6657)
@@ -37,8 +37,9 @@
 
 import string
 import sys
-from gnue.common.datasources import GDataObjects, GConditions, GConnections
-from gnue.common.apps import GDebug
+import types
+from gnue.common.datasources import Exceptions, GConditions, GConnections
+from gnue.common.apps import i18n, errors
 
 try:
   import MySQLdb
@@ -69,20 +70,27 @@
   }
 
   def connect(self, connectData={}):
-    GDebug.printMesg(1,"Mysql database driver initializing")
+    gDebug (1,"Mysql database driver initializing")
 
     # 1. just allow string type username/password 2. None -> ''
-    user   = str(connectData['_username'] or '')
-    passwd = str(connectData['_password'] or '')
+    user   = connectData ['_username'] or ''
+    passwd = connectData ['_password'] or ''
 
+    if isinstance (user, types.UnicodeType):
+      user = user.encode (i18n.getencoding ())
+    if isinstance (passwd, types.UnicodeType):
+      passwd = passwd.encode (i18n.getencoding ())
+
     try:
-      self.native = MySQLdb.connect(user=user,
-                   passwd=passwd,
-                   host=connectData['host'],
-                   db=connectData['dbname'])
+      self.native = MySQLdb.connect(user   = user,
+                                    passwd = passwd,
+                                    host   = connectData ['host'],
+                                    db     = connectData ['dbname'])
 
     except self._DatabaseError, value:
-      raise GDataObjects.LoginError, value
+      raise Exceptions.LoginError, \
+          u_("The MySQL driver returned the following error:\n%s") \
+          % errors.getException () [2]
 
     self._beginTransaction()
 

Modified: trunk/gnue-common/src/datasources/drivers/oracle/Base/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/oracle/Base/Connection.py 
2004-11-09 08:02:58 UTC (rev 6656)
+++ trunk/gnue-common/src/datasources/drivers/oracle/Base/Connection.py 
2004-11-09 08:10:00 UTC (rev 6657)
@@ -36,9 +36,9 @@
 
 __all__ = ['Connection']
 
-import os, sys, string
-from gnue.common.datasources import GDataObjects, GConditions
-from gnue.common.apps import GDebug
+import os, sys, string, types
+from gnue.common.datasources import Exceptions, GConditions
+from gnue.common.apps import i18n, errors
 from gnue.common.datasources.drivers import DBSIG2
 from gnue.common.datasources.drivers.oracle.Schema.Discovery.Introspection 
import Introspection
 from DataObject import *
@@ -60,7 +60,7 @@
   #
   # Connect to database
   def connect(self, connectData={}):
-    GDebug.printMesg(1,"Oracle database driver initializing")
+    gDebug (1,"Oracle database driver initializing")
 
     if not hasattr(self,'_DatabaseError'):
       self._DatabaseError = self._driver.DatabaseError
@@ -68,13 +68,24 @@
     if connectData.has_key('oracle_home'):
       os.environ['ORACLE_HOME'] = connectData['oracle_home']
 
+    user   = connectData ['_username']
+    passwd = connectData ['_password']
+
+    if isinstance (user, types.UnicodeType):
+      user = user.encode (i18n.getencoding ())
+    if isinstance (passwd, types.UnicodeType):
+      passwd = passwd.encode (i18n.getencoding ())
+
+
     try:
       self.native = self._driver.connect("%s/address@hidden" \
-                % (connectData['_username'], \
-                   connectData['_password'], \
+                % (user, \
+                   passwd, \
                    connectData['service']))
     except self._DatabaseError, value:
-      raise GDataObjects.LoginError, value
+      raise Exceptions.LoginError, \
+          u_("The Oracle driver returned the following error:\n%s") \
+          % errors.getException () [2]
 
     if connectData.has_key('datetimeformat'):
       self._dateTimeFormat = "'%s'" % connectData['datetimeformat']
@@ -100,8 +111,8 @@
       rv = cursor.fetchone()
       cursor.close()
     except mesg:
-      GDebug.printMesg(1,"**** Unable to execute extension query")
-      GDebug.printMesg(1,"**** %s" % mesg)
+      gDebug (1,"**** Unable to execute extension query")
+      gDebug (1,"**** %s" % mesg)
       cursor.close()
       return None
 

Modified: 
trunk/gnue-common/src/datasources/drivers/postgresql/Base/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/postgresql/Base/Connection.py     
2004-11-09 08:02:58 UTC (rev 6656)
+++ trunk/gnue-common/src/datasources/drivers/postgresql/Base/Connection.py     
2004-11-09 08:10:00 UTC (rev 6657)
@@ -23,7 +23,9 @@
 
 __all__ = ['Connection']
 
-from gnue.common.apps import errors
+import types
+
+from gnue.common.apps import errors, i18n
 from gnue.common.datasources import Exceptions
 from gnue.common.datasources.drivers import DBSIG2
 from DataObject import *
@@ -74,6 +76,9 @@
                                          connectData ['_password'],
                                          port)
 
+      if isinstance (conStr, types.UnicodeType):
+        conStr = conStr.encode (i18n.getencoding ())
+
       self.native = self._driver.connect (conStr)
 
     except self._DatabaseError, value:

Modified: trunk/gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py       
2004-11-09 08:02:58 UTC (rev 6656)
+++ trunk/gnue-common/src/datasources/drivers/sqlite/sqlite/Connection.py       
2004-11-09 08:10:00 UTC (rev 6657)
@@ -37,7 +37,7 @@
 #### ATTRIBUTES, PLEASE UPDATE info.py ####
 ####                                   ####
 
-from gnue.common.apps import GDebug
+from gnue.common.apps import errors
 from gnue.common.datasources import Exceptions
 from gnue.common.datasources.drivers import DBSIG2
 
@@ -109,7 +109,7 @@
     @param connectData: dictionary with parameters used for the connection
     """
 
-    GDebug.printMesg (1, "SQLite database driver initializing <%s>")
+    gDebug (1, "SQLite database driver initializing <%s>")
 
     if not hasattr (self, '_DatabaseError'):
       try:
@@ -124,9 +124,10 @@
                                      autocommit = self.noTransactions)
 
     except self._DatabaseError, value:
-      GDebug.printMesg (1, "Exception %s" % value)
+      gDebug (1, "Exception %s" % value)
       raise Exceptions.LoginError, \
-           u_("The SQLite driver returned the following error:\n\t%s") % value
+           u_("The SQLite driver returned the following error:\n\t%s") \
+           % errors.getException () [2]
 
 
   # ---------------------------------------------------------------------------

Modified: trunk/gnue-forms/samples/zipcode/zipcode.gsd
===================================================================
--- trunk/gnue-forms/samples/zipcode/zipcode.gsd        2004-11-09 08:02:58 UTC 
(rev 6656)
+++ trunk/gnue-forms/samples/zipcode/zipcode.gsd        2004-11-09 08:10:00 UTC 
(rev 6657)
@@ -3,8 +3,8 @@
   <tables>
     <table name="state">
       <fields>
-        <field name="state"       type="string" length="2"/>
-        <field name="description" type="string" length="30" nullable="N"/>
+        <field name="state"       type="string" length="2" nullable="False"/>
+        <field name="description" type="string" length="30" nullable="False"/>
       </fields>
       <primarykey name="pk_state">
         <pkfield name="state"/>
@@ -14,9 +14,9 @@
 
     <table name="zipcode">
       <fields>
-        <field name="zip"       type="string" length="5"/>
-        <field name="city"      type="string" length="30" nullable="N"/>
-        <field name="state"     type="string" length="2" nullable="N"/>
+        <field name="zip"       type="string" length="5" nullable="False"/>
+        <field name="city"      type="string" length="30" nullable="False"/>
+        <field name="state"     type="string" length="2" nullable="False"/>
         <field name="longitude" type="number" length="5" precision="2"/>
         <field name="latitude"  type="number" length="5" precision="2"/>
       </fields>

Modified: trunk/gnue-forms/src/uidrivers/wx/UILoginHandler.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/wx/UILoginHandler.py 2004-11-09 08:02:58 UTC 
(rev 6656)
+++ trunk/gnue-forms/src/uidrivers/wx/UILoginHandler.py 2004-11-09 08:10:00 UTC 
(rev 6657)
@@ -33,8 +33,9 @@
 from wxPython.wx import *
 
 from gnue.common.datasources import GLoginHandler
-from gnue.common.apps import GConfig
+from gnue.common.apps import GConfig, i18n
 from GFwxApp import *
+from common import wxEncode, wxDecode
 
 # Shortcut
 images_dir = GConfig.getInstalledBase('forms_images','common_images') + '/'
@@ -62,149 +63,155 @@
     self.dlg = wxDialog(NULL, -1,'dummy')
     self.destroyLoginDialog()
     
-  def getLogin(self, loginData, errortext=None):#"Invalid username/password"):
-    if 1: # TODO: This is left here to prevent me from having to unindent this 
code
-          # TODO: Since the UI stuff is currently being gutted I'm not wasting 
the time
-          # TODO: to do the right thing
-      if len(loginData[1]):
-        loginMesg = _('Login required for\n"%s"') % (loginData[1])
-      else:
-        loginMesg = _('Login required for %s') % (loginData[0])
+  # ---------------------------------------------------------------------------
+  # Get input for all fields listed in loginData
+  # ---------------------------------------------------------------------------
 
-      self.dlg = wxDialog(NULL, -1, _("GNU Enterprise: Login to %s") % 
loginData[0])
-      self.dlg.SetAutoLayout(true)
+  def getLogin (self, loginData, errortext = None):
+    """
+    """
 
-      if os.path.isabs(gConfigForms('loginPNG')):
-        imageFile = gConfigForms('loginPNG')
-      else:
-        imageFile = images_dir+gConfigForms('loginPNG')
-      bmp = wxImage(imageFile, wxBITMAP_TYPE_PNG).ConvertToBitmap()
+    if len (loginData [1]):
+      loginMesg = wxEncode (u_('Login required for\n"%s"') % loginData [1])
+    else:
+      loginMesg = wxEncode (u_('Login required for %s') % loginData [0])
 
-      messageField = WrappedStaticText(self.dlg, -1, str(loginMesg), 300, 
style=wxALIGN_CENTER)
+    self.dlg = wxDialog (NULL, -1,
+        wxEncode (u_("GNU Enterprise: Login to %s") % loginData [0]))
+    self.dlg.SetAutoLayout (True)
 
-      self.textctrlList = []
-      labelList = []
+    if os.path.isabs (gConfigForms ('loginPNG')):
+      imageFile = gConfigForms ('loginPNG')
+    else:
+      imageFile = images_dir + gConfigForms ('loginPNG')
 
-      dlgWidth = max(bmp.GetWidth(), messageField.GetSize().GetWidth()+20)
+    bmp = wxImage (imageFile, wxBITMAP_TYPE_PNG).ConvertToBitmap ()
 
-      dlgHeight = bmp.GetHeight() + messageField.GetSize().GetHeight() + 80
+    messageField = WrappedStaticText (self.dlg, -1, loginMesg, 300,
+                                      style = wxALIGN_CENTER)
 
-      xSpacing = 0
-      ySpacing = 0
-      fieldLabelWidth = 0
+    self.textctrlList = []
+    labelList = []
 
-      for prompt in loginData[2]:
-        s = wxStaticText(self.dlg, -1, '%s:' % prompt[1])
-        labelList.append(s)
-        if prompt[2]:
-          t = wxTextCtrl(self.dlg, -1,"",wxPoint(1, 1), wxSize(150, 20),
-                         style=wxTE_PASSWORD|wxTE_PROCESS_ENTER)
-        else:
-          t = wxTextCtrl(self.dlg, -1,"",wxPoint(1, 1), wxSize(150, 20),
-                         style=wxTE_PROCESS_ENTER)
+    dlgWidth  = max (bmp.GetWidth (), messageField.GetSize ().GetWidth () + 20)
+    dlgHeight = bmp.GetHeight () + messageField.GetSize ().GetHeight () + 80
 
-        myID = len(self.textctrlList)
-        self.textctrlList.append(t)
-        EVT_CHAR(t, LoginFieldHandler(self, myID).loginFieldEventTrap)
+    xSpacing        = 0
+    ySpacing        = 0
+    fieldLabelWidth = 0
 
-        fieldLabelWidth = max(fieldLabelWidth,
-                  s.GetSize().GetWidth() + t.GetSize().GetWidth() + 10)
+    for prompt in loginData [2]:
+      s = wxStaticText (self.dlg, -1, wxEncode ('%s:' % prompt [1]))
+      
+      labelList.append (s)
+      if prompt[2]:
+        t = wxTextCtrl (self.dlg, -1, "", wxPoint (1, 1), wxSize (150, 20),
+                       style = wxTE_PASSWORD | wxTE_PROCESS_ENTER)
+      else:
+        t = wxTextCtrl (self.dlg, -1, "", wxPoint (1, 1), wxSize (150, 20),
+                       style = wxTE_PROCESS_ENTER)
 
-        dlgWidth = max(dlgWidth, \
-                       s.GetSize().GetWidth() + t.GetSize().GetWidth() + 20)
+      myID = len (self.textctrlList)
+      self.textctrlList.append (t)
+      EVT_CHAR (t, LoginFieldHandler (self, myID).loginFieldEventTrap)
 
-        xSpacing = max(xSpacing, s.GetSize().GetWidth())
-        ySpacing = max(ySpacing, s.GetSize().GetHeight())
-        ySpacing = max(ySpacing, t.GetSize().GetHeight())
+      fieldLabelWidth = max (fieldLabelWidth,
+                s.GetSize ().GetWidth () + t.GetSize ().GetWidth () + 10)
 
+      dlgWidth = max (dlgWidth, \
+                     s.GetSize ().GetWidth () + t.GetSize ().GetWidth () + 20)
 
-      loginId = wxNewId()
-      cancelId = wxNewId()
+      xSpacing = max (xSpacing, s.GetSize ().GetWidth ())
+      ySpacing = max (ySpacing, s.GetSize ().GetHeight ())
+      ySpacing = max (ySpacing, t.GetSize ().GetHeight ())
 
-      loginButton = wxButton(self.dlg,loginId,_('Login'))
-      cancelButton = wxButton(self.dlg,cancelId,_('Cancel'))
+    loginId  = wxNewId ()
+    cancelId = wxNewId ()
 
-      EVT_BUTTON(self.dlg, loginId, self.loginButtonEventTrap)
-      EVT_BUTTON(self.dlg, cancelId, self.loginCancelEventTrap)
-      dlgWidth = max(dlgWidth, loginButton.GetSize().GetWidth() +
-                            cancelButton.GetSize().GetWidth() + 6) + 20
+    loginButton  = wxButton (self.dlg, loginId, _('Login'))
+    cancelButton = wxButton (self.dlg, cancelId, _('Cancel'))
 
-      dlgHeight += max(loginButton.GetSize().GetHeight(),
-                       cancelButton.GetSize().GetHeight()) - 6
+    EVT_BUTTON (self.dlg, loginId,  self.loginButtonEventTrap)
+    EVT_BUTTON (self.dlg, cancelId, self.loginCancelEventTrap)
 
-      if errortext:
-        errorField = WrappedStaticText(self.dlg, -1, str(errortext), 300,
-                                       style=wxALIGN_CENTER)
-        errorField.SetForegroundColour(wxColour(223,0,0))
+    dlgWidth = max (dlgWidth, loginButton.GetSize ().GetWidth () +
+                    cancelButton.GetSize ().GetWidth () + 6) + 20
 
-        dlgWidth = max(dlgWidth, errorField.GetSize().width+10)
-        dlgHeight += errorField.GetSize().height + 6
+    dlgHeight += max (loginButton.GetSize ().GetHeight (),
+                      cancelButton.GetSize ().GetHeight ()) - 6
 
+    if errortext:
+      errorField = WrappedStaticText (self.dlg, -1, wxEncode (errortext),
+                                      300, style = wxALIGN_CENTER)
+      errorField.SetForegroundColour (wxColour (223, 0, 0))
 
-      firstY = bmp.GetHeight() + messageField.GetSize().GetHeight() + 50
-      lastY = firstY
-      xSpacing += 10   # Add whitespace between widgets
-      ySpacing += 6    # Add whitespace between widgets
-      xPos = dlgWidth/2 - fieldLabelWidth/2
+      dlgWidth = max (dlgWidth, errorField.GetSize ().width + 10)
+      dlgHeight += errorField.GetSize ().height + 6
 
 
-      # Move the fields and labels into position
-      for i in range(0, len(self.textctrlList)):
-        dlgHeight = dlgHeight + ySpacing
-        labelList[i].SetPosition(wxPoint(xPos, lastY))
-        self.textctrlList[i].SetPosition(wxPoint(xPos + xSpacing, lastY))
-        lastY = lastY + ySpacing
+    firstY = bmp.GetHeight () + messageField.GetSize ().GetHeight () + 50
+    lastY = firstY
+    xSpacing += 10     # Add whitespace between widgets
+    ySpacing += 6      # Add whitespace between widgets
+    xPos = dlgWidth / 2 - fieldLabelWidth / 2
 
-      if errortext:
-        errorField.SetPosition(
-          wxPoint(dlgWidth/2 - errorField.GetSize().width/2,
-                lastY+3))
+    # Move the fields and labels into position
+    for i in range (0, len (self.textctrlList)):
+      dlgHeight = dlgHeight + ySpacing
+      labelList [i].SetPosition (wxPoint (xPos, lastY))
+      self.textctrlList[i].SetPosition (wxPoint (xPos + xSpacing, lastY))
+      lastY = lastY + ySpacing
 
-      # Set the focus to the first text entry field
-      self.textctrlList[0].SetFocus()
+    if errortext:
+      errorField.SetPosition (
+        wxPoint (dlgWidth / 2 - errorField.GetSize ().width / 2, lastY + 3))
 
-      # Create and position the logo
-      wxStaticBitmap(self.dlg,-1, bmp,
-                     wxPoint((dlgWidth-bmp.GetWidth())/2, 12),
-                     wxSize(bmp.GetWidth(), bmp.GetHeight()))
+    # Set the focus to the first text entry field
+    self.textctrlList [0].SetFocus ()
 
-      # Move the various widgets into position
-      messageField.SetPosition(
-        wxPoint(dlgWidth/2 - messageField.GetSize().GetWidth()/2,
-                30 + bmp.GetHeight()))
+    # Create and position the logo
+    wxStaticBitmap (self.dlg, -1, bmp,
+                   wxPoint ( (dlgWidth - bmp.GetWidth ()) / 2, 12),
+                   wxSize (bmp.GetWidth (), bmp.GetHeight ()))
 
-      cancelButton.SetPosition(
-        wxPoint(dlgWidth - 10 - cancelButton.GetSize().GetWidth(),
-                dlgHeight - 10 - max(loginButton.GetSize().GetHeight(),
-                                            
cancelButton.GetSize().GetHeight())))
-      loginButton.SetPosition(
-        wxPoint(dlgWidth - 16 - cancelButton.GetSize().GetWidth() - \
-                loginButton.GetSize().GetWidth(),
-                dlgHeight - 10 - max(loginButton.GetSize().GetHeight(),
-                                            
cancelButton.GetSize().GetHeight())))
+    # Move the various widgets into position
+    messageField.SetPosition (
+      wxPoint (dlgWidth / 2 - messageField.GetSize ().GetWidth () / 2,
+              30 + bmp.GetHeight ()))
 
-      self.loginButton = loginButton
+    cancelButton.SetPosition (
+      wxPoint (dlgWidth - 10 - cancelButton.GetSize ().GetWidth (),
+              dlgHeight - 10 - max (loginButton.GetSize ().GetHeight (),
+                                    cancelButton.GetSize ().GetHeight ())))
+    loginButton.SetPosition (
+      wxPoint (dlgWidth - 16 - cancelButton.GetSize ().GetWidth () - \
+              loginButton.GetSize ().GetWidth (),
+              dlgHeight - 10 - max (loginButton.GetSize ().GetHeight (),
+                                    cancelButton.GetSize ().GetHeight ())))
 
-      self.dlg.SetSize(wxSize(dlgWidth, dlgHeight))
+    self.loginButton = loginButton
 
-      self.dlg.Refresh()
-      self.dlg.Fit()
-      self.dlg.Raise()
-      self.dlg.CenterOnScreen()
+    self.dlg.SetSize (wxSize (dlgWidth, dlgHeight))
 
+    self.dlg.Refresh ()
+    self.dlg.Fit ()
+    self.dlg.Raise ()
+    self.dlg.CenterOnScreen ()
+
     # If user cancels, this will be set to 0
     self._completed = 0
-    self.dlg.ShowModal()
+    self.dlg.ShowModal ()
 
     if not self._completed:
       raise GLoginHandler.UserCanceledLogin
 
     rv = {}
-    for i in range(0, len(loginData[2])):
-      rv[loginData[2][i][0]] = self.textctrlList[i].GetValue()
+    for i in range (0, len (loginData [2])):
+      rv [loginData [2] [i] [0]] = wxDecode (self.textctrlList [i].GetValue ())
 
     return rv
 
+
   #
   # Login is completed, for whatever reason
   #





reply via email to

[Prev in Thread] Current Thread [Next in Thread]