sd theme: allow setting the color's theme index in the chardlg

This routes not only the rgb color and a name, but also a theme index
from the color picker to the chardlg (only there as a start).

That way the picked color will be updated if the master page theme
changes.

Change-Id: I7a45d7cf63c7c36013e4656c66d9b2dbc3aa0b88
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127135
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna
2021-12-20 08:46:40 +01:00
parent 24ea26f55e
commit 7d5984d7ae
14 changed files with 183 additions and 50 deletions

View File

@@ -85,7 +85,7 @@ ChartColorWrapper::ChartColorWrapper(
{
}
void ChartColorWrapper::operator()([[maybe_unused]] const OUString& , const NamedColor& rColor)
void ChartColorWrapper::operator()([[maybe_unused]] const OUString& , const svx::NamedThemedColor& rColor)
{
css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
@@ -95,7 +95,7 @@ void ChartColorWrapper::operator()([[maybe_unused]] const OUString& , const Name
return;
}
xPropSet->setPropertyValue(maPropertyName, css::uno::makeAny(rColor.first));
xPropSet->setPropertyValue(maPropertyName, css::uno::makeAny(rColor.m_aColor));
}
void ChartColorWrapper::updateModel(const css::uno::Reference<css::frame::XModel>& xModel)

View File

@@ -26,7 +26,7 @@ public:
SvxColorToolBoxControl* pControl,
const OUString& rPropertyName);
void operator()(const OUString& rCommand, const NamedColor& rColor);
void operator()(const OUString& rCommand, const svx::NamedThemedColor& rColor);
// ColorSelectFunction signature
void updateModel(const css::uno::Reference<css::frame::XModel>& xModel);

View File

@@ -8,6 +8,7 @@ from libreoffice.uno.propertyvalue import mkPropertyValues
from uitest.framework import UITestCase
from uitest.uihelper.common import select_pos
from uitest.uihelper.common import get_state_as_dict
from uitest.uihelper.common import select_by_text
# Test for cui/source/tabpages/chardlg.cxx.
class Test(UITestCase):
@@ -43,6 +44,71 @@ class Test(UITestCase):
# COL_AUTO.
self.assertEqual(shape.CharTransparence, 5)
def testSvxCharEffectsPageTheme(self):
# Given a document with a document theme:
# Start Impress.
with self.ui_test.create_doc_in_start_center("impress") as component:
template = self.xUITest.getTopFocusWindow()
self.ui_test.close_dialog_through_button(template.getChild("close"))
doc = self.xUITest.getTopFocusWindow()
editWin = doc.getChild("impress_win")
# Set theme colors.
drawPage = component.getDrawPages().getByIndex(0)
master = drawPage.MasterPage
theme = mkPropertyValues({
"Name": "nameA",
"ColorSchemeName": "colorSetA",
"ColorScheme": tuple([
0x000000, # dk1
0x000000, # lt1
0x000000, # dk2
0x000000, # lt2
0x000000, # accent1
0x000000, # accent2
0x000000, # accent3
0x000000, # accent4
0x000000, # accent5
0x000000, # accent6
0x000000, # hlink
0x000000, # folHlink
])
})
master.Theme = theme
# Select the title shape.
editWin.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"}))
editWin.executeAction("TYPE", mkPropertyValues({"TEXT": "t"}))
self.xUITest.executeCommand(".uno:SelectAll")
# Now use Format -> Character.
with self.ui_test.execute_dialog_through_command(".uno:FontDialog") as xDialog:
xTabs = xDialog.getChild("tabcontrol")
# Select RID_SVXPAGE_CHAR_EFFECTS.
select_pos(xTabs, "1")
# When setting the shape text color to accent 1:
accent1 = xDialog.getChild("fontcolorlb")
accent1.executeAction("OPENLIST", tuple())
floatWindow = self.xUITest.getFloatWindow()
paletteSelector = floatWindow.getChild("palette_listbox")
select_by_text(paletteSelector, "Theme colors")
colorSet = floatWindow.getChild("colorset")
colorSet.executeAction("CHOOSE", mkPropertyValues({"POS": "4"}))
# Then make sure the doc model has the correct color theme index:
drawPage = component.getDrawPages().getByIndex(0)
shape = drawPage.getByIndex(0)
paragraphs = shape.createEnumeration()
paragraph = paragraphs.nextElement()
portions = paragraph.createEnumeration()
portion = portions.nextElement()
# Without the accompanying fix in place, this test would have failed with:
# AssertionError: -1 != 4
# i.e. no theme index was set, instead of accent1 (index into the above color scheme).
self.assertEqual(portion.CharColorTheme, 4)
def testSvxCharEffectsPageWriter(self):
# Start Writer.
with self.ui_test.create_doc_in_start_center("writer") as component:

View File

@@ -1573,28 +1573,38 @@ bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
const SfxItemSet& rOldSet = GetItemSet();
Color aSelectedColor;
svx::NamedThemedColor aSelectedColor;
bool bChanged = m_bNewFontColor;
if (bChanged)
{
aSelectedColor = m_xFontColorLB->GetSelectEntryColor();
aSelectedColor = m_xFontColorLB->GetSelectedEntryThemedColor();
if (m_xFontTransparencyMtr->get_value_changed_from_saved())
{
double fTransparency
= m_xFontTransparencyMtr->get_value(FieldUnit::PERCENT) * 255.0 / 100;
aSelectedColor.SetAlpha(255 - static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
aSelectedColor.m_aColor.SetAlpha(255 - static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
}
if (m_bOrigFontColor)
bChanged = aSelectedColor != m_aOrigFontColor;
if (m_bEnableNoneFontColor && bChanged && aSelectedColor == COL_NONE_COLOR)
bChanged = aSelectedColor.m_aColor != m_aOrigFontColor;
if (m_bEnableNoneFontColor && bChanged && aSelectedColor.m_aColor == COL_NONE_COLOR)
bChanged = false;
}
if (bChanged)
rSet.Put( SvxColorItem( aSelectedColor, nWhich ) );
{
SvxColorItem aItem( aSelectedColor.m_aColor, nWhich );
if (aSelectedColor.m_nThemeIndex != -1)
{
// The color was picked from the theme palette, remember its index.
aItem.SetThemeIndex(aSelectedColor.m_nThemeIndex);
}
rSet.Put(aItem);
}
else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
rSet.InvalidateItem(nWhich);

View File

@@ -73,7 +73,19 @@ void SvxThemePage::Reset(const SfxItemSet* pAttrs)
auto itTheme = rGrabBagItem.GetGrabBag().find("Theme");
if (itTheme == rGrabBagItem.GetGrabBag().end())
{
SAL_WARN("cui.tabpages", "SvxThemePage::Reset: no Theme");
// No theme was defined previously, allow specifying colors.
m_xDk1->set_sensitive(true);
m_xLt1->set_sensitive(true);
m_xDk2->set_sensitive(true);
m_xLt2->set_sensitive(true);
m_xAccent1->set_sensitive(true);
m_xAccent2->set_sensitive(true);
m_xAccent3->set_sensitive(true);
m_xAccent4->set_sensitive(true);
m_xAccent5->set_sensitive(true);
m_xAccent6->set_sensitive(true);
m_xHlink->set_sensitive(true);
m_xFolHlink->set_sensitive(true);
return;
}

View File

@@ -24,13 +24,29 @@
#include <functional>
#include <rtl/ustring.hxx>
#include <tools/color.hxx>
#include <svx/svxdllapi.h>
class Color;
class SvxColorValueSet;
typedef std::pair<Color, OUString> NamedColor;
typedef std::function<void(const OUString&, const NamedColor&)> ColorSelectFunction;
namespace svx
{
/// A color with an optional name and other theming-related properties.
struct SVXCORE_DLLPUBLIC NamedThemedColor
{
Color m_aColor;
OUString m_aName;
sal_Int16 m_nThemeIndex = -1;
static NamedThemedColor FromNamedColor(const NamedColor& rNamedColor);
NamedColor ToNamedColor() const;
};
}
typedef std::function<void(const OUString&, const svx::NamedThemedColor&)> ColorSelectFunction;
class Palette
{

View File

@@ -74,7 +74,9 @@ public:
void SetColorSelectFunction(const ColorSelectFunction& aColorSelectFunction);
static void DispatchColorCommand(const OUString& aCommand, const NamedColor& rColor);
bool IsThemePaletteSelected() const;
static void DispatchColorCommand(const OUString& aCommand, const svx::NamedThemedColor& rColor);
};
#endif // INCLUDED_SVX_PALETTEMANAGER_HXX

View File

@@ -21,7 +21,7 @@ class ListBoxColorWrapper
public:
ListBoxColorWrapper(ColorListBox* pControl);
void operator()(const OUString& rCommand,
const NamedColor& rColor); // ColorSelectFunction signature
const svx::NamedThemedColor& rColor); // ColorSelectFunction signature
private:
ColorListBox* mpControl;
};
@@ -36,14 +36,14 @@ private:
ListBoxColorWrapper m_aColorWrapper;
Color m_aAutoDisplayColor;
Color m_aSaveColor;
NamedColor m_aSelectedColor;
svx::NamedThemedColor m_aSelectedColor;
sal_uInt16 m_nSlotId;
bool m_bShowNoneButton;
std::shared_ptr<PaletteManager> m_xPaletteManager;
TopLevelParentFunction m_aTopLevelParentFunction;
ColorStatus m_aColorStatus;
void Selected(const NamedColor& rNamedColor);
void Selected(const svx::NamedThemedColor& rNamedColor);
void createColorWindow();
void LockWidthRequest();
ColorWindow* getColorWindow() const;
@@ -60,8 +60,9 @@ public:
void SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton = false);
Color const& GetSelectEntryColor() const { return m_aSelectedColor.first; }
NamedColor const& GetSelectedEntry() const { return m_aSelectedColor; }
Color const& GetSelectEntryColor() const { return m_aSelectedColor.m_aColor; }
NamedColor GetSelectedEntry() const { return m_aSelectedColor.ToNamedColor(); }
svx::NamedThemedColor GetSelectedEntryThemedColor() const { return m_aSelectedColor; }
void SelectEntry(const NamedColor& rColor);
void SelectEntry(const Color& rColor);

