Makefile.fetch                                         |    1 
 RepositoryExternal.mk                                  |   11 +++++
 download.lst                                           |    5 ++
 external/Module_external.mk                            |    1 
 external/zxcvbn-c/ExternalProject_zxcvbn-c.mk          |   35 +++++++++++++++++
 external/zxcvbn-c/Makefile                             |   14 ++++++
 external/zxcvbn-c/Module_zxcvbn-c.mk                   |   18 ++++++++
 external/zxcvbn-c/README.md                            |    3 +
 external/zxcvbn-c/StaticLibrary_zxcvbn-c.mk            |   26 ++++++++++++
 external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk          |   18 ++++++++
 external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch |   13 ++++++
 include/vcl/salnativewidgets.hxx                       |    1 
 include/vcl/status.hxx                                 |    2 
 include/vcl/toolkit/prgsbar.hxx                        |   10 ++++
 include/vcl/weld.hxx                                   |    9 ++++
 readlicense_oo/license/license.xml                     |   24 +++++++++++
 solenv/gbuild/extensions/pre_BuildTools.mk             |    1 
 toolkit/source/awt/vclxtoolkit.cxx                     |    2 
 vcl/inc/ControlCacheKey.hxx                            |    1 
 vcl/inc/salvtables.hxx                                 |    2 
 vcl/source/app/salvtables.cxx                          |   24 +++++++++++
 vcl/source/control/prgsbar.cxx                         |   27 ++++++++-----
 vcl/source/gdi/FileDefinitionWidgetDraw.cxx            |    2 
 vcl/source/gdi/WidgetDefinitionReader.cxx              |    1 
 vcl/source/window/builder.cxx                          |    8 +++
 vcl/source/window/status.cxx                           |   22 ++++++++--
 vcl/unx/gtk3/gtkinst.cxx                               |   29 ++++++++++++++
 vcl/win/gdi/salnativewidgets-luna.cxx                  |   33 +++++++++++++++-
 28 files changed, 322 insertions(+), 21 deletions(-)

New commits:
commit df79eedf6989ab4c2913a23a7e72079bd719168b
Author:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
AuthorDate: Sun Oct 8 21:51:12 2023 +0300
Commit:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
CommitDate: Mon Oct 30 08:17:18 2023 +0100

    tdf#157518: vcl: Introduce vcl control LevelBar
    
    Introduces LevelBar that shares implementation with
    Progress(Bar).
    
    LevelBar is to be as a level indicator, e.g. password strength
    level. Currently with native backends for gtk and Windows.
    
    Currently, except on gtk - the colors of the bar at different
    levels are hardcoded and not dependent on any kind of themeing.
    
    On Windows it follows the styling of progress bar of type "Meter"
    according to the uxguide:
    https://learn.microsoft.com/en-us/windows/win32/uxguide/progress-bars#meters
    
    Change-Id: Id772cda23615e9582463bf589e4674fd4588c864
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157826
    Tested-by: Jenkins
    Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>

