1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_shell.hxx" 30 #include "internal/config.hxx" 31 #include "internal/global.hxx" 32 33 #ifndef PROPSEETS_HXX_INCLUDED 34 #include "internal/propsheets.hxx" 35 #endif 36 #include "internal/utilities.hxx" 37 #include "internal/resource.h" 38 #include "listviewbuilder.hxx" 39 40 #if defined _MSC_VER 41 #pragma warning(push, 1) 42 #endif 43 #include <shellapi.h> 44 #if defined _MSC_VER 45 #pragma warning(pop) 46 #endif 47 48 #include <string> 49 #include <vector> 50 #include <utility> 51 #include <strsafe.h> 52 53 54 /*--------------------------------------------- 55 INFO - INFO - INFO - INFO - INFO - INFO 56 57 See MSDN "Using Windows XP Visual Styles" 58 for hints how to enable the new common 59 control library for our property sheet. 60 61 INFO - INFO - INFO - INFO - INFO - INFO 62 ----------------------------------------------*/ 63 64 //----------------------------- 65 // 66 //----------------------------- 67 68 CPropertySheet::CPropertySheet(long RefCnt) : 69 m_RefCnt(RefCnt) 70 { 71 OutputDebugStringFormat("CPropertySheet::CTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); 72 InterlockedIncrement(&g_DllRefCnt); 73 } 74 75 //----------------------------- 76 // 77 //----------------------------- 78 79 CPropertySheet::~CPropertySheet() 80 { 81 OutputDebugStringFormat("CPropertySheet::DTor [%d], [%d]", m_RefCnt, g_DllRefCnt ); 82 InterlockedDecrement(&g_DllRefCnt); 83 } 84 85 //----------------------------- 86 // IUnknown methods 87 //----------------------------- 88 89 HRESULT STDMETHODCALLTYPE CPropertySheet::QueryInterface( 90 REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject) 91 { 92 *ppvObject = 0; 93 94 IUnknown* pUnk = 0; 95 if (IID_IUnknown == riid || IID_IShellExtInit == riid) 96 { 97 pUnk = static_cast<IShellExtInit*>(this); 98 pUnk->AddRef(); 99 *ppvObject = pUnk; 100 return S_OK; 101 } 102 else if (IID_IShellPropSheetExt == riid) 103 { 104 pUnk = static_cast<IShellPropSheetExt*>(this); 105 pUnk->AddRef(); 106 *ppvObject = pUnk; 107 return S_OK; 108 } 109 110 return E_NOINTERFACE; 111 } 112 113 //----------------------------- 114 // 115 //----------------------------- 116 117 ULONG STDMETHODCALLTYPE CPropertySheet::AddRef(void) 118 { 119 OutputDebugStringFormat("CPropertySheet::AddRef [%d]", m_RefCnt ); 120 return InterlockedIncrement(&m_RefCnt); 121 } 122 123 //----------------------------- 124 // 125 //----------------------------- 126 127 ULONG STDMETHODCALLTYPE CPropertySheet::Release(void) 128 { 129 OutputDebugStringFormat("CPropertySheet::Release [%d]", m_RefCnt ); 130 long refcnt = InterlockedDecrement(&m_RefCnt); 131 132 if (0 == refcnt) 133 delete this; 134 135 return refcnt; 136 } 137 138 //----------------------------- 139 // IShellExtInit 140 //----------------------------- 141 142 HRESULT STDMETHODCALLTYPE CPropertySheet::Initialize( 143 LPCITEMIDLIST /*pidlFolder*/, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/) 144 { 145 InitCommonControls(); 146 147 STGMEDIUM medium; 148 FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; 149 150 HRESULT hr = lpdobj->GetData(&fe, &medium); 151 152 // save the file name 153 if (SUCCEEDED(hr) && 154 (1 == DragQueryFileA( 155 reinterpret_cast<HDROP>(medium.hGlobal), 156 0xFFFFFFFF, 157 NULL, 158 0))) 159 { 160 UINT size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 0, 0, 0 ); 161 if ( size != 0 ) 162 { 163 TCHAR * buffer = new TCHAR[ size + 1 ]; 164 UINT result_size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 165 0, buffer, size + 1 ); 166 if ( result_size != 0 ) 167 { 168 std::wstring fname = getShortPathName( buffer ); 169 std::string fnameA = WStringToString( fname ); 170 ZeroMemory( m_szFileName, sizeof( m_szFileName ) ); 171 strncpy( m_szFileName, fnameA.c_str(), ( sizeof( m_szFileName ) - 1 ) ); 172 hr = S_OK; 173 } 174 else 175 hr = E_INVALIDARG; 176 delete [] buffer; 177 } 178 else 179 hr = E_INVALIDARG; 180 } 181 else 182 hr = E_INVALIDARG; 183 184 ReleaseStgMedium(&medium); 185 186 return hr; 187 } 188 189 //----------------------------- 190 // IShellPropSheetExt 191 //----------------------------- 192 193 HRESULT STDMETHODCALLTYPE CPropertySheet::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) 194 { 195 // Get OS version (we don't need the summary page on Windows Vista or later) 196 OSVERSIONINFO sInfoOS; 197 198 ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) ); 199 sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); 200 GetVersionEx( &sInfoOS ); 201 bool bIsVistaOrLater = (sInfoOS.dwMajorVersion >= 6); 202 203 std::wstring proppage_header; 204 205 PROPSHEETPAGE psp; 206 ZeroMemory(&psp, sizeof(PROPSHEETPAGEA)); 207 208 // add the summary property page 209 psp.dwSize = sizeof(PROPSHEETPAGE); 210 psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USECALLBACK; 211 psp.hInstance = GetModuleHandle(MODULE_NAME); 212 psp.lParam = reinterpret_cast<LPARAM>(this); 213 psp.pfnCallback = reinterpret_cast<LPFNPSPCALLBACK>(CPropertySheet::PropPageSummaryCallback); 214 215 HPROPSHEETPAGE hPage = NULL; 216 217 if ( !bIsVistaOrLater ) 218 { 219 proppage_header = GetResString(IDS_PROPPAGE_SUMMARY_TITLE); 220 221 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SUMMARY); 222 psp.pszTitle = proppage_header.c_str(); 223 psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageSummaryProc); 224 225 hPage = CreatePropertySheetPage(&psp); 226 227 // keep this instance alive, will be released when the 228 // the page is about to be destroyed in the callback function 229 230 if (hPage) 231 { 232 if (lpfnAddPage(hPage, lParam)) 233 AddRef(); 234 else 235 DestroyPropertySheetPage(hPage); 236 } 237 } 238 239 // add the statistics property page 240 proppage_header = GetResString(IDS_PROPPAGE_STATISTICS_TITLE); 241 242 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_STATISTICS); 243 psp.pszTitle = proppage_header.c_str(); 244 psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageStatisticsProc); 245 246 hPage = CreatePropertySheetPage(&psp); 247 248 if (hPage) 249 { 250 if (lpfnAddPage(hPage, lParam)) 251 AddRef(); 252 else 253 DestroyPropertySheetPage(hPage); 254 } 255 256 // always return success else 257 // no property sheet will be 258 // displayed at all 259 return NOERROR; 260 } 261 262 //----------------------------- 263 // 264 //----------------------------- 265 266 HRESULT STDMETHODCALLTYPE CPropertySheet::ReplacePage( 267 UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/) 268 { 269 return E_NOTIMPL; 270 } 271 272 //----------------------------- 273 // 274 //----------------------------- 275 276 UINT CALLBACK CPropertySheet::PropPageSummaryCallback( 277 HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp) 278 { 279 CPropertySheet* pImpl = 280 reinterpret_cast<CPropertySheet*>(ppsp->lParam); 281 282 // release this instance, acquired 283 // in the AddPages method 284 if (PSPCB_RELEASE == uMsg) 285 { 286 pImpl->Release(); 287 } 288 289 return TRUE; 290 } 291 292 293 //----------------------------- 294 // 295 //----------------------------- 296 297 BOOL CALLBACK CPropertySheet::PropPageSummaryProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) 298 { 299 switch (uiMsg) 300 { 301 case WM_INITDIALOG: 302 { 303 LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); 304 CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); 305 pImpl->InitPropPageSummary(hwnd, psp); 306 return TRUE; 307 } 308 } 309 310 return FALSE; 311 } 312 313 //----------------------------- 314 // 315 //----------------------------- 316 317 BOOL CALLBACK CPropertySheet::PropPageStatisticsProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam) 318 { 319 switch (uiMsg) 320 { 321 case WM_INITDIALOG: 322 { 323 LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam); 324 CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam); 325 pImpl->InitPropPageStatistics(hwnd, psp); 326 return TRUE; 327 } 328 } 329 330 return FALSE; 331 } 332 333 //################################## 334 void CPropertySheet::InitPropPageSummary(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) 335 { 336 try 337 { 338 CMetaInfoReader metaInfo(m_szFileName); 339 340 SetWindowText(GetDlgItem(hwnd,IDC_TITLE), metaInfo.getTagData( META_INFO_TITLE ).c_str() ); 341 SetWindowText(GetDlgItem(hwnd,IDC_AUTHOR), metaInfo.getTagData( META_INFO_AUTHOR ).c_str() ); 342 SetWindowText(GetDlgItem(hwnd,IDC_SUBJECT), metaInfo.getTagData( META_INFO_SUBJECT ).c_str() ); 343 SetWindowText(GetDlgItem(hwnd,IDC_KEYWORDS), metaInfo.getTagData( META_INFO_KEYWORDS ).c_str() ); 344 345 // comments read from meta.xml use "\n" for return, but this will not displayable in Edit control, add 346 // "\r" before "\n" to form "\r\n" in order to display return in Edit control. 347 std::wstring tempStr = metaInfo.getTagData( META_INFO_DESCRIPTION ).c_str(); 348 std::wstring::size_type itor = tempStr.find ( L"\n" , 0 ); 349 while (itor != std::wstring::npos) 350 { 351 tempStr.insert(itor, L"\r"); 352 itor = tempStr.find(L"\n", itor + 2); 353 } 354 SetWindowText(GetDlgItem(hwnd,IDC_COMMENTS), tempStr.c_str()); 355 } 356 catch (const std::exception&) 357 { 358 } 359 } 360 361 //--------------------------------- 362 /** 363 */ 364 void CPropertySheet::InitPropPageStatistics(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/) 365 { 366 try 367 { 368 CMetaInfoReader metaInfo(m_szFileName); 369 370 document_statistic_reader_ptr doc_stat_reader = create_document_statistic_reader(m_szFileName, &metaInfo); 371 372 statistic_group_list_t sgl; 373 doc_stat_reader->read(&sgl); 374 375 list_view_builder_ptr lv_builder = create_list_view_builder( 376 GetDlgItem(hwnd, IDC_STATISTICSLIST), 377 GetResString(IDS_PROPERTY), 378 GetResString(IDS_PROPERTY_VALUE)); 379 380 lv_builder->build(sgl); 381 } 382 catch (const std::exception&) 383 { 384 } 385 } 386