tdf#105829 Infobar design, tdf#102785 Font issue

Only one constructor to append an infobar
Colors defined at one place in infobar.cxx based on InfoBarType
Icons as an additional attribute of the notification

Change-Id: I4dc85c2b4ef0b7eafc139290b3b4ee21636da6ec
Reviewed-on: https://gerrit.libreoffice.org/34426
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Heiko Tietze <tietze.heiko@googlemail.com>
diff --git a/include/sfx2/classificationhelper.hxx b/include/sfx2/classificationhelper.hxx
index 18dd351..3ad53c6 100644
--- a/include/sfx2/classificationhelper.hxx
+++ b/include/sfx2/classificationhelper.hxx
@@ -17,6 +17,7 @@

#include <rtl/ustring.hxx>
#include <sfx2/dllapi.h>
#include <sfx2/infobar.hxx>

class SfxObjectShell;
class SfxViewFrame;
@@ -66,7 +67,7 @@ public:
    void SetBACName(const OUString& rName, SfxClassificationPolicyType eType);
    /// If GetImpactScale() and GetImpactLevel*() will return something meaningful.
    bool HasImpactLevel();
    basegfx::BColor GetImpactLevelColor();
    InfoBarType GetImpactLevelType();
    /// Larger value means more confidential.
    sal_Int32 GetImpactLevel();
    /// Comparing the GetImpactLevel() result is only meaningful when the impact scale is the same.
diff --git a/include/sfx2/infobar.hxx b/include/sfx2/infobar.hxx
index 3043a2f..d78aed2 100644
--- a/include/sfx2/infobar.hxx
+++ b/include/sfx2/infobar.hxx
@@ -18,6 +18,13 @@
#include <sfx2/dllapi.h>
#include <sfx2/childwin.hxx>

enum class InfoBarType {
    Info,
    Success,
    Warning,
    Danger
};

/** SfxChildWindow for positioning the InfoBar in the view.
  */
