diff options
author | Gábor Stefanik <netrolller.3d@gmail.com> | 2012-04-28 05:31:17 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-04-30 12:21:45 +0100 |
commit | 1a33c664d7f7a0662b861fbafe3b93a2656bb768 (patch) | |
tree | 1bd41024c80f54807c28499dec10359d0f8fd1e7 | |
parent | dba0aed4ca39b2b40c6609ff336384dcc75c6914 (diff) |
fdo#42779: Implement icon theme lookaside directory
Change-Id: Ib6f7e3b4f750e38198c09cdb4bd8ee2b7161ac53
-rw-r--r-- | vcl/inc/impimagetree.hxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/impimagetree.cxx | 112 |
2 files changed, 88 insertions, 31 deletions
diff --git a/vcl/inc/impimagetree.hxx b/vcl/inc/impimagetree.hxx index 41c4f565ef22..857bff0452e6 100644 --- a/vcl/inc/impimagetree.hxx +++ b/vcl/inc/impimagetree.hxx @@ -78,7 +78,7 @@ private: std::pair< rtl::OUString, com::sun::star::uno::Reference< - com::sun::star::container::XNameAccess > > > Zips; + com::sun::star::container::XNameAccess > > > Paths; typedef boost::unordered_map< rtl::OUString, bool, rtl::OUStringHash > CheckStyleCache; @@ -86,13 +86,14 @@ private: rtl::OUString, std::pair< bool, BitmapEx >, rtl::OUStringHash > IconCache; rtl::OUString m_style; - Zips m_zips; + Paths m_paths; CheckStyleCache m_checkStyleCache; IconCache m_iconCache; + bool m_cacheIcons; void setStyle(rtl::OUString const & style ); - void resetZips(); + void resetPaths(); bool checkStyleCacheLookup( rtl::OUString const & style, bool &exists ); bool iconCacheLookup( rtl::OUString const & name, bool localized, BitmapEx & bitmap ); diff --git a/vcl/source/gdi/impimagetree.cxx b/vcl/source/gdi/impimagetree.cxx index 14dfcd13ae4d..3fed0cfc2b99 100644 --- a/vcl/source/gdi/impimagetree.cxx +++ b/vcl/source/gdi/impimagetree.cxx @@ -82,6 +82,41 @@ rtl::OUString createPath( return b.makeStringAndClear(); } +boost::shared_ptr< SvStream > wrapFile(osl::File & file) +{ + // This could use SvInputStream instead if that did not have a broken + // SeekPos implementation for an XInputStream that is not also XSeekable + // (cf. "@@@" at tags/DEV300_m37/svtools/source/misc1/strmadpt.cxx@264807 + // l. 593): + boost::shared_ptr< SvStream > s(new SvMemoryStream); + for (;;) { + void *data[2048]; + sal_uInt64 n; + file.read(data, 2048, n); + s->Write(data, n); + if (n < 2048) { + break; + } + } + s->Seek(0); + return s; +} + +void loadFromFile( + osl::File & file, + rtl::OUString const & path, BitmapEx & bitmap) +{ + boost::shared_ptr< SvStream > s(wrapFile(file)); + if (path.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".png"))) + { + vcl::PNGReader aPNGReader( *s ); + aPNGReader.SetIgnoreGammaChunk( sal_True ); + bitmap = aPNGReader.Read(); + } else { + *s >> bitmap; + } +} + boost::shared_ptr< SvStream > wrapStream( css::uno::Reference< css::io::XInputStream > const & stream) { @@ -121,7 +156,7 @@ void loadFromStream( } -ImplImageTree::ImplImageTree() {} +ImplImageTree::ImplImageTree() { m_cacheIcons = true; } ImplImageTree::~ImplImageTree() {} @@ -130,7 +165,7 @@ bool ImplImageTree::checkStyle(rtl::OUString const & style) bool exists; // using cache because setStyle is an expensive operation - // setStyle calls resetZips => closes any opened zip files with icons, cleans the icon cache, ... + // setStyle calls resetPaths => closes any opened zip files with icons, cleans the icon cache, ... if (checkStyleCacheLookup(style, exists)) { return exists; } @@ -138,19 +173,27 @@ bool ImplImageTree::checkStyle(rtl::OUString const & style) setStyle(style); exists = false; - const rtl::OUString sBrandURLSuffix(RTL_CONSTASCII_USTRINGPARAM("_brand.zip")); - for (Zips::iterator i(m_zips.begin()); i != m_zips.end() && !exists;) { - ::rtl::OUString aZipURL = i->first; - sal_Int32 nFromIndex = aZipURL.getLength() - sBrandURLSuffix.getLength(); + const rtl::OUString sBrandURLSuffix(RTL_CONSTASCII_USTRINGPARAM("_brand")); + for (Paths::iterator i(m_paths.begin()); i != m_paths.end() && !exists; ++i) { + ::rtl::OUString aURL = i->first; + sal_Int32 nFromIndex = aURL.getLength() - sBrandURLSuffix.getLength(); // skip brand-specific icon themes; they are incomplete and thus not useful for this check - if (nFromIndex < 0 || !aZipURL.match(sBrandURLSuffix, nFromIndex)) { - osl::File aZip(aZipURL); + if (nFromIndex < 0 || !aURL.match(sBrandURLSuffix, nFromIndex)) { + osl::File aZip(aURL + ".zip"); if (aZip.open(osl_File_OpenFlag_Read) == ::osl::FileBase::E_None) { aZip.close(); exists = true; } + + osl::Directory aLookaside(aURL); + if (aLookaside.open() == ::osl::FileBase::E_None) { + aLookaside.close(); + exists = true; + m_cacheIcons = false; + } else { + m_cacheIcons = true; + } } - ++i; } m_checkStyleCache[style] = exists; return exists; @@ -191,7 +234,7 @@ bool ImplImageTree::doLoadImage( bool localized) { setStyle(style); - if (iconCacheLookup(name, localized, bitmap)) { + if (m_cacheIcons && iconCacheLookup(name, localized, bitmap)) { return true; } if (!bitmap.IsEmpty()) { @@ -231,7 +274,7 @@ bool ImplImageTree::doLoadImage( "ImplImageTree::loadImage exception \"%s\"", rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); } - if (found) { + if (m_cacheIcons && found) { m_iconCache[name.intern()] = std::make_pair(localized, bitmap); } return found; @@ -240,7 +283,7 @@ bool ImplImageTree::doLoadImage( void ImplImageTree::shutDown() { m_style = rtl::OUString(); // for safety; empty m_style means "not initialized" - m_zips.clear(); + m_paths.clear(); m_iconCache.clear(); m_checkStyleCache.clear(); } @@ -249,20 +292,20 @@ void ImplImageTree::setStyle(rtl::OUString const & style) { OSL_ASSERT(!style.isEmpty()); // empty m_style means "not initialized" if (style != m_style) { m_style = style; - resetZips(); + resetPaths(); m_iconCache.clear(); } } -void ImplImageTree::resetZips() { - m_zips.clear(); +void ImplImageTree::resetPaths() { + m_paths.clear(); { rtl::OUString url( - RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/edition/images.zip")); + RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/edition/images")); rtl::Bootstrap::expandMacros(url); INetURLObject u(url); OSL_ASSERT(!u.HasError()); - m_zips.push_back( + m_paths.push_back( std::make_pair( u.GetMainURL(INetURLObject::NO_DECODE), css::uno::Reference< css::container::XNameAccess >())); @@ -276,10 +319,10 @@ void ImplImageTree::resetZips() { rtl::OUStringBuffer b; b.appendAscii(RTL_CONSTASCII_STRINGPARAM("images_")); b.append(m_style); - b.appendAscii(RTL_CONSTASCII_STRINGPARAM("_brand.zip")); + b.appendAscii(RTL_CONSTASCII_STRINGPARAM("_brand")); bool ok = u.Append(b.makeStringAndClear(), INetURLObject::ENCODE_ALL); OSL_ASSERT(ok); (void) ok; - m_zips.push_back( + m_paths.push_back( std::make_pair( u.GetMainURL(INetURLObject::NO_DECODE), css::uno::Reference< css::container::XNameAccess >())); @@ -287,9 +330,9 @@ void ImplImageTree::resetZips() { { rtl::OUString url( RTL_CONSTASCII_USTRINGPARAM( - "$BRAND_BASE_DIR/share/config/images_brand.zip")); + "$BRAND_BASE_DIR/share/config/images_brand")); rtl::Bootstrap::expandMacros(url); - m_zips.push_back( + m_paths.push_back( std::make_pair( url, css::uno::Reference< css::container::XNameAccess >())); } @@ -302,10 +345,9 @@ void ImplImageTree::resetZips() { rtl::OUStringBuffer b; b.appendAscii(RTL_CONSTASCII_STRINGPARAM("images_")); b.append(m_style); - b.appendAscii(RTL_CONSTASCII_STRINGPARAM(".zip")); bool ok = u.Append(b.makeStringAndClear(), INetURLObject::ENCODE_ALL); OSL_ASSERT(ok); (void) ok; - m_zips.push_back( + m_paths.push_back( std::make_pair( u.GetMainURL(INetURLObject::NO_DECODE), css::uno::Reference< css::container::XNameAccess >())); @@ -314,9 +356,9 @@ void ImplImageTree::resetZips() { { rtl::OUString url( RTL_CONSTASCII_USTRINGPARAM( - "$BRAND_BASE_DIR/share/config/images.zip")); + "$BRAND_BASE_DIR/share/config/images")); rtl::Bootstrap::expandMacros(url); - m_zips.push_back( + m_paths.push_back( std::make_pair( url, css::uno::Reference< css::container::XNameAccess >())); } @@ -349,10 +391,24 @@ bool ImplImageTree::iconCacheLookup( bool ImplImageTree::find( std::vector< rtl::OUString > const & paths, BitmapEx & bitmap) { - for (Zips::iterator i(m_zips.begin()); i != m_zips.end();) { + for (Paths::iterator i(m_paths.begin()); i != m_paths.end(); ++i) { + for (std::vector< rtl::OUString >::const_reverse_iterator j( + paths.rbegin()); + j != paths.rend(); ++j) + { + osl::File file(i->first + "/" + *j); + if (file.open(osl_File_OpenFlag_Read) == ::osl::FileBase::E_None) { + loadFromFile(file, *j, bitmap); + file.close(); + return true; + } + } + } + + for (Paths::iterator i(m_paths.begin()); i != m_paths.end();) { if (!i->second.is()) { css::uno::Sequence< css::uno::Any > args(1); - args[0] <<= i->first; + args[0] <<= i->first + ".zip"; try { i->second.set( comphelper::createProcessComponentWithArguments( @@ -368,7 +424,7 @@ bool ImplImageTree::find( "ImplImageTree::find exception \"%s\"", rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8).getStr()); - i = m_zips.erase(i); + i = m_paths.erase(i); continue; } } |