Merge lp:~raoul-snyman/openlp/docstrings into lp:openlp
- docstrings
- Merge into trunk
Proposed by
Raoul Snyman
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~raoul-snyman/openlp/docstrings |
Merge into: | lp:openlp |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~raoul-snyman/openlp/docstrings |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Bentley | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Raoul Snyman (raoul-snyman) wrote : | # |
- 488. By Raoul Snyman
-
Merging from docstrings branch.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'openlp/core/lib/plugin.py' | |||
2 | --- openlp/core/lib/plugin.py 2009-07-06 16:34:13 +0000 | |||
3 | +++ openlp/core/lib/plugin.py 2009-07-10 13:16:15 +0000 | |||
4 | @@ -31,42 +31,58 @@ | |||
5 | 31 | Base class for openlp plugins to inherit from. | 31 | Base class for openlp plugins to inherit from. |
6 | 32 | 32 | ||
7 | 33 | Basic attributes are: | 33 | Basic attributes are: |
9 | 34 | * name | 34 | |
10 | 35 | ``name`` | ||
11 | 35 | The name that should appear in the plugins list. | 36 | The name that should appear in the plugins list. |
13 | 36 | * version | 37 | |
14 | 38 | ``version`` | ||
15 | 37 | The version number of this iteration of the plugin. | 39 | The version number of this iteration of the plugin. |
17 | 38 | * icon | 40 | |
18 | 41 | ``icon`` | ||
19 | 39 | An instance of QIcon, which holds an icon for this plugin. | 42 | An instance of QIcon, which holds an icon for this plugin. |
21 | 40 | * config | 43 | |
22 | 44 | ``config`` | ||
23 | 41 | An instance of PluginConfig, which allows plugins to read and write to | 45 | An instance of PluginConfig, which allows plugins to read and write to |
24 | 42 | openlp.org's configuration. This is pre-instantiated. | 46 | openlp.org's configuration. This is pre-instantiated. |
26 | 43 | * log | 47 | |
27 | 48 | ``log`` | ||
28 | 44 | A log object used to log debugging messages. This is pre-instantiated. | 49 | A log object used to log debugging messages. This is pre-instantiated. |
29 | 45 | 50 | ||
30 | 46 | Hook functions: | 51 | Hook functions: |
32 | 47 | * check_pre_conditions() | 52 | |
33 | 53 | ``check_pre_conditions()`` | ||
34 | 48 | Provides the Plugin with a handle to check if it can be loaded. | 54 | Provides the Plugin with a handle to check if it can be loaded. |
36 | 49 | * get_media_manager_item() | 55 | |
37 | 56 | ``get_media_manager_item()`` | ||
38 | 50 | Returns an instance of MediaManagerItem to be used in the Media Manager. | 57 | Returns an instance of MediaManagerItem to be used in the Media Manager. |
40 | 51 | * add_import_menu_item(import_menu) | 58 | |
41 | 59 | ``add_import_menu_item(import_menu)`` | ||
42 | 52 | Add an item to the Import menu. | 60 | Add an item to the Import menu. |
44 | 53 | * add_export_menu_item(export_menu) | 61 | |
45 | 62 | ``add_export_menu_item(export_menu)`` | ||
46 | 54 | Add an item to the Export menu. | 63 | Add an item to the Export menu. |
48 | 55 | * get_settings_tab() | 64 | |
49 | 65 | ``get_settings_tab()`` | ||
50 | 56 | Returns an instance of SettingsTabItem to be used in the Settings dialog. | 66 | Returns an instance of SettingsTabItem to be used in the Settings dialog. |
52 | 57 | * add_to_menu(menubar) | 67 | |
53 | 68 | ``add_to_menu(menubar)`` | ||
54 | 58 | A method to add a menu item to anywhere in the menu, given the menu bar. | 69 | A method to add a menu item to anywhere in the menu, given the menu bar. |
56 | 59 | * handle_event(event) | 70 | |
57 | 71 | ``handle_event(event)`` | ||
58 | 60 | A method use to handle events, given an Event object. | 72 | A method use to handle events, given an Event object. |
60 | 61 | * about() | 73 | |
61 | 74 | ``about()`` | ||
62 | 62 | Used in the plugin manager, when a person clicks on the 'About' button. | 75 | Used in the plugin manager, when a person clicks on the 'About' button. |
64 | 63 | * save(data) | 76 | |
65 | 77 | ``save(data)`` | ||
66 | 64 | A method to convert the plugin's data to a string to be stored in the | 78 | A method to convert the plugin's data to a string to be stored in the |
67 | 65 | Service file. | 79 | Service file. |
69 | 66 | * load(string) | 80 | |
70 | 81 | ``load(string)`` | ||
71 | 67 | A method to convert the string from a Service file into the plugin's | 82 | A method to convert the string from a Service file into the plugin's |
72 | 68 | own data format. | 83 | own data format. |
74 | 69 | * render(theme, screen_number) | 84 | |
75 | 85 | ``render(theme, screen_number)`` | ||
76 | 70 | A method used to render something to the screen, given the current theme | 86 | A method used to render something to the screen, given the current theme |
77 | 71 | and screen number. | 87 | and screen number. |
78 | 72 | """ | 88 | """ |
79 | @@ -78,11 +94,20 @@ | |||
80 | 78 | """ | 94 | """ |
81 | 79 | This is the constructor for the plugin object. This provides an easy | 95 | This is the constructor for the plugin object. This provides an easy |
82 | 80 | way for descendent plugins to populate common data. This method *must* | 96 | way for descendent plugins to populate common data. This method *must* |
88 | 81 | be overridden, like so: | 97 | be overridden, like so:: |
89 | 82 | class MyPlugin(Plugin): | 98 | |
90 | 83 | def __init__(self): | 99 | class MyPlugin(Plugin): |
91 | 84 | Plugin.__init(self, 'MyPlugin', '0.1') | 100 | def __init__(self): |
92 | 85 | ... | 101 | Plugin.__init(self, u'MyPlugin', u'0.1') |
93 | 102 | |||
94 | 103 | ``name`` | ||
95 | 104 | Defaults to *None*. The name of the plugin. | ||
96 | 105 | |||
97 | 106 | ``version`` | ||
98 | 107 | Defaults to *None*. The version of the plugin. | ||
99 | 108 | |||
100 | 109 | ``plugin_helpers`` | ||
101 | 110 | Defaults to *None*. A list of helper objects. | ||
102 | 86 | """ | 111 | """ |
103 | 87 | if name is not None: | 112 | if name is not None: |
104 | 88 | self.name = name | 113 | self.name = name |
105 | @@ -107,50 +132,59 @@ | |||
106 | 107 | def check_pre_conditions(self): | 132 | def check_pre_conditions(self): |
107 | 108 | """ | 133 | """ |
108 | 109 | Provides the Plugin with a handle to check if it can be loaded. | 134 | Provides the Plugin with a handle to check if it can be loaded. |
109 | 135 | |||
110 | 110 | Returns True or False. | 136 | Returns True or False. |
111 | 111 | """ | 137 | """ |
112 | 112 | return True | 138 | return True |
113 | 113 | 139 | ||
114 | 114 | def get_media_manager_item(self): | 140 | def get_media_manager_item(self): |
115 | 115 | """ | 141 | """ |
118 | 116 | Construct a MediaManagerItem object with all the buttons and things you | 142 | Construct a MediaManagerItem object with all the buttons and things |
119 | 117 | need, and return it for integration into openlp.org. | 143 | you need, and return it for integration into openlp.org. |
120 | 118 | """ | 144 | """ |
121 | 119 | pass | 145 | pass |
122 | 120 | 146 | ||
123 | 121 | def add_import_menu_item(self, import_menu): | 147 | def add_import_menu_item(self, import_menu): |
124 | 122 | """ | 148 | """ |
125 | 123 | Create a menu item and add it to the "Import" menu. | 149 | Create a menu item and add it to the "Import" menu. |
126 | 150 | |||
127 | 151 | ``import_menu`` | ||
128 | 152 | The Import menu. | ||
129 | 124 | """ | 153 | """ |
130 | 125 | pass | 154 | pass |
131 | 126 | 155 | ||
132 | 127 | def add_export_menu_item(self, export_menu): | 156 | def add_export_menu_item(self, export_menu): |
133 | 128 | """ | 157 | """ |
134 | 129 | Create a menu item and add it to the "Export" menu. | 158 | Create a menu item and add it to the "Export" menu. |
135 | 159 | |||
136 | 160 | ``export_menu`` | ||
137 | 161 | The Export menu | ||
138 | 130 | """ | 162 | """ |
139 | 131 | pass | 163 | pass |
140 | 132 | 164 | ||
141 | 133 | def get_settings_tab(self): | 165 | def get_settings_tab(self): |
142 | 134 | """ | 166 | """ |
144 | 135 | Create a menu item and add it to the "Import" menu. | 167 | Create a tab for the settings window. |
145 | 136 | """ | 168 | """ |
146 | 137 | pass | 169 | pass |
147 | 138 | 170 | ||
148 | 139 | def add_to_menu(self, menubar): | 171 | def add_to_menu(self, menubar): |
149 | 140 | """ | 172 | """ |
150 | 141 | Add menu items to the menu, given the menubar. | 173 | Add menu items to the menu, given the menubar. |
151 | 174 | |||
152 | 175 | ``menubar`` | ||
153 | 176 | The application's menu bar. | ||
154 | 142 | """ | 177 | """ |
155 | 143 | pass | 178 | pass |
156 | 144 | 179 | ||
157 | 145 | def handle_event(self, event): | 180 | def handle_event(self, event): |
158 | 146 | """ | 181 | """ |
159 | 147 | Handle the event contained in the event object. | ||
160 | 148 | """ | ||
161 | 149 | def handle_event(self, event): | ||
162 | 150 | """ | ||
163 | 151 | Handle the event contained in the event object. If you want | 182 | Handle the event contained in the event object. If you want |
164 | 152 | to use this default behaviour, you must set self.dnd_id equal | 183 | to use this default behaviour, you must set self.dnd_id equal |
165 | 153 | to that sent by the dnd source - eg the MediaItem | 184 | to that sent by the dnd source - eg the MediaItem |
166 | 185 | |||
167 | 186 | ``event`` | ||
168 | 187 | An object describing the event. | ||
169 | 154 | """ | 188 | """ |
170 | 155 | # default behaviour - can be overridden if desired | 189 | # default behaviour - can be overridden if desired |
171 | 156 | log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload)) | 190 | log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload)) |
172 | @@ -175,6 +209,9 @@ | |||
173 | 175 | """ | 209 | """ |
174 | 176 | Service item data is passed to this function, which should return a | 210 | Service item data is passed to this function, which should return a |
175 | 177 | string which can be written to the service file. | 211 | string which can be written to the service file. |
176 | 212 | |||
177 | 213 | ``data`` | ||
178 | 214 | The data to be saved. | ||
179 | 178 | """ | 215 | """ |
180 | 179 | pass | 216 | pass |
181 | 180 | 217 | ||
182 | @@ -182,12 +219,21 @@ | |||
183 | 182 | """ | 219 | """ |
184 | 183 | A string from the service file is passed in. This function parses and | 220 | A string from the service file is passed in. This function parses and |
185 | 184 | sets up the internals of the plugin. | 221 | sets up the internals of the plugin. |
186 | 222 | |||
187 | 223 | ``string`` | ||
188 | 224 | The data to be loaded into the plugin. | ||
189 | 185 | """ | 225 | """ |
190 | 186 | pass | 226 | pass |
191 | 187 | 227 | ||
192 | 188 | def render(self, theme, screen=None): | 228 | def render(self, theme, screen=None): |
193 | 189 | """ | 229 | """ |
194 | 190 | Render the screenth screenful of data using theme settings in theme. | 230 | Render the screenth screenful of data using theme settings in theme. |
195 | 231 | |||
196 | 232 | ``theme`` | ||
197 | 233 | The theme to use when rendering. | ||
198 | 234 | |||
199 | 235 | ``screen`` | ||
200 | 236 | Defaults to *None*. The screen to render to. | ||
201 | 191 | """ | 237 | """ |
202 | 192 | pass | 238 | pass |
203 | 193 | 239 | ||
204 | 194 | 240 | ||
205 | === modified file 'openlp/core/lib/pluginconfig.py' | |||
206 | --- openlp/core/lib/pluginconfig.py 2009-07-08 05:12:16 +0000 | |||
207 | +++ openlp/core/lib/pluginconfig.py 2009-07-10 13:16:15 +0000 | |||
208 | @@ -29,28 +29,50 @@ | |||
209 | 29 | """ | 29 | """ |
210 | 30 | Initialise the plugin config object, setting the section name to the | 30 | Initialise the plugin config object, setting the section name to the |
211 | 31 | plugin name. | 31 | plugin name. |
212 | 32 | |||
213 | 33 | ``plugin_name`` | ||
214 | 34 | The name of the plugin to use as a section name. | ||
215 | 32 | """ | 35 | """ |
216 | 33 | self.section = plugin_name.lower() | 36 | self.section = plugin_name.lower() |
217 | 34 | 37 | ||
218 | 35 | def get_config(self, key, default=None): | 38 | def get_config(self, key, default=None): |
219 | 36 | """ | 39 | """ |
220 | 37 | Get a configuration value from the configuration registry. | 40 | Get a configuration value from the configuration registry. |
221 | 41 | |||
222 | 42 | ``key`` | ||
223 | 43 | The name of configuration to load. | ||
224 | 44 | |||
225 | 45 | ``default`` | ||
226 | 46 | Defaults to *None*. The default value to return if there is no | ||
227 | 47 | other value. | ||
228 | 38 | """ | 48 | """ |
229 | 39 | return ConfigHelper.get_config(self.section, key, default) | 49 | return ConfigHelper.get_config(self.section, key, default) |
230 | 40 | 50 | ||
231 | 41 | def delete_config(self, key): | 51 | def delete_config(self, key): |
232 | 42 | """ | 52 | """ |
233 | 43 | Delete a configuration value from the configuration registry. | 53 | Delete a configuration value from the configuration registry. |
234 | 54 | |||
235 | 55 | ``key`` | ||
236 | 56 | The name of the configuration to remove. | ||
237 | 44 | """ | 57 | """ |
238 | 45 | return ConfigHelper.delete_config(self.section, key) | 58 | return ConfigHelper.delete_config(self.section, key) |
239 | 46 | 59 | ||
240 | 47 | def set_config(self, key, value): | 60 | def set_config(self, key, value): |
241 | 48 | """ | 61 | """ |
242 | 49 | Set a configuration value in the configuration registry. | 62 | Set a configuration value in the configuration registry. |
243 | 63 | |||
244 | 64 | ``key`` | ||
245 | 65 | The name of the configuration to save. | ||
246 | 66 | |||
247 | 67 | ``value`` | ||
248 | 68 | The value of the configuration to save. | ||
249 | 50 | """ | 69 | """ |
250 | 51 | return ConfigHelper.set_config(self.section, key, value) | 70 | return ConfigHelper.set_config(self.section, key, value) |
251 | 52 | 71 | ||
252 | 53 | def get_data_path(self): | 72 | def get_data_path(self): |
253 | 73 | """ | ||
254 | 74 | Dynamically build the data file path for a plugin. | ||
255 | 75 | """ | ||
256 | 54 | #app_data = ConfigHelper.get_data_path() | 76 | #app_data = ConfigHelper.get_data_path() |
257 | 55 | app_data = ConfigHelper.get_data_path() | 77 | app_data = ConfigHelper.get_data_path() |
258 | 56 | safe_name = self.section.replace(u' ',u'-') | 78 | safe_name = self.section.replace(u' ',u'-') |
259 | @@ -61,9 +83,21 @@ | |||
260 | 61 | return path | 83 | return path |
261 | 62 | 84 | ||
262 | 63 | def set_data_path(self, path): | 85 | def set_data_path(self, path): |
263 | 86 | """ | ||
264 | 87 | Set the data file path. | ||
265 | 88 | |||
266 | 89 | ``path`` | ||
267 | 90 | The path to save. | ||
268 | 91 | """ | ||
269 | 64 | return self.set_config(u'data path', os.path.basename(path)) | 92 | return self.set_config(u'data path', os.path.basename(path)) |
270 | 65 | 93 | ||
271 | 66 | def get_files(self, suffix=None): | 94 | def get_files(self, suffix=None): |
272 | 95 | """ | ||
273 | 96 | Get a list of files from the data files path. | ||
274 | 97 | |||
275 | 98 | ``suffix`` | ||
276 | 99 | Defaults to *None*. The extension to search for. | ||
277 | 100 | """ | ||
278 | 67 | try: | 101 | try: |
279 | 68 | files = os.listdir(self.get_data_path()) | 102 | files = os.listdir(self.get_data_path()) |
280 | 69 | except: | 103 | except: |
281 | @@ -86,7 +120,10 @@ | |||
282 | 86 | 120 | ||
283 | 87 | def load_list(self, name): | 121 | def load_list(self, name): |
284 | 88 | """ | 122 | """ |
286 | 89 | Load a list from the config file | 123 | Load a list from the config file. |
287 | 124 | |||
288 | 125 | ``name`` | ||
289 | 126 | The name of the list. | ||
290 | 90 | """ | 127 | """ |
291 | 91 | list_count = self.get_config(u'%s count' % name) | 128 | list_count = self.get_config(u'%s count' % name) |
292 | 92 | if list_count is not None: | 129 | if list_count is not None: |
293 | @@ -102,7 +139,13 @@ | |||
294 | 102 | 139 | ||
295 | 103 | def set_list(self, name, list): | 140 | def set_list(self, name, list): |
296 | 104 | """ | 141 | """ |
298 | 105 | Save a list to the config file | 142 | Save a list to the config file. |
299 | 143 | |||
300 | 144 | ``name`` | ||
301 | 145 | The name of the list to save. | ||
302 | 146 | |||
303 | 147 | ``list`` | ||
304 | 148 | The list of values to save. | ||
305 | 106 | """ | 149 | """ |
306 | 107 | old_count = int(self.get_config(u'%s count' % name, int(0))) | 150 | old_count = int(self.get_config(u'%s count' % name, int(0))) |
307 | 108 | new_count = len(list) | 151 | new_count = len(list) |
308 | @@ -116,7 +159,10 @@ | |||
309 | 116 | 159 | ||
310 | 117 | def get_last_dir(self, num=None): | 160 | def get_last_dir(self, num=None): |
311 | 118 | """ | 161 | """ |
313 | 119 | Read the last directory used for plugin | 162 | Read the last directory used for plugin. |
314 | 163 | |||
315 | 164 | ``num`` | ||
316 | 165 | Defaults to *None*. A further qualifier. | ||
317 | 120 | """ | 166 | """ |
318 | 121 | if num is not None: | 167 | if num is not None: |
319 | 122 | name = u'last directory %d' % num | 168 | name = u'last directory %d' % num |
320 | @@ -129,7 +175,10 @@ | |||
321 | 129 | 175 | ||
322 | 130 | def set_last_dir(self, directory, num=None): | 176 | def set_last_dir(self, directory, num=None): |
323 | 131 | """ | 177 | """ |
325 | 132 | Save the last directory used for plugin | 178 | Save the last directory used for plugin. |
326 | 179 | |||
327 | 180 | ``num`` | ||
328 | 181 | Defaults to *None*. A further qualifier. | ||
329 | 133 | """ | 182 | """ |
330 | 134 | if num is not None: | 183 | if num is not None: |
331 | 135 | name = u'last directory %d' % num | 184 | name = u'last directory %d' % num |
332 | 136 | 185 | ||
333 | === modified file 'openlp/core/lib/pluginmanager.py' | |||
334 | --- openlp/core/lib/pluginmanager.py 2009-07-08 05:12:16 +0000 | |||
335 | +++ openlp/core/lib/pluginmanager.py 2009-07-10 13:16:15 +0000 | |||
336 | @@ -34,8 +34,11 @@ | |||
337 | 34 | 34 | ||
338 | 35 | def __init__(self, dir): | 35 | def __init__(self, dir): |
339 | 36 | """ | 36 | """ |
342 | 37 | The constructor for the plugin manager. | 37 | The constructor for the plugin manager. Passes the controllers on to |
343 | 38 | Passes the controllers on to the plugins for them to interact with via their ServiceItems | 38 | the plugins for them to interact with via their ServiceItems. |
344 | 39 | |||
345 | 40 | ``dir`` | ||
346 | 41 | The directory to search for plugins. | ||
347 | 39 | """ | 42 | """ |
348 | 40 | log.info(u'Plugin manager initing') | 43 | log.info(u'Plugin manager initing') |
349 | 41 | if not dir in sys.path: | 44 | if not dir in sys.path: |
350 | @@ -49,7 +52,16 @@ | |||
351 | 49 | 52 | ||
352 | 50 | def find_plugins(self, dir, plugin_helpers, eventmanager): | 53 | def find_plugins(self, dir, plugin_helpers, eventmanager): |
353 | 51 | """ | 54 | """ |
355 | 52 | Scan the directory dir for objects inheriting from openlp.plugin | 55 | Scan the directory dir for objects inheriting from ``openlp.plugin``. |
356 | 56 | |||
357 | 57 | ``dir`` | ||
358 | 58 | The directory to scan. | ||
359 | 59 | |||
360 | 60 | ``plugin_helpers`` | ||
361 | 61 | A list of helper objects to pass to the plugins. | ||
362 | 62 | |||
363 | 63 | ``eventmanager`` | ||
364 | 64 | The event manager to pass to the plugins. | ||
365 | 53 | """ | 65 | """ |
366 | 54 | self.plugin_helpers = plugin_helpers | 66 | self.plugin_helpers = plugin_helpers |
367 | 55 | startdepth = len(os.path.abspath(dir).split(os.sep)) | 67 | startdepth = len(os.path.abspath(dir).split(os.sep)) |
368 | @@ -104,8 +116,8 @@ | |||
369 | 104 | 116 | ||
370 | 105 | def hook_media_manager(self, mediatoolbox): | 117 | def hook_media_manager(self, mediatoolbox): |
371 | 106 | """ | 118 | """ |
374 | 107 | Loop through all the plugins. If a plugin has a valid media manager item, | 119 | Loop through all the plugins. If a plugin has a valid media manager |
375 | 108 | add it to the media manager. | 120 | item, add it to the media manager. |
376 | 109 | 121 | ||
377 | 110 | ``mediatoolbox`` | 122 | ``mediatoolbox`` |
378 | 111 | The Media Manager itself. | 123 | The Media Manager itself. |
379 | @@ -118,8 +130,11 @@ | |||
380 | 118 | 130 | ||
381 | 119 | def hook_settings_tabs(self, settingsform=None): | 131 | def hook_settings_tabs(self, settingsform=None): |
382 | 120 | """ | 132 | """ |
385 | 121 | Loop through all the plugins. If a plugin has a valid settings tab item, | 133 | Loop through all the plugins. If a plugin has a valid settings tab |
386 | 122 | add it to the settings tab. | 134 | item, add it to the settings tab. |
387 | 135 | |||
388 | 136 | ``settingsform`` | ||
389 | 137 | Defaults to *None*. The settings form to add tabs to. | ||
390 | 123 | """ | 138 | """ |
391 | 124 | for plugin in self.plugins: | 139 | for plugin in self.plugins: |
392 | 125 | settings_tab = plugin.get_settings_tab() | 140 | settings_tab = plugin.get_settings_tab() |
393 | @@ -131,24 +146,30 @@ | |||
394 | 131 | 146 | ||
395 | 132 | def hook_import_menu(self, import_menu): | 147 | def hook_import_menu(self, import_menu): |
396 | 133 | """ | 148 | """ |
399 | 134 | Loop through all the plugins and give them an opportunity to add an item | 149 | Loop through all the plugins and give them an opportunity to add an |
400 | 135 | to the import menu. | 150 | item to the import menu. |
401 | 151 | |||
402 | 152 | ``import_menu`` | ||
403 | 153 | The Import menu. | ||
404 | 136 | """ | 154 | """ |
405 | 137 | for plugin in self.plugins: | 155 | for plugin in self.plugins: |
406 | 138 | plugin.add_import_menu_item(import_menu) | 156 | plugin.add_import_menu_item(import_menu) |
407 | 139 | 157 | ||
408 | 140 | def hook_export_menu(self, export_menu): | 158 | def hook_export_menu(self, export_menu): |
409 | 141 | """ | 159 | """ |
412 | 142 | Loop through all the plugins and give them an opportunity to add an item | 160 | Loop through all the plugins and give them an opportunity to add an |
413 | 143 | to the export menu. | 161 | item to the export menu. |
414 | 162 | |||
415 | 163 | ``export_menu`` | ||
416 | 164 | The Export menu. | ||
417 | 144 | """ | 165 | """ |
418 | 145 | for plugin in self.plugins: | 166 | for plugin in self.plugins: |
419 | 146 | plugin.add_export_menu_item(export_menu) | 167 | plugin.add_export_menu_item(export_menu) |
420 | 147 | 168 | ||
421 | 148 | def initialise_plugins(self): | 169 | def initialise_plugins(self): |
422 | 149 | """ | 170 | """ |
425 | 150 | Loop through all the plugins and give them an opportunity to add an item | 171 | Loop through all the plugins and give them an opportunity to |
426 | 151 | to the export menu. | 172 | initialise themselves. |
427 | 152 | """ | 173 | """ |
428 | 153 | for plugin in self.plugins: | 174 | for plugin in self.plugins: |
429 | 154 | plugin.initialise() | 175 | plugin.initialise() |
430 | 155 | 176 | ||
431 | === modified file 'openlp/core/lib/renderer.py' | |||
432 | --- openlp/core/lib/renderer.py 2009-06-26 16:17:55 +0000 | |||
433 | +++ openlp/core/lib/renderer.py 2009-07-10 13:16:15 +0000 | |||
434 | @@ -18,12 +18,12 @@ | |||
435 | 18 | Place, Suite 330, Boston, MA 02111-1307 USA | 18 | Place, Suite 330, Boston, MA 02111-1307 USA |
436 | 19 | """ | 19 | """ |
437 | 20 | import logging | 20 | import logging |
439 | 21 | import os, os.path | 21 | import os |
440 | 22 | import sys | 22 | import sys |
441 | 23 | 23 | ||
442 | 24 | from PyQt4 import QtGui, QtCore | 24 | from PyQt4 import QtGui, QtCore |
443 | 25 | 25 | ||
445 | 26 | class Renderer: | 26 | class Renderer(object): |
446 | 27 | """ | 27 | """ |
447 | 28 | Genarates a pixmap image of a array of text. The Text is formatted to | 28 | Genarates a pixmap image of a array of text. The Text is formatted to |
448 | 29 | make sure it fits on the screen and if not extra frames a generated. | 29 | make sure it fits on the screen and if not extra frames a generated. |
449 | @@ -33,6 +33,9 @@ | |||
450 | 33 | log.info(u'Renderer Loaded') | 33 | log.info(u'Renderer Loaded') |
451 | 34 | 34 | ||
452 | 35 | def __init__(self): | 35 | def __init__(self): |
453 | 36 | """ | ||
454 | 37 | Initialise the renderer. | ||
455 | 38 | """ | ||
456 | 36 | self._rect = None | 39 | self._rect = None |
457 | 37 | self._debug = 0 | 40 | self._debug = 0 |
458 | 38 | self._right_margin = 64 # the amount of right indent | 41 | self._right_margin = 64 # the amount of right indent |
459 | @@ -47,11 +50,20 @@ | |||
460 | 47 | self._bg_frame_small = None | 50 | self._bg_frame_small = None |
461 | 48 | 51 | ||
462 | 49 | def set_debug(self, debug): | 52 | def set_debug(self, debug): |
463 | 53 | """ | ||
464 | 54 | Set the debug mode of the renderer. | ||
465 | 55 | |||
466 | 56 | ``debug`` | ||
467 | 57 | The debug mode. | ||
468 | 58 | """ | ||
469 | 50 | self._debug=debug | 59 | self._debug=debug |
470 | 51 | 60 | ||
471 | 52 | def set_theme(self, theme): | 61 | def set_theme(self, theme): |
472 | 53 | """ | 62 | """ |
474 | 54 | External API to pass in the theme to be used | 63 | Set the theme to be used. |
475 | 64 | |||
476 | 65 | ``theme`` | ||
477 | 66 | The theme to be used. | ||
478 | 55 | """ | 67 | """ |
479 | 56 | log.debug(u'set theme') | 68 | log.debug(u'set theme') |
480 | 57 | self._theme = theme | 69 | self._theme = theme |
481 | @@ -64,12 +76,21 @@ | |||
482 | 64 | self.set_bg_image(theme.background_filename) | 76 | self.set_bg_image(theme.background_filename) |
483 | 65 | 77 | ||
484 | 66 | def set_bg_image(self, filename): | 78 | def set_bg_image(self, filename): |
485 | 79 | """ | ||
486 | 80 | Set a background image. | ||
487 | 81 | |||
488 | 82 | ``filename`` | ||
489 | 83 | The name of the image file. | ||
490 | 84 | """ | ||
491 | 67 | log.debug(u'set bg image %s', filename) | 85 | log.debug(u'set bg image %s', filename) |
492 | 68 | self._bg_image_filename = unicode(filename) | 86 | self._bg_image_filename = unicode(filename) |
493 | 69 | if self._frame is not None: | 87 | if self._frame is not None: |
494 | 70 | self.scale_bg_image() | 88 | self.scale_bg_image() |
495 | 71 | 89 | ||
496 | 72 | def scale_bg_image(self): | 90 | def scale_bg_image(self): |
497 | 91 | """ | ||
498 | 92 | Scale the background image to fit the screen. | ||
499 | 93 | """ | ||
500 | 73 | assert self._frame | 94 | assert self._frame |
501 | 74 | preview = QtGui.QImage(self._bg_image_filename) | 95 | preview = QtGui.QImage(self._bg_image_filename) |
502 | 75 | width = self._frame.width() | 96 | width = self._frame.width() |
503 | @@ -89,7 +110,16 @@ | |||
504 | 89 | 110 | ||
505 | 90 | def set_frame_dest(self, frame_width, frame_height, preview=False): | 111 | def set_frame_dest(self, frame_width, frame_height, preview=False): |
506 | 91 | """ | 112 | """ |
508 | 92 | External API to pass the frame size to be painted | 113 | Set the size of the slide. |
509 | 114 | |||
510 | 115 | ``frame_width`` | ||
511 | 116 | The width of the slide. | ||
512 | 117 | |||
513 | 118 | ``frame_height`` | ||
514 | 119 | The height of the slide. | ||
515 | 120 | |||
516 | 121 | ``preview`` | ||
517 | 122 | Defaults to *False*. Whether or not to generate a preview. | ||
518 | 93 | """ | 123 | """ |
519 | 94 | if preview == True: | 124 | if preview == True: |
520 | 95 | self._bg_frame = None | 125 | self._bg_frame = None |
521 | @@ -103,7 +133,14 @@ | |||
522 | 103 | 133 | ||
523 | 104 | def format_slide(self, words, footer): | 134 | def format_slide(self, words, footer): |
524 | 105 | """ | 135 | """ |
526 | 106 | External API to sort out the text to pe placed on the frame | 136 | Figure out how much text can appear on a slide, using the current |
527 | 137 | theme settings. | ||
528 | 138 | |||
529 | 139 | ``words`` | ||
530 | 140 | The words to be fitted on the slide. | ||
531 | 141 | |||
532 | 142 | ``footer`` | ||
533 | 143 | The footer of the slide. | ||
534 | 107 | """ | 144 | """ |
535 | 108 | log.debug(u'format_slide - Start') | 145 | log.debug(u'format_slide - Start') |
536 | 109 | verses = [] | 146 | verses = [] |
537 | @@ -120,15 +157,28 @@ | |||
538 | 120 | 157 | ||
539 | 121 | def set_text_rectangle(self, rect_main, rect_footer): | 158 | def set_text_rectangle(self, rect_main, rect_footer): |
540 | 122 | """ | 159 | """ |
542 | 123 | Sets the rectangle within which text should be rendered | 160 | Sets the rectangle within which text should be rendered. |
543 | 161 | |||
544 | 162 | ``rect_main`` | ||
545 | 163 | The main text block. | ||
546 | 164 | |||
547 | 165 | ``rect_footer`` | ||
548 | 166 | The footer text block. | ||
549 | 124 | """ | 167 | """ |
550 | 125 | self._rect = rect_main | 168 | self._rect = rect_main |
551 | 126 | self._rect_footer = rect_footer | 169 | self._rect_footer = rect_footer |
552 | 127 | 170 | ||
553 | 128 | def generate_frame_from_lines(self, lines, footer_lines=None): | 171 | def generate_frame_from_lines(self, lines, footer_lines=None): |
554 | 129 | """ | 172 | """ |
557 | 130 | Render a set of lines according to the theme, return bounding box | 173 | Render a set of lines according to the theme, and return the block |
558 | 131 | """ | 174 | dimensions. |
559 | 175 | |||
560 | 176 | ``lines`` | ||
561 | 177 | The lines to be rendered. | ||
562 | 178 | |||
563 | 179 | ``footer_lines`` | ||
564 | 180 | Defaults to *None*. The footer to render. | ||
565 | 181 | """ | ||
566 | 132 | log.debug(u'generate_frame_from_lines - Start') | 182 | log.debug(u'generate_frame_from_lines - Start') |
567 | 133 | #print "Render Lines ", lines | 183 | #print "Render Lines ", lines |
568 | 134 | bbox = self._render_lines_unaligned(lines, False) | 184 | bbox = self._render_lines_unaligned(lines, False) |
569 | @@ -139,14 +189,15 @@ | |||
570 | 139 | x, y = self._correctAlignment(self._rect, bbox) | 189 | x, y = self._correctAlignment(self._rect, bbox) |
571 | 140 | bbox = self._render_lines_unaligned(lines, False, (x, y), True) | 190 | bbox = self._render_lines_unaligned(lines, False, (x, y), True) |
572 | 141 | if footer_lines is not None: | 191 | if footer_lines is not None: |
574 | 142 | bbox = self._render_lines_unaligned(footer_lines, True, (self._rect_footer.left(), self._rect_footer.top()), True ) | 192 | bbox = self._render_lines_unaligned(footer_lines, True, |
575 | 193 | (self._rect_footer.left(), self._rect_footer.top()), True) | ||
576 | 143 | log.debug(u'generate_frame_from_lines - Finish') | 194 | log.debug(u'generate_frame_from_lines - Finish') |
577 | 144 | return self._frame | 195 | return self._frame |
578 | 145 | 196 | ||
579 | 146 | def _generate_background_frame(self): | 197 | def _generate_background_frame(self): |
580 | 147 | """ | 198 | """ |
583 | 148 | Generate a background frame to the same size as the frame to be used | 199 | Generate a background frame to the same size as the frame to be used. |
584 | 149 | Results cached for performance reasons. | 200 | Results are cached for performance reasons. |
585 | 150 | """ | 201 | """ |
586 | 151 | assert(self._theme) | 202 | assert(self._theme) |
587 | 152 | self._bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), | 203 | self._bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), |
588 | @@ -196,11 +247,19 @@ | |||
589 | 196 | 247 | ||
590 | 197 | def _split_set_of_lines(self, lines, footer): | 248 | def _split_set_of_lines(self, lines, footer): |
591 | 198 | """ | 249 | """ |
597 | 199 | Given a list of lines, decide how to split them best if they don't all fit on the screen | 250 | Given a list of lines, decide how to split them best if they don't all |
598 | 200 | - this is done by splitting at 1/2, 1/3 or 1/4 of the set | 251 | fit on the screen. This is done by splitting at 1/2, 1/3 or 1/4 of the |
599 | 201 | If it doesn't fit, even at this size, just split at each opportunity. | 252 | set. If it doesn't fit, even at this size, just split at each |
600 | 202 | We'll do this by getting the bounding box of each line, and then summing them appropriately | 253 | opportunity. We'll do this by getting the bounding box of each line, |
601 | 203 | Returns a list of [lists of lines], one set for each screenful | 254 | and then summing them appropriately. |
602 | 255 | |||
603 | 256 | Returns a list of [lists of lines], one set for each screenful. | ||
604 | 257 | |||
605 | 258 | ``lines`` | ||
606 | 259 | The lines of text to split. | ||
607 | 260 | |||
608 | 261 | ``footer`` | ||
609 | 262 | The footer text. | ||
610 | 204 | """ | 263 | """ |
611 | 205 | bboxes = [] | 264 | bboxes = [] |
612 | 206 | for line in lines: | 265 | for line in lines: |
613 | @@ -254,6 +313,15 @@ | |||
614 | 254 | return retval | 313 | return retval |
615 | 255 | 314 | ||
616 | 256 | def _correctAlignment(self, rect, bbox): | 315 | def _correctAlignment(self, rect, bbox): |
617 | 316 | """ | ||
618 | 317 | Corrects the vertical alignment of text. | ||
619 | 318 | |||
620 | 319 | ``rect`` | ||
621 | 320 | The block dimentions. | ||
622 | 321 | |||
623 | 322 | ``bbox`` | ||
624 | 323 | Footer dimensions? | ||
625 | 324 | """ | ||
626 | 257 | x = rect.left() | 325 | x = rect.left() |
627 | 258 | if int(self._theme.display_verticalAlign) == 0: | 326 | if int(self._theme.display_verticalAlign) == 0: |
628 | 259 | # top align | 327 | # top align |
629 | @@ -268,13 +336,26 @@ | |||
630 | 268 | log.error(u'Invalid value for theme.VerticalAlign:%s' % self._theme.display_verticalAlign) | 336 | log.error(u'Invalid value for theme.VerticalAlign:%s' % self._theme.display_verticalAlign) |
631 | 269 | return x, y | 337 | return x, y |
632 | 270 | 338 | ||
634 | 271 | def _render_lines_unaligned(self, lines, footer, tlcorner=(0,0), live=False): | 339 | def _render_lines_unaligned(self, lines, footer, tlcorner=(0, 0), live=False): |
635 | 272 | """ | 340 | """ |
641 | 273 | Given a list of lines to render, render each one in turn | 341 | Given a list of lines to render, render each one in turn (using the |
642 | 274 | (using the _render_single_line fn - which may result in going | 342 | ``_render_single_line`` fn - which may result in going off the bottom). |
643 | 275 | off the bottom) They are expected to be pre-arranged to less | 343 | They are expected to be pre-arranged to less than a screenful (eg. by |
644 | 276 | than a screenful (eg. by using split_set_of_lines) | 344 | using split_set_of_lines). |
645 | 277 | Returns the bounding box of the text as QRect | 345 | |
646 | 346 | Returns the bounding box of the text as QRect. | ||
647 | 347 | |||
648 | 348 | ``lines`` | ||
649 | 349 | The lines of text to render. | ||
650 | 350 | |||
651 | 351 | ``footer`` | ||
652 | 352 | The slide footer. | ||
653 | 353 | |||
654 | 354 | ``tlcorner`` | ||
655 | 355 | Defaults to *``(0, 0)``*. Co-ordinates of the top left corner. | ||
656 | 356 | |||
657 | 357 | ``live`` | ||
658 | 358 | Defaults to *False*. Whether or not this is a live screen. | ||
659 | 278 | """ | 359 | """ |
660 | 279 | x, y = tlcorner | 360 | x, y = tlcorner |
661 | 280 | brx = x | 361 | brx = x |
662 | @@ -282,25 +363,37 @@ | |||
663 | 282 | for line in lines: | 363 | for line in lines: |
664 | 283 | # render after current bottom, but at original left edge | 364 | # render after current bottom, but at original left edge |
665 | 284 | # keep track of right edge to see which is biggest | 365 | # keep track of right edge to see which is biggest |
667 | 285 | (thisx, bry) = self._render_and_wrap_single_line(line, footer, (x , bry), live) | 366 | (thisx, bry) = self._render_and_wrap_single_line(line, footer, (x, bry), live) |
668 | 286 | if (thisx > brx): | 367 | if (thisx > brx): |
669 | 287 | brx = thisx | 368 | brx = thisx |
671 | 288 | retval = QtCore.QRect(x, y,brx-x, bry-y) | 369 | retval = QtCore.QRect(x, y, brx - x, bry - y) |
672 | 289 | if self._debug: | 370 | if self._debug: |
673 | 290 | painter = QtGui.QPainter() | 371 | painter = QtGui.QPainter() |
674 | 291 | painter.begin(self._frame) | 372 | painter.begin(self._frame) |
676 | 292 | painter.setPen(QtGui.QPen(QtGui.QColor(0,0,255))) | 373 | painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255))) |
677 | 293 | painter.drawRect(retval) | 374 | painter.drawRect(retval) |
678 | 294 | painter.end() | 375 | painter.end() |
680 | 295 | return retval | 376 | return retval |
681 | 296 | 377 | ||
683 | 297 | def _render_and_wrap_single_line(self, line, footer, tlcorner=(0,0), live=False): | 378 | def _render_and_wrap_single_line(self, line, footer, tlcorner=(0, 0), live=False): |
684 | 298 | """ | 379 | """ |
689 | 299 | Render a single line of words onto the DC, top left corner | 380 | Render a single line of words onto the DC, top left corner specified. |
690 | 300 | specified. | 381 | If the line is too wide for the context, it wraps, but right-aligns |
691 | 301 | If the line is too wide for the context, it wraps, but | 382 | the surplus words in the manner of song lyrics. |
692 | 302 | right-aligns the surplus words in the manner of song lyrics | 383 | |
693 | 303 | Returns the bottom-right corner (of what was rendered) as a tuple(x, y). | 384 | Returns the bottom-right corner (of what was rendered) as a tuple(x, y). |
694 | 385 | |||
695 | 386 | ``line`` | ||
696 | 387 | Line of text to be rendered. | ||
697 | 388 | |||
698 | 389 | ``footer`` | ||
699 | 390 | The footer of the slide. | ||
700 | 391 | |||
701 | 392 | ``tlcorner`` | ||
702 | 393 | Defaults to *``(0, 0)``*. The top left corner. | ||
703 | 394 | |||
704 | 395 | ``live`` | ||
705 | 396 | Defaults to *False*. Whether or not this is a live screen. | ||
706 | 304 | """ | 397 | """ |
707 | 305 | x, y = tlcorner | 398 | x, y = tlcorner |
708 | 306 | # We draw the text to see how big it is and then iterate to make it fit | 399 | # We draw the text to see how big it is and then iterate to make it fit |
709 | @@ -397,6 +490,9 @@ | |||
710 | 397 | return brcorner | 490 | return brcorner |
711 | 398 | 491 | ||
712 | 399 | def _set_theme_font(self): | 492 | def _set_theme_font(self): |
713 | 493 | """ | ||
714 | 494 | Set the fonts from the current theme settings. | ||
715 | 495 | """ | ||
716 | 400 | self.footerFont = QtGui.QFont(self._theme.font_footer_name, | 496 | self.footerFont = QtGui.QFont(self._theme.font_footer_name, |
717 | 401 | int(self._theme.font_footer_proportion), # size | 497 | int(self._theme.font_footer_proportion), # size |
718 | 402 | QtGui.QFont.Normal, # weight | 498 | QtGui.QFont.Normal, # weight |
719 | @@ -408,11 +504,26 @@ | |||
720 | 408 | 0)# italic | 504 | 0)# italic |
721 | 409 | self.mainFont.setPixelSize(int(self._theme.font_main_proportion)) | 505 | self.mainFont.setPixelSize(int(self._theme.font_main_proportion)) |
722 | 410 | 506 | ||
724 | 411 | def _get_extent_and_render(self, line, footer, tlcorner=(0,0), draw=False, color=None): | 507 | def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False, color=None): |
725 | 412 | """ | 508 | """ |
729 | 413 | Find bounding box of text - as render_single_line. | 509 | Find bounding box of text - as render_single_line. If draw is set, |
730 | 414 | If draw is set, actually draw the text to the current DC as well | 510 | actually draw the text to the current DC as well return width and |
731 | 415 | return width and height of text as a tuple (w,h) | 511 | height of text as a tuple (w, h). |
732 | 512 | |||
733 | 513 | ``line`` | ||
734 | 514 | The line of text to render. | ||
735 | 515 | |||
736 | 516 | ``footer`` | ||
737 | 517 | The footer text. | ||
738 | 518 | |||
739 | 519 | ``tlcorner`` | ||
740 | 520 | Defaults to *``(0, 0)``*. The top left corner co-ordinates. | ||
741 | 521 | |||
742 | 522 | ``draw`` | ||
743 | 523 | Defaults to *False*. Draw the text to the current surface. | ||
744 | 524 | |||
745 | 525 | ``color`` | ||
746 | 526 | Defaults to *None*. The colour to draw with. | ||
747 | 416 | """ | 527 | """ |
748 | 417 | # setup defaults | 528 | # setup defaults |
749 | 418 | painter = QtGui.QPainter() | 529 | painter = QtGui.QPainter() |
750 | @@ -424,7 +535,7 @@ | |||
751 | 424 | else: | 535 | else: |
752 | 425 | font = self.mainFont | 536 | font = self.mainFont |
753 | 426 | painter.setFont(font) | 537 | painter.setFont(font) |
755 | 427 | if color == None: | 538 | if color is None: |
756 | 428 | if footer: | 539 | if footer: |
757 | 429 | painter.setPen(QtGui.QColor(self._theme.font_footer_color)) | 540 | painter.setPen(QtGui.QColor(self._theme.font_footer_color)) |
758 | 430 | else: | 541 | else: |
759 | @@ -443,7 +554,13 @@ | |||
760 | 443 | 554 | ||
761 | 444 | def snoop_Image(self, image, image2=None): | 555 | def snoop_Image(self, image, image2=None): |
762 | 445 | """ | 556 | """ |
764 | 446 | Debugging method to allow images to be viewed | 557 | Debugging method to allow images to be viewed. |
765 | 558 | |||
766 | 559 | ``image`` | ||
767 | 560 | An image to save to disk. | ||
768 | 561 | |||
769 | 562 | ``image2`` | ||
770 | 563 | Defaults to *None*. Another image to save to disk. | ||
771 | 447 | """ | 564 | """ |
772 | 448 | im = image.toImage() | 565 | im = image.toImage() |
773 | 449 | im.save(u'renderer.png', u'png') | 566 | im.save(u'renderer.png', u'png') |
774 | 450 | 567 | ||
775 | === modified file 'openlp/core/lib/rendermanager.py' | |||
776 | --- openlp/core/lib/rendermanager.py 2009-07-02 19:04:50 +0000 | |||
777 | +++ openlp/core/lib/rendermanager.py 2009-07-10 13:16:15 +0000 | |||
778 | @@ -18,26 +18,37 @@ | |||
779 | 18 | Place, Suite 330, Boston, MA 02111-1307 USA | 18 | Place, Suite 330, Boston, MA 02111-1307 USA |
780 | 19 | """ | 19 | """ |
781 | 20 | import logging | 20 | import logging |
783 | 21 | import os, os.path | 21 | import os |
784 | 22 | import sys | 22 | import sys |
785 | 23 | import linecache | ||
786 | 23 | 24 | ||
787 | 24 | from PyQt4 import QtGui, QtCore | 25 | from PyQt4 import QtGui, QtCore |
788 | 26 | |||
789 | 25 | from renderer import Renderer | 27 | from renderer import Renderer |
790 | 26 | 28 | ||
795 | 27 | import sys | 29 | class RenderManager(object): |
792 | 28 | import linecache | ||
793 | 29 | |||
794 | 30 | class RenderManager: | ||
796 | 31 | """ | 30 | """ |
800 | 32 | Class to pull all Renderer interactions into one place. | 31 | Class to pull all Renderer interactions into one place. The plugins will |
801 | 33 | The plugins will call helper methods to do the rendering but | 32 | call helper methods to do the rendering but this class will provide |
802 | 34 | this class will provide display defense code. | 33 | display defense code. |
803 | 35 | """ | 34 | """ |
804 | 36 | global log | 35 | global log |
805 | 37 | log=logging.getLogger(u'RenderManager') | 36 | log=logging.getLogger(u'RenderManager') |
806 | 38 | log.info(u'RenderManager Loaded') | 37 | log.info(u'RenderManager Loaded') |
807 | 39 | 38 | ||
808 | 40 | def __init__(self, theme_manager, screen_list, screen_number=0): | 39 | def __init__(self, theme_manager, screen_list, screen_number=0): |
809 | 40 | """ | ||
810 | 41 | Initialise the render manager. | ||
811 | 42 | |||
812 | 43 | ``theme_manager`` | ||
813 | 44 | The ThemeManager instance, used to get the current theme details. | ||
814 | 45 | |||
815 | 46 | ``screen_list`` | ||
816 | 47 | The list of screens available. | ||
817 | 48 | |||
818 | 49 | ``screen_number`` | ||
819 | 50 | Defaults to *0*. The index of the output/display screen. | ||
820 | 51 | """ | ||
821 | 41 | log.debug(u'Initilisation started') | 52 | log.debug(u'Initilisation started') |
822 | 42 | self.screen_list = screen_list | 53 | self.screen_list = screen_list |
823 | 43 | self.theme_manager = theme_manager | 54 | self.theme_manager = theme_manager |
824 | @@ -52,21 +63,46 @@ | |||
825 | 52 | def update_display(self, screen_number): | 63 | def update_display(self, screen_number): |
826 | 53 | """ | 64 | """ |
827 | 54 | Updates the render manager's information about the current screen. | 65 | Updates the render manager's information about the current screen. |
828 | 66 | |||
829 | 67 | ``screen_number`` | ||
830 | 68 | The updated index of the output/display screen. | ||
831 | 55 | """ | 69 | """ |
832 | 56 | log.debug(u'Update Display') | 70 | log.debug(u'Update Display') |
833 | 57 | if self.current_display != screen_number: | 71 | if self.current_display != screen_number: |
834 | 58 | self.current_display = screen_number | 72 | self.current_display = screen_number |
835 | 59 | self.calculate_default(self.screen_list[self.current_display][u'size']) | 73 | self.calculate_default(self.screen_list[self.current_display][u'size']) |
836 | 60 | 74 | ||
838 | 61 | def set_global_theme(self, global_theme, global_style = u'Global'): | 75 | def set_global_theme(self, global_theme, global_style=u'Global'): |
839 | 76 | """ | ||
840 | 77 | Set the global-level theme and the theme level. | ||
841 | 78 | |||
842 | 79 | ``global_theme`` | ||
843 | 80 | The global-level theme to be set. | ||
844 | 81 | |||
845 | 82 | ``global_style`` | ||
846 | 83 | Defaults to *"Global"*. The theme level, can be "Global", | ||
847 | 84 | "Service" or "Song". | ||
848 | 85 | """ | ||
849 | 62 | self.global_theme = global_theme | 86 | self.global_theme = global_theme |
850 | 63 | self.global_style = global_style | 87 | self.global_style = global_style |
851 | 64 | 88 | ||
852 | 65 | def set_service_theme(self, service_theme): | 89 | def set_service_theme(self, service_theme): |
853 | 90 | """ | ||
854 | 91 | Set the service-level theme. | ||
855 | 92 | |||
856 | 93 | ``service_theme`` | ||
857 | 94 | The service-level theme to be set. | ||
858 | 95 | """ | ||
859 | 66 | self.service_theme = service_theme | 96 | self.service_theme = service_theme |
860 | 67 | 97 | ||
861 | 68 | def set_override_theme(self, theme): | 98 | def set_override_theme(self, theme): |
863 | 69 | log.debug(u'set override theme to %s', theme) | 99 | """ |
864 | 100 | Set the appropriate theme depending on the theme level. | ||
865 | 101 | |||
866 | 102 | ``theme`` | ||
867 | 103 | The name of the song-level theme. | ||
868 | 104 | """ | ||
869 | 105 | log.debug(u'set override theme to %s', theme) | ||
870 | 70 | if self.global_style == u'Global': | 106 | if self.global_style == u'Global': |
871 | 71 | self.theme = self.global_theme | 107 | self.theme = self.global_theme |
872 | 72 | elif self.global_style == u'Service': | 108 | elif self.global_style == u'Service': |
873 | @@ -84,7 +120,7 @@ | |||
874 | 84 | self.theme = self.service_theme | 120 | self.theme = self.service_theme |
875 | 85 | else: | 121 | else: |
876 | 86 | self.theme = self.global_theme | 122 | self.theme = self.global_theme |
878 | 87 | if self.theme is not self.renderer.theme_name: | 123 | if self.theme != self.renderer.theme_name: |
879 | 88 | log.debug(u'theme is now %s', self.theme) | 124 | log.debug(u'theme is now %s', self.theme) |
880 | 89 | self.themedata = self.theme_manager.getThemeData(self.theme) | 125 | self.themedata = self.theme_manager.getThemeData(self.theme) |
881 | 90 | self.calculate_default(self.screen_list[self.current_display][u'size']) | 126 | self.calculate_default(self.screen_list[self.current_display][u'size']) |
882 | @@ -92,7 +128,13 @@ | |||
883 | 92 | self.build_text_rectangle(self.themedata) | 128 | self.build_text_rectangle(self.themedata) |
884 | 93 | 129 | ||
885 | 94 | def build_text_rectangle(self, theme): | 130 | def build_text_rectangle(self, theme): |
887 | 95 | log.debug(u'build_text_rectangle ') | 131 | """ |
888 | 132 | Builds a text block using the settings in ``theme``. | ||
889 | 133 | |||
890 | 134 | ``theme`` | ||
891 | 135 | The theme to build a text block for. | ||
892 | 136 | """ | ||
893 | 137 | log.debug(u'build_text_rectangle') | ||
894 | 96 | main_rect = None | 138 | main_rect = None |
895 | 97 | footer_rect = None | 139 | footer_rect = None |
896 | 98 | if theme.font_main_override == False: | 140 | if theme.font_main_override == False: |
897 | @@ -108,31 +150,52 @@ | |||
898 | 108 | self.renderer.set_text_rectangle(main_rect,footer_rect) | 150 | self.renderer.set_text_rectangle(main_rect,footer_rect) |
899 | 109 | 151 | ||
900 | 110 | def generate_preview(self, themedata): | 152 | def generate_preview(self, themedata): |
901 | 153 | """ | ||
902 | 154 | Generate a preview of a theme. | ||
903 | 155 | |||
904 | 156 | ``themedata`` | ||
905 | 157 | The theme to generated a preview for. | ||
906 | 158 | """ | ||
907 | 111 | log.debug(u'generate preview') | 159 | log.debug(u'generate preview') |
908 | 112 | self.calculate_default(QtCore.QSize(1024, 768)) | 160 | self.calculate_default(QtCore.QSize(1024, 768)) |
909 | 113 | self.renderer.set_theme(themedata) | 161 | self.renderer.set_theme(themedata) |
910 | 114 | self.build_text_rectangle(themedata) | 162 | self.build_text_rectangle(themedata) |
911 | 115 | self.renderer.set_frame_dest(self.width, self.height, True) | 163 | self.renderer.set_frame_dest(self.width, self.height, True) |
923 | 116 | lines = [] | 164 | verse = [] |
924 | 117 | lines.append(u'Amazing Grace!') | 165 | verse.append(u'Amazing Grace!') |
925 | 118 | lines.append(u'How sweet the sound') | 166 | verse.append(u'How sweet the sound') |
926 | 119 | lines.append(u'To save a wretch like me;') | 167 | verse.append(u'To save a wretch like me;') |
927 | 120 | lines.append(u'I once was lost but now am found,') | 168 | verse.append(u'I once was lost but now am found,') |
928 | 121 | lines.append(u'Was blind, but now I see.') | 169 | verse.append(u'Was blind, but now I see.') |
929 | 122 | lines1 = [] | 170 | footer = [] |
930 | 123 | lines1.append(u'Amazing Grace (John Newton)' ) | 171 | footer.append(u'Amazing Grace (John Newton)' ) |
931 | 124 | lines1.append(u'Public Domain') | 172 | footer.append(u'Public Domain') |
932 | 125 | lines1.append(u'CCLI xxx') | 173 | footer.append(u'CCLI xxx') |
933 | 126 | return self.renderer.generate_frame_from_lines(lines, lines1) | 174 | return self.renderer.generate_frame_from_lines(verse, footer) |
934 | 127 | 175 | ||
935 | 128 | def format_slide(self, words): | 176 | def format_slide(self, words): |
936 | 177 | """ | ||
937 | 178 | Calculate how much text can fid on a slide. | ||
938 | 179 | |||
939 | 180 | ``words`` | ||
940 | 181 | The words to go on the slides. | ||
941 | 182 | """ | ||
942 | 129 | log.debug(u'format slide') | 183 | log.debug(u'format slide') |
943 | 130 | self.calculate_default(self.screen_list[self.current_display][u'size']) | 184 | self.calculate_default(self.screen_list[self.current_display][u'size']) |
944 | 131 | self.build_text_rectangle(self.themedata) | 185 | self.build_text_rectangle(self.themedata) |
945 | 132 | self.renderer.set_frame_dest(self.width, self.height) | 186 | self.renderer.set_frame_dest(self.width, self.height) |
946 | 133 | return self.renderer.format_slide(words, False) | 187 | return self.renderer.format_slide(words, False) |
947 | 134 | 188 | ||
949 | 135 | def generate_slide(self,main_text, footer_text): | 189 | def generate_slide(self, main_text, footer_text): |
950 | 190 | """ | ||
951 | 191 | Generate the actual slide image. | ||
952 | 192 | |||
953 | 193 | ``main_text`` | ||
954 | 194 | The text for the main area of the slide. | ||
955 | 195 | |||
956 | 196 | ``footer_text`` | ||
957 | 197 | The text for the slide footer. | ||
958 | 198 | """ | ||
959 | 136 | log.debug(u'generate slide') | 199 | log.debug(u'generate slide') |
960 | 137 | self.calculate_default(self.screen_list[self.current_display][u'size']) | 200 | self.calculate_default(self.screen_list[self.current_display][u'size']) |
961 | 138 | self.build_text_rectangle(self.themedata) | 201 | self.build_text_rectangle(self.themedata) |
962 | @@ -140,6 +203,12 @@ | |||
963 | 140 | return self.renderer.generate_frame_from_lines(main_text, footer_text) | 203 | return self.renderer.generate_frame_from_lines(main_text, footer_text) |
964 | 141 | 204 | ||
965 | 142 | def resize_image(self, image): | 205 | def resize_image(self, image): |
966 | 206 | """ | ||
967 | 207 | Resize an image to fit on the current screen. | ||
968 | 208 | |||
969 | 209 | ``image`` | ||
970 | 210 | The image to resize. | ||
971 | 211 | """ | ||
972 | 143 | preview = QtGui.QImage(image) | 212 | preview = QtGui.QImage(image) |
973 | 144 | w = self.width | 213 | w = self.width |
974 | 145 | h = self.height | 214 | h = self.height |
975 | @@ -154,13 +223,19 @@ | |||
976 | 154 | return newImage | 223 | return newImage |
977 | 155 | 224 | ||
978 | 156 | def calculate_default(self, screen): | 225 | def calculate_default(self, screen): |
980 | 157 | log.debug(u'calculate default %s' , screen) | 226 | """ |
981 | 227 | Calculate the default dimentions of the screen. | ||
982 | 228 | |||
983 | 229 | ``screen`` | ||
984 | 230 | The QWidget instance of the screen. | ||
985 | 231 | """ | ||
986 | 232 | log.debug(u'calculate default %s', screen) | ||
987 | 158 | if self.current_display == 0: | 233 | if self.current_display == 0: |
988 | 159 | self.width = 1024 | 234 | self.width = 1024 |
989 | 160 | self.height = 768 | 235 | self.height = 768 |
990 | 161 | else: | 236 | else: |
991 | 162 | self.width = screen.width() | 237 | self.width = screen.width() |
992 | 163 | self.height = screen.height() | 238 | self.height = screen.height() |
994 | 164 | log.debug(u'calculate default %d,%d' , self.width, self.height) | 239 | log.debug(u'calculate default %d, %d', self.width, self.height) |
995 | 165 | # 90% is start of footer | 240 | # 90% is start of footer |
996 | 166 | self.footer_start = int(self.height * 0.90) | 241 | self.footer_start = int(self.height * 0.90) |
997 | 167 | 242 | ||
998 | === modified file 'openlp/core/lib/serviceitem.py' | |||
999 | --- openlp/core/lib/serviceitem.py 2009-06-20 19:11:17 +0000 | |||
1000 | +++ openlp/core/lib/serviceitem.py 2009-07-10 13:16:15 +0000 | |||
1001 | @@ -20,10 +20,12 @@ | |||
1002 | 20 | import logging | 20 | import logging |
1003 | 21 | import os | 21 | import os |
1004 | 22 | import time | 22 | import time |
1005 | 23 | |||
1006 | 24 | from PyQt4 import QtCore, QtGui | ||
1007 | 25 | |||
1008 | 23 | from openlp.core.lib import buildIcon | 26 | from openlp.core.lib import buildIcon |
1009 | 24 | from PyQt4 import QtCore, QtGui | ||
1010 | 25 | 27 | ||
1012 | 26 | class ServiceItem(): | 28 | class ServiceItem(object): |
1013 | 27 | """ | 29 | """ |
1014 | 28 | The service item is a base class for the plugins to use to interact with | 30 | The service item is a base class for the plugins to use to interact with |
1015 | 29 | the service manager, the slide controller, and the projection screen | 31 | the service manager, the slide controller, and the projection screen |
1016 | @@ -35,7 +37,10 @@ | |||
1017 | 35 | 37 | ||
1018 | 36 | def __init__(self, hostplugin=None): | 38 | def __init__(self, hostplugin=None): |
1019 | 37 | """ | 39 | """ |
1021 | 38 | Init Method | 40 | Set up the service item. |
1022 | 41 | |||
1023 | 42 | ``hostplugin`` | ||
1024 | 43 | The plugin that this service item belongs to. | ||
1025 | 39 | """ | 44 | """ |
1026 | 40 | self.plugin = hostplugin | 45 | self.plugin = hostplugin |
1027 | 41 | if hostplugin is not None: | 46 | if hostplugin is not None: |
1028 | @@ -56,6 +61,14 @@ | |||
1029 | 56 | self.service_frames = [] | 61 | self.service_frames = [] |
1030 | 57 | 62 | ||
1031 | 58 | def addIcon(self, icon): | 63 | def addIcon(self, icon): |
1032 | 64 | """ | ||
1033 | 65 | Add an icon to the service item. This is used when displaying the | ||
1034 | 66 | service item in the service manager. | ||
1035 | 67 | |||
1036 | 68 | ``icon`` | ||
1037 | 69 | An instance of QIcon or a string to an icon in the resource or on | ||
1038 | 70 | disk. | ||
1039 | 71 | """ | ||
1040 | 59 | self.icon = icon | 72 | self.icon = icon |
1041 | 60 | self.iconic_representation = buildIcon(icon) | 73 | self.iconic_representation = buildIcon(icon) |
1042 | 61 | 74 | ||
1043 | @@ -89,27 +102,63 @@ | |||
1044 | 89 | else: | 102 | else: |
1045 | 90 | log.error(u'Invalid value renderer :%s' % self.service_item_type) | 103 | log.error(u'Invalid value renderer :%s' % self.service_item_type) |
1046 | 91 | 104 | ||
1048 | 92 | def add_from_image(self, path, frame_title, image): | 105 | def add_from_image(self, path, frame_title, image): |
1049 | 106 | """ | ||
1050 | 107 | Add an image slide to the service item. | ||
1051 | 108 | |||
1052 | 109 | ``path`` | ||
1053 | 110 | The directory in which the image file is located. | ||
1054 | 111 | |||
1055 | 112 | ``frame_title`` | ||
1056 | 113 | A title for the slide in the service item. | ||
1057 | 114 | |||
1058 | 115 | ``image`` | ||
1059 | 116 | The actual image file name. | ||
1060 | 117 | """ | ||
1061 | 93 | self.service_item_type = u'image' | 118 | self.service_item_type = u'image' |
1062 | 94 | self.service_item_path = path | 119 | self.service_item_path = path |
1063 | 95 | self.service_frames.append({u'title': frame_title, u'image': image}) | 120 | self.service_frames.append({u'title': frame_title, u'image': image}) |
1064 | 96 | 121 | ||
1065 | 97 | def add_from_text(self, frame_title, raw_slide): | 122 | def add_from_text(self, frame_title, raw_slide): |
1066 | 123 | """ | ||
1067 | 124 | Add a text slide to the service item. | ||
1068 | 125 | |||
1069 | 126 | ``frame_title`` | ||
1070 | 127 | The title of the slide in the service item. | ||
1071 | 128 | |||
1072 | 129 | ``raw_slide`` | ||
1073 | 130 | The raw text of the slide. | ||
1074 | 131 | """ | ||
1075 | 98 | self.service_item_type = u'text' | 132 | self.service_item_type = u'text' |
1076 | 99 | frame_title = frame_title.split(u'\n')[0] | 133 | frame_title = frame_title.split(u'\n')[0] |
1077 | 100 | self.service_frames.append({u'title': frame_title, u'raw_slide': raw_slide}) | 134 | self.service_frames.append({u'title': frame_title, u'raw_slide': raw_slide}) |
1078 | 101 | 135 | ||
1079 | 102 | def add_from_command(self, frame_title, command): | 136 | def add_from_command(self, frame_title, command): |
1080 | 137 | """ | ||
1081 | 138 | Add a slide from a command. | ||
1082 | 139 | |||
1083 | 140 | ``frame_title`` | ||
1084 | 141 | The title of the slide in the service item. | ||
1085 | 142 | |||
1086 | 143 | ``command`` | ||
1087 | 144 | The command of/for the slide. | ||
1088 | 145 | """ | ||
1089 | 103 | self.service_item_type = u'command' | 146 | self.service_item_type = u'command' |
1090 | 104 | self.service_frames.append({u'title': frame_title, u'command': command}) | 147 | self.service_frames.append({u'title': frame_title, u'command': command}) |
1091 | 105 | 148 | ||
1092 | 106 | def get_oos_repr(self): | 149 | def get_oos_repr(self): |
1093 | 107 | """ | 150 | """ |
1094 | 108 | This method returns some text which can be saved into the OOS | 151 | This method returns some text which can be saved into the OOS |
1096 | 109 | file to represent this item | 152 | file to represent this item. |
1097 | 110 | """ | 153 | """ |
1100 | 111 | oos_header = {u'plugin': self.shortname,u'theme':self.theme, u'title':self.title, | 154 | oos_header = { |
1101 | 112 | u'icon':self.icon, u'footer':self.raw_footer, u'type':self.service_item_type} | 155 | u'plugin': self.shortname, |
1102 | 156 | u'theme':self.theme, | ||
1103 | 157 | u'title':self.title, | ||
1104 | 158 | u'icon':self.icon, | ||
1105 | 159 | u'footer':self.raw_footer, | ||
1106 | 160 | u'type':self.service_item_type | ||
1107 | 161 | } | ||
1108 | 113 | oos_data = [] | 162 | oos_data = [] |
1109 | 114 | if self.service_item_type == u'text': | 163 | if self.service_item_type == u'text': |
1110 | 115 | for slide in self.service_frames: | 164 | for slide in self.service_frames: |
1111 | @@ -124,8 +173,14 @@ | |||
1112 | 124 | 173 | ||
1113 | 125 | def set_from_oos(self, serviceitem, path=None): | 174 | def set_from_oos(self, serviceitem, path=None): |
1114 | 126 | """ | 175 | """ |
1117 | 127 | This method takes some oos list (passed from the ServiceManager) | 176 | This method takes a service item from a saved service file (passed |
1118 | 128 | and extracts the data actually required | 177 | from the ServiceManager) and extracts the data actually required. |
1119 | 178 | |||
1120 | 179 | ``serviceitem`` | ||
1121 | 180 | The item to extract data from. | ||
1122 | 181 | |||
1123 | 182 | ``path`` | ||
1124 | 183 | Defaults to *None*. Any path data, usually for images. | ||
1125 | 129 | """ | 184 | """ |
1126 | 130 | #print "sfs", serviceitem | 185 | #print "sfs", serviceitem |
1127 | 131 | header = serviceitem[u'serviceitem'][u'header'] | 186 | header = serviceitem[u'serviceitem'][u'header'] |
1128 | 132 | 187 | ||
1129 | === modified file 'openlp/core/lib/settingstab.py' | |||
1130 | --- openlp/core/lib/settingstab.py 2009-06-05 18:53:50 +0000 | |||
1131 | +++ openlp/core/lib/settingstab.py 2009-07-10 13:16:15 +0000 | |||
1132 | @@ -23,11 +23,20 @@ | |||
1133 | 23 | 23 | ||
1134 | 24 | class SettingsTab(QtGui.QWidget): | 24 | class SettingsTab(QtGui.QWidget): |
1135 | 25 | """ | 25 | """ |
1137 | 26 | SettingsTab is a helper widget for plugins to define Tabs for the settings dialog. | 26 | SettingsTab is a helper widget for plugins to define Tabs for the settings |
1138 | 27 | dialog. | ||
1139 | 27 | """ | 28 | """ |
1140 | 28 | def __init__(self, title=None, section=None): | 29 | def __init__(self, title=None, section=None): |
1141 | 29 | """ | 30 | """ |
1143 | 30 | Constructor to create the Steetings tab item. | 31 | Constructor to create the Settings tab item. |
1144 | 32 | |||
1145 | 33 | ``title`` | ||
1146 | 34 | Defaults to *None*. The title of the tab, which is usually | ||
1147 | 35 | displayed on the tab. | ||
1148 | 36 | |||
1149 | 37 | ``section`` | ||
1150 | 38 | Defaults to *None*. This is the section in the configuration file | ||
1151 | 39 | to write to when the ``save`` method is called. | ||
1152 | 31 | """ | 40 | """ |
1153 | 32 | QtGui.QWidget.__init__(self) | 41 | QtGui.QWidget.__init__(self) |
1154 | 33 | self.tabTitle = title | 42 | self.tabTitle = title |
1155 | @@ -43,6 +52,9 @@ | |||
1156 | 43 | def setTitle(self, title): | 52 | def setTitle(self, title): |
1157 | 44 | """ | 53 | """ |
1158 | 45 | Set the title of the tab. | 54 | Set the title of the tab. |
1159 | 55 | |||
1160 | 56 | ``title`` | ||
1161 | 57 | The title of the tab, which is usually displayed on the tab. | ||
1162 | 46 | """ | 58 | """ |
1163 | 47 | self.tabTitle = title | 59 | self.tabTitle = title |
1164 | 48 | 60 | ||
1165 | 49 | 61 | ||
1166 | === modified file 'openlp/core/lib/songxmlhandler.py' | |||
1167 | --- openlp/core/lib/songxmlhandler.py 2009-06-21 16:26:33 +0000 | |||
1168 | +++ openlp/core/lib/songxmlhandler.py 2009-07-10 13:16:15 +0000 | |||
1169 | @@ -30,21 +30,34 @@ | |||
1170 | 30 | 30 | ||
1171 | 31 | """ | 31 | """ |
1172 | 32 | import logging | 32 | import logging |
1174 | 33 | from xml.dom.minidom import Document | 33 | from xml.dom.minidom import Document |
1175 | 34 | from xml.etree.ElementTree import ElementTree, XML, dump | 34 | from xml.etree.ElementTree import ElementTree, XML, dump |
1176 | 35 | 35 | ||
1177 | 36 | class SongXMLBuilder(): | 36 | class SongXMLBuilder(): |
1178 | 37 | """ | ||
1179 | 38 | This class builds the XML used to describe songs. | ||
1180 | 39 | """ | ||
1181 | 37 | def __init__(self): | 40 | def __init__(self): |
1182 | 41 | """ | ||
1183 | 42 | Set up the song builder. | ||
1184 | 43 | """ | ||
1185 | 38 | # Create the minidom document | 44 | # Create the minidom document |
1186 | 39 | self.song_xml = Document() | 45 | self.song_xml = Document() |
1187 | 40 | 46 | ||
1188 | 41 | def new_document(self): | 47 | def new_document(self): |
1189 | 48 | """ | ||
1190 | 49 | Create a new song XML document. | ||
1191 | 50 | """ | ||
1192 | 42 | # Create the <song> base element | 51 | # Create the <song> base element |
1193 | 43 | self.song = self.song_xml.createElement(u'song') | 52 | self.song = self.song_xml.createElement(u'song') |
1194 | 44 | self.song_xml.appendChild(self.song) | 53 | self.song_xml.appendChild(self.song) |
1195 | 45 | self.song.setAttribute(u'version', u'1.0') | 54 | self.song.setAttribute(u'version', u'1.0') |
1196 | 46 | 55 | ||
1197 | 47 | def add_lyrics_to_song(self): | 56 | def add_lyrics_to_song(self): |
1198 | 57 | """ | ||
1199 | 58 | Set up and add a ``<lyrics>`` tag which contains the lyrics of the | ||
1200 | 59 | song. | ||
1201 | 60 | """ | ||
1202 | 48 | # Create the main <lyrics> element | 61 | # Create the main <lyrics> element |
1203 | 49 | self.lyrics = self.song_xml.createElement(u'lyrics') | 62 | self.lyrics = self.song_xml.createElement(u'lyrics') |
1204 | 50 | self.lyrics.setAttribute(u'language', u'en') | 63 | self.lyrics.setAttribute(u'language', u'en') |
1205 | @@ -52,50 +65,72 @@ | |||
1206 | 52 | 65 | ||
1207 | 53 | def add_verse_to_lyrics(self, type, number, content): | 66 | def add_verse_to_lyrics(self, type, number, content): |
1208 | 54 | """ | 67 | """ |
1212 | 55 | type - type of verse (Chorus, Verse , Bridge, Custom etc | 68 | Add a verse to the ``<lyrics>`` tag. |
1213 | 56 | number - number of item eg verse 1 | 69 | |
1214 | 57 | content - the text to be stored | 70 | ``type`` |
1215 | 71 | A string denoting the type of verse. Possible values are "Chorus", | ||
1216 | 72 | "Verse", "Bridge", and "Custom". | ||
1217 | 73 | |||
1218 | 74 | ``number`` | ||
1219 | 75 | An integer denoting the number of the item, for example: verse 1. | ||
1220 | 76 | |||
1221 | 77 | ``content`` | ||
1222 | 78 | The actual text of the verse to be stored. | ||
1223 | 58 | """ | 79 | """ |
1224 | 59 | verse = self.song_xml.createElement(u'verse') | 80 | verse = self.song_xml.createElement(u'verse') |
1225 | 60 | verse.setAttribute(u'type', type) | 81 | verse.setAttribute(u'type', type) |
1226 | 61 | verse.setAttribute(u'label', number) | 82 | verse.setAttribute(u'label', number) |
1227 | 62 | self.lyrics.appendChild(verse) | 83 | self.lyrics.appendChild(verse) |
1230 | 63 | 84 | # add data as a CDATA section to protect the XML from special chars | |
1229 | 64 | # add data as a CDATA section | ||
1231 | 65 | cds = self.song_xml.createCDATASection(content) | 85 | cds = self.song_xml.createCDATASection(content) |
1232 | 66 | verse.appendChild(cds) | 86 | verse.appendChild(cds) |
1233 | 67 | 87 | ||
1234 | 68 | def dump_xml(self): | 88 | def dump_xml(self): |
1236 | 69 | # Debugging aid to see what we have | 89 | """ |
1237 | 90 | Debugging aid to dump XML so that we can see what we have. | ||
1238 | 91 | """ | ||
1239 | 70 | print self.song_xml.toprettyxml(indent=u' ') | 92 | print self.song_xml.toprettyxml(indent=u' ') |
1240 | 71 | 93 | ||
1241 | 72 | def extract_xml(self): | 94 | def extract_xml(self): |
1243 | 73 | # Print our newly created XML | 95 | """ |
1244 | 96 | Extract our newly created XML song. | ||
1245 | 97 | """ | ||
1246 | 74 | return self.song_xml.toxml(u'utf-8') | 98 | return self.song_xml.toxml(u'utf-8') |
1247 | 75 | 99 | ||
1248 | 76 | class SongXMLParser(): | 100 | class SongXMLParser(): |
1249 | 101 | """ | ||
1250 | 102 | A class to read in and parse a song's XML. | ||
1251 | 103 | """ | ||
1252 | 77 | global log | 104 | global log |
1253 | 78 | log = logging.getLogger(u'SongXMLParser') | 105 | log = logging.getLogger(u'SongXMLParser') |
1254 | 79 | log.info(u'SongXMLParser Loaded') | 106 | log.info(u'SongXMLParser Loaded') |
1255 | 80 | 107 | ||
1256 | 81 | def __init__(self, xml): | 108 | def __init__(self, xml): |
1258 | 82 | #print xml | 109 | """ |
1259 | 110 | Set up our song XML parser. | ||
1260 | 111 | |||
1261 | 112 | ``xml`` | ||
1262 | 113 | The XML of the song to be parsed. | ||
1263 | 114 | """ | ||
1264 | 83 | try: | 115 | try: |
1265 | 84 | self.song_xml = ElementTree(element=XML(xml)) | 116 | self.song_xml = ElementTree(element=XML(xml)) |
1266 | 85 | except: | 117 | except: |
1269 | 86 | #print "invalid xml ", xml | 118 | log.debug(u'Invalid xml %s', xml) |
1268 | 87 | log.debug(u'invalid xml %s', xml) | ||
1270 | 88 | 119 | ||
1271 | 89 | def get_verses(self): | 120 | def get_verses(self): |
1274 | 90 | #return a list of verse's and attributes | 121 | """ |
1275 | 91 | iter=self.song_xml.getiterator() | 122 | Iterates through the verses in the XML and returns a list of verses |
1276 | 123 | and their attributes. | ||
1277 | 124 | """ | ||
1278 | 125 | iter = self.song_xml.getiterator() | ||
1279 | 92 | verse_list = [] | 126 | verse_list = [] |
1280 | 93 | for element in iter: | 127 | for element in iter: |
1281 | 94 | #print element.tag, element.attrib, element.text | ||
1282 | 95 | if element.tag == u'verse': | 128 | if element.tag == u'verse': |
1283 | 96 | verse_list.append([element.attrib, element.text]) | 129 | verse_list.append([element.attrib, element.text]) |
1284 | 97 | return verse_list | 130 | return verse_list |
1285 | 98 | 131 | ||
1286 | 99 | def dump_xml(self): | 132 | def dump_xml(self): |
1288 | 100 | # Debugging aid to see what we have | 133 | """ |
1289 | 134 | Debugging aid to dump XML so that we can see what we have. | ||
1290 | 135 | """ | ||
1291 | 101 | print dump(self.song_xml) | 136 | print dump(self.song_xml) |
1292 | 102 | 137 | ||
1293 | === modified file 'openlp/core/lib/themexmlhandler.py' | |||
1294 | --- openlp/core/lib/themexmlhandler.py 2009-07-08 06:55:08 +0000 | |||
1295 | +++ openlp/core/lib/themexmlhandler.py 2009-07-10 13:16:15 +0000 | |||
1296 | @@ -345,5 +345,5 @@ | |||
1297 | 345 | s = u'' | 345 | s = u'' |
1298 | 346 | for k in dir(self): | 346 | for k in dir(self): |
1299 | 347 | if k[0:1] != u'_': | 347 | if k[0:1] != u'_': |
1301 | 348 | s += u'%30s : %s\n' %(k, getattr(self, k)) | 348 | s += u'%30s: %s\n' %(k, getattr(self, k)) |
1302 | 349 | return s | 349 | return s |
Some more docstrings cleanups.