[Libreoffice-commits] core.git: cui/source framework/inc framework/source include/sfx2 include/svtools include/vcl sfx2/source svtools/source vcl/CppunitTest_vcl_app_test.mk vcl/inc vcl/Library_vcl.mk vcl/Module_vcl.mk vcl/qa vcl/source vcl/unx

Tobias Lippert drtl at fastmail.fm
Fri Feb 21 09:24:19 PST 2014


 cui/source/options/optgdlg.cxx                        |   88 ++---
 cui/source/options/optgdlg.hxx                        |    8 
 framework/inc/uielement/menubarmanager.hxx            |    2 
 framework/inc/uielement/toolbarmanager.hxx            |    2 
 framework/source/uiconfiguration/imagemanagerimpl.cxx |    9 
 framework/source/uiconfiguration/imagemanagerimpl.hxx |    2 
 framework/source/uielement/menubarmanager.cxx         |   12 
 framework/source/uielement/toolbarmanager.cxx         |   12 
 include/sfx2/mnuitem.hxx                              |    2 
 include/svtools/miscopt.hxx                           |    7 
 include/vcl/IconThemeInfo.hxx                         |   97 ++++++
 include/vcl/IconThemeScanner.hxx                      |  103 ++++++
 include/vcl/IconThemeSelector.hxx                     |  101 ++++++
 include/vcl/settings.hxx                              |  116 +++----
 include/vcl/toolbox.hxx                               |    4 
 sfx2/source/menu/mnuitem.cxx                          |   14 
 svtools/source/config/miscopt.cxx                     |  155 ++++++----
 svtools/source/misc/imagemgr.cxx                      |    7 
 vcl/CppunitTest_vcl_app_test.mk                       |   30 ++
 vcl/Library_vcl.mk                                    |    3 
 vcl/Module_vcl.mk                                     |    1 
 vcl/inc/toolbox.h                                     |    7 
 vcl/qa/cppunit/app/test_IconThemeInfo.cxx             |  143 +++++++++
 vcl/qa/cppunit/app/test_IconThemeScanner.cxx          |   86 +++++
 vcl/qa/cppunit/app/test_IconThemeSelector.cxx         |  198 +++++++++++++
 vcl/source/app/IconThemeInfo.cxx                      |  180 ++++++++++++
 vcl/source/app/IconThemeScanner.cxx                   |  185 ++++++++++++
 vcl/source/app/IconThemeSelector.cxx                  |  156 ++++++++++
 vcl/source/app/settings.cxx                           |  265 +++++-------------
 vcl/source/control/fixed.cxx                          |    8 
 vcl/source/gdi/bitmapex.cxx                           |    4 
 vcl/source/gdi/image.cxx                              |    4 
 vcl/source/gdi/imagerepository.cxx                    |    8 
 vcl/source/window/toolbox2.cxx                        |   40 --
 vcl/source/window/window.cxx                          |    1 
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx              |    2 
 vcl/unx/kde/salnativewidgets-kde.cxx                  |    2 
 37 files changed, 1621 insertions(+), 443 deletions(-)

New commits:
commit 076a7eacca48f203f0a8b9aa537e88fea9a88409
Author: Tobias Lippert <drtl at fastmail.fm>
Date:   Sun Feb 9 00:53:28 2014 +0100

    Bug #63962 Dynamically scan the config directory for icon themes
    
    The hard-coded icon themes have been replaced by a dynamic list
    which is filled by scanning the config directory
    
    Conflicts:
    	include/vcl/settings.hxx
    	vcl/source/app/settings.cxx
    	vcl/source/window/window.cxx
    
    Change-Id: Ie3680ffe27d06e375acf22753e036cb6ddabc4ed
    Reviewed-on: https://gerrit.libreoffice.org/7935
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index f93dc04..92fe1df 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -85,6 +85,7 @@
 
 #include <vcl/svapp.hxx>
 #include <vcl/settings.hxx>
+#include <vcl/IconThemeInfo.hxx>
 
 #include "optgdlg.hxx"
 #include <svx/ofaitem.hxx>
@@ -538,7 +539,6 @@ OfaViewTabPage::OfaViewTabPage(Window* pParent, const SfxItemSet& rSet)
     : SfxTabPage(pParent, "OptViewPage", "cui/ui/optviewpage.ui", rSet)
     , nSizeLB_InitialSelection(0)
     , nStyleLB_InitialSelection(0)
-    , aIconStyleItemId(STYLE_SYMBOLS_THEMES_MAX, 0)
     , pAppearanceCfg(new SvtTabAppearanceCfg)
     , pCanvasSettings(new CanvasSettings)
     , mpDrawinglayerOpt(new SvtOptionsDrawinglayer)
@@ -593,50 +593,27 @@ OfaViewTabPage::OfaViewTabPage(Window* pParent, const SfxItemSet& rSet)
         m_pSystemFont->Enable(false);
     }
 
-    const StyleSettings& aStyleSettings = Application::GetSettings().GetStyleSettings();
+    // Set known icon themes
+    m_pIconStyleLB->Clear();
+    StyleSettings aStyleSettings = Application::GetSettings().GetStyleSettings();
+    mInstalledIconThemes = aStyleSettings.GetInstalledIconThemes();
 
-    // remove non-installed icon themes
-    if( m_pIconStyleLB->GetEntryCount() == STYLE_SYMBOLS_THEMES_MAX )
-    {
-        // do not check 0th item == auto; it is not a real theme
-        aIconStyleItemId[0] = 0;
-        sal_uLong nItem = 1;
-        for ( sal_uLong n=0; ++n < STYLE_SYMBOLS_THEMES_MAX; )
-        {
-            if ( aStyleSettings.CheckSymbolStyle( n ) )
-            {
-                // existing style => save the item id
-                aIconStyleItemId[n] = nItem++;
-            }
-            else
-            {
-                // non-existing style => remove item;
-                m_pIconStyleLB->RemoveEntry( nItem );
-                aIconStyleItemId[n] = 0;
-            }
-        }
-    }
+    // Start with the automatically chosen icon theme
+    OUString autoThemeId = aStyleSettings.GetAutomaticallyChosenIconTheme();
+    const vcl::IconThemeInfo& autoIconTheme = vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, autoThemeId);
 
-    // add real theme name to 'auto' theme, e.g. 'auto' => 'auto (classic)'
-    if( m_pIconStyleLB->GetEntryCount() > 1 )
-    {
-        OUString aAutoStr( m_pIconStyleLB->GetEntry( 0 ) );
+    OUString entryForAuto = OUString("Auto (") +
+                                autoIconTheme.GetDisplayName() +
+                                OUString(")");
+    m_pIconStyleLB->InsertEntry(entryForAuto);
 
-        aAutoStr += " (";
-
-        // prefer the icon style set by the desktop native widgets modules
-        sal_uLong nAutoStyle = aStyleSettings.GetPreferredSymbolsStyle();
-        // fallback to the statically defined values
-        if ( nAutoStyle == STYLE_SYMBOLS_AUTO || !aIconStyleItemId.at(nAutoStyle) )
-            nAutoStyle = aStyleSettings.GetAutoSymbolsStyle();
-        if ( aIconStyleItemId.at(nAutoStyle) )
-            aAutoStr += m_pIconStyleLB->GetEntry( aIconStyleItemId.at(nAutoStyle) );
-
-        m_pIconStyleLB->RemoveEntry( 0 );
-        m_pIconStyleLB->InsertEntry( aAutoStr += ")", 0 );
-        // separate auto and other icon themes
-        m_pIconStyleLB->SetSeparatorPos( 0 );
+    for (const vcl::IconThemeInfo& i : mInstalledIconThemes) {
+        m_pIconStyleLB->InsertEntry(i.GetDisplayName());
     }
+
+    // separate auto and other icon themes
+    m_pIconStyleLB->SetSeparatorPos( 0 );
+    m_pIconStyleLB->SelectEntryPos(0);
 }
 
 OfaViewTabPage::~OfaViewTabPage()
@@ -703,16 +680,16 @@ sal_Bool OfaViewTabPage::FillItemSet( SfxItemSet& )
     sal_uInt16 nStyleLB_NewSelection = m_pIconStyleLB->GetSelectEntryPos();
     if( nStyleLB_InitialSelection != nStyleLB_NewSelection )
     {
-        // find the style name in the aIconStyleItemId table
-        // items from the non-installed icon themes were removed
-        for ( sal_uLong n=0; n < STYLE_SYMBOLS_THEMES_MAX; n++ )
-        {
-            if ( aIconStyleItemId[n] == nStyleLB_NewSelection )
-            {
-                aMiscOptions.SetSymbolsStyle( n );
-                n = STYLE_SYMBOLS_THEMES_MAX;
-            }
+        // 0 means choose style automatically
+        if (nStyleLB_NewSelection == 0) {
+            aMiscOptions.SetIconThemeAutomatically();
+        }
+        else {
+            sal_uInt16 pos = m_pIconStyleLB->GetSelectEntryPos();
+            const vcl::IconThemeInfo& iconThemeId = mInstalledIconThemes.at(pos-1);
+            aMiscOptions.SetIconTheme(iconThemeId.GetThemeId());
         }
+        nStyleLB_InitialSelection = nStyleLB_NewSelection;
     }
 
     sal_Bool bAppearanceChanged = sal_False;
@@ -880,8 +857,15 @@ void OfaViewTabPage::Reset( const SfxItemSet& )
     m_pIconSizeLB->SelectEntryPos( nSizeLB_InitialSelection );
     m_pIconSizeLB->SaveValue();
 
-    if( aMiscOptions.GetSymbolsStyle() != STYLE_SYMBOLS_AUTO )
-        nStyleLB_InitialSelection = aIconStyleItemId.at(aMiscOptions.GetCurrentSymbolsStyle());
+    if (aMiscOptions.IconThemeWasSetAutomatically()) {
+        nStyleLB_InitialSelection = 0;
+    }
+    else {
+        const OUString& selected = aMiscOptions.GetIconTheme();
+        const vcl::IconThemeInfo& selectedInfo =
+                vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, selected);
+        nStyleLB_InitialSelection = m_pIconStyleLB->GetEntryPos(selectedInfo.GetDisplayName());
+    }
 
     m_pIconStyleLB->SelectEntryPos( nStyleLB_InitialSelection );
     m_pIconStyleLB->SaveValue();
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
index 6f2f7c8..79aaeae 100644
--- a/cui/source/options/optgdlg.hxx
+++ b/cui/source/options/optgdlg.hxx
@@ -28,6 +28,9 @@
 // predeclarations
 class CanvasSettings;
 class SvtOptionsDrawinglayer;
+namespace vcl {
+class IconThemeInfo;
+}
 
 // class OfaMiscTabPage --------------------------------------------------
 
@@ -104,13 +107,12 @@ private:
     sal_uInt16      nSizeLB_InitialSelection;
     sal_uInt16      nStyleLB_InitialSelection;
 
-    // item ID for the given icon theme
-    // might be zero when the theme is not installed and the item is removed
-    std::vector<unsigned> aIconStyleItemId;
     SvtTabAppearanceCfg*    pAppearanceCfg;
     CanvasSettings*         pCanvasSettings;
     SvtOptionsDrawinglayer* mpDrawinglayerOpt;
 
+    std::vector<vcl::IconThemeInfo> mInstalledIconThemes;
+
 #if defined( UNX )
     DECL_LINK( OnAntialiasingToggled, void* );
 #endif
diff --git a/framework/inc/uielement/menubarmanager.hxx b/framework/inc/uielement/menubarmanager.hxx
index ce61dda..88ef560 100644
--- a/framework/inc/uielement/menubarmanager.hxx
+++ b/framework/inc/uielement/menubarmanager.hxx
@@ -246,7 +246,7 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener
         ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >           m_xContext;
         ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer >            m_xURLTransformer;
         ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >          m_xDeferedItemContainer;
-        sal_Int16                                                                              m_nSymbolsStyle;
+        OUString                                                                               m_sIconTheme;
         Timer                                                                                  m_aAsyncSettingsTimer;
 };
 
diff --git a/framework/inc/uielement/toolbarmanager.hxx b/framework/inc/uielement/toolbarmanager.hxx
index 7542b29..14462bb 100644
--- a/framework/inc/uielement/toolbarmanager.hxx
+++ b/framework/inc/uielement/toolbarmanager.hxx
@@ -210,7 +210,7 @@ class ToolBarManager : public ToolbarManager_Base,
         CommandToInfoMap                                                                       m_aCommandMap;
         SubToolBarToSubToolBarControllerMap                                                    m_aSubToolBarControllerMap;
         Timer                                                                                  m_aAsyncUpdateControllersTimer;
