Add Calc view separation for tiled rendering

Calc now uses different colors based on the current view theme to paint
tiles when using tiled rendering

Change-Id: I1ca84371141ff026ad49ec362518ca13c59c7c6e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152137
Tested-by: Paris Oplopoios <parisoplop@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit f4eb56b8b9ff3492e0a02fb76eb4ea7b851f4774)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152440
Tested-by: Jenkins
Reviewed-by: Paris Oplopoios <parisoplop@gmail.com>
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index cc03a13..f6c9030 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -719,6 +719,7 @@ void EditView::MoveParagraphs( tools::Long nDiff )
void EditView::SetBackgroundColor( const Color& rColor )
{
    pImpEditView->SetBackgroundColor( rColor );
    pImpEditView->pEditEngine->SetBackgroundColor( rColor );
}

Color const & EditView::GetBackgroundColor() const
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index 837f93e..23de1da 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -394,6 +394,9 @@ public:

    /// @see vcl::ITiledRenderable::completeFunction().
    virtual void completeFunction(const OUString& rFunctionName) override;

    /// @see vcl::ITiledRenderable::getViewRenderState().
    OString getViewRenderState() override;
};

class ScDrawPagesObj final : public cppu::WeakImplHelper<
diff --git a/sc/inc/viewopti.hxx b/sc/inc/viewopti.hxx
index 52b23c86..489a3e8 100644
--- a/sc/inc/viewopti.hxx
+++ b/sc/inc/viewopti.hxx
@@ -95,6 +95,12 @@ public:
    void                    SetGridOptions( const ScGridOptions& rNew ) { aGridOpt = rNew; }
    std::unique_ptr<SvxGridItem> CreateGridItem() const;

    const OUString& GetColorSchemeName() const { return sColorSchemeName; }
    void SetColorSchemeName( const OUString& rName ) { sColorSchemeName = rName; }

    const Color& GetDocColor() const { return aDocCol; }
    void SetDocColor(const Color& rDocColor) { aDocCol = rDocColor; }

    ScViewOptions&          operator=  ( const ScViewOptions& rCpy );
    bool                    operator== ( const ScViewOptions& rOpt ) const;
    bool                    operator!= ( const ScViewOptions& rOpt ) const { return !(operator==(rOpt)); }
@@ -105,6 +111,10 @@ private:
    Color           aGridCol;
    OUString        aGridColName;
    ScGridOptions   aGridOpt;
    // The name of the color scheme
    OUString sColorSchemeName = "Default";
    // The background color of the document
    Color aDocCol;
};

// Item for the options dialog - View
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 5968cfc..6eb2aa1 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -3056,6 +3056,37 @@ CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testUndoReorderingMulti)
    CPPUNIT_ASSERT_EQUAL(OUString("DD"), pDoc->GetString(ScAddress(0, 3, 0)));
}

CPPUNIT_TEST_FIXTURE(ScTiledRenderingTest, testGetViewRenderState)
{
    // Add an empty dark scheme to avoid a warning
    svtools::EditableColorConfig aColorConfig;
    aColorConfig.AddScheme(u"Dark");

    ScModelObj* pModelObj = createDoc("empty.ods");
    int nFirstViewId = SfxLokHelper::getView();
    ViewCallback aView1;

    CPPUNIT_ASSERT_EQUAL(OString(";Default"), pModelObj->getViewRenderState());
    // Create a second view
    SfxLokHelper::createView();
    ViewCallback aView2;
    CPPUNIT_ASSERT_EQUAL(OString(";Default"), pModelObj->getViewRenderState());
    // Set second view to dark scheme
    {
        uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence(
            {
                { "NewTheme", uno::Any(OUString("Dark")) },
            }
        );
        dispatchCommand(mxComponent, ".uno:ChangeTheme", aPropertyValues);
    }
    CPPUNIT_ASSERT_EQUAL(OString(";Dark"), pModelObj->getViewRenderState());

    // Switch back to first view and make sure it's the same
    SfxLokHelper::setView(nFirstViewId);
    CPPUNIT_ASSERT_EQUAL(OString(";Default"), pModelObj->getViewRenderState());
}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index 4368057..532831f 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -65,6 +65,8 @@
#include <scmod.hxx>
#include <fillinfo.hxx>
#include <boost/functional/hash.hpp>
#include <comphelper/lok.hxx>
#include <tabvwsh.hxx>

ScPatternAttr::ScPatternAttr( SfxItemSet&& pItemSet, const OUString& rStyleName )
    :   SfxSetItem  ( ATTR_PATTERN, std::move(pItemSet) ),
@@ -436,15 +438,30 @@ void ScPatternAttr::GetFont(
            if ( aBackColor == COL_TRANSPARENT ||
                    eAutoMode == SC_AUTOCOL_IGNOREBACK || eAutoMode == SC_AUTOCOL_IGNOREALL )
            {
                if ( eAutoMode == SC_AUTOCOL_PRINT )
                    aBackColor = COL_WHITE;
                else if ( pBackConfigColor )
                if (!comphelper::LibreOfficeKit::isActive())
                {
                    // pBackConfigColor can be used to avoid repeated lookup of the configured color
                    aBackColor = *pBackConfigColor;
                    if ( eAutoMode == SC_AUTOCOL_PRINT )
                        aBackColor = COL_WHITE;
                    else if ( pBackConfigColor )
                    {
                        // pBackConfigColor can be used to avoid repeated lookup of the configured color
                        aBackColor = *pBackConfigColor;
                    }
                    else
                        aBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
                }
                else
                    aBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
                {
                    // Get document color from current view instead
                    SfxViewShell* pSfxViewShell = SfxViewShell::Current();
                    ScTabViewShell* pViewShell = dynamic_cast<ScTabViewShell*>(pSfxViewShell);
                    if (pViewShell)
                    {
                        const ScViewData& pViewData = pViewShell->GetViewData();
                        const ScViewOptions& aViewOptions = pViewData.GetOptions();
                        aBackColor = aViewOptions.GetDocColor();
                    }
                }
            }

            //  get system text color for comparison
diff --git a/sc/source/core/tool/viewopti.cxx b/sc/source/core/tool/viewopti.cxx
index ad09d7e..80d8915 100644
--- a/sc/source/core/tool/viewopti.cxx
+++ b/sc/source/core/tool/viewopti.cxx
@@ -27,6 +27,7 @@
#include <global.hxx>
#include <viewopti.hxx>
#include <sc.hrc>
#include <scmod.hxx>
#include <miscuno.hxx>

using namespace utl;
@@ -114,6 +115,8 @@ void ScViewOptions::SetDefaults()

    aGridCol = svtools::ColorConfig().GetColorValue( svtools::CALCGRID ).nColor;

    aDocCol = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;

    aGridOpt.SetDefaults();
}

@@ -138,6 +141,7 @@ bool ScViewOptions::operator==( const ScViewOptions& rOpt ) const
    bEqual = bEqual && (aGridCol       == rOpt.aGridCol);
    bEqual = bEqual && (aGridColName   == rOpt.aGridColName);
    bEqual = bEqual && (aGridOpt       == rOpt.aGridOpt);
    bEqual = bEqual && (aDocCol        == rOpt.aDocCol);

    return bEqual;
}
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index c405532..544d8b8 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -94,6 +94,8 @@
#include <scabstdlg.hxx>
#include <formula/errorcodes.hxx>
#include <documentlinkmgr.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokhelper.hxx>

#define SC_IDLE_MIN     150
#define SC_IDLE_MAX     3000
@@ -151,6 +153,9 @@ ScModule::ScModule( SfxObjectFactory* pFact ) :
    ScGlobal::InitTextHeight( m_pMessagePool.get() );

    StartListening( *SfxGetpApp() );       // for SfxHintId::Deinitializing

    // Initialize the color config
    GetColorConfig();
}

