cui/inc/strings.hrc                                        |   51 ++++
 cui/source/options/appearance.cxx                          |  145 +++++++++++++
 cui/source/options/appearance.hxx                          |    9 
 cui/uiconfig/ui/appearance.ui                              |   68 ++++++
 include/vcl/settings.hxx                                   |    1 
 include/vcl/themecolors.hxx                                |    7 
 officecfg/registry/schema/org/openoffice/Office/Common.xcs |   21 +
 sw/inc/viewsh.hxx                                          |    2 
 sw/source/core/view/viewsh.cxx                             |   24 ++
 vcl/source/app/settings.cxx                                |   49 ++++
 vcl/source/app/themecolors.cxx                             |   36 +++
 11 files changed, 411 insertions(+), 2 deletions(-)

New commits:
commit d4b4d5aabe3ba1bf2d97f97351b979c29793d912
Author:     Sahil Gautam <sahil.gautam.ext...@allotropia.de>
AuthorDate: Mon May 26 23:46:04 2025 +0530
Commit:     Sahil Gautam <sahil.gautam.ext...@allotropia.de>
CommitDate: Fri May 30 11:56:35 2025 +0200

    tdf#164970 add app background bitmap customization ui/api/code
    
    please see: https://gerrit.libreoffice.org/c/core/+/185697
            (Change-Id: I71fee27467be861b610934c213cf80fbae037327)
    
    Change-Id: I46d1a03582c06e948a98b3e554c02b2939be9168
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185858
    Reviewed-by: Sahil Gautam <sahil.gautam.ext...@allotropia.de>
    Tested-by: Jenkins

diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc
index 37b4cbf85f6c..5d90da5ec3cb 100644
--- a/cui/inc/strings.hrc
+++ b/cui/inc/strings.hrc
@@ -405,6 +405,57 @@
 #define RID_COLOR_SCHEME_LIBREOFFICE_LIGHT          
NC_("RID_COLOR_SCHEME_LIBREOFFICE_LIGHT", "Light")
 #define RID_COLOR_SCHEME_LIBREOFFICE_DARK           
NC_("RID_COLOR_SCHEME_LIBREOFFICE_DARK", "Dark")
 