-        sal_Int16                                                                              m_nSymbolsStyle;
+        OUString                                                                               m_sIconTheme;
         MenuDescriptionMap m_aMenuMap;
         sal_Bool                                                                               m_bAcceleratorCfg;
         ::com::sun::star::uno::Reference< ::com::sun::star::ui::XAcceleratorConfiguration >    m_xDocAcceleratorManager;
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.cxx b/framework/source/uiconfiguration/imagemanagerimpl.cxx
index 7cf71e8..b83766c 100644
--- a/framework/source/uiconfiguration/imagemanagerimpl.cxx
+++ b/framework/source/uiconfiguration/imagemanagerimpl.cxx
@@ -153,7 +153,7 @@ CmdImageList::CmdImageList( const uno::Reference< uno::XComponentContext >& rxCo
     m_bVectorInit( sal_False ),
     m_aModuleIdentifier( aModuleIdentifier ),
     m_xContext( rxContext ),
-    m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+    m_sIconTheme( SvtMiscOptions().GetIconTheme() )
 {
     for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
         m_pImageList[n] = 0;
@@ -260,10 +260,10 @@ ImageList* CmdImageList::impl_getImageList( sal_Int16 nImageType )
 {
     SvtMiscOptions aMiscOptions;
 
-    sal_Int16 nSymbolsStyle = aMiscOptions.GetCurrentSymbolsStyle();
-    if ( nSymbolsStyle != m_nSymbolsStyle )
+    const OUString& rIconTheme = aMiscOptions.GetIconTheme();
+    if ( rIconTheme != m_sIconTheme )
     {
-        m_nSymbolsStyle = nSymbolsStyle;
+        m_sIconTheme = rIconTheme;
         for ( sal_Int32 n=0; n < ImageType_COUNT; n++ )
             delete m_pImageList[n], m_pImageList[n] = NULL;
     }
@@ -647,6 +647,7 @@ sal_Bool ImageManagerImpl::implts_storeUserImages(
 
     return sal_False;
 }
+
 const rtl::Reference< GlobalImageList >& ImageManagerImpl::implts_getGlobalImageList()
 {
     ResetableGuard aGuard( m_aLock );
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.hxx b/framework/source/uiconfiguration/imagemanagerimpl.hxx
index 2040dbe..b8888d2 100644
--- a/framework/source/uiconfiguration/imagemanagerimpl.hxx
+++ b/framework/source/uiconfiguration/imagemanagerimpl.hxx
@@ -81,7 +81,7 @@ namespace framework
             ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >     m_xContext;
             ::std::vector< OUString >                                                   m_aImageNameVector;
             ::std::vector< OUString >                                                   m_aImageCommandNameVector;
-            sal_Int16                                                                        m_nSymbolsStyle;
+            OUString                                                                    m_sIconTheme;
     };
 
     class GlobalImageList : public CmdImageList, public rtl::IReference
diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx
index ec6e846..aca7a24 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -178,7 +178,7 @@ MenuBarManager::MenuBarManager(
     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
     , m_xContext(rxContext)
     , m_xURLTransformer(_xURLTransformer)
-    , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+    , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
 {
     m_xPopupMenuControllerFactory = frame::thePopupMenuControllerFactory::get(m_xContext);
     FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren );
@@ -200,7 +200,7 @@ MenuBarManager::MenuBarManager(
     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
     , m_xContext(rxContext)
     , m_xURLTransformer(_xURLTransformer)
-    , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+    , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
 {
     Init(rFrame,pAddonMenu,bDelete,bDeleteChildren);
 }
@@ -221,7 +221,7 @@ MenuBarManager::MenuBarManager(
     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
     , m_xContext(rxContext)
     , m_xURLTransformer(_xURLTransformer)
-    , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() )
+    , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
 {
     Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true);
 }
@@ -821,15 +821,15 @@ IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu )
              MenuManager::UpdateSpecialWindowMenu( pMenu, m_xContext, m_aLock );
 
         // Check if some modes have changed so we have to update our menu images
-        sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle();
+        OUString sIconTheme = SvtMiscOptions().GetIconTheme();
 
         if ( m_bRetrieveImages ||
              bShowMenuImages != m_bShowMenuImages ||
-             nSymbolsStyle != m_nSymbolsStyle )
+             sIconTheme != m_sIconTheme )
         {
             m_bShowMenuImages   = bShowMenuImages;
             m_bRetrieveImages   = sal_False;
-            m_nSymbolsStyle     = nSymbolsStyle;
+            m_sIconTheme     = sIconTheme;
             MenuManager::FillMenuImages( m_xFrame, pMenu, bShowMenuImages );
         }
 
diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx
index cecbb66..a1afbab 100644
--- a/framework/source/uielement/toolbarmanager.cxx
+++ b/framework/source/uielement/toolbarmanager.cxx
@@ -201,7 +201,7 @@ ToolBarManager::ToolBarManager( const Reference< XComponentContext >& rxContext,
     m_xFrame( rFrame ),
     m_aListenerContainer( m_aLock.getShareableOslMutex() ),
     m_xContext( rxContext ),
-    m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ),
+    m_sIconTheme( SvtMiscOptions().GetIconTheme() ),
     m_bAcceleratorCfg( sal_False )
 {
     OSL_ASSERT( m_xContext.is() );
@@ -318,15 +318,15 @@ void ToolBarManager::CheckAndUpdateImages()
     bool bCurrentSymbolsSmall = !aMiscOptions.AreCurrentSymbolsLarge();
     if ( m_bSmallSymbols != bCurrentSymbolsSmall )
     {
-        bRefreshImages = sal_True;
+        bRefreshImages = true;
         m_bSmallSymbols = bCurrentSymbolsSmall;
     }
 
-    sal_Int16 nCurrentSymbolsStyle = aMiscOptions.GetCurrentSymbolsStyle();
-    if ( m_nSymbolsStyle != nCurrentSymbolsStyle )
+    const OUString& sCurrentIconTheme = aMiscOptions.GetIconTheme();
+    if ( m_sIconTheme != sCurrentIconTheme )
     {
-        bRefreshImages = sal_True;
-        m_nSymbolsStyle = nCurrentSymbolsStyle;
+        bRefreshImages = true;
+        m_sIconTheme = sCurrentIconTheme;
     }
 
     // Refresh images if requested
diff --git a/include/sfx2/mnuitem.hxx b/include/sfx2/mnuitem.hxx
index 51d2c65..72f5c2f 100644
--- a/include/sfx2/mnuitem.hxx
+++ b/include/sfx2/mnuitem.hxx
@@ -122,7 +122,7 @@ inline SfxVirtualMenu* SfxMenuControl::GetPopupMenu() const
 class SfxAppMenuControl_Impl : public SfxMenuControl
 {
     PopupMenu*  pMenu;
-    sal_uIntPtr m_nSymbolsStyle;
+    OUString    m_sIconTheme;
     sal_Bool    m_bShowMenuImages;
 
 protected:
diff --git a/include/svtools/miscopt.hxx b/include/svtools/miscopt.hxx
index 5c5da58..14ff116 100644
--- a/include/svtools/miscopt.hxx
+++ b/include/svtools/miscopt.hxx
@@ -86,9 +86,10 @@ class SVT_DLLPUBLIC SvtMiscOptions: public utl::detail::Options
         sal_Int16   GetCurrentSymbolsSize() const;
         bool        AreCurrentSymbolsLarge() const;
 
-        sal_Int16   GetSymbolsStyle() const;
-        void        SetSymbolsStyle( sal_Int16 eSet );
-        sal_Int16   GetCurrentSymbolsStyle() const;
+        OUString    GetIconTheme() const;
+        void        SetIconTheme(const OUString&);
+        void        SetIconThemeAutomatically();
+        bool        IconThemeWasSetAutomatically();
 
         sal_Int16   GetToolboxStyle() const;
         void        SetToolboxStyle( sal_Int16 nStyle );
diff --git a/include/vcl/IconThemeInfo.hxx b/include/vcl/IconThemeInfo.hxx
new file mode 100644
index 0000000..f745884
--- /dev/null
+++ b/include/vcl/IconThemeInfo.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef VCL_ICONTHEMEINFO_HXX_
+#define VCL_ICONTHEMEINFO_HXX_
+
+#include <vcl/dllapi.h>
+// for Size
+#include <tools/gen.hxx>
+#include <rtl/ustring.hxx>
+
+#include <vector>
+
+// forward declaration of unit test classes. Required for friend relationship.
+class IconThemeInfoTest;
+class IconThemeSelectorTest;
+class IconThemeScannerTest;
+
+namespace vcl {
+
+/** This class provides information about an icon theme.
+ */
+class SAL_DLLPUBLIC_EXPORT IconThemeInfo {
+
+public:
+
+    /** Construct an IconThemeInfo from the URL to a file.
+     * This method will throw a std::runtime_error if the URL cannot be properly parsed.
+     * Check the URL with UrlCanBeParsed() first.
+     */
+    IconThemeInfo(const OUString& urlToFile);
+
+    const OUString& GetDisplayName() const {return mDisplayName;}
+
+    const OUString& GetThemeId() const { return mThemeId; }
+
+    const OUString& GetUrlToFile() const { return mUrlToFile; }
+
+    /** Obtain the icon size by theme name.
+     * @internal
+     * It is not clear where this information belongs to. The sizes were hard-coded before they moved here.
+     * Maybe there is a way to determine the sizes from the icon theme packages.
+     */
+    static Size SizeByThemeName(const OUString&);
+
+    /** Check whether a IconThemeInfo can be constructed from an URL */
+    static bool UrlCanBeParsed(const OUString& url);
+
+    /** Find an icon theme by its id in a vector.
+     * Throws a runtime_error if the theme is not contained in the vector
+     */
+    static const vcl::IconThemeInfo&
+    FindIconThemeById(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId);
+
+    /** Check whether a theme with a specified id is in a vector of IconThemeInfo */
+    static bool
+    IconThemeIsInVector(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId);
+
+private:
+    /** private constructor for testing purposes only */
+    IconThemeInfo();
+
+    /** Determine the icon theme name from the filename
+     * If the name has an underscore, the name is taken from the first underscore to the last dot,
+     * e.g., images_oxygen.zip becomes oxygen
+     * If the name does not have an underscore in it, the whole name until the last dot is returned,
+     * e.g. default.zip becomes default
+     */
+    static OUString FileNameToThemeId(const OUString&);
+
+    /** Creates the display name for the given id of a file.
+     * Currently, we only uppercase the id.
+     */
+    static OUString ThemeIdToDisplayName(const OUString&);
+
+    /** The name which is presented to the user */
+    OUString mDisplayName;
+    /** The theme id. This id is used in ... to determine the file name */
+    OUString mThemeId;
+    /** The url to the icon theme package */
+    OUString mUrlToFile;
+
+    friend class ::IconThemeInfoTest;
+    friend class ::IconThemeScannerTest;
+    friend class ::IconThemeSelectorTest;
+};
+
+} // namespace vcl
+
+
+#endif /* VCL_ICONTHEMEINFO_HXX_ */
diff --git a/include/vcl/IconThemeScanner.hxx b/include/vcl/IconThemeScanner.hxx
new file mode 100644
index 0000000..3f6ad25
--- /dev/null
+++ b/include/vcl/IconThemeScanner.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef VCL_ICONTHEMESCANNER_HXX_
+#define VCL_ICONTHEMESCANNER_HXX_
+
+#include <vcl/dllapi.h>
+#include <tools/solar.h>
+
+#include <rtl/ustring.hxx>
+
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+// forward declaration of unit test class. Required for friend relationship.
+class IconThemeScannerTest;
+
+namespace osl {
+class Directory;
+class DirectoryItem;
+}
+
+namespace vcl {
+class IconThemeInfo;
+
+/** This class scans a folder for icon themes and provides the results.
+ */
+class SAL_DLLPUBLIC_EXPORT IconThemeScanner
+{
+public:
+    ~IconThemeScanner();
+
+    /** Factory method to create the object.
+     * Provide a path to search for IconThemes.
+     */
+    static boost::shared_ptr<IconThemeScanner>
+    Create(const OUString &path);
+
+    /** This method will return the standard path where icon themes are located.
+     */
+    static OUString
+    GetStandardIconThemePath();
+
+    const std::vector<IconThemeInfo>&
+    GetFoundIconThemes() const {return mFoundIconThemes;}
+
+    /** Get the IconThemeInfo for a theme.
+     * If the theme id is not among the found themes, a std::runtime_error will be thrown.
+     * Use IconThemeIsInstalled() to check whether it is available.
+     */
+    const IconThemeInfo& GetIconThemeInfo(const OUString& themeId);
+
+    /** Checks whether the theme with the provided name has been found in the
+     * scanned directory.
+     */
+    bool
+    IconThemeIsInstalled(const OUString& themeId) const;
+
+private:
+    IconThemeScanner();
+
+    /** Scan a directory for icon themes.
+     *
+     * @return
+     * This method will return true on success.
+     * There are several cases when this method will fail:
+     * - The directory does not exist
+     * - There are no files which which match the pattern images_xxx.zip
+     */
+    bool
+    ScanDirectoryForIconThemes(const OUString &path);
+
+    /** Adds the provided icon theme by path.
+     */
+    bool
+    AddIconThemeByPath(const OUString &path);
+
+    /** Scans the provided directory for icon themes.
+     * The returned strings will contain the URLs to the icon themes.
+     */
+    static std::vector<OUString>
+    ReadIconThemesFromPath(const OUString& dir);
+
+    /** Check whether a single file is valid */
+    static bool
+    FileIsValidIconTheme(const OUString&);
+
+    std::vector<IconThemeInfo> mFoundIconThemes;
+
+    friend class ::IconThemeScannerTest;
+};
+
+} // end namespace vcl
+
+#endif /* VCL_ICONTHEMESCANNER_HXX_ */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/IconThemeSelector.hxx b/include/vcl/IconThemeSelector.hxx
new file mode 100644
index 0000000..35bde9e
--- /dev/null
+++ b/include/vcl/IconThemeSelector.hxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef VCL_ICONTHEMESELECTOR_HXX_
+#define VCL_ICONTHEMESELECTOR_HXX_
+
+#include <rtl/ustring.hxx>
+
+#include <vcl/dllapi.h>
+
+#include <vector>
+
+// forward declaration of unit test class. Required for friend relationship.
+class IconThemeSelectorTest;
+
+namespace vcl {
+struct IconThemeInfo;
+
+/** This class helps to choose an icon theme from a list of installed themes.
+ *
+ * The following factors influence the selection:
+ * -# When high contrast mode is enabled, the high contrast icon theme is selected (if it is installed).
+ * -# When a preferred theme has been set (e.g., in the gnome desktop settings), that theme is selected.
+ */
+class SAL_DLLPUBLIC_EXPORT IconThemeSelector {
+public:
+    IconThemeSelector();
+
+    /** Select an icon theme from the list of installed themes.
+     *
+     * If high contrast mode has been enabled, the highcontrast theme will be selected (if it is available).
+     *
+     * @pre
+     * @p installedThemes must not be empty
+     */
+    OUString
+    SelectIconTheme(
+            const std::vector<IconThemeInfo>& installedThemes,
+            const OUString& theme
+            ) const;
+
+    /** Select the standard icon theme for a desktop environment from a list of installed themes.
+     *
+     * If a preferred theme has been set, this one will take precedence.
+     *
+     * The same logic as in SelectIconTheme() will apply.
+     *
+     * @pre
+     * @p installedThemes must not be empty
+     */
+    OUString
+    SelectIconThemeForDesktopEnvironment(
+            const std::vector<IconThemeInfo>& installedThemes,
+            const OUString& desktopEnvironment) const;
+
+    void
+    SetUseHighContrastTheme(bool);
+
+    void
+    SetPreferredIconTheme(const OUString&);
+
+    bool
+    operator==(const vcl::IconThemeSelector&) const;
+
+    bool
+    operator!=(const vcl::IconThemeSelector&) const;
+
+private:
+    /** Return the first element of the themes, or the fallback if the vector is empty */
+    static OUString
+    ReturnFallback(const std::vector<IconThemeInfo>& installedThemes);
+
+    /** The name of the icon theme to use for high contrast mode */
+    static const OUString
+    HIGH_CONTRAST_ICON_THEME_ID;
+
+    /** The name of the icon theme which is used as fallback */
+    static const OUString
+    FALLBACK_ICON_THEME_ID;
+
+
+    static OUString
+    GetIconThemeForDesktopEnvironment(const OUString& desktopEnvironment);
+
+    OUString mPreferredIconTheme;
+    bool mUseHighContrastTheme;
+
+    friend class ::IconThemeSelectorTest;
+};
+
+} /* namespace vcl */
+
+#endif /* VCL_ICONTHEMESELECTOR_HXX_ */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/settings.hxx b/include/vcl/settings.hxx
index 828c7a1..ee50d38 100644
--- a/include/vcl/settings.hxx
+++ b/include/vcl/settings.hxx
@@ -37,6 +37,9 @@ class LocaleDataWrapper;
 
 namespace vcl {
     class I18nHelper;
+    class IconThemeScanner;
+    class IconThemeSelector;
+    class IconThemeInfo;
 }
 
 // -----------------
@@ -248,6 +251,7 @@ public:
 
 private:
     void                            SetStandardStyles();
+
     Color                           maActiveBorderColor;
     Color                           maActiveColor;
     Color                           maActiveColor2;
@@ -330,21 +334,25 @@ private:
     sal_uLong                       mnDisplayOptions;
     sal_uLong                       mnToolbarIconSize;
     bool                       mnUseFlatMenus;
-    sal_uLong                       mnOptions;
-    sal_uInt16                      mnScreenZoom;
-    sal_uInt16                      mnScreenFontZoom;
-    bool                      mnHighContrast;
-    bool                      mnUseSystemUIFonts;
-    sal_uInt16                      mnAutoMnemonic;
-    AutoState                      mnUseImagesInMenus;
+    sal_uLong                  mnOptions;
+    sal_uInt16                 mnScreenZoom;
+    sal_uInt16                 mnScreenFontZoom;
+    bool                       mbHighContrast;
+    bool                       mbUseSystemUIFonts;
+    sal_uInt16                 mnAutoMnemonic;
+    AutoState                  mnUseImagesInMenus;
     bool                       mnUseFlatBorders;
-    bool                        mbPreferredUseImagesInMenus;
-    long                            mnMinThumbSize;
-    sal_uLong                       mnSymbolsStyle;
-    sal_uLong                       mnPreferredSymbolsStyle;
-    bool                      mnSkipDisabledInMenus;
-    bool                        mbHideDisabledMenuItems;
-    bool                        mbAcceleratorsInContextMenus;
+    bool                       mbPreferredUseImagesInMenus;
+    long                       mnMinThumbSize;
+    boost::shared_ptr<vcl::IconThemeScanner>
+                                    mIconThemeScanner;
+    boost::shared_ptr<vcl::IconThemeSelector>
+                                    mIconThemeSelector;
+
+    OUString                   mIconTheme;
+    bool                       mbSkipDisabledInMenus;
+    bool                       mbHideDisabledMenuItems;
+    bool                       mbAcceleratorsInContextMenus;
     //mbPrimaryButtonWarpsSlider == true for "jump to here" behavior for primary button, otherwise
     //primary means scroll by single page. Secondary button takes the alternative behaviour
     bool                        mbPrimaryButtonWarpsSlider;
@@ -414,19 +422,6 @@ private:
 #define STYLE_TOOLBAR_ICONSIZE_SMALL        ((sal_uLong)1)
 #define STYLE_TOOLBAR_ICONSIZE_LARGE        ((sal_uLong)2)
 
-#define STYLE_SYMBOLS_AUTO          ((sal_uLong)0)
-#define STYLE_SYMBOLS_DEFAULT       ((sal_uLong)1)
-#define STYLE_SYMBOLS_HICONTRAST    ((sal_uLong)2)
-#define STYLE_SYMBOLS_INDUSTRIAL    ((sal_uLong)3)
-#define STYLE_SYMBOLS_CRYSTAL       ((sal_uLong)4)
-#define STYLE_SYMBOLS_TANGO         ((sal_uLong)5)
-#define STYLE_SYMBOLS_OXYGEN        ((sal_uLong)6)
-#define STYLE_SYMBOLS_CLASSIC       ((sal_uLong)7)
-#define STYLE_SYMBOLS_HUMAN         ((sal_uLong)8)
-#define STYLE_SYMBOLS_SIFR          ((sal_uLong)9)
-#define STYLE_SYMBOLS_TANGO_TESTING ((sal_uLong)10)
-#define STYLE_SYMBOLS_THEMES_MAX    ((sal_uLong)11)
-
 #define STYLE_CURSOR_NOBLINKTIME    ((sal_uLong)0xFFFFFFFF)
 
 class VCL_DLLPUBLIC StyleSettings
@@ -640,14 +635,13 @@ public:
     const Color&                    GetInactiveTabColor() const
                                         { return mpData->maInactiveTabColor; }
 
-    void                            SetHighContrastMode( bool bHighContrast )
-                                        { CopyData(); mpData->mnHighContrast = bHighContrast; }
-    bool                            GetHighContrastMode() const
-                                        { return mpData->mnHighContrast; }
+    void                            SetHighContrastMode(bool bHighContrast );
+    bool                            GetHighContrastMode() const;
+
     void                            SetUseSystemUIFonts( bool bUseSystemUIFonts )
-                                        { CopyData(); mpData->mnUseSystemUIFonts = bUseSystemUIFonts; }
+                                        { CopyData(); mpData->mbUseSystemUIFonts = bUseSystemUIFonts; }
     bool                            GetUseSystemUIFonts() const
-                                        { return mpData->mnUseSystemUIFonts; }
+                                        { return mpData->mbUseSystemUIFonts; }
     void                            SetUseFlatBorders( bool bUseFlatBorders )
                                         { CopyData(); mpData->mnUseFlatBorders = bUseFlatBorders; }
     bool                            GetUseFlatBorders() const
@@ -664,9 +658,9 @@ public:
     bool                                                   GetPreferredUseImagesInMenus() const
                                         { return mpData->mbPreferredUseImagesInMenus; }
     void                                                       SetSkipDisabledInMenus( bool bSkipDisabledInMenus )
-                                        { CopyData(); mpData->mnSkipDisabledInMenus = bSkipDisabledInMenus; }
+                                        { CopyData(); mpData->mbSkipDisabledInMenus = bSkipDisabledInMenus; }
     bool                            GetSkipDisabledInMenus() const
-                                        { return mpData->mnSkipDisabledInMenus; }
+                                        { return mpData->mbSkipDisabledInMenus; }
     void                                                       SetHideDisabledMenuItems( bool bHideDisabledMenuItems )
                                         { CopyData(); mpData->mbHideDisabledMenuItems = bHideDisabledMenuItems; }
     bool                            GetHideDisabledMenuItems() const
@@ -850,28 +844,32 @@ public:
     sal_uLong                           GetToolbarIconSize() const
                                         { return mpData->mnToolbarIconSize; }
 
-    void                            SetSymbolsStyle( sal_uLong nStyle )
-                                        { CopyData(); mpData->mnSymbolsStyle = nStyle; }
-    sal_uLong                           GetSymbolsStyle() const
-                                        { return mpData->mnSymbolsStyle; }
-
-    void                            SetPreferredSymbolsStyle( sal_uLong nStyle )
-                                        { CopyData(); mpData->mnPreferredSymbolsStyle = nStyle; }
-    void                            SetPreferredSymbolsStyleName( const OUString &rName );
-    sal_uLong                           GetPreferredSymbolsStyle() const
-                                        { return mpData->mnPreferredSymbolsStyle; }
-    // check whether the symbols style is supported (icons are installed)
-    bool                            CheckSymbolStyle( sal_uLong nStyle ) const;
-    sal_uLong                           GetAutoSymbolsStyle() const;
-
-    sal_uLong                           GetCurrentSymbolsStyle() const;
-
-    void                            SetSymbolsStyleName( const OUString &rName )
-                                        { return SetSymbolsStyle( ImplNameToSymbolsStyle( rName ) ); }
-    OUString                 GetSymbolsStyleName() const
-                                        { return ImplSymbolsStyleToName( GetSymbolsStyle() ); }
-    OUString                 GetCurrentSymbolsStyleName() const
-                                        { return ImplSymbolsStyleToName( GetCurrentSymbolsStyle() ); }
+    /** Set the icon theme to use. */
+    void                            SetIconTheme(const OUString&);
+
+    /** Determine which icon theme should be used.
+     *
+     * This might not be the same as the one which has been set with SetIconTheme(),
+     * e.g., if high contrast mode is enabled.
+     *
+     * (for the detailed logic @see vcl::IconThemeSelector)
+     */
+    OUString                        DetermineIconTheme() const;
+
+    /** Obtain the list of icon themes which were found in the config folder
+     * @see vcl::IconThemeScanner for more details.
+     */
+    std::vector<vcl::IconThemeInfo> GetInstalledIconThemes() const;
+
+    /** Obtain the name of the icon theme which will be chosen automatically for the desktop environment.
+     * This method will only return icon themes which were actually found on the system.
+     */
+    OUString                        GetAutomaticallyChosenIconTheme() const;
+
+    /** Set a preferred icon theme.
+     * This theme will be preferred in GetAutomaticallyChosenIconTheme()
+     */
+    void                            SetPreferredIconTheme(const OUString&);
 
     const Wallpaper&                GetWorkspaceGradient() const
                                         { return mpData->maWorkspaceGradient; }
@@ -945,10 +943,6 @@ public:
     bool                            operator ==( const StyleSettings& rSet ) const;
     bool                            operator !=( const StyleSettings& rSet ) const
                                         { return !(*this == rSet); }
-
-protected:
-    OUString                 ImplSymbolsStyleToName( sal_uLong nStyle ) const;
-    sal_uLong                           ImplNameToSymbolsStyle( const OUString &rName ) const;
 };
 
 // ----------------
diff --git a/include/vcl/toolbox.hxx b/include/vcl/toolbox.hxx
index d595191..4ca253f 100644
--- a/include/vcl/toolbox.hxx
+++ b/include/vcl/toolbox.hxx
@@ -569,8 +569,8 @@ public:
     // if an index is found the corresponding item id is filled in (else 0)
     long GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const;
 
-    static const Size&  GetDefaultImageSize(bool bLarge);
-    const Size&         GetDefaultImageSize() const;
+    static Size         GetDefaultImageSize(bool bLarge);
+    Size                GetDefaultImageSize() const;
     void                ChangeHighlight( sal_uInt16 nPos );
 
     void SetImageListProvider(vcl::IImageListProvider* _pProvider);
diff --git a/sfx2/source/menu/mnuitem.cxx b/sfx2/source/menu/mnuitem.cxx
index ad4432c..dfae122 100644
--- a/sfx2/source/menu/mnuitem.cxx
+++ b/sfx2/source/menu/mnuitem.cxx
@@ -308,8 +308,8 @@ SfxAppMenuControl_Impl::SfxAppMenuControl_Impl(
 {
     // Determine the current background color setting for menus
     const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
-    m_nSymbolsStyle         = rSettings.GetSymbolsStyle();
-    m_bShowMenuImages       = rSettings.GetUseImagesInMenus();
+    m_sIconTheme         = rSettings.DetermineIconTheme();
+    m_bShowMenuImages    = rSettings.GetUseImagesInMenus();
 
     ::framework::MenuConfiguration aConf( ::comphelper::getProcessComponentContext() );
     Reference<com::sun::star::frame::XFrame> aXFrame( GetBindings().GetDispatcher_Impl()->GetFrame()->GetFrame().GetFrameInterface() );
@@ -332,14 +332,14 @@ IMPL_LINK( SfxAppMenuControl_Impl, Activate, Menu *, pActMenu )
     if ( pActMenu )
     {
         const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
-        sal_uIntPtr nSymbolsStyle = rSettings.GetSymbolsStyle();
+        OUString sIconTheme = rSettings.DetermineIconTheme();
         sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
 
-        if (( nSymbolsStyle != m_nSymbolsStyle ) ||
+        if (( sIconTheme != m_sIconTheme ) ||
             ( bShowMenuImages != m_bShowMenuImages ))
         {
-            m_nSymbolsStyle         = nSymbolsStyle;
-            m_bShowMenuImages       = bShowMenuImages;
+            m_sIconTheme        = sIconTheme;
+            m_bShowMenuImages   = bShowMenuImages;
 
             sal_uInt16 nCount = pActMenu->GetItemCount();
             for ( sal_uInt16 nSVPos = 0; nSVPos < nCount; nSVPos++ )
@@ -350,7 +350,7 @@ IMPL_LINK( SfxAppMenuControl_Impl, Activate, Menu *, pActMenu )
                     if ( bShowMenuImages )
                     {
                         sal_Bool        bImageSet = sal_False;
-                        ::rtl::OUString aImageId;
+                        OUString aImageId;
                         ::framework::MenuConfiguration::Attributes* pMenuAttributes =
                             (::framework::MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
 
diff --git a/svtools/source/config/miscopt.cxx b/svtools/source/config/miscopt.cxx
index 77ce11d..0d3ac13 100644
--- a/svtools/source/config/miscopt.cxx
+++ b/svtools/source/config/miscopt.cxx
@@ -51,7 +51,7 @@ using namespace ::com::sun::star;
 #define PROPERTYHANDLE_TOOLBOXSTYLE             2
 #define PROPERTYNAME_USESYSTEMFILEDIALOG    "UseSystemFileDialog"
 #define PROPERTYHANDLE_USESYSTEMFILEDIALOG      3
-#define PROPERTYNAME_SYMBOLSTYLE            "SymbolStyle"
+#define PROPERTYNAME_ICONTHEME              "SymbolStyle"
 #define PROPERTYHANDLE_SYMBOLSTYLE              4
 #define PROPERTYNAME_USESYSTEMPRINTDIALOG   "UseSystemPrintDialog"
 #define PROPERTYHANDLE_USESYSTEMPRINTDIALOG     5
@@ -89,6 +89,7 @@ class SvtMiscOptions_Impl : public ConfigItem
     sal_Bool    m_bAlwaysAllowSave;
     sal_Bool    m_bExperimentalMode;
     sal_Bool    m_bMacroRecorderMode;
+    sal_Bool    m_bIconThemeWasSetAutomatically;
 
     public:
 
@@ -180,15 +181,32 @@ class SvtMiscOptions_Impl : public ConfigItem
         inline sal_Bool IsGetSymbolsSizeReadOnly()
         { return m_bIsSymbolsSizeRO; }
 
-        sal_Int16 GetSymbolsStyle() const;
-        OUString GetSymbolsStyleName() const;
-        sal_Int16 GetCurrentSymbolsStyle() const;
+        OUString GetIconTheme() const;
+
+        enum SetModifiedFlag { SET_MODIFIED, DONT_SET_MODIFIED };
+
+        /** Set the icon theme
+         *
+         * @param theme
+         * The name of the icon theme to use.
+         *
+         * @param setModified
+         * Whether to call SetModified() and CallListeners().
+         *
+         * @internal
+         * The @p setModified flag was introduced because the unittests fail if we call SetModified()
+         * during initialization in the constructor.
+         */
+        void
+        SetIconTheme(const OUString &theme, SetModifiedFlag setModified = SET_MODIFIED );
 
-        inline void SetSymbolsStyle( sal_Int16 nSet )
-        { ImplSetSymbolsStyle( true, nSet, OUString() ); }
+        bool IconThemeWasSetAutomatically()
+        {return m_bIconThemeWasSetAutomatically;}
 
-        inline void SetSymbolsStyleName( OUString &rName )
-        { ImplSetSymbolsStyle( false, 0, rName ); }
+        /** Set the icon theme automatically by detecting the best theme for the desktop environment.
+         * The parameter setModified controls whether SetModified() will be called.
+         */
+        void SetIconThemeAutomatically(SetModifiedFlag = SET_MODIFIED);
 
         inline sal_Bool IsGetSymbolsStyleReadOnly()
         { return m_bIsSymbolsStyleRO; }
@@ -246,8 +264,9 @@ class SvtMiscOptions_Impl : public ConfigItem
 
         static Sequence< OUString > GetPropertyNames();
 
-    protected:
-        void ImplSetSymbolsStyle( bool bValue, sal_Int16 nSet, const OUString &rName );
+    private:
+        // The unittests fail if we call SetModified during initialization in the constructor.
+        void ImplSetSymbolsStyleWithoutSettingModifiedFlag( bool bValue, sal_Int16 nSet, const OUString &rName );
 };
 
 //*****************************************************************************************************************
@@ -273,7 +292,7 @@ SvtMiscOptions_Impl::SvtMiscOptions_Impl()
     , m_bAlwaysAllowSave( sal_False )
     , m_bExperimentalMode( sal_False )
     , m_bMacroRecorderMode( sal_False )
-
+    , m_bIconThemeWasSetAutomatically( sal_False )
 {
     // Use our static list of configuration keys to get his values.
     Sequence< OUString >    seqNames    = GetPropertyNames  (           );
@@ -356,9 +375,15 @@ SvtMiscOptions_Impl::SvtMiscOptions_Impl()
 
             case PROPERTYHANDLE_SYMBOLSTYLE :
             {
-                OUString aSymbolsStyle;
-                if( seqValues[nProperty] >>= aSymbolsStyle )
-                    SetSymbolsStyleName( aSymbolsStyle );
+                OUString aIconTheme;
+                if( seqValues[nProperty] >>= aIconTheme ) {
+                    if (aIconTheme == "auto") {
+                        SetIconThemeAutomatically(DONT_SET_MODIFIED);
+                    }
+                    else {
+                        SetIconTheme(aIconTheme, DONT_SET_MODIFIED);
+                    }
+                }
                 else
                 {
                     OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" );
@@ -483,11 +508,16 @@ void SvtMiscOptions_Impl::Load( const Sequence< OUString >& rPropertyNames )
                                                         }
                                                     break;
             case PROPERTYHANDLE_SYMBOLSTYLE         :   {
-                                                            OUString aSymbolsStyle;
-                                                            if( seqValues[nProperty] >>= aSymbolsStyle )
-                                                                SetSymbolsStyleName( aSymbolsStyle );
-                                                            else
-                                                            {
+                                                            OUString aIconTheme;
+                                                            if( seqValues[nProperty] >>= aIconTheme ) {
+                                                                if (aIconTheme == "auto") {
+                                                                    SetIconThemeAutomatically(DONT_SET_MODIFIED);
+                                                                }
+                                                                else {
+                                                                    SetIconTheme(aIconTheme, DONT_SET_MODIFIED);
+                                                                }
+                                                            }
+                                                            else {
                                                                 OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" );
                                                             }
                                                         }
@@ -545,41 +575,27 @@ void SvtMiscOptions_Impl::SetSymbolsSize( sal_Int16 nSet )
     CallListeners();
 }
 
-sal_Int16 SvtMiscOptions_Impl::GetSymbolsStyle() const
+OUString SvtMiscOptions_Impl::GetIconTheme() const
 {
-    return (sal_Int16)Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+    return Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 }
 
-OUString SvtMiscOptions_Impl::GetSymbolsStyleName() const
+void
+SvtMiscOptions_Impl::SetIconTheme(const OUString &rName, SetModifiedFlag setModified)
 {
-    return Application::GetSettings().GetStyleSettings().GetSymbolsStyleName();
-}
-
-sal_Int16 SvtMiscOptions_Impl::GetCurrentSymbolsStyle() const
-{
-    return (sal_Int16)Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle();
-}
-
-void SvtMiscOptions_Impl::ImplSetSymbolsStyle( bool bValue, sal_Int16 nSet, const OUString &rName )
-{
-    if ( ( bValue && ( nSet != GetSymbolsStyle() ) ) ||
-         ( !bValue && ( rName != GetSymbolsStyleName() ) ) )
-    {
-        AllSettings aAllSettings = Application::GetSettings();
-        StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
-
-        if ( bValue )
-            aStyleSettings.SetSymbolsStyle( nSet );
-        else
-            aStyleSettings.SetSymbolsStyleName( rName );
+    AllSettings aAllSettings = Application::GetSettings();
+    StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+    aStyleSettings.SetIconTheme( rName );
+    m_bIconThemeWasSetAutomatically = false;
 
-        aAllSettings.SetStyleSettings(aStyleSettings);
-        Application::MergeSystemSettings( aAllSettings );
-        Application::SetSettings(aAllSettings);
+    aAllSettings.SetStyleSettings(aStyleSettings);
+    Application::MergeSystemSettings( aAllSettings );
+    Application::SetSettings(aAllSettings);
 
+    if (setModified == SET_MODIFIED) {
         SetModified();
-        CallListeners();
     }
+    CallListeners();
 }
 
 //*****************************************************************************************************************
@@ -634,8 +650,16 @@ void SvtMiscOptions_Impl::Commit()
 
             case PROPERTYHANDLE_SYMBOLSTYLE :
             {
-                if ( !m_bIsSymbolsStyleRO )
-                    seqValues[nProperty] <<= GetSymbolsStyleName();
+                if ( !m_bIsSymbolsStyleRO ) {
+                    OUString value;
+                    if (m_bIconThemeWasSetAutomatically) {
+                        value = "auto";
+                    }
+                    else {
+                        value = GetIconTheme();
+                    }
+                    seqValues[nProperty] <<= value;
+                }
                 break;
             }
 
@@ -691,7 +715,7 @@ Sequence< OUString > SvtMiscOptions_Impl::GetPropertyNames()
         OUString(PROPERTYNAME_SYMBOLSET),
         OUString(PROPERTYNAME_TOOLBOXSTYLE),
         OUString(PROPERTYNAME_USESYSTEMFILEDIALOG),
-        OUString(PROPERTYNAME_SYMBOLSTYLE),
+        OUString(PROPERTYNAME_ICONTHEME),
         OUString(PROPERTYNAME_USESYSTEMPRINTDIALOG),
         OUString(PROPERTYNAME_SHOWLINKWARNINGDIALOG),
         OUString(PROPERTYNAME_DISABLEUICUSTOMIZATION),
@@ -802,19 +826,14 @@ bool SvtMiscOptions::AreCurrentSymbolsLarge() const
     return ( GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE );
 }
 
-sal_Int16 SvtMiscOptions::GetSymbolsStyle() const
-{
-    return m_pDataContainer->GetSymbolsStyle();
-}
-
-sal_Int16 SvtMiscOptions::GetCurrentSymbolsStyle() const
+OUString SvtMiscOptions::GetIconTheme() const
 {
-    return m_pDataContainer->GetCurrentSymbolsStyle();
+    return m_pDataContainer->GetIconTheme();
 }
 
-void SvtMiscOptions::SetSymbolsStyle( sal_Int16 nSet )
+void SvtMiscOptions::SetIconTheme(const OUString& iconTheme)
 {
-    m_pDataContainer->SetSymbolsStyle( nSet );
+    m_pDataContainer->SetIconTheme(iconTheme);
 }
 
 sal_Bool SvtMiscOptions::DisableUICustomization() const
@@ -908,4 +927,24 @@ void SvtMiscOptions::RemoveListenerLink( const Link& rLink )
     m_pDataContainer->RemoveListenerLink( rLink );
 }
 
+void
+SvtMiscOptions_Impl::SetIconThemeAutomatically(enum SetModifiedFlag setModified)
+{
+    OUString theme = Application::GetSettings().GetStyleSettings().GetAutomaticallyChosenIconTheme();
+    SetIconTheme(theme, setModified);
+    m_bIconThemeWasSetAutomatically = true;
+}
+
+void
+SvtMiscOptions::SetIconThemeAutomatically()
+{
+    m_pDataContainer->SetIconThemeAutomatically();
+}
+
+bool
+SvtMiscOptions::IconThemeWasSetAutomatically()
+{
+    return m_pDataContainer->IconThemeWasSetAutomatically();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/misc/imagemgr.cxx b/svtools/source/misc/imagemgr.cxx
index 82953df..767344f 100644
--- a/svtools/source/misc/imagemgr.cxx
+++ b/svtools/source/misc/imagemgr.cxx
@@ -487,14 +487,15 @@ static Image GetImageFromList_Impl( sal_uInt16 nImageId, sal_Bool bBig )
 
     static vcl::DeleteOnDeinit< ImageList > xSmallImageList( NULL );
     static vcl::DeleteOnDeinit< ImageList > xBigImageList( NULL );
-    static sal_uLong nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+    static OUString style = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
     // If the style has been changed, throw away our cache of the older images
-    if ( nStyle != Application::GetSettings().GetStyleSettings().GetSymbolsStyle() )
+    OUString currentStyle = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
+    if ( style != currentStyle)
     {
         xSmallImageList.reset();
         xBigImageList.reset();
-        nStyle = Application::GetSettings().GetStyleSettings().GetSymbolsStyle();
+        style = currentStyle;
     }
 
     if ( bBig )
diff --git a/vcl/CppunitTest_vcl_app_test.mk b/vcl/CppunitTest_vcl_app_test.mk
new file mode 100644
index 0000000..0aa3202
--- /dev/null
+++ b/vcl/CppunitTest_vcl_app_test.mk
@@ -0,0 +1,30 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,vcl_app_test))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,vcl_app_test, \
+    vcl/qa/cppunit/app/test_IconThemeInfo \
+    vcl/qa/cppunit/app/test_IconThemeScanner \
+    vcl/qa/cppunit/app/test_IconThemeSelector \
+))
+
+# add a list of all needed libraries here
+$(eval $(call gb_CppunitTest_use_libraries,vcl_app_test, \
+sal \
+vcl \
+$(gb_STDLIBS) \
+))
+
+$(eval $(call gb_CppunitTest_set_include,vcl_app_test, \
+$$(INCLUDE) \
+-I$(OUTDIR)/inc \
+ ))
+
+# vim: set noet sw=4 ts=4:
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 1725823..ff91533 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -112,6 +112,9 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/app/salvtables \
     vcl/source/app/session \
     vcl/source/app/settings \
+    vcl/source/app/IconThemeInfo \
+    vcl/source/app/IconThemeScanner \
+    vcl/source/app/IconThemeSelector \
     vcl/source/app/solarmutex \
     vcl/source/app/sound \
     vcl/source/app/stdtext \
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 4dc6434..1f3c8e2 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -88,6 +88,7 @@ endif
 $(eval $(call gb_Module_add_check_targets,vcl,\
 	CppunitTest_vcl_complextext \
 	CppunitTest_vcl_filters_test \
+	CppunitTest_vcl_app_test \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/vcl/inc/toolbox.h b/vcl/inc/toolbox.h
index bfffe7b..cf89d02 100644
--- a/vcl/inc/toolbox.h
+++ b/vcl/inc/toolbox.h
@@ -34,13 +34,6 @@
 #define TB_MENUBUTTON_SIZE      12
 #define TB_MENUBUTTON_OFFSET    2
 
-#define TB_SMALLIMAGESIZE       16
-
-#define TB_LARGEIMAGESIZE            26
-#define TB_LARGEIMAGESIZE_INDUSTRIAL 24
-#define TB_LARGEIMAGESIZE_CRYSTAL    22
-#define TB_LARGEIMAGESIZE_OXYGEN     22
-
 class Window;
 
 struct ImplToolItem
diff --git a/vcl/qa/cppunit/app/test_IconThemeInfo.cxx b/vcl/qa/cppunit/app/test_IconThemeInfo.cxx
new file mode 100644
index 0000000..e401046
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeInfo.cxx
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/types.h>
+
+#include <rtl/ustring.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+using namespace vcl;
+
+class IconThemeInfoTest : public CppUnit::TestFixture
+{
+    void
+    UpperCaseDisplayNameIsReturnedForNonDefaultId();
+
+    void
+    ImagesZipIsNotValid();
+
+    void
+    ImagesOxygenZipIsValid();
+
+    void
+    DefaultZipIsValid();
+
+    void
+    ThemeIdIsDetectedFromFileNameWithUnderscore();
+
+    void
+    ExceptionIsThrownWhenIdCannotBeDetermined1();
+
+    void
+    ExceptionIsThrownWhenIdCannotBeDetermined2();
+
+    void
+    GalaxyIsReturnedAsDisplayNameForDefaultZip();
+
+    // Adds code needed to register the test suite
+    CPPUNIT_TEST_SUITE(IconThemeInfoTest);
+    CPPUNIT_TEST(UpperCaseDisplayNameIsReturnedForNonDefaultId);
+    CPPUNIT_TEST(ThemeIdIsDetectedFromFileNameWithUnderscore);
+    CPPUNIT_TEST(ImagesZipIsNotValid);
+    CPPUNIT_TEST(ImagesOxygenZipIsValid);
+    CPPUNIT_TEST(DefaultZipIsValid);
+    CPPUNIT_TEST(GalaxyIsReturnedAsDisplayNameForDefaultZip);
+    CPPUNIT_TEST(ExceptionIsThrownWhenIdCannotBeDetermined1);
+    CPPUNIT_TEST(ExceptionIsThrownWhenIdCannotBeDetermined2);
+
+    // End of test suite definition
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void
+IconThemeInfoTest::UpperCaseDisplayNameIsReturnedForNonDefaultId()
+{
+    OUString id("katze");
+    OUString displayName = vcl::IconThemeInfo::ThemeIdToDisplayName(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("theme id is properly uppercased", OUString("Katze"), displayName);
+}
+
+void
+IconThemeInfoTest::ImagesZipIsNotValid()
+{
+    OUString id("file://images.zip");
+    bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("images.zip is not a valid theme name", false, valid);
+}
+
+void
+IconThemeInfoTest::ImagesOxygenZipIsValid()
+{
+    OUString id("file://images_oxygen.zip");
+    bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("images_oxygen.zip is a valid theme name", true, valid);
+}
+
+void
+IconThemeInfoTest::DefaultZipIsValid()
+{
+    OUString id("file://default.zip");
+    bool valid = vcl::IconThemeInfo::UrlCanBeParsed(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("default.zip is a valid theme name", true, valid);
+}
+
+
+void
+IconThemeInfoTest::ThemeIdIsDetectedFromFileNameWithUnderscore()
+{
+    OUString fname("images_oxygen.zip");
+    OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme id is returned for 'images_oxygen.zip'", OUString("oxygen"), sname);
+}
+
+void
+IconThemeInfoTest::ExceptionIsThrownWhenIdCannotBeDetermined1()
+{
+    bool thrown = false;
+    OUString fname("images_oxygen");
+    try {
+        OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+    }
+    catch (std::runtime_error&) {
+        thrown = true;
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception was thrown",true, thrown);
+}
+
+void
+IconThemeInfoTest::ExceptionIsThrownWhenIdCannotBeDetermined2()
+{
+    bool thrown = false;
+    OUString fname("image_oxygen.zip");
+    try {
+        OUString sname = vcl::IconThemeInfo::FileNameToThemeId(fname);
+    }
+    catch (std::runtime_error&) {
+        thrown = true;
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception was thrown", true, thrown);
+}
+
+void
+IconThemeInfoTest::GalaxyIsReturnedAsDisplayNameForDefaultZip()
+{
+    OUString id("file://default.zip");
+    IconThemeInfo i(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("default.zip is displayed as Galaxy", OUString("Galaxy"), i.GetDisplayName());
+}
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeInfoTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/app/test_IconThemeScanner.cxx b/vcl/qa/cppunit/app/test_IconThemeScanner.cxx
new file mode 100644
index 0000000..af2e957
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeScanner.cxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/types.h>
+
+#include <rtl/ustring.hxx>
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+class IconThemeScannerTest : public CppUnit::TestFixture
+{
+    void
+    AddedThemeIsFoundById();
+
+    void
+    AddedThemeInfoIsReturned();
+
+    void
+    ExceptionIsThrownIfInvalidInfoIsRequested();
+
+    // Adds code needed to register the test suite
+    CPPUNIT_TEST_SUITE(IconThemeScannerTest);
+    CPPUNIT_TEST(AddedThemeIsFoundById);
+    CPPUNIT_TEST(AddedThemeInfoIsReturned);
+    CPPUNIT_TEST(ExceptionIsThrownIfInvalidInfoIsRequested);
+
+    // End of test suite definition
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void
+IconThemeScannerTest::AddedThemeIsFoundById()
+{
+    vcl::IconThemeScanner scanner;
+    OUString theme("file:://images_katze.zip");
+    scanner.AddIconThemeByPath(theme);
+    OUString id = vcl::IconThemeInfo::FileNameToThemeId("images_katze.zip");
+    bool found = false;
+    found = scanner.IconThemeIsInstalled(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("icon theme could be added by url", true, found);
+}
+
+void
+IconThemeScannerTest::AddedThemeInfoIsReturned()
+{
+    vcl::IconThemeScanner scanner;
+    OUString theme("file:://images_katze.zip");
+    scanner.AddIconThemeByPath(theme);
+    OUString id = vcl::IconThemeInfo::FileNameToThemeId("images_katze.zip");
+    const vcl::IconThemeInfo& info = scanner.GetIconThemeInfo(id);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'katze' icon theme is found from id", theme, info.GetUrlToFile());
+}
+
+void
+IconThemeScannerTest::ExceptionIsThrownIfInvalidInfoIsRequested()
+{
+    vcl::IconThemeScanner scanner;
+    OUString theme("file:://images_katze.zip");
+    scanner.AddIconThemeByPath(theme);
+    bool thrown = false;
+    try
+    {
+        scanner.GetIconThemeInfo("hund");
+    }
+    catch (const std::runtime_error&)
+    {
+        thrown = true;
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Exception is thrown if invalid theme info is requested", true, thrown);
+}
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeScannerTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qa/cppunit/app/test_IconThemeSelector.cxx b/vcl/qa/cppunit/app/test_IconThemeSelector.cxx
new file mode 100644
index 0000000..34961e7
--- /dev/null
+++ b/vcl/qa/cppunit/app/test_IconThemeSelector.cxx
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/IconThemeSelector.hxx>
+
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+class IconThemeSelectorTest : public CppUnit::TestFixture
+{
+    void
+    OxygenThemeIsReturnedForKde4Desktop();
+
+    void
+    TangoThemeIsReturnedForGtkDesktop();
+
+    void
+    ThemeIsOverriddenByPreferredTheme();
+
+    void
+    ThemeIsOverriddenByHighContrastMode();
+
+    void
+    NotInstalledThemeDoesNotOverride();
+
+    void
+    InstalledThemeIsFound();
+
+    void
+    FirstThemeIsReturnedIfRequestedThemeIsNotFound();
+
+    void
+    FallbackThemeIsReturnedForEmptyInput();
+
+    void
+    DifferentPreferredThemesAreInequal();
+
+    void
+    DifferentHighContrastModesAreInequal();
+
+    static std::vector<vcl::IconThemeInfo>
+    GetFakeInstalledThemes();
+
+    // Adds code needed to register the test suite
+    CPPUNIT_TEST_SUITE(IconThemeSelectorTest);
+
+    CPPUNIT_TEST(OxygenThemeIsReturnedForKde4Desktop);
+    CPPUNIT_TEST(TangoThemeIsReturnedForGtkDesktop);
+    CPPUNIT_TEST(ThemeIsOverriddenByPreferredTheme);
+    CPPUNIT_TEST(ThemeIsOverriddenByHighContrastMode);
+    CPPUNIT_TEST(NotInstalledThemeDoesNotOverride);
+    CPPUNIT_TEST(InstalledThemeIsFound);
+    CPPUNIT_TEST(FirstThemeIsReturnedIfRequestedThemeIsNotFound);
+    CPPUNIT_TEST(FallbackThemeIsReturnedForEmptyInput);
+    CPPUNIT_TEST(DifferentPreferredThemesAreInequal);
+    CPPUNIT_TEST(DifferentHighContrastModesAreInequal);
+
+    // End of test suite definition
+
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+/*static*/ std::vector<vcl::IconThemeInfo>
+IconThemeSelectorTest::GetFakeInstalledThemes()
+{
+    std::vector<vcl::IconThemeInfo> r;
+    vcl::IconThemeInfo a{};
+    a.mThemeId = "tango";
+    r.push_back(a);
+    a.mThemeId = "oxygen";
+    r.push_back(a);
+    a.mThemeId = vcl::IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID;
+    r.push_back(a);
+    return r;
+}
+
+void
+IconThemeSelectorTest::OxygenThemeIsReturnedForKde4Desktop()
+{
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    vcl::IconThemeSelector s;
+    OUString r = s.SelectIconThemeForDesktopEnvironment(themes, "kde4");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is returned for kde4 desktop", OUString("oxygen"), r);
+}
+
+void
+IconThemeSelectorTest::TangoThemeIsReturnedForGtkDesktop()
+{
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    vcl::IconThemeSelector s;
+    OUString r = s.SelectIconThemeForDesktopEnvironment(themes, "gtk");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is returned for kde4 desktop", OUString("tango"), r);
+}
+
+void
+IconThemeSelectorTest::ThemeIsOverriddenByPreferredTheme()
+{
+    vcl::IconThemeSelector s;
+    OUString preferred("oxygen");
+    s.SetPreferredIconTheme(preferred);
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    OUString selected = s.SelectIconThemeForDesktopEnvironment(themes, "gtk");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is overridden by oxygen", preferred, selected);
+}
+
+void
+IconThemeSelectorTest::ThemeIsOverriddenByHighContrastMode()
+{
+    vcl::IconThemeSelector s;
+    s.SetUseHighContrastTheme(true);
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    OUString selected = s.SelectIconTheme(themes, "tango");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is overridden by high contrast mode",
+            vcl::IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID, selected);
+    s.SetUseHighContrastTheme(false);
+    selected = s.SelectIconTheme(themes, "tango");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'tango' theme is no longer overridden by high contrast mode",
+            OUString("tango"), selected);
+}
+
+void
+IconThemeSelectorTest::NotInstalledThemeDoesNotOverride()
+{
+    vcl::IconThemeSelector s;
+    s.SetPreferredIconTheme("oxygen_katze");
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    OUString selected = s.SelectIconTheme(themes, "oxygen");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is not overridden by 'oxygen_katze'", OUString("oxygen"), selected);
+}
+
+void
+IconThemeSelectorTest::InstalledThemeIsFound()
+{
+    vcl::IconThemeSelector s;
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    OUString selected = s.SelectIconTheme(themes, "oxygen");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is found", OUString("oxygen"), selected);
+}
+
+void
+IconThemeSelectorTest::FirstThemeIsReturnedIfRequestedThemeIsNotFound()
+{
+    vcl::IconThemeSelector s;
+    std::vector<vcl::IconThemeInfo> themes = GetFakeInstalledThemes();
+    OUString selected = s.SelectIconTheme(themes, "oxygen_katze");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("'oxygen' theme is found", themes.front().GetThemeId(), selected);
+}
+
+void
+IconThemeSelectorTest::FallbackThemeIsReturnedForEmptyInput()
+{
+    vcl::IconThemeSelector s;
+    OUString selected = s.SelectIconTheme(std::vector<vcl::IconThemeInfo>{}, "oxygen");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("fallback is returned for empty input",
+            vcl::IconThemeSelector::FALLBACK_ICON_THEME_ID, selected);
+}
+
+void
+IconThemeSelectorTest::DifferentHighContrastModesAreInequal()
+{
+    vcl::IconThemeSelector s1;
+    vcl::IconThemeSelector s2;
+    s1.SetUseHighContrastTheme(true);
+    s2.SetUseHighContrastTheme(false);
+    bool equal = (s1 == s2);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Different high contrast modes are detected as inequal", false, equal);
+}
+
+void
+IconThemeSelectorTest::DifferentPreferredThemesAreInequal()
+{
+    vcl::IconThemeSelector s1;
+    vcl::IconThemeSelector s2;
+    s1.SetPreferredIconTheme("oxygen");
+    s2.SetUseHighContrastTheme("katze");
+    bool equal = (s1 == s2);
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Different preferred themes are detected as inequal", false, equal);
+}
+
+
+// Put the test suite in the registry
+CPPUNIT_TEST_SUITE_REGISTRATION(IconThemeSelectorTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/IconThemeInfo.cxx b/vcl/source/app/IconThemeInfo.cxx
new file mode 100644
index 0000000..69f0302
--- /dev/null
+++ b/vcl/source/app/IconThemeInfo.cxx
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/IconThemeInfo.hxx>
+#include <rtl/character.hxx>
+
+#include <stdexcept>
+#include <algorithm>
+
+namespace {
+
+OUString
+filename_from_url(const OUString& url)
+{
+    sal_Int32 slashPosition = url.lastIndexOf( '/' );
+    if (slashPosition < 0) {
+        return OUString("");
+    }
+    OUString filename = url.copy( slashPosition+1 );
+    return filename;
+}
+
+}
+
+namespace vcl {
+
+static const char ICON_THEME_PACKAGE_PREFIX[] = "images_";
+
+static const char EXTENSION_FOR_ICON_PACKAGES[] = ".zip";
+
+IconThemeInfo::IconThemeInfo()
+{
+}
+
+IconThemeInfo::IconThemeInfo(const OUString& urlToFile)
+: mUrlToFile(urlToFile)
+{
+    OUString filename = filename_from_url(urlToFile);
+    if (filename.isEmpty()) {
+        throw std::runtime_error("invalid URL passed to IconThemeInfo()");
+    }
+
+    mThemeId = FileNameToThemeId(filename);
+    mDisplayName = ThemeIdToDisplayName(mThemeId);
+
+}
+
+/*static*/ Size
+IconThemeInfo::SizeByThemeName(const OUString& themeName)
+{
+    if (themeName == "tango") {
+        return Size( 24, 24 );
+    }
+    else if (themeName == "crystal") {
+        return Size( 22, 22 );
+    }
+    else if (themeName == "default") {
+        return Size( 22, 22 );
+    }
+    else {
+        return Size( 26, 26 );
+    }
+}
+
+/*static*/ bool
+IconThemeInfo::UrlCanBeParsed(const OUString& url)
+{
+    OUString fname = filename_from_url(url);
+    if (fname.isEmpty()) {
+        return false;
+    }
+
+    if (fname == "default.zip") {
+        return true;
+    }
+
+    if (!fname.startsWithIgnoreAsciiCase(ICON_THEME_PACKAGE_PREFIX)) {
+        return false;
+    }
+
+    if (!fname.endsWithIgnoreAsciiCase(EXTENSION_FOR_ICON_PACKAGES, nullptr)) {
+        return false;
+    }
+
+    return true;
+}
+
+/*static*/ OUString
+IconThemeInfo::FileNameToThemeId(const OUString& filename)
+{
+    if (filename == "default.zip") {
+        return OUString("default");
+    }
+    OUString r;
+    sal_Int32 positionOfLastDot = filename.lastIndexOf(EXTENSION_FOR_ICON_PACKAGES);
+    if (positionOfLastDot < 0) { // -1 means index not found
+        throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
+    }
+    sal_Int32 positionOfFirstUnderscore = filename.indexOf(ICON_THEME_PACKAGE_PREFIX);
+    if (positionOfFirstUnderscore < 0) { // -1 means index not found. Use the whole name instead
+        throw std::runtime_error("IconThemeInfo::FileNameToThemeId() called with invalid filename.");
+    }
+    positionOfFirstUnderscore += RTL_CONSTASCII_LENGTH(ICON_THEME_PACKAGE_PREFIX);
+    r = filename.copy(positionOfFirstUnderscore, positionOfLastDot - positionOfFirstUnderscore);
+    return r;
+}
+
+/*static*/ OUString
+IconThemeInfo::ThemeIdToDisplayName(const OUString& themeId)
+{
+    if (themeId.isEmpty()) {
+        throw std::runtime_error("IconThemeInfo::ThemeIdToDisplayName() called with invalid id.");
+    }
+
+    if (themeId == "default") {
+        return OUString("Galaxy");
+    }
+
+    // make the first letter uppercase
+    OUString r;
+    sal_Unicode firstLetter = themeId[0];
+    if (rtl::isAsciiLowerCase(firstLetter)) {
+        r = OUString(rtl::toAsciiUpperCase(firstLetter));
+        r += themeId.copy(1);
+    }
+    else {
+        r = themeId;
+    }
+    return r;
+}
+
+namespace
+{
+    class SameTheme :
+        public std::unary_function<const vcl::IconThemeInfo &, bool>
+    {
+    private:
+        const OUString& m_rThemeId;
+    public:
+        SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+        bool operator()(const vcl::IconThemeInfo &rInfo)
+        {
+            return m_rThemeId == rInfo.GetThemeId();
+        }
+    };
+}
+
+/*static*/ const vcl::IconThemeInfo&
+IconThemeInfo::FindIconThemeById(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
+{
+    std::vector<vcl::IconThemeInfo>::const_iterator it = std::find_if(themes.begin(), themes.end(),
+               SameTheme(themeId));
+    if (it == themes.end())
+    {
+        throw std::runtime_error("Could not find theme id in theme vector.");
+    }
+    return *it;
+}
+
+/*static*/ bool
+IconThemeInfo::IconThemeIsInVector(const std::vector<vcl::IconThemeInfo>& themes, const OUString& themeId)
+{
+    std::vector<vcl::IconThemeInfo>::const_iterator it = std::find_if(themes.begin(), themes.end(),
+               SameTheme(themeId));
+    if (it != themes.end()) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+} // end namespace vcl
+
+
diff --git a/vcl/source/app/IconThemeScanner.cxx b/vcl/source/app/IconThemeScanner.cxx
new file mode 100644
index 0000000..e6a6a13
--- /dev/null
+++ b/vcl/source/app/IconThemeScanner.cxx
@@ -0,0 +1,185 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/IconThemeScanner.hxx>
+
+#include <config_folders.h>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+namespace vcl {
+
+namespace {
+
+bool
+search_path_is_valid(const OUString& dir)
+{
+    osl::DirectoryItem dirItem;
+    osl::FileBase::RC retvalGet = osl::DirectoryItem::get(dir, dirItem);
+    if (retvalGet != osl::FileBase::RC::E_None) {
+        return false;
+    }
+    osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
+    osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
+    if (retvalStatus != osl::FileBase::RC::E_None) {
+        return false;
+    }
+
+    if (!fileStatus.isDirectory()) {
+        return false;
+    }
+    return true;
+}
+
+}
+
+IconThemeScanner::IconThemeScanner()
+{;}
+
+bool
+IconThemeScanner::ScanDirectoryForIconThemes(const OUString& path)
+{
+    bool pathIsValid = search_path_is_valid(path);
+    if (!pathIsValid) {
+        return false;
+    }
+    std::vector<OUString> iconThemePaths = ReadIconThemesFromPath(path);
+    if (iconThemePaths.empty()) {
+        return false;
+    }
+    mFoundIconThemes.clear();
+    for (const OUString& pathToTheme : iconThemePaths) {
+        AddIconThemeByPath(pathToTheme);
+    }
+    return true;
+}
+
+bool
+IconThemeScanner::AddIconThemeByPath(const OUString &url)
+{
+    if (!IconThemeInfo::UrlCanBeParsed(url)) {
+        return false;
+    }
+    IconThemeInfo newTheme{url};
+    mFoundIconThemes.push_back(newTheme);
+    return true;
+}
+
+/*static*/ std::vector<OUString>
+IconThemeScanner::ReadIconThemesFromPath(const OUString& dir)
+{
+    std::vector<OUString> found;
+
+    osl::Directory dirToScan(dir);
+    osl::FileBase::RC retvalOpen = dirToScan.open();
+    if (retvalOpen != osl::FileBase::RC::E_None) {
+        return found;
+    }
+
+    osl::DirectoryItem directoryItem;
+    while (dirToScan.getNextItem(directoryItem) == osl::FileBase::RC::E_None) {
+        osl::FileStatus status(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL | osl_FileStatus_Mask_FileName);
+        osl::FileBase::RC retvalStatus = directoryItem.getFileStatus(status);
+        if (retvalStatus != osl::FileBase::RC::E_None) {
+            continue;
+        }
+        if (!status.isRegular()) {
+            continue;
+        }
+        if (!FileIsValidIconTheme(status.getFileURL())) {
+            continue;
+        }
+        OUString entry;
+        entry = status.getFileURL();
+        found.push_back(entry);
+    }
+    return found;
+}
+
+/*static*/ bool
+IconThemeScanner::FileIsValidIconTheme(const OUString& filename)
+{
+    // check whether we can construct a IconThemeInfo from it
+    if (!IconThemeInfo::UrlCanBeParsed(filename)) {
+        return false;
+    }
+
+    // check whether the file is a regular file
+    osl::DirectoryItem dirItem;
+    osl::FileBase::RC retvalGet = osl::DirectoryItem::get(filename, dirItem);
+    if (retvalGet != osl::FileBase::RC::E_None) {
+        return false;
+    }
+    osl::FileStatus fileStatus(osl_FileStatus_Mask_Type);
+    osl::FileBase::RC retvalStatus = dirItem.getFileStatus(fileStatus);
+    if (retvalStatus != osl::FileBase::RC::E_None) {
+        return false;
+    }
+    if (!fileStatus.isRegular()) {
+        return false;
+    }
+    return true;
+}
+
+bool
+IconThemeScanner::IconThemeIsInstalled(const OUString& themeId) const
+{
+    return IconThemeInfo::IconThemeIsInVector(mFoundIconThemes, themeId);
+}
+
+/*static*/ boost::shared_ptr<IconThemeScanner>
+IconThemeScanner::Create(const OUString &path)
+{
+    boost::shared_ptr<IconThemeScanner> retval(new IconThemeScanner{});
+    retval->ScanDirectoryForIconThemes(path);
+    return retval;
+}
+
+/*static*/ OUString
+IconThemeScanner::GetStandardIconThemePath()
+{
+    OUString url( "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/config/" );
+    rtl::Bootstrap::expandMacros(url);
+    return url;
+}
+
+IconThemeScanner::~IconThemeScanner()
+{;}
+
+namespace
+{
+    class SameTheme :
+        public std::unary_function<const vcl::IconThemeInfo &, bool>
+    {
+    private:
+        const OUString& m_rThemeId;
+    public:
+        SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+        bool operator()(const vcl::IconThemeInfo &rInfo)
+        {
+            return m_rThemeId == rInfo.GetThemeId();
+        }
+    };
+}
+
+const vcl::IconThemeInfo&
+IconThemeScanner::GetIconThemeInfo(const OUString& themeId)
+{
+    std::vector<IconThemeInfo>::iterator info = std::find_if(mFoundIconThemes.begin(), mFoundIconThemes.end(),
+        SameTheme(themeId));
+    if (info == mFoundIconThemes.end()) {
+        throw std::runtime_error("Requested information on not-installed icon theme");
+    }
+    return *info;
+}
+
+
+} // end namespace vcl
diff --git a/vcl/source/app/IconThemeSelector.cxx b/vcl/source/app/IconThemeSelector.cxx
new file mode 100644
index 0000000..023745b
--- /dev/null
+++ b/vcl/source/app/IconThemeSelector.cxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/IconThemeSelector.hxx>
+
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeInfo.hxx>
+
+#include <algorithm>
+
+namespace vcl {
+
+/*static*/ const OUString
+IconThemeSelector::HIGH_CONTRAST_ICON_THEME_ID("hicontrast");
+
+/*static*/ const OUString
+IconThemeSelector::FALLBACK_ICON_THEME_ID("tango");
+
+
+namespace {
+
+    class SameTheme :
+        public std::unary_function<const vcl::IconThemeInfo &, bool>
+    {
+    private:
+        const OUString& m_rThemeId;
+    public:
+        SameTheme(const OUString &rThemeId) : m_rThemeId(rThemeId) {}
+        bool operator()(const vcl::IconThemeInfo &rInfo)
+        {
+            return m_rThemeId == rInfo.GetThemeId();
+        }
+    };
+
+bool icon_theme_is_in_installed_themes(const OUString& theme,
+        const std::vector<IconThemeInfo>& installedThemes)
+{
+    return std::find_if(installedThemes.begin(), installedThemes.end(),
+               SameTheme(theme)
+           ) != installedThemes.end();
+}
+
+} // end anonymous namespace
+
+IconThemeSelector::IconThemeSelector()
+: mUseHighContrastTheme(false)
+{
+}
+
+/*static*/ OUString
+IconThemeSelector::GetIconThemeForDesktopEnvironment(const OUString& desktopEnvironment)
+{
+    OUString r;
+    if ( desktopEnvironment.equalsIgnoreAsciiCase("tde") ||
+         desktopEnvironment.equalsIgnoreAsciiCase("kde") ) {
+        r = "crystal";
+    }
+    else if ( desktopEnvironment.equalsIgnoreAsciiCase("kde4") ) {
+        r = "oxygen";
+    }
+    else {
+        r = FALLBACK_ICON_THEME_ID;
+    }
+    return r;
+}
+
+OUString
+IconThemeSelector::SelectIconThemeForDesktopEnvironment(
+        const std::vector<IconThemeInfo>& installedThemes,
+        const OUString& desktopEnvironment) const
+{
+    if (!mPreferredIconTheme.isEmpty()) {
+        if (icon_theme_is_in_installed_themes(mPreferredIconTheme, installedThemes)) {
+            return mPreferredIconTheme;
+        }
+    }
+
+    OUString themeForDesktop = GetIconThemeForDesktopEnvironment(desktopEnvironment);
+    if (icon_theme_is_in_installed_themes(themeForDesktop, installedThemes)) {
+        return themeForDesktop;
+    }
+
+    return ReturnFallback(installedThemes);
+}
+
+OUString
+IconThemeSelector::SelectIconTheme(
+        const std::vector<IconThemeInfo>& installedThemes,
+        const OUString& theme) const
+{
+    if (mUseHighContrastTheme) {
+        if (icon_theme_is_in_installed_themes(HIGH_CONTRAST_ICON_THEME_ID, installedThemes)) {
+            return HIGH_CONTRAST_ICON_THEME_ID;
+        }
+    }
+
+    if (icon_theme_is_in_installed_themes(theme, installedThemes)) {
+        return theme;
+    }
+
+    return ReturnFallback(installedThemes);
+}
+
+void
+IconThemeSelector::SetUseHighContrastTheme(bool v)
+{
+    mUseHighContrastTheme = v;
+}
+
+void
+IconThemeSelector::SetPreferredIconTheme(const OUString& theme)
+{
+    mPreferredIconTheme = theme;
+}
+
+bool
+IconThemeSelector::operator==(const vcl::IconThemeSelector& other) const
+{
+    if (this == &other) {
+        return true;
+    }
+    if (mPreferredIconTheme != other.mPreferredIconTheme) {
+        return false;
+    }
+    if (mUseHighContrastTheme != other.mUseHighContrastTheme) {
+        return false;
+    }
+    return true;
+}
+
+bool
+IconThemeSelector::operator!=(const vcl::IconThemeSelector& other) const
+{
+    return !((*this) == other);
+}
+
+/*static*/ OUString
+IconThemeSelector::ReturnFallback(const std::vector<IconThemeInfo>& installedThemes)
+{
+    if (!installedThemes.empty()) {
+        return installedThemes.front().GetThemeId();
+    }
+    else {
+        return FALLBACK_ICON_THEME_ID;
+    }
+}
+
+} /* namespace vcl */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index 9714747..c6c93dd 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -25,11 +25,14 @@
 #include "comphelper/processfactory.hxx"
 #include <rtl/bootstrap.hxx>
 #include "tools/debug.hxx"
-#include <vcl/graphicfilter.hxx>
 
 #include "i18nlangtag/mslangid.hxx"
 #include "i18nlangtag/languagetag.hxx"
 
+#include <vcl/graphicfilter.hxx>
+#include <vcl/IconThemeScanner.hxx>
+#include <vcl/IconThemeSelector.hxx>
+#include <vcl/IconThemeInfo.hxx>
 #include "vcl/svapp.hxx"
 #include "vcl/event.hxx"
 #include "vcl/settings.hxx"
@@ -53,9 +56,6 @@ using namespace ::com::sun::star;
 
 // =======================================================================
 
-
-// =======================================================================
-
 ImplMouseData::ImplMouseData()
 {
     mnOptions                   = 0;
@@ -182,6 +182,8 @@ bool MouseSettings::operator ==( const MouseSettings& rSet ) const
 // =======================================================================
 
 ImplStyleData::ImplStyleData() :
+    mIconThemeScanner(vcl::IconThemeScanner::Create(vcl::IconThemeScanner::GetStandardIconThemePath())),
+    mIconThemeSelector(new vcl::IconThemeSelector()),
     maPersonaHeaderFooter(),
     maPersonaHeaderBitmap(),
     maPersonaFooterBitmap()
@@ -205,9 +207,7 @@ ImplStyleData::ImplStyleData() :
     mnOptions                   = 0;
     mnAutoMnemonic              = 1;
     mnToolbarIconSize           = STYLE_TOOLBAR_ICONSIZE_UNKNOWN;
-    mnSymbolsStyle              = STYLE_SYMBOLS_AUTO;
     mnUseImagesInMenus          = AUTO_STATE_AUTO;
-    mnPreferredSymbolsStyle         = STYLE_SYMBOLS_AUTO;
     mpFontOptions              = NULL;
     mnEdgeBlending = 35;
     maEdgeBlendingTopLeftColor = RGB_COLORDATA(0xC0, 0xC0, 0xC0);
@@ -288,6 +288,7 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
     maFieldFont( rData.maFieldFont ),
     maIconFont( rData.maIconFont ),
     maGroupFont( rData.maGroupFont ),
+    mIconTheme(rData.mIconTheme),
     maWorkspaceGradient( rData.maWorkspaceGradient ),
     maDialogStyle( rData.maDialogStyle ),
     maFrameStyle( rData.maFrameStyle ),
@@ -317,20 +318,20 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
     mnSelectionOptions          = rData.mnSelectionOptions;
     mnDisplayOptions            = rData.mnDisplayOptions;
     mnOptions                   = rData.mnOptions;
-    mnHighContrast              = rData.mnHighContrast;
-    mnUseSystemUIFonts          = rData.mnUseSystemUIFonts;
+    mbHighContrast              = rData.mbHighContrast;
+    mbUseSystemUIFonts          = rData.mbUseSystemUIFonts;
     mnUseFlatBorders            = rData.mnUseFlatBorders;
     mnUseFlatMenus              = rData.mnUseFlatMenus;
     mnAutoMnemonic              = rData.mnAutoMnemonic;
     mnUseImagesInMenus          = rData.mnUseImagesInMenus;
     mbPreferredUseImagesInMenus = rData.mbPreferredUseImagesInMenus;
-    mnSkipDisabledInMenus       = rData.mnSkipDisabledInMenus;
+    mbSkipDisabledInMenus       = rData.mbSkipDisabledInMenus;
     mbHideDisabledMenuItems     = rData.mbHideDisabledMenuItems;
     mbAcceleratorsInContextMenus = rData.mbAcceleratorsInContextMenus;
     mbPrimaryButtonWarpsSlider  = rData.mbPrimaryButtonWarpsSlider;
     mnToolbarIconSize           = rData.mnToolbarIconSize;
-    mnSymbolsStyle              = rData.mnSymbolsStyle;
-    mnPreferredSymbolsStyle     = rData.mnPreferredSymbolsStyle;
+    mIconThemeScanner.reset(new vcl::IconThemeScanner(*rData.mIconThemeScanner));
+    mIconThemeSelector.reset(new vcl::IconThemeSelector(*rData.mIconThemeSelector));
     mpFontOptions               = rData.mpFontOptions;
     mnEdgeBlending              = rData.mnEdgeBlending;
     maEdgeBlendingTopLeftColor  = rData.maEdgeBlendingTopLeftColor;
@@ -422,12 +423,12 @@ void ImplStyleData::SetStandardStyles()
     mnFloatTitleHeight          = 13;
     mnTearOffTitleHeight        = 8;
     mnMenuBarHeight             = 14;
-    mnHighContrast              = false;
-    mnUseSystemUIFonts          = true;
+    mbHighContrast              = false;
+    mbUseSystemUIFonts          = true;
     mnUseFlatBorders            = false;
     mnUseFlatMenus              = false;
     mbPreferredUseImagesInMenus = true;
-    mnSkipDisabledInMenus       = false;
+    mbSkipDisabledInMenus       = false;
     mbHideDisabledMenuItems     = false;
     mbAcceleratorsInContextMenus = true;
     mbPrimaryButtonWarpsSlider = false;
@@ -500,75 +501,6 @@ void StyleSettings::Set3DColors( const Color& rColor )
     }
 }
 
-// -----------------------------------------------------------------------
-
-OUString StyleSettings::ImplSymbolsStyleToName( sal_uLong nStyle ) const
-{
-    switch ( nStyle )
-    {
-        case STYLE_SYMBOLS_DEFAULT:    return OUString("default");
-        case STYLE_SYMBOLS_HICONTRAST: return OUString("hicontrast");
-        case STYLE_SYMBOLS_INDUSTRIAL: return OUString("tango"); // industrial is dead
-        case STYLE_SYMBOLS_CRYSTAL:    return OUString("crystal");
-        case STYLE_SYMBOLS_TANGO:      return OUString("tango");
-        case STYLE_SYMBOLS_OXYGEN:     return OUString("oxygen");
-        case STYLE_SYMBOLS_CLASSIC:    return OUString("classic");
-        case STYLE_SYMBOLS_HUMAN:      return OUString("human");
-        case STYLE_SYMBOLS_SIFR:       return OUString("sifr");
-        case STYLE_SYMBOLS_TANGO_TESTING: return OUString("tango_testing");
-    }
-
-    return OUString("auto");
-}
-
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::ImplNameToSymbolsStyle( const OUString &rName ) const
-{
-    if ( rName == "default" )
-        return STYLE_SYMBOLS_DEFAULT;
-    else if ( rName == "hicontrast" )
-        return STYLE_SYMBOLS_HICONTRAST;
-    else if ( rName == "industrial" )
-        return STYLE_SYMBOLS_TANGO; // industrial is dead
-    else if ( rName == "crystal" )
-        return STYLE_SYMBOLS_CRYSTAL;
-    else if ( rName == "tango" )
-        return STYLE_SYMBOLS_TANGO;
-    else if ( rName == "oxygen" )
-        return STYLE_SYMBOLS_OXYGEN;
-    else if ( rName == "classic" )
-        return STYLE_SYMBOLS_CLASSIC;
-    else if ( rName == "human" )
-        return STYLE_SYMBOLS_HUMAN;
-    else if ( rName == "sifr" )
-        return STYLE_SYMBOLS_SIFR;
-    else if ( rName == "tango_testing" )
-        return STYLE_SYMBOLS_TANGO_TESTING;
-
-    return STYLE_SYMBOLS_AUTO;
-}
-
-// -----------------------------------------------------------------------
-
-/**
-    The preferred style name can be read from the desktop setting. We
-    need to find the closest theme name registered in OOo. Therefore
-    we check if any registered style name is a case-insensitive
-    substring of the preferred style name.
-*/
-void StyleSettings::SetPreferredSymbolsStyleName( const OUString &rName )
-{
-    if ( !rName.isEmpty() )
-    {
-        OUString rNameLowCase( rName.toAsciiLowerCase() );
-
-        for( sal_uInt32 n = 0; n <= STYLE_SYMBOLS_THEMES_MAX; n++ )
-            if ( rNameLowCase.indexOf( ImplSymbolsStyleToName( n ) ) != -1 )
-                SetPreferredSymbolsStyle( n );
-    }
-}
-
 void StyleSettings::SetCheckedColorSpecialCase( )
 {
     CopyData();
@@ -584,99 +516,6 @@ void StyleSettings::SetCheckedColorSpecialCase( )
     }
 }
 
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::GetCurrentSymbolsStyle() const
-{
-    // style selected in Tools -> Options... -> LibreOffice -> View
-    sal_uLong nStyle = GetSymbolsStyle();
-
-    if ( nStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nStyle) ) )
-    {
-        // the preferred style can be read from the desktop setting by the desktop native widgets modules
-        sal_uLong nPreferredStyle = GetPreferredSymbolsStyle();
-
-        if ( nPreferredStyle == STYLE_SYMBOLS_AUTO || ( !CheckSymbolStyle (nPreferredStyle) ) )
-        {
-
-            // use a hardcoded desktop-specific fallback if no preferred style has been detected
-            static bool sbFallbackDesktopChecked = false;
-            static sal_uLong snFallbackDesktopStyle = STYLE_SYMBOLS_DEFAULT;
-
-            if ( !sbFallbackDesktopChecked )
-            {
-                snFallbackDesktopStyle = GetAutoSymbolsStyle();
-                sbFallbackDesktopChecked = true;
-            }
-
-            nPreferredStyle = snFallbackDesktopStyle;
-        }
-
-        if (GetHighContrastMode() && CheckSymbolStyle (STYLE_SYMBOLS_HICONTRAST) )
-            nStyle = STYLE_SYMBOLS_HICONTRAST;
-        else
-            nStyle = nPreferredStyle;
-    }
-
-    return nStyle;
-}
-
-// -----------------------------------------------------------------------
-
-sal_uLong StyleSettings::GetAutoSymbolsStyle() const
-{
-    OUString const & env = Application::GetDesktopEnvironment();
-
-    sal_uLong nRet;
-    if ( env.equalsIgnoreAsciiCase("tde") ||
-         env.equalsIgnoreAsciiCase("kde") )
-        nRet = STYLE_SYMBOLS_CRYSTAL;
-    else if ( env.equalsIgnoreAsciiCase("kde4") )
-        nRet = STYLE_SYMBOLS_OXYGEN;
-    else
-        nRet = STYLE_SYMBOLS_TANGO;
-
-    // fallback to any existing style
-    if ( ! CheckSymbolStyle (nRet) )
-    {
-        for ( sal_uLong n = 0 ; n <= STYLE_SYMBOLS_THEMES_MAX  ; n++ )
-        {
-            sal_uLong nStyleToCheck = n;
-
-            // auto is not a real theme => can't be fallback
-            if ( nStyleToCheck == STYLE_SYMBOLS_AUTO )
-                continue;
-
-            // will check hicontrast in the end
-            if ( nStyleToCheck == STYLE_SYMBOLS_HICONTRAST )
-                continue;
-            if ( nStyleToCheck == STYLE_SYMBOLS_THEMES_MAX )
-                nStyleToCheck = STYLE_SYMBOLS_HICONTRAST;
-
-            if ( CheckSymbolStyle ( nStyleToCheck ) )
-            {
-                nRet = nStyleToCheck;
-                n = STYLE_SYMBOLS_THEMES_MAX;
-            }
-        }
-    }
-
-    return nRet;
-}
-
-// -----------------------------------------------------------------------
-
-bool StyleSettings::CheckSymbolStyle( sal_uLong nStyle ) const
-{
-    if ( nStyle == STYLE_SYMBOLS_INDUSTRIAL )
-        return false; // industrial is dead
-
-    static ImplImageTreeSingletonRef aImageTree;
-    return aImageTree->checkStyle( ImplSymbolsStyleToName( nStyle ) );
-}
-
-// -----------------------------------------------------------------------
-
 bool StyleSettings::GetUseImagesInMenus() const
 {
     // icon mode selected in Tools -> Options... -> OpenOffice.org -> View
@@ -841,6 +680,14 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
     if ( mpData == rSet.mpData )
         return true;
 
+    if (mpData->mIconTheme != rSet.mpData->mIconTheme) {
+        return sal_False;
+    }
+
+    if (*mpData->mIconThemeSelector != *rSet.mpData->mIconThemeSelector) {
+        return sal_False;
+    }
+
     if ( (mpData->mnOptions                 == rSet.mpData->mnOptions)                  &&
          (mpData->mnAutoMnemonic            == rSet.mpData->mnAutoMnemonic)             &&
          (mpData->mnLogoDisplayTime         == rSet.mpData->mnLogoDisplayTime)          &&
@@ -864,12 +711,10 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
          (mpData->mnAntialiasedMin          == rSet.mpData->mnAntialiasedMin)           &&
          (mpData->mnScreenZoom              == rSet.mpData->mnScreenZoom)               &&
          (mpData->mnScreenFontZoom          == rSet.mpData->mnScreenFontZoom)           &&
-         (mpData->mnHighContrast            == rSet.mpData->mnHighContrast)             &&
-         (mpData->mnUseSystemUIFonts        == rSet.mpData->mnUseSystemUIFonts)         &&
+         (mpData->mbHighContrast            == rSet.mpData->mbHighContrast)             &&
+         (mpData->mbUseSystemUIFonts        == rSet.mpData->mbUseSystemUIFonts)         &&
          (mpData->mnUseFlatBorders          == rSet.mpData->mnUseFlatBorders)           &&
          (mpData->mnUseFlatMenus            == rSet.mpData->mnUseFlatMenus)             &&
-         (mpData->mnSymbolsStyle            == rSet.mpData->mnSymbolsStyle)             &&
-         (mpData->mnPreferredSymbolsStyle   == rSet.mpData->mnPreferredSymbolsStyle)    &&
          (mpData->maFaceColor               == rSet.mpData->maFaceColor)                &&
          (mpData->maCheckedColor            == rSet.mpData->maCheckedColor)             &&
          (mpData->maLightColor              == rSet.mpData->maLightColor)               &&
@@ -931,7 +776,7 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
          (mpData->maIconFont                == rSet.mpData->maIconFont)                 &&
          (mpData->mnUseImagesInMenus        == rSet.mpData->mnUseImagesInMenus)         &&
          (mpData->mbPreferredUseImagesInMenus == rSet.mpData->mbPreferredUseImagesInMenus) &&
-         (mpData->mnSkipDisabledInMenus     == rSet.mpData->mnSkipDisabledInMenus)      &&
+         (mpData->mbSkipDisabledInMenus     == rSet.mpData->mbSkipDisabledInMenus)      &&
          (mpData->mbHideDisabledMenuItems   == rSet.mpData->mbHideDisabledMenuItems)    &&
          (mpData->mbAcceleratorsInContextMenus  == rSet.mpData->mbAcceleratorsInContextMenus)&&
          (mpData->mbPrimaryButtonWarpsSlider == rSet.mpData->mbPrimaryButtonWarpsSlider) &&
@@ -1635,4 +1480,62 @@ StyleSettings::GetOptions() const
     return mpData->mnOptions;
 }
 
+std::vector<vcl::IconThemeInfo>
+StyleSettings::GetInstalledIconThemes() const
+{
+    return mpData->mIconThemeScanner->GetFoundIconThemes();
+}
+
+/*static*/ OUString
+StyleSettings::GetAutomaticallyChosenIconTheme() const
+{
+    OUString desktopEnvironment = Application::GetDesktopEnvironment();
+    OUString themeName = mpData->mIconThemeSelector->SelectIconThemeForDesktopEnvironment(
+            mpData->mIconThemeScanner->GetFoundIconThemes(),
+            desktopEnvironment
+            );
+    return themeName;
+}
+
+void
+StyleSettings::SetIconTheme(const OUString& theme)
+{
+    CopyData();
+    mpData->mIconTheme = theme;
+}
+
+OUString
+StyleSettings::DetermineIconTheme() const
+{
+    OUString r = mpData->mIconThemeSelector->SelectIconTheme(
+                        mpData->mIconThemeScanner->GetFoundIconThemes(),
+                        mpData->mIconTheme
+                        );
+    return r;
+}
+
+void
+StyleSettings::SetHighContrastMode(bool bHighContrast )
+{
+    if (mpData->mbHighContrast == bHighContrast) {
+        return;
+    }
+
+    CopyData();
+    mpData->mbHighContrast = bHighContrast;
+    mpData->mIconThemeSelector->SetUseHighContrastTheme(bHighContrast);
+}
+
+bool
+StyleSettings::GetHighContrastMode() const
+{
+    return mpData->mbHighContrast;
+}
+
+void
+StyleSettings::SetPreferredIconTheme(const OUString& theme)
+{
+    mpData->mIconThemeSelector->SetPreferredIconTheme(theme);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index fe988dd..695d3ae 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -1210,13 +1210,13 @@ const Image& FixedImage::GetModeImage( ) const
 Image FixedImage::loadThemeImage(const OString &rFileName)
 {
     static ImplImageTreeSingletonRef aImageTree;
-    OUString sCurrentSymbolsStyle =
-        Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+    OUString sIconTheme =
+        Application::GetSettings().GetStyleSettings().DetermineIconTheme();
     const OUString sFileName(OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8));
     BitmapEx aBitmap;
-    bool bSuccess = aImageTree->loadImage(sFileName, sCurrentSymbolsStyle, aBitmap, true);
+    bool bSuccess = aImageTree->loadImage(sFileName, sIconTheme, aBitmap, true);
     SAL_WARN_IF(!bSuccess, "vcl.layout", "Unable to load " << sFileName
-        << " from theme " << sCurrentSymbolsStyle);
+        << " from theme " << sIconTheme);
     return Image(aBitmap);
 }
 
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index a8b2877..0e9cd05 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -96,9 +96,9 @@ BitmapEx::BitmapEx( const ResId& rResId ) :
     pResMgr->ReadLong();
 
     const OUString aFileName( pResMgr->ReadString() );
-    OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+    OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
-    if( !aImageTree->loadImage( aFileName, aCurrentSymbolsStyle, *this, true ) )
+    if( !aImageTree->loadImage( aFileName, aIconTheme, *this, true ) )
     {
 #ifdef DBG_UTIL
         OStringBuffer aErrorStr(
diff --git a/vcl/source/gdi/image.cxx b/vcl/source/gdi/image.cxx
index 8400942..77dd01e 100644
--- a/vcl/source/gdi/image.cxx
+++ b/vcl/source/gdi/image.cxx
@@ -379,7 +379,7 @@ void ImageAryData::Load(const OUString &rPrefix)
 {
     static ImplImageTreeSingletonRef aImageTree;
 
-    OUString aSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
+    OUString aIconTheme = Application::GetSettings().GetStyleSettings().DetermineIconTheme();
 
     BitmapEx aBmpEx;
 
@@ -388,7 +388,7 @@ void ImageAryData::Load(const OUString &rPrefix)
 #if OSL_DEBUG_LEVEL > 0
     bool bSuccess =
 #endif
-        aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list