1 /*
2 * DesktopPowerpointViewer.cpp
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16 #include <iostream>
17
18 #include <windows.h>
19 #include <winuser.h>
20 #include <oleauto.h>
21
22 #include <shared_core/Error.hpp>
23 #include <core/system/System.hpp>
24
25 #include "DesktopComUtils.hpp"
26 #include "DesktopPowerpointViewer.hpp"
27
28 using namespace rstudio::core;
29
30 namespace rstudio {
31 namespace desktop {
32
PowerpointViewer()33 PowerpointViewer::PowerpointViewer():
34 OfficeViewer(L"Powerpoint.Application", L"Presentations",
35 1 /* position of read-only flag in Open method */),
36 slideIndex_(0)
37 {
38 }
39
getDocumentWindow(IDispatch * source,IDispatch ** window) const40 Error PowerpointViewer::getDocumentWindow(IDispatch* source, IDispatch** window) const
41 {
42 Error errorHR = Success();
43 HRESULT hr = S_OK;
44
45 // Get the first document window for the presentation
46 IDispatch* idispWindows = nullptr;
47 VARIANT varResult;
48 VARIANT varItem;
49 varItem.vt = VT_INT;
50 varItem.intVal = 1;
51 VERIFY_HRESULT(getIDispatchProp(source, L"Windows", &idispWindows));
52 VERIFY_HRESULT(invokeDispatch(DISPATCH_METHOD, &varResult, idispWindows, L"Item", 1, varItem));
53 *window = varResult.pdispVal;
54
55 LErrExit:
56 return errorHR;
57 }
58
savePosition(IDispatch * source)59 Error PowerpointViewer::savePosition(IDispatch* source)
60 {
61 Error errorHR = Success();
62 HRESULT hr = S_OK;
63
64 IDispatch* idispPres = nullptr;
65 IDispatch* idispSelection = nullptr;
66 IDispatch* idispRange = nullptr;
67
68 // Get the window containing the document interface
69 errorHR = getDocumentWindow(source, &idispPres);
70 if (errorHR)
71 return errorHR;
72
73 // Get the selection (the slides the user has selected)
74 VERIFY_HRESULT(getIDispatchProp(idispPres, L"Selection", &idispSelection));
75 VERIFY_HRESULT(getIDispatchProp(idispSelection, L"SlideRange", &idispRange));
76
77 // Find the slide number the user's working on
78 VERIFY_HRESULT(getIntProp(idispRange, L"SlideNumber", &slideIndex_));
79
80 LErrExit:
81 return errorHR;
82 }
83
restorePosition(IDispatch * target) const84 Error PowerpointViewer::restorePosition(IDispatch* target) const
85 {
86 Error errorHR = Success();
87 HRESULT hr = S_OK;
88
89 IDispatch* idispPres = nullptr;
90 IDispatch* idispView = nullptr;
91
92 // Get the window containing the document interface
93 errorHR = getDocumentWindow(target, &idispPres);
94 if (errorHR)
95 return errorHR;
96
97 // Get the slide view
98 VERIFY_HRESULT(getIDispatchProp(idispPres, L"View", &idispView));
99
100 // Go to the slide in question
101 VARIANT varSlide;
102 varSlide.vt = VT_INT;
103 varSlide.intVal = slideIndex_;
104 VERIFY_HRESULT(invokeDispatch(DISPATCH_METHOD, nullptr, idispView,
105 L"GotoSlide", 1, varSlide));
106
107 LErrExit:
108 return errorHR;
109 }
110
resetPosition()111 void PowerpointViewer::resetPosition()
112 {
113 slideIndex_ = 0;
114 }
115
hasPosition() const116 bool PowerpointViewer::hasPosition() const
117 {
118 return slideIndex_ > 0;
119 }
120
121 } // namespace desktop
122 } // namespace rstudio
123