+// Translatable Bitmap Names
+#define BMP_FUZZY_LIGHTGREY                         NC_("BMP_FUZZY_LIGHTGREY", 
"Fuzzy Lightgrey")
+#define BMP_ICE_LIGHT                               NC_("BMP_ICE_LIGHT", "Ice 
Light")
+#define BMP_PAINTED_WHITE                           NC_("BMP_PAINTED_WHITE", 
"Painted White")
+#define BMP_TEXTURE_PAPER                           NC_("BMP_TEXTURE_PAPER", 
"Texture Paper")
+#define BMP_CRUMPLED_PAPER                          NC_("BMP_CRUMPLED_PAPER", 
"Crumpled Paper")
+#define BMP_MARBLE                                  NC_("BMP_MARBLE", "Marble")
+#define BMP_CONCRETE                                NC_("BMP_CONCRETE", 
"Concrete")
+#define BMP_FUZZY_GREY                              NC_("BMP_FUZZY_GREY", 
"Fuzzy Grey")
+#define BMP_FUZZY_DARKGREY                          NC_("BMP_FUZZY_DARKGREY", 
"Fuzzy Darkgrey")
+#define BMP_STONE                                   NC_("BMP_STONE", "Stone")
+#define BMP_WHITE_DIFFUSION                         NC_("BMP_WHITE_DIFFUSION", 
"White Diffusion")
+#define BMP_SAND_LIGHT                              NC_("BMP_SAND_LIGHT", 
"Sand Light")
+#define BMP_SAND                                    NC_("BMP_SAND", "Sand")
+#define BMP_SURFACE                                 NC_("BMP_SURFACE", 
"Surface")
+#define BMP_STUDIO                                  NC_("BMP_STUDIO", "Studio")
+#define BMP_INVOICE_PAPER                           NC_("BMP_INVOICE_PAPER", 
"Invoice Paper")
+#define BMP_PARCHMENT_PAPER                         NC_("BMP_PARCHMENT_PAPER", 
"Parchment Paper")
+#define BMP_CARDBOARD                               NC_("BMP_CARDBOARD", 
"Cardboard")
+#define BMP_FENCE                                   NC_("BMP_FENCE", "Fence")
+#define BMP_WOODEN_FENCE                            NC_("BMP_WOODEN_FENCE", 
"Wooden Fence")
+#define BMP_WOOD                                    NC_("BMP_WOOD", "Wood")
+#define BMP_WOODEN_BOARD                            NC_("BMP_WOODEN_BOARD", 
"Wooden Board")
+#define BMP_PAINTED_WOOD                            NC_("BMP_PAINTED_WOOD", 
"Painted Wood")
+#define BMP_STONES                                  NC_("BMP_STONES", "Stones")
+#define BMP_PEBBLE_LIGHT                            NC_("BMP_PEBBLE_LIGHT", 
"Pebble Light")
+#define BMP_STONE_WALL                              NC_("BMP_STONE_WALL", 
"Stone Wall")
+#define BMP_STONE_GRAY                              NC_("BMP_STONE_GRAY", 
"Stone Gray")
+#define BMP_ROCK_WALL                               NC_("BMP_ROCK_WALL", "Rock 
Wall")
+#define BMP_SURFACE_BLACK                           NC_("BMP_SURFACE_BLACK", 
"Surface Black")
+#define BMP_BRICK_WALL                              NC_("BMP_BRICK_WALL", 
"Brick Wall")
+#define BMP_TILES                                   NC_("BMP_TILES", "Tiles")
+#define BMP_GRAPH_PAPER                             NC_("BMP_GRAPH_PAPER", 
"Graph Paper")
+#define BMP_CLOUD                                   NC_("BMP_CLOUD", "Cloud")
+#define BMP_POOL                                    NC_("BMP_POOL", "Pool")
+#define BMP_SKY                                     NC_("BMP_SKY", "Sky")
+#define BMP_CIRCUIT_BOARD                           NC_("BMP_CIRCUIT_BOARD", 
"Circuit Board")
+#define BMP_COFFEE                                  NC_("BMP_COFFEE", "Coffee")
+#define BMP_COLOR_STRIPES                           NC_("BMP_COLOR_STRIPES", 
"Color Stripes")
+#define BMP_FLORAL                                  NC_("BMP_FLORAL", "Floral")
+#define BMP_LEAF                                    NC_("BMP_LEAF", "Leaf")
+#define BMP_MAPLE_LEAVES                            NC_("BMP_MAPLE_LEAVES", 
"Maple Leaves")
+#define BMP_SPACE                                   NC_("BMP_SPACE", "Space")
+#define BMP_GIRAFFE                                 NC_("BMP_GIRAFFE", 
"Giraffe")
+#define BMP_TIGER                                   NC_("BMP_TIGER", "Tiger")
+#define BMP_ZEBRA                                   NC_("BMP_ZEBRA", "Zebra")
+
+// Transalted bitmap draw types
+#define BMP_DRAWTYPE_TILED                          NC_("BMP_DRAWTYPE_TILED", 
"Tiled")
+#define BMP_DRAWTYPE_STRETCHED                      
NC_("BMP_DRAWTYPE_STRETCHED", "Stretched")
+
 // Translated Registry Entries
 #define REG_DOCCOLOR                        NC_("REG_DOCCOLOR", "Document 
background")
 #define REG_DOCBOUNDARIES                   NC_("REG_DOCBOUNDARIES", "Document 
boundaries")
diff --git a/cui/source/options/appearance.cxx 
b/cui/source/options/appearance.cxx
index d4a3befad7f9..e697a9cfc968 100644
--- a/cui/source/options/appearance.cxx
+++ b/cui/source/options/appearance.cxx
@@ -26,6 +26,76 @@
 #include <comphelper/propertyvalue.hxx>
 #include <map>
 
