424 lines
14 KiB
C++
424 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 <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);
|
|
SetAccessibleName(SvxResId(STR_COLORTABLE));
|
|
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 = ((1 == nPos)
|
|
? 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* _pBindings, SfxChildWindow* pCW, vcl::Window* _pParent)
|
|
: SfxDockingWindow(_pBindings, pCW, _pParent,
|
|
u"DockingColorWindow"_ustr, u"svx/ui/dockingcolorwindow.ui"_ustr)
|
|
, xColorSet(new SvxColorValueSet_docking(m_xBuilder->weld_scrolled_window(u"valuesetwin"_ustr, true)))
|
|
, xColorSetWin(new weld::CustomWeld(*m_xBuilder, u"valueset"_ustr, *xColorSet))
|
|
{
|
|
SetText(SvxResId(STR_COLORTABLE));
|
|
SetQuickHelpText(SvxResId(RID_SVXSTR_COLORBAR));
|
|
SetSizePixel(LogicToPixel(Size(150, 22), MapMode(MapUnit::MapAppFont)));
|
|
SetHelpId(HID_CTRL_COLOR);
|
|
|
|
xColorSet->SetSelectHdl( LINK( this, SvxColorDockingWindow, SelectHdl ) );
|
|
xColorSet->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;
|
|
if (_pBindings != nullptr)
|
|
{
|
|
SfxDispatcher* pDispatcher = _pBindings->GetDispatcher();
|
|
if (pDispatcher != nullptr)
|
|
{
|
|
SfxViewFrame* pFrame = pDispatcher->GetFrame();
|
|
if (pFrame != nullptr)
|
|
{
|
|
SfxViewShell* pViewShell = pFrame->GetViewShell();
|
|
if (pViewShell != nullptr)
|
|
pDocSh = pViewShell->GetObjectShell();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pDocSh )
|
|
{
|
|
const SfxPoolItem* pItem = pDocSh->GetItem( SID_COLOR_TABLE );
|
|
if( pItem )
|
|
{
|
|
pColorList = static_cast<const SvxColorListItem*>(pItem)->GetColorList();
|
|
FillValueSet();
|
|
}
|
|
}
|
|
|
|
Size aItemSize = xColorSet->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 );
|
|
|
|
if (_pBindings != nullptr)
|
|
StartListening(*_pBindings, DuplicateHandling::Prevent);
|
|
}
|
|
|
|
SvxColorDockingWindow::~SvxColorDockingWindow()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void SvxColorDockingWindow::dispose()
|
|
{
|
|
EndListening( GetBindings() );
|
|
xColorSetWin.reset();
|
|
xColorSet.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
|
|
pColorList = pColorListItem->GetColorList();
|
|
FillValueSet();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvxColorDockingWindow::FillValueSet()
|
|
{
|
|
if( !pColorList.is() )
|
|
return;
|
|
|
|
xColorSet->Clear();
|
|
|
|
xColorSet->addEntriesForXColorList(*pColorList, 2);
|
|
|
|
// 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 ) );
|
|
|
|
BitmapEx aBmp( pVD->GetBitmapEx( Point(), aColorSize ) );
|
|
|
|
xColorSet->InsertItem( sal_uInt16(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 = xColorSet->GetSelectedItemId();
|
|
Color aColor( xColorSet->GetItemColor( nPos ) );
|
|
OUString aStr( xColorSet->GetItemText( nPos ) );
|
|
|
|
if (xColorSet->IsLeftButton())
|
|
{
|
|
if ( gnLeftSlot == SID_ATTR_FILL_COLOR )
|
|
{
|
|
if ( nPos == 1 ) // invisible
|
|
{
|
|
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 != 1 ) // invisible
|
|
{
|
|
SvxColorItem aLeftColorItem( aColor, gnLeftSlot );
|
|
pDispatcher->ExecuteList(gnLeftSlot, SfxCallMode::RECORD,
|
|
{ &aLeftColorItem });
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( gnRightSlot == SID_ATTR_LINE_COLOR )
|
|
{
|
|
if( nPos == 1 ) // invisible
|
|
{
|
|
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 != 1 ) // invisible
|
|
{
|
|
SvxColorItem aRightColorItem( aColor, gnRightSlot );
|
|
pDispatcher->ExecuteList(gnRightSlot, SfxCallMode::RECORD,
|
|
{ &aRightColorItem });
|
|
}
|
|
}
|
|
}
|
|
|
|
void SvxColorDockingWindow::GetFocus()
|
|
{
|
|
SfxDockingWindow::GetFocus();
|
|
if (xColorSet)
|
|
{
|
|
// Grab the focus to the color value set so that it can be controlled
|
|
// with the keyboard.
|
|
xColorSet->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: */
|