1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2008 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
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.
28 ************************************************************************/
30 #include "precompiled_vcl.hxx"
31 #include "sal/config.h"
40 #include "com/sun/star/container/XNameAccess.hpp"
41 #include "com/sun/star/io/XInputStream.hpp"
42 #include "com/sun/star/lang/Locale.hpp"
43 #include "com/sun/star/uno/Any.hxx"
44 #include "com/sun/star/uno/Exception.hpp"
45 #include "com/sun/star/uno/Reference.hxx"
46 #include "com/sun/star/uno/RuntimeException.hpp"
47 #include "com/sun/star/uno/Sequence.hxx"
48 #include "comphelper/processfactory.hxx"
49 #include "osl/diagnose.h"
50 #include "rtl/bootstrap.hxx"
51 #include "rtl/string.h"
52 #include "rtl/textenc.h"
53 #include "rtl/ustrbuf.hxx"
54 #include "rtl/ustring.h"
55 #include "rtl/ustring.hxx"
56 #include "sal/types.h"
57 #include "tools/stream.hxx"
58 #include "tools/urlobj.hxx"
59 #include "vcl/bitmapex.hxx"
60 #include "vcl/impimagetree.hxx"
61 #include "vcl/pngread.hxx"
62 #include "vcl/settings.hxx"
63 #include "vcl/svapp.hxx"
67 namespace css
= com::sun::star
;
69 rtl::OUString
createPath(
70 rtl::OUString
const & name
, sal_Int32 pos
, rtl::OUString
const & locale
)
72 rtl::OUStringBuffer
b(name
.copy(0, pos
+ 1));
74 b
.append(name
.copy(pos
));
75 return b
.makeStringAndClear();
78 std::auto_ptr
< SvStream
> wrapStream(
79 css::uno::Reference
< css::io::XInputStream
> const & stream
)
81 // This could use SvInputStream instead if that did not have a broken
82 // SeekPos implementation for an XInputStream that is not also XSeekable
83 // (cf. "@@@" at tags/DEV300_m37/svtools/source/misc1/strmadpt.cxx@264807
85 OSL_ASSERT(stream
.is());
86 std::auto_ptr
< SvStream
> s(new SvMemoryStream
);
88 css::uno::Sequence
< sal_Int8
> data
;
89 sal_Int32
const size
= 30000;
90 sal_Int32 n
= stream
->readBytes(data
, size
);
91 s
->Write(data
.getConstArray(), n
);
101 css::uno::Reference
< css::io::XInputStream
> const & stream
,
102 rtl::OUString
const & path
, BitmapEx
& bitmap
)
104 std::auto_ptr
< SvStream
> s(wrapStream(stream
));
105 if (path
.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".png")))
107 vcl::PNGReader
aPNGReader( *s
);
108 aPNGReader
.SetIgnoreGammaChunk( sal_True
);
109 bitmap
= aPNGReader
.Read();
117 ImplImageTree::ImplImageTree()
119 m_datadir
= ::rtl::OUString::createFromAscii ( "/usr/share/" );
121 m_libdir
= ::rtl::OUString::createFromAscii ( "/usr/lib64/" );
123 m_libdir
= ::rtl::OUString::createFromAscii ( "/usr/lib/" );
127 ImplImageTree::~ImplImageTree() {}
129 bool ImplImageTree::loadImage(
130 rtl::OUString
const & name
, rtl::OUString
const & style
, BitmapEx
& bitmap
,
134 if (cacheLookup(name
, localized
, bitmap
)) {
137 if (!bitmap
.IsEmpty()) {
140 std::vector
< rtl::OUString
> paths
;
141 paths
.push_back(name
);
143 sal_Int32 pos
= name
.lastIndexOf('/');
145 css::lang::Locale
const & loc
=
146 Application::GetSettings().GetUILocale();
147 paths
.push_back(createPath(name
, pos
, loc
.Language
));
148 if (loc
.Country
.getLength() != 0) {
149 rtl::OUStringBuffer
b(loc
.Language
);
150 b
.append(sal_Unicode('-'));
151 b
.append(loc
.Country
);
152 rtl::OUString
p(createPath(name
, pos
, b
.makeStringAndClear()));
154 if (loc
.Variant
.getLength() != 0) {
156 b
.append(sal_Unicode('-'));
157 b
.append(loc
.Variant
);
159 createPath(name
, pos
, b
.makeStringAndClear()));
166 found
= find(paths
, bitmap
);
167 } catch (css::uno::RuntimeException
&) {
169 } catch (css::uno::Exception
& e
) {
171 "ImplImageTree::loadImage exception \"%s\"",
172 rtl::OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
175 m_cache
[name
.intern()] = std::make_pair(localized
, bitmap
);
180 void ImplImageTree::shutDown() {
181 m_style
= rtl::OUString();
182 // for safety; empty m_style means "not initialized"
187 void ImplImageTree::setStyle(rtl::OUString
const & style
) {
188 OSL_ASSERT(style
.getLength() != 0); // empty m_style means "not initialized"
189 if (style
!= m_style
) {
196 void ImplImageTree::addUrlToZips(const rtl::OUString
&url
) {
197 if ( url
.getLength() == 0 )
202 css::uno::Reference
< css::container::XNameAccess
>()));
203 sal_Int32 nLibDirPos
= url
.indexOf( m_libdir
);
204 if ( nLibDirPos
>= 0 ) {
207 url
.replaceAt( nLibDirPos
, m_libdir
.getLength(), m_datadir
),
208 css::uno::Reference
< css::container::XNameAccess
>()));
212 void ImplImageTree::resetZips() {
216 RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/edition/images.zip"));
217 rtl::Bootstrap::expandMacros(url
);
218 INetURLObject
u(url
);
219 OSL_ASSERT(!u
.HasError());
222 u
.GetMainURL(INetURLObject::NO_DECODE
),
223 css::uno::Reference
< css::container::XNameAccess
>()));
227 RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/share/config"));
228 rtl::Bootstrap::expandMacros(url
);
229 INetURLObject
u(url
);
230 OSL_ASSERT(!u
.HasError());
231 rtl::OUStringBuffer b
;
232 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM("images_"));
234 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM("_brand.zip"));
235 bool ok
= u
.Append(b
.makeStringAndClear(), INetURLObject::ENCODE_ALL
);
236 OSL_ASSERT(ok
); (void) ok
;
237 addUrlToZips(u
.GetMainURL(INetURLObject::NO_DECODE
));
241 RTL_CONSTASCII_USTRINGPARAM(
242 "$BRAND_BASE_DIR/share/config/images_brand.zip"));
243 rtl::Bootstrap::expandMacros(url
);
248 RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/config"));
249 rtl::Bootstrap::expandMacros(url
);
250 INetURLObject
u(url
);
251 OSL_ASSERT(!u
.HasError());
252 rtl::OUStringBuffer b
;
253 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM("images_"));
255 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM(".zip"));
256 bool ok
= u
.Append(b
.makeStringAndClear(), INetURLObject::ENCODE_ALL
);
257 OSL_ASSERT(ok
); (void) ok
;
258 addUrlToZips(u
.GetMainURL(INetURLObject::NO_DECODE
));
262 RTL_CONSTASCII_USTRINGPARAM(
263 "$OOO_BASE_DIR/share/config/images.zip"));
264 rtl::Bootstrap::expandMacros(url
);
269 bool ImplImageTree::cacheLookup(
270 rtl::OUString
const & name
, bool localized
, BitmapEx
& bitmap
)
272 Cache::iterator
i(m_cache
.find(name
));
273 if (i
!= m_cache
.end() && i
->second
.first
== localized
) {
274 bitmap
= i
->second
.second
;
281 bool ImplImageTree::find(
282 std::vector
< rtl::OUString
> const & paths
, BitmapEx
& bitmap
)
284 for (Zips::iterator
i(m_zips
.begin()); i
!= m_zips
.end();) {
285 if (!i
->second
.is()) {
286 css::uno::Sequence
< css::uno::Any
> args(1);
287 args
[0] <<= i
->first
;
290 comphelper::createProcessComponentWithArguments(
292 RTL_CONSTASCII_USTRINGPARAM(
293 "com.sun.star.packages.zip.ZipFileAccess")),
295 css::uno::UNO_QUERY_THROW
);
296 } catch (css::uno::RuntimeException
&) {
298 } catch (css::uno::Exception
& e
) {
300 "ImplImageTree::find exception \"%s\"",
301 rtl::OUStringToOString(
302 e
.Message
, RTL_TEXTENCODING_UTF8
).getStr());
307 for (std::vector
< rtl::OUString
>::const_reverse_iterator
j(
309 j
!= paths
.rend(); ++j
)
311 if (i
->second
->hasByName(*j
)) {
312 css::uno::Reference
< css::io::XInputStream
> s
;
313 bool ok
= i
->second
->getByName(*j
) >>= s
;
314 OSL_ASSERT(ok
); (void) ok
;
315 loadFromStream(s
, *j
, bitmap
);