+namespace
+{
+struct StringPair
+{
+    OUString aTranslatedString;
+    OUString aRawString;
+};
+
+std::vector<StringPair> const& getBitmapList()
+{
+    static const std::vector<StringPair> aBitmapList = {
+        { CuiResId(BMP_FUZZY_LIGHTGREY), "fuzzy-lightgrey.jpg" },
+        { CuiResId(BMP_ICE_LIGHT), "ice-light.jpg" },
+        { CuiResId(BMP_PAINTED_WHITE), "painted-white.jpg" },
+        { CuiResId(BMP_TEXTURE_PAPER), "texture-paper.jpg" },
+        { CuiResId(BMP_CRUMPLED_PAPER), "crumpled-paper.jpg" },
+        { CuiResId(BMP_MARBLE), "marble.jpg" },
+        { CuiResId(BMP_CONCRETE), "concrete.jpg" },
+        { CuiResId(BMP_FUZZY_GREY), "fuzzy-grey.jpg" },
+        { CuiResId(BMP_FUZZY_DARKGREY), "fuzzy-darkgrey.jpg" },
+        { CuiResId(BMP_STONE), "stone.jpg" },
+        { CuiResId(BMP_WHITE_DIFFUSION), "white-diffusion.jpg" },
+        { CuiResId(BMP_SAND_LIGHT), "sand-light.jpg" },
+        { CuiResId(BMP_SAND), "sand.jpg" },
+        { CuiResId(BMP_SURFACE), "surface.jpg" },
+        { CuiResId(BMP_STUDIO), "studio.jpg" },
+        { CuiResId(BMP_INVOICE_PAPER), "invoice-paper.jpg" },
+        { CuiResId(BMP_PARCHMENT_PAPER), "parchment-paper.jpg" },
+        { CuiResId(BMP_CARDBOARD), "cardboard.jpg" },
+        { CuiResId(BMP_FENCE), "fence.jpg" },
+        { CuiResId(BMP_WOODEN_FENCE), "wooden-fence.jpg" },
+        { CuiResId(BMP_WOOD), "wood.jpg" },
+        { CuiResId(BMP_WOODEN_BOARD), "wooden-board.jpg" },
+        { CuiResId(BMP_PAINTED_WOOD), "painted-wood.jpg" },
+        { CuiResId(BMP_STONES), "stones.jpg" },
+        { CuiResId(BMP_PEBBLE_LIGHT), "pebble-light.jpg" },
+        { CuiResId(BMP_STONE_WALL), "stone-wall.jpg" },
+        { CuiResId(BMP_STONE_GRAY), "stone-gray.jpg" },
+        { CuiResId(BMP_ROCK_WALL), "rock-wall.jpg" },
+        { CuiResId(BMP_SURFACE_BLACK), "surface-black.jpg" },
+        { CuiResId(BMP_BRICK_WALL), "brick-wall.png" },
+        { CuiResId(BMP_TILES), "tiles.jpg" },
+        { CuiResId(BMP_GRAPH_PAPER), "graph-paper.png" },
+        { CuiResId(BMP_CLOUD), "cloud.jpg" },
+        { CuiResId(BMP_POOL), "pool.jpg" },
+        { CuiResId(BMP_SKY), "sky.jpg" },
+        { CuiResId(BMP_CIRCUIT_BOARD), "circuit-board.jpg" },
+        { CuiResId(BMP_COFFEE), "coffee.jpg" },
+        { CuiResId(BMP_COLOR_STRIPES), "color-stripes.png" },
+        { CuiResId(BMP_FLORAL), "floral.png" },
+        { CuiResId(BMP_LEAF), "leaf.jpg" },
+        { CuiResId(BMP_MAPLE_LEAVES), "maple-leaves.jpg" },
+        { CuiResId(BMP_SPACE), "space.png" },
+        { CuiResId(BMP_GIRAFFE), "giraffe.png" },
+        { CuiResId(BMP_TIGER), "tiger.jpg" },
+        { CuiResId(BMP_ZEBRA), "zebra.png" },
+    };
+    return aBitmapList;
+}
+
+std::vector<StringPair> const& getBitmapDrawTypeList()
+{
+    static std::vector<StringPair> aBitmapDrawTypeList = {
+        { CuiResId(BMP_DRAWTYPE_TILED), "Tiled" },
+        { CuiResId(BMP_DRAWTYPE_STRETCHED), "Stretched" },
+    };
+    return aBitmapDrawTypeList;
+}
+}
+
 static bool IsDarkModeEnabled()
 {
     return MiscSettings::GetAppColorMode() == AppearanceMode::DARK
@@ -48,6 +118,9 @@ SvxAppearanceTabPage::SvxAppearanceTabPage(weld::Container* 
pPage,
                                           [this] { return GetFrameWeld(); })))
     , 
