1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "internal/global.hxx"
21 #include "internal/infotips.hxx"
22 #include "internal/shlxthdl.hxx"
23 #include "internal/metainforeader.hxx"
24 #include "internal/contentreader.hxx"
25 #include "internal/utilities.hxx"
26 #include "internal/registry.hxx"
27 #include "internal/fileextensions.hxx"
28 #include "internal/iso8601_converter.hxx"
29 #include "internal/config.hxx"
31 #include "internal/resource.h"
39 const std::wstring WSPACE
= std::wstring(SPACE
);
43 CInfoTip::CInfoTip(long RefCnt
) :
46 ZeroMemory(m_szFileName
, sizeof(m_szFileName
));
47 InterlockedIncrement(&g_DllRefCnt
);
54 InterlockedDecrement(&g_DllRefCnt
);
61 HRESULT STDMETHODCALLTYPE
CInfoTip::QueryInterface(REFIID riid
, void __RPC_FAR
*__RPC_FAR
*ppvObject
)
67 if (IID_IUnknown
== riid
|| IID_IQueryInfo
== riid
)
69 pUnk
= static_cast<IQueryInfo
*>(this);
74 else if (IID_IPersistFile
== riid
)
76 pUnk
= static_cast<IPersistFile
*>(this);
87 ULONG STDMETHODCALLTYPE
CInfoTip::AddRef()
89 return InterlockedIncrement(&m_RefCnt
);
94 ULONG STDMETHODCALLTYPE
CInfoTip::Release()
96 long refcnt
= InterlockedDecrement(&m_RefCnt
);
104 //********************helper functions for GetInfoTip functions**********************
106 /** get file type information from registry.
108 std::wstring
getFileTypeInfo(const std::string
& file_extension
)
110 char extKeyValue
[MAX_STRING
];
111 char typeKeyValue
[MAX_STRING
];
112 ::std::string
sDot(".");
113 if (QueryRegistryKey(HKEY_CLASSES_ROOT
, (sDot
.append(file_extension
)).c_str(), "", extKeyValue
, MAX_STRING
))
114 if (QueryRegistryKey( HKEY_CLASSES_ROOT
, extKeyValue
, "",typeKeyValue
, MAX_STRING
))
115 return StringToWString(typeKeyValue
);
122 DWORD
getSizeOfFile( char* FileName
)
124 HANDLE hFile
= CreateFile(StringToWString(FileName
).c_str(), // open file
125 GENERIC_READ
, // open for reading
126 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, // share for all operations
128 OPEN_EXISTING
, // existing file only
129 FILE_ATTRIBUTE_NORMAL
, // normal file
130 NULL
); // no attr. template
132 if (hFile
!= INVALID_HANDLE_VALUE
)
134 DWORD dwSize
= GetFileSize( HANDLE(hFile
), NULL
);
135 CloseHandle( HANDLE(hFile
) );
139 return INVALID_FILE_SIZE
;
142 /** format file size in to be more readable.
144 std::wstring
formatSizeOfFile( DWORD dwSize
)
149 int dFileSize
= dwSize
;
151 _itoa( dFileSize
, buffer
, 10 );
152 return StringToWString( buffer
).append(StringToWString("B"));
157 double dFileSize
= (double)dwSize
/(double)KB
;
159 buffer
= _fcvt( dFileSize
, 1, &decimal
, &sign
);
161 ::std::wstring wsTemp
= StringToWString( buffer
);
163 ::std::wstring wsBuffer
= wsTemp
.substr( 0,pos
);
166 for (;decimal
- pos
> 2;pos
+= 3)
169 wsBuffer
.append(StringToWString(","));
170 wsBuffer
.append( wsTemp
.substr( pos
, 3) );
173 wsBuffer
.append(StringToWString("0"));
175 wsBuffer
.append(StringToWString("."));
176 wsBuffer
.append(wsTemp
.substr( decimal
, wsTemp
.size()-decimal
));
177 wsBuffer
.append(StringToWString("KB"));
183 /** get file size information.
185 std::wstring
getFileSizeInfo(char* FileName
)
187 DWORD dwSize
=getSizeOfFile(FileName
);
188 if (dwSize
!= INVALID_FILE_SIZE
)
189 return formatSizeOfFile( dwSize
);
195 // IQueryInfo methods
198 HRESULT STDMETHODCALLTYPE
CInfoTip::GetInfoTip(DWORD
/*dwFlags*/, wchar_t** ppwszTip
)
201 const std::wstring
CONST_SPACE(SPACE
);
203 //display File Type, no matter other info is loaded successfully or not.
204 std::wstring tmpTypeStr
= getFileTypeInfo( get_file_name_extension(m_szFileName
) );
205 if ( tmpTypeStr
!= EMPTY_STRING
)
207 msg
+= GetResString(IDS_TYPE_COLON
) + CONST_SPACE
;
213 CMetaInfoReader
meta_info_accessor(m_szFileName
);
215 //display document title;
216 if ( meta_info_accessor
.getTagData( META_INFO_TITLE
).length() > 0)
218 if ( msg
!= EMPTY_STRING
)
220 msg
+= GetResString(IDS_TITLE_COLON
) + CONST_SPACE
;
221 msg
+= meta_info_accessor
.getTagData( META_INFO_TITLE
);
225 if ( msg
!= EMPTY_STRING
)
227 msg
+= GetResString(IDS_TITLE_COLON
) + CONST_SPACE
;
228 msg
+= m_FileNameOnly
;
231 //display document author;
232 if ( meta_info_accessor
.getTagData( META_INFO_AUTHOR
).length() > 0)
234 if ( msg
!= EMPTY_STRING
)
236 msg
+= GetResString( IDS_AUTHOR_COLON
) + CONST_SPACE
;
237 msg
+= meta_info_accessor
.getTagData( META_INFO_AUTHOR
);
240 //display document subject;
241 if ( meta_info_accessor
.getTagData( META_INFO_SUBJECT
).length() > 0)
243 if ( msg
!= EMPTY_STRING
)
245 msg
+= GetResString(IDS_SUBJECT_COLON
) + CONST_SPACE
;
246 msg
+= meta_info_accessor
.getTagData( META_INFO_SUBJECT
);
249 //display document description;
250 if ( meta_info_accessor
.getTagData( META_INFO_DESCRIPTION
).length() > 0)
252 if ( msg
!= EMPTY_STRING
)
254 msg
+= GetResString( IDS_COMMENTS_COLON
) + CONST_SPACE
;
255 msg
+= meta_info_accessor
.getTagData( META_INFO_DESCRIPTION
);
258 //display midified time formatted into locale representation.
259 if ( iso8601_date_to_local_date(meta_info_accessor
.getTagData(META_INFO_MODIFIED
)).length() > 0)
261 if ( msg
!= EMPTY_STRING
)
263 msg
+= GetResString( IDS_MODIFIED_COLON
) + CONST_SPACE
;
264 msg
+= iso8601_date_to_local_date(meta_info_accessor
.getTagData(META_INFO_MODIFIED
));
267 catch (const std::exception
&)
271 //display file size, no matter other information is loaded successfully or not.
272 std::wstring tmpSizeStr
= getFileSizeInfo( m_szFileName
);
273 if ( tmpSizeStr
!= EMPTY_STRING
)
276 msg
+= GetResString( IDS_SIZE_COLON
) + CONST_SPACE
;
281 //finalize and assignthe string.
283 HRESULT hr
= SHGetMalloc(&lpMalloc
);
287 size_t len
= sizeof(wchar_t) * msg
.length() + sizeof(wchar_t);
288 wchar_t* pMem
= reinterpret_cast<wchar_t*>(lpMalloc
->Alloc(len
));
290 ZeroMemory(pMem
, len
);
292 wcscpy_s(pMem
, msg
.length()+1, msg
.c_str());
305 HRESULT STDMETHODCALLTYPE
CInfoTip::GetInfoFlags(DWORD
* /*pdwFlags*/ )
314 HRESULT STDMETHODCALLTYPE
CInfoTip::GetClassID(CLSID
* pClassID
)
316 pClassID
= const_cast<CLSID
*>(&CLSID_INFOTIP_HANDLER
);
321 // IPersistFile methods
324 HRESULT STDMETHODCALLTYPE
CInfoTip::Load(LPCOLESTR pszFileName
, DWORD
/*dwMode*/)
326 std::wstring fname
= pszFileName
;
328 // there must be a '\' and there must even be an
329 // extension, else we would not have been called
330 std::wstring::iterator begin
= fname
.begin() + fname
.find_last_of(L
"\\") + 1;
331 std::wstring::iterator end
= fname
.end();
333 m_FileNameOnly
= std::wstring(begin
, end
);
335 fname
= getShortPathName( fname
);
337 std::string fnameA
= WStringToString(fname
);
339 // ZeroMemory because strncpy doesn't '\0'-terminates the destination
340 // string; reserve the last place in the buffer for the final '\0'
341 // that's why '(sizeof(m_szFileName) - 1)'
342 ZeroMemory(m_szFileName
, sizeof(m_szFileName
));
343 strncpy(m_szFileName
, fnameA
.c_str(), (sizeof(m_szFileName
) - 1));
350 HRESULT STDMETHODCALLTYPE
CInfoTip::IsDirty()
357 HRESULT STDMETHODCALLTYPE
CInfoTip::Save(LPCOLESTR
/*pszFileName*/, BOOL
/*fRemember*/)
364 HRESULT STDMETHODCALLTYPE
CInfoTip::SaveCompleted(LPCOLESTR
/*pszFileName*/)
371 HRESULT STDMETHODCALLTYPE
CInfoTip::GetCurFile(LPOLESTR __RPC_FAR
* /*ppszFileName*/)
376 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */