Quelle fontworkgallery.cxx
Sprache: 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 <com/sun/star/text/WritingMode.hpp>
#include <comphelper/lok.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <vcl/toolbox.hxx>
#include <vcl/virdev.hxx>
#include <sfx2/viewsh.hxx>
#include <svl/itempool.hxx>
#include <svtools/toolbarmenu.hxx>
#include <svtools/popupwindowcontroller.hxx>
#include <svx/fmmodel.hxx>
#include <svx/svdpage.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdview.hxx>
#include <svx/gallery.hxx>
#include <svx/fontworkgallery.hxx>
#include <tools/UnitConversion.hxx>
#include <memory>
#include <svx/strings.hrc>
#include <svx/dialmgr.hxx>
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
namespace svx
{
FontWorkGalleryDialog::FontWorkGalleryDialog(weld::Window* pParent, SdrView& rS
drView,
Reference<css::frame::XFrame> xFrame)
: GenericDialogController(pParent, u"svx/ui/fontworkgallerydialog.ui" _ustr, u"FontworkGalleryDialog" _ustr)
, mnThemeId(0 xffff)
, mrSdrView(rSdrView)
, mbInsertIntoPage(true )
, mpDestModel(nullptr)
, maCtlFavorites(m_xBuilder->weld_icon_view(u"ctlFavoriteswin" _ustr))
, mxOKButton(m_xBuilder->weld_button(u"ok" _ustr))
, mxFrame(std::move(xFrame))
{
Size aSize(530 , 400 );
maCtlFavorites->set_size_request(aSize.Width(), aSize.Height());
maCtlFavorites->connect_item_activated( LINK( this , FontWorkGalleryDialog, DoubleClickFavoriteHdl ) );
maCtlFavorites->connect_query_tooltip(LINK(this , FontWorkGalleryDialog, QueryTooltipHandler));
mxOKButton->connect_clicked(LINK(this , FontWorkGalleryDialog, ClickOKHdl));
initFavorites( GALLERY_THEME_FONTWORK );
fillFavorites( GALLERY_THEME_FONTWORK );
}
FontWorkGalleryDialog::~FontWorkGalleryDialog()
{
}
void FontWorkGalleryDialog::initFavorites(sal_uInt16 nThemeId)
{
// the favorites are read via the gallery
sal_uInt32 nFavCount = GalleryExplorer::GetSdrObjCount( nThemeId );
// lock gallery theme
GalleryExplorer::BeginLocking(nThemeId);
sal_uInt32 nModelPos;
FmFormModel *pModel = nullptr;
for ( nModelPos = 0 ; nModelPos < nFavCount; nModelPos++ )
{
BitmapEx aThumb;
if (GalleryExplorer::GetSdrObj(nThemeId, nModelPos, pModel, &aThumb) && !aThumb.IsEmpty())
{
ScopedVclPtrInstance< VirtualDevice > pVDev;
const Point aNull(0 , 0 );
if (pVDev->GetDPIScaleFactor() > 1 )
aThumb.Scale(pVDev->GetDPIScaleFactor(), pVDev->GetDPIScaleFactor());
const Size aSize(aThumb.GetSizePixel());
pVDev->SetOutputSizePixel(aSize);
static const sal_uInt32 nLen(8 );
static const Color aW(COL_WHITE);
static const Color aG(0 xef, 0 xef, 0 xef);
pVDev->DrawCheckered(aNull, aSize, nLen, aW, aG);
pVDev->DrawBitmapEx(aNull, aThumb);
maFavoritesHorizontal.emplace_back(pVDev->GetBitmapEx(Point(0 ,0 ), aSize));
}
}
// release gallery theme
GalleryExplorer::EndLocking(nThemeId);
}
void FontWorkGalleryDialog::fillFavorites(sal_uInt16 nThemeId)
{
mnThemeId = nThemeId;
auto nFavCount = maFavoritesHorizontal.size();
maCtlFavorites->clear();
maIdToTitleMap.clear();
std::vector<OUString> aTitles;
(void )GalleryExplorer::FillObjListTitle(nThemeId, aTitles);
assert(aTitles.size() == nFavCount);
for ( size_t nFavorite = 1 ; nFavorite <= nFavCount; nFavorite++ )
{
OUString sId = OUString::number(static_cast <sal_uInt16>(nFavorite));
maIdToTitleMap.emplace(sId, aTitles.at(nFavorite - 1 ));
maCtlFavorites->insert(-1 , nullptr, &sId, &maFavoritesHorizontal[nFavorite - 1 ], nullptr);
maCtlFavorites->set_item_accessible_name(maCtlFavorites->n_children() - 1 , aTitles.at(nFavorite -1 ));
}
if (maCtlFavorites->n_children())
maCtlFavorites->select(0 );
}
void FontWorkGalleryDialog::SetSdrObjectRef( SdrModel* pModel)
{
mbInsertIntoPage = false ;
mpDestModel = pModel;
}
void FontWorkGalleryDialog::insertSelectedFontwork()
{
OUString sItemId = maCtlFavorites->get_selected_id();
if (sItemId.isEmpty())
return ;
sal_Int32 nItemId = sItemId.toInt32();
if (nItemId == 0 )
return ;
FmFormModel aModel;
if ( !GalleryExplorer::GetSdrObj( mnThemeId, nItemId-1 , &aModel ) )
return ;
SdrPage* pPage = aModel.GetPage(0 );
if ( !(pPage && pPage->GetObjCount()) )
return ;
// tdf#116993 Calc uses a 'special' mode for this dialog in being the
// only caller of ::SetSdrObjectRef. Only in that case mpDestModel seems
// to be the correct target SdrModel.
// If this is not used, the correct SdrModel seems to be the one from
// the mrSdrView that is used to insert (InsertObjectAtView below) the
// cloned SdrObject.
const bool bUseSpecialCalcMode(!mbInsertIntoPage && nullptr != mpDestModel);
// center shape on current view
OutputDevice* pOutDev(mrSdrView.GetFirstOutputDevice());
if (!pOutDev)
return ;
// Clone directly to target SdrModel (may be different due to user/caller (!))
rtl::Reference<SdrObject> xNewObject(
pPage->GetObj(0 )->CloneSdrObject(
bUseSpecialCalcMode ? *mpDestModel : mrSdrView.getSdrModelFromSdrView()));
const Reference<XComponentContext>& xContext = comphelper::getProcessComponentContext();
css::uno::Reference<css::frame::XModuleManager> xModuleManager =
css::frame::ModuleManager::create(xContext);
OUString aModuleIdentifier = xModuleManager->identify(mxFrame);
if (aModuleIdentifier != "com.sun.star.drawing.DrawingDocument" &&
aModuleIdentifier != "com.sun.star.presentation.PresentationDocument" )
{
xNewObject->SetName(SvxResId(STR_ObjNameSingulFONTWORK) + u" 1" );
xNewObject->MakeNameUnique();
}
else
xNewObject->SetName(OUString());
// tdf#117629
// Since the 'old' ::CloneSdrObject also copies the SdrPage* the
// SdrObject::getUnoShape() *will* create the wrong UNO API object
// early. This IS one of the reasons I do change these things - this
// error does not happen with my next change I am working on already
// ARGH! For now, reset the SdrPage* to nullptr.
// What sense does it have to copy the SdrPage* of the original SdrObject ?!?
// TTTT: This also *might* be the hidden reason for the strange code at the
// end of SdrObject::SetPage that tries to delete the SvxShape under some
// circumstances...
// xNewObject->SetPage(nullptr);
tools::Rectangle aObjRect( xNewObject->GetLogicRect() );
Point aPagePos;
Size aFontworkSize = aObjRect.GetSize();
SfxViewShell* pKitViewShell = comphelper::LibreOfficeKit::isActive() ?
SfxViewShell::Current() : nullptr;
if (pKitViewShell)
{
aPagePos = convertTwipToMm100(pKitViewShell->getLOKVisibleArea().Center());
sal_Int32 nLOKViewWidth = 0 .8 * convertTwipToMm100(pKitViewShell->getLOKVisibleArea().getOpenWidth());
if (aFontworkSize.getWidth() > nLOKViewWidth)
{
double fScale = static_cast <double >(aFontworkSize.getWidth()) / nLOKViewWidth;
aFontworkSize.setWidth(aFontworkSize.getWidth() / fScale);
aFontworkSize.setHeight(aFontworkSize.getHeight() / fScale);
}
}
else
{
Size aSize = pOutDev->GetOutputSizePixel();
tools::Rectangle aPixelVisRect(Point(0 ,0 ), aSize);
tools::Rectangle aVisArea = pOutDev->PixelToLogic(aPixelVisRect);
aPagePos = aVisArea.Center();
}
if (aPagePos.getX() > aFontworkSize.getWidth() / 2 )
aPagePos.AdjustX( -(aFontworkSize.getWidth() / 2 ) );
if (aPagePos.getY() > aFontworkSize.getHeight() / 2 )
aPagePos.AdjustY( -(aFontworkSize.getHeight() / 2 ) );
tools::Rectangle aNewObjectRectangle(aPagePos, aFontworkSize);
xNewObject->SetLogicRect(aNewObjectRectangle);
if (bUseSpecialCalcMode)
{
mxSdrObject = std::move(xNewObject);
}
else
{
SdrPageView* pPV(mrSdrView.GetSdrPageView());
if (nullptr != pPV)
{
mrSdrView.InsertObjectAtView( xNewObject.get(), *pPV );
}
}
}
IMPL_LINK_NOARG(FontWorkGalleryDialog, ClickOKHdl, weld::Button&, void )
{
insertSelectedFontwork();
m_xDialog->response(RET_OK);
}
IMPL_LINK_NOARG(FontWorkGalleryDialog, DoubleClickFavoriteHdl, weld::IconView&, bool )
{
insertSelectedFontwork();
m_xDialog->response(RET_OK);
return true ;
}
IMPL_LINK(FontWorkGalleryDialog, QueryTooltipHandler, const weld::TreeIter&, iter, OUString)
{
const OUString id = maCtlFavorites->get_id(iter);
auto it = maIdToTitleMap.find(id);
return it != maIdToTitleMap.end() ? it->second : OUString();
}
namespace {
class FontworkAlignmentWindow final : public WeldToolbarPopup
{
public :
FontworkAlignmentWindow(svt::PopupWindowController* pControl, weld::Widget* pParentWindow);
virtual void GrabFocus() override
{
mxLeft->grab_focus();
}
virtual void statusChanged( const css::frame::FeatureStateEvent& Event ) override;
private :
rtl::Reference<svt::PopupWindowController> mxControl;
std::unique_ptr<weld::RadioButton> mxLeft;
std::unique_ptr<weld::RadioButton> mxCenter;
std::unique_ptr<weld::RadioButton> mxRight;
std::unique_ptr<weld::RadioButton> mxStretch;
bool mbSettingValue;
DECL_LINK( SelectHdl, weld::Toggleable&, void );
void implSetAlignment( int nAlignmentMode, bool bEnabled );
};
}
constexpr OUString gsFontworkAlignment(u".uno:FontworkAlignment" _ustr);
FontworkAlignmentWindow::FontworkAlignmentWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
: WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/fontworkalignmentcontrol.ui" _ustr, u"FontworkAlignmentControl" _ustr)
, mxControl(pControl)
, mxLeft(m_xBuilder->weld_radio_button(u"left" _ustr))
, mxCenter(m_xBuilder->weld_radio_button(u"center" _ustr))
, mxRight(m_xBuilder->weld_radio_button(u"right" _ustr))
, mxStretch(m_xBuilder->weld_radio_button(u"stretch" _ustr))
, mbSettingValue(false )
{
mxLeft->connect_toggled(LINK(this , FontworkAlignmentWindow, SelectHdl));
mxCenter->connect_toggled(LINK(this , FontworkAlignmentWindow, SelectHdl));
mxRight->connect_toggled(LINK(this , FontworkAlignmentWindow, SelectHdl));
mxStretch->connect_toggled(LINK(this , FontworkAlignmentWindow, SelectHdl));
AddStatusListener( gsFontworkAlignment );
}
void FontworkAlignmentWindow::implSetAlignment( int nSurface, bool bEnabled )
{
bool bSettingValue = mbSettingValue;
mbSettingValue = true ;
mxLeft->set_active(nSurface == 0 && bEnabled);
mxLeft->set_sensitive(bEnabled);
mxCenter->set_active(nSurface == 1 && bEnabled);
mxCenter->set_sensitive(bEnabled);
mxRight->set_active(nSurface == 2 && bEnabled);
mxRight->set_sensitive(bEnabled);
//Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
//mxWord->set_active(nSurface == 3 && bEnabled);
//mxWord->set_sensitive(bEnabled);
mxStretch->set_active(nSurface == 4 && bEnabled);
mxStretch->set_sensitive(bEnabled);
mbSettingValue = bSettingValue;
}
void FontworkAlignmentWindow::statusChanged( const css::frame::FeatureStateEvent& Event )
{
if ( Event.FeatureURL.Main != gsFontworkAlignment )
return ;
if ( !Event.IsEnabled )
{
implSetAlignment( 0 , false );
}
else
{
sal_Int32 nValue = 0 ;
if ( Event.State >>= nValue )
implSetAlignment( nValue, true );
}
}
IMPL_LINK(FontworkAlignmentWindow, SelectHdl, weld::Toggleable&, rButton, void )
{
if (mbSettingValue || !rButton.get_active())
return ;
sal_Int32 nAlignment;
if (mxLeft->get_active())
nAlignment = 0 ;
else if (mxCenter->get_active())
nAlignment = 1 ;
else if (mxRight->get_active())
nAlignment = 2 ;
//Refer https://bugs.documentfoundation.org/show_bug.cgi?id=145092 for why following lines are commented
//else if (mxWord->get_active())
// nAlignment = 3;
else
nAlignment = 4 ;
Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
gsFontworkAlignment.copy(5 ), nAlignment) };
mxControl->dispatchCommand( gsFontworkAlignment, aArgs );
implSetAlignment( nAlignment, true );
mxControl->EndPopupMode();
}
namespace {
class FontworkAlignmentControl : public svt::PopupWindowController
{
public :
explicit FontworkAlignmentControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
// XInitialization
virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};
}
FontworkAlignmentControl::FontworkAlignmentControl( const Reference< XComponentContext >& rxContext )
: svt::PopupWindowController( rxContext, Reference< css::frame::XFrame >(), u".uno:FontworkAlignment" _ustr )
{
}
std::unique_ptr<WeldToolbarPopup> FontworkAlignmentControl::weldPopupWindow()
{
return std::make_unique<FontworkAlignmentWindow>(this , m_pToolbar);
}
VclPtr<vcl::Window> FontworkAlignmentControl::createVclPopupWindow( vcl::Window* pParent )
{
mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
std::make_unique<FontworkAlignmentWindow>(this , pParent->GetFrameWeld()));
mxInterimPopover->Show();
return mxInterimPopover;
}
// XInitialization
void SAL_CALL FontworkAlignmentControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
{
svt::PopupWindowController::initialize( aArguments );
if (m_pToolbar)
{
mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
}
ToolBox* pToolBox = nullptr;
ToolBoxItemId nId;
if ( getToolboxId( nId, &pToolBox ) )
pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
}
// XServiceInfo
OUString FontworkAlignmentControl::getImplementationName()
{
return u"com.sun.star.comp.svx.FontworkAlignmentController" _ustr;
}
Sequence< OUString > FontworkAlignmentControl::getSupportedServiceNames()
{
return { u"com.sun.star.frame.ToolbarController" _ustr };
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_svx_FontworkAlignmentControl_get_implementation(
css::uno::XComponentContext* xContext,
css::uno::Sequence<css::uno::Any> const &)
{
return cppu::acquire(new FontworkAlignmentControl(xContext));
}
namespace {
class FontworkCharacterSpacingWindow final : public WeldToolbarPopup
{
public :
FontworkCharacterSpacingWindow(svt::PopupWindowController* pControl, weld::Widget* pParentWindow);
virtual void GrabFocus() override;
virtual void statusChanged( const css::frame::FeatureStateEvent& Event ) override;
private :
rtl::Reference<svt::PopupWindowController> mxControl;
std::unique_ptr<weld::RadioButton> mxVeryTight;
std::unique_ptr<weld::RadioButton> mxTight;
std::unique_ptr<weld::RadioButton> mxNormal;
std::unique_ptr<weld::RadioButton> mxLoose;
std::unique_ptr<weld::RadioButton> mxVeryLoose;
std::unique_ptr<weld::RadioButton> mxCustom;
std::unique_ptr<weld::CheckButton> mxKernPairs;
sal_Int32 mnCharacterSpacing;
bool mbSettingValue;
bool mbCommandDispatched;
DECL_LINK( KernSelectHdl, weld::Toggleable&, void );
DECL_LINK( SelectHdl, weld::Toggleable&, void );
DECL_LINK( MouseReleaseHdl, const MouseEvent&, bool );
void implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled );
void implSetKernCharacterPairs(bool bKernOnOff, bool bEnabled);
void DispatchSpacingDialog();
};
}
constexpr OUString gsFontworkCharacterSpacing(u".uno:FontworkCharacterSpacing" _ustr);
constexpr OUString gsFontworkKernCharacterPairs(u".uno:FontworkKernCharacterPairs" _ustr);
FontworkCharacterSpacingWindow::FontworkCharacterSpacingWindow(svt::PopupWindowController* pControl, weld::Widget* pParent)
: WeldToolbarPopup(pControl->getFrameInterface(), pParent, u"svx/ui/fontworkcharacterspacingcontrol.ui" _ustr, u"FontworkCharacterSpacingControl" _ustr)
, mxControl(pControl)
, mxVeryTight(m_xBuilder->weld_radio_button(u"verytight" _ustr))
, mxTight(m_xBuilder->weld_radio_button(u"tight" _ustr))
, mxNormal(m_xBuilder->weld_radio_button(u"normal" _ustr))
, mxLoose(m_xBuilder->weld_radio_button(u"loose" _ustr))
, mxVeryLoose(m_xBuilder->weld_radio_button(u"veryloose" _ustr))
, mxCustom(m_xBuilder->weld_radio_button(u"custom" _ustr))
, mxKernPairs(m_xBuilder->weld_check_button(u"kernpairs" _ustr))
, mnCharacterSpacing(0 )
, mbSettingValue(false )
, mbCommandDispatched(false )
{
mxVeryTight->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxTight->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxNormal->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxLoose->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxVeryLoose->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxCustom->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, SelectHdl));
mxCustom->connect_mouse_release(LINK(this , FontworkCharacterSpacingWindow, MouseReleaseHdl));
mxKernPairs->connect_toggled(LINK(this , FontworkCharacterSpacingWindow, KernSelectHdl));
AddStatusListener( gsFontworkCharacterSpacing );
AddStatusListener( gsFontworkKernCharacterPairs );
// See TODO in svx/source/toolbars/fontworkbar.cxx for SID_FONTWORK_KERN_CHARACTER_PAIRS,
// the kernpairs setting is ignored, so hide the widget entirely
mxKernPairs->hide();
}
void FontworkCharacterSpacingWindow::GrabFocus()
{
mxVeryTight->grab_focus();
}
void FontworkCharacterSpacingWindow::implSetCharacterSpacing( sal_Int32 nCharacterSpacing, bool bEnabled )
{
bool bSettingValue = mbSettingValue;
mbSettingValue = true ;
mxVeryTight->set_sensitive(bEnabled);
mxTight->set_sensitive(bEnabled);
mxNormal->set_sensitive(bEnabled);
mxLoose->set_sensitive(bEnabled);
mxVeryLoose->set_sensitive(bEnabled);
mxCustom->set_sensitive(bEnabled);
mxVeryTight->set_active(false );
mxTight->set_active(false );
mxNormal->set_active(false );
mxLoose->set_active(false );
mxVeryLoose->set_active(false );
mxCustom->set_active(true );
switch (nCharacterSpacing)
{
case 80 :
mxVeryTight->set_active(true );
break ;
case 90 :
mxTight->set_active(true );
break ;
case 100 :
mxNormal->set_active(true );
break ;
case 120 :
mxLoose->set_active(true );
break ;
case 150 :
mxVeryLoose->set_active(true );
break ;
}
mnCharacterSpacing = nCharacterSpacing;
mbSettingValue = bSettingValue;
}
void FontworkCharacterSpacingWindow::implSetKernCharacterPairs(bool bKernOnOff, bool bEnabled)
{
mxKernPairs->set_sensitive(bEnabled);
mxKernPairs->set_active(bKernOnOff);
}
void FontworkCharacterSpacingWindow::statusChanged( const css::frame::FeatureStateEvent& Event )
{
if ( Event.FeatureURL.Main == gsFontworkCharacterSpacing )
{
if ( !Event.IsEnabled )
{
implSetCharacterSpacing( 0 , false );
}
else
{
sal_Int32 nValue = 0 ;
if ( Event.State >>= nValue )
implSetCharacterSpacing( nValue, true );
}
}
else if ( Event.FeatureURL.Main == gsFontworkKernCharacterPairs )
{
if ( !Event.IsEnabled )
{
implSetKernCharacterPairs(false , false );
}
else
{
bool bValue = false ;
if ( Event.State >>= bValue )
implSetKernCharacterPairs(bValue, true );
}
}
}
IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, KernSelectHdl, weld::Toggleable&, void )
{
if (mbSettingValue)
return ;
bool bKernOnOff = mxKernPairs->get_active();
Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
gsFontworkKernCharacterPairs.copy(5 ), bKernOnOff) };
mxControl->dispatchCommand( gsFontworkKernCharacterPairs, aArgs );
mbCommandDispatched = true ;
implSetKernCharacterPairs(bKernOnOff, true );
mxControl->EndPopupMode();
}
void FontworkCharacterSpacingWindow::DispatchSpacingDialog()
{
Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
gsFontworkCharacterSpacing.copy(5 ), mnCharacterSpacing) };
rtl::Reference<svt::PopupWindowController> xControl(mxControl);
xControl->EndPopupMode();
xControl->dispatchCommand(u".uno:FontworkCharacterSpacingDialog" _ustr, aArgs);
mbCommandDispatched = true ;
}
IMPL_LINK(FontworkCharacterSpacingWindow, SelectHdl, weld::Toggleable&, rButton, void )
{
if (!rButton.get_active())
return ;
if (mbSettingValue)
return ;
// see MouseReleaseHdl for mbCommandDispatched check, there's no guarantee
// this toggle will happen before that mouse release though it does in
// practice for vcl and gtk
if (mbCommandDispatched)
return ;
if (mxCustom->get_active())
DispatchSpacingDialog();
else
{
sal_Int32 nCharacterSpacing;
if (mxVeryTight->get_active())
nCharacterSpacing = 80 ;
else if (mxTight->get_active())
nCharacterSpacing = 90 ;
else if (mxLoose->get_active())
nCharacterSpacing = 120 ;
else if (mxVeryLoose->get_active())
nCharacterSpacing = 150 ;
else
nCharacterSpacing = 100 ;
Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue(
gsFontworkCharacterSpacing.copy(5 ), nCharacterSpacing) };
mxControl->dispatchCommand( gsFontworkCharacterSpacing, aArgs );
mbCommandDispatched = true ;
implSetCharacterSpacing( nCharacterSpacing, true );
}
mxControl->EndPopupMode();
}
IMPL_LINK_NOARG(FontworkCharacterSpacingWindow, MouseReleaseHdl, const MouseEvent&, bool )
{
/*
tdf # 145296 if the " custom " radiobutton was presented preselected as
toggled on and the user clicked on it then there ' s no toggled signal sent
because the item was already toggled on and didn ' t change state .
So if that happens launch the custom spacing dialog explicitly here on
mouse release .
*/
if (mxCustom->get_active() && !mbCommandDispatched)
{
DispatchSpacingDialog();
return true ;
}
return false ;
}
namespace {
class FontworkCharacterSpacingControl : public svt::PopupWindowController
{
public :
explicit FontworkCharacterSpacingControl( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
virtual std::unique_ptr<WeldToolbarPopup> weldPopupWindow() override;
virtual VclPtr<vcl::Window> createVclPopupWindow( vcl::Window* pParent ) override;
// XInitialization
virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
};
}
FontworkCharacterSpacingControl::FontworkCharacterSpacingControl( const Reference< XComponentContext >& rxContext )
: svt::PopupWindowController( rxContext, Reference< css::frame::XFrame >(), u".uno:FontworkCharacterSpacingFloater" _ustr )
{
}
std::unique_ptr<WeldToolbarPopup> FontworkCharacterSpacingControl::weldPopupWindow()
{
return std::make_unique<FontworkCharacterSpacingWindow>(this , m_pToolbar);
}
VclPtr<vcl::Window> FontworkCharacterSpacingControl::createVclPopupWindow( vcl::Window* pParent )
{
mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent,
std::make_unique<FontworkCharacterSpacingWindow>(this , pParent->GetFrameWeld()));
mxInterimPopover->Show();
return mxInterimPopover;
}
// XInitialization
void SAL_CALL FontworkCharacterSpacingControl::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
{
svt::PopupWindowController::initialize( aArguments );
if (m_pToolbar)
{
mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar));
m_pToolbar->set_item_popover(m_aCommandURL, mxPopoverContainer->getTopLevel());
}
ToolBox* pToolBox = nullptr;
ToolBoxItemId nId;
if ( getToolboxId( nId, &pToolBox ) )
pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ToolBoxItemBits::DROPDOWNONLY );
}
// XServiceInfo
OUString FontworkCharacterSpacingControl::getImplementationName()
{
return u"com.sun.star.comp.svx.FontworkCharacterSpacingController" _ustr;
}
Sequence< OUString > FontworkCharacterSpacingControl::getSupportedServiceNames()
{
Sequence<OUString> aSNS { u"com.sun.star.frame.ToolbarController" _ustr };
return aSNS;
}
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_svx_FontworkCharacterSpacingControl_get_implementation(
css::uno::XComponentContext* xContext,
css::uno::Sequence<css::uno::Any> const &)
{
return cppu::acquire(new FontworkCharacterSpacingControl(xContext));
}
FontworkCharacterSpacingDialog::FontworkCharacterSpacingDialog(weld::Window* pParent, sal_Int32 nScale)
: GenericDialogController(pParent, u"svx/ui/fontworkspacingdialog.ui" _ustr, u"FontworkSpacingDialog" _ustr)
, m_xMtrScale(m_xBuilder->weld_metric_spin_button(u"entry" _ustr, FieldUnit::PERCENT))
{
m_xMtrScale->set_value(nScale, FieldUnit::PERCENT);
}
FontworkCharacterSpacingDialog::~FontworkCharacterSpacingDialog()
{
}
sal_Int32 FontworkCharacterSpacingDialog::getScale() const
{
return static_cast <sal_Int32>(m_xMtrScale->get_value(FieldUnit::PERCENT));
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=95 H=99 G=96
¤ Dauer der Verarbeitung: 0.33 Sekunden
(vorverarbeitet am 2026-10-01)
¤
*© Formatika GbR, Deutschland
2026-10-09
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126438
#Domains=1867298