blob: 65c1458ce9b5c52f3246e475928f4c453e2bb62a [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_shell.hxx"
#include "internal/config.hxx"
#include "internal/global.hxx"
#ifndef PROPSEETS_HXX_INCLUDED
#include "internal/propsheets.hxx"
#endif
#include "internal/utilities.hxx"
#include "internal/resource.h"
#include "listviewbuilder.hxx"
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <shellapi.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <string>
#include <vector>
#include <utility>
#include <strsafe.h>
/*---------------------------------------------
INFO - INFO - INFO - INFO - INFO - INFO
See MSDN "Using Windows XP Visual Styles"
for hints how to enable the new common
control library for our property sheet.
INFO - INFO - INFO - INFO - INFO - INFO
----------------------------------------------*/
//-----------------------------
//
//-----------------------------
CPropertySheet::CPropertySheet(long RefCnt) :
m_RefCnt(RefCnt)
{
OutputDebugStringFormat("CPropertySheet::CTor [%d], [%d]", m_RefCnt, g_DllRefCnt );
InterlockedIncrement(&g_DllRefCnt);
}
//-----------------------------
//
//-----------------------------
CPropertySheet::~CPropertySheet()
{
OutputDebugStringFormat("CPropertySheet::DTor [%d], [%d]", m_RefCnt, g_DllRefCnt );
InterlockedDecrement(&g_DllRefCnt);
}
//-----------------------------
// IUnknown methods
//-----------------------------
HRESULT STDMETHODCALLTYPE CPropertySheet::QueryInterface(
REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
{
*ppvObject = 0;
IUnknown* pUnk = 0;
if (IID_IUnknown == riid || IID_IShellExtInit == riid)
{
pUnk = static_cast<IShellExtInit*>(this);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
else if (IID_IShellPropSheetExt == riid)
{
pUnk = static_cast<IShellPropSheetExt*>(this);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
return E_NOINTERFACE;
}
//-----------------------------
//
//-----------------------------
ULONG STDMETHODCALLTYPE CPropertySheet::AddRef(void)
{
OutputDebugStringFormat("CPropertySheet::AddRef [%d]", m_RefCnt );
return InterlockedIncrement(&m_RefCnt);
}
//-----------------------------
//
//-----------------------------
ULONG STDMETHODCALLTYPE CPropertySheet::Release(void)
{
OutputDebugStringFormat("CPropertySheet::Release [%d]", m_RefCnt );
long refcnt = InterlockedDecrement(&m_RefCnt);
if (0 == refcnt)
delete this;
return refcnt;
}
//-----------------------------
// IShellExtInit
//-----------------------------
HRESULT STDMETHODCALLTYPE CPropertySheet::Initialize(
LPCITEMIDLIST /*pidlFolder*/, LPDATAOBJECT lpdobj, HKEY /*hkeyProgID*/)
{
InitCommonControls();
STGMEDIUM medium;
FORMATETC fe = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
HRESULT hr = lpdobj->GetData(&fe, &medium);
// save the file name
if (SUCCEEDED(hr) &&
(1 == DragQueryFileA(
reinterpret_cast<HDROP>(medium.hGlobal),
0xFFFFFFFF,
NULL,
0)))
{
UINT size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal), 0, 0, 0 );
if ( size != 0 )
{
TCHAR * buffer = new TCHAR[ size + 1 ];
UINT result_size = DragQueryFile( reinterpret_cast<HDROP>(medium.hGlobal),
0, buffer, size + 1 );
if ( result_size != 0 )
{
std::wstring fname = getShortPathName( buffer );
std::string fnameA = WStringToString( fname );
ZeroMemory( m_szFileName, sizeof( m_szFileName ) );
strncpy( m_szFileName, fnameA.c_str(), ( sizeof( m_szFileName ) - 1 ) );
hr = S_OK;
}
else
hr = E_INVALIDARG;
delete [] buffer;
}
else
hr = E_INVALIDARG;
}
else
hr = E_INVALIDARG;
ReleaseStgMedium(&medium);
return hr;
}
//-----------------------------
// IShellPropSheetExt
//-----------------------------
HRESULT STDMETHODCALLTYPE CPropertySheet::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
// Get OS version (we don't need the summary page on Windows Vista or later)
OSVERSIONINFO sInfoOS;
ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) );
sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx( &sInfoOS );
bool bIsVistaOrLater = (sInfoOS.dwMajorVersion >= 6);
std::wstring proppage_header;
PROPSHEETPAGE psp;
ZeroMemory(&psp, sizeof(PROPSHEETPAGEA));
// add the summary property page
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USECALLBACK;
psp.hInstance = GetModuleHandle(MODULE_NAME);
psp.lParam = reinterpret_cast<LPARAM>(this);
psp.pfnCallback = reinterpret_cast<LPFNPSPCALLBACK>(CPropertySheet::PropPageSummaryCallback);
HPROPSHEETPAGE hPage = NULL;
if ( !bIsVistaOrLater )
{
proppage_header = GetResString(IDS_PROPPAGE_SUMMARY_TITLE);
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_SUMMARY);
psp.pszTitle = proppage_header.c_str();
psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageSummaryProc);
hPage = CreatePropertySheetPage(&psp);
// keep this instance alive, will be released when the
// the page is about to be destroyed in the callback function
if (hPage)
{
if (lpfnAddPage(hPage, lParam))
AddRef();
else
DestroyPropertySheetPage(hPage);
}
}
// add the statistics property page
proppage_header = GetResString(IDS_PROPPAGE_STATISTICS_TITLE);
psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE_STATISTICS);
psp.pszTitle = proppage_header.c_str();
psp.pfnDlgProc = reinterpret_cast<DLGPROC>(CPropertySheet::PropPageStatisticsProc);
hPage = CreatePropertySheetPage(&psp);
if (hPage)
{
if (lpfnAddPage(hPage, lParam))
AddRef();
else
DestroyPropertySheetPage(hPage);
}
// always return success else
// no property sheet will be
// displayed at all
return NOERROR;
}
//-----------------------------
//
//-----------------------------
HRESULT STDMETHODCALLTYPE CPropertySheet::ReplacePage(
UINT /*uPageID*/, LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, LPARAM /*lParam*/)
{
return E_NOTIMPL;
}
//-----------------------------
//
//-----------------------------
UINT CALLBACK CPropertySheet::PropPageSummaryCallback(
HWND /*hwnd*/, UINT uMsg, LPPROPSHEETPAGE ppsp)
{
CPropertySheet* pImpl =
reinterpret_cast<CPropertySheet*>(ppsp->lParam);
// release this instance, acquired
// in the AddPages method
if (PSPCB_RELEASE == uMsg)
{
pImpl->Release();
}
return TRUE;
}
//-----------------------------
//
//-----------------------------
BOOL CALLBACK CPropertySheet::PropPageSummaryProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam)
{
switch (uiMsg)
{
case WM_INITDIALOG:
{
LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam);
CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam);
pImpl->InitPropPageSummary(hwnd, psp);
return TRUE;
}
}
return FALSE;
}
//-----------------------------
//
//-----------------------------
BOOL CALLBACK CPropertySheet::PropPageStatisticsProc(HWND hwnd, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam)
{
switch (uiMsg)
{
case WM_INITDIALOG:
{
LPPROPSHEETPAGE psp = reinterpret_cast<LPPROPSHEETPAGE>(lParam);
CPropertySheet* pImpl = reinterpret_cast<CPropertySheet*>(psp->lParam);
pImpl->InitPropPageStatistics(hwnd, psp);
return TRUE;
}
}
return FALSE;
}
//##################################
void CPropertySheet::InitPropPageSummary(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/)
{
try
{
CMetaInfoReader metaInfo(m_szFileName);
SetWindowText(GetDlgItem(hwnd,IDC_TITLE), metaInfo.getTagData( META_INFO_TITLE ).c_str() );
SetWindowText(GetDlgItem(hwnd,IDC_AUTHOR), metaInfo.getTagData( META_INFO_AUTHOR ).c_str() );
SetWindowText(GetDlgItem(hwnd,IDC_SUBJECT), metaInfo.getTagData( META_INFO_SUBJECT ).c_str() );
SetWindowText(GetDlgItem(hwnd,IDC_KEYWORDS), metaInfo.getTagData( META_INFO_KEYWORDS ).c_str() );
// comments read from meta.xml use "\n" for return, but this will not displayable in Edit control, add
// "\r" before "\n" to form "\r\n" in order to display return in Edit control.
std::wstring tempStr = metaInfo.getTagData( META_INFO_DESCRIPTION ).c_str();
std::wstring::size_type itor = tempStr.find ( L"\n" , 0 );
while (itor != std::wstring::npos)
{
tempStr.insert(itor, L"\r");
itor = tempStr.find(L"\n", itor + 2);
}
SetWindowText(GetDlgItem(hwnd,IDC_COMMENTS), tempStr.c_str());
}
catch (const std::exception&)
{
}
}
//---------------------------------
/**
*/
void CPropertySheet::InitPropPageStatistics(HWND hwnd, LPPROPSHEETPAGE /*lppsp*/)
{
try
{
CMetaInfoReader metaInfo(m_szFileName);
document_statistic_reader_ptr doc_stat_reader = create_document_statistic_reader(m_szFileName, &metaInfo);
statistic_group_list_t sgl;
doc_stat_reader->read(&sgl);
list_view_builder_ptr lv_builder = create_list_view_builder(
GetDlgItem(hwnd, IDC_STATISTICSLIST),
GetResString(IDS_PROPERTY),
GetResString(IDS_PROPERTY_VALUE));
lv_builder->build(sgl);
}
catch (const std::exception&)
{
}
}