summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolfo Ribeiro Gomes <rodolforg@gmail.com>2013-05-15 08:05:05 -0300
committerFridrich Strba <fridrich@documentfoundation.org>2013-05-21 19:43:25 +0000
commitd5151ab592367fde7db03fce81e0b76776d18216 (patch)
treeece94e39ffca1fefebf42e4ccf82b5c923646be6
parente8c9a6af25a7ff476e33ad239b70414168aabe3a (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>
-rw-r--r--vcl/inc/impimagetree.hxx7
-rw-r--r--vcl/source/gdi/impimagetree.cxx88
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: */