diff --git a/include/vcl/salnativewidgets.hxx b/include/vcl/salnativewidgets.hxx
index 907c3b618f88..aa856a16c35d 100644
--- a/include/vcl/salnativewidgets.hxx
+++ b/include/vcl/salnativewidgets.hxx
@@ -92,6 +92,7 @@ enum class ControlType {
 // application but not for the splash
 // screen (used in desktop/)
     IntroProgress      = 132,
+    LevelBar           = 133,
 // tool tips
     Tooltip            = 140,
 // to draw the implemented theme
diff --git a/include/vcl/status.hxx b/include/vcl/status.hxx
index 4e59481671fd..0c287ddbc1b1 100644
--- a/include/vcl/status.hxx
+++ b/include/vcl/status.hxx
@@ -36,7 +36,7 @@ struct ImplStatusItem;
 void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, 
const Point& rPos,
                                 tools::Long nOffset, tools::Long nPrgsWidth, 
tools::Long nPrgsHeight,
                                 sal_uInt16 nPercent1, sal_uInt16 nPercent2, 
sal_uInt16 nPercentCount,
-                                const tools::Rectangle& rFramePosSize);
+                                const tools::Rectangle& rFramePosSize, 
ControlType eControlType);
 
 
 enum class StatusBarItemBits {
diff --git a/include/vcl/toolkit/prgsbar.hxx b/include/vcl/toolkit/prgsbar.hxx
index dd9423178dda..1fcba74fdaba 100644
--- a/include/vcl/toolkit/prgsbar.hxx
+++ b/include/vcl/toolkit/prgsbar.hxx
@@ -52,6 +52,13 @@
 
 class UNLESS_MERGELIBS(VCL_DLLPUBLIC) ProgressBar final : public vcl::Window
 {
+public:
+    enum class BarStyle
+    {
+        Progress,
+        Level,
+    };
+
 private:
     Point               maPos;
     tools::Long                mnPrgsWidth;
@@ -59,6 +66,7 @@ private:
     sal_uInt16          mnPercent;
     sal_uInt16          mnPercentCount;
     bool                mbCalcNew;
+    BarStyle            meBarStyle;
 
     using Window::ImplInit;
     SAL_DLLPRIVATE void             ImplInit();
@@ -66,7 +74,7 @@ private:
     SAL_DLLPRIVATE void ImplDrawProgress(vcl::RenderContext& rRenderContext, 
sal_uInt16 nNewPerc);
 
 public:
-                        ProgressBar( vcl::Window* pParent, WinBits nWinBits );
+                        ProgressBar( vcl::Window* pParent, WinBits nWinBits, 
BarStyle eBarStyle );
 
     virtual void        Paint( vcl::RenderContext& rRenderContext, const 
tools::Rectangle& rRect ) override;
     virtual void        Resize() override;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index e37bd36f65f4..2d8c4db085d6 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -1714,6 +1714,14 @@ public:
     virtual void set_text(const OUString& rText) = 0;
 };
 
+class VCL_DLLPUBLIC LevelBar : virtual public Widget
+{
+public:
+    /// Sets LevelBar fill percentage.
+    /// @param fPercentage bar's fill percentage, [0.0, 100.0]
+    virtual void set_percentage(double fPercentage) = 0;
+};
+
 class VCL_DLLPUBLIC Entry : virtual public Widget
 {
 private:
@@ -2622,6 +2630,7 @@ public:
     virtual std::unique_ptr<Entry> weld_entry(const OUString& id) = 0;
     virtual std::unique_ptr<Scale> weld_scale(const OUString& id) = 0;
     virtual std::unique_ptr<ProgressBar> weld_progress_bar(const OUString& id) 
= 0;
+    virtual std::unique_ptr<LevelBar> weld_level_bar(const OUString& id) = 0;
     virtual std::unique_ptr<Spinner> weld_spinner(const OUString& id) = 0;
     virtual std::unique_ptr<Image> weld_image(const OUString& id) = 0;
     virtual std::unique_ptr<Calendar> weld_calendar(const OUString& id) = 0;
diff --git a/toolkit/source/awt/vclxtoolkit.cxx 
b/toolkit/source/awt/vclxtoolkit.cxx
index 7f6bd757b914..fc6b7b9df8d9 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -1781,7 +1781,7 @@ vcl::Window* VCLXToolkit::ImplCreateWindow( 
rtl::Reference<VCLXWindow>* ppNewCom
                 }
                 else if (aServiceName == "progressbar")
                 {
-                    pNewWindow = VclPtr<ProgressBar>::Create( pParent, 
nWinBits );
+                    pNewWindow = VclPtr<ProgressBar>::Create( pParent, 
nWinBits, ProgressBar::BarStyle::Progress );
                     *ppNewComp = new VCLXProgressBar;
                 }
                 else if (aServiceName == "filecontrol")
diff --git a/vcl/inc/ControlCacheKey.hxx b/vcl/inc/ControlCacheKey.hxx
index 658d05bc84a2..e422004ca58e 100644
--- a/vcl/inc/ControlCacheKey.hxx
+++ b/vcl/inc/ControlCacheKey.hxx
@@ -55,6 +55,7 @@ public:
             case ControlType::Radiobutton:
             case ControlType::ListNode:
             case ControlType::Slider:
+            case ControlType::LevelBar:
             case ControlType::Progress:
             // FIXME: these guys have complex state hidden in ImplControlValue
             // structs which affects rendering, needs to be a and needs to be
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 8648db8e5143..4074e097a4f4 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -91,6 +91,8 @@ public:
 
     virtual std::unique_ptr<weld::ProgressBar> weld_progress_bar(const 
OUString& id) override;
 
+    virtual std::unique_ptr<weld::LevelBar> weld_level_bar(const OUString& id) 
override;
+
     virtual std::unique_ptr<weld::Spinner> weld_spinner(const OUString& id) 
override;
 
     virtual std::unique_ptr<weld::Image> weld_image(const OUString& id) 
override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ce78cf1e235c..fa9e7fa6d476 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3302,6 +3302,24 @@ public:
 
     virtual void set_text(const OUString& rText) override { 
m_xProgressBar->SetText(rText); }
 };
+
+class SalInstanceLevelBar : public SalInstanceWidget, public virtual 
weld::LevelBar
+{
+private:
+    VclPtr<::ProgressBar> m_xLevelBar;
+
+public:
+    SalInstanceLevelBar(::ProgressBar* pLevelBar, SalInstanceBuilder* 
pBuilder, bool bTakeOwnership)
+        : SalInstanceWidget(pLevelBar, pBuilder, bTakeOwnership)
+        , m_xLevelBar(pLevelBar)
+    {
+    }
+
+    virtual void set_percentage(double fPercentage) override
+    {
+        m_xLevelBar->SetValue(static_cast<sal_uInt16>(fPercentage));
+    }
+};
 }
 
 IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
