Merge lp:~trb143/openlp/cleanups2018 into lp:openlp
- cleanups2018
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 2812 |
Proposed branch: | lp:~trb143/openlp/cleanups2018 |
Merge into: | lp:openlp |
Diff against target: |
2937 lines (+148/-2159) 20 files modified
openlp/core/api/http/wsgiapp.py (+4/-0) openlp/core/app.py (+2/-1) openlp/core/common/mixins.py (+11/-1) openlp/core/common/settings.py (+2/-1) openlp/core/ui/aboutdialog.py (+1/-1) openlp/core/ui/mainwindow.py (+16/-22) openlp/core/ui/servicemanager.py (+27/-46) openlp/core/ui/slidecontroller.py (+8/-8) openlp/plugins/bibles/lib/mediaitem.py (+7/-3) openlp/plugins/presentations/lib/pptviewcontroller.py (+0/-307) openlp/plugins/presentations/lib/pptviewlib/README.TXT (+0/-121) openlp/plugins/presentations/lib/pptviewlib/ppttest.py (+0/-210) openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp (+0/-920) openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h (+0/-80) openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj (+0/-202) openlp/plugins/presentations/presentationplugin.py (+1/-2) openlp/plugins/songs/lib/mediaitem.py (+14/-7) tests/functional/openlp_core/api/endpoint/test_controller.py (+54/-0) tests/functional/openlp_plugins/bibles/test_mediaitem.py (+1/-1) tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py (+0/-226) |
To merge this branch: | bzr merge lp:~trb143/openlp/cleanups2018 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tomas Groth | Approve | ||
Review via email: mp+337120@code.launchpad.net |
This proposal supersedes a proposal from 2018-02-03.
Commit message
Description of the change
Remove Powerpoint Viewer
Clean up the logging framework and add to MainWindow
Fix bug in remote API
various minor text fixes.
lp:~trb143/openlp/cleanups2018 (revision 2827)
https:/
https:/
https:/
https:/
https:/
https:/
https:/
Preview Diff
1 | === modified file 'openlp/core/api/http/wsgiapp.py' |
2 | --- openlp/core/api/http/wsgiapp.py 2017-12-29 09:15:48 +0000 |
3 | +++ openlp/core/api/http/wsgiapp.py 2018-02-03 15:03:00 +0000 |
4 | @@ -69,6 +69,7 @@ |
5 | """ |
6 | Create a Response object from response |
7 | """ |
8 | + log.debug("in Make response") |
9 | if isinstance(view_result, Response): |
10 | return view_result |
11 | elif isinstance(view_result, tuple): |
12 | @@ -88,6 +89,9 @@ |
13 | elif isinstance(view_result, str): |
14 | return Response(body=view_result, status=200, |
15 | content_type='text/html', charset='utf8') |
16 | + else: |
17 | + return Response(body=view_result, status=200, |
18 | + content_type='text/plain', charset='utf8') |
19 | |
20 | |
21 | def _handle_exception(error): |
22 | |
23 | === modified file 'openlp/core/app.py' |
24 | --- openlp/core/app.py 2018-01-12 18:29:32 +0000 |
25 | +++ openlp/core/app.py 2018-02-03 15:03:00 +0000 |
26 | @@ -120,7 +120,8 @@ |
27 | self.main_window.show() |
28 | if can_show_splash: |
29 | # now kill the splashscreen |
30 | - self.splash.finish(self.main_window) |
31 | + log.debug('Splashscreen closing') |
32 | + self.splash.close() |
33 | log.debug('Splashscreen closed') |
34 | # make sure Qt really display the splash screen |
35 | self.processEvents() |
36 | |
37 | === modified file 'openlp/core/common/mixins.py' |
38 | --- openlp/core/common/mixins.py 2017-12-29 09:15:48 +0000 |
39 | +++ openlp/core/common/mixins.py 2018-02-03 15:03:00 +0000 |
40 | @@ -56,7 +56,10 @@ |
41 | def wrapped(*args, **kwargs): |
42 | parent.logger.debug("Entering {function}".format(function=func.__name__)) |
43 | try: |
44 | - return func(*args, **kwargs) |
45 | + if len(inspect.signature(func).parameters.values()): |
46 | + return func(*args, **kwargs) |
47 | + else: |
48 | + return func(*args) |
49 | except Exception as e: |
50 | if parent.logger.getEffectiveLevel() <= logging.ERROR: |
51 | parent.logger.error('Exception in {function} : {error}'.format(function=func.__name__, |
52 | @@ -89,6 +92,13 @@ |
53 | trace_error_handler(self.logger) |
54 | self.logger.error(message) |
55 | |
56 | + def log_critical(self, message): |
57 | + """ |
58 | + Common log critical handler which prints the calling path |
59 | + """ |
60 | + trace_error_handler(self.logger) |
61 | + self.logger.critical(message) |
62 | + |
63 | def log_exception(self, message): |
64 | """ |
65 | Common log exception handler which prints the calling path |
66 | |
67 | === modified file 'openlp/core/common/settings.py' |
68 | --- openlp/core/common/settings.py 2017-12-29 09:15:48 +0000 |
69 | +++ openlp/core/common/settings.py 2018-02-03 15:03:00 +0000 |
70 | @@ -259,7 +259,8 @@ |
71 | ('media/last directory', 'media/last directory', [(str_to_path, None)]), |
72 | ('songuasge/db password', 'songusage/db password', []), |
73 | ('songuasge/db hostname', 'songusage/db hostname', []), |
74 | - ('songuasge/db database', 'songusage/db database', []) |
75 | + ('songuasge/db database', 'songusage/db database', []), |
76 | + ('presentations / Powerpoint Viewer', '', []) |
77 | ] |
78 | |
79 | @staticmethod |
80 | |
81 | === modified file 'openlp/core/ui/aboutdialog.py' |
82 | --- openlp/core/ui/aboutdialog.py 2017-12-29 09:15:48 +0000 |
83 | +++ openlp/core/ui/aboutdialog.py 2018-02-03 15:03:00 +0000 |
84 | @@ -98,7 +98,7 @@ |
85 | 'OpenLP is free church presentation software, or lyrics ' |
86 | 'projection software, used to display slides of songs, Bible ' |
87 | 'verses, videos, images, and even presentations (if ' |
88 | - 'Impress, PowerPoint or PowerPoint Viewer is installed) ' |
89 | + 'Impress or PowerPoint is installed) ' |
90 | 'for church worship using a computer and a data projector.\n' |
91 | '\n' |
92 | 'Find out more about OpenLP: http://openlp.org/\n' |
93 | |
94 | === modified file 'openlp/core/ui/mainwindow.py' |
95 | --- openlp/core/ui/mainwindow.py 2018-01-20 09:30:30 +0000 |
96 | +++ openlp/core/ui/mainwindow.py 2018-02-03 15:03:00 +0000 |
97 | @@ -37,7 +37,7 @@ |
98 | from openlp.core.common.actions import ActionList, CategoryOrder |
99 | from openlp.core.common.applocation import AppLocation |
100 | from openlp.core.common.i18n import LanguageManager, UiStrings, translate |
101 | -from openlp.core.common.mixins import RegistryProperties |
102 | +from openlp.core.common.mixins import LogMixin, RegistryProperties |
103 | from openlp.core.common.path import Path, copyfile, create_paths |
104 | from openlp.core.common.registry import Registry |
105 | from openlp.core.common.settings import Settings |
106 | @@ -56,8 +56,6 @@ |
107 | from openlp.core.widgets.dialogs import FileDialog |
108 | from openlp.core.widgets.docks import OpenLPDockWidget, MediaDockManager |
109 | |
110 | -log = logging.getLogger(__name__) |
111 | - |
112 | |
113 | class Ui_MainWindow(object): |
114 | """ |
115 | @@ -465,12 +463,10 @@ |
116 | self.mode_live_item.setStatusTip(translate('OpenLP.MainWindow', 'Use layout that focuses on Live.')) |
117 | |
118 | |
119 | -class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties): |
120 | +class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryProperties): |
121 | """ |
122 | The main window. |
123 | """ |
124 | - log.info('MainWindow loaded') |
125 | - |
126 | def __init__(self): |
127 | """ |
128 | This constructor sets up the interface, the various managers, and the plugins. |
129 | @@ -557,7 +553,7 @@ |
130 | wait_dialog.setCancelButton(None) |
131 | wait_dialog.show() |
132 | for thread_name in self.application.worker_threads.keys(): |
133 | - log.debug('Waiting for thread %s', thread_name) |
134 | + self.log_debug('Waiting for thread %s' % thread_name) |
135 | self.application.processEvents() |
136 | thread = self.application.worker_threads[thread_name]['thread'] |
137 | worker = self.application.worker_threads[thread_name]['worker'] |
138 | @@ -595,7 +591,7 @@ |
139 | """ |
140 | Called on start up to restore the last active media plugin. |
141 | """ |
142 | - log.info('Load data from Settings') |
143 | + self.log_info('Load data from Settings') |
144 | if Settings().value('advanced/save current plugin'): |
145 | saved_plugin_id = Settings().value('advanced/current media plugin') |
146 | if saved_plugin_id != -1: |
147 | @@ -627,7 +623,6 @@ |
148 | |
149 | :param version: The Version to be displayed. |
150 | """ |
151 | - log.debug('version_notice') |
152 | version_text = translate('OpenLP.MainWindow', 'Version {new} of OpenLP is now available for download (you are ' |
153 | 'currently running version {current}). \n\nYou can download the latest version from ' |
154 | 'http://openlp.org/.').format(new=version, current=get_version()[u'full']) |
155 | @@ -774,7 +769,8 @@ |
156 | self.application.splash.close() |
157 | QtWidgets.QMessageBox.information(self, title, message) |
158 | |
159 | - def on_help_web_site_clicked(self): |
160 | + @staticmethod |
161 | + def on_help_web_site_clicked(): |
162 | """ |
163 | Load the OpenLP website |
164 | """ |
165 | @@ -891,7 +887,7 @@ |
166 | settings = Settings() |
167 | import_settings = Settings(str(temp_config_path), Settings.IniFormat) |
168 | |
169 | - log.info('hook upgrade_plugin_settings') |
170 | + self.log_info('hook upgrade_plugin_settings') |
171 | self.plugin_manager.hook_upgrade_plugin_settings(import_settings) |
172 | # Upgrade settings to prepare the import. |
173 | if import_settings.can_upgrade(): |
174 | @@ -929,7 +925,8 @@ |
175 | value = import_settings.value(section_key) |
176 | except KeyError: |
177 | value = None |
178 | - log.warning('The key "{key}" does not exist (anymore), so it will be skipped.'.format(key=section_key)) |
179 | + self.log_warning('The key "{key}" does not exist (anymore), so it will be skipped.'. |
180 | + format(key=section_key)) |
181 | if value is not None: |
182 | settings.setValue('{key}'.format(key=section_key), value) |
183 | now = datetime.now() |
184 | @@ -1013,7 +1010,6 @@ |
185 | """ |
186 | The screen has changed so we have to update components such as the renderer. |
187 | """ |
188 | - log.debug('screen_changed') |
189 | self.application.set_busy_cursor() |
190 | self.image_manager.update_display() |
191 | self.renderer.update_display() |
192 | @@ -1076,7 +1072,7 @@ |
193 | if Settings().value('advanced/save current plugin'): |
194 | Settings().setValue('advanced/current media plugin', self.media_tool_box.currentIndex()) |
195 | # Call the cleanup method to shutdown plugins. |
196 | - log.info('cleanup plugins') |
197 | + self.log_info('cleanup plugins') |
198 | self.plugin_manager.finalise_plugins() |
199 | if save_settings: |
200 | # Save settings |
201 | @@ -1216,7 +1212,6 @@ |
202 | """ |
203 | Load the main window settings. |
204 | """ |
205 | - log.debug('Loading QSettings') |
206 | settings = Settings() |
207 | # Remove obsolete entries. |
208 | settings.remove('custom slide') |
209 | @@ -1243,7 +1238,6 @@ |
210 | # Exit if we just did a settings import. |
211 | if self.settings_imported: |
212 | return |
213 | - log.debug('Saving QSettings') |
214 | settings = Settings() |
215 | settings.beginGroup(self.general_settings_section) |
216 | settings.setValue('recent files', self.recent_files) |
217 | @@ -1268,7 +1262,7 @@ |
218 | if not recent_path.is_file(): |
219 | continue |
220 | count += 1 |
221 | - log.debug('Recent file name: {name}'.format(name=recent_path)) |
222 | + self.log_debug('Recent file name: {name}'.format(name=recent_path)) |
223 | action = create_action(self, '', |
224 | text='&{n} {name}'.format(n=count, name=recent_path.name), |
225 | data=recent_path, triggers=self.service_manager_contents.on_recent_service_clicked) |
226 | @@ -1350,21 +1344,21 @@ |
227 | """ |
228 | Change the data directory. |
229 | """ |
230 | - log.info('Changing data path to {newpath}'.format(newpath=self.new_data_path)) |
231 | + self.log_info('Changing data path to {newpath}'.format(newpath=self.new_data_path)) |
232 | old_data_path = AppLocation.get_data_path() |
233 | # Copy OpenLP data to new location if requested. |
234 | self.application.set_busy_cursor() |
235 | if self.copy_data: |
236 | - log.info('Copying data to new path') |
237 | + self.log_info('Copying data to new path') |
238 | try: |
239 | self.show_status_message( |
240 | translate('OpenLP.MainWindow', 'Copying OpenLP data to new data directory location - {path} ' |
241 | '- Please wait for copy to finish').format(path=self.new_data_path)) |
242 | dir_util.copy_tree(str(old_data_path), str(self.new_data_path)) |
243 | - log.info('Copy successful') |
244 | + self.log_info('Copy successful') |
245 | except (OSError, DistutilsFileError) as why: |
246 | self.application.set_normal_cursor() |
247 | - log.exception('Data copy failed {err}'.format(err=str(why))) |
248 | + self.log_exception('Data copy failed {err}'.format(err=str(why))) |
249 | err_text = translate('OpenLP.MainWindow', |
250 | 'OpenLP Data directory copy failed\n\n{err}').format(err=str(why)), |
251 | QtWidgets.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'New Data Directory Error'), |
252 | @@ -1372,7 +1366,7 @@ |
253 | QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok)) |
254 | return False |
255 | else: |
256 | - log.info('No data copy requested') |
257 | + self.log_info('No data copy requested') |
258 | # Change the location of data directory in config file. |
259 | settings = QtCore.QSettings() |
260 | settings.setValue('advanced/data path', self.new_data_path) |
261 | |
262 | === modified file 'openlp/core/ui/servicemanager.py' |
263 | --- openlp/core/ui/servicemanager.py 2018-01-22 21:37:00 +0000 |
264 | +++ openlp/core/ui/servicemanager.py 2018-02-03 15:03:00 +0000 |
265 | @@ -302,7 +302,7 @@ |
266 | class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixin, RegistryProperties): |
267 | """ |
268 | Manages the services. This involves taking text strings from plugins and adding them to the service. This service |
269 | - can then be zipped up with all the resources used into one OSZ or oszl file for use on any OpenLP v2 installation. |
270 | + can then be zipped up with all the resources used into one OSZ or OSZL file for use on any OpenLP installation. |
271 | Also handles the UI tasks of moving things up and down etc. |
272 | """ |
273 | servicemanager_set_item = QtCore.pyqtSignal(int) |
274 | @@ -415,10 +415,9 @@ |
275 | if suffix not in self.suffixes: |
276 | self.suffixes.append(suffix) |
277 | |
278 | - def on_new_service_clicked(self, field=None): |
279 | + def on_new_service_clicked(self): |
280 | """ |
281 | Create a new service. |
282 | - :param field: |
283 | """ |
284 | if self.is_modified(): |
285 | result = self.save_modified_service() |
286 | @@ -466,10 +465,9 @@ |
287 | QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | |
288 | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Save) |
289 | |
290 | - def on_recent_service_clicked(self, field=None): |
291 | + def on_recent_service_clicked(self): |
292 | """ |
293 | Load a recent file as the service triggered by mainwindow recent service list. |
294 | - :param field: |
295 | """ |
296 | if self.is_modified(): |
297 | result = self.save_modified_service() |
298 | @@ -608,7 +606,7 @@ |
299 | self.set_modified(False) |
300 | return True |
301 | |
302 | - def save_file_as(self, field=None): |
303 | + def save_file_as(self): |
304 | """ |
305 | Get a file name and then call :func:`ServiceManager.save_file` to save the file. |
306 | """ |
307 | @@ -660,10 +658,9 @@ |
308 | self.set_file_name(file_path) |
309 | self.decide_save_method() |
310 | |
311 | - def decide_save_method(self, field=None): |
312 | + def decide_save_method(self): |
313 | """ |
314 | Determine which type of save method to use. |
315 | - :param field: |
316 | """ |
317 | if not self.file_name(): |
318 | return self.save_file_as() |
319 | @@ -824,10 +821,9 @@ |
320 | theme_action.setChecked(True) |
321 | self.menu.exec(self.service_manager_list.mapToGlobal(point)) |
322 | |
323 | - def on_service_item_note_form(self, field=None): |
324 | + def on_service_item_note_form(self): |
325 | """ |
326 | Allow the service note to be edited |
327 | - :param field: |
328 | """ |
329 | item = self.find_service_item()[0] |
330 | self.service_note_form.text_edit.setPlainText(self.service_items[item]['service_item'].notes) |
331 | @@ -836,21 +832,18 @@ |
332 | self.repaint_service_list(item, -1) |
333 | self.set_modified() |
334 | |
335 | - def on_start_time_form(self, field=None): |
336 | + def on_start_time_form(self): |
337 | """ |
338 | Opens a dialog to type in service item notes. |
339 | - :param field: |
340 | """ |
341 | item = self.find_service_item()[0] |
342 | self.start_time_form.item = self.service_items[item] |
343 | if self.start_time_form.exec(): |
344 | self.repaint_service_list(item, -1) |
345 | |
346 | - def toggle_auto_play_slides_once(self, field=None): |
347 | + def toggle_auto_play_slides_once(self): |
348 | """ |
349 | Toggle Auto play slide once. Inverts auto play once option for the item |
350 | - |
351 | - :param field: |
352 | """ |
353 | item = self.find_service_item()[0] |
354 | service_item = self.service_items[item]['service_item'] |
355 | @@ -863,11 +856,9 @@ |
356 | self.main_window.general_settings_section + '/loop delay') |
357 | self.set_modified() |
358 | |
359 | - def toggle_auto_play_slides_loop(self, field=None): |
360 | + def toggle_auto_play_slides_loop(self): |
361 | """ |
362 | Toggle Auto play slide loop. |
363 | - |
364 | - :param field: |
365 | """ |
366 | item = self.find_service_item()[0] |
367 | service_item = self.service_items[item]['service_item'] |
368 | @@ -880,10 +871,9 @@ |
369 | self.main_window.general_settings_section + '/loop delay') |
370 | self.set_modified() |
371 | |
372 | - def on_timed_slide_interval(self, field=None): |
373 | + def on_timed_slide_interval(self): |
374 | """ |
375 | Shows input dialog for enter interval in seconds for delay |
376 | - :param field: |
377 | """ |
378 | item = self.find_service_item()[0] |
379 | service_item = self.service_items[item]['service_item'] |
380 | @@ -906,7 +896,7 @@ |
381 | service_item.auto_play_slides_once = False |
382 | self.set_modified() |
383 | |
384 | - def on_auto_start(self, field=None): |
385 | + def on_auto_start(self): |
386 | """ |
387 | Toggles to Auto Start Setting. |
388 | """ |
389 | @@ -914,10 +904,9 @@ |
390 | self.service_items[item]['service_item'].will_auto_start = \ |
391 | not self.service_items[item]['service_item'].will_auto_start |
392 | |
393 | - def on_service_item_edit_form(self, field=None): |
394 | + def on_service_item_edit_form(self): |
395 | """ |
396 | Opens a dialog to edit the service item and update the service display if changes are saved. |
397 | - :param field: |
398 | """ |
399 | item = self.find_service_item()[0] |
400 | self.service_item_edit_form.set_service_item(self.service_items[item]['service_item']) |
401 | @@ -990,11 +979,9 @@ |
402 | prev_item_last_slide = service_iterator.value() |
403 | service_iterator += 1 |
404 | |
405 | - def on_set_item(self, message, field=None): |
406 | + def on_set_item(self, message): |
407 | """ |
408 | Called by a signal to select a specific item and make it live usually from remote. |
409 | - |
410 | - :param field: |
411 | :param message: The data passed in from a remove message |
412 | """ |
413 | self.log_debug(message) |
414 | @@ -1060,10 +1047,9 @@ |
415 | self.service_manager.collapsed(item.parent()) |
416 | self.service_manager_list.setCurrentItem(item.parent()) |
417 | |
418 | - def on_collapse_all(self, field=None): |
419 | + def on_collapse_all(self): |
420 | """ |
421 | Collapse all the service items. |
422 | - :param field: |
423 | """ |
424 | for item in self.service_items: |
425 | item['expanded'] = False |
426 | @@ -1080,10 +1066,9 @@ |
427 | if item.childCount(): |
428 | self.service_items[pos - 1]['expanded'] = False |
429 | |
430 | - def on_expand_all(self, field=None): |
431 | + def on_expand_all(self): |
432 | """ |
433 | Collapse all the service items. |
434 | - :param field: |
435 | """ |
436 | for item in self.service_items: |
437 | item['expanded'] = True |
438 | @@ -1100,10 +1085,9 @@ |
439 | if item.childCount(): |
440 | self.service_items[pos - 1]['expanded'] = True |
441 | |
442 | - def on_service_top(self, field=None): |
443 | + def on_service_top(self): |
444 | """ |
445 | Move the current ServiceItem to the top of the list. |
446 | - :param field: |
447 | """ |
448 | item, child = self.find_service_item() |
449 | if item < len(self.service_items) and item != -1: |
450 | @@ -1113,10 +1097,9 @@ |
451 | self.repaint_service_list(0, child) |
452 | self.set_modified() |
453 | |
454 | - def on_service_up(self, field=None): |
455 | + def on_service_up(self): |
456 | """ |
457 | Move the current ServiceItem one position up in the list. |
458 | - :param field: |
459 | """ |
460 | item, child = self.find_service_item() |
461 | if item > 0: |
462 | @@ -1126,10 +1109,9 @@ |
463 | self.repaint_service_list(item - 1, child) |
464 | self.set_modified() |
465 | |
466 | - def on_service_down(self, field=None): |
467 | + def on_service_down(self): |
468 | """ |
469 | Move the current ServiceItem one position down in the list. |
470 | - :param field: |
471 | """ |
472 | item, child = self.find_service_item() |
473 | if item < len(self.service_items) and item != -1: |
474 | @@ -1139,10 +1121,9 @@ |
475 | self.repaint_service_list(item + 1, child) |
476 | self.set_modified() |
477 | |
478 | - def on_service_end(self, field=None): |
479 | + def on_service_end(self): |
480 | """ |
481 | Move the current ServiceItem to the bottom of the list. |
482 | - :param field: |
483 | """ |
484 | item, child = self.find_service_item() |
485 | if item < len(self.service_items) and item != -1: |
486 | @@ -1152,7 +1133,7 @@ |
487 | self.repaint_service_list(len(self.service_items) - 1, child) |
488 | self.set_modified() |
489 | |
490 | - def on_delete_from_service(self, field=None): |
491 | + def on_delete_from_service(self): |
492 | """ |
493 | Remove the current ServiceItem from the list. |
494 | :param field: |
495 | @@ -1378,7 +1359,7 @@ |
496 | self.drop_position = -1 |
497 | self.set_modified() |
498 | |
499 | - def make_preview(self, field=None): |
500 | + def make_preview(self): |
501 | """ |
502 | Send the current item to the Preview slide controller |
503 | :param field: |
504 | @@ -1403,7 +1384,7 @@ |
505 | else: |
506 | return self.service_items[item]['service_item'] |
507 | |
508 | - def on_double_click_live(self, field=None): |
509 | + def on_double_click_live(self): |
510 | """ |
511 | Send the current item to the Live slide controller but triggered by a tablewidget click event. |
512 | :param field: |
513 | @@ -1411,7 +1392,7 @@ |
514 | self.list_double_clicked = True |
515 | self.make_live() |
516 | |
517 | - def on_single_click_preview(self, field=None): |
518 | + def on_single_click_preview(self): |
519 | """ |
520 | If single click previewing is enabled, and triggered by a tablewidget click event, |
521 | start a timeout to verify a double-click hasn't triggered. |
522 | @@ -1463,7 +1444,7 @@ |
523 | 'is missing or inactive')) |
524 | self.application.set_normal_cursor() |
525 | |
526 | - def remote_edit(self, field=None): |
527 | + def remote_edit(self): |
528 | """ |
529 | Triggers a remote edit to a plugin to allow item to be edited. |
530 | :param field: |
531 | @@ -1475,7 +1456,7 @@ |
532 | if new_item: |
533 | self.add_service_item(new_item, replace=True) |
534 | |
535 | - def on_service_item_rename(self, field=None): |
536 | + def on_service_item_rename(self): |
537 | """ |
538 | Opens a dialog to rename the service item. |
539 | |
540 | @@ -1493,7 +1474,7 @@ |
541 | self.repaint_service_list(item, -1) |
542 | self.set_modified() |
543 | |
544 | - def create_custom(self, field=None): |
545 | + def create_custom(self): |
546 | """ |
547 | Saves the current text item as a custom slide |
548 | :param field: |
549 | @@ -1613,7 +1594,7 @@ |
550 | self.renderer.set_service_theme(self.service_theme) |
551 | self.regenerate_service_items() |
552 | |
553 | - def on_theme_change_action(self, field=None): |
554 | + def on_theme_change_action(self): |
555 | """ |
556 | Handles theme change events |
557 | |
558 | |
559 | === modified file 'openlp/core/ui/slidecontroller.py' |
560 | --- openlp/core/ui/slidecontroller.py 2017-12-29 09:15:48 +0000 |
561 | +++ openlp/core/ui/slidecontroller.py 2018-02-03 15:03:00 +0000 |
562 | @@ -545,14 +545,14 @@ |
563 | self.on_theme_display(False) |
564 | self.on_hide_display(False) |
565 | |
566 | - def service_previous(self, field=None): |
567 | + def service_previous(self): |
568 | """ |
569 | Live event to select the previous service item from the service manager. |
570 | """ |
571 | self.keypress_queue.append(ServiceItemAction.Previous) |
572 | self._process_queue() |
573 | |
574 | - def service_next(self, field=None): |
575 | + def service_next(self): |
576 | """ |
577 | Live event to select the next service item from the service manager. |
578 | """ |
579 | @@ -1103,7 +1103,7 @@ |
580 | else: |
581 | Registry().execute('live_display_show') |
582 | |
583 | - def on_slide_selected(self, field=None): |
584 | + def on_slide_selected(self): |
585 | """ |
586 | Slide selected in controller |
587 | Note for some reason a dummy field is required. Nothing is passed! |
588 | @@ -1244,7 +1244,7 @@ |
589 | self.preview_widget.change_slide(row) |
590 | self.slide_selected() |
591 | |
592 | - def on_slide_selected_previous(self, field=None): |
593 | + def on_slide_selected_previous(self): |
594 | """ |
595 | Go to the previous slide. |
596 | """ |
597 | @@ -1372,7 +1372,7 @@ |
598 | if event.timerId() == self.timer_id: |
599 | self.on_slide_selected_next(self.play_slides_loop.isChecked()) |
600 | |
601 | - def on_edit_song(self, field=None): |
602 | + def on_edit_song(self): |
603 | """ |
604 | From the preview display requires the service Item to be editied |
605 | """ |
606 | @@ -1381,16 +1381,16 @@ |
607 | if new_item: |
608 | self.add_service_item(new_item) |
609 | |
610 | - def on_preview_add_to_service(self, field=None): |
611 | + def on_preview_add_to_service(self): |
612 | """ |
613 | From the preview display request the Item to be added to service |
614 | """ |
615 | if self.service_item: |
616 | self.service_manager.add_service_item(self.service_item) |
617 | |
618 | - def on_preview_double_click(self, field=None): |
619 | + def on_preview_double_click(self): |
620 | """ |
621 | - Triggered when a preview slide item is doubleclicked |
622 | + Triggered when a preview slide item is double clicked |
623 | """ |
624 | if self.service_item: |
625 | if Settings().value('advanced/double click live') and Settings().value('core/auto unblank'): |
626 | |
627 | === modified file 'openlp/plugins/bibles/lib/mediaitem.py' |
628 | --- openlp/plugins/bibles/lib/mediaitem.py 2017-12-29 09:15:48 +0000 |
629 | +++ openlp/plugins/bibles/lib/mediaitem.py 2018-02-03 15:03:00 +0000 |
630 | @@ -384,7 +384,7 @@ |
631 | This initialises the given bible, which means that its book names and their chapter numbers is added to the |
632 | combo boxes on the 'Select' Tab. This is not of any importance of the 'Search' Tab. |
633 | |
634 | - :param last_book_id: The "book reference id" of the book which is chosen at the moment. (int) |
635 | + :param last_book: The "book reference id" of the book which is chosen at the moment. (int) |
636 | :return: None |
637 | """ |
638 | log.debug('initialise_advanced_bible {bible}, {ref}'.format(bible=self.bible, ref=last_book)) |
639 | @@ -574,6 +574,7 @@ |
640 | Update the second bible. If changing from single to dual bible modes as if the user wants to clear the search |
641 | results, if not revert to the previously selected bible |
642 | |
643 | + :param: selection not required by part of the signature |
644 | :return: None |
645 | """ |
646 | new_selection = self.second_combo_box.currentData() |
647 | @@ -1005,14 +1006,17 @@ |
648 | }[self.settings.display_style] |
649 | return '{{su}}{bracket[0]}{verse_text}{bracket[1]}{{/su}} '.format(verse_text=verse_text, bracket=bracket) |
650 | |
651 | - def search(self, string, showError): |
652 | + def search(self, string, show_error=True): |
653 | """ |
654 | Search for some Bible verses (by reference). |
655 | + :param string: search string |
656 | + :param show_error: do we show the error |
657 | + :return: the results of the search |
658 | """ |
659 | if self.bible is None: |
660 | return [] |
661 | reference = self.plugin.manager.parse_ref(self.bible.name, string) |
662 | - search_results = self.plugin.manager.get_verses(self.bible.name, reference, showError) |
663 | + search_results = self.plugin.manager.get_verses(self.bible.name, reference, show_error) |
664 | if search_results: |
665 | verse_text = ' '.join([verse.text for verse in search_results]) |
666 | return [[string, verse_text]] |
667 | |
668 | === removed file 'openlp/plugins/presentations/lib/pptviewcontroller.py' |
669 | --- openlp/plugins/presentations/lib/pptviewcontroller.py 2017-12-29 09:15:48 +0000 |
670 | +++ openlp/plugins/presentations/lib/pptviewcontroller.py 1970-01-01 00:00:00 +0000 |
671 | @@ -1,307 +0,0 @@ |
672 | -# -*- coding: utf-8 -*- |
673 | -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
674 | - |
675 | -############################################################################### |
676 | -# OpenLP - Open Source Lyrics Projection # |
677 | -# --------------------------------------------------------------------------- # |
678 | -# Copyright (c) 2008-2018 OpenLP Developers # |
679 | -# --------------------------------------------------------------------------- # |
680 | -# This program is free software; you can redistribute it and/or modify it # |
681 | -# under the terms of the GNU General Public License as published by the Free # |
682 | -# Software Foundation; version 2 of the License. # |
683 | -# # |
684 | -# This program is distributed in the hope that it will be useful, but WITHOUT # |
685 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
686 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
687 | -# more details. # |
688 | -# # |
689 | -# You should have received a copy of the GNU General Public License along # |
690 | -# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
691 | -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
692 | -############################################################################### |
693 | -import logging |
694 | -import re |
695 | -import zipfile |
696 | -from xml.etree import ElementTree |
697 | - |
698 | -from openlp.core.common import is_win |
699 | -from openlp.core.common.applocation import AppLocation |
700 | -from openlp.core.display.screens import ScreenList |
701 | -from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument |
702 | - |
703 | -if is_win(): |
704 | - from ctypes import cdll |
705 | - from ctypes.wintypes import RECT |
706 | - |
707 | -log = logging.getLogger(__name__) |
708 | - |
709 | - |
710 | -class PptviewController(PresentationController): |
711 | - """ |
712 | - Class to control interactions with PowerPoint Viewer Presentations. It creates the runtime Environment , Loads the |
713 | - and Closes the Presentation. As well as triggering the correct activities based on the users input |
714 | - """ |
715 | - log.info('PPTViewController loaded') |
716 | - |
717 | - def __init__(self, plugin): |
718 | - """ |
719 | - Initialise the class |
720 | - """ |
721 | - log.debug('Initialising') |
722 | - self.process = None |
723 | - super(PptviewController, self).__init__(plugin, 'Powerpoint Viewer', PptviewDocument) |
724 | - self.supports = ['ppt', 'pps', 'pptx', 'ppsx', 'pptm'] |
725 | - |
726 | - def check_available(self): |
727 | - """ |
728 | - PPT Viewer is able to run on this machine. |
729 | - """ |
730 | - log.debug('check_available') |
731 | - if not is_win(): |
732 | - return False |
733 | - return self.check_installed() |
734 | - |
735 | - if is_win(): |
736 | - def check_installed(self): |
737 | - """ |
738 | - Check the viewer is installed. |
739 | - """ |
740 | - log.debug('Check installed') |
741 | - try: |
742 | - self.start_process() |
743 | - return self.process.CheckInstalled() |
744 | - except OSError: |
745 | - return False |
746 | - |
747 | - def start_process(self): |
748 | - """ |
749 | - Loads the PPTVIEWLIB library. |
750 | - """ |
751 | - if self.process: |
752 | - return |
753 | - log.debug('start PPTView') |
754 | - dll_path = AppLocation.get_directory(AppLocation.AppDir) \ |
755 | - / 'plugins' / 'presentations' / 'lib' / 'pptviewlib' / 'pptviewlib.dll' |
756 | - self.process = cdll.LoadLibrary(str(dll_path)) |
757 | - if log.isEnabledFor(logging.DEBUG): |
758 | - self.process.SetDebug(1) |
759 | - |
760 | - def kill(self): |
761 | - """ |
762 | - Called at system exit to clean up any running presentations |
763 | - """ |
764 | - log.debug('Kill pptviewer') |
765 | - while self.docs: |
766 | - self.docs[0].close_presentation() |
767 | - |
768 | - |
769 | -class PptviewDocument(PresentationDocument): |
770 | - """ |
771 | - Class which holds information and controls a single presentation. |
772 | - """ |
773 | - def __init__(self, controller, document_path): |
774 | - """ |
775 | - Constructor, store information about the file and initialise. |
776 | - |
777 | - :param openlp.core.common.path.Path document_path: File path to the document to load |
778 | - :rtype: None |
779 | - """ |
780 | - log.debug('Init Presentation PowerPoint') |
781 | - super().__init__(controller, document_path) |
782 | - self.presentation = None |
783 | - self.ppt_id = None |
784 | - self.blanked = False |
785 | - self.hidden = False |
786 | - |
787 | - def load_presentation(self): |
788 | - """ |
789 | - Called when a presentation is added to the SlideController. It builds the environment, starts communication with |
790 | - the background PptView task started earlier. |
791 | - """ |
792 | - log.debug('LoadPresentation') |
793 | - temp_path = self.get_temp_folder() |
794 | - size = ScreenList().current['size'] |
795 | - rect = RECT(size.x(), size.y(), size.right(), size.bottom()) |
796 | - preview_path = temp_path / 'slide' |
797 | - # Ensure that the paths are null terminated |
798 | - file_path_utf16 = str(self.file_path).encode('utf-16-le') + b'\0' |
799 | - preview_path_utf16 = str(preview_path).encode('utf-16-le') + b'\0' |
800 | - if not temp_path.is_dir(): |
801 | - temp_path.mkdir(parents=True) |
802 | - self.ppt_id = self.controller.process.OpenPPT(file_path_utf16, None, rect, preview_path_utf16) |
803 | - if self.ppt_id >= 0: |
804 | - self.create_thumbnails() |
805 | - self.stop_presentation() |
806 | - return True |
807 | - else: |
808 | - return False |
809 | - |
810 | - def create_thumbnails(self): |
811 | - """ |
812 | - PPTviewLib creates large BMP's, but we want small PNG's for consistency. Convert them here. |
813 | - """ |
814 | - log.debug('create_thumbnails') |
815 | - if self.check_thumbnails(): |
816 | - return |
817 | - log.debug('create_thumbnails proceeding') |
818 | - for idx in range(self.get_slide_count()): |
819 | - path = self.get_temp_folder() / 'slide{index:d}.bmp'.format(index=idx + 1) |
820 | - self.convert_thumbnail(path, idx + 1) |
821 | - |
822 | - def create_titles_and_notes(self): |
823 | - """ |
824 | - Extracts the titles and notes from the zipped file |
825 | - and writes the list of titles (one per slide) |
826 | - to 'titles.txt' |
827 | - and the notes to 'slideNotes[x].txt' |
828 | - in the thumbnails directory |
829 | - """ |
830 | - titles = None |
831 | - notes = None |
832 | - # let's make sure we have a valid zipped presentation |
833 | - if self.file_path.exists() and zipfile.is_zipfile(str(self.file_path)): |
834 | - namespaces = {"p": "http://schemas.openxmlformats.org/presentationml/2006/main", |
835 | - "a": "http://schemas.openxmlformats.org/drawingml/2006/main"} |
836 | - # open the file |
837 | - with zipfile.ZipFile(str(self.file_path)) as zip_file: |
838 | - # find the presentation.xml to get the slide count |
839 | - with zip_file.open('ppt/presentation.xml') as pres: |
840 | - tree = ElementTree.parse(pres) |
841 | - nodes = tree.getroot().findall(".//p:sldIdLst/p:sldId", namespaces=namespaces) |
842 | - # initialize the lists |
843 | - titles = ['' for i in range(len(nodes))] |
844 | - notes = ['' for i in range(len(nodes))] |
845 | - # loop thru the file list to find slides and notes |
846 | - for zip_info in zip_file.infolist(): |
847 | - node_type = '' |
848 | - index = -1 |
849 | - list_to_add = None |
850 | - # check if it is a slide |
851 | - match = re.search(r'slides/slide(.+)\.xml', zip_info.filename) |
852 | - if match: |
853 | - index = int(match.group(1)) - 1 |
854 | - node_type = 'ctrTitle' |
855 | - list_to_add = titles |
856 | - # or a note |
857 | - match = re.search(r'notesSlides/notesSlide(.+)\.xml', zip_info.filename) |
858 | - if match: |
859 | - index = int(match.group(1)) - 1 |
860 | - node_type = 'body' |
861 | - list_to_add = notes |
862 | - # if it is one of our files, index shouldn't be -1 |
863 | - if index >= 0: |
864 | - with zip_file.open(zip_info) as zipped_file: |
865 | - tree = ElementTree.parse(zipped_file) |
866 | - text = '' |
867 | - nodes = tree.getroot().findall(".//p:ph[@type='" + node_type + "']../../..//p:txBody//a:t", |
868 | - namespaces=namespaces) |
869 | - # if we found any content |
870 | - if nodes and len(nodes) > 0: |
871 | - for node in nodes: |
872 | - if len(text) > 0: |
873 | - text += '\n' |
874 | - text += node.text |
875 | - # Let's remove the \n from the titles and |
876 | - # just add one at the end |
877 | - if node_type == 'ctrTitle': |
878 | - text = text.replace('\n', ' ').replace('\x0b', ' ') + '\n' |
879 | - list_to_add[index] = text |
880 | - # now let's write the files |
881 | - self.save_titles_and_notes(titles, notes) |
882 | - |
883 | - def close_presentation(self): |
884 | - """ |
885 | - Close presentation and clean up objects. Triggered by new object being added to SlideController or OpenLP being |
886 | - shut down. |
887 | - """ |
888 | - log.debug('ClosePresentation') |
889 | - if self.controller.process: |
890 | - self.controller.process.ClosePPT(self.ppt_id) |
891 | - self.ppt_id = -1 |
892 | - self.controller.remove_doc(self) |
893 | - |
894 | - def is_loaded(self): |
895 | - """ |
896 | - Returns true if a presentation is loaded. |
897 | - """ |
898 | - if self.ppt_id < 0: |
899 | - return False |
900 | - if self.get_slide_count() < 0: |
901 | - return False |
902 | - return True |
903 | - |
904 | - def is_active(self): |
905 | - """ |
906 | - Returns true if a presentation is currently active. |
907 | - """ |
908 | - return self.is_loaded() and not self.hidden |
909 | - |
910 | - def blank_screen(self): |
911 | - """ |
912 | - Blanks the screen. |
913 | - """ |
914 | - self.controller.process.Blank(self.ppt_id) |
915 | - self.blanked = True |
916 | - |
917 | - def unblank_screen(self): |
918 | - """ |
919 | - Unblanks (restores) the presentation. |
920 | - """ |
921 | - self.controller.process.Unblank(self.ppt_id) |
922 | - self.blanked = False |
923 | - |
924 | - def is_blank(self): |
925 | - """ |
926 | - Returns true if screen is blank. |
927 | - """ |
928 | - log.debug('is blank OpenOffice') |
929 | - return self.blanked |
930 | - |
931 | - def stop_presentation(self): |
932 | - """ |
933 | - Stops the current presentation and hides the output. |
934 | - """ |
935 | - self.hidden = True |
936 | - self.controller.process.Stop(self.ppt_id) |
937 | - |
938 | - def start_presentation(self): |
939 | - """ |
940 | - Starts a presentation from the beginning. |
941 | - """ |
942 | - if self.hidden: |
943 | - self.hidden = False |
944 | - self.controller.process.Resume(self.ppt_id) |
945 | - else: |
946 | - self.controller.process.RestartShow(self.ppt_id) |
947 | - |
948 | - def get_slide_number(self): |
949 | - """ |
950 | - Returns the current slide number. |
951 | - """ |
952 | - return self.controller.process.GetCurrentSlide(self.ppt_id) |
953 | - |
954 | - def get_slide_count(self): |
955 | - """ |
956 | - Returns total number of slides. |
957 | - """ |
958 | - return self.controller.process.GetSlideCount(self.ppt_id) |
959 | - |
960 | - def goto_slide(self, slide_no): |
961 | - """ |
962 | - Moves to a specific slide in the presentation. |
963 | - |
964 | - :param slide_no: The slide the text is required for, starting at 1 |
965 | - """ |
966 | - self.controller.process.GotoSlide(self.ppt_id, slide_no) |
967 | - |
968 | - def next_step(self): |
969 | - """ |
970 | - Triggers the next effect of slide on the running presentation. |
971 | - """ |
972 | - self.controller.process.NextStep(self.ppt_id) |
973 | - |
974 | - def previous_step(self): |
975 | - """ |
976 | - Triggers the previous slide on the running presentation. |
977 | - """ |
978 | - self.controller.process.PrevStep(self.ppt_id) |
979 | |
980 | === removed directory 'openlp/plugins/presentations/lib/pptviewlib' |
981 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/README.TXT' |
982 | --- openlp/plugins/presentations/lib/pptviewlib/README.TXT 2017-12-29 09:15:48 +0000 |
983 | +++ openlp/plugins/presentations/lib/pptviewlib/README.TXT 1970-01-01 00:00:00 +0000 |
984 | @@ -1,121 +0,0 @@ |
985 | - |
986 | -PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org) |
987 | -Copyright (C) 2008-2018 Jonathan Corwin (j@corwin.co.uk) |
988 | - |
989 | -This library wrappers the free Microsoft PowerPoint Viewer (2003/2007) program, |
990 | -allowing it to be more easily controlled from another program. |
991 | - |
992 | -The PowerPoint Viewer must already be installed on the destination machine, and is |
993 | -freely available at microsoft.com. |
994 | - |
995 | -The full Microsoft Office PowerPoint and PowerPoint Viewer 97 have a COM interface allowing |
996 | -automation. This ability was removed from the 2003+ viewer offerings. |
997 | - |
998 | -To developers: I am not a C/C++ or Win32 API programmer as you can probably tell. |
999 | -The code and API of this DLL could certainly do with some tidying up, and the |
1000 | -error trapping, where it exists, is very basic. I'll happily accept patches! |
1001 | - |
1002 | -This library is covered by the GPL (http://www.gnu.org/licenses/) |
1003 | -It is NOT covered by the LGPL, so can only be used in GPL compatable programs. |
1004 | -(http://www.gnu.org/licenses/why-not-lgpl.html) |
1005 | - |
1006 | -This README.TXT must be distributed with the pptviewlib.dll |
1007 | - |
1008 | -This library has a limit of 50 PowerPoints which can be opened simultaneously. |
1009 | - |
1010 | -This project can be built with the free Microsoft Visual C++ 2008 Express Edition. |
1011 | - |
1012 | -USAGE |
1013 | ------ |
1014 | -BOOL CheckInstalled(void); |
1015 | - Returns TRUE if PowerPointViewer is installed. FALSE if not. |
1016 | - |
1017 | -int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); |
1018 | - |
1019 | - Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly |
1020 | - and creates preview images of each slide. Note PowerPoint Viewer only allows the |
1021 | - slideshow to be resized whilst it is being loaded. It can be moved at any time however. |
1022 | - |
1023 | - The only way to count the number of slides is to step through the entire show. Therefore |
1024 | - there will be a delay whilst opening large presentations for the first time. |
1025 | - For pre XP/2003 systems, the slideshow will flicker as the screen snapshots are taken. |
1026 | - |
1027 | - filename: The PowerPoint file to be opened. Full path |
1028 | - hParentWnd: The window which will become the parent of the slideshow window. |
1029 | - Can be NULL. |
1030 | - rect: The location/dimensions of the slideshow window. |
1031 | - If all properties of this structure are zero, the dimensions of the hParentWnd |
1032 | - are used. |
1033 | - previewpath If specified, the prefix to use for snapshot images of each slide, in the |
1034 | - form: previewpath + n + ".bmp", where n is the slide number. |
1035 | - A file called previewpath + "info.txt" will also be created containing information |
1036 | - about the PPT file, to speed up future openings of the unmodified file. |
1037 | - Note it is up the calling program to directly access these images if they |
1038 | - are required. |
1039 | - |
1040 | - RETURNS: An unique identifier to pass to other methods in this library. |
1041 | - If < 0, then the PPT failed to open. |
1042 | - If >=0, ClosePPT must be called when the PPT is no longer being used |
1043 | - or when the calling program is closed to release resources/hooks. |
1044 | - |
1045 | -void ClosePPT(int id); |
1046 | - Closes the presentation, releasing any resources and hooks. |
1047 | - |
1048 | - id: The value returned from OpenPPT. |
1049 | - |
1050 | -int GetCurrentSlide(int id); |
1051 | - Returns the current slide number (from 1) |
1052 | - |
1053 | - id: The value returned from OpenPPT. |
1054 | - |
1055 | -int GetSlideCount(int id); |
1056 | - Returns the total number of slides. |
1057 | - |
1058 | - id: The value returned from OpenPPT. |
1059 | - |
1060 | -void NextStep(int id); |
1061 | - Advances one step (animation) through the slideshow. |
1062 | - |
1063 | - id: The value returned from OpenPPT. |
1064 | - |
1065 | -void PrevStep(int id); |
1066 | - Goes backwards one step (animation) through the slideshow. |
1067 | - |
1068 | - id: The value returned from OpenPPT. |
1069 | - |
1070 | -void GotoSlide(int id, int slideno); |
1071 | - Goes directly to a specific slide in the slideshow |
1072 | - |
1073 | - id: The value returned from OpenPPT. |
1074 | - slideno: The number of the slide (from 1) to go directly to. |
1075 | - |
1076 | - If the slide has already been displayed, then the completed slide with animations performed |
1077 | - will be shown. This is how the PowerPoint Viewer works so have no control over this. |
1078 | - |
1079 | -void RestartShow(int id); |
1080 | - Restarts the show from the beginning. To reset animations, behind the scenes it |
1081 | - has to travel to the end and step backwards though the entire show. Therefore |
1082 | - for large presentations there might be a delay. |
1083 | - |
1084 | - id: The value returned from OpenPPT. |
1085 | - |
1086 | -void Blank(int id); |
1087 | - Blanks the screen, colour black. |
1088 | - |
1089 | - id: The value returned from OpenPPT. |
1090 | - |
1091 | -void Unblank(int id) |
1092 | - Unblanks the screen, restoring it to it's pre-blank state. |
1093 | - |
1094 | - id: The value returned from OpenPPT. |
1095 | - |
1096 | -void Stop(int id) |
1097 | - Moves the slideshow off the screen. (There is no concept of stop show in the PowerPoint Viewer) |
1098 | - |
1099 | - id: The value returned from OpenPPT. |
1100 | - |
1101 | -void Resume(int id) |
1102 | - Moves the slideshow display back onto the screen following a Stop() |
1103 | - |
1104 | - id: The value returned from OpenPPT. |
1105 | - |
1106 | |
1107 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/ppttest.py' |
1108 | --- openlp/plugins/presentations/lib/pptviewlib/ppttest.py 2017-12-29 09:15:48 +0000 |
1109 | +++ openlp/plugins/presentations/lib/pptviewlib/ppttest.py 1970-01-01 00:00:00 +0000 |
1110 | @@ -1,210 +0,0 @@ |
1111 | -# -*- coding: utf-8 -*- |
1112 | -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
1113 | - |
1114 | -############################################################################### |
1115 | -# OpenLP - Open Source Lyrics Projection # |
1116 | -# --------------------------------------------------------------------------- # |
1117 | -# Copyright (c) 2008-2018 OpenLP Developers # |
1118 | -# --------------------------------------------------------------------------- # |
1119 | -# This program is free software; you can redistribute it and/or modify it # |
1120 | -# under the terms of the GNU General Public License as published by the Free # |
1121 | -# Software Foundation; version 2 of the License. # |
1122 | -# # |
1123 | -# This program is distributed in the hope that it will be useful, but WITHOUT # |
1124 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
1125 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
1126 | -# more details. # |
1127 | -# # |
1128 | -# You should have received a copy of the GNU General Public License along # |
1129 | -# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
1130 | -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
1131 | -############################################################################### |
1132 | - |
1133 | -import sys |
1134 | -from ctypes import * |
1135 | -from ctypes.wintypes import RECT |
1136 | - |
1137 | -from PyQt5 import QtWidgets |
1138 | - |
1139 | - |
1140 | -class PPTViewer(QtWidgets.QWidget): |
1141 | - """ |
1142 | - Standalone Test Harness for the pptviewlib library |
1143 | - """ |
1144 | - def __init__(self, parent=None): |
1145 | - super(PPTViewer, self).__init__(parent) |
1146 | - self.pptid = -1 |
1147 | - self.setWindowTitle('PowerPoint Viewer Test') |
1148 | - |
1149 | - ppt_label = QtWidgets.QLabel('Open PowerPoint file') |
1150 | - slide_label = QtWidgets.QLabel('Go to slide #') |
1151 | - self.pptEdit = QtWidgets.QLineEdit() |
1152 | - self.slideEdit = QtWidgets.QLineEdit() |
1153 | - x_label = QtWidgets.QLabel('X pos') |
1154 | - y_label = QtWidgets.QLabel('Y pos') |
1155 | - width_label = QtWidgets.QLabel('Width') |
1156 | - height_label = QtWidgets.QLabel('Height') |
1157 | - self.xEdit = QtWidgets.QLineEdit('100') |
1158 | - self.yEdit = QtWidgets.QLineEdit('100') |
1159 | - self.widthEdit = QtWidgets.QLineEdit('900') |
1160 | - self.heightEdit = QtWidgets.QLineEdit('700') |
1161 | - self.total = QtWidgets.QLabel() |
1162 | - ppt_btn = QtWidgets.QPushButton('Open') |
1163 | - ppt_dlg_btn = QtWidgets.QPushButton('...') |
1164 | - folder_label = QtWidgets.QLabel('Slide .bmp path') |
1165 | - self.folderEdit = QtWidgets.QLineEdit('slide') |
1166 | - slide_btn = QtWidgets.QPushButton('Go') |
1167 | - prev = QtWidgets.QPushButton('Prev') |
1168 | - next = QtWidgets.QPushButton('Next') |
1169 | - blank = QtWidgets.QPushButton('Blank') |
1170 | - unblank = QtWidgets.QPushButton('Unblank') |
1171 | - restart = QtWidgets.QPushButton('Restart') |
1172 | - close = QtWidgets.QPushButton('Close') |
1173 | - resume = QtWidgets.QPushButton('Resume') |
1174 | - stop = QtWidgets.QPushButton('Stop') |
1175 | - grid = QtWidgets.QGridLayout() |
1176 | - row = 0 |
1177 | - grid.addWidget(folder_label, 0, 0) |
1178 | - grid.addWidget(self.folderEdit, 0, 1) |
1179 | - row += 1 |
1180 | - grid.addWidget(x_label, row, 0) |
1181 | - grid.addWidget(self.xEdit, row, 1) |
1182 | - grid.addWidget(y_label, row, 2) |
1183 | - grid.addWidget(self.yEdit, row, 3) |
1184 | - row += 1 |
1185 | - grid.addWidget(width_label, row, 0) |
1186 | - grid.addWidget(self.widthEdit, row, 1) |
1187 | - grid.addWidget(height_label, row, 2) |
1188 | - grid.addWidget(self.heightEdit, row, 3) |
1189 | - row += 1 |
1190 | - grid.addWidget(ppt_label, row, 0) |
1191 | - grid.addWidget(self.pptEdit, row, 1) |
1192 | - grid.addWidget(ppt_dlg_btn, row, 2) |
1193 | - grid.addWidget(ppt_btn, row, 3) |
1194 | - row += 1 |
1195 | - grid.addWidget(slide_label, row, 0) |
1196 | - grid.addWidget(self.slideEdit, row, 1) |
1197 | - grid.addWidget(slide_btn, row, 2) |
1198 | - row += 1 |
1199 | - grid.addWidget(prev, row, 0) |
1200 | - grid.addWidget(next, row, 1) |
1201 | - row += 1 |
1202 | - grid.addWidget(blank, row, 0) |
1203 | - grid.addWidget(unblank, row, 1) |
1204 | - row += 1 |
1205 | - grid.addWidget(restart, row, 0) |
1206 | - grid.addWidget(close, row, 1) |
1207 | - row += 1 |
1208 | - grid.addWidget(stop, row, 0) |
1209 | - grid.addWidget(resume, row, 1) |
1210 | - ppt_btn.clicked.connect(self.openClick) |
1211 | - ppt_dlg_btn.clicked.connect(self.openDialog) |
1212 | - slide_btn.clicked.connect(self.gotoClick) |
1213 | - prev.clicked.connect(self.prevClick) |
1214 | - next.clicked.connect(self.nextClick) |
1215 | - blank.clicked.connect(self.blankClick) |
1216 | - unblank.clicked.connect(self.unblankClick) |
1217 | - restart.clicked.connect(self.restartClick) |
1218 | - close.clicked.connect(self.closeClick) |
1219 | - stop.clicked.connect(self.stopClick) |
1220 | - resume.clicked.connect(self.resumeClick) |
1221 | - self.setLayout(grid) |
1222 | - self.resize(300, 150) |
1223 | - |
1224 | - def prevClick(self): |
1225 | - if self.pptid < 0: |
1226 | - return |
1227 | - self.pptdll.PrevStep(self.pptid) |
1228 | - self.updateCurrSlide() |
1229 | - app.processEvents() |
1230 | - |
1231 | - def nextClick(self): |
1232 | - if self.pptid < 0: |
1233 | - return |
1234 | - self.pptdll.NextStep(self.pptid) |
1235 | - self.updateCurrSlide() |
1236 | - app.processEvents() |
1237 | - |
1238 | - def blankClick(self): |
1239 | - if self.pptid < 0: |
1240 | - return |
1241 | - self.pptdll.Blank(self.pptid) |
1242 | - app.processEvents() |
1243 | - |
1244 | - def unblankClick(self): |
1245 | - if self.pptid < 0: |
1246 | - return |
1247 | - self.pptdll.Unblank(self.pptid) |
1248 | - app.processEvents() |
1249 | - |
1250 | - def restartClick(self): |
1251 | - if self.pptid < 0: |
1252 | - return |
1253 | - self.pptdll.RestartShow(self.pptid) |
1254 | - self.updateCurrSlide() |
1255 | - app.processEvents() |
1256 | - |
1257 | - def stopClick(self): |
1258 | - if self.pptid < 0: |
1259 | - return |
1260 | - self.pptdll.Stop(self.pptid) |
1261 | - app.processEvents() |
1262 | - |
1263 | - def resumeClick(self): |
1264 | - if self.pptid < 0: |
1265 | - return |
1266 | - self.pptdll.Resume(self.pptid) |
1267 | - app.processEvents() |
1268 | - |
1269 | - def closeClick(self): |
1270 | - if self.pptid < 0: |
1271 | - return |
1272 | - self.pptdll.ClosePPT(self.pptid) |
1273 | - self.pptid = -1 |
1274 | - app.processEvents() |
1275 | - |
1276 | - def openClick(self): |
1277 | - oldid = self.pptid |
1278 | - rect = RECT(int(self.xEdit.text()), int(self.yEdit.text()), |
1279 | - int(self.widthEdit.text()), int(self.heightEdit.text())) |
1280 | - filename = str(self.pptEdit.text().replace('/', '\\')) |
1281 | - folder = str(self.folderEdit.text().replace('/', '\\')) |
1282 | - print(filename, folder) |
1283 | - self.pptid = self.pptdll.OpenPPT(filename, None, rect, folder) |
1284 | - print('id: ' + str(self.pptid)) |
1285 | - if oldid >= 0: |
1286 | - self.pptdll.ClosePPT(oldid) |
1287 | - slides = self.pptdll.GetSlideCount(self.pptid) |
1288 | - print('slidecount: ' + str(slides)) |
1289 | - self.total.setNum(self.pptdll.GetSlideCount(self.pptid)) |
1290 | - self.updateCurrSlide() |
1291 | - |
1292 | - def updateCurrSlide(self): |
1293 | - if self.pptid < 0: |
1294 | - return |
1295 | - slide = str(self.pptdll.GetCurrentSlide(self.pptid)) |
1296 | - print('currslide: ' + slide) |
1297 | - self.slideEdit.setText(slide) |
1298 | - app.processEvents() |
1299 | - |
1300 | - def gotoClick(self): |
1301 | - if self.pptid < 0: |
1302 | - return |
1303 | - print(self.slideEdit.text()) |
1304 | - self.pptdll.GotoSlide(self.pptid, int(self.slideEdit.text())) |
1305 | - self.updateCurrSlide() |
1306 | - app.processEvents() |
1307 | - |
1308 | - def openDialog(self): |
1309 | - self.pptEdit.setText(QtWidgets.QFileDialog.getOpenFileName(self, 'Open file')[0]) |
1310 | - |
1311 | - |
1312 | -if __name__ == '__main__': |
1313 | - pptdll = cdll.LoadLibrary(r'pptviewlib.dll') |
1314 | - pptdll.SetDebug(1) |
1315 | - print('Begin...') |
1316 | - app = QtWidgets.QApplication(sys.argv) |
1317 | - window = PPTViewer() |
1318 | - window.pptdll = pptdll |
1319 | - window.show() |
1320 | - sys.exit(app.exec()) |
1321 | |
1322 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp' |
1323 | --- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp 2017-12-29 09:15:48 +0000 |
1324 | +++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp 1970-01-01 00:00:00 +0000 |
1325 | @@ -1,920 +0,0 @@ |
1326 | -/****************************************************************************** |
1327 | -* OpenLP - Open Source Lyrics Projection * |
1328 | -* --------------------------------------------------------------------------- * |
1329 | -* Copyright (c) 2008-2018 OpenLP Developers * |
1330 | -* --------------------------------------------------------------------------- * |
1331 | -* This program is free software; you can redistribute it and/or modify it * |
1332 | -* under the terms of the GNU General Public License as published by the Free * |
1333 | -* Software Foundation; version 2 of the License. * |
1334 | -* * |
1335 | -* This program is distributed in the hope that it will be useful, but WITHOUT * |
1336 | -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * |
1337 | -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * |
1338 | -* more details. * |
1339 | -* * |
1340 | -* You should have received a copy of the GNU General Public License along * |
1341 | -* with this program; if not, write to the Free Software Foundation, Inc., 59 * |
1342 | -* Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
1343 | -******************************************************************************/ |
1344 | - |
1345 | -#define WIN32_LEAN_AND_MEAN |
1346 | -#include <windows.h> |
1347 | -#include <string.h> |
1348 | -#include <stdlib.h> |
1349 | -#include <stdio.h> |
1350 | -#include <io.h> |
1351 | -#include <direct.h> |
1352 | -#include <time.h> |
1353 | -#include <sys/types.h> |
1354 | -#include <sys/stat.h> |
1355 | -#include "pptviewlib.h" |
1356 | - |
1357 | -// Because of the callbacks used by SetWindowsHookEx, the memory used needs to |
1358 | -// be sharable across processes (the callbacks are done from a different |
1359 | -// process) Therefore use data_seg with RWS memory. |
1360 | -// |
1361 | -// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for |
1362 | -// alternative method of holding memory, removing fixed limits which would allow |
1363 | -// dynamic number of items, rather than a fixed number. Use a Local\ mapping, |
1364 | -// since global has UAC issues in Vista. |
1365 | - |
1366 | -#pragma data_seg(".PPTVIEWLIB") |
1367 | -PPTVIEW pptView[MAX_PPTS] = {NULL}; |
1368 | -HHOOK globalHook = NULL; |
1369 | -BOOL debug = FALSE; |
1370 | -#pragma data_seg() |
1371 | -#pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS") |
1372 | - |
1373 | -HINSTANCE hInstance = NULL; |
1374 | - |
1375 | -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall, |
1376 | - LPVOID lpReserved) |
1377 | -{ |
1378 | - hInstance = (HINSTANCE)hModule; |
1379 | - switch(ulReasonForCall) |
1380 | - { |
1381 | - case DLL_PROCESS_ATTACH: |
1382 | - DEBUG(L"PROCESS_ATTACH\n"); |
1383 | - break; |
1384 | - case DLL_THREAD_ATTACH: |
1385 | - //DEBUG(L"THREAD_ATTACH\n"); |
1386 | - break; |
1387 | - case DLL_THREAD_DETACH: |
1388 | - //DEBUG(L"THREAD_DETACH\n"); |
1389 | - break; |
1390 | - case DLL_PROCESS_DETACH: |
1391 | - // Clean up... hopefully there is only the one process attached? |
1392 | - // We'll find out soon enough during tests! |
1393 | - DEBUG(L"PROCESS_DETACH\n"); |
1394 | - for (int i = 0; i < MAX_PPTS; i++) |
1395 | - ClosePPT(i); |
1396 | - break; |
1397 | - } |
1398 | - return TRUE; |
1399 | -} |
1400 | - |
1401 | -DllExport void SetDebug(BOOL onOff) |
1402 | -{ |
1403 | - printf("SetDebug\n"); |
1404 | - debug = onOff; |
1405 | - DEBUG(L"enabled\n"); |
1406 | -} |
1407 | - |
1408 | -DllExport BOOL CheckInstalled() |
1409 | -{ |
1410 | - wchar_t cmdLine[MAX_PATH * 2]; |
1411 | - |
1412 | - DEBUG(L"CheckInstalled\n"); |
1413 | - BOOL found = GetPPTViewerPath(cmdLine, sizeof(cmdLine)); |
1414 | - if(found) |
1415 | - { |
1416 | - DEBUG(L"Exe: %s\n", cmdLine); |
1417 | - } |
1418 | - return found; |
1419 | -} |
1420 | - |
1421 | -// Open the PointPoint, count the slides and take a snapshot of each slide |
1422 | -// for use in previews |
1423 | -// previewpath is a prefix for the location to put preview images of each slide. |
1424 | -// "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would |
1425 | -// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc. |
1426 | -// It will also create a *info.txt containing information about the ppt |
1427 | -DllExport int OpenPPT(wchar_t *filename, HWND hParentWnd, RECT rect, |
1428 | - wchar_t *previewPath) |
1429 | -{ |
1430 | - STARTUPINFO si; |
1431 | - PROCESS_INFORMATION pi; |
1432 | - wchar_t cmdLine[MAX_PATH * 2]; |
1433 | - int id; |
1434 | - |
1435 | - DEBUG(L"OpenPPT start: %s; %s\n", filename, previewPath); |
1436 | - DEBUG(L"OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, |
1437 | - rect.left, rect.bottom, rect.right); |
1438 | - if (GetPPTViewerPath(cmdLine, sizeof(cmdLine)) == FALSE) |
1439 | - { |
1440 | - DEBUG(L"OpenPPT: GetPPTViewerPath failed\n"); |
1441 | - return -1; |
1442 | - } |
1443 | - id = -1; |
1444 | - for (int i = 0; i < MAX_PPTS; i++) |
1445 | - { |
1446 | - if (pptView[i].state == PPT_CLOSED) |
1447 | - { |
1448 | - id = i; |
1449 | - break; |
1450 | - } |
1451 | - } |
1452 | - if (id < 0) |
1453 | - { |
1454 | - DEBUG(L"OpenPPT: Too many PPTs\n"); |
1455 | - return -1; |
1456 | - } |
1457 | - memset(&pptView[id], 0, sizeof(PPTVIEW)); |
1458 | - wcscpy_s(pptView[id].filename, MAX_PATH, filename); |
1459 | - wcscpy_s(pptView[id].previewPath, MAX_PATH, previewPath); |
1460 | - pptView[id].state = PPT_CLOSED; |
1461 | - pptView[id].slideCount = 0; |
1462 | - pptView[id].currentSlide = 0; |
1463 | - pptView[id].firstSlideSteps = 0; |
1464 | - pptView[id].lastSlideSteps = 0; |
1465 | - pptView[id].guess = 0; |
1466 | - pptView[id].hParentWnd = hParentWnd; |
1467 | - pptView[id].hWnd = NULL; |
1468 | - pptView[id].hWnd2 = NULL; |
1469 | - for (int i = 0; i < MAX_SLIDES; i++) |
1470 | - { |
1471 | - pptView[id].slideNos[i] = 0; |
1472 | - } |
1473 | - if (hParentWnd != NULL && rect.top == 0 && rect.bottom == 0 |
1474 | - && rect.left == 0 && rect.right == 0) |
1475 | - { |
1476 | - LPRECT windowRect = NULL; |
1477 | - GetWindowRect(hParentWnd, windowRect); |
1478 | - pptView[id].rect.top = 0; |
1479 | - pptView[id].rect.left = 0; |
1480 | - pptView[id].rect.bottom = windowRect->bottom - windowRect->top; |
1481 | - pptView[id].rect.right = windowRect->right - windowRect->left; |
1482 | - } |
1483 | - else |
1484 | - { |
1485 | - pptView[id].rect.top = rect.top; |
1486 | - pptView[id].rect.left = rect.left; |
1487 | - pptView[id].rect.bottom = rect.bottom; |
1488 | - pptView[id].rect.right = rect.right; |
1489 | - } |
1490 | - wcscat_s(cmdLine, MAX_PATH * 2, L" /F /S \""); |
1491 | - wcscat_s(cmdLine, MAX_PATH * 2, filename); |
1492 | - wcscat_s(cmdLine, MAX_PATH * 2, L"\""); |
1493 | - memset(&si, 0, sizeof(si)); |
1494 | - memset(&pi, 0, sizeof(pi)); |
1495 | - BOOL gotInfo = GetPPTInfo(id); |
1496 | - /* |
1497 | - * I'd really like to just hook on the new threadid. However this always |
1498 | - * gives error 87. Perhaps I'm hooking to soon? No idea... however can't |
1499 | - * wait since I need to ensure I pick up the WM_CREATE as this is the only |
1500 | - * time the window can be resized in such away the content scales correctly |
1501 | - * |
1502 | - * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); |
1503 | - */ |
1504 | - if (globalHook != NULL) |
1505 | - { |
1506 | - UnhookWindowsHookEx(globalHook); |
1507 | - } |
1508 | - globalHook = SetWindowsHookEx(WH_CBT, CbtProc, hInstance, NULL); |
1509 | - if (globalHook == 0) |
1510 | - { |
1511 | - DEBUG(L"OpenPPT: SetWindowsHookEx failed\n"); |
1512 | - ClosePPT(id); |
1513 | - return -1; |
1514 | - } |
1515 | - pptView[id].state = PPT_STARTED; |
1516 | - Sleep(10); |
1517 | - if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) |
1518 | - { |
1519 | - DEBUG(L"OpenPPT: CreateProcess failed: %s\n", cmdLine); |
1520 | - ClosePPT(id); |
1521 | - return -1; |
1522 | - } |
1523 | - pptView[id].dwProcessId = pi.dwProcessId; |
1524 | - pptView[id].dwThreadId = pi.dwThreadId; |
1525 | - pptView[id].hThread = pi.hThread; |
1526 | - pptView[id].hProcess = pi.hProcess; |
1527 | - while (pptView[id].state == PPT_STARTED) |
1528 | - Sleep(10); |
1529 | - if (gotInfo) |
1530 | - { |
1531 | - DEBUG(L"OpenPPT: Info loaded, no refresh\n"); |
1532 | - pptView[id].state = PPT_LOADED; |
1533 | - Resume(id); |
1534 | - } |
1535 | - else |
1536 | - { |
1537 | - DEBUG(L"OpenPPT: Get info\n"); |
1538 | - pptView[id].steps = 0; |
1539 | - int steps = 0; |
1540 | - while (pptView[id].state == PPT_OPENED) |
1541 | - { |
1542 | - if (steps <= pptView[id].steps) |
1543 | - { |
1544 | - Sleep(100); |
1545 | - DEBUG(L"OpenPPT: Step %d/%d\n", steps, pptView[id].steps); |
1546 | - steps++; |
1547 | - NextStep(id); |
1548 | - } |
1549 | - Sleep(10); |
1550 | - } |
1551 | - DEBUG(L"OpenPPT: Slides %d, Steps %d, first slide steps %d\n", |
1552 | - pptView[id].slideCount, pptView[id].steps, |
1553 | - pptView[id].firstSlideSteps); |
1554 | - for(int i = 1; i <= pptView[id].slideCount; i++) |
1555 | - { |
1556 | - DEBUG(L"OpenPPT: Slide %d = %d\n", i, pptView[id].slideNos[i]); |
1557 | - } |
1558 | - SavePPTInfo(id); |
1559 | - if (pptView[id].state == PPT_CLOSING |
1560 | - || pptView[id].slideCount <= 0) |
1561 | - { |
1562 | - ClosePPT(id); |
1563 | - id=-1; |
1564 | - } |
1565 | - else |
1566 | - { |
1567 | - RestartShow(id); |
1568 | - } |
1569 | - } |
1570 | - if (id >= 0) |
1571 | - { |
1572 | - if (pptView[id].msgHook != NULL) |
1573 | - { |
1574 | - UnhookWindowsHookEx(pptView[id].msgHook); |
1575 | - } |
1576 | - pptView[id].msgHook = NULL; |
1577 | - } |
1578 | - DEBUG(L"OpenPPT: Exit: id=%i\n", id); |
1579 | - return id; |
1580 | -} |
1581 | -// Load information about the ppt from an info.txt file. |
1582 | -// Format: |
1583 | -// version |
1584 | -// filedate |
1585 | -// filesize |
1586 | -// slidecount |
1587 | -// first slide steps |
1588 | -BOOL GetPPTInfo(int id) |
1589 | -{ |
1590 | - struct _stat fileStats; |
1591 | - wchar_t info[MAX_PATH]; |
1592 | - FILE* pFile; |
1593 | - wchar_t buf[100]; |
1594 | - |
1595 | - DEBUG(L"GetPPTInfo: start\n"); |
1596 | - if (_wstat(pptView[id].filename, &fileStats) != 0) |
1597 | - { |
1598 | - return FALSE; |
1599 | - } |
1600 | - swprintf_s(info, MAX_PATH, L"%sinfo.txt", pptView[id].previewPath); |
1601 | - int err = _wfopen_s(&pFile, info, L"r"); |
1602 | - if (err != 0) |
1603 | - { |
1604 | - DEBUG(L"GetPPTInfo: file open failed - %d\n", err); |
1605 | - return FALSE; |
1606 | - } |
1607 | - fgetws(buf, 100, pFile); // version == 1 |
1608 | - fgetws(buf, 100, pFile); |
1609 | - if (fileStats.st_mtime != _wtoi(buf)) |
1610 | - { |
1611 | - DEBUG(L"GetPPTInfo: date changed\n"); |
1612 | - fclose (pFile); |
1613 | - return FALSE; |
1614 | - } |
1615 | - fgetws(buf, 100, pFile); |
1616 | - if (fileStats.st_size != _wtoi(buf)) |
1617 | - { |
1618 | - DEBUG(L"GetPPTInfo: size changed\n"); |
1619 | - fclose (pFile); |
1620 | - return FALSE; |
1621 | - } |
1622 | - fgetws(buf, 100, pFile); // slidecount |
1623 | - int slideCount = _wtoi(buf); |
1624 | - fgetws(buf, 100, pFile); // first slide steps |
1625 | - int firstSlideSteps = _wtoi(buf); |
1626 | - // check all the preview images still exist |
1627 | - for (int i = 1; i <= slideCount; i++) |
1628 | - { |
1629 | - swprintf_s(info, MAX_PATH, L"%s%i.bmp", pptView[id].previewPath, i); |
1630 | - if (GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES) |
1631 | - { |
1632 | - DEBUG(L"GetPPTInfo: bmp not found\n"); |
1633 | - return FALSE; |
1634 | - } |
1635 | - } |
1636 | - fclose(pFile); |
1637 | - pptView[id].slideCount = slideCount; |
1638 | - pptView[id].firstSlideSteps = firstSlideSteps; |
1639 | - DEBUG(L"GetPPTInfo: exit ok\n"); |
1640 | - return TRUE; |
1641 | -} |
1642 | - |
1643 | -BOOL SavePPTInfo(int id) |
1644 | -{ |
1645 | - struct _stat fileStats; |
1646 | - wchar_t info[MAX_PATH]; |
1647 | - FILE* pFile; |
1648 | - |
1649 | - DEBUG(L"SavePPTInfo: start\n"); |
1650 | - if (_wstat(pptView[id].filename, &fileStats) != 0) |
1651 | - { |
1652 | - DEBUG(L"SavePPTInfo: stat of %s failed\n", pptView[id].filename); |
1653 | - return FALSE; |
1654 | - } |
1655 | - swprintf_s(info, MAX_PATH, L"%sinfo.txt", pptView[id].previewPath); |
1656 | - int err = _wfopen_s(&pFile, info, L"w"); |
1657 | - if (err != 0) |
1658 | - { |
1659 | - DEBUG(L"SavePPTInfo: fopen of %s failed%i\n", info, err); |
1660 | - return FALSE; |
1661 | - } |
1662 | - fprintf(pFile, "1\n"); |
1663 | - fprintf(pFile, "%u\n", fileStats.st_mtime); |
1664 | - fprintf(pFile, "%u\n", fileStats.st_size); |
1665 | - fprintf(pFile, "%u\n", pptView[id].slideCount); |
1666 | - fprintf(pFile, "%u\n", pptView[id].firstSlideSteps); |
1667 | - fclose(pFile); |
1668 | - DEBUG(L"SavePPTInfo: exit ok\n"); |
1669 | - return TRUE; |
1670 | -} |
1671 | - |
1672 | -// Get the path of the PowerPoint viewer from the registry |
1673 | -BOOL GetPPTViewerPath(wchar_t *pptViewerPath, int stringSize) |
1674 | -{ |
1675 | - wchar_t cwd[MAX_PATH]; |
1676 | - |
1677 | - DEBUG(L"GetPPTViewerPath: start\n"); |
1678 | - if(GetPPTViewerPathFromReg(pptViewerPath, stringSize)) |
1679 | - { |
1680 | - if(_waccess(pptViewerPath, 0) != -1) |
1681 | - { |
1682 | - DEBUG(L"GetPPTViewerPath: exit registry\n"); |
1683 | - return TRUE; |
1684 | - } |
1685 | - } |
1686 | - // This is where it gets ugly. PPT2007 it seems no longer stores its |
1687 | - // location in the registry. So we have to use the defaults which will |
1688 | - // upset those who like to put things somewhere else |
1689 | - |
1690 | - // Viewer 2007 in 64bit Windows: |
1691 | - if(_waccess(L"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE", |
1692 | - 0) != -1) |
1693 | - { |
1694 | - wcscpy_s( |
1695 | - L"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE", |
1696 | - stringSize, pptViewerPath); |
1697 | - DEBUG(L"GetPPTViewerPath: exit 64bit 2007\n"); |
1698 | - return TRUE; |
1699 | - } |
1700 | - // Viewer 2007 in 32bit Windows: |
1701 | - if(_waccess(L"C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE", 0) |
1702 | - != -1) |
1703 | - { |
1704 | - wcscpy_s(L"C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE", |
1705 | - stringSize, pptViewerPath); |
1706 | - DEBUG(L"GetPPTViewerPath: exit 32bit 2007\n"); |
1707 | - return TRUE; |
1708 | - } |
1709 | - // Give them the opportunity to place it in the same folder as the app |
1710 | - _wgetcwd(cwd, MAX_PATH); |
1711 | - wcscat_s(cwd, MAX_PATH, L"\\PPTVIEW.EXE"); |
1712 | - if(_waccess(cwd, 0) != -1) |
1713 | - { |
1714 | - wcscpy_s(pptViewerPath, stringSize, cwd); |
1715 | - DEBUG(L"GetPPTViewerPath: exit local\n"); |
1716 | - return TRUE; |
1717 | - } |
1718 | - DEBUG(L"GetPPTViewerPath: exit fail\n"); |
1719 | - return FALSE; |
1720 | -} |
1721 | -BOOL GetPPTViewerPathFromReg(wchar_t *pptViewerPath, int stringSize) |
1722 | -{ |
1723 | - HKEY hKey; |
1724 | - DWORD dwType, dwSize; |
1725 | - LRESULT lResult; |
1726 | - |
1727 | - // The following registry settings are for, respectively, (I think) |
1728 | - // PPT Viewer 2007 (older versions. Latest not in registry) & PPT Viewer 2010 |
1729 | - // PPT Viewer 2003 (recent versions) |
1730 | - // PPT Viewer 2003 (older versions) |
1731 | - // PPT Viewer 97 |
1732 | - if ((RegOpenKeyExW(HKEY_CLASSES_ROOT, |
1733 | - L"PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey) |
1734 | - != ERROR_SUCCESS) |
1735 | - && (RegOpenKeyExW(HKEY_CLASSES_ROOT, |
1736 | - L"PowerPointViewer.Show.11\\shell\\Show\\command", 0, KEY_READ, &hKey) |
1737 | - != ERROR_SUCCESS) |
1738 | - && (RegOpenKeyExW(HKEY_CLASSES_ROOT, |
1739 | - L"Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hKey) |
1740 | - != ERROR_SUCCESS) |
1741 | - && (RegOpenKeyExW(HKEY_CLASSES_ROOT, |
1742 | - L"Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hKey) |
1743 | - != ERROR_SUCCESS)) |
1744 | - { |
1745 | - return FALSE; |
1746 | - } |
1747 | - dwType = REG_SZ; |
1748 | - dwSize = (DWORD)stringSize; |
1749 | - lResult = RegQueryValueEx(hKey, NULL, NULL, &dwType, (LPBYTE)pptViewerPath, |
1750 | - &dwSize); |
1751 | - RegCloseKey(hKey); |
1752 | - if (lResult != ERROR_SUCCESS) |
1753 | - { |
1754 | - return FALSE; |
1755 | - } |
1756 | - // remove "%1" from end of key value |
1757 | - pptViewerPath[wcslen(pptViewerPath) - 4] = '\0'; |
1758 | - return TRUE; |
1759 | -} |
1760 | - |
1761 | -// Unhook the Windows hook |
1762 | -void Unhook(int id) |
1763 | -{ |
1764 | - DEBUG(L"Unhook: start %d\n", id); |
1765 | - if (pptView[id].hook != NULL) |
1766 | - { |
1767 | - UnhookWindowsHookEx(pptView[id].hook); |
1768 | - } |
1769 | - if (pptView[id].msgHook != NULL) |
1770 | - { |
1771 | - UnhookWindowsHookEx(pptView[id].msgHook); |
1772 | - } |
1773 | - pptView[id].hook = NULL; |
1774 | - pptView[id].msgHook = NULL; |
1775 | - DEBUG(L"Unhook: exit ok\n"); |
1776 | -} |
1777 | - |
1778 | -// Close the PowerPoint viewer, release resources |
1779 | -DllExport void ClosePPT(int id) |
1780 | -{ |
1781 | - DEBUG(L"ClosePPT: start%d\n", id); |
1782 | - pptView[id].state = PPT_CLOSED; |
1783 | - Unhook(id); |
1784 | - if (pptView[id].hWnd == 0) |
1785 | - { |
1786 | - TerminateThread(pptView[id].hThread, 0); |
1787 | - } |
1788 | - else |
1789 | - { |
1790 | - PostMessage(pptView[id].hWnd, WM_CLOSE, 0, 0); |
1791 | - } |
1792 | - CloseHandle(pptView[id].hThread); |
1793 | - CloseHandle(pptView[id].hProcess); |
1794 | - memset(&pptView[id], 0, sizeof(PPTVIEW)); |
1795 | - DEBUG(L"ClosePPT: exit ok\n"); |
1796 | - return; |
1797 | -} |
1798 | -// Moves the show back onto the display |
1799 | -DllExport void Resume(int id) |
1800 | -{ |
1801 | - DEBUG(L"Resume: %d\n", id); |
1802 | - MoveWindow(pptView[id].hWnd, pptView[id].rect.left, |
1803 | - pptView[id].rect.top, |
1804 | - pptView[id].rect.right - pptView[id].rect.left, |
1805 | - pptView[id].rect.bottom - pptView[id].rect.top, TRUE); |
1806 | - Unblank(id); |
1807 | -} |
1808 | -// Moves the show off the screen so it can't be seen |
1809 | -DllExport void Stop(int id) |
1810 | -{ |
1811 | - DEBUG(L"Stop:%d\n", id); |
1812 | - MoveWindow(pptView[id].hWnd, -32000, -32000, |
1813 | - pptView[id].rect.right - pptView[id].rect.left, |
1814 | - pptView[id].rect.bottom - pptView[id].rect.top, TRUE); |
1815 | -} |
1816 | - |
1817 | -// Return the total number of slides |
1818 | -DllExport int GetSlideCount(int id) |
1819 | -{ |
1820 | - DEBUG(L"GetSlideCount:%d\n", id); |
1821 | - if (pptView[id].state == 0) |
1822 | - { |
1823 | - return -1; |
1824 | - } |
1825 | - else |
1826 | - { |
1827 | - return pptView[id].slideCount; |
1828 | - } |
1829 | -} |
1830 | - |
1831 | -// Return the number of the slide currently viewing |
1832 | -DllExport int GetCurrentSlide(int id) |
1833 | -{ |
1834 | - DEBUG(L"GetCurrentSlide:%d\n", id); |
1835 | - if (pptView[id].state == 0) |
1836 | - { |
1837 | - return -1; |
1838 | - } |
1839 | - else |
1840 | - { |
1841 | - return pptView[id].currentSlide; |
1842 | - } |
1843 | -} |
1844 | - |
1845 | -// Take a step forwards through the show |
1846 | -DllExport void NextStep(int id) |
1847 | -{ |
1848 | - DEBUG(L"NextStep:%d (%d)\n", id, pptView[id].currentSlide); |
1849 | - if (pptView[id].currentSlide > pptView[id].slideCount) return; |
1850 | - if (pptView[id].currentSlide < pptView[id].slideCount) |
1851 | - { |
1852 | - pptView[id].guess = pptView[id].currentSlide + 1; |
1853 | - } |
1854 | - PostMessage(pptView[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), |
1855 | - 0); |
1856 | -} |
1857 | - |
1858 | -// Take a step backwards through the show |
1859 | -DllExport void PrevStep(int id) |
1860 | -{ |
1861 | - DEBUG(L"PrevStep:%d (%d)\n", id, pptView[id].currentSlide); |
1862 | - if (pptView[id].currentSlide > 1) |
1863 | - { |
1864 | - pptView[id].guess = pptView[id].currentSlide - 1; |
1865 | - } |
1866 | - PostMessage(pptView[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), |
1867 | - 0); |
1868 | -} |
1869 | - |
1870 | -// Blank the show (black screen) |
1871 | -DllExport void Blank(int id) |
1872 | -{ |
1873 | - // B just toggles blank on/off. However pressing any key unblanks. |
1874 | - // So send random unmapped letter first (say 'A'), then we can |
1875 | - // better guarantee B will blank instead of trying to guess |
1876 | - // whether it was already blank or not. |
1877 | - DEBUG(L"Blank:%d\n", id); |
1878 | - HWND h1 = GetForegroundWindow(); |
1879 | - HWND h2 = GetFocus(); |
1880 | - SetForegroundWindow(pptView[id].hWnd); |
1881 | - SetFocus(pptView[id].hWnd); |
1882 | - // slight pause, otherwise event triggering this call may grab focus back! |
1883 | - Sleep(50); |
1884 | - keybd_event((int)'A', 0, 0, 0); |
1885 | - keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0); |
1886 | - keybd_event((int)'B', 0, 0, 0); |
1887 | - keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0); |
1888 | - SetForegroundWindow(h1); |
1889 | - SetFocus(h2); |
1890 | -} |
1891 | -// Unblank the show |
1892 | -DllExport void Unblank(int id) |
1893 | -{ |
1894 | - DEBUG(L"Unblank:%d\n", id); |
1895 | - // Pressing any key resumes. |
1896 | - // For some reason SendMessage works for unblanking, but not blanking. |
1897 | - SendMessage(pptView[id].hWnd2, WM_CHAR, 'A', 0); |
1898 | -} |
1899 | - |
1900 | -// Go directly to a slide |
1901 | -DllExport void GotoSlide(int id, int slideNo) |
1902 | -{ |
1903 | - DEBUG(L"GotoSlide %i %i:\n", id, slideNo); |
1904 | - // Did try WM_KEYDOWN/WM_CHAR/WM_KEYUP with SendMessage but didn't work |
1905 | - // perhaps I was sending to the wrong window? No idea. |
1906 | - // Anyway fall back to keybd_event, which is OK as long we makesure |
1907 | - // the slideshow has focus first |
1908 | - char ch[10]; |
1909 | - |
1910 | - if (slideNo < 0) return; |
1911 | - pptView[id].guess = slideNo; |
1912 | - _itoa_s(slideNo, ch, 10, 10); |
1913 | - HWND h1 = GetForegroundWindow(); |
1914 | - HWND h2 = GetFocus(); |
1915 | - SetForegroundWindow(pptView[id].hWnd); |
1916 | - SetFocus(pptView[id].hWnd); |
1917 | - // slight pause, otherwise event triggering this call may grab focus back! |
1918 | - Sleep(50); |
1919 | - for (int i=0; i<10; i++) |
1920 | - { |
1921 | - if (ch[i] == '\0') break; |
1922 | - keybd_event((BYTE)ch[i], 0, 0, 0); |
1923 | - keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); |
1924 | - } |
1925 | - keybd_event(VK_RETURN, 0, 0, 0); |
1926 | - keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); |
1927 | - SetForegroundWindow(h1); |
1928 | - SetFocus(h2); |
1929 | -} |
1930 | - |
1931 | -// Restart the show from the beginning |
1932 | -DllExport void RestartShow(int id) |
1933 | -{ |
1934 | - // If we just go direct to slide one, then it remembers that all other |
1935 | - // slides have been animated, so ends up just showing the completed slides |
1936 | - // of those slides that have been animated next time we advance. |
1937 | - // Only way I've found to get around this is to step backwards all the way |
1938 | - // through. Lets move the window out of the way first so the audience |
1939 | - // doesn't see this. |
1940 | - DEBUG(L"RestartShow:%d\n", id); |
1941 | - Stop(id); |
1942 | - GotoSlide(id, pptView[id].slideCount); |
1943 | - for (int i=0; i <= pptView[id].steps - pptView[id].lastSlideSteps; i++) |
1944 | - { |
1945 | - PrevStep(id); |
1946 | - Sleep(10); |
1947 | - } |
1948 | - int i = 0; |
1949 | - while ((pptView[id].currentSlide > 1) && (i++ < 30000)) |
1950 | - { |
1951 | - Sleep(10); |
1952 | - } |
1953 | - Resume(id); |
1954 | -} |
1955 | - |
1956 | -// This hook is started with the PPTVIEW.EXE process and waits for the |
1957 | -// WM_CREATEWND message. At this point (and only this point) can the |
1958 | -// window be resized to the correct size. |
1959 | -// Release the hook as soon as we're complete to free up resources |
1960 | -LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) |
1961 | -{ |
1962 | - HHOOK hook = globalHook; |
1963 | - if (nCode == HCBT_CREATEWND) |
1964 | - { |
1965 | - wchar_t csClassName[32]; |
1966 | - HWND hCurrWnd = (HWND)wParam; |
1967 | - DWORD retProcId = NULL; |
1968 | - GetClassName(hCurrWnd, csClassName, sizeof(csClassName)); |
1969 | - if ((wcscmp(csClassName, L"paneClassDC") == 0) |
1970 | - ||(wcscmp(csClassName, L"screenClass") == 0)) |
1971 | - { |
1972 | - int id = -1; |
1973 | - DWORD windowThread = GetWindowThreadProcessId(hCurrWnd, NULL); |
1974 | - for (int i=0; i < MAX_PPTS; i++) |
1975 | - { |
1976 | - if (pptView[i].dwThreadId == windowThread) |
1977 | - { |
1978 | - id = i; |
1979 | - break; |
1980 | - } |
1981 | - } |
1982 | - if (id >= 0) |
1983 | - { |
1984 | - if (wcscmp(csClassName, L"paneClassDC") == 0) |
1985 | - { |
1986 | - pptView[id].hWnd2 = hCurrWnd; |
1987 | - } |
1988 | - else |
1989 | - { |
1990 | - pptView[id].hWnd = hCurrWnd; |
1991 | - CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; |
1992 | - if (pptView[id].hParentWnd != NULL) |
1993 | - { |
1994 | - cw->lpcs->hwndParent = pptView[id].hParentWnd; |
1995 | - } |
1996 | - cw->lpcs->cy = pptView[id].rect.bottom |
1997 | - - pptView[id].rect.top; |
1998 | - cw->lpcs->cx = pptView[id].rect.right |
1999 | - - pptView[id].rect.left; |
2000 | - cw->lpcs->y = -32000; |
2001 | - cw->lpcs->x = -32000; |
2002 | - } |
2003 | - if ((pptView[id].hWnd != NULL) && (pptView[id].hWnd2 != NULL)) |
2004 | - { |
2005 | - UnhookWindowsHookEx(globalHook); |
2006 | - globalHook = NULL; |
2007 | - pptView[id].hook = SetWindowsHookEx(WH_CALLWNDPROC, |
2008 | - CwpProc, hInstance, pptView[id].dwThreadId); |
2009 | - pptView[id].msgHook = SetWindowsHookEx(WH_GETMESSAGE, |
2010 | - GetMsgProc, hInstance, pptView[id].dwThreadId); |
2011 | - Sleep(10); |
2012 | - pptView[id].state = PPT_OPENED; |
2013 | - } |
2014 | - } |
2015 | - } |
2016 | - } |
2017 | - return CallNextHookEx(hook, nCode, wParam, lParam); |
2018 | -} |
2019 | - |
2020 | -// This hook exists whilst the slideshow is loading but only listens on the |
2021 | -// slideshows thread. It listens out for mousewheel events |
2022 | -LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) |
2023 | -{ |
2024 | - HHOOK hook = NULL; |
2025 | - MSG *pMSG = (MSG *)lParam; |
2026 | - DWORD windowThread = GetWindowThreadProcessId(pMSG->hwnd, NULL); |
2027 | - int id = -1; |
2028 | - for (int i = 0; i < MAX_PPTS; i++) |
2029 | - { |
2030 | - if (pptView[i].dwThreadId == windowThread) |
2031 | - { |
2032 | - id = i; |
2033 | - hook = pptView[id].msgHook; |
2034 | - break; |
2035 | - } |
2036 | - } |
2037 | - if (id >= 0 && nCode == HC_ACTION && wParam == PM_REMOVE |
2038 | - && pMSG->message == WM_MOUSEWHEEL) |
2039 | - { |
2040 | - if (pptView[id].state != PPT_LOADED) |
2041 | - { |
2042 | - if (pptView[id].currentSlide == 1) |
2043 | - { |
2044 | - pptView[id].firstSlideSteps++; |
2045 | - } |
2046 | - pptView[id].steps++; |
2047 | - pptView[id].lastSlideSteps++; |
2048 | - } |
2049 | - } |
2050 | - return CallNextHookEx(hook, nCode, wParam, lParam); |
2051 | -} |
2052 | -// This hook exists whilst the slideshow is running but only listens on the |
2053 | -// slideshows thread. It listens out for slide changes, message WM_USER+22. |
2054 | -LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ |
2055 | - CWPSTRUCT *cwp; |
2056 | - cwp = (CWPSTRUCT *)lParam; |
2057 | - HHOOK hook = NULL; |
2058 | - wchar_t filename[MAX_PATH]; |
2059 | - |
2060 | - DWORD windowThread = GetWindowThreadProcessId(cwp->hwnd, NULL); |
2061 | - int id = -1; |
2062 | - for (int i = 0; i < MAX_PPTS; i++) |
2063 | - { |
2064 | - if (pptView[i].dwThreadId == windowThread) |
2065 | - { |
2066 | - id = i; |
2067 | - hook = pptView[id].hook; |
2068 | - break; |
2069 | - } |
2070 | - } |
2071 | - if ((id >= 0) && (nCode == HC_ACTION)) |
2072 | - { |
2073 | - if (cwp->message == WM_USER + 22) |
2074 | - { |
2075 | - if (pptView[id].state != PPT_LOADED) |
2076 | - { |
2077 | - if ((pptView[id].currentSlide > 0) |
2078 | - && (pptView[id].previewPath != NULL |
2079 | - && wcslen(pptView[id].previewPath) > 0)) |
2080 | - { |
2081 | - swprintf_s(filename, MAX_PATH, L"%s%i.bmp", |
2082 | - pptView[id].previewPath, |
2083 | - pptView[id].currentSlide); |
2084 | - CaptureAndSaveWindow(cwp->hwnd, filename); |
2085 | - } |
2086 | - if (((cwp->wParam == 0) |
2087 | - || (pptView[id].slideNos[1] == cwp->wParam)) |
2088 | - && (pptView[id].currentSlide > 0)) |
2089 | - { |
2090 | - pptView[id].state = PPT_LOADED; |
2091 | - pptView[id].currentSlide = pptView[id].slideCount + 1; |
2092 | - } |
2093 | - else |
2094 | - { |
2095 | - if (cwp->wParam > 0) |
2096 | - { |
2097 | - pptView[id].currentSlide = pptView[id].currentSlide + 1; |
2098 | - pptView[id].slideNos[pptView[id].currentSlide] |
2099 | - = cwp->wParam; |
2100 | - pptView[id].slideCount = pptView[id].currentSlide; |
2101 | - pptView[id].lastSlideSteps = 0; |
2102 | - } |
2103 | - } |
2104 | - } |
2105 | - else |
2106 | - { |
2107 | - if (cwp->wParam > 0) |
2108 | - { |
2109 | - if(pptView[id].guess > 0 |
2110 | - && pptView[id].slideNos[pptView[id].guess] == 0) |
2111 | - { |
2112 | - pptView[id].currentSlide = 0; |
2113 | - } |
2114 | - for(int i = 1; i <= pptView[id].slideCount; i++) |
2115 | - { |
2116 | - if(pptView[id].slideNos[i] == cwp->wParam) |
2117 | - { |
2118 | - pptView[id].currentSlide = i; |
2119 | - break; |
2120 | - } |
2121 | - } |
2122 | - if(pptView[id].currentSlide == 0) |
2123 | - { |
2124 | - pptView[id].slideNos[pptView[id].guess] = cwp->wParam; |
2125 | - pptView[id].currentSlide = pptView[id].guess; |
2126 | - } |
2127 | - pptView[id].guess = 0; |
2128 | - } |
2129 | - } |
2130 | - } |
2131 | - if ((pptView[id].state != PPT_CLOSED) |
2132 | - |
2133 | - &&(cwp->message == WM_CLOSE || cwp->message == WM_QUIT)) |
2134 | - { |
2135 | - pptView[id].state = PPT_CLOSING; |
2136 | - } |
2137 | - } |
2138 | - return CallNextHookEx(hook, nCode, wParam, lParam); |
2139 | -} |
2140 | - |
2141 | -VOID CaptureAndSaveWindow(HWND hWnd, wchar_t* filename) |
2142 | -{ |
2143 | - HBITMAP hBmp; |
2144 | - if ((hBmp = CaptureWindow(hWnd)) == NULL) |
2145 | - { |
2146 | - return; |
2147 | - } |
2148 | - RECT client; |
2149 | - GetClientRect(hWnd, &client); |
2150 | - UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits |
2151 | - UINT uiRemainderForPadding; |
2152 | - |
2153 | - if ((uiRemainderForPadding = uiBytesPerRow % sizeof(DWORD)) > 0) |
2154 | - uiBytesPerRow += (sizeof(DWORD) - uiRemainderForPadding); |
2155 | - |
2156 | - UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; |
2157 | - PBYTE pDataBits; |
2158 | - |
2159 | - if ((pDataBits = new BYTE[uiBytesPerAllRows]) != NULL) |
2160 | - { |
2161 | - BITMAPINFOHEADER bmi = {0}; |
2162 | - BITMAPFILEHEADER bmf = {0}; |
2163 | - |
2164 | - // Prepare to get the data out of HBITMAP: |
2165 | - bmi.biSize = sizeof(bmi); |
2166 | - bmi.biPlanes = 1; |
2167 | - bmi.biBitCount = 24; |
2168 | - bmi.biHeight = client.bottom; |
2169 | - bmi.biWidth = client.right; |
2170 | - |
2171 | - // Get it: |
2172 | - HDC hDC = GetDC(hWnd); |
2173 | - GetDIBits(hDC, hBmp, 0, client.bottom, pDataBits, (BITMAPINFO*) &bmi, |
2174 | - DIB_RGB_COLORS); |
2175 | - ReleaseDC(hWnd, hDC); |
2176 | - |
2177 | - // Fill the file header: |
2178 | - bmf.bfOffBits = sizeof(bmf) + sizeof(bmi); |
2179 | - bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; |
2180 | - bmf.bfType = 0x4D42; |
2181 | - |
2182 | - // Writing: |
2183 | - FILE* pFile; |
2184 | - int err = _wfopen_s(&pFile, filename, L"wb"); |
2185 | - if (err == 0) |
2186 | - { |
2187 | - fwrite(&bmf, sizeof(bmf), 1, pFile); |
2188 | - fwrite(&bmi, sizeof(bmi), 1, pFile); |
2189 | - fwrite(pDataBits, sizeof(BYTE), uiBytesPerAllRows, pFile); |
2190 | - fclose(pFile); |
2191 | - } |
2192 | - delete [] pDataBits; |
2193 | - } |
2194 | - DeleteObject(hBmp); |
2195 | -} |
2196 | -HBITMAP CaptureWindow(HWND hWnd) |
2197 | -{ |
2198 | - HDC hDC; |
2199 | - BOOL bOk = FALSE; |
2200 | - HBITMAP hImage = NULL; |
2201 | - |
2202 | - hDC = GetDC(hWnd); |
2203 | - RECT rcClient; |
2204 | - GetClientRect(hWnd, &rcClient); |
2205 | - if ((hImage = CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom)) |
2206 | - != NULL) |
2207 | - { |
2208 | - HDC hMemDC; |
2209 | - HBITMAP hDCBmp; |
2210 | - |
2211 | - if ((hMemDC = CreateCompatibleDC(hDC)) != NULL) |
2212 | - { |
2213 | - hDCBmp = (HBITMAP)SelectObject(hMemDC, hImage); |
2214 | - HMODULE hLib = LoadLibrary(L"User32"); |
2215 | - // PrintWindow works for windows outside displayable area |
2216 | - // but was only introduced in WinXP. BitBlt requires the window to |
2217 | - // be topmost and within the viewable area of the display |
2218 | - if (GetProcAddress(hLib, "PrintWindow") == NULL) |
2219 | - { |
2220 | - SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); |
2221 | - BitBlt(hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, |
2222 | - 0, SRCCOPY); |
2223 | - SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, |
2224 | - SWP_NOSIZE); |
2225 | - } |
2226 | - else |
2227 | - { |
2228 | - PrintWindow(hWnd, hMemDC, 0); |
2229 | - } |
2230 | - SelectObject(hMemDC, hDCBmp); |
2231 | - DeleteDC(hMemDC); |
2232 | - bOk = TRUE; |
2233 | - } |
2234 | - } |
2235 | - ReleaseDC(hWnd, hDC); |
2236 | - if (!bOk) |
2237 | - { |
2238 | - if (hImage) |
2239 | - { |
2240 | - DeleteObject(hImage); |
2241 | - hImage = NULL; |
2242 | - } |
2243 | - } |
2244 | - return hImage; |
2245 | -} |
2246 | |
2247 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h' |
2248 | --- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h 2017-12-29 09:15:48 +0000 |
2249 | +++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h 1970-01-01 00:00:00 +0000 |
2250 | @@ -1,80 +0,0 @@ |
2251 | -/****************************************************************************** |
2252 | -* OpenLP - Open Source Lyrics Projection * |
2253 | -* --------------------------------------------------------------------------- * |
2254 | -* Copyright (c) 2008-2018 OpenLP Developers * |
2255 | -* --------------------------------------------------------------------------- * |
2256 | -* This program is free software; you can redistribute it and/or modify it * |
2257 | -* under the terms of the GNU General Public License as published by the Free * |
2258 | -* Software Foundation; version 2 of the License. * |
2259 | -* * |
2260 | -* This program is distributed in the hope that it will be useful, but WITHOUT * |
2261 | -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * |
2262 | -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * |
2263 | -* more details. * |
2264 | -* * |
2265 | -* You should have received a copy of the GNU General Public License along * |
2266 | -* with this program; if not, write to the Free Software Foundation, Inc., 59 * |
2267 | -* Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
2268 | -******************************************************************************/ |
2269 | - |
2270 | -#define DllExport extern "C" __declspec( dllexport ) |
2271 | - |
2272 | -#define DEBUG(...) if (debug) wprintf(__VA_ARGS__) |
2273 | - |
2274 | -enum PPTVIEWSTATE {PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, |
2275 | - PPT_CLOSING}; |
2276 | - |
2277 | -DllExport int OpenPPT(wchar_t *filename, HWND hParentWnd, RECT rect, |
2278 | - wchar_t *previewPath); |
2279 | -DllExport BOOL CheckInstalled(); |
2280 | -DllExport void ClosePPT(int id); |
2281 | -DllExport int GetCurrentSlide(int id); |
2282 | -DllExport int GetSlideCount(int id); |
2283 | -DllExport void NextStep(int id); |
2284 | -DllExport void PrevStep(int id); |
2285 | -DllExport void GotoSlide(int id, int slide_no); |
2286 | -DllExport void RestartShow(int id); |
2287 | -DllExport void Blank(int id); |
2288 | -DllExport void Unblank(int id); |
2289 | -DllExport void Stop(int id); |
2290 | -DllExport void Resume(int id); |
2291 | -DllExport void SetDebug(BOOL onOff); |
2292 | - |
2293 | -LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam); |
2294 | -LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam); |
2295 | -LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam); |
2296 | -BOOL GetPPTViewerPath(wchar_t *pptViewerPath, int stringSize); |
2297 | -BOOL GetPPTViewerPathFromReg(wchar_t *pptViewerPath, int stringSize); |
2298 | -HBITMAP CaptureWindow(HWND hWnd); |
2299 | -VOID SaveBitmap(wchar_t* filename, HBITMAP hBmp) ; |
2300 | -VOID CaptureAndSaveWindow(HWND hWnd, wchar_t* filename); |
2301 | -BOOL GetPPTInfo(int id); |
2302 | -BOOL SavePPTInfo(int id); |
2303 | -void Unhook(int id); |
2304 | - |
2305 | -#define MAX_PPTS 16 |
2306 | -#define MAX_SLIDES 256 |
2307 | - |
2308 | -struct PPTVIEW |
2309 | -{ |
2310 | - HHOOK hook; |
2311 | - HHOOK msgHook; |
2312 | - HWND hWnd; |
2313 | - HWND hWnd2; |
2314 | - HWND hParentWnd; |
2315 | - HANDLE hProcess; |
2316 | - HANDLE hThread; |
2317 | - DWORD dwProcessId; |
2318 | - DWORD dwThreadId; |
2319 | - RECT rect; |
2320 | - int slideCount; |
2321 | - int currentSlide; |
2322 | - int firstSlideSteps; |
2323 | - int lastSlideSteps; |
2324 | - int steps; |
2325 | - int guess; |
2326 | - wchar_t filename[MAX_PATH]; |
2327 | - wchar_t previewPath[MAX_PATH]; |
2328 | - int slideNos[MAX_SLIDES]; |
2329 | - PPTVIEWSTATE state; |
2330 | -}; |
2331 | |
2332 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj' |
2333 | --- openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj 2013-11-16 10:16:06 +0000 |
2334 | +++ openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj 1970-01-01 00:00:00 +0000 |
2335 | @@ -1,202 +0,0 @@ |
2336 | -<?xml version="1.0" encoding="Windows-1252"?> |
2337 | -<VisualStudioProject |
2338 | - ProjectType="Visual C++" |
2339 | - Version="9.00" |
2340 | - Name="pptviewlib" |
2341 | - ProjectGUID="{04CC20D1-DC5A-4189-8181-4011E3C21DCF}" |
2342 | - RootNamespace="pptviewlib" |
2343 | - Keyword="Win32Proj" |
2344 | - TargetFrameworkVersion="196613" |
2345 | - > |
2346 | - <Platforms> |
2347 | - <Platform |
2348 | - Name="Win32" |
2349 | - /> |
2350 | - </Platforms> |
2351 | - <ToolFiles> |
2352 | - </ToolFiles> |
2353 | - <Configurations> |
2354 | - <Configuration |
2355 | - Name="Debug|Win32" |
2356 | - OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
2357 | - IntermediateDirectory="$(ConfigurationName)" |
2358 | - ConfigurationType="2" |
2359 | - CharacterSet="1" |
2360 | - > |
2361 | - <Tool |
2362 | - Name="VCPreBuildEventTool" |
2363 | - /> |
2364 | - <Tool |
2365 | - Name="VCCustomBuildTool" |
2366 | - /> |
2367 | - <Tool |
2368 | - Name="VCXMLDataGeneratorTool" |
2369 | - /> |
2370 | - <Tool |
2371 | - Name="VCWebServiceProxyGeneratorTool" |
2372 | - /> |
2373 | - <Tool |
2374 | - Name="VCMIDLTool" |
2375 | - /> |
2376 | - <Tool |
2377 | - Name="VCCLCompilerTool" |
2378 | - Optimization="0" |
2379 | - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS" |
2380 | - MinimalRebuild="true" |
2381 | - BasicRuntimeChecks="3" |
2382 | - RuntimeLibrary="3" |
2383 | - UsePrecompiledHeader="0" |
2384 | - WarningLevel="3" |
2385 | - DebugInformationFormat="4" |
2386 | - /> |
2387 | - <Tool |
2388 | - Name="VCManagedResourceCompilerTool" |
2389 | - /> |
2390 | - <Tool |
2391 | - Name="VCResourceCompilerTool" |
2392 | - /> |
2393 | - <Tool |
2394 | - Name="VCPreLinkEventTool" |
2395 | - /> |
2396 | - <Tool |
2397 | - Name="VCLinkerTool" |
2398 | - LinkIncremental="2" |
2399 | - ModuleDefinitionFile="" |
2400 | - GenerateDebugInformation="true" |
2401 | - SubSystem="2" |
2402 | - TargetMachine="1" |
2403 | - /> |
2404 | - <Tool |
2405 | - Name="VCALinkTool" |
2406 | - /> |
2407 | - <Tool |
2408 | - Name="VCManifestTool" |
2409 | - /> |
2410 | - <Tool |
2411 | - Name="VCXDCMakeTool" |
2412 | - /> |
2413 | - <Tool |
2414 | - Name="VCBscMakeTool" |
2415 | - /> |
2416 | - <Tool |
2417 | - Name="VCFxCopTool" |
2418 | - /> |
2419 | - <Tool |
2420 | - Name="VCAppVerifierTool" |
2421 | - /> |
2422 | - <Tool |
2423 | - Name="VCPostBuildEventTool" |
2424 | - /> |
2425 | - </Configuration> |
2426 | - <Configuration |
2427 | - Name="Release|Win32" |
2428 | - OutputDirectory="$(SolutionDir)$(ConfigurationName)" |
2429 | - IntermediateDirectory="$(ConfigurationName)" |
2430 | - ConfigurationType="2" |
2431 | - CharacterSet="1" |
2432 | - WholeProgramOptimization="1" |
2433 | - > |
2434 | - <Tool |
2435 | - Name="VCPreBuildEventTool" |
2436 | - /> |
2437 | - <Tool |
2438 | - Name="VCCustomBuildTool" |
2439 | - /> |
2440 | - <Tool |
2441 | - Name="VCXMLDataGeneratorTool" |
2442 | - /> |
2443 | - <Tool |
2444 | - Name="VCWebServiceProxyGeneratorTool" |
2445 | - /> |
2446 | - <Tool |
2447 | - Name="VCMIDLTool" |
2448 | - /> |
2449 | - <Tool |
2450 | - Name="VCCLCompilerTool" |
2451 | - Optimization="2" |
2452 | - EnableIntrinsicFunctions="true" |
2453 | - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS" |
2454 | - RuntimeLibrary="2" |
2455 | - EnableFunctionLevelLinking="true" |
2456 | - UsePrecompiledHeader="0" |
2457 | - WarningLevel="3" |
2458 | - DebugInformationFormat="3" |
2459 | - /> |
2460 | - <Tool |
2461 | - Name="VCManagedResourceCompilerTool" |
2462 | - /> |
2463 | - <Tool |
2464 | - Name="VCResourceCompilerTool" |
2465 | - /> |
2466 | - <Tool |
2467 | - Name="VCPreLinkEventTool" |
2468 | - /> |
2469 | - <Tool |
2470 | - Name="VCLinkerTool" |
2471 | - LinkIncremental="1" |
2472 | - GenerateDebugInformation="true" |
2473 | - SubSystem="2" |
2474 | - OptimizeReferences="2" |
2475 | - EnableCOMDATFolding="2" |
2476 | - TargetMachine="1" |
2477 | - /> |
2478 | - <Tool |
2479 | - Name="VCALinkTool" |
2480 | - /> |
2481 | - <Tool |
2482 | - Name="VCManifestTool" |
2483 | - /> |
2484 | - <Tool |
2485 | - Name="VCXDCMakeTool" |
2486 | - /> |
2487 | - <Tool |
2488 | - Name="VCBscMakeTool" |
2489 | - /> |
2490 | - <Tool |
2491 | - Name="VCFxCopTool" |
2492 | - /> |
2493 | - <Tool |
2494 | - Name="VCAppVerifierTool" |
2495 | - /> |
2496 | - <Tool |
2497 | - Name="VCPostBuildEventTool" |
2498 | - /> |
2499 | - </Configuration> |
2500 | - </Configurations> |
2501 | - <References> |
2502 | - </References> |
2503 | - <Files> |
2504 | - <Filter |
2505 | - Name="Source Files" |
2506 | - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" |
2507 | - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" |
2508 | - > |
2509 | - <File |
2510 | - RelativePath=".\pptviewlib.cpp" |
2511 | - > |
2512 | - </File> |
2513 | - <File |
2514 | - RelativePath=".\README.TXT" |
2515 | - > |
2516 | - </File> |
2517 | - </Filter> |
2518 | - <Filter |
2519 | - Name="Header Files" |
2520 | - Filter="h;hpp;hxx;hm;inl;inc;xsd" |
2521 | - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" |
2522 | - > |
2523 | - <File |
2524 | - RelativePath=".\pptviewlib.h" |
2525 | - > |
2526 | - </File> |
2527 | - </Filter> |
2528 | - <Filter |
2529 | - Name="Resource Files" |
2530 | - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" |
2531 | - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" |
2532 | - > |
2533 | - </Filter> |
2534 | - </Files> |
2535 | - <Globals> |
2536 | - </Globals> |
2537 | -</VisualStudioProject> |
2538 | |
2539 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/test.ppt' |
2540 | Binary files openlp/plugins/presentations/lib/pptviewlib/test.ppt 2010-09-14 18:18:47 +0000 and openlp/plugins/presentations/lib/pptviewlib/test.ppt 1970-01-01 00:00:00 +0000 differ |
2541 | === removed file 'openlp/plugins/presentations/lib/pptviewlib/test.pptx' |
2542 | Binary files openlp/plugins/presentations/lib/pptviewlib/test.pptx 2013-10-17 19:31:17 +0000 and openlp/plugins/presentations/lib/pptviewlib/test.pptx 1970-01-01 00:00:00 +0000 differ |
2543 | === modified file 'openlp/plugins/presentations/presentationplugin.py' |
2544 | --- openlp/plugins/presentations/presentationplugin.py 2017-12-29 09:15:48 +0000 |
2545 | +++ openlp/plugins/presentations/presentationplugin.py 2018-02-03 15:03:00 +0000 |
2546 | @@ -44,7 +44,6 @@ |
2547 | 'presentations/pdf_program': None, |
2548 | 'presentations/Impress': QtCore.Qt.Checked, |
2549 | 'presentations/Powerpoint': QtCore.Qt.Checked, |
2550 | - 'presentations/Powerpoint Viewer': QtCore.Qt.Checked, |
2551 | 'presentations/Pdf': QtCore.Qt.Checked, |
2552 | 'presentations/presentations files': [], |
2553 | 'presentations/thumbnail_scheme': '', |
2554 | @@ -57,7 +56,7 @@ |
2555 | class PresentationPlugin(Plugin): |
2556 | """ |
2557 | This plugin allowed a Presentation to be opened, controlled and displayed on the output display. The plugin controls |
2558 | - third party applications such as OpenOffice.org Impress, Microsoft PowerPoint and the PowerPoint viewer. |
2559 | + third party applications such as OpenOffice.org Impress, and Microsoft PowerPoint. |
2560 | """ |
2561 | log = logging.getLogger('PresentationPlugin') |
2562 | |
2563 | |
2564 | === modified file 'openlp/plugins/songs/lib/mediaitem.py' |
2565 | --- openlp/plugins/songs/lib/mediaitem.py 2017-12-29 09:15:48 +0000 |
2566 | +++ openlp/plugins/songs/lib/mediaitem.py 2018-02-03 15:03:00 +0000 |
2567 | @@ -321,9 +321,12 @@ |
2568 | :param search_results: A tuple containing (songbook entry, book name, song title, song id) |
2569 | :return: None |
2570 | """ |
2571 | - def get_songbook_key(result): |
2572 | - """Get the key to sort by""" |
2573 | - return (get_natural_key(result[1]), get_natural_key(result[0]), get_natural_key(result[2])) |
2574 | + def get_songbook_key(text_array): |
2575 | + """ |
2576 | + Get the key to sort by |
2577 | + :param text_array: the result text to be processed. |
2578 | + """ |
2579 | + return get_natural_key(text_array[1]), get_natural_key(text_array[0]), get_natural_key(text_array[2]) |
2580 | |
2581 | log.debug('display results Book') |
2582 | self.list_view.clear() |
2583 | @@ -373,7 +376,7 @@ |
2584 | """ |
2585 | def get_theme_key(song): |
2586 | """Get the key to sort by""" |
2587 | - return (get_natural_key(song.theme_name), song.sort_key) |
2588 | + return get_natural_key(song.theme_name), song.sort_key |
2589 | |
2590 | log.debug('display results Themes') |
2591 | self.list_view.clear() |
2592 | @@ -396,7 +399,7 @@ |
2593 | """ |
2594 | def get_cclinumber_key(song): |
2595 | """Get the key to sort by""" |
2596 | - return (get_natural_key(song.ccli_number), song.sort_key) |
2597 | + return get_natural_key(song.ccli_number), song.sort_key |
2598 | |
2599 | log.debug('display results CCLI number') |
2600 | self.list_view.clear() |
2601 | @@ -460,6 +463,8 @@ |
2602 | """ |
2603 | Called by ServiceManager or SlideController by event passing the Song Id in the payload along with an indicator |
2604 | to say which type of display is required. |
2605 | + :param song_id: the id of the song |
2606 | + :param preview: show we preview after the update |
2607 | """ |
2608 | log.debug('on_remote_edit for song {song}'.format(song=song_id)) |
2609 | song_id = int(song_id) |
2610 | @@ -721,7 +726,8 @@ |
2611 | self.generate_footer(item, song) |
2612 | return item |
2613 | |
2614 | - def _authors_match(self, song, authors): |
2615 | + @staticmethod |
2616 | + def _authors_match(song, authors): |
2617 | """ |
2618 | Checks whether authors from a song in the database match the authors of the song to be imported. |
2619 | |
2620 | @@ -738,11 +744,12 @@ |
2621 | # List must be empty at the end |
2622 | return not author_list |
2623 | |
2624 | - def search(self, string, show_error): |
2625 | + def search(self, string, show_error=True): |
2626 | """ |
2627 | Search for some songs |
2628 | :param string: The string to show |
2629 | :param show_error: Is this an error? |
2630 | + :return: the results of the search |
2631 | """ |
2632 | search_results = self.search_entire(string) |
2633 | return [[song.id, song.title, song.alternate_title] for song in search_results] |
2634 | |
2635 | === added file 'tests/functional/openlp_core/api/endpoint/__init__.py' |
2636 | === added file 'tests/functional/openlp_core/api/endpoint/test_controller.py' |
2637 | --- tests/functional/openlp_core/api/endpoint/test_controller.py 1970-01-01 00:00:00 +0000 |
2638 | +++ tests/functional/openlp_core/api/endpoint/test_controller.py 2018-02-03 15:03:00 +0000 |
2639 | @@ -0,0 +1,54 @@ |
2640 | +# -*- coding: utf-8 -*- |
2641 | +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
2642 | + |
2643 | +############################################################################### |
2644 | +# OpenLP - Open Source Lyrics Projection # |
2645 | +# --------------------------------------------------------------------------- # |
2646 | +# Copyright (c) 2008-2018 OpenLP Developers # |
2647 | +# --------------------------------------------------------------------------- # |
2648 | +# This program is free software; you can redistribute it and/or modify it # |
2649 | +# under the terms of the GNU General Public License as published by the Free # |
2650 | +# Software Foundation; version 2 of the License. # |
2651 | +# # |
2652 | +# This program is distributed in the hope that it will be useful, but WITHOUT # |
2653 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
2654 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
2655 | +# more details. # |
2656 | +# # |
2657 | +# You should have received a copy of the GNU General Public License along # |
2658 | +# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
2659 | +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
2660 | +############################################################################### |
2661 | +from unittest import TestCase |
2662 | +from unittest.mock import MagicMock, patch |
2663 | + |
2664 | +from openlp.core.common.registry import Registry |
2665 | +from openlp.core.api.endpoint.controller import controller_text |
2666 | + |
2667 | + |
2668 | +class TestController(TestCase): |
2669 | + """ |
2670 | + Test the Remote plugin deploy functions |
2671 | + """ |
2672 | + |
2673 | + def setUp(self): |
2674 | + """ |
2675 | + Setup for tests |
2676 | + """ |
2677 | + Registry.create() |
2678 | + self.registry = Registry() |
2679 | + self.mocked_live_controller = MagicMock() |
2680 | + Registry().register('live_controller', self.mocked_live_controller) |
2681 | + |
2682 | + def test_controller_text(self): |
2683 | + """ |
2684 | + Remote Deploy tests - test the dummy zip file is processed correctly |
2685 | + """ |
2686 | + # GIVEN: A mocked service with a dummy service item |
2687 | + self.mocked_live_controller.service_item = MagicMock() |
2688 | + # WHEN: I trigger the method |
2689 | + ret = controller_text("SomeText") |
2690 | + # THEN: I get a basic set of results |
2691 | + results = ret['results'] |
2692 | + assert isinstance(results['item'], MagicMock) |
2693 | + assert len(results['slides']) == 0 |
2694 | |
2695 | === modified file 'tests/functional/openlp_plugins/bibles/test_mediaitem.py' |
2696 | --- tests/functional/openlp_plugins/bibles/test_mediaitem.py 2017-12-29 09:15:48 +0000 |
2697 | +++ tests/functional/openlp_plugins/bibles/test_mediaitem.py 2018-02-03 15:03:00 +0000 |
2698 | @@ -167,7 +167,7 @@ |
2699 | # THEN: It should be a subclass of :class:`MediaManagerItem` |
2700 | assert isinstance(self.media_item, MediaManagerItem) |
2701 | |
2702 | - def test_steup_item(self): |
2703 | + def test_setup_item(self): |
2704 | """ |
2705 | Test the setup_item method |
2706 | """ |
2707 | |
2708 | === removed file 'tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py' |
2709 | --- tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py 2017-12-29 10:19:33 +0000 |
2710 | +++ tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py 1970-01-01 00:00:00 +0000 |
2711 | @@ -1,226 +0,0 @@ |
2712 | -# -*- coding: utf-8 -*- |
2713 | -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
2714 | - |
2715 | -############################################################################### |
2716 | -# OpenLP - Open Source Lyrics Projection # |
2717 | -# --------------------------------------------------------------------------- # |
2718 | -# Copyright (c) 2008-2018 OpenLP Developers # |
2719 | -# --------------------------------------------------------------------------- # |
2720 | -# This program is free software; you can redistribute it and/or modify it # |
2721 | -# under the terms of the GNU General Public License as published by the Free # |
2722 | -# Software Foundation; version 2 of the License. # |
2723 | -# # |
2724 | -# This program is distributed in the hope that it will be useful, but WITHOUT # |
2725 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
2726 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
2727 | -# more details. # |
2728 | -# # |
2729 | -# You should have received a copy of the GNU General Public License along # |
2730 | -# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
2731 | -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
2732 | -############################################################################### |
2733 | -""" |
2734 | -This module contains tests for the pptviewcontroller module of the Presentations plugin. |
2735 | -""" |
2736 | -import shutil |
2737 | -from tempfile import mkdtemp |
2738 | -from unittest import TestCase, skipIf |
2739 | -from unittest.mock import MagicMock, patch |
2740 | - |
2741 | -from openlp.core.common import is_win |
2742 | -from openlp.core.common.path import Path |
2743 | -from openlp.plugins.presentations.lib.pptviewcontroller import PptviewDocument, PptviewController |
2744 | -from tests.helpers.testmixin import TestMixin |
2745 | -from tests.utils.constants import RESOURCE_PATH |
2746 | - |
2747 | - |
2748 | -class TestPptviewController(TestCase, TestMixin): |
2749 | - """ |
2750 | - Test the PptviewController Class |
2751 | - """ |
2752 | - def setUp(self): |
2753 | - """ |
2754 | - Set up the patches and mocks need for all tests. |
2755 | - """ |
2756 | - self.setup_application() |
2757 | - self.build_settings() |
2758 | - self.mock_plugin = MagicMock() |
2759 | - self.temp_folder = mkdtemp() |
2760 | - self.mock_plugin.settings_section = self.temp_folder |
2761 | - |
2762 | - def tearDown(self): |
2763 | - """ |
2764 | - Stop the patches |
2765 | - """ |
2766 | - self.destroy_settings() |
2767 | - shutil.rmtree(self.temp_folder) |
2768 | - |
2769 | - def test_constructor(self): |
2770 | - """ |
2771 | - Test the Constructor from the PptViewController |
2772 | - """ |
2773 | - # GIVEN: No presentation controller |
2774 | - controller = None |
2775 | - |
2776 | - # WHEN: The presentation controller object is created |
2777 | - controller = PptviewController(plugin=self.mock_plugin) |
2778 | - |
2779 | - # THEN: The name of the presentation controller should be correct |
2780 | - assert 'Powerpoint Viewer' == controller.name, 'The name of the presentation controller should be correct' |
2781 | - |
2782 | - def test_check_available(self): |
2783 | - """ |
2784 | - Test check_available / check_installed |
2785 | - """ |
2786 | - # GIVEN: A mocked dll loader and a controller |
2787 | - with patch('ctypes.cdll.LoadLibrary') as mocked_load_library: |
2788 | - mocked_process = MagicMock() |
2789 | - mocked_process.CheckInstalled.return_value = True |
2790 | - mocked_load_library.return_value = mocked_process |
2791 | - controller = PptviewController(plugin=self.mock_plugin) |
2792 | - |
2793 | - # WHEN: check_available is called |
2794 | - available = controller.check_available() |
2795 | - |
2796 | - # THEN: On windows it should return True, on other platforms False |
2797 | - if is_win(): |
2798 | - assert available is True, 'check_available should return True on windows.' |
2799 | - else: |
2800 | - assert available is False, 'check_available should return False when not on windows.' |
2801 | - |
2802 | - |
2803 | -class TestPptviewDocument(TestCase): |
2804 | - """ |
2805 | - Test the PptviewDocument Class |
2806 | - """ |
2807 | - def setUp(self): |
2808 | - """ |
2809 | - Set up the patches and mocks need for all tests. |
2810 | - """ |
2811 | - self.pptview_document_create_thumbnails_patcher = patch( |
2812 | - 'openlp.plugins.presentations.lib.pptviewcontroller.PptviewDocument.create_thumbnails') |
2813 | - self.pptview_document_stop_presentation_patcher = patch( |
2814 | - 'openlp.plugins.presentations.lib.pptviewcontroller.PptviewDocument.stop_presentation') |
2815 | - self.presentation_document_get_temp_folder_patcher = patch( |
2816 | - 'openlp.plugins.presentations.lib.pptviewcontroller.PresentationDocument.get_temp_folder') |
2817 | - self.presentation_document_setup_patcher = patch( |
2818 | - 'openlp.plugins.presentations.lib.pptviewcontroller.PresentationDocument._setup') |
2819 | - self.screen_list_patcher = patch('openlp.plugins.presentations.lib.pptviewcontroller.ScreenList') |
2820 | - self.rect_patcher = MagicMock() |
2821 | - self.mock_pptview_document_create_thumbnails = self.pptview_document_create_thumbnails_patcher.start() |
2822 | - self.mock_pptview_document_stop_presentation = self.pptview_document_stop_presentation_patcher.start() |
2823 | - self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start() |
2824 | - self.mock_presentation_document_setup = self.presentation_document_setup_patcher.start() |
2825 | - self.mock_rect = self.rect_patcher.start() |
2826 | - self.mock_screen_list = self.screen_list_patcher.start() |
2827 | - self.mock_controller = MagicMock() |
2828 | - self.mock_presentation = MagicMock() |
2829 | - self.temp_folder = mkdtemp() |
2830 | - self.mock_presentation_document_get_temp_folder.return_value = self.temp_folder |
2831 | - |
2832 | - def tearDown(self): |
2833 | - """ |
2834 | - Stop the patches |
2835 | - """ |
2836 | - self.pptview_document_create_thumbnails_patcher.stop() |
2837 | - self.pptview_document_stop_presentation_patcher.stop() |
2838 | - self.presentation_document_get_temp_folder_patcher.stop() |
2839 | - self.presentation_document_setup_patcher.stop() |
2840 | - self.rect_patcher.stop() |
2841 | - self.screen_list_patcher.stop() |
2842 | - shutil.rmtree(self.temp_folder) |
2843 | - |
2844 | - @skipIf(not is_win(), 'Not Windows') |
2845 | - def test_load_presentation_succesful(self): |
2846 | - """ |
2847 | - Test the PptviewDocument.load_presentation() method when the PPT is successfully opened |
2848 | - """ |
2849 | - # GIVEN: A reset mocked_os |
2850 | - self.mock_controller.process.OpenPPT.return_value = 0 |
2851 | - instance = PptviewDocument(self.mock_controller, self.mock_presentation) |
2852 | - instance.file_path = 'test\path.ppt' |
2853 | - |
2854 | - # WHEN: The temporary directory exists and OpenPPT returns successfully (not -1) |
2855 | - result = instance.load_presentation() |
2856 | - |
2857 | - # THEN: PptviewDocument.load_presentation should return True |
2858 | - assert result is True |
2859 | - |
2860 | - @skipIf(not is_win(), 'Not Windows') |
2861 | - def test_load_presentation_un_succesful(self): |
2862 | - """ |
2863 | - Test the PptviewDocument.load_presentation() method when the temporary directory does not exist and the PPT is |
2864 | - not successfully opened |
2865 | - """ |
2866 | - # GIVEN: A reset mock_os_isdir |
2867 | - self.mock_controller.process.OpenPPT.return_value = -1 |
2868 | - instance = PptviewDocument(self.mock_controller, self.mock_presentation) |
2869 | - instance.file_path = 'test\path.ppt' |
2870 | - |
2871 | - # WHEN: The temporary directory does not exist and OpenPPT returns unsuccessfully (-1) |
2872 | - with patch.object(instance, 'get_temp_folder') as mocked_get_folder: |
2873 | - mocked_get_folder.return_value = MagicMock(spec=Path) |
2874 | - result = instance.load_presentation() |
2875 | - |
2876 | - # THEN: The temp folder should be created and PptviewDocument.load_presentation should return False |
2877 | - assert result is False |
2878 | - |
2879 | - def test_create_titles_and_notes(self): |
2880 | - """ |
2881 | - Test PowerpointController.create_titles_and_notes |
2882 | - """ |
2883 | - # GIVEN: mocked PresentationController.save_titles_and_notes and a pptx file |
2884 | - doc = PptviewDocument(self.mock_controller, self.mock_presentation) |
2885 | - doc.file_path = RESOURCE_PATH / 'presentations' / 'test.pptx' |
2886 | - doc.save_titles_and_notes = MagicMock() |
2887 | - |
2888 | - # WHEN reading the titles and notes |
2889 | - doc.create_titles_and_notes() |
2890 | - |
2891 | - # THEN save_titles_and_notes should have been called once with empty arrays |
2892 | - doc.save_titles_and_notes.assert_called_once_with(['Test 1\n', '\n', 'Test 2\n', 'Test 4\n', 'Test 3\n'], |
2893 | - ['Notes for slide 1', 'Inserted', 'Notes for slide 2', |
2894 | - 'Notes \nfor slide 4', 'Notes for slide 3']) |
2895 | - |
2896 | - def test_create_titles_and_notes_nonexistent_file(self): |
2897 | - """ |
2898 | - Test PowerpointController.create_titles_and_notes with nonexistent file |
2899 | - """ |
2900 | - # GIVEN: mocked PresentationController.save_titles_and_notes and an nonexistent file |
2901 | - with patch('builtins.open') as mocked_open, \ |
2902 | - patch.object(Path, 'exists') as mocked_path_exists, \ |
2903 | - patch('openlp.plugins.presentations.lib.presentationcontroller.create_paths') as \ |
2904 | - mocked_dir_exists: |
2905 | - mocked_path_exists.return_value = False |
2906 | - mocked_dir_exists.return_value = False |
2907 | - doc = PptviewDocument(self.mock_controller, self.mock_presentation) |
2908 | - doc.file_path = Path('Idontexist.pptx') |
2909 | - doc.save_titles_and_notes = MagicMock() |
2910 | - |
2911 | - # WHEN: Reading the titles and notes |
2912 | - doc.create_titles_and_notes() |
2913 | - |
2914 | - # THEN: File existens should have been checked, and not have been opened. |
2915 | - doc.save_titles_and_notes.assert_called_once_with(None, None) |
2916 | - mocked_path_exists.assert_called_with() |
2917 | - assert mocked_open.call_count == 0, 'There should be no calls to open a file.' |
2918 | - |
2919 | - def test_create_titles_and_notes_invalid_file(self): |
2920 | - """ |
2921 | - Test PowerpointController.create_titles_and_notes with invalid file |
2922 | - """ |
2923 | - # GIVEN: mocked PresentationController.save_titles_and_notes and an invalid file |
2924 | - with patch('builtins.open') as mocked_open, \ |
2925 | - patch('openlp.plugins.presentations.lib.pptviewcontroller.zipfile.is_zipfile') as mocked_is_zf: |
2926 | - mocked_is_zf.return_value = False |
2927 | - mocked_open.filesize = 10 |
2928 | - doc = PptviewDocument(self.mock_controller, self.mock_presentation) |
2929 | - doc.file_path = RESOURCE_PATH / 'presentations' / 'test.ppt' |
2930 | - doc.save_titles_and_notes = MagicMock() |
2931 | - |
2932 | - # WHEN: reading the titles and notes |
2933 | - doc.create_titles_and_notes() |
2934 | - |
2935 | - # THEN: |
2936 | - doc.save_titles_and_notes.assert_called_once_with(None, None) |
2937 | - assert mocked_is_zf.call_count == 1, 'is_zipfile should have been called once' |
Looks good to me