ScModule::~ScModule()
@@ -203,6 +208,28 @@ void ScModule::ConfigurationChanged( utl::ConfigurationBroadcaster* p, Configura
            }
        }

        if (comphelper::LibreOfficeKit::isActive() && m_pColorConfig)
        {
            SfxViewShell* pSfxViewShell = SfxViewShell::Current();
            ScTabViewShell* pViewShell = dynamic_cast<ScTabViewShell*>(pSfxViewShell);

            if (pViewShell)
            {
                ScViewData& pViewData = pViewShell->GetViewData();
                ScViewOptions aViewOptions = pViewData.GetOptions();
                Color aFillColor(m_pColorConfig->GetColorValue(svtools::DOCCOLOR).nColor);
                aViewOptions.SetDocColor(aFillColor);
                aViewOptions.SetColorSchemeName(m_pColorConfig->GetCurrentSchemeName());
                pViewData.SetOptions(aViewOptions);
                ScModelObj* pScModelObj = comphelper::getFromUnoTunnel<ScModelObj>(SfxObjectShell::Current()->GetModel());
                SfxLokHelper::notifyViewRenderState(SfxViewShell::Current(), pScModelObj);
                // In Online, the document color is the one used for the background, contrary to
                // Writer and Draw that use the application background color.
                pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR,
                        aFillColor.AsRGBHexString().toUtf8());
            }
        }

        // force all views to repaint, using the new options
        SfxViewShell* pViewShell = SfxViewShell::GetFirst();
        while(pViewShell)
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 563c843..3473c08 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -1239,6 +1239,23 @@ void ScModelObj::completeFunction(const OUString& rFunctionName)
    }
}

OString ScModelObj::getViewRenderState()
{
    OStringBuffer aState;
    ScViewData* pViewData = ScDocShell::GetViewData();

    if (pViewData)
    {
        aState.append(';');

        const ScViewOptions& aViewOptions = pViewData->GetOptions();
        OString aThemeName = OUStringToOString(aViewOptions.GetColorSchemeName(), RTL_TEXTENCODING_UTF8);
        aState.append(aThemeName);
    }

    return aState.makeStringAndClear();
}

void ScModelObj::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
{
    SolarMutexGuard aGuard;
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 16d37447..80217c8 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -25,6 +25,7 @@
#include <editeng/colritem.hxx>
#include <editeng/editview.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/brushitem.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/printer.hxx>
#include <vcl/cursor.hxx>
@@ -1122,7 +1123,21 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
                            tools::Long nScreenY = aOutputData.nScrY;

                            rDevice.SetLineColor();
                            rDevice.SetFillColor(pOtherEditView->GetBackgroundColor());
                            SfxViewShell* pSfxViewShell = SfxViewShell::Current();
                            ScTabViewShell* pCurrentViewShell = dynamic_cast<ScTabViewShell*>(pSfxViewShell);
                            if (pCurrentViewShell)
                            {
                                const ScViewData& pViewData = pCurrentViewShell->GetViewData();
                                const ScViewOptions& aViewOptions = pViewData.GetOptions();
                                const ScPatternAttr* pPattern = rDoc.GetPattern( nCol1, nRow1, nTab );
                                Color aCellColor = pPattern->GetItem(ATTR_BACKGROUND).GetColor();
                                if (aCellColor.IsTransparent())
                                {
                                    aCellColor = aViewOptions.GetDocColor();
                                }
                                rDevice.SetFillColor(aCellColor);
                                pOtherEditView->SetBackgroundColor(aCellColor);
                            }
                            Point aStart = mrViewData.GetScrPos( nCol1, nRow1, eOtherWhich );
                            Point aEnd = mrViewData.GetScrPos( nCol2+1, nRow2+1, eOtherWhich );