root/tags/dabo-0.1.1/dApp.py

Revision 291, 10.4 kB (checked in by paul, 5 years ago)

Add a place for messages to be added to the login form, and set up
dSecurityManager to pass on informative messages during the login
process.

Add logged-in user name to the caption of the main form. Display
the application name in the caption of the login form.

Move the ordering of app instantiation steps around somewhat so that
the login form displays before the main form. Now, you only get to
see the main form after a successful login.

Base dDialog on dFormMixin, which lets it harness some useful form
properties.

  • Property svn:eol-style set to native
Line 
1 """
2     dApp.py : The application object for Dabo.
3
4     This object gets instantiated from the client app's main.py,
5     and lives through the life of the application.
6
7         -- set up an empty data connections object which holds
8         -- connectInfo objects connected to pretty names. Entries
9         -- can be added programatically, but upon initialiazation
10         -- it will look for a file called 'dbConnectionDefs.py' which
11         -- contains connection definitions.
12
13         -- Set up a DB Connection manager, that is basically a dictionary
14         -- of dConnection objects. This allows connections to be shared
15         -- application-wide.
16
17         -- decide which ui to use (wx) and gets that ball rolling
18
19         -- make a system menu bar, based on a combination
20         -- of dabo defaults and user resource files.
21
22         -- ditto for toolbar(s)
23
24         -- look for a mainFrame ui resource file in an expected
25         -- place, otherwise uses default dabo mainFrame, and
26         -- instantiate that.
27
28         -- maintain a forms collection and provide interfaces for
29         -- opening dForms, closing them, and iterating through them.
30
31         -- start the main app event loop.
32
33         -- clean up and exit gracefully
34 """
35 import sys, os, warnings
36 import ui
37 from biz import *
38 from db import *
39 import dabo.common, dSecurityManager
40 from dLocalize import _
41
42 class Collection(list):
43     """
44     Collection : Base class for the various collection
45                     classes used in the app object.
46     """
47
48     def __init__(self):
49         list.__init__(self)
50
51     def add(self, objRef):
52         """
53         Collection.add(objRef)
54             Add the object reference to the collection.
55         """
56         self.append(objRef)
57
58     def remove(self, objRef):
59         """
60         Collection.remove(objRef)
61             Delete the object reference from the collection.
62         """
63         index = self.index(objRef)
64         if index >= 0:
65             del self[index]
66
67
68 class dApp(dabo.common.DoDefaultMixin, dabo.common.PropertyHelperMixin):
69     """ dabo.dApp
70
71         The containing object for the entire application.
72         Various UI's will have app objects also, which
73         dabo.App is a wrapper for.
74     """
75     def __init__(self):
76         dabo.dAppRef = self
77         dApp.doDefault()
78         self._initProperties()
79
80        
81     def setup(self):
82         """ Set up the app - call this before start()."""
83
84         # dabo is going to want to import various things from the homeDir
85         sys.path.append(self.homeDir)
86
87         if not self.getAppInfo("appName"):
88             self.setAppInfo("appName", "Dabo")
89         if not self.getAppInfo("appVersion"):
90             self.setAppInfo("appVersion", "0.1")
91         if not self.getAppInfo("vendorName"):
92             self.setAppInfo("vendorName", "Dabo")
93
94         self._initUI()
95         self._initDB()
96
97         self.uiApp = self.uiModule.uiApp()
98
99         self.actionList.setAction("FileExit", self.uiApp.onFileExit)
100         self.actionList.setAction("HelpAbout", self.uiApp.onHelpAbout)
101         self.actionList.setAction("EditPreferences", self.uiApp.onEditPreferences)
102         self.actionList.setAction("EditCut", self.uiApp.onEditCut)
103         self.actionList.setAction("EditCopy", self.uiApp.onEditCopy)
104         self.actionList.setAction("EditPaste", self.uiApp.onEditPaste)
105         self.actionList.setAction("EditFind", self.uiApp.onEditFind)
106
107         self.uiApp.setup(self)
108         self.mainFrame = self.uiApp.mainFrame
109
110
111     def start(self):
112         """
113         Start the application event loop, which involves
114             wrapping the application object for the ui library
115             being used.
116         """
117         if (not self.SecurityManager or not self.SecurityManager.RequireAppLogin
118             or self.SecurityManager.login()):
119            
120             mf = self.mainFrame
121             mf.setStatusText("Welcome to %s" % self.getAppInfo("appName"))
122            
123             userName = self.getUserCaption()
124             if userName:
125                 userName = " (%s)" % userName
126             else:
127                 userName = ""
128                
129             mf.Caption = "%s Version %s %s" % (self.getAppInfo("appName"),
130                                             self.getAppInfo("appVersion"),
131                                             userName)
132        
133             self.uiApp.start(self)
134         self.finish()
135
136
137     def finish(self):
138         """
139         The main event loop has exited and the application
140             is about to finish.
141         """
142         print _("Application finished.")
143         pass
144
145
146     def getAppInfo(self, item):
147         """ dApp.getAppInfo(self, item) -> value
148
149             Look up the item, and return the value.
150         """
151         try:
152             retVal = self._appInfo[item]
153         except KeyError:
154             retVal = None
155         return retVal
156
157
158     def setAppInfo(self, item, value):
159         """ dApp.getAppInfo(self, item, value) -> None
160
161             Set item to value in the appinfo table.
162         """
163         self._appInfo[item] = value
164
165
166     def getUserSetting(self, item, user="*", system="*"):
167         """ Return the value of the user settings table that
168             corresponds to the item, user, and system id
169             passed. Based on the ctype field in the table,
170             convert the return value into the appropriate
171             type first.
172
173             Types:    I: Int
174                     N: Float
175                     C: String
176                     M: String
177                     D: Date, saved as a string 3-tuple
178                         of integers '(year,month,day)'
179                     T: DateTime, saved as a string
180                         9-tuple of integers '(year,month,
181                         day,hour,minute,second,?,?,?)'
182
183         """
184         import ConfigParser
185
186         configFileName = '%s/.userSettings.ini' % self.homeDir
187
188         cp = ConfigParser.ConfigParser()
189         cp.read(configFileName)
190
191         try:
192             valueType = cp.get("UserSettingsValueTypes", item)
193         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
194             valueType = "C"
195
196         try:
197             if valueType == "I":
198                 value = cp.getint("UserSettings", item)
199             elif valueType == "N":
200                 value = cp.getfloat("UserSettings", item)
201             elif valueType == "L":
202                 value = cp.getboolean("UserSettings", item)
203             else:
204                 value = cp.get("UserSettings", item)
205         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
206             value = None
207
208         return value
209
210
211     def setUserSetting(self, item, valueType, value, user="*", system="*"):
212         """ Set the value of the user settings table that corresponds to the
213             item, user, and systemid passed. If it doesn't exist in the table,
214             add it. See self.getUserSetting() for the type codes.
215         """
216         # For now, save this info in a plain ini file. Eventually, I'd like
217         # to see this get saved in a persistent dabosettings db table.
218         import ConfigParser
219
220         configFileName = '%s/.userSettings.ini' % self.homeDir
221
222         cp = ConfigParser.ConfigParser()
223         cp.read(configFileName)
224
225         # convert value to string type for saving to db:
226         value = str(value)
227
228         if not cp.has_section("UserSettings"):
229             cp.add_section("UserSettings")
230         cp.set("UserSettings", item, value)
231
232         if not cp.has_section("UserSettingsValueTypes"):
233             cp.add_section("UserSettingsValueTypes")
234         cp.set("UserSettingsValueTypes", item, valueType)
235
236         configFile = open(configFileName, 'w')
237         cp.write(configFile)
238         configFile.close()
239        
240        
241     def getUserCaption(self):
242         """ Return the full name of the currently logged-on user.
243         """
244         if self.SecurityManager:
245             return self.SecurityManager.UserCaption
246         else:
247             return None
248            
249
250     def _initProperties(self):
251         """ Initialize the public properties of the app object. """
252
253         # it is useful to know from where we came
254         self.homeDir = sys.path[0]
255
256         self.uiType   = None    # ('wx', 'qt', 'curses', 'http', etc.)
257         self.uiModule = None
258
259         # Initialize UI collections
260         self.uiForms = Collection()
261         self.uiMenus = Collection()
262         self.uiToolBars = Collection()
263         self.uiResources = {}
264
265         self.actionList = ui.dActionList()
266
267         # Initialize DB collections
268         self.dbConnectionDefs = {}
269
270         self._appInfo = {}
271
272     def _initDB(self):
273         """ Set the available connection definitions for use by the app. """
274
275         dbConnectionDefs = None
276         try:
277             globals_ = {}
278             execfile("%s/dbConnectionDefs.py" % (self.homeDir,), globals_)
279             dbConnectionDefs = globals_["dbConnectionDefs"]
280         except:
281             dbConnectionDefs = None
282
283         if dbConnectionDefs and type(dbConnectionDefs) == type(dict()):
284             # For each connection definition, add an entry to
285             # self.dbConnectionDefs that contains a key on the
286             # name, and a value of a dConnectInfo object.
287             for entry in dbConnectionDefs:
288                 try:             dbType   = dbConnectionDefs[entry]['dbType']
289                 except KeyError: dbType   = None
290                 try:             host     = dbConnectionDefs[entry]['host']
291                 except KeyError: host     = None
292                 try:             user     = dbConnectionDefs[entry]['user']
293                 except KeyError: user     = None
294                 try:             password = dbConnectionDefs[entry]['password']
295                 except KeyError: password = None
296                 try:             dbName   = dbConnectionDefs[entry]['dbName']
297                 except KeyError: dbName   = None
298                 try:             port     = dbConnectionDefs[entry]['port']
299                 except KeyError: port     = None
300
301                 self.dbConnectionDefs[entry] = dConnectInfo(backendName=dbType,
302                                                             host=host,
303                                                             user=user,
304                                                             password=password,
305                                                             dbName=dbName,
306                                                             port=port)
307
308             print _("%s database connection definition(s) loaded.") % (
309                                                 len(self.dbConnectionDefs))
310
311         else:
312             print _("No database connection definitions loaded (dbConnectionDefs.py)")
313
314
315     def _initUI(self):
316         """ Set the user-interface library for the application. """
317
318         if self.uiType == None:
319             # Future: read a config file in the homeDir
320             # Present: set UI to wx
321             uiType = "wx"
322
323             # Now, get the appropriate ui module into self.uiModule
324             uiModule = ui.getUI(uiType)
325             if uiModule != None:
326                 self.uiType = uiType
327                 self.uiModule = uiModule
328         else:
329             # Custom app code already set this: don't touch
330             pass
331
332         print _("User interface set to %s using module %s") % (self.uiType, self.uiModule)
333
334
335     def _getAutoNegotiateUniqueNames(self):
336         try:
337             return self._autoNegotiateUniqueNames
338         except AttributeError:
339             return True
340    
341     def _setAutoNegotiateUniqueNames(self, value):
342         self._autoNegotiateUniqueNames = bool(value)
343        
344    
345     def _getSecurityManager(self):
346         try:
347             return self._securityManager
348         except AttributeError:
349             return None
350            
351     def _setSecurityManager(self, value):
352         if isinstance(value, dSecurityManager.dSecurityManager):
353             if self.SecurityManager:
354                 warnings.warn(Warning, _('SecurityManager previously set'))
355             self._securityManager = value
356         else:
357             raise TypeError, _('SecurityManager must descend from dSecurityManager.')
358            
359            
360     AutoNegotiateUniqueNames = property(_getAutoNegotiateUniqueNames,_setAutoNegotiateUniqueNames,
361                         None, _('Specifies whether setting an object\'s name to a non-unique '
362                         'value results in a unique integer being appended, or whether '
363                         'a NameError is raised. Default is True: negotiate the name.'))
364
365     SecurityManager = property(_getSecurityManager, _setSecurityManager,
366                         None, _('Specifies the Security Manager, if any. You '
367                         'must subclass dSecurityManager, overriding the appropriate hooks '
368                         'and properties, and then set dApp.SecurityManager to an instance '
369                         'of your subclass. There is no security manager by default - you '
370                         'explicitly set this to use Dabo security.'))
371    
Note: See TracBrowser for help on using the browser.