m_xShowInDocumentChkBtn(m_xBuilder->weld_check_button(u"showindocumentchkbtn"_ustr))
     , m_xResetAllBtn(m_xBuilder->weld_button(u"resetallbtn"_ustr))
+    , 
m_xUseBmpForAppBack(m_xBuilder->weld_check_button(u"usebmpforappback"_ustr))
+    , m_xBitmapDropDown(m_xBuilder->weld_combo_box(u"bitmapdropdown"_ustr))
+    , 
m_xBitmapDrawTypeDropDown(m_xBuilder->weld_combo_box(u"bitmapdrawtypedropdown"_ustr))
 {
     InitThemes();
     InitCustomization();
@@ -291,6 +364,22 @@ IMPL_LINK_NOARG(SvxAppearanceTabPage, ResetAllBtnHdl, 
weld::Button&, void)
     }
 }
 
+IMPL_LINK_NOARG(SvxAppearanceTabPage, BitmapDropDownHdl, weld::ComboBox&, void)
+{
+    ThemeColors::SetAppBackBmpFileName(m_xBitmapDropDown->get_active_id());
+}
+
+IMPL_LINK_NOARG(SvxAppearanceTabPage, BitmapDrawTypeDropDownHdl, 
weld::ComboBox&, void)
+{
+    
ThemeColors::SetAppBackBmpDrawType(m_xBitmapDrawTypeDropDown->get_active_id());
+}
+
+IMPL_LINK_NOARG(SvxAppearanceTabPage, UseBmpForAppBackHdl, weld::Toggleable&, 
void)
+{
+    ThemeColors::SetUseBmpForAppBack(m_xUseBmpForAppBack->get_active());
+    UpdateBmpControlsState();
+}
+
 void SvxAppearanceTabPage::InitThemes()
 {
     // init schemes combobox
@@ -306,6 +395,55 @@ void SvxAppearanceTabPage::InitThemes()
     m_xUseOnlyWhiteDocBackground->connect_toggled(
         LINK(this, SvxAppearanceTabPage, UseOnlyWhiteDocBackgroundHdl));
     
m_xUseOnlyWhiteDocBackground->set_active(ThemeColors::UseOnlyWhiteDocBackground());
+
+    // connnect callbacks for bitmap controls
+    m_xUseBmpForAppBack->connect_toggled(LINK(this, SvxAppearanceTabPage, 
UseBmpForAppBackHdl));
+    m_xBitmapDropDown->connect_changed(LINK(this, SvxAppearanceTabPage, 
BitmapDropDownHdl));
+    m_xBitmapDrawTypeDropDown->connect_changed(
+        LINK(this, SvxAppearanceTabPage, BitmapDrawTypeDropDownHdl));
+
+    // initialize bitmap controls
+    m_xUseBmpForAppBack->set_active(ThemeColors::UseBmpForAppBack());
+
+    // insert bitmap entrires
+    for (size_t i = 0; i < getBitmapList().size(); ++i)
+        m_xBitmapDropDown->append(getBitmapList()[i].aRawString,
+                                  getBitmapList()[i].aTranslatedString);
+
+    // check if the registry setting is valid or not
+    bool bFound = false;
+    for (size_t i = 0; i < getBitmapList().size(); ++i)
+    {
+        if (ThemeColors::GetAppBackBmpFileName() == 
getBitmapList()[i].aRawString)
+        {
+            bFound = true;
+            
m_xBitmapDropDown->set_active_id(ThemeColors::GetAppBackBmpFileName());
+            break;
+        }
+    }
+    if (!bFound)
+        m_xBitmapDropDown->set_active(0);
+
+    // insert bitmap draw type entries
+    for (size_t i = 0; i < getBitmapDrawTypeList().size(); ++i)
+        
m_xBitmapDrawTypeDropDown->append(getBitmapDrawTypeList()[i].aRawString,
+                                          
getBitmapDrawTypeList()[i].aTranslatedString);
+
+    // check if the registry setting is valid or not
+    bFound = false;
+    for (size_t i = 0; i < getBitmapList().size(); ++i)
+    {
+        if (ThemeColors::GetAppBackBmpDrawType() == 
getBitmapDrawTypeList()[i].aRawString)
+        {
+            bFound = true;
+            
m_xBitmapDrawTypeDropDown->set_active_id(ThemeColors::GetAppBackBmpDrawType());
+            break;
+        }
+    }
+    if (!bFound)
+        m_xBitmapDrawTypeDropDown->set_active(0);
+
+    UpdateBmpControlsState();
 }
 
 void SvxAppearanceTabPage::InitCustomization()