View File

@@ -200,7 +200,7 @@ friend class SfxStyleControllerItem_Impl;
SfxStyleFamily GetActFamily() const;
};
typedef std::function<void(const OUString&, const NamedColor&)> ColorSelectFunction;
typedef std::function<void(const OUString&, const svx::NamedThemedColor&)> ColorSelectFunction;
class SVXCORE_DLLPUBLIC SvxColorToolBoxControl final : public cppu::ImplInheritanceHelper< svt::PopupWindowController,
css::frame::XSubToolbarController >

View File

@@ -74,9 +74,9 @@ ConditionColorWrapper::ConditionColorWrapper(Condition* pControl, sal_uInt16 nSl
}
void ConditionColorWrapper::operator()(
[[maybe_unused]] const OUString& /*rCommand*/, const NamedColor& rNamedColor)
[[maybe_unused]] const OUString& /*rCommand*/, const svx::NamedThemedColor& rNamedColor)
{
mpControl->ApplyCommand(mnSlotId, rNamedColor);
mpControl->ApplyCommand(mnSlotId, rNamedColor.ToNamedColor());
}
// = Condition

View File

@@ -58,7 +58,7 @@ namespace rptui
{
public:
ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId);
void operator()(const OUString& rCommand, const NamedColor& rColor);
void operator()(const OUString& rCommand, const svx::NamedThemedColor& rColor);
// ColorSelectFunction signature
private:
Condition* mpControl;

View File

@@ -361,4 +361,17 @@ bool PaletteSOC::IsValid()
return true;
}
namespace svx
{
NamedColor NamedThemedColor::ToNamedColor() const { return { m_aColor, m_aName }; }
NamedThemedColor NamedThemedColor::FromNamedColor(const NamedColor& rNamedColor)
{
NamedThemedColor aColor;
aColor.m_aColor = rNamedColor.first;
aColor.m_aName = rNamedColor.second;
return aColor;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -126,6 +126,11 @@ void PaletteManager::LoadPalettes()
}
}
bool PaletteManager::IsThemePaletteSelected() const
{
return mnCurrentPalette == mnNumOfPalettes - 2;
}
void PaletteManager::ReloadColorSet(SvxColorValueSet &rColorSet)
{
if( mnCurrentPalette == 0)
@@ -141,7 +146,7 @@ void PaletteManager::ReloadColorSet(SvxColorValueSet &rColorSet)
++nIx;
}
}
else if (mnCurrentPalette == mnNumOfPalettes - 2)
else if (IsThemePaletteSelected())
{
SfxObjectShell* pObjectShell = SfxObjectShell::Current();
if (pObjectShell)
@@ -149,17 +154,20 @@ void PaletteManager::ReloadColorSet(SvxColorValueSet &rColorSet)
std::vector<Color> aColors = pObjectShell->GetThemeColors();
mnColorCount = aColors.size();
rColorSet.Clear();
std::vector<OUString> aNames = {
SvxResId(RID_SVXSTR_THEME_COLOR1), SvxResId(RID_SVXSTR_THEME_COLOR2),
SvxResId(RID_SVXSTR_THEME_COLOR3), SvxResId(RID_SVXSTR_THEME_COLOR4),
SvxResId(RID_SVXSTR_THEME_COLOR5), SvxResId(RID_SVXSTR_THEME_COLOR6),
SvxResId(RID_SVXSTR_THEME_COLOR7), SvxResId(RID_SVXSTR_THEME_COLOR8),
SvxResId(RID_SVXSTR_THEME_COLOR9), SvxResId(RID_SVXSTR_THEME_COLOR10),
SvxResId(RID_SVXSTR_THEME_COLOR11), SvxResId(RID_SVXSTR_THEME_COLOR12),
};
for (int i = 0; i < 12; ++i)
if (aColors.size() >= 12)
{
rColorSet.InsertItem(i, aColors[i], aNames[i]);
std::vector<OUString> aNames = {
SvxResId(RID_SVXSTR_THEME_COLOR1), SvxResId(RID_SVXSTR_THEME_COLOR2),
SvxResId(RID_SVXSTR_THEME_COLOR3), SvxResId(RID_SVXSTR_THEME_COLOR4),
SvxResId(RID_SVXSTR_THEME_COLOR5), SvxResId(RID_SVXSTR_THEME_COLOR6),
SvxResId(RID_SVXSTR_THEME_COLOR7), SvxResId(RID_SVXSTR_THEME_COLOR8),
SvxResId(RID_SVXSTR_THEME_COLOR9), SvxResId(RID_SVXSTR_THEME_COLOR10),
SvxResId(RID_SVXSTR_THEME_COLOR11), SvxResId(RID_SVXSTR_THEME_COLOR12),
};
for (int i = 0; i < 12; ++i)
{
rColorSet.InsertItem(i, aColors[i], aNames[i]);
}
}
}
}
@@ -340,12 +348,12 @@ void PaletteManager::PopupColorPicker(weld::Window* pParent, const OUString& aCo
if (mpBtnUpdater)
mpBtnUpdater->Update(aNamedColor);
AddRecentColor(aLastColor, sColorName);
maColorSelectFunction(aCommandCopy, aNamedColor);
maColorSelectFunction(aCommandCopy, svx::NamedThemedColor::FromNamedColor(aNamedColor));
}
});
}
void PaletteManager::DispatchColorCommand(const OUString& aCommand, const NamedColor& rColor)
void PaletteManager::DispatchColorCommand(const OUString& aCommand, const svx::NamedThemedColor& rColor)
{
using namespace css::uno;
using namespace css::frame;
@@ -362,7 +370,7 @@ void PaletteManager::DispatchColorCommand(const OUString& aCommand, const NamedC
INetURLObject aObj( aCommand );
Sequence<PropertyValue> aArgs{ comphelper::makePropertyValue(aObj.GetURLPath(),
sal_Int32(rColor.first)) };
sal_Int32(rColor.m_aColor)) };
URL aTargetURL;
aTargetURL.Complete = aCommand;

View File

@@ -1969,7 +1969,12 @@ IMPL_LINK(ColorWindow, SelectHdl, ValueSet*, pColorSet, void)
maMenuButton.set_inactive();
aColorSelectFunction(sCommand, aNamedColor);
auto aNamedThemedColor = svx::NamedThemedColor::FromNamedColor(aNamedColor);
if (mxPaletteManager->IsThemePaletteSelected())
{
aNamedThemedColor.m_nThemeIndex = pColorSet->GetSelectedItemId();
}
aColorSelectFunction(sCommand, aNamedThemedColor);
}
IMPL_LINK_NOARG(ColorWindow, SelectPaletteHdl, weld::ComboBox&, void)
@@ -2002,7 +2007,7 @@ IMPL_LINK(ColorWindow, AutoColorClickHdl, weld::Button&, rButton, void)
maMenuButton.set_inactive();
aColorSelectFunction(sCommand, aNamedColor);
aColorSelectFunction(sCommand, svx::NamedThemedColor::FromNamedColor(aNamedColor));
}
IMPL_LINK_NOARG(ColorWindow, OpenPickerClickHdl, weld::Button&, void)
@@ -3885,7 +3890,7 @@ ListBoxColorWrapper::ListBoxColorWrapper(ColorListBox* pControl)
}
void ListBoxColorWrapper::operator()(
[[maybe_unused]] const OUString& /*rCommand*/, const NamedColor& rColor)
[[maybe_unused]] const OUString& /*rCommand*/, const svx::NamedThemedColor& rColor)
{
mpControl->Selected(rColor);
}
@@ -3905,8 +3910,8 @@ void ColorListBox::SetSlotId(sal_uInt16 nSlotId, bool bShowNoneButton)
m_bShowNoneButton = bShowNoneButton;
m_xButton->set_popover(nullptr);
m_xColorWindow.reset();
m_aSelectedColor = bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId);
ShowPreview(m_aSelectedColor);
m_aSelectedColor = svx::NamedThemedColor::FromNamedColor(bShowNoneButton ? GetNoneColor() : GetAutoColor(m_nSlotId));
ShowPreview(m_aSelectedColor.ToNamedColor());
createColorWindow();
}
@@ -3919,9 +3924,9 @@ ColorListBox::ColorListBox(std::unique_ptr<weld::MenuButton> pControl, TopLevelP
, m_aTopLevelParentFunction(rTopLevelParentFunction)
{
m_xButton->connect_toggled(LINK(this, ColorListBox, ToggleHdl));
m_aSelectedColor = GetAutoColor(m_nSlotId);
m_aSelectedColor = svx::NamedThemedColor::FromNamedColor(GetAutoColor(m_nSlotId));
LockWidthRequest();
ShowPreview(m_aSelectedColor);
ShowPreview(m_aSelectedColor.ToNamedColor());
}
IMPL_LINK(ColorListBox, ToggleHdl, weld::Toggleable&, rButton, void)
@@ -3967,7 +3972,7 @@ void ColorListBox::createColorWindow()
m_xButton->set_popover(m_xColorWindow->getTopLevel());
if (m_bShowNoneButton)
m_xColorWindow->ShowNoneButton();
m_xColorWindow->SelectEntry(m_aSelectedColor);
m_xColorWindow->SelectEntry(m_aSelectedColor.ToNamedColor());
}
void ColorListBox::SelectEntry(const NamedColor& rColor)
@@ -3979,21 +3984,21 @@ void ColorListBox::SelectEntry(const NamedColor& rColor)
}
ColorWindow* pColorWindow = getColorWindow();
pColorWindow->SelectEntry(rColor);
m_aSelectedColor = pColorWindow->GetSelectEntryColor();
ShowPreview(m_aSelectedColor);
m_aSelectedColor = svx::NamedThemedColor::FromNamedColor(pColorWindow->GetSelectEntryColor());
ShowPreview(m_aSelectedColor.ToNamedColor());
}
void ColorListBox::SelectEntry(const Color& rColor)
{
ColorWindow* pColorWindow = getColorWindow();
pColorWindow->SelectEntry(rColor);
m_aSelectedColor = pColorWindow->GetSelectEntryColor();
ShowPreview(m_aSelectedColor);
m_aSelectedColor = svx::NamedThemedColor::FromNamedColor(pColorWindow->GetSelectEntryColor());
ShowPreview(m_aSelectedColor.ToNamedColor());
}
void ColorListBox::Selected(const NamedColor& rColor)
void ColorListBox::Selected(const svx::NamedThemedColor& rColor)
{
ShowPreview(rColor);
ShowPreview(rColor.ToNamedColor());
m_aSelectedColor = rColor;
if (m_aSelectedLink.IsSet())
m_aSelectedLink.Call(*this);