@@ -7212,6 +7230,12 @@ std::unique_ptr<weld::ProgressBar> 
SalInstanceBuilder::weld_progress_bar(const O
     return pProgress ? std::make_unique<SalInstanceProgressBar>(pProgress, 
this, false) : nullptr;
 }
 
+std::unique_ptr<weld::LevelBar> SalInstanceBuilder::weld_level_bar(const 
OUString& id)
+{
+    ::ProgressBar* pLevel = m_xBuilder->get<::ProgressBar>(id);
+    return pLevel ? std::make_unique<SalInstanceLevelBar>(pLevel, this, false) 
: nullptr;
+}
+
 std::unique_ptr<weld::Spinner> SalInstanceBuilder::weld_spinner(const 
OUString& id)
 {
     Throbber* pThrobber = m_xBuilder->get<Throbber>(id);
diff --git a/vcl/source/control/prgsbar.cxx b/vcl/source/control/prgsbar.cxx
index 6b7a7007c599..e15c7c055dbe 100644
--- a/vcl/source/control/prgsbar.cxx
+++ b/vcl/source/control/prgsbar.cxx
@@ -39,12 +39,15 @@ void ProgressBar::ImplInit()
     ImplInitSettings( true, true, true );
 }
 
-static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits 
nOrgStyle )
+static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits 
nOrgStyle, ProgressBar::BarStyle eBarStyle )
 {
     WinBits nOutStyle = nOrgStyle;
     if( pParent && (nOrgStyle & WB_BORDER) != 0 )
     {
-        if( pParent->IsNativeControlSupported( ControlType::Progress, 
ControlPart::Entire ) )
+        if (pParent->IsNativeControlSupported(eBarStyle == 
ProgressBar::BarStyle::Progress
+                                                  ? ControlType::Progress
+                                                  : ControlType::LevelBar,
+                                              ControlPart::Entire))
             nOutStyle &= WB_BORDER;
     }
     return nOutStyle;
@@ -52,11 +55,12 @@ static WinBits clearProgressBarBorder( vcl::Window const * 
pParent, WinBits nOrg
 
 Size ProgressBar::GetOptimalSize() const
 {
-    return Size(150, 20);
+    return meBarStyle == BarStyle::Progress ? Size(150, 20) : Size(150,10);
 }
 
-ProgressBar::ProgressBar( vcl::Window* pParent, WinBits nWinStyle ) :
-    Window( pParent, clearProgressBarBorder( pParent, nWinStyle ) )
+ProgressBar::ProgressBar( vcl::Window* pParent, WinBits nWinStyle, BarStyle 
eBarStyle ) :
+        Window( pParent, clearProgressBarBorder( pParent, nWinStyle, eBarStyle 
) ),
+        meBarStyle(eBarStyle)
 {
     SetOutputSizePixel( GetOptimalSize() );
     ImplInit();
@@ -74,8 +78,10 @@ void ProgressBar::ImplInitSettings( bool bFont,
 
     if ( bBackground )
     {
-        if( !IsControlBackground() &&
-            IsNativeControlSupported( ControlType::Progress, 
ControlPart::Entire ) )
+        if (!IsControlBackground()
+            && IsNativeControlSupported(meBarStyle == BarStyle::Progress ? 
ControlType::Progress
+                                                                         : 
ControlType::LevelBar,
+                                        ControlPart::Entire))
         {
             if( GetStyle() & WB_BORDER )
                 SetBorderStyle( WindowBorderStyle::REMOVEBORDER );
@@ -144,9 +150,10 @@ void ProgressBar::ImplDrawProgress(vcl::RenderContext& 
rRenderContext, sal_uInt1
         maPos.setX( (aSize.Width() - nMaxWidth) / 2 );
     }
 
-    ::DrawProgress(this, rRenderContext, maPos, PROGRESSBAR_OFFSET, 
mnPrgsWidth, mnPrgsHeight,
-                   /*nPercent1=*/0, nNewPerc * 100, mnPercentCount,
-                   tools::Rectangle(Point(), GetSizePixel()));
+    ::DrawProgress(
+        this, rRenderContext, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, 
mnPrgsHeight,
+        /*nPercent1=*/0, nNewPerc * 100, mnPercentCount, 
tools::Rectangle(Point(), GetSizePixel()),
+        meBarStyle == BarStyle::Progress ? ControlType::Progress : 
ControlType::LevelBar);
 }
 
 void ProgressBar::Paint(vcl::RenderContext& rRenderContext, const 
tools::Rectangle& /*rRect*/)
diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx 
b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
index 442111571dd8..6426491f25d7 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -188,6 +188,7 @@ bool 
FileDefinitionWidgetDraw::isNativeControlSupported(ControlType eType, Contr
         case ControlType::MenuPopup:
             return true;
         case ControlType::Progress:
+        case ControlType::LevelBar:
             return true;
         case ControlType::IntroProgress:
             return false;
@@ -750,6 +751,7 @@ bool 
FileDefinitionWidgetDraw::drawNativeControl(ControlType eType, ControlPart
         }
         break;
         case ControlType::Progress:
+        case ControlType::LevelBar:
         {
             bOK = resolveDefinition(eType, ePart, eState, rValue, nX, nY, 
nWidth, nHeight);
         }
diff --git a/vcl/source/gdi/WidgetDefinitionReader.cxx 
b/vcl/source/gdi/WidgetDefinitionReader.cxx
index b635c5e3f9b0..a36c62564ea2 100644
--- a/vcl/source/gdi/WidgetDefinitionReader.cxx
+++ b/vcl/source/gdi/WidgetDefinitionReader.cxx
@@ -160,6 +160,7 @@ bool getControlTypeForXmlString(OString const& rString, 
ControlType& reType)
         { "slider", ControlType::Slider },
         { "fixedline", ControlType::Fixedline },
         { "progress", ControlType::Progress },
+        { "levelbar", ControlType::LevelBar },
         { "tabitem", ControlType::TabItem },
         { "tabheader", ControlType::TabHeader },
         { "tabpane", ControlType::TabPane },
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 3d9456432164..bc307ba85561 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -2025,7 +2025,13 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window 
*pParent, const OUString
     {
         extractAdjustmentToMap(id, rMap, 
m_pParserState->m_aScrollAdjustmentMaps);
         bVertical = extractOrientation(rMap);
-        xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : 
WB_HORZ);
+        xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : 
WB_HORZ, ProgressBar::BarStyle::Progress);
+    }
+    else if (name == "GtkLevelBar")
+    {
+        extractAdjustmentToMap(id, rMap, 
m_pParserState->m_aScrollAdjustmentMaps);
+        bVertical = extractOrientation(rMap);
+        xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : 
WB_HORZ, ProgressBar::BarStyle::Level);
     }
     else if (name == "GtkScrolledWindow")
     {
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index 23f4cfc086bf..fc14762bef7a 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -474,9 +474,9 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& 
rRenderContext, bool bOffScreen
 void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, 
const Point& rPos,
                   tools::Long nOffset, tools::Long nPrgsWidth, tools::Long 
nPrgsHeight,
                   sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 
nPercentCount,
-                  const tools::Rectangle& rFramePosSize)
+                  const tools::Rectangle& rFramePosSize, ControlType 
eControlType)
 {
-    if (rRenderContext.IsNativeControlSupported(ControlType::Progress, 
ControlPart::Entire))
+    if (rRenderContext.IsNativeControlSupported(eControlType, 
ControlPart::Entire))
     {
         bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
 
@@ -514,7 +514,7 @@ void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& 
rRenderContext, cons
             rRenderContext.IntersectClipRegion(rFramePosSize);
         }
 
-        bool bNativeOK = 
rRenderContext.DrawNativeControl(ControlType::Progress, ControlPart::Entire, 
aControlRegion,
+        bool bNativeOK = rRenderContext.DrawNativeControl(eControlType, 
ControlPart::Entire, aControlRegion,
                                                           
ControlState::ENABLED, aValue, OUString());
         if (bNeedErase)
             rRenderContext.Pop();
@@ -522,6 +522,18 @@ void DrawProgress(vcl::Window* pWindow, 
vcl::RenderContext& rRenderContext, cons
             return;
     }
 
+    if (eControlType == ControlType::LevelBar)
+    {
+        if (nPercent2 < 2500)
+            rRenderContext.SetFillColor({ 0xFF0000 });
+        else if (nPercent2 < 5000)
+            rRenderContext.SetFillColor({ 0xFFFF00 });
+        else if (nPercent2 < 7500)
+            rRenderContext.SetFillColor({ 0x0000FF });
+        else
+            rRenderContext.SetFillColor({ 0x00FF00 });
+    }
+
     // precompute values
     sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
     sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
@@ -570,7 +582,7 @@ void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& 
rRenderContext, cons
         while (nPerc1 < nPerc2);
 
         // if greater than 100%, set rectangle to blink
-        if (nPercent2 > 10000)
+        if (nPercent2 > 10000 && eControlType == ControlType::Progress)
         {
             // define on/off status
             if (((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01))
@@ -603,7 +615,7 @@ void StatusBar::ImplDrawProgress(vcl::RenderContext& 
rRenderContext, sal_uInt16
         nPrgsHeight = maPrgsFrameRect.GetHeight();
     }
     DrawProgress(this, rRenderContext, aPos, mnPrgsSize / 2, mnPrgsSize, 
nPrgsHeight,
-                 0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect);
+                 0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect, 
ControlType::Progress);
 }
 
 void StatusBar::ImplCalcProgressRect()
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index aaddf24bce32..22b0e0273381 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -12843,6 +12843,25 @@ public:
     }
 };
 
+class GtkInstanceLevelBar : public GtkInstanceWidget, public virtual 
weld::LevelBar
+{
+private:
+    GtkLevelBar* m_pLevelBar;
+
+public:
+    GtkInstanceLevelBar(GtkLevelBar* pLevelBar, GtkInstanceBuilder* pBuilder,
+                        bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pLevelBar), pBuilder, bTakeOwnership)
+        , m_pLevelBar(pLevelBar)
+    {
+    }
+
+    virtual void set_percentage(double fPercentage) override
+    {
+        gtk_level_bar_set_value(m_pLevelBar, fPercentage / 100.0);
+    }
+};
+
 class GtkInstanceSpinner : public GtkInstanceWidget, public virtual 
weld::Spinner
 {
 private:
@@ -24341,6 +24360,16 @@ public:
         return std::make_unique<GtkInstanceProgressBar>(pProgressBar, this, 
false);
     }
 
+    virtual std::unique_ptr<weld::LevelBar> weld_level_bar(const OUString& id) 
override
+    {
+        GtkLevelBar* pLevelBar = GTK_LEVEL_BAR(gtk_builder_get_object(
+            m_pBuilder, OUStringToOString(id, 
RTL_TEXTENCODING_UTF8).getStr()));
+        if (!pLevelBar)
+            return nullptr;
+        auto_add_parentless_widgets_to_container(GTK_WIDGET(pLevelBar));
+        return std::make_unique<GtkInstanceLevelBar>(pLevelBar, this, false);
+    }
+
     virtual std::unique_ptr<weld::Spinner> weld_spinner(const OUString &id) 
override
     {
         GtkSpinner* pSpinner = GTK_SPINNER(gtk_builder_get_object(m_pBuilder, 
OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr()));
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx 
b/vcl/win/gdi/salnativewidgets-luna.cxx
index 0dd5b2dd7442..c5a368c8c52c 100644
--- a/vcl/win/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/gdi/salnativewidgets-luna.cxx
@@ -190,6 +190,7 @@ bool WinSalGraphics::isNativeControlSupported( ControlType 
nType, ControlPart nP
             }
             break;
         case ControlType::Progress:
+        case ControlType::LevelBar:
             if( nPart == ControlPart::Entire )
                 hTheme = getThemeHandle(mhWnd, L"Progress", 
mWinSalGraphicsImplBase);
             break;
@@ -1003,12 +1004,19 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME 
hTheme, RECT rc,
         }
     }
 