@@ -343,6 +481,13 @@ void SvxAppearanceTabPage::UpdateColorDropdown()
         m_xColorChangeBtn->SelectEntry(rCurrentEntryColor.nLightColor);
 }
 
+void SvxAppearanceTabPage::UpdateBmpControlsState()
+{
+    bool bEnabled = m_xUseBmpForAppBack->get_active();
+    m_xBitmapDropDown->set_sensitive(bEnabled);
+    m_xBitmapDrawTypeDropDown->set_sensitive(bEnabled);
+}
+
 void SvxAppearanceTabPage::FillItemsList()
 {
     static const std::map<ColorConfigEntry, OUString> aRegistryEntries
diff --git a/cui/source/options/appearance.hxx 
b/cui/source/options/appearance.hxx
index 55b806bddd12..a545752423e1 100644
--- a/cui/source/options/appearance.hxx
+++ b/cui/source/options/appearance.hxx
@@ -45,6 +45,10 @@ private:
     std::unique_ptr<weld::CheckButton> m_xShowInDocumentChkBtn;
     std::unique_ptr<weld::Button> m_xResetAllBtn;
 
+    std::unique_ptr<weld::CheckButton> m_xUseBmpForAppBack;
+    std::unique_ptr<weld::ComboBox> m_xBitmapDropDown;
+    std::unique_ptr<weld::ComboBox> m_xBitmapDrawTypeDropDown;
+
     DECL_LINK(ColorEntryChgHdl, weld::ComboBox&, void);
     DECL_LINK(ColorValueChgHdl, ColorListBox&, void);
     DECL_LINK(ShowInDocumentHdl, weld::Toggleable&, void);
@@ -55,10 +59,15 @@ private:
     DECL_STATIC_LINK(SvxAppearanceTabPage, MoreThemesHdl, weld::Button&, void);
     DECL_LINK(ResetAllBtnHdl, weld::Button&, void);
 
+    DECL_LINK(BitmapDropDownHdl, weld::ComboBox&, void);
+    DECL_LINK(BitmapDrawTypeDropDownHdl, weld::ComboBox&, void);
+    DECL_LINK(UseBmpForAppBackHdl, weld::Toggleable&, void);
+
     void InitThemes();
     void InitCustomization();
     void LoadSchemeList();
 
+    void UpdateBmpControlsState();
     void UpdateColorDropdown();
     void FillItemsList();
     ColorConfigEntry GetActiveEntry();
diff --git a/cui/uiconfig/ui/appearance.ui b/cui/uiconfig/ui/appearance.ui
index 5b5d2c76840c..e1964bde8c17 100644
--- a/cui/uiconfig/ui/appearance.ui
+++ b/cui/uiconfig/ui/appearance.ui
@@ -123,6 +123,74 @@
                     <property name="position">2</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkCheckButton" id="usebmpforappback">
+                    <property name="label" translatable="yes" 
context="appearance|enableapptheming">Use bitmap for application 
background</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="draw-indicator">True</property>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" 
id="usebmpforappback-atkobject">
+                        <property name="AtkObject::accessible-description" 
translatable="yes" 
context="appearance|extended_tip|useonlywhitedocbackground">Check to disable 
document color customizations and only use white document colors.</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkComboBoxText" id="bitmapdropdown">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="halign">start</property>
+                        <property name="hexpand">False</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="bitmapdropdown-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="appearance|extended_tip|bitmapdropdown">Select 
bitmap for application background from the dropdown.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkComboBoxText" 
id="bitmapdrawtypedropdown">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="halign">start</property>
+                        <property name="hexpand">False</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="bitmapdrawtypedropdown-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" 
context="appearance|extended_tip|bitmapdrawtypedropdown">Select application 
background bitmap draw type from the dropdown.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
               </object>
             </child>
             <child type="label">
diff --git a/include/vcl/settings.hxx b/include/vcl/settings.hxx
index b0ea6ab7e336..4d2b0d55cf17 100644
--- a/include/vcl/settings.hxx
+++ b/include/vcl/settings.hxx
@@ -607,6 +607,7 @@ public:
     void                            SetPreferredIconTheme(const OUString&, 
bool bDarkIconTheme = false);
 
     const DialogStyle&              GetDialogStyle() const;
+    const BitmapEx&                 GetAppBackgroundBitmap() const;
 
     // global switch to allow EdgeBlenging; currently possible for ValueSet 
and ListBox
     // when activated there using Get/SetEdgeBlending; default is true
diff --git a/include/vcl/themecolors.hxx b/include/vcl/themecolors.hxx
index 37e32bebbefe..74bdbe4cf508 100644
--- a/include/vcl/themecolors.hxx
+++ b/include/vcl/themecolors.hxx
@@ -79,6 +79,13 @@ public:
     static bool UseOnlyWhiteDocBackground();
     static void SetUseOnlyWhiteDocBackground(bool bFlag);
 
+    static bool UseBmpForAppBack();
+    static OUString GetAppBackBmpFileName();
+    static OUString GetAppBackBmpDrawType();
+    static void SetAppBackBmpFileName(const OUString& rFileName);
+    static void SetAppBackBmpDrawType(const OUString& rDrawType);
+    static void SetUseBmpForAppBack(bool bUseBmp);
+
     // !IsThemeCached means that the ThemeColors object doesn't have the 
colors from the registry yet.
     // IsThemeReset means that the user pressed the Reset All  button and the 
UI colors in the registry
     //      are not valid anymore => read from the system again
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index f520774a65f4..869790296884 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -5253,6 +5253,27 @@
         </info>
         <value>true</value>
       </prop>
+      <prop oor:name="UseBmpForAppBack" oor:type="xs:boolean" 
oor:nillable="false">
+        <info>
+          <desc>Determines whether to use bitmap or color for application 
background.</desc>
+          <label>Use bitmap for application background</label>
+        </info>
+        <value>false</value>
+      </prop>
+      <prop oor:name="AppBackBmpFileName" oor:type="xs:string" 
oor:nillable="false">
+        <info>
+          <desc>Determines the bitmap file name for application 
background.</desc>
+          <label>Application background bitmap file name</label>
+        </info>
+        <value>maple-leaves.jpg</value>
+      </prop>
+      <prop oor:name="AppBackBmpDrawType" oor:type="xs:string" 
oor:nillable="false">
+        <info>
+          <desc>Determines the draw type for application background 
bitmap.</desc>
+          <label>Application background bitmap draw type</label>
+        </info>
+        <value>Tiled</value>
+      </prop>
     </group>
     <group oor:name="Misc">
       <info>
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 7f9a9b04fafc..dc2b09f4440a 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -187,6 +187,8 @@ class SAL_DLLPUBLIC_RTTI SwViewShell : public 
sw::Ring<SwViewShell>
     // PaintDesktop split. This pars is also used by PreviewPage.
     void PaintDesktop_(const SwRegionRects &rRegion);
 
+    static bool DrawAppBackgroundBitmap(vcl::RenderContext* rRenderContext, 
const SwRect& rRect);
+
     bool CheckInvalidForPaint( const SwRect & );  // Direct Paint or rather
                                                                     // trigger 
an action.
 
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index ba4ea438ff1f..d1468614cff8 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1787,7 +1787,7 @@ void SwViewShell::PaintDesktop(const vcl::RenderContext& 
rRenderContext, const S
 // PaintDesktop is split in two, this part is also used by PreviewPage
 void SwViewShell::PaintDesktop_(const SwRegionRects &rRegion)
 {
-    if (Application::IsHeadlessModeEnabled())
+    if (DrawAppBackgroundBitmap(GetOut(), rRegion.GetOrigin()))
         return;
 
     // OD 2004-04-23 #116347#
@@ -1839,6 +1839,28 @@ void SwViewShell::PaintDesktop_(const SwRegionRects 
&rRegion)
     GetOut()->Pop();
 }
 
+bool SwViewShell::DrawAppBackgroundBitmap(vcl::RenderContext* rRenderContext, 
const SwRect& rRect)
+{
+    if (Application::IsHeadlessModeEnabled() || 
!ThemeColors::UseBmpForAppBack())
+        return false;
+
+    const BitmapEx& aAppBackImg
+        = 
Application::GetSettings().GetStyleSettings().GetAppBackgroundBitmap();
+    if (aAppBackImg.IsEmpty())
+        return false;
+
+    Wallpaper aWallpaper(aAppBackImg);
+    if (ThemeColors::GetAppBackBmpDrawType() == u"Tiled"_ustr)
+        aWallpaper.SetStyle(WallpaperStyle::Tile);
+    else if (ThemeColors::GetAppBackBmpDrawType() == u"Stretched"_ustr)
+        aWallpaper.SetStyle(WallpaperStyle::Scale);
+    else
+        aWallpaper.SetStyle(WallpaperStyle::Tile);
+
+    rRenderContext->DrawWallpaper(rRect.SVRect(), aWallpaper);
+    return true;
+}
+
 bool SwViewShell::CheckInvalidForPaint( const SwRect &rRect )
 {
     if ( !GetWin() )
diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index fac81e31f699..138f15d413a2 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -250,6 +250,9 @@ struct ImplStyleData
     Size                            maListBoxPreviewDefaultLogicSize = 
getInitListBoxPreviewDefaultLogicSize();
     // on-demand calculated in GetListBoxPreviewDefaultPixelSize()
     Size                    mutable maListBoxPreviewDefaultPixelSize;
+    BitmapEx                mutable maAppBackgroundBitmap; // cache 
AppBackground bitmap
+    OUString                mutable maAppBackgroundBitmapFileName; // cache 
AppBackground bitmap file name
+
     bool operator==(const ImplStyleData& rSet) const;
 };
 
@@ -1950,6 +1953,48 @@ StyleSettings::GetDialogStyle() const
     return mxData->maDialogStyle;
 }
 
+static BitmapEx readBitmapEx(const OUString& rPath)
+{
+    OUString aPath(rPath);
+    rtl::Bootstrap::expandMacros(aPath);
+
+    // import the image
+    Graphic aGraphic;
+    if (GraphicFilter::LoadGraphic(aPath, OUString(), aGraphic) != 
ERRCODE_NONE)
+        return BitmapEx();
+    return aGraphic.GetBitmapEx();
+}
+
+static void setupAppBackgroundBitmap(OUString& rAppBackBitmapFileName, 
BitmapEx& rAppBackBitmap)
+{
+    if (Application::IsHeadlessModeEnabled() || 
!ThemeColors::UseBmpForAppBack())
+        return;
+
+    OUString sAppBackgroundBitmap = ThemeColors::GetAppBackBmpFileName();
+    if (rAppBackBitmapFileName == sAppBackgroundBitmap)
+        return;
+
+    rAppBackBitmapFileName = sAppBackgroundBitmap;
+
+    if (!rAppBackBitmapFileName.isEmpty())
+    {
+        rAppBackBitmap = readBitmapEx("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER 
"/gallery/backgrounds/"
+                                      + rAppBackBitmapFileName);
+    }
+
+    if (rAppBackBitmap.IsEmpty())
+    {
+        SAL_WARN("vcl.app", "Failed to load AppBackground bitmap file: " << 
rAppBackBitmapFileName);
+        ThemeColors::SetUseBmpForAppBack(false);
+    }
+}
+
+BitmapEx const& StyleSettings::GetAppBackgroundBitmap() const
+{
+    setupAppBackgroundBitmap(mxData->maAppBackgroundBitmapFileName, 
mxData->maAppBackgroundBitmap);
+    return mxData->maAppBackgroundBitmap;
+}
+
 void
 StyleSettings::SetEdgeBlending(sal_uInt16 nCount)
 {
@@ -2190,7 +2235,9 @@ bool ImplStyleData::operator==(const ImplStyleData& rSet) 
const
            (mnListBoxMaximumLineCount         == 
rSet.mnListBoxMaximumLineCount)          &&
            (mnColorValueSetColumnCount        == 
rSet.mnColorValueSetColumnCount)         &&
            (maListBoxPreviewDefaultLogicSize  == 
rSet.maListBoxPreviewDefaultLogicSize)   &&
-           (mbPreviewUsesCheckeredBackground  == 
rSet.mbPreviewUsesCheckeredBackground);
+           (mbPreviewUsesCheckeredBackground  == 
rSet.mbPreviewUsesCheckeredBackground)   &&
+           (maAppBackgroundBitmapFileName     == 
rSet.maAppBackgroundBitmapFileName)      &&
+           (maAppBackgroundBitmap             == rSet.maAppBackgroundBitmap);
 }
 
 ImplMiscData::ImplMiscData() :
diff --git a/vcl/source/app/themecolors.cxx b/vcl/source/app/themecolors.cxx
index f5197bbad8e9..7cf62aab10ef 100644
--- a/vcl/source/app/themecolors.cxx
+++ b/vcl/source/app/themecolors.cxx
@@ -36,4 +36,40 @@ void ThemeColors::SetUseOnlyWhiteDocBackground(bool bFlag)
     pChange->commit();
 }
 
