diff options
author | Rodolfo Ribeiro Gomes <rodolforg@gmail.com> | 2013-05-15 08:05:05 -0300 |
---|---|---|
committer | Fridrich Strba <fridrich@documentfoundation.org> | 2013-05-21 19:43:25 +0000 |
commit | d5151ab592367fde7db03fce81e0b76776d18216 (patch) | |
tree | ece94e39ffca1fefebf42e4ccf82b5c923646be6 /vcl | |
parent | e8c9a6af25a7ff476e33ad239b70414168aabe3a (diff) |
Allow 'textual links' on icon theme packages
This would allow use of better icon names ( fdo#30425 ) and
minimizes space size needed by reuses of same icons bitmaps
with different filenames.
Icon packages shoud have a file named "links.txt" on root folder
in order to achieve that. It binds a name of a 'virtual' file to
an existing one, to avoid duplicates.
This file should contain one or more lines like this:
path/for/fakefile_that_reuse_a_bitmap.png path/for/existing_one.png
Implemented as discussed in:
http://lists.freedesktop.org/archives/libreoffice/2013-April/049650.html
Change-Id: Ia65a1ba18f93297fae47fa520104821f6f336694
Signed-off-by: Rodolfo Ribeiro Gomes <rodolforg@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/3953
Reviewed-by: Fridrich Strba <fridrich@documentfoundation.org>
Tested-by: Fridrich Strba <fridrich@documentfoundation.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/impimagetree.hxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/impimagetree.cxx | 88 |
2 files changed, 92 insertions, 3 deletions
diff --git a/vcl/inc/impimagetree.hxx b/vcl/inc/impimagetree.hxx index d22e770e1016..11c003e2b079 100644 --- a/vcl/inc/impimagetree.hxx +++ b/vcl/inc/impimagetree.hxx @@ -72,12 +72,15 @@ private: OUString, bool, OUStringHash > CheckStyleCache; typedef boost::unordered_map< OUString, std::pair< bool, BitmapEx >, OUStringHash > IconCache; + typedef boost::unordered_map< + OUString, OUString, OUStringHash > IconLinkCache; OUString m_style; Path m_path; CheckStyleCache m_checkStyleCache; IconCache m_iconCache; bool m_cacheIcons; + IconLinkCache m_iconLinkCache; void setStyle(OUString const & style ); @@ -87,6 +90,10 @@ private: bool iconCacheLookup( OUString const & name, bool localized, BitmapEx & bitmap ); bool find(std::vector< OUString > const & paths, BitmapEx & bitmap ); + + void loadImageLinks(); + void parseLinkFile(boost::shared_ptr< SvStream > stream); + OUString const & getRealImageName(OUString const & name); }; typedef salhelper::SingletonRef< ImplImageTree > ImplImageTreeSingletonRef; diff --git a/vcl/source/gdi/impimagetree.cxx b/vcl/source/gdi/impimagetree.cxx index bb0013fbd000..857a080f4756 100644 --- a/vcl/source/gdi/impimagetree.cxx +++ b/vcl/source/gdi/impimagetree.cxx @@ -194,7 +194,7 @@ bool ImplImageTree::doLoadImage( bitmap.SetEmpty(); } std::vector< OUString > paths; - paths.push_back(name); + paths.push_back(getRealImageName(name)); if (localized) { sal_Int32 pos = name.lastIndexOf('/'); if (pos != -1) { @@ -203,7 +203,7 @@ bool ImplImageTree::doLoadImage( for (std::vector< OUString >::const_reverse_iterator it( aFallbacks.rbegin()); it != aFallbacks.rend(); ++it) { - paths.push_back(createPath(name, pos, *it)); + paths.push_back( getRealImageName( createPath(name, pos, *it) ) ); } } } @@ -226,6 +226,7 @@ void ImplImageTree::shutDown() { // for safety; empty m_style means "not initialized" m_iconCache.clear(); m_checkStyleCache.clear(); + m_iconLinkCache.clear(); } void ImplImageTree::setStyle(OUString const & style) { @@ -234,6 +235,8 @@ void ImplImageTree::setStyle(OUString const & style) { m_style = style; resetPaths(); m_iconCache.clear(); + m_iconLinkCache.clear(); + loadImageLinks(); } } @@ -282,7 +285,8 @@ bool ImplImageTree::find( std::vector< OUString > const & paths, BitmapEx & bitmap) { if (!m_cacheIcons) { - for (std::vector< OUString >::const_reverse_iterator j(paths.rbegin()); + for (std::vector< OUString >::const_reverse_iterator j( + paths.rbegin()); j != paths.rend(); ++j) { osl::File file(m_path.first + "/" + *j); @@ -325,4 +329,82 @@ bool ImplImageTree::find( return false; } +void ImplImageTree::loadImageLinks() +{ + const OUString aLinkFilename("links.txt"); + + if (!m_cacheIcons) + { + osl::File file(m_path.first + "/" + aLinkFilename); + if (file.open(osl_File_OpenFlag_Read) == ::osl::FileBase::E_None) + { + parseLinkFile( wrapFile(file) ); + file.close(); + return; + } + } + + if ( !m_path.second.is() ) + { + css::uno::Sequence< css::uno::Any > args(1); + args[0] <<= m_path.first + ".zip"; + try + { + m_path.second.set( + comphelper::getProcessServiceFactory()->createInstanceWithArguments( + OUString( "com.sun.star.packages.zip.ZipFileAccess"), + args), + css::uno::UNO_QUERY_THROW); + } + catch (css::uno::RuntimeException &) + { + throw; + } + catch (const css::uno::Exception & e) + { + SAL_INFO("vcl", "ImplImageTree::find exception " + << e.Message << " for " << m_path.first); + return; + } + } + if ( m_path.second->hasByName(aLinkFilename) ) + { + css::uno::Reference< css::io::XInputStream > s; + bool ok = m_path.second->getByName(aLinkFilename) >>= s; + OSL_ASSERT(ok); (void) ok; + + parseLinkFile( wrapStream(s) ); + return; + } +} + +void ImplImageTree::parseLinkFile(boost::shared_ptr< SvStream > pStream) +{ + OString aLine; + OUString aLink, aOriginal; + while ( pStream->ReadLine( aLine ) ) + { + sal_Int32 nIndex = 0; + if ( aLine.isEmpty() ) + continue; + aLink = OStringToOUString( aLine.getToken(0, ' ', nIndex), RTL_TEXTENCODING_UTF8 ); + aOriginal = OStringToOUString( aLine.getToken(0, ' ', nIndex), RTL_TEXTENCODING_UTF8 ); + if ( aLink.isEmpty() || aOriginal.isEmpty() ) + { + SAL_INFO("vcl", "ImplImageTree::parseLinkFile: icon links.txt parse error. " + "Link is incomplete." ); + continue; + } + m_iconLinkCache[aLink] = aOriginal; + } +} + +OUString const & ImplImageTree::getRealImageName(OUString const & name) +{ + IconLinkCache::iterator it(m_iconLinkCache.find(name)); + if (it == m_iconLinkCache.end()) + return name; + return it->second; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |