1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <global.hxx>
21 #include <columninfo.hxx>
22 #include <fileextensions.hxx>
23 #include <metainforeader.hxx>
24 #include <utilities.hxx>
25 #include <config.hxx>
26 
27 #include <sal/macros.h>
28 #include <malloc.h>
29 
30 namespace /* private */
31 {
32     const SHCOLUMNINFO ColumnInfoTable[] =
33     {
34         {{PSGUID_SUMMARYINFORMATION, PIDSI_TITLE},    VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Title",    L"Title"},
35         {{PSGUID_SUMMARYINFORMATION, PIDSI_AUTHOR},   VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Author",   L"Author"},
36         {{PSGUID_SUMMARYINFORMATION, PIDSI_SUBJECT},  VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Subject",  L"Subject"},
37         {{PSGUID_SUMMARYINFORMATION, PIDSI_KEYWORDS}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Keywords", L"Keywords"},
38         {{PSGUID_SUMMARYINFORMATION, PIDSI_COMMENTS}, VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Comments", L"Comments"},
39         {{PSGUID_SUMMARYINFORMATION, PIDSI_PAGECOUNT},VT_BSTR, LVCFMT_LEFT, 30, SHCOLSTATE_TYPE_STR, L"Pagecount", L"Pagecount"}
40     };
41 
42     size_t ColumnInfoTableSize = SAL_N_ELEMENTS(ColumnInfoTable);
43 
IsOOFileExtension(wchar_t const * Extension)44 bool IsOOFileExtension(wchar_t const * Extension)
45 {
46     for (size_t i = 0; i < OOFileExtensionTableSize; i++)
47     {
48         if (0 == _wcsicmp(Extension, OOFileExtensionTable[i].ExtensionU))
49             return true;
50     }
51 
52     return false;
53 }
54 
55 }
56 
57 
CColumnInfo(LONG RefCnt)58 CColumnInfo::CColumnInfo(LONG RefCnt) :
59     m_RefCnt(RefCnt)
60 {
61     InterlockedIncrement(&g_DllRefCnt);
62 }
63 
64 
~CColumnInfo()65 CColumnInfo::~CColumnInfo()
66 {
67     InterlockedDecrement(&g_DllRefCnt);
68 }
69 
70 
71 // IUnknown methods
72 
73 
QueryInterface(REFIID riid,void __RPC_FAR * __RPC_FAR * ppvObject)74 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CColumnInfo::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
75 {
76     *ppvObject = nullptr;
77 
78     if (IID_IUnknown == riid || IID_IColumnProvider == riid)
79     {
80         IUnknown* pUnk = static_cast<IColumnProvider*>(this);
81         pUnk->AddRef();
82         *ppvObject = pUnk;
83         return S_OK;
84     }
85 
86     return E_NOINTERFACE;
87 }
88 
89 
AddRef()90 COM_DECLSPEC_NOTHROW ULONG STDMETHODCALLTYPE CColumnInfo::AddRef()
91 {
92     return InterlockedIncrement(&m_RefCnt);
93 }
94 
95 
Release()96 COM_DECLSPEC_NOTHROW ULONG STDMETHODCALLTYPE CColumnInfo::Release()
97 {
98     LONG refcnt = InterlockedDecrement(&m_RefCnt);
99 
100     if (0 == m_RefCnt)
101         delete this;
102 
103     return refcnt;
104 }
105 
106 
107 // IColumnProvider
108 
109 
Initialize(LPCSHCOLUMNINIT)110 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CColumnInfo::Initialize(LPCSHCOLUMNINIT /*psci*/)
111 {
112     return S_OK;
113 }
114 
115 // Register all columns we support
GetColumnInfo(DWORD dwIndex,SHCOLUMNINFO * psci)116 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CColumnInfo::GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO *psci)
117 {
118     if (dwIndex >= ColumnInfoTableSize)
119         return S_FALSE;
120 
121     //  Return information on each column we support. Return S_FALSE
122     //  to indicate that we have returned information on all our
123     //  columns. GetColumnInfo will be called repeatedly until S_FALSE
124     //  or an error is returned
125     psci->scid.fmtid = ColumnInfoTable[dwIndex].scid.fmtid;
126     psci->scid.pid   = ColumnInfoTable[dwIndex].scid.pid;
127     ZeroMemory(psci->wszTitle, sizeof(psci->wszTitle));
128     wcsncpy(psci->wszTitle, ColumnInfoTable[dwIndex].wszTitle,
129             SAL_N_ELEMENTS(psci->wszTitle) - 1);
130 
131     return S_OK;
132 }
133 
GetItemData(LPCSHCOLUMNID pscid,LPCSHCOLUMNDATA pscd,VARIANT * pvarData)134 COM_DECLSPEC_NOTHROW HRESULT STDMETHODCALLTYPE CColumnInfo::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT *pvarData)
135 {
136     if (IsOOFileExtension(pscd->pwszExt))
137     {
138         try
139         {
140             std::wstring fname = getShortPathName( std::wstring( pscd->wszFile ) );
141 
142             CMetaInfoReader meta_info_accessor(fname);
143 
144             VariantClear(pvarData);
145 
146             if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_TITLE)
147             {
148                 pvarData->vt = VT_BSTR;
149                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_TITLE ).c_str());
150 
151                 return S_OK;
152             }
153             else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_AUTHOR)
154             {
155                 pvarData->vt = VT_BSTR;
156                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_AUTHOR).c_str());
157 
158                 return S_OK;
159             }
160             else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_SUBJECT)
161             {
162                 pvarData->vt = VT_BSTR;
163                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_SUBJECT).c_str());
164 
165                 return S_OK;
166             }
167             else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_KEYWORDS)
168             {
169                 pvarData->vt = VT_BSTR;
170                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_KEYWORDS).c_str());
171 
172                 return S_OK;
173             }
174             else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_COMMENTS)
175             {
176                 pvarData->vt = VT_BSTR;
177                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagData( META_INFO_DESCRIPTION).c_str());
178 
179                 return S_OK;
180             }
181             else if (IsEqualGUID (pscid->fmtid, FMTID_SummaryInformation) && pscid->pid == PIDSI_PAGECOUNT)
182             {
183                 pvarData->vt = VT_BSTR;
184                 pvarData->bstrVal = SysAllocString(meta_info_accessor.getTagAttribute( META_INFO_DOCUMENT_STATISTIC, META_INFO_PAGES).c_str());
185 
186                 return S_OK;
187             }
188         }
189         catch (const std::exception&)
190         {
191             return S_FALSE;
192         }
193     }
194 
195     return S_FALSE;
196 }
197 
198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
199