update dev300-m58
[ooovba.git] / shell / source / win32 / shlxthandler / infotips / infotips.cxx
blob2b0826fa456182349f6ce15a134f9be47a3df8fd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: infotips.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_shell.hxx"
33 #include "internal/global.hxx"
34 #include "internal/infotips.hxx"
35 #include "internal/shlxthdl.hxx"
36 #include "internal/metainforeader.hxx"
37 #include "internal/contentreader.hxx"
38 #include "internal/utilities.hxx"
39 #include "internal/registry.hxx"
40 #include "internal/fileextensions.hxx"
41 #include "internal/iso8601_converter.hxx"
42 #include "internal/config.hxx"
44 #include "internal/resource.h"
45 #include <stdio.h>
46 #include <utility>
47 #include <stdlib.h>
48 #define MAX_STRING 80
49 #define KB 1024.0
50 const std::wstring WSPACE = std::wstring(SPACE);
52 //-----------------------------
54 //-----------------------------
56 CInfoTip::CInfoTip(long RefCnt) :
57 m_RefCnt(RefCnt)
59 ZeroMemory(m_szFileName, sizeof(m_szFileName));
60 InterlockedIncrement(&g_DllRefCnt);
63 //-----------------------------
65 //-----------------------------
67 CInfoTip::~CInfoTip()
69 InterlockedDecrement(&g_DllRefCnt);
72 //-----------------------------
73 // IUnknown methods
74 //-----------------------------
76 HRESULT STDMETHODCALLTYPE CInfoTip::QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
78 *ppvObject = 0;
80 IUnknown* pUnk = 0;
82 if (IID_IUnknown == riid || IID_IQueryInfo == riid)
84 pUnk = static_cast<IQueryInfo*>(this);
85 pUnk->AddRef();
86 *ppvObject = pUnk;
87 return S_OK;
89 else if (IID_IPersistFile == riid)
91 pUnk = static_cast<IPersistFile*>(this);
92 pUnk->AddRef();
93 *ppvObject = pUnk;
94 return S_OK;
97 return E_NOINTERFACE;
100 //----------------------------
102 //----------------------------
104 ULONG STDMETHODCALLTYPE CInfoTip::AddRef(void)
106 return InterlockedIncrement(&m_RefCnt);
109 //----------------------------
111 //----------------------------
113 ULONG STDMETHODCALLTYPE CInfoTip::Release( void)
115 long refcnt = InterlockedDecrement(&m_RefCnt);
117 if (0 == m_RefCnt)
118 delete this;
120 return refcnt;
123 //********************helper functions for GetInfoTip functions**********************
125 /** get file type infomation from registry.
127 std::wstring getFileTypeInfo(const std::string& file_extension)
129 char extKeyValue[MAX_STRING];
130 char typeKeyValue[MAX_STRING];
131 ::std::string sDot(".");
132 if (QueryRegistryKey(HKEY_CLASSES_ROOT, (sDot.append(file_extension)).c_str(), "", extKeyValue, MAX_STRING))
133 if (QueryRegistryKey( HKEY_CLASSES_ROOT, extKeyValue, "",typeKeyValue, MAX_STRING))
134 return StringToWString(typeKeyValue);
136 return EMPTY_STRING;
139 /** get file size.
141 DWORD getSizeOfFile( char* FileName )
143 HANDLE hFile = CreateFile(StringToWString(FileName).c_str(), // open file
144 GENERIC_READ, // open for reading
145 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, // share for all operations
146 NULL, // no security
147 OPEN_EXISTING, // existing file only
148 FILE_ATTRIBUTE_NORMAL, // normal file
149 NULL); // no attr. template
151 if (hFile != INVALID_HANDLE_VALUE)
153 DWORD dwSize = GetFileSize( HANDLE(hFile), NULL );
154 CloseHandle( HANDLE(hFile) );
155 return dwSize;
158 return INVALID_FILE_SIZE;
161 /** format file size in to be more readable.
163 std::wstring formatSizeOfFile( DWORD dwSize )
165 if ( dwSize < 1000 )
167 char buffer[3];
168 int dFileSize = dwSize;
170 _itoa( dFileSize, buffer, 10 );
171 return StringToWString( buffer ).append(StringToWString("B"));
174 char *buffer=NULL;
175 int decimal, sign;
176 double dFileSize = (double)dwSize/(double)KB;
178 buffer = _fcvt( dFileSize, 1, &decimal, &sign );
180 ::std::wstring wsTemp = StringToWString( buffer );
181 int pos=decimal % 3;
182 ::std::wstring wsBuffer = wsTemp.substr( 0,pos);
184 if ( decimal )
185 for (;decimal - pos > 2;pos += 3)
187 if (pos)
188 wsBuffer.append(StringToWString(","));
189 wsBuffer.append( wsTemp.substr( pos, 3) );
191 else
192 wsBuffer.append(StringToWString("0"));
194 wsBuffer.append(StringToWString("."));
195 wsBuffer.append(wsTemp.substr( decimal, wsTemp.size()-decimal ));
196 wsBuffer.append(StringToWString("KB"));
198 return wsBuffer;
202 /** get file size infomation.
204 std::wstring getFileSizeInfo(char* FileName)
206 DWORD dwSize=getSizeOfFile(FileName);
207 if (dwSize != INVALID_FILE_SIZE)
208 return formatSizeOfFile( dwSize );
210 return EMPTY_STRING;
213 //----------------------------
214 // IQueryInfo methods
215 //----------------------------
217 HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoTip(DWORD /*dwFlags*/, wchar_t** ppwszTip)
219 std::wstring msg;
220 const std::wstring CONST_SPACE(SPACE);
222 //display File Type, no matter other info is loaded successfully or not.
223 std::wstring tmpTypeStr = getFileTypeInfo( get_file_name_extension(m_szFileName) );
224 if ( tmpTypeStr != EMPTY_STRING )
226 msg += GetResString(IDS_TYPE_COLON) + CONST_SPACE;
227 msg += tmpTypeStr;
232 CMetaInfoReader meta_info_accessor(m_szFileName);
234 //display document title;
235 if ( meta_info_accessor.getTagData( META_INFO_TITLE ).length() > 0)
237 if ( msg != EMPTY_STRING )
238 msg += L"\n";
239 msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE;
240 msg += meta_info_accessor.getTagData( META_INFO_TITLE );
242 else
244 if ( msg != EMPTY_STRING )
245 msg += L"\n";
246 msg += GetResString(IDS_TITLE_COLON) + CONST_SPACE;
247 msg += m_FileNameOnly;
250 //display document author;
251 if ( meta_info_accessor.getTagData( META_INFO_AUTHOR ).length() > 0)
253 if ( msg != EMPTY_STRING )
254 msg += L"\n";
255 msg += GetResString( IDS_AUTHOR_COLON ) + CONST_SPACE;
256 msg += meta_info_accessor.getTagData( META_INFO_AUTHOR );
259 //display document subject;
260 if ( meta_info_accessor.getTagData( META_INFO_SUBJECT ).length() > 0)
262 if ( msg != EMPTY_STRING )
263 msg += L"\n";
264 msg += GetResString(IDS_SUBJECT_COLON) + CONST_SPACE;
265 msg += meta_info_accessor.getTagData( META_INFO_SUBJECT );
268 //display document description;
269 if ( meta_info_accessor.getTagData( META_INFO_DESCRIPTION ).length() > 0)
271 if ( msg != EMPTY_STRING )
272 msg += L"\n";
273 msg += GetResString( IDS_COMMENTS_COLON ) + CONST_SPACE;
274 msg += meta_info_accessor.getTagData( META_INFO_DESCRIPTION );
277 //display midified time formated into locale representation.
278 if ( iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED )).length() > 0)
280 if ( msg != EMPTY_STRING )
281 msg += L"\n";
282 msg += GetResString( IDS_MODIFIED_COLON ) + CONST_SPACE;
283 msg += iso8601_date_to_local_date(meta_info_accessor.getTagData(META_INFO_MODIFIED ));
286 catch (const std::exception&)
288 //return E_FAIL;
291 //display file size, no matter other infomation is loaded successfully or not.
292 std::wstring tmpSizeStr = getFileSizeInfo( m_szFileName );
293 if ( tmpSizeStr != EMPTY_STRING )
295 msg += L"\n";
296 msg += GetResString( IDS_SIZE_COLON ) + CONST_SPACE;
297 msg += tmpSizeStr;
301 //finalize and assignthe string.
302 LPMALLOC lpMalloc;
303 HRESULT hr = SHGetMalloc(&lpMalloc);
305 if (SUCCEEDED(hr))
307 size_t len = sizeof(wchar_t) * msg.length() + sizeof(wchar_t);
308 wchar_t* pMem = reinterpret_cast<wchar_t*>(lpMalloc->Alloc(len));
310 ZeroMemory(pMem, len);
312 msg.copy(pMem,msg.length());
314 *ppwszTip = pMem;
315 lpMalloc->Release();
317 return S_OK;
320 return E_FAIL;
323 //----------------------------
325 //----------------------------
327 HRESULT STDMETHODCALLTYPE CInfoTip::GetInfoFlags(DWORD * /*pdwFlags*/ )
329 return E_NOTIMPL;
332 //----------------------------
333 // IPersist methods
334 //----------------------------
336 HRESULT STDMETHODCALLTYPE CInfoTip::GetClassID(CLSID* pClassID)
338 pClassID = const_cast<CLSID*>(&CLSID_INFOTIP_HANDLER);
339 return S_OK;
342 //----------------------------
343 // IPersistFile methods
344 //----------------------------
346 HRESULT STDMETHODCALLTYPE CInfoTip::Load(LPCOLESTR pszFileName, DWORD /*dwMode*/)
348 std::wstring fname = pszFileName;
350 // there must be a '\' and there must even be an
351 // extension, else we would not have been called
352 std::wstring::iterator begin = fname.begin() + fname.find_last_of(L"\\") + 1;
353 std::wstring::iterator end = fname.end();
355 m_FileNameOnly = std::wstring(begin, end);
357 std::string fnameA = WStringToString(fname);
359 // #115531#
360 // ZeroMemory because strncpy doesn't '\0'-terminates the destination
361 // string; reserve the last place in the buffer for the final '\0'
362 // that's why '(sizeof(m_szFileName) - 1)'
363 ZeroMemory(m_szFileName, sizeof(m_szFileName));
364 strncpy(m_szFileName, fnameA.c_str(), (sizeof(m_szFileName) - 1));
366 return S_OK;
369 //----------------------------
371 //----------------------------
373 HRESULT STDMETHODCALLTYPE CInfoTip::IsDirty(void)
375 return E_NOTIMPL;
378 //----------------------------
380 //----------------------------
382 HRESULT STDMETHODCALLTYPE CInfoTip::Save(LPCOLESTR /*pszFileName*/, BOOL /*fRemember*/)
384 return E_NOTIMPL;
387 //----------------------------
389 //----------------------------
391 HRESULT STDMETHODCALLTYPE CInfoTip::SaveCompleted(LPCOLESTR /*pszFileName*/)
393 return E_NOTIMPL;
396 //----------------------------
398 //----------------------------
400 HRESULT STDMETHODCALLTYPE CInfoTip::GetCurFile(LPOLESTR __RPC_FAR * /*ppszFileName*/)
402 return E_NOTIMPL;