+bool ThemeColors::UseBmpForAppBack()
+{
+    return officecfg::Office::Common::Appearance::UseBmpForAppBack::get();
+}
+
+OUString ThemeColors::GetAppBackBmpFileName()
+{
+    return officecfg::Office::Common::Appearance::AppBackBmpFileName::get();
+}
+
+OUString ThemeColors::GetAppBackBmpDrawType()
+{
+    return officecfg::Office::Common::Appearance::AppBackBmpDrawType::get();
+}
+
+void ThemeColors::SetAppBackBmpFileName(const OUString& rFileName)
+{
+    auto pChange(comphelper::ConfigurationChanges::create());
+    officecfg::Office::Common::Appearance::AppBackBmpFileName::set(rFileName, 
pChange);
+    pChange->commit();
+}
+
+void ThemeColors::SetAppBackBmpDrawType(const OUString& rDrawType)
+{
+    auto pChange(comphelper::ConfigurationChanges::create());
+    officecfg::Office::Common::Appearance::AppBackBmpDrawType::set(rDrawType, 
pChange);
+    pChange->commit();
+}
+
+void ThemeColors::SetUseBmpForAppBack(bool bUseBmp)
+{
+    auto pChange(comphelper::ConfigurationChanges::create());
+    officecfg::Office::Common::Appearance::UseBmpForAppBack::set(bUseBmp, 
pChange);
+    pChange->commit();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to