1 /* AbiCollab - Code to enable the modification of remote documents.
2 * Copyright (C) 2007 by Ryan Pavlik <abiryan@ryand.net>
3 * Copyright (C) 2006,2008 by Marc Maurer <uwog@uwog.net>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA.
19 */
20
21 #include <windows.h>
22 #include "xap_App.h"
23 #include "ap_Win32App.h"
24 #include "xap_Win32App.h"
25 #include "xap_Frame.h"
26 #include "xap_Win32DialogHelper.h"
27 #include "ut_string_class.h"
28 #include <session/xp/AbiCollabSessionManager.h>
29 #include <account/xp/AccountHandler.h>
30
31 #include "ap_Win32Dialog_CollaborationAddAccount.h"
32
33 // We can't seem to pass user data to our custom message proc,
34 // which is why we have the static dialog pointer below
35 static AP_Win32Dialog_CollaborationAddAccount* s_pThis = NULL;
36
s_dlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)37 BOOL CALLBACK AP_Win32Dialog_CollaborationAddAccount::s_dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
38 {
39 switch (msg)
40 {
41 case WM_INITDIALOG:
42 {
43 AP_Win32Dialog_CollaborationAddAccount* pThis = (AP_Win32Dialog_CollaborationAddAccount *)lParam;
44 UT_return_val_if_fail(pThis, false);
45 SetWindowLongPtrW(hWnd,DWLP_USER,lParam);
46 return pThis->_onInitDialog(hWnd,wParam,lParam);
47 }
48 case WM_COMMAND:
49 {
50 AP_Win32Dialog_CollaborationAddAccount* pThis = (AP_Win32Dialog_CollaborationAddAccount *)GetWindowLongPtrW(hWnd,DWLP_USER);
51 UT_return_val_if_fail(pThis, false);
52 return pThis->_onCommand(hWnd,wParam,lParam);
53 }
54 case WM_DESTROY:
55 {
56 UT_DEBUGMSG(("Got WM_DESTROY\n"));
57 AP_Win32Dialog_CollaborationAddAccount* pThis = (AP_Win32Dialog_CollaborationAddAccount *)GetWindowLongPtrW(hWnd,DWLP_USER);
58 UT_return_val_if_fail(pThis, false);
59 DELETEP(pThis->m_pWin32Dialog);
60 return true;
61 }
62 default:
63 return false;
64 }
65 }
66
s_detailsProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)67 BOOL CALLBACK AP_Win32Dialog_CollaborationAddAccount::s_detailsProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
68 {
69 AP_Win32Dialog_CollaborationAddAccount* pThis = (AP_Win32Dialog_CollaborationAddAccount *)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
70 UT_return_val_if_fail(pThis, false);
71
72 switch (msg)
73 {
74 case WM_COMMAND:
75 if (pThis->_onDetailsCommand(hWnd, msg, wParam, lParam))
76 return true;
77 return pThis->detailsProc(hWnd, msg, wParam, lParam);
78 default:
79 return pThis->detailsProc(hWnd, msg, wParam, lParam);
80 }
81 }
82
static_constructor(XAP_DialogFactory * pFactory,XAP_Dialog_Id id)83 XAP_Dialog * AP_Win32Dialog_CollaborationAddAccount::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id id)
84 {
85 return static_cast<XAP_Dialog *>(new AP_Win32Dialog_CollaborationAddAccount(pFactory, id));
86 }
87 pt2Constructor ap_Dialog_CollaborationAddAccount_Constructor = &AP_Win32Dialog_CollaborationAddAccount::static_constructor;
88
AP_Win32Dialog_CollaborationAddAccount(XAP_DialogFactory * pDlgFactory,XAP_Dialog_Id id)89 AP_Win32Dialog_CollaborationAddAccount::AP_Win32Dialog_CollaborationAddAccount(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id)
90 : AP_Dialog_CollaborationAddAccount(pDlgFactory, id),
91 m_pWin32Dialog(NULL),
92 m_hInstance(NULL),
93 m_hOk(NULL),
94 m_pOldDetailsProc(NULL),
95 m_hWnd(NULL),
96 m_hDetails(NULL),
97 m_hDetailsHook(NULL)
98 {
99 AbiCollabSessionManager * pSessionManager = AbiCollabSessionManager::getManager();
100 if (pSessionManager)
101 {
102 m_hInstance=pSessionManager->getInstance();
103 }
104
105 // hack
106 s_pThis = this;
107 }
108
runModal(XAP_Frame * pFrame)109 void AP_Win32Dialog_CollaborationAddAccount::runModal(XAP_Frame * pFrame)
110 {
111 UT_return_if_fail(pFrame);
112 UT_return_if_fail(m_hInstance);
113
114 // create the dialog
115 LPCTSTR lpTemplate = MAKEINTRESOURCE(AP_RID_DIALOG_COLLABORATIONADDACCOUNT);
116 int result = DialogBoxParam( m_hInstance, lpTemplate,
117 static_cast<XAP_Win32FrameImpl*>(pFrame->getFrameImpl())->getTopLevelWindow(),
118 (DLGPROC)s_dlgProc, (LPARAM)this );
119 switch (result)
120 {
121 case 0:
122 // MSDN: If the function fails because the hWndParent parameter is invalid, the return value is zero.
123 break;
124 case -1:
125 UT_DEBUGMSG(("Win32 error: %d. lpTemplate: %d, RID:%d\n", GetLastError(), lpTemplate, AP_RID_DIALOG_COLLABORATIONADDACCOUNT));
126 break;
127 default:
128 break;
129 };
130
131 UnhookWindowsHookEx(m_hDetailsHook);
132 m_hDetailsHook = NULL;
133
134 s_pThis = NULL;
135 }
136
137 /*****************************************************************/
_onInitDialog(HWND hWnd,WPARAM wParam,LPARAM lParam)138 BOOL AP_Win32Dialog_CollaborationAddAccount::_onInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
139 {
140 // Store handles for easy access
141 m_hWnd = hWnd;
142 m_hOk = GetDlgItem(hWnd, AP_RID_DIALOG_COLLABORATIONADDACCOUNT_OK_BUTTON);
143 UT_return_val_if_fail(m_hOk, false);
144 m_hDetails = GetDlgItem(hWnd, AP_RID_DIALOG_COLLABORATIONADDACCOUNT_DETAILS_BOX);
145 UT_return_val_if_fail(m_hDetails, false);
146
147 // trap the messages that will be sent to the m_hDetails window, so we can forward
148 // them to the account handler
149 m_pOldDetailsProc = GetWindowLongPtrW(m_hDetails, GWLP_WNDPROC);
150 SetWindowLongPtrW(m_hDetails, GWLP_WNDPROC, (LPARAM)s_detailsProc);
151 SetWindowLongPtrW(m_hDetails, GWLP_USERDATA, (LPARAM)this);
152
153 // we need to trap the account details window's message hook,
154 // so we can make TAB stops work
155 m_hDetailsHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)s_detailsGetMsgProc, m_hInstance, GetCurrentThreadId());
156
157 // Get ourselves a custom DialogHelper
158 DELETEP(m_pWin32Dialog);
159 m_pWin32Dialog = new XAP_Win32DialogHelper(hWnd);
160
161 // Set up dialog initial state
162 _populateWindowData();
163
164 // Center Window
165 m_pWin32Dialog->centerDialog();
166
167 return true;
168 }
169
170 // return true if we process the command, false otherwise
_onCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)171 BOOL AP_Win32Dialog_CollaborationAddAccount::_onCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
172 {
173 WORD wNotifyCode = HIWORD(wParam);
174 WORD wId = LOWORD(wParam);
175
176 AccountHandler* pHandler;
177 switch (wId)
178 {
179 case AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO:
180 // Oh hey, something happened to the typecombo!
181 if (wNotifyCode == CBN_SELCHANGE)
182 {
183 // New account type selected
184 UT_DEBUGMSG(("Add Account - New handler type selected\n"));
185 pHandler = _getActiveAccountHandler();
186 if (pHandler)
187 {
188 UT_DEBUGMSG(("Changed account handler to type: %s\n", pHandler->getDisplayType().utf8_str()));
189 _setAccountHandler(pHandler);
190 }
191 else
192 UT_DEBUGMSG(("No account handler types to select; this makes abicollab kinda pointless...\n"));
193
194 return true;
195 }
196 return false;
197
198 case AP_RID_DIALOG_COLLABORATIONADDACCOUNT_OK_BUTTON:
199 UT_DEBUGMSG(("Add Account - OK button clicked\n"));
200 pHandler = _getActiveAccountHandler();
201 // if pHandler is no good, then we tell Windows we didn't handle the button
202 UT_return_val_if_fail(pHandler, 1);
203 pHandler->storeProperties();
204 m_answer=AP_Dialog_CollaborationAddAccount::a_OK;
205 EndDialog(hWnd,0);
206 return true;
207
208 case AP_RID_DIALOG_COLLABORATIONADDACCOUNT_CANCEL_BUTTON:
209 // Close without applying changes
210 EndDialog(hWnd,0);
211 m_answer=AP_Dialog_CollaborationAddAccount::a_CANCEL;
212 return true;
213
214 default:
215 // WM_COMMAND message NOT processed
216 return false;
217 }
218 }
219
_onDetailsCommand(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)220 BOOL AP_Win32Dialog_CollaborationAddAccount::_onDetailsCommand(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
221 {
222 AccountHandler* pAccountHandler = _getActiveAccountHandler();
223 UT_return_val_if_fail(pAccountHandler, false);
224 return pAccountHandler->_onCommand(hWnd, wParam, lParam);
225 }
226
detailsProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)227 BOOL AP_Win32Dialog_CollaborationAddAccount::detailsProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
228 {
229 return CallWindowProc((WNDPROC)m_pOldDetailsProc, hWnd, msg, wParam, lParam);
230 }
231
s_detailsGetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)232 LRESULT AP_Win32Dialog_CollaborationAddAccount::s_detailsGetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
233 {
234 if (s_pThis)
235 return s_pThis->detailsGetMsgProc(nCode, wParam, lParam);
236 return CallNextHookEx(NULL, nCode, wParam, lParam);
237 }
238
detailsGetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)239 LRESULT AP_Win32Dialog_CollaborationAddAccount::detailsGetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
240 {
241 LPMSG lpMsg = (LPMSG)lParam;
242
243 if (nCode >= 0 && PM_REMOVE == wParam)
244 {
245 // Don't translate non-input events.
246 if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST))
247 {
248 AccountHandler* pAccount = _getActiveAccountHandler();
249 HWND hwnd = pAccount && pAccount->shouldProcessFocus() ? m_hDetails : m_hWnd;
250 if (IsDialogMessage(hwnd, lpMsg))
251 {
252 // The value returned from this hookproc is ignored,
253 // and it cannot be used to tell Windows the message
254 // has been handled. To avoid further processing,
255 // convert the message to WM_NULL before returning.
256 lpMsg->message = WM_NULL;
257 lpMsg->lParam = 0;
258 lpMsg->wParam = 0;
259 }
260 }
261 }
262 return CallNextHookEx(NULL, nCode, wParam, lParam);
263 }
264
_populateWindowData()265 void AP_Win32Dialog_CollaborationAddAccount::_populateWindowData()
266 {
267 UT_DEBUGMSG(("AP_Win32Dialog_CollaborationAddAccount::_populateWindowData()\n"));
268
269 AbiCollabSessionManager* pSessionManager = AbiCollabSessionManager::getManager();
270 UT_return_if_fail(pSessionManager);
271
272 UT_return_if_fail(m_pWin32Dialog);
273
274 const std::map<UT_UTF8String, AccountHandlerConstructor>& registeredAccounts = pSessionManager->getRegisteredAccountHandlers();
275 for (std::map<UT_UTF8String, AccountHandlerConstructor>::const_iterator cit = registeredAccounts.begin(); cit != registeredAccounts.end(); cit++)
276 {
277 AccountHandlerConstructor pConstructor = (*cit).second;
278 UT_continue_if_fail(pConstructor);
279
280 // TODO: we need to free these somewhere
281 AccountHandler* pHandler = pConstructor();
282 UT_continue_if_fail(pHandler);
283
284 UT_sint32 index = m_pWin32Dialog->addItemToCombo(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO, (LPCSTR) AP_Win32App::s_fromUTF8ToWinLocale(pHandler->getDisplayType().utf8_str()).c_str());
285 if (index >= 0)
286 {
287 UT_DEBUGMSG(("Added handler to index %d\n", index));
288 m_vAccountTypeCombo.insert(m_vAccountTypeCombo.begin()+index, pHandler);
289 }
290 else
291 UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
292 }
293
294 // if we have at least one account handler, then make sure the first one is selected
295 if (pSessionManager->getRegisteredAccountHandlers().size() > 0)
296 {
297 m_pWin32Dialog->selectComboItem(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO, 0);
298 // Note, this requires that the backends be alright with having their widgets destroyed before being created.
299 // TCP does this, but I didn't add such code to any other backends yet. --RP 22 July 2007
300 UT_DEBUGMSG(("Add Account - New handler type selected\n"));
301 AccountHandler* pHandler = _getActiveAccountHandler();
302 if (pHandler)
303 {
304 UT_DEBUGMSG(("Changed account handler to type: %s\n", pHandler->getDisplayType().utf8_str()));
305 _setAccountHandler(pHandler);
306 }
307 else
308 UT_DEBUGMSG(("No account handler types to select; this makes abicollab kinda pointless...\n"));
309
310 }
311 else
312 {
313 // nope, we don't have any account handler :'-(
314 // Add a sample item to show that we can. Then, disable the box and the ok button
315 m_pWin32Dialog->addItemToCombo(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO, (LPCSTR) "No Handlers!");
316 m_pWin32Dialog->selectComboItem(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO, 0);
317 m_pWin32Dialog->enableControl(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO, false);
318 m_pWin32Dialog->enableControl(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_OK_BUTTON, false);
319 }
320 }
321
_getEmbeddingParent()322 void* AP_Win32Dialog_CollaborationAddAccount::_getEmbeddingParent()
323 {
324 return m_hDetails;
325 }
326
_getActiveAccountHandler()327 AccountHandler* AP_Win32Dialog_CollaborationAddAccount::_getActiveAccountHandler()
328 {
329 UT_DEBUGMSG(("AP_Win32Dialog_CollaborationAddAccount::_getActiveAccountHandler()\n"));
330 UT_return_val_if_fail(m_pWin32Dialog, NULL);
331
332 int index = m_pWin32Dialog->getComboSelectedIndex(AP_RID_DIALOG_COLLABORATIONADDACCOUNT_TYPECOMBO);
333 UT_return_val_if_fail(index >= 0 && index < static_cast<UT_sint32>(m_vAccountTypeCombo.size()), NULL);
334
335 // check the return value of this function!
336 return m_vAccountTypeCombo[index];
337 }
338
setBackendValidity(bool valid)339 void AP_Win32Dialog_CollaborationAddAccount::setBackendValidity(bool valid)
340 {
341 EnableWindow(m_hOk, valid);
342 }
343
344