-    if( nType == ControlType::Progress )
+    if( nType == ControlType::Progress || nType == ControlType::LevelBar )
     {
         if( nPart != ControlPart::Entire )
             return false;
 
-        if( ! ImplDrawTheme( hTheme, hDC, PP_BAR, iState, rc, aCaption) )
+        int nPartIdBackground = PP_BAR;
+        if( nType == ControlType::LevelBar )
+        {
+            nPartIdBackground = PP_TRANSPARENTBAR;
+            iState = PBBS_PARTIAL;
+        }
+
+        if( ! ImplDrawTheme( hTheme, hDC, nPartIdBackground, iState, rc, 
aCaption) )
             return false;
         RECT aProgressRect = rc;
         if( GetThemeBackgroundContentRect( hTheme, hDC, PP_BAR, iState, &rc, 
&aProgressRect) != S_OK )
@@ -1022,6 +1030,26 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME 
hTheme, RECT rc,
         else
             aProgressRect.right = aProgressRect.left + nProgressWidth;
 
+        if (nType == ControlType::LevelBar)
+        {
+            const auto nPercentage
+                = aValue.getNumericVal() * 100 / std::max(LONG{ 1 }, (rc.right 
- rc.left));
+
+            COLORREF aBrushColor{};
+            if (nPercentage < 25)
+                aBrushColor = RGB(255, 0, 0);
+            else if (nPercentage < 50)
+                aBrushColor = RGB(255, 255, 0);
+            else if (nPercentage < 75)
+                aBrushColor = RGB(0, 0, 255);
+            else
+                aBrushColor = RGB(0, 255, 0);
+
+            ScopedHBRUSH hBrush(CreateSolidBrush(aBrushColor));
+            FillRect(hDC, &aProgressRect, hBrush.get());
+            return true;
+        }
+
         return ImplDrawTheme( hTheme, hDC, PP_CHUNK, iState, aProgressRect, 
aCaption );
     }
 