class SFX2_DLLPUBLIC SfxInfoBarContainerChild : public SfxChildWindow
@@ -43,25 +50,24 @@ class SfxInfoBarWindow : public vcl::Window
{
    private:
        OUString                           m_sId;
        VclPtr<FixedText>                  m_pMessage;
        VclPtr<Button>                     m_pCloseBtn;
        VclPtr<FixedImage>        m_pImage;
        VclPtr<FixedText>           m_pMessage;
        VclPtr<Button>                m_pCloseBtn;
        std::vector< VclPtr<PushButton> >  m_aActionBtns;
        basegfx::BColor                    m_aBackgroundColor;
        basegfx::BColor                    m_aForegroundColor;

    public:
        SfxInfoBarWindow( vcl::Window* parent, const OUString& sId,
                          const OUString& sMessage,
                          const basegfx::BColor* pBackgroundColor,
                          const basegfx::BColor* pForegroundColor,
                          const basegfx::BColor* pMessageColor,
                          WinBits nMessageStyle );
                          InfoBarType infoBarType,
                          WinBits nMessageStyle);
        virtual ~SfxInfoBarWindow( ) override;
        virtual void dispose() override;

        const OUString& getId() const { return m_sId; }
        virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& ) override;
        virtual void Resize( ) override;
        basegfx::BColor                m_aBackgroundColor;
        basegfx::BColor                m_aForegroundColor;

        /** Add button to Infobar.
         * Infobar takes ownership of the button so the button is
@@ -73,14 +79,6 @@ class SfxInfoBarWindow : public vcl::Window
        DECL_LINK( CloseHandler, Button*, void );
};


enum class InfoBarType {
    Info,
    Success,
    Warning,
    Danger
};

class SfxInfoBarContainerWindow : public vcl::Window
{
    private:
@@ -94,14 +92,8 @@ class SfxInfoBarContainerWindow : public vcl::Window

        VclPtr<SfxInfoBarWindow> appendInfoBar(const OUString& sId,
                                        const OUString& sMessage,
                                        InfoBarType aInfoBarType,
                                        WinBits nMessageStyle);
        VclPtr<SfxInfoBarWindow> appendInfoBar(const OUString& sId,
                                        const OUString& sMessage,
                                        const basegfx::BColor* pBackgroundColor,
                                        const basegfx::BColor* pForegroundColor,
                                        const basegfx::BColor* pMessageColor,
                                        WinBits nMessageStyle);
                                        InfoBarType ibType,
                                        WinBits nMessageStyle = WB_LEFT|WB_VCENTER);
        VclPtr<SfxInfoBarWindow> getInfoBar(const OUString& sId);
        void removeInfoBar(VclPtr<SfxInfoBarWindow> const & pInfoBar);

diff --git a/include/sfx2/viewfrm.hxx b/include/sfx2/viewfrm.hxx
index 1ae2a58..2b6093e 100644
--- a/include/sfx2/viewfrm.hxx
+++ b/include/sfx2/viewfrm.hxx
@@ -174,13 +174,7 @@ public:
    VclPtr<SfxInfoBarWindow> AppendInfoBar(const OUString& sId,
                                    const OUString& sMessage,
                                    InfoBarType aInfoBarType,
                                    WinBits nMessageStyle = 0);
    VclPtr<SfxInfoBarWindow> AppendInfoBar(const OUString& sId,
                                    const OUString& sMessage,
                                    const basegfx::BColor* pBackgroundColor = nullptr,
                                    const basegfx::BColor* pForegroundColor = nullptr,
                                    const basegfx::BColor* pMessageColor = nullptr,
                                    WinBits nMessageStyle = 0);
                                    WinBits nMessageStyle = WB_LEFT|WB_VCENTER);
    void              RemoveInfoBar(const OUString& sId);

    SAL_DLLPRIVATE void GetDocNumber_Impl();
diff --git a/sfx2/source/dialog/infobar.cxx b/sfx2/source/dialog/infobar.cxx
index c80825b..190759b 100644
--- a/sfx2/source/dialog/infobar.cxx
+++ b/sfx2/source/dialog/infobar.cxx
@@ -34,33 +34,75 @@ namespace

const long INFO_BAR_BASE_HEIGHT = 40;

const BColor constLightColor(1.0, 1.0, 191.0 / 255.0);
const BColor constDarkColor(217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0);

void lclDetermineLightDarkColor(BColor& rLightColor, BColor& rDarkColor)
void GetInfoBarColors(InfoBarType ibType, BColor&  rBackgroundColor, BColor& rForegroundColor, BColor& rMessageColor)
{
    switch (ibType)
    {
    case InfoBarType::Info: // blue; #00529B/0,82,155; #BDE5F8/189,229,248
        rBackgroundColor = basegfx::BColor(0.741, 0.898, 0.973);
        rForegroundColor = basegfx::BColor(0.0, 0.322, 0.608);
        rMessageColor = basegfx::BColor(0.0, 0.322, 0.608);
        break;
    case InfoBarType::Success: // green; #4F8A10/79,138,16; #DFF2BF/223,242,191
        rBackgroundColor = basegfx::BColor(0.874,0.949,0.749);
        rForegroundColor = basegfx::BColor(0.31,0.541,0.063);
        rMessageColor = basegfx::BColor(0.31,0.541,0.063);
        break;
    case InfoBarType::Warning: // orange; #9F6000/159,96,0; #FEEFB3/254,239,179
        rBackgroundColor = basegfx::BColor(0.996,0.937,0.702);
        rForegroundColor = basegfx::BColor(0.623,0.376,0.0);
        rMessageColor = basegfx::BColor(0.623,0.376,0.0);
        break;
    case InfoBarType::Danger: // red; #D8000C/216,0,12; #FFBABA/255,186,186
        rBackgroundColor = basegfx::BColor(1.0,0.729,0.729);
        rForegroundColor = basegfx::BColor(0.847,0.0,0.047);
        rMessageColor = basegfx::BColor(0.847,0.0,0.047);
        break;
    }//switch

    //remove this?
    const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
    if (rSettings.GetHighContrastMode())
    {
        rLightColor = rSettings.GetLightColor().getBColor();
        rDarkColor = rSettings.GetDialogTextColor().getBColor();
        rBackgroundColor = rSettings.GetLightColor().getBColor();
        rForegroundColor = rSettings.GetDialogTextColor().getBColor();
    }
    else

}
OUString GetInfoBarIconName(InfoBarType ibType)
{

    OUString aRet;

    switch (ibType)
    {
        rLightColor = constLightColor;
        rDarkColor = constDarkColor;
    }
    case InfoBarType::Info:
       aRet = "vcl/res/infobox.svg";
       break;
    case InfoBarType::Success:
        aRet = "cmd/lc_apply.svg";
        break;
    case InfoBarType::Warning:
        aRet = "vcl/res/warningbox.svg";
        break;
    case InfoBarType::Danger:
        aRet = "vcl/res/errorbox.svg";
        break;
    }//switch

    return aRet;
}

class SfxCloseButton : public PushButton
{
    basegfx::BColor m_aBackgroundColor;
    basegfx::BColor m_aForegroundColor;
    basegfx::BColor m_aMessageColor;

public:
    explicit SfxCloseButton(vcl::Window* pParent) : PushButton(pParent, 0)
    {
        lclDetermineLightDarkColor(m_aBackgroundColor, m_aForegroundColor);
        GetInfoBarColors(InfoBarType::Warning,m_aBackgroundColor,m_aForegroundColor,m_aMessageColor);
    }

    virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) override;
@@ -79,7 +121,7 @@ void SfxCloseButton::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)

    drawinglayer::primitive2d::Primitive2DContainer aSeq(2);

    // Light background
    //  background
    B2DPolygon aPolygon;
    aPolygon.append(B2DPoint(aRect.Left(), aRect.Top()));
    aPolygon.append(B2DPoint(aRect.Right(), aRect.Top()));
@@ -128,34 +170,31 @@ void SfxCloseButton::setForegroundColor(const basegfx::BColor& rColor)

SfxInfoBarWindow::SfxInfoBarWindow(vcl::Window* pParent, const OUString& sId,
       const OUString& sMessage,
       const basegfx::BColor* pBackgroundColor,
       const basegfx::BColor* pForegroundColor,
       const basegfx::BColor* pMessageColor,
       WinBits nMessageStyle ) :
       InfoBarType ibType,
       WinBits nMessageStyle = WB_LEFT|WB_VCENTER) :
    Window(pParent, 0),
    m_sId(sId),
    m_pImage(VclPtr<FixedImage>::Create(this, nMessageStyle)),
    m_pMessage(VclPtr<FixedText>::Create(this, nMessageStyle)),
    m_pCloseBtn(VclPtr<SfxCloseButton>::Create(this)),
    m_aActionBtns()
{
    lclDetermineLightDarkColor(m_aBackgroundColor, m_aForegroundColor);
    if (pBackgroundColor)
    {
        m_aBackgroundColor = *pBackgroundColor;
        static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setBackgroundColor(m_aBackgroundColor);
    }
    if (pForegroundColor)
    {
        m_aForegroundColor = *pForegroundColor;
        static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setForegroundColor(m_aForegroundColor);
    }
    if (pMessageColor)
        m_pMessage->SetControlForeground(Color(*pMessageColor));
    basegfx::BColor aBackgroundColor;
    basegfx::BColor aForegroundColor;
    basegfx::BColor aMessageColor;
    GetInfoBarColors(ibType,aBackgroundColor,aForegroundColor,aMessageColor);
    static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setBackgroundColor(aBackgroundColor);
    static_cast<SfxCloseButton*>(m_pCloseBtn.get())->setForegroundColor(aForegroundColor);
    m_pMessage->SetControlForeground(Color(aMessageColor));

    float fScaleFactor = GetDPIScaleFactor();
    long nWidth = pParent->GetSizePixel().getWidth();
    SetPosSizePixel(Point(0, 0), Size(nWidth, INFO_BAR_BASE_HEIGHT * fScaleFactor));

    m_pImage->SetImage(Image(BitmapEx(GetInfoBarIconName(ibType))));
    m_pImage->SetPaintTransparent(true);
    m_pImage->Show();

    m_pMessage->SetText(sMessage);
    m_pMessage->Show();

@@ -184,6 +223,7 @@ void SfxInfoBarWindow::dispose()
    for ( auto it = m_aActionBtns.begin( ); it != m_aActionBtns.end( ); ++it )
        it->disposeAndClear();

    m_pImage.disposeAndClear();
    m_pMessage.disposeAndClear();
    m_pCloseBtn.disposeAndClear();
    m_aActionBtns.clear( );
@@ -248,10 +288,13 @@ void SfxInfoBarWindow::Resize()
        nX -= nButtonGap;
    }

    Point aMessagePosition(10 * fScaleFactor, 10 * fScaleFactor);
    m_pImage->SetPosSizePixel(Point(4,4), Size(32, 32));

    Point aMessagePosition(32 + 10 * fScaleFactor, 10 * fScaleFactor);
    Size aMessageSize(nX - 20 * fScaleFactor, 20 * fScaleFactor);

    m_pMessage->SetPosSizePixel(aMessagePosition, aMessageSize);

}

IMPL_LINK_NOARG(SfxInfoBarWindow, CloseHandler, Button*, void)
@@ -281,47 +324,20 @@ void SfxInfoBarContainerWindow::dispose()

VclPtr<SfxInfoBarWindow> SfxInfoBarContainerWindow::appendInfoBar(const OUString& sId,
                                                           const OUString& sMessage,
                                                           InfoBarType aInfoBarType,
                                                           WinBits nMessageStyle)
{
    basegfx::BColor pBackgroundColor;
    basegfx::BColor pForegroundColor;
    basegfx::BColor pMessageColor;
    switch (aInfoBarType)
    {
    case InfoBarType::Info: // yellow
        pBackgroundColor = constLightColor;
        // Use defaults for foreground & message color
        break;
    case InfoBarType::Success: // green
        pBackgroundColor = basegfx::BColor(0.0, 0.5, 0.0);
        pForegroundColor = basegfx::BColor(1.0, 1.0, 1.0);
        pMessageColor = basegfx::BColor(1.0, 1.0, 01.0);
        break;
    case InfoBarType::Warning: // orange
        pBackgroundColor = basegfx::BColor(1.0, 0.5, 0.0);
        pForegroundColor = basegfx::BColor(1.0, 1.0, 1.0);
        pMessageColor = basegfx::BColor(1.0, 1.0, 01.0);
        break;
    case InfoBarType::Danger: // red
        pBackgroundColor = basegfx::BColor(0.5, 0.0, 0.0);
        pForegroundColor = basegfx::BColor(1.0, 1.0, 1.0);
        pMessageColor = basegfx::BColor(1.0, 1.0, 01.0);
        break;
    }
    return appendInfoBar(sId, sMessage, &pBackgroundColor, &pForegroundColor, &pMessageColor, nMessageStyle);
}

VclPtr<SfxInfoBarWindow> SfxInfoBarContainerWindow::appendInfoBar(const OUString& sId,
                                                           const OUString& sMessage,
                                                           const basegfx::BColor* pBackgroundColor,
                                                           const basegfx::BColor* pForegroundColor,
                                                           const basegfx::BColor* pMessageColor,
                                                           InfoBarType ibType,
                                                           WinBits nMessageStyle)
{
    Size aSize = GetSizePixel();

    VclPtrInstance<SfxInfoBarWindow> pInfoBar(this, sId, sMessage, pBackgroundColor, pForegroundColor, pMessageColor, nMessageStyle);
    VclPtrInstance<SfxInfoBarWindow> pInfoBar(this, sId, sMessage, ibType, nMessageStyle);

    basegfx::BColor aBackgroundColor;
    basegfx::BColor aForegroundColor;
    basegfx::BColor aMessageColor;
    GetInfoBarColors(ibType,aBackgroundColor,aForegroundColor,aMessageColor);
    pInfoBar->m_aBackgroundColor = aBackgroundColor;
    pInfoBar->m_aForegroundColor = aForegroundColor;

    pInfoBar->SetPosPixel(Point(0, aSize.getHeight()));
    pInfoBar->Show();
    m_pInfoBars.push_back(pInfoBar);
diff --git a/sfx2/source/view/classificationhelper.cxx b/sfx2/source/view/classificationhelper.cxx
index a63b804..769a0c6 100644
--- a/sfx2/source/view/classificationhelper.cxx
+++ b/sfx2/source/view/classificationhelper.cxx
@@ -588,9 +588,11 @@ bool SfxClassificationHelper::HasDocumentFooter()
    return true;
}

basegfx::BColor SfxClassificationHelper::GetImpactLevelColor()
InfoBarType SfxClassificationHelper::GetImpactLevelType()
{
    basegfx::BColor aRet;
    InfoBarType aRet;

    aRet = InfoBarType::Warning;

    auto itCategory = m_pImpl->m_aCategory.find(SfxClassificationPolicyType::IntellectualProperty);
    if (itCategory == m_pImpl->m_aCategory.end())
@@ -598,48 +600,36 @@ basegfx::BColor SfxClassificationHelper::GetImpactLevelColor()

    SfxClassificationCategory& rCategory = itCategory->second;
    auto it = rCategory.m_aLabels.find(PROP_PREFIX_INTELLECTUALPROPERTY() + PROP_IMPACTSCALE());
    OUString aScale = it->second;
    if (it == rCategory.m_aLabels.end())
        return aRet;
    OUString aScale = it->second;

    it = rCategory.m_aLabels.find(PROP_PREFIX_INTELLECTUALPROPERTY() + PROP_IMPACTLEVEL());
    OUString aLevel = it->second;
    if (it == rCategory.m_aLabels.end())
        return aRet;
    OUString aLevel = it->second;

    // The spec defines two valid scale values: FIPS-199 and UK-Cabinet.
    if (aScale == "UK-Cabinet")
    {
        static std::map<OUString, basegfx::BColor> aColors;
        if (aColors.empty())
        {
            // Green -> brown -> orange -> red.
            aColors["0"] = basegfx::BColor(0.0, 0.5, 0.0);
            aColors["1"] = basegfx::BColor(0.5, 0.5, 0.0);
            aColors["2"] = basegfx::BColor(1.0, 0.5, 0.0);
            aColors["3"] = basegfx::BColor(0.5, 0.0, 0.0);
        }
        auto itColor = aColors.find(aLevel);
        if (itColor == aColors.end())
            return aRet;
        aRet = itColor->second;
        if (aLevel == "0")
            aRet = InfoBarType::Success;
        else if (aLevel == "1")
            aRet = InfoBarType::Warning;
        else if (aLevel == "2")
            aRet = InfoBarType::Warning;
        else if (aLevel == "3")
            aRet = InfoBarType::Danger;
    }
    else if (aScale == "FIPS-199")
    {
        static std::map<OUString, basegfx::BColor> aColors;
        if (aColors.empty())
        {
            // Green -> orange -> red.
            aColors["Low"] = basegfx::BColor(0.0, 0.5, 0.0);
            aColors["Moderate"] = basegfx::BColor(1.0, 0.5, 0.0);
            aColors["High"] = basegfx::BColor(0.5, 0.0, 0.0);
        }
        auto itColor = aColors.find(aLevel);
        if (itColor == aColors.end())
            return aRet;
        aRet = itColor->second;
        if (aLevel == "Low")
            aRet = InfoBarType::Success;
        else if (aLevel == "Moderate")
            aRet = InfoBarType::Warning;
        else if (aLevel == "High")
            aRet = InfoBarType::Danger;
    }

    return aRet;
}

@@ -766,11 +756,9 @@ void SfxClassificationHelper::UpdateInfobar(SfxViewFrame& rViewFrame)
    {
        OUString aMessage = SfxResId(STR_CLASSIFIED_DOCUMENT);
        aMessage = aMessage.replaceFirst("%1", aBACName);
        basegfx::BColor aBackgroundColor = GetImpactLevelColor();
        basegfx::BColor aForegroundColor(1.0, 1.0, 1.0);

        rViewFrame.RemoveInfoBar("classification");
        rViewFrame.AppendInfoBar("classification", aMessage, &aBackgroundColor, &aForegroundColor, &aForegroundColor, WB_CENTER);
        rViewFrame.AppendInfoBar("classification", aMessage, GetImpactLevelType());
    }
}

diff --git a/sfx2/source/view/sfxbasecontroller.cxx b/sfx2/source/view/sfxbasecontroller.cxx
index 8c273a7..d2d06e7 100644
--- a/sfx2/source/view/sfxbasecontroller.cxx
+++ b/sfx2/source/view/sfxbasecontroller.cxx
@@ -1440,7 +1440,7 @@ void SfxBaseController::ShowInfoBars( )
                {
                    // Get the Frame and show the InfoBar if not checked out
                    SfxViewFrame* pViewFrame = m_pData->m_pViewShell->GetFrame();
                    auto pInfoBar = pViewFrame->AppendInfoBar( "checkout", SfxResId( STR_NONCHECKEDOUT_DOCUMENT ) );
                    auto pInfoBar = pViewFrame->AppendInfoBar( "checkout", SfxResId( STR_NONCHECKEDOUT_DOCUMENT ), InfoBarType::Warning);
                    if (pInfoBar)
                    {
                        VclPtrInstance<PushButton> xBtn(&pViewFrame->GetWindow());
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index e79c38b..5848f6b 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -1219,7 +1219,7 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
                {
                    bool bSignPDF = IsSignPDF(m_xObjSh);

                    auto pInfoBar = AppendInfoBar("readonly", SfxResId(bSignPDF ? STR_READONLY_PDF : STR_READONLY_DOCUMENT));
                    auto pInfoBar = AppendInfoBar("readonly", SfxResId(bSignPDF ? STR_READONLY_PDF : STR_READONLY_DOCUMENT), InfoBarType::Info);
                    if (pInfoBar)
                    {
                        if (bSignPDF)
@@ -3097,23 +3097,6 @@ VclPtr<SfxInfoBarWindow> SfxViewFrame::AppendInfoBar(const OUString& sId,
    return pInfoBar;
}

VclPtr<SfxInfoBarWindow> SfxViewFrame::AppendInfoBar( const OUString& sId,
                                               const OUString& sMessage,
                                               const basegfx::BColor* pBackgroundColor,
                                               const basegfx::BColor* pForegroundColor,
                                               const basegfx::BColor* pMessageColor,
                                               WinBits nMessageStyle )
{
    SfxChildWindow* pChild = GetChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
    if (!pChild)
        return nullptr;

    SfxInfoBarContainerWindow* pInfoBarContainer = static_cast<SfxInfoBarContainerWindow*>(pChild->GetWindow());
    auto pInfoBar = pInfoBarContainer->appendInfoBar(sId, sMessage, pBackgroundColor, pForegroundColor, pMessageColor, nMessageStyle);
    ShowChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
    return pInfoBar;
}

void SfxViewFrame::RemoveInfoBar( const OUString& sId )
{
    const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId();