With the refactoring from previous commits in place, it's clear that all callers pass a non-null SfxBindings* param. Switch the param to a reference, to make that clear and prepare for further refactoring. Change-Id: Id9f1487dba4b84860f9afa52ff9ffb4dd7b1d2c6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208387 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
428 lines
14 KiB
C++
428 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* 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/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <sot/exchange.hxx>
|
|
#include <svx/strings.hrc>
|
|
#include <svx/svxids.hrc>
|
|
|
|
#include <sfx2/viewsh.hxx>
|
|
#include <sfx2/objsh.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/viewfrm.hxx>
|
|
#include <vcl/image.hxx>
|
|
#include <vcl/transfer.hxx>
|
|
#include <vcl/weld/Builder.hxx>
|
|
#include <vcl/weld/ScrolledWindow.hxx>
|
|
|
|
#include <colrctrl.hxx>
|
|
|
|
#include <svx/svdview.hxx>
|
|
#include <svx/drawitem.hxx>
|
|
#include <svx/xfillit0.hxx>
|
|
#include <svx/xflclit.hxx>
|
|
#include <editeng/colritem.hxx>
|
|
#include <svx/xlineit0.hxx>
|
|
#include <svx/xlnclit.hxx>
|
|
#include <svx/dialmgr.hxx>
|
|
#include <helpids.h>
|
|
#include <vcl/virdev.hxx>
|
|
|
|
#include <com/sun/star/beans/NamedValue.hpp>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
class SvxColorValueSetData final : public TransferDataContainer
|
|
{
|
|
private:
|
|
uno::Sequence<beans::NamedValue> m_Data;
|
|
|
|
virtual void AddSupportedFormats() override;
|
|
virtual bool GetData(const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc) override;
|
|
|
|
public:
|
|
SvxColorValueSetData()
|
|
{
|
|
}
|
|
|
|
void SetData(const uno::Sequence<beans::NamedValue>& rData)
|
|
{
|
|
m_Data = rData;
|
|
ClearFormats(); // invalidate m_aAny so new data will take effect
|
|
}
|
|
};
|
|
|
|
void SvxColorValueSetData::AddSupportedFormats()
|
|
{
|
|
AddFormat( SotClipboardFormatId::XFA );
|
|
}
|
|
|
|
bool SvxColorValueSetData::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
|
|
{
|
|
bool bRet = false;
|
|
|
|
if( SotExchange::GetFormat( rFlavor ) == SotClipboardFormatId::XFA )
|
|
{
|
|
SetAny(uno::Any(m_Data));
|
|
bRet = true;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void SvxColorValueSet_docking::SetDrawingArea(weld::DrawingArea* pDrawingArea)
|
|
{
|
|
SvxColorValueSet::SetDrawingArea(pDrawingArea);
|
|
SetStyle(GetStyle() | WB_ITEMBORDER);
|
|
|
|
m_xHelper.set(new SvxColorValueSetData);
|
|
rtl::Reference<TransferDataContainer> xHelper(m_xHelper);
|
|
SetDragDataTransferable(xHelper, DND_ACTION_COPY);
|
|
}
|
|
|
|
SvxColorValueSet_docking::SvxColorValueSet_docking(std::unique_ptr<weld::ScrolledWindow> xWindow)
|
|
: SvxColorValueSet(std::move(xWindow))
|
|
, mbLeftButton(true)
|
|
{
|
|
}
|
|
|
|
bool SvxColorValueSet_docking::MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
bool bRet;
|
|
|
|
// For Mac still handle differently!
|
|
if( rMEvt.IsLeft() )
|
|
{
|
|
mbLeftButton = true;
|
|
bRet = SvxColorValueSet::MouseButtonDown( rMEvt );
|
|
}
|
|
else
|
|
{
|
|
mbLeftButton = false;
|
|
MouseEvent aMEvt( rMEvt.GetPosPixel(),
|
|
rMEvt.GetClicks(),
|
|
rMEvt.GetMode(),
|
|
MOUSE_LEFT,
|
|
rMEvt.GetModifier() );
|
|
bRet = SvxColorValueSet::MouseButtonDown( aMEvt );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool SvxColorValueSet_docking::MouseButtonUp( const MouseEvent& rMEvt )
|
|
{
|
|
bool bRet;
|
|
|
|
// For Mac still handle differently!
|
|
if( rMEvt.IsLeft() )
|
|
{
|
|
mbLeftButton = true;
|
|
bRet = SvxColorValueSet::MouseButtonUp( rMEvt );
|
|
}
|
|
else
|
|
{
|
|
mbLeftButton = false;
|
|
MouseEvent aMEvt( rMEvt.GetPosPixel(),
|
|
rMEvt.GetClicks(),
|
|
rMEvt.GetMode(),
|
|
MOUSE_LEFT,
|
|
rMEvt.GetModifier() );
|
|
bRet = SvxColorValueSet::MouseButtonUp( aMEvt );
|
|
}
|
|
SetNoSelection();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool SvxColorValueSet_docking::StartDrag()
|
|
{
|
|
sal_uInt16 nPos = GetSelectedItemId();
|
|
Color aItemColor( GetItemColor( nPos ) );
|
|
OUString sItemText( GetItemText( nPos ) );
|
|
|
|
drawing::FillStyle eStyle = (nPos == GetItemCount())
|
|
? drawing::FillStyle_NONE
|
|
: drawing::FillStyle_SOLID;
|
|
|
|
XFillColorItem const color(sItemText, aItemColor);
|
|
XFillStyleItem const style(eStyle);
|
|
uno::Any c, s;
|
|
color.QueryValue(c, 0);
|
|
style.QueryValue(s, 0);
|
|
|
|
uno::Sequence<beans::NamedValue> props{ { u"FillColor"_ustr, std::move(c) },
|
|
{ u"FillStyle"_ustr, std::move(s) } };
|
|
m_xHelper->SetData(props);
|
|
|
|
return false;
|
|
}
|
|
|
|
constexpr sal_uInt16 gnLeftSlot = SID_ATTR_FILL_COLOR;
|
|
constexpr sal_uInt16 gnRightSlot = SID_ATTR_LINE_COLOR;
|
|
|
|
SvxColorDockingWindow::SvxColorDockingWindow(SfxBindings& rBindings, SfxChildWindow* pCW,
|
|
vcl::Window* _pParent)
|
|
: SfxDockingWindow(rBindings, pCW, _pParent, u"DockingColorWindow"_ustr,
|
|
u"svx/ui/dockingcolorwindow.ui"_ustr)
|
|
, m_pColorSet(
|
|
new SvxColorValueSet_docking(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
|
|
, m_pColorSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *m_pColorSet))
|
|
{
|
|
SetText(SvxResId(STR_COLORTABLE));
|
|
SetQuickHelpText(SvxResId(RID_SVXSTR_COLORBAR));
|
|
SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MapUnit::MapAppFont)));
|
|
SetHelpId(HID_CTRL_COLOR);
|
|
|
|
m_pColorSet->SetSelectHdl(LINK(this, SvxColorDockingWindow, SelectHdl));
|
|
m_pColorSet->SetAccessibleName(SvxResId(STR_COLORTABLE));
|
|
m_pColorSet->SetHelpId(HID_COLOR_CTL_COLORS);
|
|
|
|
// Get the model from the view shell. Using SfxObjectShell::Current()
|
|
// is unreliable when called at the wrong times.
|
|
SfxObjectShell* pDocSh = nullptr;
|
|
SfxDispatcher* pDispatcher = rBindings.GetDispatcher();
|
|
if (pDispatcher != nullptr)
|
|
{
|
|
SfxViewFrame* pFrame = pDispatcher->GetFrame();
|
|
if (pFrame != nullptr)
|
|
{
|
|
SfxViewShell* pViewShell = pFrame->GetViewShell();
|
|
if (pViewShell != nullptr)
|
|
pDocSh = pViewShell->GetObjectShell();
|
|
}
|
|
}
|
|
|
|
if ( pDocSh )
|
|
{
|
|
if (const SvxColorListItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE ))
|
|
{
|
|
m_pColorList = pItem->GetColorList();
|
|
FillValueSet();
|
|
}
|
|
}
|
|
|
|
Size aItemSize = m_pColorSet->CalcItemSizePixel(
|
|
Size(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength()));
|
|
aItemSize.setWidth( aItemSize.Width() + SvxColorValueSet::getEntryEdgeLength() );
|
|
aItemSize.setWidth( aItemSize.Width() / 2 );
|
|
aItemSize.setHeight( aItemSize.Height() + SvxColorValueSet::getEntryEdgeLength() );
|
|
aItemSize.setHeight( aItemSize.Height() / 2 );
|
|
|
|
StartListening(rBindings, DuplicateHandling::Prevent);
|
|
}
|
|
|
|
SvxColorDockingWindow::~SvxColorDockingWindow()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SvxColorDockingWindow::dispose()
|
|
{
|
|
EndListening( GetBindings() );
|
|
m_pColorSetWin.reset();
|
|
m_pColorSet.reset();
|
|
SfxDockingWindow::dispose();
|
|
}
|
|
|
|
void SvxColorDockingWindow::Notify( SfxBroadcaster& , const SfxHint& rHint )
|
|
{
|
|
if (rHint.GetId() == SfxHintId::PoolItem)
|
|
{
|
|
const SfxPoolItemHint* pPoolItemHint = static_cast<const SfxPoolItemHint*>(&rHint);
|
|
if (auto pColorListItem = dynamic_cast<const SvxColorListItem*>(pPoolItemHint->GetObject()))
|
|
{
|
|
// The list of colors has changed
|
|
m_pColorList = pColorListItem->GetColorList();
|
|
FillValueSet();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvxColorDockingWindow::FillValueSet()
|
|
{
|
|
if (!m_pColorList.is())
|
|
return;
|
|
|
|
m_pColorSet->Clear();
|
|
|
|
m_pColorSet->addEntriesForXColorList(*m_pColorList);
|
|
|
|
// create the last entry for 'invisible/none'
|
|
const Size aColorSize(SvxColorValueSet::getEntryEdgeLength(), SvxColorValueSet::getEntryEdgeLength());
|
|
tools::Long nPtX = aColorSize.Width() - 1;
|
|
tools::Long nPtY = aColorSize.Height() - 1;
|
|
ScopedVclPtrInstance< VirtualDevice > pVD;
|
|
|
|
pVD->SetOutputSizePixel( aColorSize );
|
|
pVD->SetLineColor( COL_BLACK );
|
|
pVD->SetBackground( Wallpaper( COL_WHITE ) );
|
|
pVD->DrawLine( Point(), Point( nPtX, nPtY ) );
|
|
pVD->DrawLine( Point( 0, nPtY ), Point( nPtX, 0 ) );
|
|
|
|
Bitmap aBmp( pVD->GetBitmap( Point(), aColorSize ) );
|
|
|
|
m_pColorSet->InsertItem(m_pColorSet->GetItemCount() + 1, Image(aBmp),
|
|
SvxResId(RID_SVXSTR_INVISIBLE));
|
|
}
|
|
|
|
bool SvxColorDockingWindow::Close()
|
|
{
|
|
SfxBoolItem aItem( SID_COLOR_CONTROL, false );
|
|
GetBindings().GetDispatcher()->ExecuteList(SID_COLOR_CONTROL,
|
|
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem });
|
|
SfxDockingWindow::Close();
|
|
return true;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxColorDockingWindow, SelectHdl, ValueSet*, void)
|
|
{
|
|
SfxDispatcher* pDispatcher = GetBindings().GetDispatcher();
|
|
sal_uInt16 nPos = m_pColorSet->GetSelectedItemId();
|
|
Color aColor(m_pColorSet->GetItemColor(nPos));
|
|
OUString aStr(m_pColorSet->GetItemText(nPos));
|
|
|
|
// ID of 'invisible/none' entry, see SvxColorDockingWindow::FillValueSet
|
|
const sal_uInt16 nIdNone = m_pColorSet->GetItemCount();
|
|
if (m_pColorSet->IsLeftButton())
|
|
{
|
|
if ( gnLeftSlot == SID_ATTR_FILL_COLOR )
|
|
{
|
|
if (nPos == nIdNone)
|
|
{
|
|
XFillStyleItem aXFillStyleItem( drawing::FillStyle_NONE );
|
|
pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
|
|
{ &aXFillStyleItem });
|
|
}
|
|
else
|
|
{
|
|
bool bDone = false;
|
|
|
|
// If we have a DrawView and we are in TextEdit mode, then
|
|
// not the area color but the text color is assigned
|
|
SfxViewShell* pViewSh = SfxViewShell::Current();
|
|
if ( pViewSh )
|
|
{
|
|
SdrView* pView = pViewSh->GetDrawView();
|
|
if ( pView && pView->IsTextEdit() )
|
|
{
|
|
SvxColorItem aTextColorItem( aColor, SID_ATTR_CHAR_COLOR );
|
|
pDispatcher->ExecuteList(SID_ATTR_CHAR_COLOR,
|
|
SfxCallMode::RECORD, { &aTextColorItem });
|
|
bDone = true;
|
|
}
|
|
}
|
|
if ( !bDone )
|
|
{
|
|
XFillStyleItem aXFillStyleItem( drawing::FillStyle_SOLID );
|
|
XFillColorItem aXFillColorItem( aStr, aColor );
|
|
pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
|
|
{ &aXFillColorItem, &aXFillStyleItem });
|
|
}
|
|
}
|
|
}
|
|
else if (nPos != nIdNone)
|
|
{
|
|
SvxColorItem aLeftColorItem( aColor, gnLeftSlot );
|
|
pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
|
|
{ &aLeftColorItem });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( gnRightSlot == SID_ATTR_LINE_COLOR )
|
|
{
|
|
if (nPos == nIdNone)
|
|
{
|
|
XLineStyleItem aXLineStyleItem( drawing::LineStyle_NONE );
|
|
pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
|
|
{ &aXLineStyleItem });
|
|
}
|
|
else
|
|
{
|
|
// If the LineStyle is invisible, it is set to SOLID
|
|
SfxViewShell* pViewSh = SfxViewShell::Current();
|
|
if ( pViewSh )
|
|
{
|
|
SdrView* pView = pViewSh->GetDrawView();
|
|
if ( pView )
|
|
{
|
|
SfxItemSet aAttrSet(pView->GetModel().GetItemPool());
|
|
pView->GetAttributes( aAttrSet );
|
|
if ( aAttrSet.GetItemState( XATTR_LINESTYLE ) != SfxItemState::INVALID )
|
|
{
|
|
drawing::LineStyle eXLS =
|
|
aAttrSet.Get( XATTR_LINESTYLE ).GetValue();
|
|
if ( eXLS == drawing::LineStyle_NONE )
|
|
{
|
|
XLineStyleItem aXLineStyleItem( drawing::LineStyle_SOLID );
|
|
pDispatcher->ExecuteList(gnRightSlot,
|
|
SfxCallMode::RECORD, { &aXLineStyleItem });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XLineColorItem aXLineColorItem( aStr, aColor );
|
|
pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
|
|
{ &aXLineColorItem });
|
|
}
|
|
}
|
|
else if (nPos != nIdNone)
|
|
{
|
|
SvxColorItem aRightColorItem( aColor, gnRightSlot );
|
|
pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
|
|
{ &aRightColorItem });
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvxColorDockingWindow::GetFocus()
|
|
{
|
|
SfxDockingWindow::GetFocus();
|
|
if (m_pColorSet)
|
|
{
|
|
// Grab the focus to the color value set so that it can be controlled
|
|
// with the keyboard.
|
|
m_pColorSet->GrabFocus();
|
|
}
|
|
}
|
|
|
|
bool SvxColorDockingWindow::EventNotify( NotifyEvent& rNEvt )
|
|
{
|
|
bool bRet = false;
|
|
if( rNEvt.GetType() == NotifyEventType::KEYINPUT )
|
|
{
|
|
KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
|
|
sal_uInt16 nKeyCode = aKeyEvt.GetKeyCode().GetCode();
|
|
switch( nKeyCode )
|
|
{
|
|
case KEY_ESCAPE:
|
|
GrabFocusToDocument();
|
|
bRet = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet || SfxDockingWindow::EventNotify(rNEvt);
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|