@@ -1272,6 +1300,7 @@ bool WinSalGraphics::drawNativeControl( ControlType nType,
             }
             break;
         case ControlType::Progress:
+        case ControlType::LevelBar:
             if( nPart == ControlPart::Entire )
                 hTheme = getThemeHandle(mhWnd, L"Progress", 
mWinSalGraphicsImplBase);
             break;
commit 3d5cafbe1727a95a54eb4a65d98d6d79ec46f0c8
Author:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
AuthorDate: Mon Oct 2 15:56:04 2023 +0300
Commit:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
CommitDate: Mon Oct 30 08:17:05 2023 +0100

    tdf#157518: external: bundle zxcvbn-c
    
    Integrates zxcvbn-c as a static library.
    
    zxcvbn-c is C/C++ implementation of
    https://dropbox.tech/security/zxcvbn-realistic-password-strength-estimation.
    
    This is the first step for introducing a password strength
    meter. Some example projects that utilize zxcvbn-c are
    KeepassXC, monero-gui.
    
    ExternalProject_zxcvbn-c takes care of the dictionary node
    generation bits resulting in the dict-src.h
    
    Then StaticLibrary_zxcvbn-c depends on
    ExternalProject_zxcvbn-c and uses the generated bits and the
    zxcvbn-c source to compile the library.
    
    It should be possible to get rid of dictionary node
    generation bit with a patch that includes a constant
    dict-src.h that's what monero-gui does for example. But this
    might also obfuscate what dict-src.h is.
    
    Right now the dictionary that is included with zxcvbn-c only
    targets English, so that might be something to improve upon.
    
    Change-Id: Ic2b0a558cff341114d69fbdc257979a28bf5c865
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157565
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    Tested-by: Jenkins
    Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>

diff --git a/Makefile.fetch b/Makefile.fetch
index 8cd2c543891f..d445898c94c6 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -171,6 +171,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk 
$(SRCDIR)/download.lst $(S
                $(call fetch_Optional,LXML,LXML_TARBALL) \
                $(call 
fetch_Optional,MARIADB_CONNECTOR_C,MARIADB_CONNECTOR_C_TARBALL) \
                $(call fetch_Optional,MDDS,MDDS_TARBALL) \
+               ZXCVBN_C_TARBALL \
                $(call fetch_Optional,ZXING,ZXING_TARBALL) \
                $(call fetch_Optional,MDNSRESPONDER,MDNSRESPONDER_TARBALL) \
                $(call fetch_Optional,MORE_FONTS,FONT_CALADEA_TARBALL) \
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 744353b58fe3..0a0be689fd07 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -4287,6 +4287,17 @@ endef
 
 endif # SYSTEM_BOX2D
 
+define gb_LinkTarget__use_zxcvbn-c
+$(call gb_LinkTarget_use_unpacked,$(1),zxcvbn-c)
+$(call gb_LinkTarget_set_include,$(1),\
+       -I$(call gb_UnpackedTarball_get_dir,zxcvbn-c)\
+       $$(INCLUDE) \
+)
+$(call gb_LinkTarget_use_static_libraries,$(1),\
+       zxcvbn-c \
+)
+endef
+
 ifneq ($(SYSTEM_ZXING),)
 
 define gb_LinkTarget__use_zxing
diff --git a/download.lst b/download.lst
index d83931988bdd..b85d4bd437e9 100644
--- a/download.lst
+++ b/download.lst
@@ -640,6 +640,11 @@ ZMF_TARBALL := libzmf-0.0.2.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
+ZXCVBN_C_SHA256SUM := 
77d6c6ecb35952a8d8ce7f736b7a2bf466275c48210e309b73782d6b7e84dffd
+ZXCVBN_C_TARBALL := zxcvbn-c-2.5.tar.gz
+# three static lines
+# so that git cherry-pick
+# will not run into conflicts
 ZXING_SHA256SUM := 
6d54e403592ec7a143791c6526c1baafddf4c0897bb49b1af72b70a0f0c4a3fe
 ZXING_TARBALL := zxing-cpp-2.1.0.tar.gz
 # three static lines
diff --git a/external/Module_external.mk b/external/Module_external.mk
index 366509f8960e..2b2cd99ff399 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -90,6 +90,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\
        $(call gb_Helper_optional,POSTGRESQL,postgresql) \
        $(call gb_Helper_optional,PYTHON,python3) \
        $(call gb_Helper_optional,QXP,libqxp) \
+       zxcvbn-c \
        $(call gb_Helper_optional,ZXING,zxing) \
        $(call gb_Helper_optional,REDLAND,redland) \
        $(call gb_Helper_optional,REVENGE,librevenge) \
diff --git a/external/zxcvbn-c/ExternalProject_zxcvbn-c.mk 
b/external/zxcvbn-c/ExternalProject_zxcvbn-c.mk
new file mode 100644
index 000000000000..51b60a9c2ecb
--- /dev/null
+++ b/external/zxcvbn-c/ExternalProject_zxcvbn-c.mk
@@ -0,0 +1,35 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# 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_ExternalProject_ExternalProject,zxcvbn-c))
+
+$(eval $(call gb_ExternalProject_register_targets,zxcvbn-c,\
+       generate-dictionary-nodes \
+))
+
+$(call 
gb_ExternalProject_get_state_target,zxcvbn-c,generate-dictionary-nodes): \
+               $(call gb_Executable_get_runtime_dependencies,gcc-wrapper) \
+               $(call gb_Executable_get_runtime_dependencies,g++-wrapper) \
+               $(if $(CROSS_COMPILING),$(call 
gb_ExternalProject_get_target_for_build,zxcvbn-c))
+       $(call gb_Trace_StartRange,zxcvbn-c,EXTERNAL)
+       $(call gb_ExternalProject_run,generate-dictionary-nodes,\
+               $(if $(CROSS_COMPILING),\
+                       cp 
$(WORKDIR_FOR_BUILD)/UnpackedTarball/zxcvbn-c/dict-src.h \
+                               $(WORKDIR)/UnpackedTarball/zxcvbn-c/dict-src.h \
+               ,\
+                       $(MAKE) dict-src.h \
+                               AR="$(gb_AR)" \
+                               CFLAGS="$(gb_CFLAGS)" \
+                               CXXFLAGS="$(gb_CXXFLAGS)" \
+                               $(if $(filter 
MSC,$(COM)),$(gb_AUTOCONF_WRAPPERS) )\
+               )\
+       )
+       $(call gb_Trace_EndRange,zxcvbn-c,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxcvbn-c/Makefile b/external/zxcvbn-c/Makefile
new file mode 100644
index 000000000000..6427d44e3790
--- /dev/null
+++ b/external/zxcvbn-c/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# 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/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxcvbn-c/Module_zxcvbn-c.mk 
b/external/zxcvbn-c/Module_zxcvbn-c.mk
new file mode 100644
index 000000000000..14d5dfbe6abc
--- /dev/null
+++ b/external/zxcvbn-c/Module_zxcvbn-c.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# 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_Module_Module,zxcvbn-c))
+
+$(eval $(call gb_Module_add_targets,zxcvbn-c,\
+       UnpackedTarball_zxcvbn-c \
+       ExternalProject_zxcvbn-c \
+       StaticLibrary_zxcvbn-c \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxcvbn-c/README.md b/external/zxcvbn-c/README.md
new file mode 100644
index 000000000000..6193c7307e85
--- /dev/null
+++ b/external/zxcvbn-c/README.md
@@ -0,0 +1,3 @@
+C/C++ version of the zxcvbn password strength estimator.
+
+zxcvbn-c is available from [ https://github.com/tsyrogit/zxcvbn-c ].
diff --git a/external/zxcvbn-c/StaticLibrary_zxcvbn-c.mk 
b/external/zxcvbn-c/StaticLibrary_zxcvbn-c.mk
new file mode 100644
index 000000000000..9748ef850c55
--- /dev/null
+++ b/external/zxcvbn-c/StaticLibrary_zxcvbn-c.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# 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_StaticLibrary_StaticLibrary,zxcvbn-c))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,zxcvbn-c,zxcvbn-c))
+
+# zxcvbn-c static library depends on generation of dictionary nodes resulting 
in dict-src.h
+$(eval $(call gb_StaticLibrary_use_external_project,zxcvbn-c,zxcvbn-c,full))
+
+$(eval $(call gb_StaticLibrary_set_include,zxcvbn-c,\
+    -I$(call gb_UnpackedTarball_get_dir,zxcvbn-c)\
+    $$(INCLUDE)\
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,zxcvbn-c,\
+       UnpackedTarball/zxcvbn-c/zxcvbn \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk 
b/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk
new file mode 100644
index 000000000000..b6eba6b8cb3a
--- /dev/null
+++ b/external/zxcvbn-c/UnpackedTarball_zxcvbn-c.mk
@@ -0,0 +1,18 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 
100 -*-
+#
+# 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_UnpackedTarball_UnpackedTarball,zxcvbn-c))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,zxcvbn-c,$(ZXCVBN_C_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_add_patches,zxcvbn-c,\
+       external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch 
b/external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch
new file mode 100644
index 000000000000..1b5151995067
--- /dev/null
+++ b/external/zxcvbn-c/zxcvbn-c-2.5-do-not-use-stdafx.patch
@@ -0,0 +1,13 @@
+--- a/zxcvbn-c/zxcvbn.c
++++ b/zxcvbn-c/zxcvbn.c
+@@ -44,11 +44,6 @@
+ #endif
+ #endif
+
+-/* For pre-compiled headers under windows */
+-#ifdef _WIN32
+-#include "stdafx.h"
+-#endif
+-
+ /* Minimum number of characters in a incrementing/decrementing sequence match 
*/
+ #define MIN_SEQUENCE_LEN 3
diff --git a/readlicense_oo/license/license.xml 
b/readlicense_oo/license/license.xml
index 57d270e15b94..2e61d6f82e75 100644
--- a/readlicense_oo/license/license.xml
+++ b/readlicense_oo/license/license.xml
@@ -1815,6 +1815,30 @@
         PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
         WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</p>
     </div>
+    <h2>zxcvbn-c</h2>
+    <p>The following software may be included in this product: zxcvbn-c.</p>
+    <p>zxcvbn-c code is covered by the MIT license:</p>
+    <blockquote>
+      <p>Copyright (c) 2015-2017 Tony Evans </p>
+
+      <p>Permission is hereby granted, free of charge, to any person obtaining 
a copy
+      of this software and associated documentation files (the "Software"), to 
deal
+      in the Software without restriction, including without limitation the 
rights
+      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+      copies of the Software, and to permit persons to whom the Software is
+      furnished to do so, subject to the following conditions:</p>
+
+      <p>The above copyright notice and this permission notice shall be 
included in
+      all copies or substantial portions of the Software.</p>
+
+      <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
THE
+      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+      THE SOFTWARE.</p>
+    </blockquote>
     <h2>Dragonbox</h2>
     <p>The following software may be included in this product: Dragonbox.</p>
     <p>Dragonbox code is covered by the following license:</p>
diff --git a/solenv/gbuild/extensions/pre_BuildTools.mk 
b/solenv/gbuild/extensions/pre_BuildTools.mk
index 0a83545cf748..891d478262b5 100644
--- a/solenv/gbuild/extensions/pre_BuildTools.mk
+++ b/solenv/gbuild/extensions/pre_BuildTools.mk
@@ -48,6 +48,7 @@ gb_BUILD_TOOLS = \
     $(foreach executable,$(gb_BUILD_TOOLS_executables),$(call 
gb_Executable_get_runtime_dependencies,$(executable))) \
     $(foreach executable,$(gb_BUILD_TOOLS_executables_extern),$(call 
gb_ExternalExecutable_get_dependencies,$(executable))) \
        $(INSTROOT)/$(LIBO_URE_ETC_FOLDER)/$(call gb_Helper_get_rcfile,uno) \
+       $(call gb_ExternalProject_get_target_for_build,zxcvbn-c) \
 
 endif
 

Reply via email to