diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svx/source/sidebar | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/sidebar')
55 files changed, 11560 insertions, 0 deletions
diff --git a/svx/source/sidebar/ContextChangeEventMultiplexer.cxx b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx new file mode 100644 index 000000000..ce1d5785f --- /dev/null +++ b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx @@ -0,0 +1,90 @@ +/* -*- 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 <svx/sidebar/ContextChangeEventMultiplexer.hxx> + +#include <com/sun/star/ui/ContextChangeEventObject.hpp> +#include <com/sun/star/ui/XContextChangeEventMultiplexer.hpp> +#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> +#include <com/sun/star/frame/ModuleManager.hpp> +#include <comphelper/lok.hxx> +#include <comphelper/processfactory.hxx> +#include <sfx2/lokhelper.hxx> +#include <sfx2/viewsh.hxx> + +using namespace css; +using namespace css::uno; + + +void ContextChangeEventMultiplexer::NotifyContextChange ( + const css::uno::Reference<css::frame::XController>& rxController, + const vcl::EnumContext::Context eContext) +{ + if (rxController.is() && rxController->getFrame().is()) + { + const css::ui::ContextChangeEventObject aEvent( + rxController, + GetModuleName(rxController->getFrame()), + vcl::EnumContext::GetContextName(eContext)); + + css::uno::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer ( + css::ui::ContextChangeEventMultiplexer::get( + ::comphelper::getProcessComponentContext())); + if (xMultiplexer.is()) + xMultiplexer->broadcastContextChangeEvent(aEvent, rxController); + + // notify the LOK too after all the change have taken effect. + if (comphelper::LibreOfficeKit::isActive()) + { + if (SfxViewShell* pViewShell = SfxViewShell::Get(rxController)) + SfxLokHelper::notifyContextChange(pViewShell, GetModuleName(rxController->getFrame()), vcl::EnumContext::GetContextName(eContext)); + } + } +} + + +void ContextChangeEventMultiplexer::NotifyContextChange ( + const SfxViewShell* pViewShell, + const vcl::EnumContext::Context eContext) +{ + if (pViewShell != nullptr) + NotifyContextChange(pViewShell->GetController(), eContext); +} + + +OUString ContextChangeEventMultiplexer::GetModuleName ( + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + try + { + const Reference<frame::XModuleManager> xModuleManager = + frame::ModuleManager::create( comphelper::getProcessComponentContext() ); + return xModuleManager->identify(rxFrame); + } + catch (const Exception&) + { + // An exception typically means that a context change is notified + // during initialization or destruction of a view. + // Ignore it. + } + return vcl::EnumContext::GetApplicationName( + vcl::EnumContext::Application::NONE); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/EmptyPanel.cxx b/svx/source/sidebar/EmptyPanel.cxx new file mode 100644 index 000000000..116b1c3e8 --- /dev/null +++ b/svx/source/sidebar/EmptyPanel.cxx @@ -0,0 +1,43 @@ +/* -*- 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 "EmptyPanel.hxx" + +namespace svx::sidebar { + +EmptyPanel::EmptyPanel (vcl::Window* pParent) + : PanelLayout(pParent, "EmptyPanel", "svx/ui/sidebarempty.ui", nullptr) + , mxMessageControl(m_xBuilder->weld_label("message")) +{ +} + +EmptyPanel::~EmptyPanel() +{ + disposeOnce(); +} + +void EmptyPanel::dispose() +{ + mxMessageControl.reset(); + PanelLayout::dispose(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/EmptyPanel.hxx b/svx/source/sidebar/EmptyPanel.hxx new file mode 100644 index 000000000..a2465fc9a --- /dev/null +++ b/svx/source/sidebar/EmptyPanel.hxx @@ -0,0 +1,45 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_EMPTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_EMPTYPANEL_HXX + +#include <sfx2/sidebar/PanelLayout.hxx> + +namespace svx::sidebar { + + +/** Display a panel that tells the user that the current deck is + intentionally empty. +*/ +class EmptyPanel final : public PanelLayout +{ +public: + explicit EmptyPanel (vcl::Window* pParent); + virtual ~EmptyPanel() override; + virtual void dispose() override; + +private: + std::unique_ptr<weld::Label> mxMessageControl; +}; + +} // end of namespace svx::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/PanelFactory.cxx b/svx/source/sidebar/PanelFactory.cxx new file mode 100644 index 000000000..6b8ed6573 --- /dev/null +++ b/svx/source/sidebar/PanelFactory.cxx @@ -0,0 +1,220 @@ +/* -*- 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 <config_features.h> + +#include "text/TextPropertyPanel.hxx" +#include "inspector/InspectorTextPanel.hxx" +#include "styles/StylesPropertyPanel.hxx" +#include "paragraph/ParaPropertyPanel.hxx" +#include "lists/ListsPropertyPanel.hxx" +#include "area/AreaPropertyPanel.hxx" +#include "glow/GlowPropertyPanel.hxx" +#include "shadow/ShadowPropertyPanel.hxx" +#include "softedge/SoftEdgePropertyPanel.hxx" +#include "graphic/GraphicPropertyPanel.hxx" +#include "line/LinePropertyPanel.hxx" +#include "possize/PosSizePropertyPanel.hxx" +#include <DefaultShapesPanel.hxx> +#if HAVE_FEATURE_AVMEDIA +#include "media/MediaPlaybackPanel.hxx" +#endif +#include <GalleryControl.hxx> +#include "EmptyPanel.hxx" +#include <sfx2/sidebar/SidebarPanelBase.hxx> +#include <sfx2/templdlg.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/window.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ui/XSidebar.hpp> +#include <com/sun/star/ui/XUIElementFactory.hpp> + +using namespace css; +using namespace css::uno; +using namespace svx::sidebar; + + +namespace { + +/* Why this is not used ? Doesn't it need to inherit from XServiceInfo ? +#define IMPLEMENTATION_NAME "org.apache.openoffice.comp.svx.sidebar.PanelFactory" +#define SERVICE_NAME "com.sun.star.ui.UIElementFactory" +*/ + +typedef ::cppu::WeakComponentImplHelper< css::ui::XUIElementFactory, css::lang::XServiceInfo > + PanelFactoryInterfaceBase; + +class PanelFactory + : private ::cppu::BaseMutex, + public PanelFactoryInterfaceBase +{ +public: + PanelFactory(); + PanelFactory(const PanelFactory&) = delete; + PanelFactory& operator=(const PanelFactory&) = delete; + + // XUIElementFactory + css::uno::Reference<css::ui::XUIElement> SAL_CALL createUIElement ( + const OUString& rsResourceURL, + const ::css::uno::Sequence<css::beans::PropertyValue>& rArguments) override; + + OUString SAL_CALL getImplementationName() override + { return "org.apache.openoffice.comp.svx.sidebar.PanelFactory"; } + + sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override + { return cppu::supportsService(this, ServiceName); } + + css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override + { return {"com.sun.star.ui.UIElementFactory"}; } +}; + +PanelFactory::PanelFactory() + : PanelFactoryInterfaceBase(m_aMutex) +{ +} + +Reference<ui::XUIElement> SAL_CALL PanelFactory::createUIElement ( + const OUString& rsResourceURL, + const ::css::uno::Sequence<css::beans::PropertyValue>& rArguments) +{ + const ::comphelper::NamedValueCollection aArguments (rArguments); + Reference<frame::XFrame> xFrame (aArguments.getOrDefault("Frame", Reference<frame::XFrame>())); + Reference<awt::XWindow> xParentWindow (aArguments.getOrDefault("ParentWindow", Reference<awt::XWindow>())); + Reference<ui::XSidebar> xSidebar (aArguments.getOrDefault("Sidebar", Reference<ui::XSidebar>())); + const sal_uInt64 nBindingsValue (aArguments.getOrDefault("SfxBindings", sal_uInt64(0))); + SfxBindings* pBindings = reinterpret_cast<SfxBindings*>(nBindingsValue); + + VclPtr<vcl::Window> pParentWindow = VCLUnoHelper::GetWindow(xParentWindow); + if ( ! xParentWindow.is() || pParentWindow==nullptr) + throw RuntimeException( + "PanelFactory::createUIElement called without ParentWindow", + nullptr); + if ( ! xFrame.is()) + throw RuntimeException( + "PanelFactory::createUIElement called without Frame", + nullptr); + if (pBindings == nullptr) + throw RuntimeException( + "PanelFactory::createUIElement called without SfxBindings", + nullptr); + + VclPtr<vcl::Window> pControl; + ui::LayoutSize aLayoutSize (-1,-1,-1); + + if (rsResourceURL.endsWith("/TextPropertyPanel")) + { + pControl = TextPropertyPanel::Create(pParentWindow, xFrame); + } + else if (rsResourceURL.endsWith("/InspectorTextPanel")) + { + pControl = InspectorTextPanel::Create(pParentWindow, xFrame); + } + else if (rsResourceURL.endsWith("/StylesPropertyPanel")) + { + pControl = StylesPropertyPanel::Create(pParentWindow, xFrame); + } + else if (rsResourceURL.endsWith("/ParaPropertyPanel")) + { + pControl = ParaPropertyPanel::Create(pParentWindow, xFrame, pBindings, xSidebar); + } + else if (rsResourceURL.endsWith("/ListsPropertyPanel")) + { + pControl = ListsPropertyPanel::Create(pParentWindow, xFrame); + } + else if (rsResourceURL.endsWith("/AreaPropertyPanel")) + { + pControl = AreaPropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/GlowPropertyPanel")) + { + pControl = GlowPropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/ShadowPropertyPanel")) + { + pControl = ShadowPropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/SoftEdgePropertyPanel")) + { + pControl = SoftEdgePropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/GraphicPropertyPanel")) + { + pControl = GraphicPropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/LinePropertyPanel")) + { + pControl = LinePropertyPanel::Create(pParentWindow, xFrame, pBindings); + } + else if (rsResourceURL.endsWith("/PosSizePropertyPanel")) + { + pControl = PosSizePropertyPanel::Create(pParentWindow, xFrame, pBindings, xSidebar); + } + else if (rsResourceURL.endsWith("/DefaultShapesPanel")) + { + pControl = DefaultShapesPanel::Create(pParentWindow, xFrame); + } +#if HAVE_FEATURE_AVMEDIA + else if (rsResourceURL.endsWith("/MediaPlaybackPanel")) + { + pControl = MediaPlaybackPanel::Create(pParentWindow, xFrame, pBindings); + } +#endif + else if (rsResourceURL.endsWith("/GalleryPanel")) + { + pControl.reset(VclPtr<GalleryControl>::Create(pParentWindow)); + aLayoutSize = ui::LayoutSize(300,-1,400); + } + else if (rsResourceURL.endsWith("/StyleListPanel")) + { + pControl.reset(VclPtr<SfxTemplatePanelControl>::Create(pBindings, pParentWindow)); + aLayoutSize = ui::LayoutSize(0,-1,-1); + } + else if (rsResourceURL.endsWith("/EmptyPanel")) + { + pControl.reset(VclPtr<EmptyPanel>::Create(pParentWindow)); + aLayoutSize = ui::LayoutSize(20,-1, 50); + } + + if (pControl) + { + return sfx2::sidebar::SidebarPanelBase::Create( + rsResourceURL, + xFrame, + pControl, + aLayoutSize); + } + else + return Reference<ui::XUIElement>(); +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +org_apache_openoffice_comp_svx_sidebar_PanelFactory_get_implementation( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new PanelFactory); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/SelectionAnalyzer.cxx b/svx/source/sidebar/SelectionAnalyzer.cxx new file mode 100644 index 000000000..14134980f --- /dev/null +++ b/svx/source/sidebar/SelectionAnalyzer.cxx @@ -0,0 +1,479 @@ +/* -*- 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 <svx/sidebar/SelectionAnalyzer.hxx> +#include <svx/svdmark.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdotext.hxx> +#include <svx/svdpage.hxx> + +using vcl::EnumContext; + + +namespace svx::sidebar { + +EnumContext::Context SelectionAnalyzer::GetContextForSelection_SC (const SdrMarkList& rMarkList) +{ + EnumContext::Context eContext = EnumContext::Context::Unknown; + + switch (rMarkList.GetMarkCount()) + { + case 0: + // Empty selection. Return Context::Unknown to let the caller + // substitute it with the default context. + break; + + case 1: + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + if ( dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsInEditMode() ) + { + eContext = EnumContext::Context::DrawText; + } + else + { + const SdrInventor nInv = pObj->GetObjInventor(); + const sal_uInt16 nObjId = pObj->GetObjIdentifier(); + if (nInv == SdrInventor::Default) + eContext = GetContextForObjectId_SC(nObjId); + else if (nInv == SdrInventor::FmForm) + eContext = EnumContext::Context::Form; + } + break; + } + + default: + { + // Multi selection. + switch (GetInventorTypeFromMark(rMarkList)) + { + case SdrInventor::Default: + { + const sal_uInt16 nObjId (GetObjectTypeFromMark(rMarkList)); + if (nObjId == 0) + eContext = EnumContext::Context::MultiObject; + else + eContext = GetContextForObjectId_SC(nObjId); + break; + } + + case SdrInventor::FmForm: + eContext = EnumContext::Context::Form; + break; + + case SdrInventor::Unknown: + eContext = EnumContext::Context::MultiObject; + break; + + default: break; + } + } + } + + return eContext; +} + + +EnumContext::Context SelectionAnalyzer::GetContextForSelection_SD ( + const SdrMarkList& rMarkList, + const ViewType eViewType) +{ + EnumContext::Context eContext = EnumContext::Context::Unknown; + + // Note that some cases are handled by the caller. They rely on + // sd specific data. + switch (rMarkList.GetMarkCount()) + { + case 0: + switch(eViewType) + { + case ViewType::Standard: + eContext = EnumContext::Context::DrawPage; + break; + case ViewType::Master: + eContext = EnumContext::Context::MasterPage; + break; + case ViewType::Handout: + eContext = EnumContext::Context::HandoutPage; + break; + case ViewType::Notes: + eContext = EnumContext::Context::NotesPage; + break; + } + break; + + case 1: + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + if (dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsInEditMode()) + { + if (pObj->GetObjIdentifier() == OBJ_TABLE) + { + // Let a table object take precedence over text + // edit mode. The panels for text editing are + // present for table context as well, anyway. + eContext = EnumContext::Context::Table; + } + else + eContext = EnumContext::Context::DrawText; + } + else + { + const SdrInventor nInv = pObj->GetObjInventor(); + sal_uInt16 nObjId = pObj->GetObjIdentifier(); + if (nInv == SdrInventor::Default) + { + if (nObjId == OBJ_GRUP) + { + nObjId = GetObjectTypeFromGroup(pObj); + if (nObjId == 0) + nObjId = OBJ_GRUP; + } + eContext = GetContextForObjectId_SD(nObjId, eViewType); + } + else if (nInv == SdrInventor::E3d) + { + eContext = EnumContext::Context::ThreeDObject; + } + else if (nInv == SdrInventor::FmForm) + { + eContext = EnumContext::Context::Form; + } + } + break; + } + + default: + { + switch (GetInventorTypeFromMark(rMarkList)) + { + case SdrInventor::Default: + { + const sal_uInt16 nObjId = GetObjectTypeFromMark(rMarkList); + if (nObjId == 0) + eContext = EnumContext::Context::MultiObject; + else + eContext = GetContextForObjectId_SD(nObjId, eViewType); + break; + } + + case SdrInventor::E3d: + eContext = EnumContext::Context::ThreeDObject; + break; + + case SdrInventor::FmForm: + eContext = EnumContext::Context::Form; + break; + + case SdrInventor::Unknown: + eContext = EnumContext::Context::MultiObject; + break; + + default: break; + } + break; + } + } + + return eContext; +} + + +EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SC (const sal_uInt16 nObjectId) +{ + switch (nObjectId) + { + case OBJ_CAPTION: + case OBJ_TITLETEXT: + case OBJ_OUTLINETEXT: + case OBJ_TEXT: + case OBJ_MEASURE: + case OBJ_RECT: + case OBJ_CIRC: + case OBJ_FREEFILL: + case OBJ_PATHFILL: + case OBJ_POLY: + case OBJ_SECT: + case OBJ_CARC: + case OBJ_CCUT: + case OBJ_CUSTOMSHAPE: + case OBJ_GRUP: + return EnumContext::Context::Draw; + + case OBJ_PLIN: + case OBJ_PATHLINE: + case OBJ_FREELINE: + case OBJ_LINE: + case OBJ_EDGE: + return EnumContext::Context::DrawLine; + + case OBJ_GRAF: + return EnumContext::Context::Graphic; + + case OBJ_OLE2: + return EnumContext::Context::OLE; + + case OBJ_MEDIA: + return EnumContext::Context::Media; + break; + + default: + return EnumContext::Context::Unknown; + } +} + + +EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SD ( + const sal_uInt16 nObjectId, + const ViewType eViewType) +{ + switch (nObjectId) + { + case OBJ_CAPTION: + case OBJ_MEASURE: + case OBJ_RECT: + case OBJ_CIRC: + case OBJ_FREEFILL: + case OBJ_PATHFILL: + case OBJ_POLY: + case OBJ_SECT: + case OBJ_CARC: + case OBJ_CCUT: + case OBJ_CUSTOMSHAPE: + case OBJ_GRUP: + return EnumContext::Context::Draw; + + case OBJ_EDGE: + case OBJ_PATHLINE: + case OBJ_FREELINE: + case OBJ_PLIN: + case OBJ_LINE: + return EnumContext::Context::DrawLine; + + case OBJ_TITLETEXT: + case OBJ_OUTLINETEXT: + case OBJ_TEXT: + return EnumContext::Context::TextObject; + + case OBJ_GRAF: + return EnumContext::Context::Graphic; + + case OBJ_OLE2: + return EnumContext::Context::OLE; + + case OBJ_MEDIA: + return EnumContext::Context::Media; + + case OBJ_TABLE: + return EnumContext::Context::Table; + + case OBJ_PAGE: + switch (eViewType) + { + case ViewType::Handout: + return EnumContext::Context::HandoutPage; + case ViewType::Notes: + return EnumContext::Context::NotesPage; + default: + return EnumContext::Context::Unknown; + } + + default: + return EnumContext::Context::Unknown; + } +} + + +SdrInventor SelectionAnalyzer::GetInventorTypeFromMark (const SdrMarkList& rMarkList) +{ + const size_t nMarkCount (rMarkList.GetMarkCount()); + + if (nMarkCount < 1) + return SdrInventor::Unknown; + + SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + const SdrInventor nFirstInv = pObj->GetObjInventor(); + + for (size_t nIndex=1; nIndex<nMarkCount; ++nIndex) + { + pMark = rMarkList.GetMark(nIndex); + pObj = pMark->GetMarkedSdrObj(); + const SdrInventor nInv (pObj->GetObjInventor()); + + if (nInv != nFirstInv) + return SdrInventor::Unknown; + } + + return nFirstInv; +} + + +sal_uInt16 SelectionAnalyzer::GetObjectTypeFromGroup (const SdrObject* pObj) +{ + SdrObjList* pObjList = pObj->GetSubList(); + if (pObjList) + { + const size_t nSubObjCount (pObjList->GetObjCount()); + + if (nSubObjCount>0) + { + SdrObject* pSubObj = pObjList->GetObj(0); + sal_uInt16 nResultType = pSubObj->GetObjIdentifier(); + + if (nResultType == OBJ_GRUP) + nResultType = GetObjectTypeFromGroup(pSubObj); + + if (IsShapeType(nResultType)) + nResultType = OBJ_CUSTOMSHAPE; + + if (IsTextObjType(nResultType)) + nResultType = OBJ_TEXT; + + for (size_t nIndex=1; nIndex<nSubObjCount; ++nIndex) + { + pSubObj = pObjList->GetObj(nIndex); + sal_uInt16 nType (pSubObj->GetObjIdentifier()); + + if(nType == OBJ_GRUP) + nType = GetObjectTypeFromGroup(pSubObj); + + if (IsShapeType(nType)) + nType = OBJ_CUSTOMSHAPE; + + if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT)) + nType = OBJ_TEXT; + + if (IsTextObjType(nType)) + nType = OBJ_TEXT; + + if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE)) + nResultType = OBJ_TEXT; + + if (nType != nResultType) + return 0; + } + + return nResultType; + } + } + + return 0; +} + + +sal_uInt16 SelectionAnalyzer::GetObjectTypeFromMark (const SdrMarkList& rMarkList) +{ + const size_t nMarkCount (rMarkList.GetMarkCount()); + + if (nMarkCount < 1) + return 0; + + SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + sal_uInt16 nResultType = pObj->GetObjIdentifier(); + + if(nResultType == OBJ_GRUP) + nResultType = GetObjectTypeFromGroup(pObj); + + if (IsShapeType(nResultType)) + nResultType = OBJ_CUSTOMSHAPE; + + if (IsTextObjType(nResultType)) + nResultType = OBJ_TEXT; + + for (size_t nIndex=1; nIndex<nMarkCount; ++nIndex) + { + pMark = rMarkList.GetMark(nIndex); + pObj = pMark->GetMarkedSdrObj(); + sal_uInt16 nType = pObj->GetObjIdentifier(); + + if(nType == OBJ_GRUP) + nType = GetObjectTypeFromGroup(pObj); + + if (IsShapeType(nType)) + nType = OBJ_CUSTOMSHAPE; + + if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT)) + nType = OBJ_TEXT; + + if (IsTextObjType(nType)) + nType = OBJ_TEXT; + + if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE)) + nResultType = OBJ_TEXT; + + if (nType != nResultType) + return 0; + } + + return nResultType; +} + + +bool SelectionAnalyzer::IsShapeType (const sal_uInt16 nType) +{ + switch (nType) + { + case OBJ_LINE: + case OBJ_CARC: + case OBJ_PLIN: + case OBJ_PATHLINE: + case OBJ_RECT: + case OBJ_CIRC: + case OBJ_SECT: + case OBJ_CCUT: + case OBJ_PATHFILL: + case OBJ_CUSTOMSHAPE: + case OBJ_CAPTION: + case OBJ_MEASURE: + case OBJ_EDGE: + case OBJ_POLY: + case OBJ_FREELINE: + case OBJ_FREEFILL: + + // #122145# adding OBJ_OLE2 since these also allow line/fill style and may + // be multiselected/grouped with normal draw objects, e.g. math OLE objects + case OBJ_OLE2: + return true; + + default: + return false; + } +} + + +bool SelectionAnalyzer::IsTextObjType (const sal_uInt16 nType) +{ + switch(nType) + { + case OBJ_TEXT: + case OBJ_TITLETEXT: + case OBJ_OUTLINETEXT: + return true; + + default: + return false; + } +} + + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/SelectionChangeHandler.cxx b/svx/source/sidebar/SelectionChangeHandler.cxx new file mode 100644 index 000000000..c015578e8 --- /dev/null +++ b/svx/source/sidebar/SelectionChangeHandler.cxx @@ -0,0 +1,101 @@ +/* -*- 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 <svx/sidebar/SelectionChangeHandler.hxx> +#include <svx/sidebar/ContextChangeEventMultiplexer.hxx> + +#include <com/sun/star/view/XSelectionSupplier.hpp> + +#include <vcl/EnumContext.hxx> + + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { + +SelectionChangeHandler::SelectionChangeHandler ( + const std::function<OUString()>& rSelectionChangeCallback, + const Reference<css::frame::XController>& rxController, + const vcl::EnumContext::Context eDefaultContext) + : SelectionChangeHandlerInterfaceBase(m_aMutex), + maSelectionChangeCallback(rSelectionChangeCallback), + mxController(rxController), + meDefaultContext(eDefaultContext), + mbIsConnected(false) +{ +} + + +SelectionChangeHandler::~SelectionChangeHandler() +{ +} + + +void SAL_CALL SelectionChangeHandler::selectionChanged (const lang::EventObject&) +{ + if (maSelectionChangeCallback) + { + const vcl::EnumContext::Context eContext ( + vcl::EnumContext::GetContextEnum(maSelectionChangeCallback())); + ContextChangeEventMultiplexer::NotifyContextChange( + mxController, + eContext==vcl::EnumContext::Context::Unknown + ? meDefaultContext + : eContext); + } +} + + +void SAL_CALL SelectionChangeHandler::disposing (const lang::EventObject&) +{ +} + + +void SAL_CALL SelectionChangeHandler::disposing() +{ + if (mbIsConnected) + Disconnect(); +} + + +void SelectionChangeHandler::Connect() +{ + uno::Reference<view::XSelectionSupplier> xSupplier (mxController, uno::UNO_QUERY); + if (xSupplier.is()) + { + mbIsConnected = true; + xSupplier->addSelectionChangeListener(this); + } +} + + +void SelectionChangeHandler::Disconnect() +{ + uno::Reference<view::XSelectionSupplier> xSupplier (mxController, uno::UNO_QUERY); + if (xSupplier.is()) + { + mbIsConnected = false; + xSupplier->removeSelectionChangeListener(this); + } +} + + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/area/AreaPropertyPanel.cxx b/svx/source/sidebar/area/AreaPropertyPanel.cxx new file mode 100644 index 000000000..f71754888 --- /dev/null +++ b/svx/source/sidebar/area/AreaPropertyPanel.cxx @@ -0,0 +1,149 @@ +/* -*- 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 "AreaPropertyPanel.hxx" +#include <svx/svxids.hrc> +#include <svx/xfltrit.hxx> +#include <svx/xflftrit.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> + + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { + +AreaPropertyPanel::AreaPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) + : AreaPropertyPanelBase(pParent, rxFrame), + maStyleControl(SID_ATTR_FILL_STYLE, *pBindings, *this), + maColorControl(SID_ATTR_FILL_COLOR, *pBindings, *this), + maGradientControl(SID_ATTR_FILL_GRADIENT, *pBindings, *this), + maHatchControl(SID_ATTR_FILL_HATCH, *pBindings, *this), + maBitmapControl(SID_ATTR_FILL_BITMAP, *pBindings, *this), + maGradientListControl(SID_GRADIENT_LIST, *pBindings, *this), + maHatchListControl(SID_HATCH_LIST, *pBindings, *this), + maBitmapListControl(SID_BITMAP_LIST, *pBindings, *this), + maPatternListControl(SID_PATTERN_LIST, *pBindings, *this), + maFillTransparenceController(SID_ATTR_FILL_TRANSPARENCE, *pBindings, *this), + maFillFloatTransparenceController(SID_ATTR_FILL_FLOATTRANSPARENCE, *pBindings, *this), + mpBindings(pBindings) +{ +} + +AreaPropertyPanel::~AreaPropertyPanel() +{ + disposeOnce(); +} + +void AreaPropertyPanel::dispose() +{ + maStyleControl.dispose(); + maColorControl.dispose(); + maGradientControl.dispose(); + maHatchControl.dispose(); + maBitmapControl.dispose(); + maGradientListControl.dispose(); + maHatchListControl.dispose(); + maBitmapListControl.dispose(); + maPatternListControl.dispose(); + maFillTransparenceController.dispose(); + maFillFloatTransparenceController.dispose(); + + AreaPropertyPanelBase::dispose(); +} + +VclPtr<vcl::Window> AreaPropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to AreaPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to AreaPropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to AreaPropertyPanel::Create", nullptr, 2); + + return VclPtr<AreaPropertyPanel>::Create( + pParent, + rxFrame, + pBindings); +} + +void AreaPropertyPanel::setFillTransparence(const XFillTransparenceItem& rItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_TRANSPARENCE, + SfxCallMode::RECORD, { &rItem }); +} + +void AreaPropertyPanel::setFillFloatTransparence(const XFillFloatTransparenceItem& rItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_FLOATTRANSPARENCE, + SfxCallMode::RECORD, { &rItem }); +} + +void AreaPropertyPanel::setFillStyle(const XFillStyleItem& rItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_STYLE, + SfxCallMode::RECORD, { &rItem }); +} + +void AreaPropertyPanel::setFillStyleAndColor(const XFillStyleItem* pStyleItem, + const XFillColorItem& rColorItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_COLOR, + SfxCallMode::RECORD, pStyleItem + ? std::initializer_list<SfxPoolItem const*>{ &rColorItem, pStyleItem } + : std::initializer_list<SfxPoolItem const*>{ &rColorItem }); +} + +void AreaPropertyPanel::setFillStyleAndGradient(const XFillStyleItem* pStyleItem, + const XFillGradientItem& rGradientItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_GRADIENT, + SfxCallMode::RECORD, pStyleItem + ? std::initializer_list<SfxPoolItem const*>{ &rGradientItem, pStyleItem } + : std::initializer_list<SfxPoolItem const*>{ &rGradientItem }); +} + +void AreaPropertyPanel::setFillStyleAndHatch(const XFillStyleItem* pStyleItem, + const XFillHatchItem& rHatchItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_HATCH, + SfxCallMode::RECORD, pStyleItem + ? std::initializer_list<SfxPoolItem const*>{ &rHatchItem, pStyleItem } + : std::initializer_list<SfxPoolItem const*>{ &rHatchItem }); +} + +void AreaPropertyPanel::setFillStyleAndBitmap(const XFillStyleItem* pStyleItem, + const XFillBitmapItem& rBitmapItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_BITMAP, + SfxCallMode::RECORD, pStyleItem + ? std::initializer_list<SfxPoolItem const*>{ &rBitmapItem, pStyleItem } + : std::initializer_list<SfxPoolItem const*>{ &rBitmapItem }); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/area/AreaPropertyPanel.hxx b/svx/source/sidebar/area/AreaPropertyPanel.hxx new file mode 100644 index 000000000..fb97c00b3 --- /dev/null +++ b/svx/source/sidebar/area/AreaPropertyPanel.hxx @@ -0,0 +1,93 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_AREA_AREAPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_AREA_AREAPROPERTYPANEL_HXX + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xflclit.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xbtmpit.hxx> + +#include <svx/sidebar/AreaPropertyPanelBase.hxx> + +class XFillFloatTransparenceItem; +class XFillTransparenceItem; +class XFillStyleItem; +class XFillGradientItem; +class XFillColorItem; +class XFillHatchItem; +class XFillBitmapItem; + +namespace svx::sidebar { + +class AreaTransparencyGradientControl; + +class AreaPropertyPanel : public AreaPropertyPanelBase +{ +public: + virtual void dispose() override; + + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + SfxBindings* GetBindings() { return mpBindings;} + + // constructor/destructor + AreaPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual ~AreaPropertyPanel() override; + + virtual void setFillTransparence(const XFillTransparenceItem& rItem) override; + virtual void setFillFloatTransparence(const XFillFloatTransparenceItem& rItem) override; + virtual void setFillStyle(const XFillStyleItem& rItem) override; + virtual void setFillStyleAndColor(const XFillStyleItem* pStyleItem, const XFillColorItem& aColorItem) override; + virtual void setFillStyleAndGradient(const XFillStyleItem* pStyleItem, const XFillGradientItem& aGradientItem) override; + virtual void setFillStyleAndHatch(const XFillStyleItem* pStyleItem, const XFillHatchItem& aHatchItem) override; + virtual void setFillStyleAndBitmap(const XFillStyleItem* pStyleItem, const XFillBitmapItem& aHatchItem) override; + +private: + ::sfx2::sidebar::ControllerItem maStyleControl; + ::sfx2::sidebar::ControllerItem maColorControl; + ::sfx2::sidebar::ControllerItem maGradientControl; + ::sfx2::sidebar::ControllerItem maHatchControl; + ::sfx2::sidebar::ControllerItem maBitmapControl; + ::sfx2::sidebar::ControllerItem maGradientListControl; + ::sfx2::sidebar::ControllerItem maHatchListControl; + ::sfx2::sidebar::ControllerItem maBitmapListControl; + ::sfx2::sidebar::ControllerItem maPatternListControl; + ::sfx2::sidebar::ControllerItem maFillTransparenceController; + ::sfx2::sidebar::ControllerItem maFillFloatTransparenceController; + + SfxBindings* mpBindings; +}; + + +} // end of namespace svx::sidebar + + +#endif // INCLUDED_SVX_SOURCE_SIDEBAR_AREA_AREAPROPERTYPANEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/area/AreaPropertyPanelBase.cxx b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx new file mode 100644 index 000000000..f83e9bafd --- /dev/null +++ b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx @@ -0,0 +1,1441 @@ +/* -*- 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 <osl/diagnose.h> +#include <svx/sidebar/AreaPropertyPanelBase.hxx> +#include <svx/drawitem.hxx> +#include <svx/svxids.hrc> +#include <sfx2/objsh.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xtable.hxx> +#include <sfx2/opengrf.hxx> +#include <sfx2/weldutils.hxx> +#include <tools/urlobj.hxx> +#include <bitmaps.hlst> + +using namespace css; +using namespace css::uno; + +const char SIDEBARGRADIENT[] = "sidebargradient"; + +namespace svx::sidebar { + +namespace { + +enum eFillStyle +{ + NONE, + SOLID, + GRADIENT, + HATCH, + BITMAP, + PATTERN +}; + +} + +const sal_Int32 AreaPropertyPanelBase::DEFAULT_CENTERX = 50; +const sal_Int32 AreaPropertyPanelBase::DEFAULT_CENTERY = 50; +const sal_Int32 AreaPropertyPanelBase::DEFAULT_ANGLE = 0; +const sal_Int32 AreaPropertyPanelBase::DEFAULT_STARTVALUE = 0; +const sal_Int32 AreaPropertyPanelBase::DEFAULT_ENDVALUE = 16777215; +const sal_Int32 AreaPropertyPanelBase::DEFAULT_BORDER = 0; + +AreaPropertyPanelBase::AreaPropertyPanelBase( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) + : PanelLayout(pParent, "AreaPropertyPanel", "svx/ui/sidebararea.ui", rxFrame), + meLastXFS(static_cast<sal_uInt16>(-1)), + mnLastPosHatch(0), + mnLastPosBitmap(0), + mnLastPosPattern(0), + mnLastTransSolid(50), + maGradientLinear(), + maGradientAxial(), + maGradientRadial(), + maGradientElliptical(), + maGradientSquare(), + maGradientRect(), + mxColorTextFT(m_xBuilder->weld_label("filllabel")), + mxLbFillType(m_xBuilder->weld_combo_box("fillstylearea")), + mxLbFillAttr(m_xBuilder->weld_combo_box("fillattrhb")), + mxLbFillGradFrom(new ColorListBox(m_xBuilder->weld_menu_button("fillgrad1"), GetFrameWeld())), + mxLbFillGradTo(new ColorListBox(m_xBuilder->weld_menu_button("fillgrad2"), GetFrameWeld())), + mxToolBoxColor(m_xBuilder->weld_toolbar("selectcolor")), + mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor, *m_xBuilder, rxFrame)), + mxTrspTextFT(m_xBuilder->weld_label("transparencylabel")), + mxLBTransType(m_xBuilder->weld_combo_box("transtype")), + mxMTRTransparent(m_xBuilder->weld_metric_spin_button("settransparency", FieldUnit::PERCENT)), + mxSldTransparent(m_xBuilder->weld_scale("transparencyslider")), + mxBTNGradient(m_xBuilder->weld_toolbar("selectgradient")), + mxMTRAngle(m_xBuilder->weld_metric_spin_button("gradangle", FieldUnit::DEGREE)), + mxGradientStyle(m_xBuilder->weld_combo_box("gradientstyle")), + mxBmpImport(m_xBuilder->weld_button("bmpimport")), + mpStyleItem(), + mpColorItem(), + mpFillGradientItem(), + mpHatchItem(), + mpBitmapItem(), + maImgAxial(BMP_AXIAL), + maImgElli(BMP_ELLI), + maImgQuad(BMP_QUAD), + maImgRadial(BMP_RADIAL), + maImgSquare(BMP_SQUARE), + maImgLinear(BMP_LINEAR), + mpFloatTransparenceItem(), + mpTransparanceItem() +{ + mpPanel = dynamic_cast<sfx2::sidebar::Panel*>(pParent); + + Initialize(); +} + +AreaPropertyPanelBase::~AreaPropertyPanelBase() +{ + disposeOnce(); +} + +void AreaPropertyPanelBase::dispose() +{ + mxTrGrPopup.reset(); + mxColorTextFT.reset(); + mxLbFillType.reset(); + mxLbFillAttr.reset(); + mxColorDispatch.reset(); + mxToolBoxColor.reset(); + mxTrspTextFT.reset(); + mxLBTransType.reset(); + mxMTRTransparent.reset(); + mxSldTransparent.reset(); + mxBTNGradient.reset(); + mxMTRAngle.reset(); + mxLbFillGradFrom.reset(); + mxLbFillGradTo.reset(); + mxGradientStyle.reset(); + mxBmpImport.reset(); + mpPanel.clear(); + + PanelLayout::dispose(); +} + +void AreaPropertyPanelBase::Initialize() +{ + SvxFillTypeBox::Fill(*mxLbFillType); + + mxLbFillAttr->set_size_request(42, -1); + + maGradientLinear.SetXOffset(DEFAULT_CENTERX); + maGradientLinear.SetYOffset(DEFAULT_CENTERY); + maGradientLinear.SetAngle(DEFAULT_ANGLE); + maGradientLinear.SetStartColor(Color(DEFAULT_STARTVALUE)); + maGradientLinear.SetEndColor(Color(DEFAULT_ENDVALUE)); + maGradientLinear.SetBorder(DEFAULT_BORDER); + maGradientLinear.SetGradientStyle(css::awt::GradientStyle_LINEAR); + + maGradientAxial = maGradientLinear; + maGradientAxial.SetGradientStyle(css::awt::GradientStyle_AXIAL); + + maGradientRadial = maGradientLinear; + maGradientRadial.SetGradientStyle(css::awt::GradientStyle_RADIAL); + + maGradientElliptical = maGradientLinear; + maGradientElliptical.SetGradientStyle(css::awt::GradientStyle_ELLIPTICAL); + + maGradientSquare = maGradientLinear; + maGradientSquare.SetGradientStyle(css::awt::GradientStyle_SQUARE); + + maGradientRect = maGradientLinear; + maGradientRect.SetGradientStyle(css::awt::GradientStyle_RECT); + + + mxLbFillType->connect_changed( LINK( this, AreaPropertyPanelBase, SelectFillTypeHdl ) ); + + Link<weld::ComboBox&,void> aLink = LINK( this, AreaPropertyPanelBase, SelectFillAttrHdl ); + mxLbFillAttr->connect_changed( aLink ); + mxGradientStyle->connect_changed( aLink ); + Link<ColorListBox&,void> aLink3 = LINK( this, AreaPropertyPanelBase, SelectFillColorHdl ); + mxLbFillGradFrom->SetSelectHdl( aLink3 ); + mxLbFillGradTo->SetSelectHdl( aLink3 ); + mxMTRAngle->connect_value_changed(LINK(this,AreaPropertyPanelBase, ChangeGradientAngle)); + + // https://gerrit.libreoffice.org/c/core/+/87313 set a small width to force widgets to + // take their final width from other widgets in the grid + mxLbFillGradFrom->get_widget().set_size_request(42, -1); + mxLbFillGradTo->get_widget().set_size_request(42, -1); + + mxLBTransType->connect_changed(LINK(this, AreaPropertyPanelBase, ChangeTrgrTypeHdl_Impl)); + + SetTransparency( 50 ); + mxMTRTransparent->connect_value_changed(LINK(this, AreaPropertyPanelBase, ModifyTransparentHdl_Impl)); + mxSldTransparent->connect_value_changed(LINK(this, AreaPropertyPanelBase, ModifyTransSliderHdl)); + + mxTrGrPopup = std::make_unique<AreaTransparencyGradientPopup>(*this, mxBTNGradient.get()); + + mxBTNGradient->set_item_popover(SIDEBARGRADIENT, mxTrGrPopup->getTopLevel()); + mxBTNGradient->connect_clicked(LINK(this, AreaPropertyPanelBase, ToolbarHdl_Impl)); + + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgLinear); + mxBTNGradient->hide(); + mxBmpImport->connect_clicked( LINK(this, AreaPropertyPanelBase, ClickImportBitmapHdl)); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ToolbarHdl_Impl, const OString&, void) +{ + mxBTNGradient->set_menu_item_active(SIDEBARGRADIENT, !mxBTNGradient->get_menu_item_active(SIDEBARGRADIENT)); +} + +void AreaPropertyPanelBase::SetTransparency(sal_uInt16 nVal) +{ + mxSldTransparent->set_value(nVal); + mxMTRTransparent->set_value(nVal, FieldUnit::PERCENT); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ClickImportBitmapHdl, weld::Button&, void) +{ + SvxOpenGraphicDialog aDlg("Import", GetFrameWeld()); + aDlg.EnableLink(false); + if( aDlg.Execute() == ERRCODE_NONE ) + { + Graphic aGraphic; + EnterWait(); + ErrCode nError = aDlg.GetGraphic( aGraphic ); + LeaveWait(); + if( nError == ERRCODE_NONE ) + { + XBitmapListRef pList = SfxObjectShell::Current()->GetItem(SID_BITMAP_LIST)->GetBitmapList(); + INetURLObject aURL( aDlg.GetPath() ); + OUString aFileName = aURL.GetLastName().getToken(0, '.'); + OUString aName = aFileName; + long j = 1; + bool bValidBitmapName = false; + while( !bValidBitmapName ) + { + bValidBitmapName = true; + for( long i = 0; i < pList->Count() && bValidBitmapName; i++ ) + { + if( aName == pList->GetBitmap(i)->GetName() ) + { + bValidBitmapName = false; + aName = aFileName + OUString::number(j++); + } + } + } + + pList->Insert(std::make_unique<XBitmapEntry>(aGraphic, aName)); + pList->Save(); + mxLbFillAttr->clear(); + SvxFillAttrBox::Fill(*mxLbFillAttr, pList); + mxLbFillAttr->set_active_text(aName); + SelectFillAttrHdl(*mxLbFillAttr); + } + } +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, SelectFillTypeHdl, weld::ComboBox&, void) +{ + sal_Int32 nPos = static_cast<eFillStyle>(mxLbFillType->get_active()); + mxLbFillAttr->clear(); + SfxObjectShell* pSh = SfxObjectShell::Current(); + if(!pSh) + return; + + // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE + // and one for setting the fill attribute itself, but add two SfxPoolItems to the + // call to get just one action at the SdrObject and to create only one Undo action, too. + // Checked that this works in all apps. + switch( nPos ) + { + default: + case NONE: + { + mxLbFillAttr->show(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxGradientStyle->hide(); + mxMTRAngle->hide(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + mxLbFillAttr->set_sensitive(false); + + // #i122676# need to call a single SID_ATTR_FILL_STYLE change + setFillStyle(XFillStyleItem(drawing::FillStyle_NONE)); + break; + } + case SOLID: + { + mxLbFillAttr->hide(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxGradientStyle->hide(); + mxMTRAngle->hide(); + mxBmpImport->hide(); + mxToolBoxColor->show(); + const OUString aTmpStr; + const Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO; + const XFillColorItem aXFillColorItem( aTmpStr, aColor ); + + // #i122676# change FillStyle and Color in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_SOLID); + setFillStyleAndColor(&aXFillStyleItem, aXFillColorItem); + break; + } + case GRADIENT: + { + mxLbFillAttr->hide(); + mxLbFillGradFrom->show(); + mxLbFillGradTo->show(); + mxGradientStyle->show(); + mxMTRAngle->show(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + + mxLbFillAttr->set_sensitive(true); + mxLbFillGradTo->set_sensitive(true); + mxLbFillGradFrom->set_sensitive(true); + mxGradientStyle->set_sensitive(true); + mxMTRAngle->set_sensitive(true); + mxLbFillAttr->clear(); + + const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST); + + if(0 < pItem->GetGradientList()->Count()) + { + const XGradient aGradient = pItem->GetGradientList()->GetGradient(0)->GetGradient(); + const OUString aName = pItem->GetGradientList()->GetGradient(0)->GetName(); + const XFillGradientItem aXFillGradientItem(aName, aGradient); + + // #i122676# change FillStyle and Gradient in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_GRADIENT); + setFillStyleAndGradient(&aXFillStyleItem, aXFillGradientItem); + mxLbFillGradFrom->SelectEntry(aGradient.GetStartColor()); + mxLbFillGradTo->SelectEntry(aGradient.GetEndColor()); + + mxMTRAngle->set_value(aGradient.GetAngle() / 10, FieldUnit::DEGREE); + css::awt::GradientStyle eXGS = aGradient.GetGradientStyle(); + mxGradientStyle->set_active(sal::static_int_cast< sal_Int32 >( eXGS )); + } + break; + } + case HATCH: + { + mxLbFillAttr->show(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + + const SvxHatchListItem* pItem( pSh->GetItem(SID_HATCH_LIST) ); + if(pItem) + { + const XHatchListRef& pXHatchList(pItem->GetHatchList()); + mxLbFillAttr->set_sensitive(true); + mxLbFillAttr->clear(); + SvxFillAttrBox::Fill(*mxLbFillAttr, pXHatchList); + + if (mnLastPosHatch != -1) + { + if(mnLastPosHatch < pXHatchList->Count()) + { + const XHatch aHatch = pXHatchList->GetHatch(mnLastPosHatch)->GetHatch(); + const OUString aName = pXHatchList->GetHatch(mnLastPosHatch)->GetName(); + const XFillHatchItem aXFillHatchItem(aName, aHatch); + + // #i122676# change FillStyle and Hatch in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_HATCH); + setFillStyleAndHatch(&aXFillStyleItem, aXFillHatchItem); + mxLbFillAttr->set_active(mnLastPosHatch); + } + } + } + else + { + mxLbFillAttr->set_sensitive(false); + } + break; + } + case BITMAP: + case PATTERN: + { + mxLbFillAttr->show(); + mxLbFillAttr->set_sensitive(true); + mxLbFillAttr->clear(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + mxToolBoxColor->hide(); + + OUString aName; + GraphicObject aBitmap; + if(nPos == static_cast< sal_Int32 >(BITMAP)) + { + mxBmpImport->show(); + const SvxBitmapListItem* pItem = pSh->GetItem(SID_BITMAP_LIST); + if(pItem) + { + const XBitmapListRef& pXBitmapList(pItem->GetBitmapList()); + SvxFillAttrBox::Fill(*mxLbFillAttr, pXBitmapList); + + if (mnLastPosBitmap != -1) + { + if(mnLastPosBitmap < pXBitmapList->Count()) + { + const XBitmapEntry* pXBitmapEntry = pXBitmapList->GetBitmap(mnLastPosBitmap); + aBitmap = pXBitmapEntry->GetGraphicObject(); + aName = pXBitmapEntry->GetName(); + mxLbFillAttr->set_active(mnLastPosBitmap); + } + } + } + else + { + mxLbFillAttr->hide(); + } + } + else if(nPos == static_cast< sal_Int32 >(PATTERN)) + { + mxBmpImport->hide(); + const SvxPatternListItem* pItem = pSh->GetItem(SID_PATTERN_LIST); + if(pItem) + { + const XPatternListRef& pXPatternList(pItem->GetPatternList()); + SvxFillAttrBox::Fill(*mxLbFillAttr, pXPatternList); + + if (mnLastPosPattern != -1) + { + if(mnLastPosPattern < pXPatternList->Count()) + { + const XBitmapEntry* pXPatternEntry = pXPatternList->GetBitmap(mnLastPosPattern); + aBitmap = pXPatternEntry->GetGraphicObject(); + aName = pXPatternEntry->GetName(); + mxLbFillAttr->set_active(mnLastPosPattern); + } + } + } + else + { + mxLbFillAttr->hide(); + } + } + const XFillBitmapItem aXFillBitmapItem( aName, aBitmap ); + const XFillStyleItem aXFillStyleItem(drawing::FillStyle_BITMAP); + setFillStyleAndBitmap(&aXFillStyleItem, aXFillBitmapItem); + break; + } + } + + meLastXFS = static_cast<sal_uInt16>(nPos); + + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, SelectFillColorHdl, ColorListBox&, void) +{ + SelectFillAttrHdl_Impl(); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, SelectFillAttrHdl, weld::ComboBox&, void) +{ + SelectFillAttrHdl_Impl(); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ChangeGradientAngle, weld::MetricSpinButton&, void) +{ + SelectFillAttrHdl_Impl(); +} + +void AreaPropertyPanelBase::DataChanged( + const DataChangedEvent& /*rEvent*/) +{ +} + +void AreaPropertyPanelBase::SelectFillAttrHdl_Impl() +{ + sal_Int32 nPosFillStyle = static_cast<eFillStyle>(mxLbFillType->get_active()); + SfxObjectShell* pSh = SfxObjectShell::Current(); + + // #i122676# dependent from bFillStyleChange, do execute a single or two + // changes in one Execute call + const bool bFillStyleChange(static_cast<eFillStyle>(meLastXFS) != static_cast<eFillStyle>(nPosFillStyle)); + + switch(nPosFillStyle) + { + case eFillStyle::NONE: + { + if(bFillStyleChange) + { + XFillStyleItem aXFillStyleItem(drawing::FillStyle_NONE); + setFillStyle(aXFillStyleItem); + } + break; + } + case eFillStyle::SOLID: + { + if(bFillStyleChange) + { + // #i122676# Single FillStyle change call needed here + XFillStyleItem aXFillStyleItem(drawing::FillStyle_SOLID); + setFillStyle(aXFillStyleItem); + } + break; + } + case eFillStyle::GRADIENT: + { + + if(pSh && pSh->GetItem(SID_COLOR_TABLE)) + { + XGradient aGradient; + aGradient.SetAngle(mxMTRAngle->get_value(FieldUnit::DEGREE) * 10); + aGradient.SetGradientStyle(static_cast<css::awt::GradientStyle>(mxGradientStyle->get_active())); + aGradient.SetStartColor(mxLbFillGradFrom->GetSelectEntryColor()); + aGradient.SetEndColor(mxLbFillGradTo->GetSelectEntryColor()); + + const XFillGradientItem aXFillGradientItem(mxLbFillAttr->get_active_text(), aGradient); + + // #i122676# Change FillStyle and Gradient in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_GRADIENT); + setFillStyleAndGradient(bFillStyleChange ? &aXFillStyleItem : nullptr, aXFillGradientItem); + } + break; + } + case eFillStyle::HATCH: + { + sal_Int32 nPos = mxLbFillAttr->get_active(); + + if (nPos == -1) + { + nPos = mnLastPosHatch; + } + + if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST)) + { + const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST); + + if(nPos < pItem->GetHatchList()->Count()) + { + const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch(); + const XFillHatchItem aXFillHatchItem( mxLbFillAttr->get_active_text(), aHatch); + + // #i122676# Change FillStyle and Hatch in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_HATCH); + setFillStyleAndHatch(bFillStyleChange ? &aXFillStyleItem : nullptr, aXFillHatchItem); + } + } + + if (nPos != -1) + { + mnLastPosHatch = nPos; + } + break; + } + case eFillStyle::BITMAP: + { + sal_Int32 nPos = mxLbFillAttr->get_active(); + + if (nPos == -1) + { + nPos = mnLastPosBitmap; + } + + if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST)) + { + const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST); + + if(nPos < pItem->GetBitmapList()->Count()) + { + const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos); + const XFillBitmapItem aXFillBitmapItem(mxLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject()); + + // #i122676# Change FillStyle and Bitmap in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_BITMAP); + setFillStyleAndBitmap(bFillStyleChange ? &aXFillStyleItem : nullptr, aXFillBitmapItem); + } + } + + if (nPos != -1) + { + mnLastPosBitmap = nPos; + } + break; + } + case eFillStyle::PATTERN: + { + sal_Int32 nPos = mxLbFillAttr->get_active(); + + if (nPos == -1) + { + nPos = mnLastPosPattern; + } + + if (nPos != -1 && pSh && pSh->GetItem(SID_PATTERN_LIST)) + { + const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST); + + if(nPos < pItem->GetPatternList()->Count()) + { + const XBitmapEntry* pXPatternEntry = pItem->GetPatternList()->GetBitmap(nPos); + const XFillBitmapItem aXFillBitmapItem(mxLbFillAttr->get_active_text(), pXPatternEntry->GetGraphicObject()); + + // #i122676# Change FillStyle and Bitmap in one call + XFillStyleItem aXFillStyleItem(drawing::FillStyle_BITMAP); + setFillStyleAndBitmap(bFillStyleChange ? &aXFillStyleItem : nullptr, aXFillBitmapItem); + } + } + + if (nPos != -1) + { + mnLastPosPattern = nPos; + } + break; + } + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::ImpUpdateTransparencies() +{ + if(mpTransparanceItem || mpFloatTransparenceItem) + { + bool bZeroValue(false); + + if (mpTransparanceItem) + { + const sal_uInt16 nValue(mpTransparanceItem->GetValue()); + + if(!nValue) + { + bZeroValue = true; + } + else if(nValue <= 100) + { + mxLBTransType->set_sensitive(true); + mxTrspTextFT->set_sensitive(true); + mxLBTransType->set_active(1); + mxBTNGradient->hide(); + mxMTRTransparent->show(); + mxSldTransparent->show(); + mxMTRTransparent->set_sensitive(true); + mxSldTransparent->set_sensitive(true); + SetTransparency(nValue); + } + + if (!bZeroValue && mxTrGrPopup) + { + mxBTNGradient->set_menu_item_active(SIDEBARGRADIENT, false); + } + } + + if(bZeroValue && mpFloatTransparenceItem) + { + if(mpFloatTransparenceItem->IsEnabled()) + { + const XGradient& rGradient = mpFloatTransparenceItem->GetGradientValue(); + sal_Int32 nEntryPos(0); + OUString* pImage = nullptr; + + mxLBTransType->set_sensitive(true); + mxTrspTextFT->set_sensitive(true); + mxMTRTransparent->hide(); + mxSldTransparent->hide(); + mxBTNGradient->set_sensitive(true); + mxBTNGradient->show(); + + switch(rGradient.GetGradientStyle()) + { + default: + case css::awt::GradientStyle_LINEAR: + { + nEntryPos = 2; + pImage = &maImgLinear; + break; + } + case css::awt::GradientStyle_AXIAL: + { + nEntryPos = 3; + pImage = &maImgAxial; + break; + } + case css::awt::GradientStyle_RADIAL: + { + nEntryPos = 4; + pImage = &maImgRadial; + break; + } + case css::awt::GradientStyle_ELLIPTICAL: + { + nEntryPos = 5; + pImage = &maImgElli; + break; + } + case css::awt::GradientStyle_SQUARE: + { + nEntryPos = 6; + pImage = &maImgQuad; + break; + } + case css::awt::GradientStyle_RECT: + { + nEntryPos = 7; + pImage = &maImgSquare; + break; + } + } + mxLBTransType->set_active(nEntryPos); + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, *pImage); + mxTrGrPopup->Rearrange(mpFloatTransparenceItem.get()); + bZeroValue = false; + } + else + { + bZeroValue = true; + } + } + + if(bZeroValue) + { + mxLBTransType->set_sensitive(true); + mxTrspTextFT->set_sensitive(true); + mxLBTransType->set_active(0); + mxBTNGradient->hide(); + mxMTRTransparent->set_sensitive(true); + mxSldTransparent->set_sensitive(true); + mxMTRTransparent->show(); + mxSldTransparent->show(); + SetTransparency(0); + } + } + else + { + // no transparency at all + mxLBTransType->set_active(-1); + mxLBTransType->set_sensitive(false); + mxTrspTextFT->set_sensitive(false); + mxMTRTransparent->set_sensitive(false); + mxSldTransparent->set_sensitive(false); + mxMTRTransparent->show(); + mxSldTransparent->show(); + mxBTNGradient->set_sensitive(false); + mxBTNGradient->hide(); + } +} + +void AreaPropertyPanelBase::updateFillTransparence(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDisabled) + { + mpTransparanceItem.reset(); + return; + } + else if (bDefaultOrSet) + { + if (pState) + { + const SfxUInt16Item* pItem = static_cast<const SfxUInt16Item*>(pState); + mpTransparanceItem.reset(pItem->Clone()); + } + else + { + mpTransparanceItem.reset(); + } + } + else + { + mpTransparanceItem.reset(); + } + + // update transparency settings dependent of mpTransparanceItem and mpFloatTransparenceItem + ImpUpdateTransparencies(); +} + +void AreaPropertyPanelBase::updateFillFloatTransparence(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDisabled) + { + mpFloatTransparenceItem.reset(); + return; + } + + if (bDefaultOrSet) + { + if (pState) + { + const XFillFloatTransparenceItem* pItem = static_cast<const XFillFloatTransparenceItem*>(pState); + mpFloatTransparenceItem.reset(pItem->Clone()); + } + else + { + mpFloatTransparenceItem.reset(); + } + } + else + { + mpFloatTransparenceItem.reset(); + } + + // update transparency settings dependent of mpTransparanceItem and mpFloatTransparenceItem + ImpUpdateTransparencies(); +} + +void AreaPropertyPanelBase::updateFillStyle(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if(bDisabled) + { + mxLbFillType->set_sensitive(false); + mxColorTextFT->set_sensitive(false); + mxLbFillType->set_active(-1); + mxLbFillAttr->show(); + mxLbFillAttr->set_sensitive(false); + mxLbFillAttr->set_active(-1); + mxToolBoxColor->hide(); + meLastXFS = static_cast<sal_uInt16>(-1); + mpStyleItem.reset(); + } + else if (bDefaultOrSet && pState) + { + const XFillStyleItem* pItem = static_cast<const XFillStyleItem*>(pState); + mpStyleItem.reset(pItem->Clone()); + mxLbFillType->set_sensitive(true); + mxColorTextFT->set_sensitive(true); + drawing::FillStyle eXFS = mpStyleItem->GetValue(); + eFillStyle nPos = NONE; + switch(eXFS) + { + default: + case drawing::FillStyle_NONE: + { + mxLbFillAttr->set_active(-1); + mxLbFillAttr->set_sensitive(false); + nPos = NONE; + break; + } + case drawing::FillStyle_SOLID: + nPos = SOLID; + break; + case drawing::FillStyle_GRADIENT: + nPos = GRADIENT; + break; + case drawing::FillStyle_HATCH: + nPos = HATCH; + break; + case drawing::FillStyle_BITMAP: + { + if(mpBitmapItem) + { + if(!mpBitmapItem->isPattern()) + nPos = BITMAP; + else + nPos = PATTERN; + } + else + nPos = BITMAP; + break; + } + } + meLastXFS = static_cast< sal_uInt16 >(mxLbFillType->get_active()); + mxLbFillType->set_active(static_cast< sal_Int32 >(nPos)); + Update(); + return; + } + + mxLbFillType->set_active(-1); + mxLbFillAttr->show(); + mxLbFillAttr->set_sensitive(false); + mxLbFillAttr->set_active(-1); + mxToolBoxColor->hide(); + meLastXFS = static_cast<sal_uInt16>(-1); + mpStyleItem.reset(); + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::updateFillGradient(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDefaultOrSet) + { + const XFillGradientItem* pItem = static_cast<const XFillGradientItem*>(pState); + mpFillGradientItem.reset(pItem ? pItem->Clone() : nullptr); + } + + if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue()) + { + mxLbFillAttr->hide(); + mxLbFillGradFrom->show(); + mxLbFillGradTo->show(); + mxMTRAngle->show(); + mxGradientStyle->show(); + mxToolBoxColor->hide(); + + if (bDefaultOrSet) + { + mxLbFillType->set_active(GRADIENT); + Update(); + } + else if(bDisabled) + { + mxLbFillGradFrom->SetNoSelection(); + mxLbFillGradTo->SetNoSelection(); + mxLbFillGradFrom->set_sensitive(false); + mxLbFillGradTo->set_sensitive(false); + mxMTRAngle->set_sensitive(false); + mxGradientStyle->set_sensitive(false); + } + else + { + mxLbFillGradFrom->SetNoSelection(); + mxLbFillGradTo->SetNoSelection(); + } + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::updateFillHatch(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDefaultOrSet) + { + const XFillHatchItem* pItem = static_cast<const XFillHatchItem*>(pState); + mpHatchItem.reset(pItem ? pItem->Clone() : nullptr); + } + + if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue()) + { + mxLbFillAttr->show(); + mxToolBoxColor->hide(); + + if (bDefaultOrSet) + { + mxLbFillAttr->set_sensitive(true); + mxLbFillType->set_active(HATCH); + Update(); + } + else if(bDisabled) + { + mxLbFillAttr->set_sensitive(false); + mxLbFillAttr->set_active(-1); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::updateFillColor(bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDefaultOrSet) + { + const XFillColorItem* pItem = static_cast<const XFillColorItem*>(pState); + mpColorItem.reset(pItem ? pItem->Clone() : nullptr); + } + + if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue()) + { + mxLbFillAttr->hide(); + mxToolBoxColor->show(); + mxLbFillType->set_active(SOLID); + Update(); + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::updateFillBitmap(bool bDisabled, bool bDefaultOrSet, const SfxPoolItem* pState) +{ + if (bDefaultOrSet) + { + const XFillBitmapItem* pItem = static_cast<const XFillBitmapItem*>(pState); + mpBitmapItem.reset(pItem ? pItem->Clone() : nullptr); + } + + if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue()) + { + mxLbFillAttr->show(); + mxToolBoxColor->hide(); + + if (bDefaultOrSet) + { + if(mpBitmapItem->isPattern()) + mxLbFillType->set_active(PATTERN); + else + mxLbFillType->set_active(BITMAP); + Update(); + } + else if(bDisabled) + { + mxLbFillAttr->hide(); + mxLbFillAttr->set_active(-1); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +void AreaPropertyPanelBase::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + const bool bDisabled(SfxItemState::DISABLED == eState); + const bool bDefaultOrSet(SfxItemState::DEFAULT <= eState); + const bool bDefault(SfxItemState::DEFAULT == eState); + + switch(nSID) + { + case SID_ATTR_FILL_TRANSPARENCE: + updateFillTransparence(bDisabled, bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_FLOATTRANSPARENCE: + updateFillFloatTransparence(bDisabled, bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_STYLE: + updateFillStyle(bDisabled, bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_COLOR: + updateFillColor(bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_GRADIENT: + updateFillGradient(bDisabled, bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_HATCH: + updateFillHatch(bDisabled, bDefaultOrSet, pState); + break; + case SID_ATTR_FILL_BITMAP: + updateFillBitmap(bDisabled, bDefaultOrSet, pState); + break; + case SID_GRADIENT_LIST: + { + if(bDefault) + { + if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue()) + { + if(mpFillGradientItem) + { + const OUString aString( mpFillGradientItem->GetName() ); + const SfxObjectShell* pSh = SfxObjectShell::Current(); + + mxLbFillAttr->clear(); + mxLbFillAttr->set_sensitive(true); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList()); + mxLbFillAttr->set_active_text(aString); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + } + break; + } + case SID_HATCH_LIST: + { + if(bDefault) + { + if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue()) + { + if(mpHatchItem) + { + const OUString aString( mpHatchItem->GetName() ); + const SfxObjectShell* pSh = SfxObjectShell::Current(); + + mxLbFillAttr->clear(); + mxLbFillAttr->set_sensitive(true); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList()); + mxLbFillAttr->set_active_text(aString); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + } + break; + } + case SID_BITMAP_LIST: + case SID_PATTERN_LIST: + { + if(bDefault) + { + if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue()) + { + if(mpBitmapItem) + { + const OUString aString( mpBitmapItem->GetName() ); + const SfxObjectShell* pSh = SfxObjectShell::Current(); + mxLbFillAttr->clear(); + mxLbFillAttr->show(); + if(nSID == SID_BITMAP_LIST) + { + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList()); + } + else if(nSID == SID_PATTERN_LIST) + { + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList()); + } + mxLbFillAttr->set_active_text(aString); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + } + break; + } + } +} + +void AreaPropertyPanelBase::Update() +{ + const eFillStyle eXFS = static_cast<eFillStyle>(mxLbFillType->get_active()); + SfxObjectShell* pSh = SfxObjectShell::Current(); + + switch( eXFS ) + { + case eFillStyle::NONE: + { + mxLbFillAttr->show(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + break; + } + case eFillStyle::SOLID: + { + if(mpColorItem) + { + mxLbFillAttr->hide(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + mxToolBoxColor->show(); + mxBmpImport->hide(); + } + break; + } + case eFillStyle::GRADIENT: + { + mxLbFillAttr->hide(); + mxLbFillGradFrom->show(); + mxLbFillGradTo->show(); + mxMTRAngle->set_sensitive(true); + mxMTRAngle->show(); + mxGradientStyle->show(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + + if(pSh && pSh->GetItem(SID_GRADIENT_LIST)) + { + mxLbFillAttr->set_sensitive(true); + mxLbFillAttr->clear(); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList()); + mxLbFillGradTo->SetNoSelection(); + mxLbFillGradFrom->SetNoSelection(); + if (mpFillGradientItem) + { + const OUString aString(mpFillGradientItem->GetName()); + mxLbFillAttr->set_active_text(aString); + const XGradient aGradient = mpFillGradientItem->GetGradientValue(); + mxLbFillGradFrom->SelectEntry(aGradient.GetStartColor()); + mxLbFillGradTo->SelectEntry(aGradient.GetEndColor()); + mxGradientStyle->set_active(sal::static_int_cast< sal_Int32 >( aGradient.GetGradientStyle() )); + if(mxGradientStyle->get_active() == sal_Int32(GradientStyle::Radial)) + mxMTRAngle->set_sensitive(false); + else + mxMTRAngle->set_value(aGradient.GetAngle() / 10, FieldUnit::DEGREE); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + else + { + mxLbFillAttr->set_active(-1); + } + break; + } + case eFillStyle::HATCH: + { + mxLbFillAttr->show(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + mxToolBoxColor->hide(); + mxBmpImport->hide(); + mxBmpImport->hide(); + + if(pSh && pSh->GetItem(SID_HATCH_LIST)) + { + mxLbFillAttr->set_sensitive(true); + mxLbFillAttr->clear(); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList()); + + if(mpHatchItem) + { + const OUString aString(mpHatchItem->GetName()); + + mxLbFillAttr->set_active_text( aString ); + } + else + { + mxLbFillAttr->set_active(-1); + } + } + else + { + mxLbFillAttr->set_active(-1); + } + break; + } + case eFillStyle::BITMAP: + case eFillStyle::PATTERN: + { + mxLbFillAttr->show(); + mxLbFillAttr->set_sensitive(true); + mxLbFillAttr->clear(); + mxToolBoxColor->hide(); + mxLbFillGradFrom->hide(); + mxLbFillGradTo->hide(); + mxMTRAngle->hide(); + mxGradientStyle->hide(); + + if(mpBitmapItem) + { + if(pSh && pSh->GetItem(SID_BITMAP_LIST) && eXFS == BITMAP) + { + mxBmpImport->show(); + mxLbFillType->set_active(sal_uInt32(BITMAP)); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList()); + + const OUString aString(mpBitmapItem->GetName()); + mxLbFillAttr->set_active_text(aString); + } + else if(pSh && pSh->GetItem(SID_PATTERN_LIST) && eXFS == PATTERN) + { + mxBmpImport->hide(); + mxLbFillType->set_active(sal_uInt32(PATTERN)); + SvxFillAttrBox::Fill(*mxLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList()); + + const OUString aString(mpBitmapItem->GetName()); + mxLbFillAttr->set_active_text(aString); + } + } + else + mxLbFillAttr->set_active(-1); + break; + } + default: + OSL_ENSURE(false, "Non supported FillType (!)"); + break; + } + if(mpPanel) + mpPanel->TriggerDeckLayouting(); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ModifyTransSliderHdl, weld::Scale&, void) +{ + const sal_uInt16 nVal = mxSldTransparent->get_value(); + SetTransparency(nVal); + const XFillTransparenceItem aLinearItem(nVal); + setFillTransparence(aLinearItem); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ChangeTrgrTypeHdl_Impl, weld::ComboBox&, void) +{ + sal_Int32 nSelectType = mxLBTransType->get_active(); + bool bGradient = false; + sal_uInt16 nTrans = 0; + + if(!nSelectType) + { + mxBTNGradient->hide(); + mxMTRTransparent->show(); + mxSldTransparent->show(); + mxMTRTransparent->set_sensitive(true); + mxSldTransparent->set_sensitive(true); + SetTransparency(0); + } + else if(1 == nSelectType) + { + mxBTNGradient->hide(); + mxMTRTransparent->show(); + mxSldTransparent->show(); + nTrans = mnLastTransSolid; + mxMTRTransparent->set_value(nTrans, FieldUnit::PERCENT); + mxLBTransType->set_active(1); + mxMTRTransparent->set_sensitive(true); + mxSldTransparent->set_sensitive(true); + } + else + { + mxBTNGradient->show(); + + switch (nSelectType) + { + case 2: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgLinear); + break; + case 3: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgAxial); + break; + case 4: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgRadial); + break; + case 5: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgElli); + break; + case 6: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgQuad); + break; + case 7: + mxBTNGradient->set_item_icon_name(SIDEBARGRADIENT, maImgSquare); + break; + } + + mxMTRTransparent->hide(); + mxSldTransparent->hide(); + mxBTNGradient->set_sensitive(true); + bGradient = true; + } + + const XFillTransparenceItem aLinearItem(nTrans); + setFillTransparence(aLinearItem); + + if(nSelectType > 1) + { + nSelectType -= 2; + } + + XGradient aTmpGradient; + + switch(static_cast<css::awt::GradientStyle>(nSelectType)) + { + case css::awt::GradientStyle_LINEAR: + aTmpGradient = maGradientLinear; + break; + case css::awt::GradientStyle_AXIAL: + aTmpGradient = maGradientAxial; + break; + case css::awt::GradientStyle_RADIAL: + aTmpGradient = maGradientRadial; + break; + case css::awt::GradientStyle_ELLIPTICAL: + aTmpGradient = maGradientElliptical; + break; + case css::awt::GradientStyle_SQUARE: + aTmpGradient = maGradientSquare; + break; + case css::awt::GradientStyle_RECT: + aTmpGradient = maGradientRect; + break; + default: + break; + } + + const XFillFloatTransparenceItem aGradientItem(aTmpGradient, bGradient); + setFillFloatTransparence(aGradientItem); +} + +IMPL_LINK_NOARG(AreaPropertyPanelBase, ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void) +{ + const sal_uInt16 nTrans = static_cast<sal_uInt16>(mxMTRTransparent->get_value(FieldUnit::PERCENT)); + mnLastTransSolid = nTrans; + SetTransparency(nTrans); + const sal_Int32 nSelectType = mxLBTransType->get_active(); + + if(nTrans && !nSelectType) + { + mxLBTransType->set_active(1); + } + + const XFillTransparenceItem aLinearItem(nTrans); + setFillTransparence(aLinearItem); +} + +const XGradient& AreaPropertyPanelBase::GetGradient (const css::awt::GradientStyle eStyle) const +{ + switch (eStyle) + { + default: + case css::awt::GradientStyle_LINEAR: + return maGradientLinear; + case css::awt::GradientStyle_AXIAL: + return maGradientAxial; + case css::awt::GradientStyle_RADIAL: + return maGradientRadial; + case css::awt::GradientStyle_ELLIPTICAL: + return maGradientElliptical; + case css::awt::GradientStyle_SQUARE: + return maGradientSquare; + case css::awt::GradientStyle_RECT: + return maGradientRect; + } +} + +void AreaPropertyPanelBase::SetGradient (const XGradient& rGradient) +{ + switch (rGradient.GetGradientStyle()) + { + case css::awt::GradientStyle_LINEAR: + maGradientLinear = rGradient; + break; + case css::awt::GradientStyle_AXIAL: + maGradientAxial = rGradient; + break; + case css::awt::GradientStyle_RADIAL: + maGradientRadial = rGradient; + break; + case css::awt::GradientStyle_ELLIPTICAL: + maGradientElliptical = rGradient; + break; + case css::awt::GradientStyle_SQUARE: + maGradientSquare = rGradient; + break; + case css::awt::GradientStyle_RECT: + maGradientRect = rGradient; + break; + default: + break; + } +} + +sal_Int32 AreaPropertyPanelBase::GetSelectedTransparencyTypeIndex() const +{ + return mxLBTransType->get_active(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx b/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx new file mode 100644 index 000000000..a6330f03f --- /dev/null +++ b/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx @@ -0,0 +1,181 @@ +/* -*- 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 <svx/sidebar/AreaTransparencyGradientPopup.hxx> +#include <svx/sidebar/AreaPropertyPanelBase.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xgrad.hxx> +#include <vcl/svapp.hxx> + +namespace svx::sidebar { + +AreaTransparencyGradientPopup::AreaTransparencyGradientPopup(AreaPropertyPanelBase& rPanel, weld::Widget* pParent) + : mrAreaPropertyPanel(rPanel) + , mxBuilder(Application::CreateBuilder(pParent, "svx/ui/floatingareastyle.ui")) + , mxTopLevel(mxBuilder->weld_container("FloatingAreaStyle")) + , mxCenterGrid(mxBuilder->weld_widget("centergrid")) + , mxAngleGrid(mxBuilder->weld_widget("anglegrid")) + , mxMtrTrgrCenterX(mxBuilder->weld_metric_spin_button("centerx", FieldUnit::PERCENT)) + , mxMtrTrgrCenterY(mxBuilder->weld_metric_spin_button("centery", FieldUnit::PERCENT)) + , mxMtrTrgrAngle(mxBuilder->weld_metric_spin_button("angle", FieldUnit::DEGREE)) + , mxBtnLeft45(mxBuilder->weld_toolbar("lefttoolbox")) + , mxBtnRight45(mxBuilder->weld_toolbar("righttoolbox")) + , mxMtrTrgrStartValue(mxBuilder->weld_metric_spin_button("start", FieldUnit::PERCENT)) + , mxMtrTrgrEndValue(mxBuilder->weld_metric_spin_button("end", FieldUnit::PERCENT)) + , mxMtrTrgrBorder(mxBuilder->weld_metric_spin_button("border", FieldUnit::PERCENT)) +{ + Link<weld::MetricSpinButton&,void> aLink = LINK(this, AreaTransparencyGradientPopup, ModifiedTrgrHdl_Impl); + mxMtrTrgrCenterX->connect_value_changed(aLink); + mxMtrTrgrCenterY->connect_value_changed(aLink); + mxMtrTrgrAngle->connect_value_changed(aLink); + mxMtrTrgrBorder->connect_value_changed(aLink); + mxMtrTrgrStartValue->connect_value_changed(aLink); + mxMtrTrgrEndValue->connect_value_changed(aLink); + mxBtnLeft45->connect_clicked(LINK(this, AreaTransparencyGradientPopup, Left_Click45_Impl)); + mxBtnRight45->connect_clicked(LINK(this, AreaTransparencyGradientPopup, Right_Click45_Impl)); + mxTopLevel->connect_focus_in(LINK(this, AreaTransparencyGradientPopup, FocusHdl)); +} + +AreaTransparencyGradientPopup::~AreaTransparencyGradientPopup() +{ +} + +void AreaTransparencyGradientPopup::InitStatus(XFillFloatTransparenceItem const * pGradientItem) +{ + const XGradient& rGradient = pGradientItem->GetGradientValue(); + + XGradient aGradient; + + if (rGradient.GetXOffset() == AreaPropertyPanelBase::DEFAULT_CENTERX + && rGradient.GetYOffset() == AreaPropertyPanelBase::DEFAULT_CENTERY + && (rGradient.GetAngle() / 10) == AreaPropertyPanelBase::DEFAULT_ANGLE + && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetStartColor().GetRed()) + 1) * 100) / 255) + == AreaPropertyPanelBase::DEFAULT_STARTVALUE + && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetEndColor().GetRed()) + 1) * 100) / 255) + == AreaPropertyPanelBase::DEFAULT_ENDVALUE + && rGradient.GetBorder() == AreaPropertyPanelBase::DEFAULT_BORDER) + { + aGradient = mrAreaPropertyPanel.GetGradient(rGradient.GetGradientStyle()); + } + else + { + aGradient = rGradient; + } + mxMtrTrgrCenterX->set_value(aGradient.GetXOffset(), FieldUnit::PERCENT); + mxMtrTrgrCenterY->set_value(aGradient.GetYOffset(), FieldUnit::PERCENT); + mxMtrTrgrAngle->set_value(aGradient.GetAngle() / 10, FieldUnit::DEGREE); + mxMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aGradient.GetStartColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT); + mxMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aGradient.GetEndColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT); + mxMtrTrgrBorder->set_value(aGradient.GetBorder(), FieldUnit::PERCENT); +} + +void AreaTransparencyGradientPopup::Rearrange(XFillFloatTransparenceItem const * pGradientItem) +{ + InitStatus(pGradientItem); + const XGradient& rGradient = pGradientItem->GetGradientValue(); + css::awt::GradientStyle eXGS(rGradient.GetGradientStyle()); + + switch(eXGS) + { + case css::awt::GradientStyle_LINEAR: + case css::awt::GradientStyle_AXIAL: + mxCenterGrid->hide(); + mxAngleGrid->show(); + break; + case css::awt::GradientStyle_RADIAL: + mxCenterGrid->show(); + mxAngleGrid->hide(); + break; + case css::awt::GradientStyle_ELLIPTICAL: + case css::awt::GradientStyle_SQUARE: + case css::awt::GradientStyle_RECT: + mxCenterGrid->show(); + mxAngleGrid->show(); + break; + default: + break; + } +} + +void AreaTransparencyGradientPopup::ExecuteValueModify(sal_uInt8 nStartCol, sal_uInt8 nEndCol) +{ + //Added + sal_Int16 aMtrValue = static_cast<sal_Int16>(mxMtrTrgrAngle->get_value(FieldUnit::DEGREE)); + while(aMtrValue<0) + aMtrValue += 360; + sal_uInt16 nVal = aMtrValue/360; + nVal = aMtrValue - nVal*360; + mxMtrTrgrAngle->set_value(nVal, FieldUnit::DEGREE); + //End of new code + XGradient aTmpGradient( + Color(nStartCol, nStartCol, nStartCol), + Color(nEndCol, nEndCol, nEndCol), + static_cast<css::awt::GradientStyle>(mrAreaPropertyPanel.GetSelectedTransparencyTypeIndex()-2), + static_cast<sal_uInt16>(mxMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10, + static_cast<sal_uInt16>(mxMtrTrgrCenterX->get_value(FieldUnit::PERCENT)), + static_cast<sal_uInt16>(mxMtrTrgrCenterY->get_value(FieldUnit::PERCENT)), + static_cast<sal_uInt16>(mxMtrTrgrBorder->get_value(FieldUnit::PERCENT)), + 100, 100); + + mrAreaPropertyPanel.SetGradient(aTmpGradient); + + XFillFloatTransparenceItem aGradientItem(aTmpGradient, true ); + + mrAreaPropertyPanel.setFillFloatTransparence(aGradientItem); +} + +IMPL_LINK_NOARG(AreaTransparencyGradientPopup, ModifiedTrgrHdl_Impl, weld::MetricSpinButton&, void) +{ + sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + ExecuteValueModify( nStartCol, nEndCol ); +} + +IMPL_LINK_NOARG(AreaTransparencyGradientPopup, Left_Click45_Impl, const OString&, void) +{ + sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + sal_uInt16 nTemp = static_cast<sal_uInt16>(mxMtrTrgrAngle->get_value(FieldUnit::DEGREE)); + if (nTemp>=315) + nTemp -= 360; + nTemp += 45; + mxMtrTrgrAngle->set_value(nTemp, FieldUnit::DEGREE); + ExecuteValueModify(nStartCol, nEndCol); +} + +IMPL_LINK_NOARG(AreaTransparencyGradientPopup, Right_Click45_Impl, const OString&, void) +{ + sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(mxMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100); + sal_uInt16 nTemp = static_cast<sal_uInt16>(mxMtrTrgrAngle->get_value(FieldUnit::DEGREE)); + if (nTemp<45) + nTemp += 360; + nTemp -= 45; + mxMtrTrgrAngle->set_value(nTemp, FieldUnit::DEGREE); + ExecuteValueModify(nStartCol, nEndCol); +} + +IMPL_LINK_NOARG(AreaTransparencyGradientPopup, FocusHdl, weld::Widget&, void) +{ + mxMtrTrgrCenterX->grab_focus(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/glow/GlowPropertyPanel.cxx b/svx/source/sidebar/glow/GlowPropertyPanel.cxx new file mode 100644 index 000000000..acb63e090 --- /dev/null +++ b/svx/source/sidebar/glow/GlowPropertyPanel.cxx @@ -0,0 +1,162 @@ +/* -*- 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/. + */ + +#include <sal/config.h> + +#include "GlowPropertyPanel.hxx" + +#include <sfx2/dispatch.hxx> +#include <svx/colorbox.hxx> +#include <svx/sdmetitm.hxx> +#include <svx/sdooitm.hxx> +#include <svx/sdprcitm.hxx> +#include <svx/svddef.hxx> +#include <svx/svxids.hrc> +#include <svx/xcolit.hxx> +#include <rtl/math.hxx> + +namespace svx::sidebar +{ +GlowPropertyPanel::GlowPropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) + : PanelLayout(pParent, "GlowPropertyPanel", "svx/ui/sidebarglow.ui", rxFrame) + , maGlowColorController(SID_ATTR_GLOW_COLOR, *pBindings, *this) + , maGlowRadiusController(SID_ATTR_GLOW_RADIUS, *pBindings, *this) + , maGlowTransparencyController(SID_ATTR_GLOW_TRANSPARENCY, *pBindings, *this) + , mpBindings(pBindings) + , mxGlowRadius(m_xBuilder->weld_metric_spin_button("LB_GLOW_RADIUS", FieldUnit::POINT)) + , mxLBGlowColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_GLOW_COLOR"), GetFrameWeld())) + , mxGlowTransparency( + m_xBuilder->weld_metric_spin_button("LB_GLOW_TRANSPARENCY", FieldUnit::PERCENT)) + , mxFTRadius(m_xBuilder->weld_label("radius")) + , mxFTColor(m_xBuilder->weld_label("color")) + , mxFTTransparency(m_xBuilder->weld_label("transparency")) +{ + Initialize(); +} + +GlowPropertyPanel::~GlowPropertyPanel() { disposeOnce(); } + +void GlowPropertyPanel::dispose() +{ + mxFTRadius.reset(); + mxGlowRadius.reset(); + mxFTColor.reset(); + mxLBGlowColor.reset(); + mxFTTransparency.reset(); + mxGlowTransparency.reset(); + + maGlowColorController.dispose(); + maGlowRadiusController.dispose(); + maGlowTransparencyController.dispose(); + PanelLayout::dispose(); +} + +void GlowPropertyPanel::Initialize() +{ + mxLBGlowColor->SetSelectHdl(LINK(this, GlowPropertyPanel, ModifyGlowColorHdl)); + mxGlowRadius->connect_value_changed(LINK(this, GlowPropertyPanel, ModifyGlowRadiusHdl)); + mxGlowTransparency->connect_value_changed( + LINK(this, GlowPropertyPanel, ModifyGlowTransparencyHdl)); +} + +IMPL_LINK_NOARG(GlowPropertyPanel, ModifyGlowColorHdl, ColorListBox&, void) +{ + XColorItem aItem(SDRATTR_GLOW_COLOR, mxLBGlowColor->GetSelectEntryColor()); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_COLOR, SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(GlowPropertyPanel, ModifyGlowRadiusHdl, weld::MetricSpinButton&, void) +{ + SdrMetricItem aItem(SDRATTR_GLOW_RADIUS, mxGlowRadius->get_value(FieldUnit::MM_100TH)); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_RADIUS, SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(GlowPropertyPanel, ModifyGlowTransparencyHdl, weld::MetricSpinButton&, void) +{ + SdrPercentItem aItem(SDRATTR_GLOW_TRANSPARENCY, + mxGlowTransparency->get_value(FieldUnit::PERCENT)); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_GLOW_TRANSPARENCY, SfxCallMode::RECORD, + { &aItem }); +} + +void GlowPropertyPanel::UpdateControls() +{ + const bool bEnabled = mxGlowRadius->get_value(FieldUnit::MM_100TH) != 0; + mxLBGlowColor->set_sensitive(bEnabled); + mxGlowTransparency->set_sensitive(bEnabled); + mxFTColor->set_sensitive(bEnabled); + mxFTTransparency->set_sensitive(bEnabled); +} + +void GlowPropertyPanel::NotifyItemUpdate(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_ATTR_GLOW_COLOR: + { + if (eState >= SfxItemState::DEFAULT) + { + const XColorItem* pColorItem = dynamic_cast<const XColorItem*>(pState); + if (pColorItem) + { + mxLBGlowColor->SelectEntry(pColorItem->GetColorValue()); + } + } + } + break; + case SID_ATTR_GLOW_RADIUS: + { + if (eState >= SfxItemState::DEFAULT) + { + const SdrMetricItem* pRadiusItem = dynamic_cast<const SdrMetricItem*>(pState); + if (pRadiusItem) + { + mxGlowRadius->set_value(pRadiusItem->GetValue(), FieldUnit::MM_100TH); + } + } + } + break; + case SID_ATTR_GLOW_TRANSPARENCY: + { + if (eState >= SfxItemState::DEFAULT) + { + if (auto pItem = dynamic_cast<const SdrPercentItem*>(pState)) + { + mxGlowTransparency->set_value(pItem->GetValue(), FieldUnit::PERCENT); + } + } + } + break; + } + UpdateControls(); +} + +VclPtr<vcl::Window> +GlowPropertyPanel::Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw css::lang::IllegalArgumentException( + "no parent Window given to GlowPropertyPanel::Create", nullptr, 0); + if (!rxFrame.is()) + throw css::lang::IllegalArgumentException("no XFrame given to GlowPropertyPanel::Create", + nullptr, 1); + if (pBindings == nullptr) + throw css::lang::IllegalArgumentException( + "no SfxBindings given to GlowPropertyPanel::Create", nullptr, 2); + + return VclPtr<GlowPropertyPanel>::Create(pParent, rxFrame, pBindings); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/glow/GlowPropertyPanel.hxx b/svx/source/sidebar/glow/GlowPropertyPanel.hxx new file mode 100644 index 000000000..aaffa44e4 --- /dev/null +++ b/svx/source/sidebar/glow/GlowPropertyPanel.hxx @@ -0,0 +1,64 @@ +/* -*- 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/. + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_GLOW_GLOWPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_GLOW_GLOWPROPERTYPANEL_HXX + +#include <vcl/vclptr.hxx> +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> + +class ColorListBox; + +namespace svx::sidebar +{ +class GlowPropertyPanel : public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + GlowPropertyPanel(vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + virtual ~GlowPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState(const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override{}; + +private: + sfx2::sidebar::ControllerItem maGlowColorController; + sfx2::sidebar::ControllerItem maGlowRadiusController; + sfx2::sidebar::ControllerItem maGlowTransparencyController; + + SfxBindings* mpBindings; + + std::unique_ptr<weld::MetricSpinButton> mxGlowRadius; + std::unique_ptr<ColorListBox> mxLBGlowColor; + std::unique_ptr<weld::MetricSpinButton> mxGlowTransparency; + std::unique_ptr<weld::Label> mxFTRadius; + std::unique_ptr<weld::Label> mxFTColor; + std::unique_ptr<weld::Label> mxFTTransparency; + + void Initialize(); + void UpdateControls(); + + DECL_LINK(ModifyGlowColorHdl, ColorListBox&, void); + DECL_LINK(ModifyGlowRadiusHdl, weld::MetricSpinButton&, void); + DECL_LINK(ModifyGlowTransparencyHdl, weld::MetricSpinButton&, void); +}; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/graphic/GraphicPropertyPanel.cxx b/svx/source/sidebar/graphic/GraphicPropertyPanel.cxx new file mode 100644 index 000000000..5ab60aff0 --- /dev/null +++ b/svx/source/sidebar/graphic/GraphicPropertyPanel.cxx @@ -0,0 +1,415 @@ +/* -*- 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 "GraphicPropertyPanel.hxx" +#include <svx/strings.hrc> +#include <svx/svxids.hrc> +#include <svx/dialmgr.hxx> +#include <svl/intitem.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace css; +using namespace css::uno; + + +// namespace open + +namespace svx::sidebar { + + +GraphicPropertyPanel::GraphicPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +: PanelLayout(pParent, "GraphicPropertyPanel", "svx/ui/sidebargraphic.ui", rxFrame), + maBrightControl(SID_ATTR_GRAF_LUMINANCE, *pBindings, *this), + maContrastControl(SID_ATTR_GRAF_CONTRAST, *pBindings, *this), + maTransparenceControl(SID_ATTR_GRAF_TRANSPARENCE, *pBindings, *this), + maRedControl(SID_ATTR_GRAF_RED, *pBindings, *this), + maGreenControl(SID_ATTR_GRAF_GREEN, *pBindings, *this), + maBlueControl(SID_ATTR_GRAF_BLUE, *pBindings, *this), + maGammaControl(SID_ATTR_GRAF_GAMMA, *pBindings, *this), + maModeControl(SID_ATTR_GRAF_MODE, *pBindings, *this), + mpBindings(pBindings), + mxMtrBrightness(m_xBuilder->weld_metric_spin_button("setbrightness", FieldUnit::PERCENT)), + mxMtrContrast(m_xBuilder->weld_metric_spin_button("setcontrast", FieldUnit::PERCENT)), + mxLBColorMode(m_xBuilder->weld_combo_box("setcolormode")), + mxMtrTrans(m_xBuilder->weld_metric_spin_button("setgraphtransparency", FieldUnit::PERCENT)), + mxMtrRed(m_xBuilder->weld_metric_spin_button("setred", FieldUnit::PERCENT)), + mxMtrGreen(m_xBuilder->weld_metric_spin_button("setgreen", FieldUnit::PERCENT)), + mxMtrBlue(m_xBuilder->weld_metric_spin_button("setblue", FieldUnit::PERCENT)), + mxMtrGamma(m_xBuilder->weld_spin_button("setgamma")) +{ + mxLBColorMode->set_size_request(mxLBColorMode->get_preferred_size().Width(), -1); + Initialize(); +} + +GraphicPropertyPanel::~GraphicPropertyPanel() +{ + disposeOnce(); +} + +void GraphicPropertyPanel::dispose() +{ + mxMtrBrightness.reset(); + mxMtrContrast.reset(); + mxLBColorMode.reset(); + mxMtrTrans.reset(); + mxMtrRed.reset(); + mxMtrGreen.reset(); + mxMtrBlue.reset(); + mxMtrGamma.reset(); + + maBrightControl.dispose(); + maContrastControl.dispose(); + maTransparenceControl.dispose(); + maRedControl.dispose(); + maGreenControl.dispose(); + maBlueControl.dispose(); + maGammaControl.dispose(); + maModeControl.dispose(); + + PanelLayout::dispose(); +} + +void GraphicPropertyPanel::Initialize() +{ + mxMtrBrightness->connect_value_changed( LINK( this, GraphicPropertyPanel, ModifyBrightnessHdl ) ); + mxMtrContrast->connect_value_changed( LINK( this, GraphicPropertyPanel, ModifyContrastHdl ) ); + mxMtrTrans->connect_value_changed( LINK( this, GraphicPropertyPanel, ModifyTransHdl ) ); + + mxLBColorMode->append_text(SvxResId(RID_SVXSTR_GRAFMODE_STANDARD)); + mxLBColorMode->append_text(SvxResId(RID_SVXSTR_GRAFMODE_GREYS)); + mxLBColorMode->append_text(SvxResId(RID_SVXSTR_GRAFMODE_MONO)); + mxLBColorMode->append_text(SvxResId(RID_SVXSTR_GRAFMODE_WATERMARK)); + mxLBColorMode->connect_changed( LINK( this, GraphicPropertyPanel, ClickColorModeHdl )); + + mxMtrRed->connect_value_changed( LINK( this, GraphicPropertyPanel, RedHdl ) ); + mxMtrGreen->connect_value_changed( LINK( this, GraphicPropertyPanel, GreenHdl ) ); + mxMtrBlue->connect_value_changed( LINK( this, GraphicPropertyPanel, BlueHdl ) ); + mxMtrGamma->connect_value_changed( LINK( this, GraphicPropertyPanel, GammaHdl ) ); +} + +IMPL_LINK_NOARG( GraphicPropertyPanel, ModifyBrightnessHdl, weld::MetricSpinButton&, void ) +{ + const sal_Int16 nBright = mxMtrBrightness->get_value(FieldUnit::PERCENT); + const SfxInt16Item aBrightItem( SID_ATTR_GRAF_LUMINANCE, nBright ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_LUMINANCE, + SfxCallMode::RECORD, { &aBrightItem }); +} + + +IMPL_LINK_NOARG( GraphicPropertyPanel, ModifyContrastHdl, weld::MetricSpinButton&, void ) +{ + const sal_Int16 nContrast = mxMtrContrast->get_value(FieldUnit::PERCENT); + const SfxInt16Item aContrastItem( SID_ATTR_GRAF_CONTRAST, nContrast ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_CONTRAST, + SfxCallMode::RECORD, { &aContrastItem }); +} + + +IMPL_LINK_NOARG( GraphicPropertyPanel, ModifyTransHdl, weld::MetricSpinButton&, void ) +{ + const sal_Int16 nTrans = mxMtrTrans->get_value(FieldUnit::PERCENT); + const SfxInt16Item aTransItem( SID_ATTR_GRAF_TRANSPARENCE, nTrans ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_TRANSPARENCE, + SfxCallMode::RECORD, { &aTransItem }); +} + + +IMPL_LINK_NOARG( GraphicPropertyPanel, ClickColorModeHdl, weld::ComboBox&, void ) +{ + const sal_Int16 nTrans = mxLBColorMode->get_active(); + const SfxInt16Item aTransItem( SID_ATTR_GRAF_MODE, nTrans ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_MODE, + SfxCallMode::RECORD, { &aTransItem }); +} + + +IMPL_LINK_NOARG( GraphicPropertyPanel, RedHdl, weld::MetricSpinButton&, void ) +{ + const sal_Int16 nRed = mxMtrRed->get_value(FieldUnit::PERCENT); + const SfxInt16Item aRedItem( SID_ATTR_GRAF_RED, nRed ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_RED, + SfxCallMode::RECORD, { &aRedItem }); +} + + +IMPL_LINK_NOARG( GraphicPropertyPanel, GreenHdl, weld::MetricSpinButton&, void ) +{ + const sal_Int16 nGreen = mxMtrGreen->get_value(FieldUnit::PERCENT); + const SfxInt16Item aGreenItem( SID_ATTR_GRAF_GREEN, nGreen ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_GREEN, + SfxCallMode::RECORD, { &aGreenItem }); +} + + +IMPL_LINK_NOARG(GraphicPropertyPanel, BlueHdl, weld::MetricSpinButton&, void) +{ + const sal_Int16 nBlue = mxMtrBlue->get_value(FieldUnit::PERCENT); + const SfxInt16Item aBlueItem( SID_ATTR_GRAF_BLUE, nBlue ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_BLUE, + SfxCallMode::RECORD, { &aBlueItem }); +} + + +IMPL_LINK_NOARG(GraphicPropertyPanel, GammaHdl, weld::SpinButton&, void) +{ + const sal_Int32 nGamma = mxMtrGamma->get_value(); + const SfxInt32Item nGammaItem( SID_ATTR_GRAF_GAMMA, nGamma ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_GRAF_GAMMA, + SfxCallMode::RECORD, { &nGammaItem }); +} + + +VclPtr<vcl::Window> GraphicPropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to GraphicPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to GraphicPropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to GraphicPropertyPanel::Create", nullptr, 2); + + return VclPtr<GraphicPropertyPanel>::Create( + pParent, + rxFrame, + pBindings); +} + + +void GraphicPropertyPanel::DataChanged( + const DataChangedEvent& /*rEvent*/) +{ +} + + +void GraphicPropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + switch( nSID ) + { + case SID_ATTR_GRAF_LUMINANCE: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrBrightness->set_sensitive(true); + const SfxInt16Item* pItem = dynamic_cast< const SfxInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nBright = pItem->GetValue(); + mxMtrBrightness->set_value(nBright, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrBrightness->set_sensitive(false); + } + else + { + mxMtrBrightness->set_sensitive(true); + mxMtrBrightness->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_CONTRAST: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrContrast->set_sensitive(true); + const SfxInt16Item* pItem = dynamic_cast< const SfxInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nContrast = pItem->GetValue(); + mxMtrContrast->set_value(nContrast, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrContrast->set_sensitive(false); + } + else + { + mxMtrContrast->set_sensitive(true); + mxMtrContrast->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_TRANSPARENCE: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrTrans->set_sensitive(true); + const SfxUInt16Item* pItem = dynamic_cast< const SfxUInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nTrans = pItem->GetValue(); + mxMtrTrans->set_value(nTrans, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrTrans->set_sensitive(false); + } + else + { + mxMtrTrans->set_sensitive(true); + mxMtrTrans->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_MODE: + { + if(eState >= SfxItemState::DEFAULT) + { + mxLBColorMode->set_sensitive(true); + const SfxUInt16Item* pItem = dynamic_cast< const SfxUInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nTrans = pItem->GetValue(); + mxLBColorMode->set_active(nTrans); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxLBColorMode->set_sensitive(false); + } + else + { + mxLBColorMode->set_sensitive(true); + mxLBColorMode->set_active(-1); + } + break; + } + case SID_ATTR_GRAF_RED: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrRed->set_sensitive(true); + const SfxInt16Item* pItem = dynamic_cast< const SfxInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nRed = pItem->GetValue(); + mxMtrRed->set_value(nRed, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrRed->set_sensitive(false); + } + else + { + mxMtrRed->set_sensitive(true); + mxMtrRed->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_GREEN: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrGreen->set_sensitive(true); + const SfxInt16Item* pItem = dynamic_cast< const SfxInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nGreen = pItem->GetValue(); + mxMtrGreen->set_value(nGreen, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrGreen->set_sensitive(false); + } + else + { + mxMtrGreen->set_sensitive(true); + mxMtrGreen->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_BLUE: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrBlue->set_sensitive(true); + const SfxInt16Item* pItem = dynamic_cast< const SfxInt16Item* >(pState); + + if(pItem) + { + const sal_Int64 nBlue = pItem->GetValue(); + mxMtrBlue->set_value(nBlue, FieldUnit::PERCENT); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrBlue->set_sensitive(false); + } + else + { + mxMtrBlue->set_sensitive(true); + mxMtrBlue->set_text(OUString()); + } + break; + } + case SID_ATTR_GRAF_GAMMA: + { + if(eState >= SfxItemState::DEFAULT) + { + mxMtrGamma->set_sensitive(true); + const SfxUInt32Item* pItem = dynamic_cast< const SfxUInt32Item* >(pState); + + if(pItem) + { + const sal_Int64 nGamma = pItem->GetValue(); + mxMtrGamma->set_value( nGamma ); + } + } + else if(SfxItemState::DISABLED == eState) + { + mxMtrGamma->set_sensitive(false); + } + else + { + mxMtrGamma->set_sensitive(true); + mxMtrGamma->set_text(OUString()); + } + break; + } + } +} + + +// namespace close + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx b/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx new file mode 100644 index 000000000..bb724d4c4 --- /dev/null +++ b/svx/source/sidebar/graphic/GraphicPropertyPanel.hxx @@ -0,0 +1,99 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_GRAPHIC_GRAPHICPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_GRAPHIC_GRAPHICPROPERTYPANEL_HXX + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <vcl/weld.hxx> + +namespace svx::sidebar { + +class GraphicPropertyPanel +: public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~GraphicPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void DataChanged( + const DataChangedEvent& rEvent) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + SfxBindings* GetBindings() { return mpBindings;} + + // constructor/destructor + GraphicPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + +private: + ::sfx2::sidebar::ControllerItem maBrightControl; + ::sfx2::sidebar::ControllerItem maContrastControl; + ::sfx2::sidebar::ControllerItem maTransparenceControl; + ::sfx2::sidebar::ControllerItem maRedControl; + ::sfx2::sidebar::ControllerItem maGreenControl; + ::sfx2::sidebar::ControllerItem maBlueControl; + ::sfx2::sidebar::ControllerItem maGammaControl; + ::sfx2::sidebar::ControllerItem maModeControl; + + SfxBindings* mpBindings; + + //ui controls + std::unique_ptr<weld::MetricSpinButton> mxMtrBrightness; + std::unique_ptr<weld::MetricSpinButton> mxMtrContrast; + std::unique_ptr<weld::ComboBox> mxLBColorMode; + std::unique_ptr<weld::MetricSpinButton> mxMtrTrans; + std::unique_ptr<weld::MetricSpinButton> mxMtrRed; + std::unique_ptr<weld::MetricSpinButton> mxMtrGreen; + std::unique_ptr<weld::MetricSpinButton> mxMtrBlue; + std::unique_ptr<weld::SpinButton> mxMtrGamma; + + DECL_LINK( ModifyBrightnessHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ModifyContrastHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ModifyTransHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ClickColorModeHdl, weld::ComboBox&, void ); + DECL_LINK( RedHdl, weld::MetricSpinButton&, void ); + DECL_LINK( GreenHdl, weld::MetricSpinButton&, void ); + DECL_LINK( BlueHdl, weld::MetricSpinButton&, void ); + DECL_LINK( GammaHdl, weld::SpinButton&, void ); + + void Initialize(); +}; + +} // end of namespace svx::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/inspector/InspectorTextPanel.cxx b/svx/source/sidebar/inspector/InspectorTextPanel.cxx new file mode 100644 index 000000000..0c719dfcc --- /dev/null +++ b/svx/source/sidebar/inspector/InspectorTextPanel.cxx @@ -0,0 +1,77 @@ +/* -*- 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 "InspectorTextPanel.hxx" + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <comphelper/lok.hxx> +#include <sfx2/lokhelper.hxx> + +using namespace css; + +namespace svx::sidebar +{ +VclPtr<vcl::Window> +InspectorTextPanel::Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to InspectorTextPanel::Create", + nullptr, 0); + if (!rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to InspectorTextPanel::Create", + nullptr, 1); + + return VclPtr<InspectorTextPanel>::Create(pParent, rxFrame); +} + +InspectorTextPanel::InspectorTextPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) + : PanelLayout(pParent, "InspectorTextPanel", "svx/ui/inspectortextpanel.ui", rxFrame) + , mxFont(m_xBuilder->weld_toolbar("font")) + , mxFontDispatch(new ToolbarUnoDispatcher(*mxFont, *m_xBuilder, rxFrame)) + , mxFontHeight(m_xBuilder->weld_toolbar("fontheight")) + , mxFontHeightDispatch(new ToolbarUnoDispatcher(*mxFontHeight, *m_xBuilder, rxFrame)) +{ +} + +InspectorTextPanel::~InspectorTextPanel() { disposeOnce(); } + +void InspectorTextPanel::dispose() +{ + mxFontHeightDispatch.reset(); + mxFontDispatch.reset(); + + mxFontHeight.reset(); + mxFont.reset(); + + PanelLayout::dispose(); +} + +void InspectorTextPanel::HandleContextChange(const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + return; + + maContext = rContext; +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/inspector/InspectorTextPanel.hxx b/svx/source/sidebar/inspector/InspectorTextPanel.hxx new file mode 100644 index 000000000..ed8b24a52 --- /dev/null +++ b/svx/source/sidebar/inspector/InspectorTextPanel.hxx @@ -0,0 +1,55 @@ +/* -*- 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 . + */ +#pragma once + +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/weldutils.hxx> +#include <vcl/EnumContext.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> + +namespace svx +{ +namespace sidebar +{ +class InspectorTextPanel : public PanelLayout, public ::sfx2::sidebar::IContextChangeReceiver +{ +public: + virtual ~InspectorTextPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + + virtual void HandleContextChange(const vcl::EnumContext& rContext) override; + + InspectorTextPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + +private: + std::unique_ptr<weld::Toolbar> mxFont; + std::unique_ptr<ToolbarUnoDispatcher> mxFontDispatch; + std::unique_ptr<weld::Toolbar> mxFontHeight; + std::unique_ptr<ToolbarUnoDispatcher> mxFontHeightDispatch; + + vcl::EnumContext maContext; +}; +} +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LinePropertyPanel.cxx b/svx/source/sidebar/line/LinePropertyPanel.cxx new file mode 100644 index 000000000..070512cd3 --- /dev/null +++ b/svx/source/sidebar/line/LinePropertyPanel.cxx @@ -0,0 +1,172 @@ +/* -*- 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 "LinePropertyPanel.hxx" +#include <svx/svxids.hrc> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xlncapit.hxx> +#include <svx/xlinjoit.hxx> + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { + +LinePropertyPanel::LinePropertyPanel( + vcl::Window* pParent, + const uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +: LinePropertyPanelBase(pParent, rxFrame), + maStyleControl(SID_ATTR_LINE_STYLE, *pBindings, *this), + maDashControl (SID_ATTR_LINE_DASH, *pBindings, *this), + maWidthControl(SID_ATTR_LINE_WIDTH, *pBindings, *this), + maTransControl(SID_ATTR_LINE_TRANSPARENCE, *pBindings, *this), + maEdgeStyle(SID_ATTR_LINE_JOINT, *pBindings, *this), + maCapStyle(SID_ATTR_LINE_CAP, *pBindings, *this), + mpBindings(pBindings), + maContext() +{ + setMapUnit(maWidthControl.GetCoreMetric()); +} + +LinePropertyPanel::~LinePropertyPanel() +{ + disposeOnce(); +} + +void LinePropertyPanel::dispose() +{ + maStyleControl.dispose(); + maDashControl.dispose(); + maWidthControl.dispose(); + maTransControl.dispose(); + maEdgeStyle.dispose(); + maCapStyle.dispose(); + + LinePropertyPanelBase::dispose(); +} + +VclPtr<vcl::Window> LinePropertyPanel::Create ( + vcl::Window* pParent, + const uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to LinePropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to LinePropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to LinePropertyPanel::Create", nullptr, 2); + + return VclPtr<LinePropertyPanel>::Create(pParent, rxFrame, pBindings); +} + +void LinePropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + const bool bDisabled(SfxItemState::DISABLED == eState); + const bool bSetOrDefault = eState >= SfxItemState::DEFAULT; + + switch(nSID) + { + case SID_ATTR_LINE_TRANSPARENCE: + { + updateLineTransparence(bDisabled, bSetOrDefault, pState); + break; + } + case SID_ATTR_LINE_WIDTH: + { + updateLineWidth(bDisabled, bSetOrDefault, pState); + break; + } + case SID_ATTR_LINE_JOINT: + { + updateLineJoint(bDisabled, bSetOrDefault, pState); + break; + } + case SID_ATTR_LINE_CAP: + { + updateLineCap(bDisabled, bSetOrDefault, pState); + break; + } + } + ActivateControls(); +} + +void LinePropertyPanel::HandleContextChange( + const vcl::EnumContext& rContext) +{ + if(maContext == rContext) + { + // Nothing to do + return; + } + + maContext = rContext; + bool bShowArrows = false; + + switch(maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::Calc, Context::DrawLine): + case CombinedEnumContext(Application::DrawImpress, Context::DrawLine): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::WriterVariants, Context::Draw): + // TODO : Implement DrawLine context in Writer + bShowArrows = true; + break; + } + + if (!bShowArrows) + disableArrowHead(); + else + enableArrowHead(); +} + +void LinePropertyPanel::setLineJoint(const XLineJointItem* pItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_LINE_JOINT, + SfxCallMode::RECORD, { pItem }); +} + +void LinePropertyPanel::setLineCap(const XLineCapItem* pItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_LINE_CAP, + SfxCallMode::RECORD, { pItem }); +} + +void LinePropertyPanel::setLineTransparency(const XLineTransparenceItem& rItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_LINE_STYLE, + SfxCallMode::RECORD, { &rItem }); +} + +void LinePropertyPanel::setLineWidth(const XLineWidthItem& rItem) +{ + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_LINE_WIDTH, + SfxCallMode::RECORD, { &rItem }); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LinePropertyPanel.hxx b/svx/source/sidebar/line/LinePropertyPanel.hxx new file mode 100644 index 000000000..767564fe6 --- /dev/null +++ b/svx/source/sidebar/line/LinePropertyPanel.hxx @@ -0,0 +1,100 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEPROPERTYPANEL_HXX + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <svx/sidebar/LinePropertyPanelBase.hxx> +#include <vcl/EnumContext.hxx> + +class XLineStyleItem; +class XLineDashItem; +class XLineStartItem; +class XLineEndItem; +class XLineEndList; +class XDashList; +class ListBox; +class ToolBox; +class FloatingWindow; + +namespace svx +{ +namespace sidebar +{ + +class LinePropertyPanel : public LinePropertyPanelBase, + public sfx2::sidebar::IContextChangeReceiver, + public sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~LinePropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void HandleContextChange( + const vcl::EnumContext& rContext) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + SfxBindings* GetBindings() { return mpBindings;} + + // constructor/destructor + LinePropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void setLineWidth(const XLineWidthItem& rItem) override; + +protected: + + virtual void setLineTransparency(const XLineTransparenceItem& rItem) override; + virtual void setLineJoint(const XLineJointItem* pItem) override; + virtual void setLineCap(const XLineCapItem* pItem) override; + +private: + //ControllerItem + sfx2::sidebar::ControllerItem maStyleControl; + sfx2::sidebar::ControllerItem maDashControl; + sfx2::sidebar::ControllerItem maWidthControl; + sfx2::sidebar::ControllerItem maTransControl; + sfx2::sidebar::ControllerItem maEdgeStyle; + sfx2::sidebar::ControllerItem maCapStyle; + + SfxBindings* mpBindings; + vcl::EnumContext maContext; +}; + +} } // end of namespace svx::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LinePropertyPanelBase.cxx b/svx/source/sidebar/line/LinePropertyPanelBase.cxx new file mode 100644 index 000000000..f2c1b4553 --- /dev/null +++ b/svx/source/sidebar/line/LinePropertyPanelBase.cxx @@ -0,0 +1,484 @@ +/* -*- 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 <memory> +#include <svx/sidebar/LinePropertyPanelBase.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <sfx2/weldutils.hxx> +#include <svx/linectrl.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xlncapit.hxx> +#include <svx/xlinjoit.hxx> +#include <bitmaps.hlst> + +using namespace css; +using namespace css::uno; + +const char SELECTWIDTH[] = "SelectWidth"; + +namespace svx::sidebar { + +// trigger disabling the arrows if the none line style is selected +class DisableArrowsWrapper +{ +private: + LinePropertyPanelBase& m_rPanel; + +public: + DisableArrowsWrapper(LinePropertyPanelBase& rPanel) + : m_rPanel(rPanel) + { + } + + bool operator()(const OUString& rCommand, const css::uno::Any& rValue) + { + if (rCommand == ".uno:XLineStyle") + { + css::drawing::LineStyle eLineStyle(css::drawing::LineStyle_NONE); + rValue >>= eLineStyle; + m_rPanel.SetNoneLineStyle(eLineStyle == css::drawing::LineStyle_NONE); + } + return false; + } +}; + +namespace +{ + SvxLineStyleToolBoxControl* getLineStyleToolBoxControl(ToolbarUnoDispatcher& rToolBoxColor) + { + css::uno::Reference<css::frame::XToolbarController> xController = rToolBoxColor.GetControllerForCommand(".uno:XLineStyle"); + SvxLineStyleToolBoxControl* pToolBoxLineStyleControl = dynamic_cast<SvxLineStyleToolBoxControl*>(xController.get()); + return pToolBoxLineStyleControl; + } +} + + +LinePropertyPanelBase::LinePropertyPanelBase( + vcl::Window* pParent, + const uno::Reference<css::frame::XFrame>& rxFrame) +: PanelLayout(pParent, "LinePropertyPanel", "svx/ui/sidebarline.ui", rxFrame), + mxTBColor(m_xBuilder->weld_toolbar("color")), + mxColorDispatch(new ToolbarUnoDispatcher(*mxTBColor, *m_xBuilder, rxFrame)), + mxLineStyleTB(m_xBuilder->weld_toolbar("linestyle")), + mxLineStyleDispatch(new ToolbarUnoDispatcher(*mxLineStyleTB, *m_xBuilder, rxFrame)), + mxFTWidth(m_xBuilder->weld_label("widthlabel")), + mxTBWidth(m_xBuilder->weld_toolbar("width")), + mxFTTransparency(m_xBuilder->weld_label("translabel")), + mxMFTransparent(m_xBuilder->weld_metric_spin_button("linetransparency", FieldUnit::PERCENT)), + mxFTEdgeStyle(m_xBuilder->weld_label("cornerlabel")), + mxLBEdgeStyle(m_xBuilder->weld_combo_box("edgestyle")), + mxFTCapStyle(m_xBuilder->weld_label("caplabel")), + mxLBCapStyle(m_xBuilder->weld_combo_box("linecapstyle")), + mxGridLineProps(m_xBuilder->weld_widget("lineproperties")), + mxBoxArrowProps(m_xBuilder->weld_widget("arrowproperties")), + mxLineWidthPopup(new LineWidthPopup(mxTBWidth.get(), *this)), + mxDisableArrowsWrapper(new DisableArrowsWrapper(*this)), + mnTrans(0), + meMapUnit(MapUnit::MapMM), + mnWidthCoreValue(0), + maIMGNone(BMP_NONE_ICON), + mbWidthValuable(true), + mbArrowSupported(true), + mbNoneLineStyle(false) +{ + Initialize(); +} + +LinePropertyPanelBase::~LinePropertyPanelBase() +{ + disposeOnce(); +} + +void LinePropertyPanelBase::dispose() +{ + mxLineWidthPopup.reset(); + mxFTWidth.reset(); + mxTBWidth.reset(); + mxColorDispatch.reset(); + mxTBColor.reset(); + mxFTTransparency.reset(); + mxMFTransparent.reset(); + mxLineStyleDispatch.reset(); + mxLineStyleTB.reset(); + mxFTEdgeStyle.reset(); + mxLBEdgeStyle.reset(); + mxFTCapStyle.reset(); + mxLBCapStyle.reset(); + mxGridLineProps.reset(); + mxBoxArrowProps.reset(); + + PanelLayout::dispose(); +} + +void LinePropertyPanelBase::Initialize() +{ + mxTBWidth->set_item_popover(SELECTWIDTH, mxLineWidthPopup->getTopLevel()); + + maIMGWidthIcon[0] = BMP_WIDTH1_ICON; + maIMGWidthIcon[1] = BMP_WIDTH2_ICON; + maIMGWidthIcon[2] = BMP_WIDTH3_ICON; + maIMGWidthIcon[3] = BMP_WIDTH4_ICON; + maIMGWidthIcon[4] = BMP_WIDTH5_ICON; + maIMGWidthIcon[5] = BMP_WIDTH6_ICON; + maIMGWidthIcon[6] = BMP_WIDTH7_ICON; + maIMGWidthIcon[7] = BMP_WIDTH8_ICON; + + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[0]); + mxTBWidth->connect_clicked(LINK(this, LinePropertyPanelBase, ToolboxWidthSelectHdl)); + + mxMFTransparent->connect_value_changed(LINK(this, LinePropertyPanelBase, ChangeTransparentHdl)); + + mxLBEdgeStyle->connect_changed( LINK( this, LinePropertyPanelBase, ChangeEdgeStyleHdl ) ); + + mxLBCapStyle->connect_changed( LINK( this, LinePropertyPanelBase, ChangeCapStyleHdl ) ); + + SvxLineStyleToolBoxControl* pLineStyleControl = getLineStyleToolBoxControl(*mxLineStyleDispatch); + pLineStyleControl->setLineStyleSelectFunction(*mxDisableArrowsWrapper); +} + +void LinePropertyPanelBase::updateLineTransparence(bool bDisabled, bool bSetOrDefault, + const SfxPoolItem* pState) +{ + if(bDisabled) + { + mxFTTransparency->set_sensitive(false); + mxMFTransparent->set_sensitive(false); + } + else + { + mxFTTransparency->set_sensitive(true); + mxMFTransparent->set_sensitive(true); + } + + if(bSetOrDefault) + { + if (const XLineTransparenceItem* pItem = dynamic_cast<const XLineTransparenceItem*>(pState)) + { + mnTrans = pItem->GetValue(); + mxMFTransparent->set_value(mnTrans, FieldUnit::PERCENT); + return; + } + } + + mxMFTransparent->set_value(0, FieldUnit::PERCENT);//add + mxMFTransparent->set_text(OUString()); +} + +void LinePropertyPanelBase::updateLineWidth(bool bDisabled, bool bSetOrDefault, + const SfxPoolItem* pState) +{ + if(bDisabled) + { + mxTBWidth->set_sensitive(false); + mxFTWidth->set_sensitive(false); + } + else + { + mxTBWidth->set_sensitive(true); + mxFTWidth->set_sensitive(true); + } + + if(bSetOrDefault) + { + if (const XLineWidthItem* pItem = dynamic_cast<const XLineWidthItem*>(pState)) + { + mnWidthCoreValue = pItem->GetValue(); + mbWidthValuable = true; + SetWidthIcon(); + return; + } + } + + mbWidthValuable = false; + SetWidthIcon(); +} + +void LinePropertyPanelBase::updateLineJoint(bool bDisabled, bool bSetOrDefault, + const SfxPoolItem* pState) +{ + if(bDisabled) + { + mxLBEdgeStyle->set_sensitive(false); + mxFTEdgeStyle->set_sensitive(false); + } + else + { + mxLBEdgeStyle->set_sensitive(true); + mxFTEdgeStyle->set_sensitive(true); + } + + if(bSetOrDefault) + { + if (const XLineJointItem* pItem = dynamic_cast<const XLineJointItem*>(pState)) + { + sal_Int32 nEntryPos(0); + + switch(pItem->GetValue()) + { + case drawing::LineJoint_ROUND: + { + nEntryPos = 1; + break; + } + case drawing::LineJoint_NONE: + { + nEntryPos = 2; + break; + } + case drawing::LineJoint_MIDDLE: + case drawing::LineJoint_MITER: + { + nEntryPos = 3; + break; + } + case drawing::LineJoint_BEVEL: + { + nEntryPos = 4; + break; + } + + default: + break; + } + + if(nEntryPos) + { + mxLBEdgeStyle->set_active(nEntryPos - 1); + return; + } + } + } + + mxLBEdgeStyle->set_active(-1); +} + +void LinePropertyPanelBase::updateLineCap(bool bDisabled, bool bSetOrDefault, + const SfxPoolItem* pState) +{ + if(bDisabled) + { + mxLBCapStyle->set_sensitive(false); + mxFTCapStyle->set_sensitive(false); + } + else + { + mxLBCapStyle->set_sensitive(true); + mxLBCapStyle->set_sensitive(true); + } + + if(bSetOrDefault) + { + if (const XLineCapItem* pItem = dynamic_cast<const XLineCapItem*>(pState)) + { + sal_Int32 nEntryPos(0); + + switch(pItem->GetValue()) + { + case drawing::LineCap_BUTT: + { + nEntryPos = 1; + break; + } + case drawing::LineCap_ROUND: + { + nEntryPos = 2; + break; + } + case drawing::LineCap_SQUARE: + { + nEntryPos = 3; + break; + } + + default: + break; + } + + if(nEntryPos) + { + mxLBCapStyle->set_active(nEntryPos - 1); + return; + } + } + } + + mxLBCapStyle->set_active(-1); +} + +IMPL_LINK_NOARG(LinePropertyPanelBase, ChangeEdgeStyleHdl, weld::ComboBox&, void) +{ + const sal_Int32 nPos(mxLBEdgeStyle->get_active()); + + if (nPos != -1 && mxLBEdgeStyle->get_value_changed_from_saved()) + { + std::unique_ptr<XLineJointItem> pItem; + + switch(nPos) + { + case 0: // rounded + { + pItem.reset(new XLineJointItem(drawing::LineJoint_ROUND)); + break; + } + case 1: // none + { + pItem.reset(new XLineJointItem(drawing::LineJoint_NONE)); + break; + } + case 2: // mitered + { + pItem.reset(new XLineJointItem(drawing::LineJoint_MITER)); + break; + } + case 3: // beveled + { + pItem.reset(new XLineJointItem(drawing::LineJoint_BEVEL)); + break; + } + } + + setLineJoint(pItem.get()); + } +} + +IMPL_LINK_NOARG(LinePropertyPanelBase, ChangeCapStyleHdl, weld::ComboBox&, void) +{ + const sal_Int32 nPos(mxLBCapStyle->get_active()); + + if (nPos != -1 && mxLBCapStyle->get_value_changed_from_saved()) + { + std::unique_ptr<XLineCapItem> pItem; + + switch(nPos) + { + case 0: // flat + { + pItem.reset(new XLineCapItem(drawing::LineCap_BUTT)); + break; + } + case 1: // round + { + pItem.reset(new XLineCapItem(drawing::LineCap_ROUND)); + break; + } + case 2: // square + { + pItem.reset(new XLineCapItem(drawing::LineCap_SQUARE)); + break; + } + } + + setLineCap(pItem.get()); + } +} + +IMPL_LINK_NOARG(LinePropertyPanelBase, ToolboxWidthSelectHdl, const OString&, void) +{ + mxTBWidth->set_menu_item_active(SELECTWIDTH, !mxTBWidth->get_menu_item_active(SELECTWIDTH)); +} + +void LinePropertyPanelBase::EndLineWidthPopup() +{ + mxTBWidth->set_menu_item_active(SELECTWIDTH, false); +} + +IMPL_LINK_NOARG( LinePropertyPanelBase, ChangeTransparentHdl, weld::MetricSpinButton&, void ) +{ + sal_uInt16 nVal = static_cast<sal_uInt16>(mxMFTransparent->get_value(FieldUnit::PERCENT)); + XLineTransparenceItem aItem( nVal ); + + setLineTransparency(aItem); +} + +void LinePropertyPanelBase::SetWidthIcon(int n) +{ + if (n == 0) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGNone); + else + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[n-1]); +} + +void LinePropertyPanelBase::SetWidthIcon() +{ + if(!mbWidthValuable) + { + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGNone); + return; + } + + long nVal = LogicToLogic(mnWidthCoreValue * 10, meMapUnit, MapUnit::MapPoint); + + if(nVal <= 6) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[0]); + else if (nVal <= 9) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[1]); + else if (nVal <= 12) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[2]); + else if (nVal <= 19) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[3]); + else if (nVal <= 26) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[4]); + else if (nVal <= 37) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[5]); + else if (nVal <= 52) + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[6]); + else + mxTBWidth->set_item_icon_name(SELECTWIDTH, maIMGWidthIcon[7]); + +} + +void LinePropertyPanelBase::SetWidth(long nWidth) +{ + mnWidthCoreValue = nWidth; + mbWidthValuable = true; + mxLineWidthPopup->SetWidthSelect(mnWidthCoreValue, mbWidthValuable, meMapUnit); +} + +void LinePropertyPanelBase::ActivateControls() +{ + mxGridLineProps->set_sensitive(!mbNoneLineStyle); + mxBoxArrowProps->set_sensitive(!mbNoneLineStyle); + mxLineStyleTB->set_item_sensitive(".uno:LineEndStyle", !mbNoneLineStyle); + + mxBoxArrowProps->set_visible(mbArrowSupported); + mxLineStyleTB->set_item_visible(".uno:LineEndStyle", mbArrowSupported); +} + +void LinePropertyPanelBase::setMapUnit(MapUnit eMapUnit) +{ + meMapUnit = eMapUnit; + mxLineWidthPopup->SetWidthSelect(mnWidthCoreValue, mbWidthValuable, meMapUnit); +} + +void LinePropertyPanelBase::disableArrowHead() +{ + mbArrowSupported = false; + ActivateControls(); +} + +void LinePropertyPanelBase::enableArrowHead() +{ + mbArrowSupported = true; + ActivateControls(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LineWidthPopup.cxx b/svx/source/sidebar/line/LineWidthPopup.cxx new file mode 100644 index 000000000..c65afbe63 --- /dev/null +++ b/svx/source/sidebar/line/LineWidthPopup.cxx @@ -0,0 +1,226 @@ +/* -*- 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 <svx/sidebar/LineWidthPopup.hxx> +#include <svx/sidebar/LinePropertyPanelBase.hxx> +#include <com/sun/star/beans/NamedValue.hpp> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <svx/xlnwtit.hxx> +#include <unotools/localedatawrapper.hxx> +#include <unotools/viewoptions.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include "LineWidthValueSet.hxx" +#include <bitmaps.hlst> + +namespace svx::sidebar { + +LineWidthPopup::LineWidthPopup(weld::Widget* pParent, LinePropertyPanelBase& rParent) + : m_rParent(rParent) + , m_sPt(SvxResId(RID_SVXSTR_PT)) + , m_eMapUnit(MapUnit::MapTwip) + , m_bVSFocus(true) + , m_bCustom(false) + , m_nCustomWidth(0) + , m_aIMGCus(StockImage::Yes, RID_SVXBMP_WIDTH_CUSTOM) + , m_aIMGCusGray(StockImage::Yes, RID_SVXBMP_WIDTH_CUSTOM_GRAY) + , m_xBuilder(Application::CreateBuilder(pParent, "svx/ui/floatinglineproperty.ui")) + , m_xTopLevel(m_xBuilder->weld_container("FloatingLineProperty")) + , m_xMFWidth(m_xBuilder->weld_metric_spin_button("spin", FieldUnit::POINT)) + , m_xVSWidth(new LineWidthValueSet()) + , m_xVSWidthWin(new weld::CustomWeld(*m_xBuilder, "lineset", *m_xVSWidth)) +{ + m_xTopLevel->connect_focus_in(LINK(this, LineWidthPopup, FocusHdl)); + + m_xVSWidth->SetStyle(m_xVSWidth->GetStyle() | WB_3DLOOK | WB_NO_DIRECTSELECT); + + maStrUnits[0] = "0.5"; + maStrUnits[1] = "0.8"; + maStrUnits[2] = "1.0"; + maStrUnits[3] = "1.5"; + maStrUnits[4] = "2.3"; + maStrUnits[5] = "3.0"; + maStrUnits[6] = "4.5"; + maStrUnits[7] = "6.0"; + maStrUnits[8] = SvxResId(RID_SVXSTR_WIDTH_LAST_CUSTOM); + + const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() ); + const sal_Unicode cSep = rLocaleWrapper.getNumDecimalSep()[0]; + + for(int i = 0; i <= 7 ; i++) + { + maStrUnits[i] = maStrUnits[i].replace('.', cSep);//Modify + maStrUnits[i] += " "; + maStrUnits[i] += m_sPt; + } + + for (sal_uInt16 i = 1 ; i <= 9; ++i) + { + m_xVSWidth->InsertItem(i); + m_xVSWidth->SetItemText(i, maStrUnits[i-1]); + } + + m_xVSWidth->SetUnit(maStrUnits); + m_xVSWidth->SetItemData(1, reinterpret_cast<void*>(5)); + m_xVSWidth->SetItemData(2, reinterpret_cast<void*>(8)); + m_xVSWidth->SetItemData(3, reinterpret_cast<void*>(10)); + m_xVSWidth->SetItemData(4, reinterpret_cast<void*>(15)); + m_xVSWidth->SetItemData(5, reinterpret_cast<void*>(23)); + m_xVSWidth->SetItemData(6, reinterpret_cast<void*>(30)); + m_xVSWidth->SetItemData(7, reinterpret_cast<void*>(45)); + m_xVSWidth->SetItemData(8, reinterpret_cast<void*>(60)); + m_xVSWidth->SetImage(m_aIMGCusGray); + + m_xVSWidth->SetSelItem(0); + + m_xVSWidth->SetSelectHdl(LINK(this, LineWidthPopup, VSSelectHdl)); + m_xMFWidth->connect_value_changed(LINK(this, LineWidthPopup, MFModifyHdl)); +} + +LineWidthPopup::~LineWidthPopup() +{ +} + +IMPL_LINK_NOARG(LineWidthPopup, VSSelectHdl, ValueSet*, void) +{ + sal_uInt16 iPos = m_xVSWidth->GetSelectedItemId(); + if (iPos >= 1 && iPos <= 8) + { + sal_IntPtr nVal = OutputDevice::LogicToLogic(reinterpret_cast<sal_IntPtr>(m_xVSWidth->GetItemData( iPos )), MapUnit::MapPoint, m_eMapUnit); + nVal = m_xMFWidth->denormalize(nVal); + XLineWidthItem aWidthItem( nVal ); + m_rParent.setLineWidth(aWidthItem); + m_rParent.SetWidthIcon(iPos); + m_rParent.SetWidth(nVal); + } + else if (iPos == 9) + {//last custom + //modified + if (m_bCustom) + { + long nVal = OutputDevice::LogicToLogic(m_nCustomWidth , MapUnit::MapPoint, m_eMapUnit); + nVal = m_xMFWidth->denormalize(nVal); + XLineWidthItem aWidthItem( nVal ); + m_rParent.setLineWidth(aWidthItem); + m_rParent.SetWidth(nVal); + } + else + { + m_xVSWidth->SetNoSelection(); //add , set no selection and keep the last select item + m_xVSWidth->SetFormat(); + m_xVSWidth->Invalidate(); + } + //modify end + } + + if ((iPos >= 1 && iPos <= 8) || (iPos == 9 && m_bCustom)) //add + { + m_rParent.EndLineWidthPopup(); + } +} + +IMPL_LINK_NOARG(LineWidthPopup, MFModifyHdl, weld::MetricSpinButton&, void) +{ + if (m_xVSWidth->GetSelItem()) + { + m_xVSWidth->SetSelItem(0); + m_xVSWidth->SetFormat(); + m_xVSWidth->Invalidate(); + } + long nTmp = static_cast<long>(m_xMFWidth->get_value(FieldUnit::NONE)); + long nVal = OutputDevice::LogicToLogic( nTmp, MapUnit::MapPoint, m_eMapUnit ); + sal_Int32 nNewWidth = static_cast<short>(m_xMFWidth->denormalize( nVal )); + XLineWidthItem aWidthItem(nNewWidth); + m_rParent.setLineWidth(aWidthItem); +} + +void LineWidthPopup::SetWidthSelect(long lValue, bool bValuable, MapUnit eMapUnit) +{ + m_bVSFocus = true; + m_xVSWidth->SetSelItem(0); + m_eMapUnit = eMapUnit; + SvtViewOptions aWinOpt( EViewType::Window, "PopupPanel_LineWidth" ); + if (aWinOpt.Exists()) + { + css::uno::Sequence <css::beans::NamedValue> aSeq = aWinOpt.GetUserData(); + OUString aTmp; + if ( aSeq.hasElements()) + aSeq[0].Value >>= aTmp; + + OUString aWinData( aTmp ); + m_nCustomWidth = aWinData.toInt32(); + m_bCustom = true; + m_xVSWidth->SetImage(m_aIMGCus); + m_xVSWidth->SetCusEnable(true); + + OUString aStrTip = OUString::number( static_cast<double>(m_nCustomWidth) / 10) + + m_sPt; + m_xVSWidth->SetItemText(9, aStrTip); + } + else + { + m_bCustom = false; + m_xVSWidth->SetImage(m_aIMGCusGray); + m_xVSWidth->SetCusEnable(false); + m_xVSWidth->SetItemText(9, maStrUnits[8]); + } + + if (bValuable) + { + sal_Int64 nVal = OutputDevice::LogicToLogic(lValue, eMapUnit, MapUnit::Map100thMM ); + nVal = m_xMFWidth->normalize(nVal); + m_xMFWidth->set_value( nVal, FieldUnit::MM_100TH ); + } + else + { + m_xMFWidth->set_text( "" ); + } + + OUString strCurrValue = m_xMFWidth->get_text(); + sal_uInt16 i = 0; + for(; i < 8; i++) + { + if (strCurrValue == maStrUnits[i]) + { + m_xVSWidth->SetSelItem(i+1); + break; + } + } + + if (i>=8) + { + m_bVSFocus = false; + m_xVSWidth->SetSelItem(0); + } + + m_xVSWidth->SetFormat(); + m_xVSWidth->Invalidate(); +} + +IMPL_LINK_NOARG(LineWidthPopup, FocusHdl, weld::Widget&, void) +{ + if (m_bVSFocus) + m_xVSWidth->GrabFocus(); + else + m_xMFWidth->grab_focus(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LineWidthValueSet.cxx b/svx/source/sidebar/line/LineWidthValueSet.cxx new file mode 100644 index 000000000..e78fd51ae --- /dev/null +++ b/svx/source/sidebar/line/LineWidthValueSet.cxx @@ -0,0 +1,172 @@ +/* -*- 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 "LineWidthValueSet.hxx" + +#include <i18nlangtag/mslangid.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + +namespace svx::sidebar { + +LineWidthValueSet::LineWidthValueSet() + : ValueSet(nullptr) + , nSelItem(0) + , bCusEnable(false) +{ +} + +void LineWidthValueSet::Resize() +{ + SetColCount(); + SetLineCount(9); + ValueSet::Resize(); +} + +LineWidthValueSet::~LineWidthValueSet() +{ +} + +void LineWidthValueSet::SetUnit(std::array<OUString,9> const & strUnits) +{ + maStrUnits = strUnits; +} + +void LineWidthValueSet::SetSelItem(sal_uInt16 nSel) +{ + nSelItem = nSel; + if(nSel == 0) + { + SelectItem(1); // ,false); // 'false' nut supported by AOO + SetNoSelection(); + } + else + { + SelectItem(nSelItem); + GrabFocus(); + } +} + +void LineWidthValueSet::SetImage(const Image& img) +{ + imgCus = img; +} + +void LineWidthValueSet::SetCusEnable(bool bEnable) +{ + bCusEnable = bEnable; +} + +void LineWidthValueSet::UserDraw( const UserDrawEvent& rUDEvt ) +{ + tools::Rectangle aRect = rUDEvt.GetRect(); + vcl::RenderContext* pDev = rUDEvt.GetRenderContext(); + sal_uInt16 nItemId = rUDEvt.GetItemId(); + + long nRectHeight = aRect.GetHeight(); + long nRectWidth = aRect.GetWidth(); + Point aBLPos = aRect.TopLeft(); + + //const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + //Color aBackColor(0,0,200); + //const Color aTextColor = rStyleSettings.GetFieldTextColor(); + vcl::Font aOldFont = pDev->GetFont(); + Color aOldColor = pDev->GetLineColor(); + Color aOldFillColor = pDev->GetFillColor(); + + vcl::Font aFont(OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getSystemLanguage(), GetDefaultFontFlags::OnlyOne)); + Size aSize = aFont.GetFontSize(); + aSize.setHeight( nRectHeight*3/5 ); + aFont.SetFontSize( aSize ); + + Point aLineStart(aBLPos.X() + 5, aBLPos.Y() + ( nRectHeight - nItemId )/2); + Point aLineEnd(aBLPos.X() + nRectWidth * 7 / 9 - 10, aBLPos.Y() + ( nRectHeight - nItemId )/2); + if (nItemId == 9) + { + Point aImgStart(aBLPos.X() + 5, aBLPos.Y() + ( nRectHeight - 23 ) / 2); + pDev->DrawImage(aImgStart, imgCus); + + tools::Rectangle aStrRect = aRect; + aStrRect.AdjustTop(nRectHeight/6 ); + aStrRect.AdjustBottom( -(nRectHeight/6) ); + aStrRect.AdjustLeft(imgCus.GetSizePixel().Width() + 20 ); + if(bCusEnable) + aFont.SetColor(Application::GetSettings().GetStyleSettings().GetFieldTextColor()); + else + aFont.SetColor(Application::GetSettings().GetStyleSettings().GetDisableColor()); + + pDev->SetFont(aFont); + pDev->DrawText(aStrRect, maStrUnits[ nItemId - 1 ], DrawTextFlags::EndEllipsis); + } + else + { + if( nSelItem == nItemId ) + { + tools::Rectangle aBackRect = aRect; + aBackRect.AdjustTop(3 ); + aBackRect.AdjustBottom( -2 ); + pDev->SetFillColor(Color(50,107,197)); + pDev->DrawRect(aBackRect); + } + else + { + pDev->SetFillColor( COL_TRANSPARENT ); + pDev->DrawRect(aRect); + } + + //draw text + if(nSelItem == nItemId ) + aFont.SetColor(COL_WHITE); + else + aFont.SetColor(Application::GetSettings().GetStyleSettings().GetFieldTextColor()); + pDev->SetFont(aFont); + Point aStart(aBLPos.X() + nRectWidth * 7 / 9 , aBLPos.Y() + nRectHeight/6); + pDev->DrawText(aStart, maStrUnits[ nItemId - 1 ]); //can't set DrawTextFlags::EndEllipsis here ,or the text will disappear + + //draw line + if( nSelItem == nItemId ) + pDev->SetLineColor(COL_WHITE); + else + pDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetFieldTextColor()); + + for(sal_uInt16 i = 1; i <= nItemId; i++) + { + pDev->DrawLine(aLineStart,aLineEnd ); + aLineStart.setY(aLineStart.getY() + 1); + aLineEnd.setY (aLineEnd.getY() + 1); + } + } + + Invalidate( aRect ); + pDev->SetLineColor(aOldColor); + pDev->SetFillColor(aOldFillColor); + pDev->SetFont(aOldFont); +} + +void LineWidthValueSet::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + ValueSet::SetDrawingArea(pDrawingArea); + Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(80, 12 * 9), MapMode(MapUnit::MapAppFont))); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + SetOutputSizePixel(aSize); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/line/LineWidthValueSet.hxx b/svx/source/sidebar/line/LineWidthValueSet.hxx new file mode 100644 index 000000000..225e706a6 --- /dev/null +++ b/svx/source/sidebar/line/LineWidthValueSet.hxx @@ -0,0 +1,55 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEWIDTHVALUESET_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEWIDTHVALUESET_HXX + +#include <svtools/valueset.hxx> +#include <vcl/image.hxx> +#include <array> + +namespace svx::sidebar { + +class LineWidthValueSet final : public ValueSet +{ +public: + explicit LineWidthValueSet(); + virtual ~LineWidthValueSet() override; + + void SetUnit(std::array<OUString,9> const & strUnits); + void SetSelItem(sal_uInt16 nSel); + sal_uInt16 GetSelItem() const { return nSelItem;} + void SetImage(const Image& img); + void SetCusEnable(bool bEnable); + + virtual void UserDraw( const UserDrawEvent& rUDEvt ) override; + virtual void Resize() override; + virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; + +private: + sal_uInt16 nSelItem; + std::array<OUString,9> maStrUnits; + Image imgCus; + bool bCusEnable; +}; + +} // end of namespace svx::sidebar + +#endif // INCLUDED_SVX_SOURCE_SIDEBAR_LINE_LINEWIDTHVALUESET_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/lists/ListsPropertyPanel.cxx b/svx/source/sidebar/lists/ListsPropertyPanel.cxx new file mode 100644 index 000000000..2b579b497 --- /dev/null +++ b/svx/source/sidebar/lists/ListsPropertyPanel.cxx @@ -0,0 +1,64 @@ +/* -*- 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 "ListsPropertyPanel.hxx" +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar +{ +VclPtr<vcl::Window> +ListsPropertyPanel::Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to ListsPropertyPanel::Create", + nullptr, 0); + if (!rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to ListsPropertyPanel::Create", + nullptr, 1); + + return VclPtr<ListsPropertyPanel>::Create(pParent, rxFrame); +} + +ListsPropertyPanel::ListsPropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) + : PanelLayout(pParent, "ListsPropertyPanel", "svx/ui/sidebarlists.ui", rxFrame) + , mxTBxNumBullet(m_xBuilder->weld_toolbar("numberbullet")) + , mxNumBulletDispatcher(new ToolbarUnoDispatcher(*mxTBxNumBullet, *m_xBuilder, rxFrame)) + , mxTBxOutline(m_xBuilder->weld_toolbar("outline")) + , mxOutlineDispatcher(new ToolbarUnoDispatcher(*mxTBxOutline, *m_xBuilder, rxFrame)) +{ +} + +ListsPropertyPanel::~ListsPropertyPanel() { disposeOnce(); } + +void ListsPropertyPanel::dispose() +{ + mxOutlineDispatcher.reset(); + mxTBxOutline.reset(); + mxNumBulletDispatcher.reset(); + mxTBxNumBullet.reset(); + + PanelLayout::dispose(); +} +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/lists/ListsPropertyPanel.hxx b/svx/source/sidebar/lists/ListsPropertyPanel.hxx new file mode 100644 index 000000000..350891684 --- /dev/null +++ b/svx/source/sidebar/lists/ListsPropertyPanel.hxx @@ -0,0 +1,53 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_LISTS_LISTSPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_LISTS_LISTSPROPERTYPANEL_HXX + +#include <sfx2/weldutils.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <com/sun/star/frame/XFrame.hpp> + +namespace svx +{ +namespace sidebar +{ +class ListsPropertyPanel : public PanelLayout +{ +public: + virtual ~ListsPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + + ListsPropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + +private: + std::unique_ptr<weld::Toolbar> mxTBxNumBullet; + std::unique_ptr<ToolbarUnoDispatcher> mxNumBulletDispatcher; + std::unique_ptr<weld::Toolbar> mxTBxOutline; + std::unique_ptr<ToolbarUnoDispatcher> mxOutlineDispatcher; +}; +} +} // end of namespace svx::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/media/MediaPlaybackPanel.cxx b/svx/source/sidebar/media/MediaPlaybackPanel.cxx new file mode 100644 index 000000000..b62eb3292 --- /dev/null +++ b/svx/source/sidebar/media/MediaPlaybackPanel.cxx @@ -0,0 +1,190 @@ +/* -*- 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 "MediaPlaybackPanel.hxx" +#include <avmedia/mediaitem.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/dispatch.hxx> +#include <avmedia/MediaControlBase.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace avmedia; + +namespace svx::sidebar { + +MediaPlaybackPanel::MediaPlaybackPanel ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) + : PanelLayout(pParent, "MediaPlaybackPanel", "svx/ui/mediaplayback.ui", rxFrame), + MediaControlBase(), + maMediaController(SID_AVMEDIA_TOOLBOX, *pBindings, *this), + maIdle("MediaPlaybackPanel"), + mpBindings(pBindings) +{ + mxTimeEdit = m_xBuilder->weld_entry("timeedit"); + mxPlayToolBox = m_xBuilder->weld_toolbar("playtoolbox"); + mxMuteToolBox = m_xBuilder->weld_toolbar("mutetoolbox"); + mxTimeSlider = m_xBuilder->weld_scale("timeslider"); + mxVolumeSlider = m_xBuilder->weld_scale("volumeslider"); + mxZoomListBox = m_xBuilder->weld_combo_box("zoombox"); + + Initialize(); +} + +VclPtr< vcl::Window > MediaPlaybackPanel::Create( + vcl::Window* pParent, + const Reference< XFrame >& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to MediaPlaybackPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to MediaPlaybackPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to MediaPlaybackPanel::Create", nullptr, 2); + + return VclPtr<MediaPlaybackPanel>::Create( + pParent, + rxFrame, + pBindings); +} + +MediaPlaybackPanel::~MediaPlaybackPanel() +{ + disposeOnce(); +} + +void MediaPlaybackPanel::Initialize() +{ + InitializeWidgets(); + mxVolumeSlider->connect_value_changed(LINK(this, MediaPlaybackPanel, VolumeSlideHdl)); + mxPlayToolBox->connect_clicked(LINK(this, MediaPlaybackPanel, PlayToolBoxSelectHdl)); + mxMuteToolBox->connect_clicked(LINK(this, MediaPlaybackPanel, PlayToolBoxSelectHdl)); + mxTimeSlider->connect_value_changed(LINK(this, MediaPlaybackPanel, SeekHdl)); + + maIdle.SetPriority( TaskPriority::HIGHEST ); + maIdle.SetInvokeHandler( LINK( this, MediaPlaybackPanel, TimeoutHdl ) ); + maIdle.Start(); + mpBindings->Invalidate(SID_AVMEDIA_TOOLBOX); +} + +void MediaPlaybackPanel::dispose() +{ + disposeWidgets(); + PanelLayout::dispose(); +} + +void MediaPlaybackPanel::NotifyItemUpdate( + const sal_uInt16 nSID, + const SfxItemState eState, + const SfxPoolItem* pState) +{ + if( nSID == SID_AVMEDIA_TOOLBOX ) + { + if(eState >= SfxItemState::DEFAULT) + { + mpMediaItem.reset(pState ? static_cast< MediaItem* >(pState->Clone()) : nullptr); + Update(); + } + } +} + +void MediaPlaybackPanel::UpdateToolBoxes(const MediaItem& rMediaItem) +{ + mxPlayToolBox->set_sensitive(false); + avmedia::MediaControlBase::UpdateToolBoxes(rMediaItem); +} + +void MediaPlaybackPanel::Update() +{ + if (mpMediaItem) + { + UpdateToolBoxes( *mpMediaItem ); + UpdateTimeSlider( *mpMediaItem ); + UpdateVolumeSlider( *mpMediaItem ); + UpdateTimeField( *mpMediaItem, mpMediaItem->getTime() ); + } +} + +IMPL_LINK_NOARG( MediaPlaybackPanel, VolumeSlideHdl, weld::Scale&, void) +{ + MediaItem aItem(SID_AVMEDIA_TOOLBOX); + aItem.setVolumeDB(mxVolumeSlider->get_value()); + mpBindings->GetDispatcher()->ExecuteList(SID_AVMEDIA_TOOLBOX, SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG( MediaPlaybackPanel, SeekHdl, weld::Scale&, void) +{ + MediaItem aItem(SID_AVMEDIA_TOOLBOX); + aItem.setState( MediaState::Pause ); + double nTime = 0; + if (mpMediaItem) + nTime = mxTimeSlider->get_value() * mpMediaItem->getDuration() / AVMEDIA_TIME_RANGE; + aItem.setTime(nTime); + mpBindings->GetDispatcher()->ExecuteList(SID_AVMEDIA_TOOLBOX, SfxCallMode::RECORD, { &aItem }); + mpBindings->Invalidate(SID_AVMEDIA_TOOLBOX); +} + +IMPL_LINK_NOARG( MediaPlaybackPanel, TimeoutHdl, Timer*, void) +{ + mpBindings->Invalidate(SID_AVMEDIA_TOOLBOX); +} + +IMPL_LINK( MediaPlaybackPanel, PlayToolBoxSelectHdl, const OString&, rId, void) +{ + MediaItem aItem(SID_AVMEDIA_TOOLBOX); + + if (rId == "play") + { + aItem.setState( MediaState::Play ); + + if( !mpMediaItem || (mpMediaItem->getTime() == mpMediaItem->getDuration() )) + aItem.setTime( 0.0 ); + else + aItem.setTime( mpMediaItem->getTime()); + } + else if (rId == "pause") + { + aItem.setState( MediaState::Pause ); + } + else if (rId == "stop") + { + aItem.setState( MediaState::Stop ); + aItem.setTime( 0.0 ); + } + else if (rId == "mute") + { + aItem.setMute( mxMuteToolBox->get_item_active("mute") ); + } + else if (rId == "loop") + { + aItem.setLoop( mxPlayToolBox->get_item_active("loop") ); + } + + if(aItem.getMaskSet() != AVMediaSetMask::NONE) + { + mpBindings->GetDispatcher()->ExecuteList(SID_AVMEDIA_TOOLBOX, SfxCallMode::RECORD, { &aItem } ); + mpBindings->Invalidate(SID_AVMEDIA_TOOLBOX); + } +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/media/MediaPlaybackPanel.hxx b/svx/source/sidebar/media/MediaPlaybackPanel.hxx new file mode 100644 index 000000000..a71a18a5e --- /dev/null +++ b/svx/source/sidebar/media/MediaPlaybackPanel.hxx @@ -0,0 +1,83 @@ +/* -*- 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 . + */ +#pragma once + +#include <memory> +#include <com/sun/star/frame/XFrame.hpp> + +#include <sfx2/sidebar/PanelLayout.hxx> +#include <avmedia/mediaitem.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/sidebar/ControllerItem.hxx> +#include <avmedia/MediaControlBase.hxx> + +using namespace css; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; + +namespace svx::sidebar { + +/** This panel provides media playback control in document +*/ +class MediaPlaybackPanel + : public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface, + public ::avmedia::MediaControlBase +{ +public: + MediaPlaybackPanel ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + virtual ~MediaPlaybackPanel() override; + virtual void dispose() override; + +protected: + virtual void UpdateToolBoxes(const avmedia::MediaItem& rMediaItem) override; + +private: + std::unique_ptr< ::avmedia::MediaItem > mpMediaItem; + ::sfx2::sidebar::ControllerItem maMediaController; + Idle maIdle; + SfxBindings* mpBindings; + void Initialize(); + void Update(); + virtual void NotifyItemUpdate( const sal_uInt16 nSID, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + DECL_LINK(PlayToolBoxSelectHdl, const OString&, void); + DECL_LINK(VolumeSlideHdl, weld::Scale&, void); + DECL_LINK(SeekHdl, weld::Scale&, void); + + DECL_LINK(TimeoutHdl, Timer*, void); +}; + + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/nbdtmg.cxx b/svx/source/sidebar/nbdtmg.cxx new file mode 100644 index 000000000..627da9eae --- /dev/null +++ b/svx/source/sidebar/nbdtmg.cxx @@ -0,0 +1,913 @@ +/* -*- 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 <svx/nbdtmg.hxx> +#include <svx/svxids.hrc> +#include <vcl/svapp.hxx> +#include <svl/itemset.hxx> +#include <sfx2/request.hxx> +#include <svl/stritem.hxx> +#include <svtools/ctrltool.hxx> +#include <sfx2/objsh.hxx> +#include <editeng/flstitem.hxx> +#include <svl/itempool.hxx> +#include <vcl/outdev.hxx> +#include <editeng/brushitem.hxx> +#include <svx/dialmgr.hxx> +#include <svx/strings.hrc> +#include <vcl/graph.hxx> +#include <vcl/settings.hxx> + +#include <i18nlangtag/languagetag.hxx> +#include <tools/debug.hxx> +#include <tools/urlobj.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <unotools/pathoptions.hxx> +#include <editeng/eeitem.hxx> + +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/text/DefaultNumberingProvider.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <comphelper/processfactory.hxx> +#include <memory> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::text; +using namespace com::sun::star::container; +using namespace com::sun::star::style; + +namespace svx::sidebar { + +namespace { + +const vcl::Font& lcl_GetDefaultBulletFont() +{ + static vcl::Font aDefBulletFont = [&]() + { + static vcl::Font tmp("OpenSymbol", "", Size(0, 14)); + tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL ); + tmp.SetFamily( FAMILY_DONTKNOW ); + tmp.SetPitch( PITCH_DONTKNOW ); + tmp.SetWeight( WEIGHT_DONTKNOW ); + tmp.SetTransparent( true ); + return tmp; + }(); + return aDefBulletFont; +} + +const sal_Unicode aDefaultBulletTypes[] = +{ + 0x2022, + 0x25cf, + 0xe00c, + 0xe00a, + 0x2794, + 0x27a2, + 0x2717, + 0x2714 +}; + +NumSettings_Impl* lcl_CreateNumberingSettingsPtr(const Sequence<PropertyValue>& rLevelProps) +{ + NumSettings_Impl* pNew = new NumSettings_Impl; + for(const PropertyValue& rValue : rLevelProps) + { + if(rValue.Name == "NumberingType") + { + sal_Int16 nTmp; + if (rValue.Value >>= nTmp) + pNew->nNumberType = static_cast<SvxNumType>(nTmp); + } + else if(rValue.Name == "Prefix") + rValue.Value >>= pNew->sPrefix; + else if(rValue.Name == "Suffix") + rValue.Value >>= pNew->sSuffix; + else if(rValue.Name == "ParentNumbering") + rValue.Value >>= pNew->nParentNumbering; + else if(rValue.Name == "BulletChar") + rValue.Value >>= pNew->sBulletChar; + else if(rValue.Name == "BulletFontName") + rValue.Value >>= pNew->sBulletFont; + } + const sal_Unicode cLocalPrefix = pNew->sPrefix.getLength() ? pNew->sPrefix[0] : 0; + const sal_Unicode cLocalSuffix = pNew->sSuffix.getLength() ? pNew->sSuffix[0] : 0; + if( cLocalPrefix == ' ') pNew->sPrefix.clear(); + if( cLocalSuffix == ' ') pNew->sSuffix.clear(); + return pNew; +} + +} + +sal_uInt16 NBOTypeMgrBase:: IsSingleLevel(sal_uInt16 nCurLevel) +{ + sal_uInt16 nLv = sal_uInt16(0xFFFF); + sal_uInt16 nCount = 0; + sal_uInt16 nMask = 1; + for( sal_uInt16 i = 0; i < SVX_MAX_NUM; i++ ) + { + if(nCurLevel & nMask) + { + nCount++; + nLv=i; + } + nMask <<= 1 ; + } + + if ( nCount == 1) + return nLv; + else + return sal_uInt16(0xFFFF); +} + +void NBOTypeMgrBase::SetItems(const SfxItemSet* pArg) { + pSet = pArg; + if ( pSet ) + { + SfxAllItemSet aSet(*pSet); + + const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false); + if (pBulletCharFmt) + aBulletCharFmtName = pBulletCharFmt->GetValue(); + + const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false); + if (pNumCharFmt) + aNumCharFmtName = pNumCharFmt->GetValue(); + + const SfxPoolItem* pItem; + SfxItemState eState = pSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem); + if(eState == SfxItemState::SET) + { + eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE)); + } else { + //sd use different sid for numbering rule + eState = pSet->GetItemState(EE_PARA_NUMBULLET, false, &pItem); + if(eState == SfxItemState::SET) + { + eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(EE_PARA_NUMBULLET)); + } + } + } +} + +void NBOTypeMgrBase::ImplLoad(const OUString& filename) +{ + bIsLoading = true; + MapUnit eOldCoreUnit=eCoreUnit; + eCoreUnit = MapUnit::Map100thMM; + INetURLObject aFile( SvtPathOptions().GetUserConfigPath() ); + aFile.Append( filename); + std::unique_ptr<SvStream> xIStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ )); + if( xIStm ) { + sal_uInt32 nVersion = 0; + sal_Int32 nNumIndex = 0; + xIStm->ReadUInt32( nVersion ); + if (nVersion==DEFAULT_NUMBERING_CACHE_FORMAT_VERSION) //first version + { + xIStm->ReadInt32( nNumIndex ); + while (nNumIndex>=0 && nNumIndex<DEFAULT_NUM_VALUSET_COUNT) { + SvxNumRule aNum(*xIStm); + //bullet color in font properties is not stored correctly. Need set transparency bits manually + for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++) + { + SvxNumberFormat aFmt(aNum.GetLevel(i)); + if (aFmt.GetBulletFont()) { + vcl::Font aFont(*aFmt.GetBulletFont()); + Color c=aFont.GetColor(); + c.SetTransparency(0xFF); + aFont.SetColor(c); + aFmt.SetBulletFont(&aFont); + aNum.SetLevel(i, aFmt); + } + } + RelplaceNumRule(aNum,nNumIndex,0x1/*nLevel*/); + xIStm->ReadInt32( nNumIndex ); + } + } + } + eCoreUnit = eOldCoreUnit; + bIsLoading = false; +} +void NBOTypeMgrBase::ImplStore(const OUString& filename) +{ + if (bIsLoading) return; + MapUnit eOldCoreUnit=eCoreUnit; + eCoreUnit = MapUnit::Map100thMM; + INetURLObject aFile( SvtPathOptions().GetUserConfigPath() ); + aFile.Append( filename); + std::unique_ptr<SvStream> xOStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE )); + if( xOStm ) { + sal_uInt32 nVersion; + sal_Int32 nNumIndex; + nVersion = DEFAULT_NUMBERING_CACHE_FORMAT_VERSION; + xOStm->WriteUInt32( nVersion ); + for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ ) { + if (IsCustomized(nItem)) { + SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR, + 10, false, + SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT); + xOStm->WriteInt32( nItem ); + ApplyNumRule(aDefNumRule,nItem,0x1/*nLevel*/,false,true); + aDefNumRule.Store(*xOStm); + } + } + nNumIndex = -1; + xOStm->WriteInt32( nNumIndex ); //write end flag + } + eCoreUnit = eOldCoreUnit; +} + +// Character Bullet Type lib +BulletsSettings* BulletsTypeMgr::pActualBullets[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr}; +sal_Unicode BulletsTypeMgr::aDynamicBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '}; +sal_Unicode BulletsTypeMgr::aDynamicRTLBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '}; + +BulletsTypeMgr::BulletsTypeMgr() + : NBOTypeMgrBase() +{ + Init(); +} + +namespace { + +class theBulletsTypeMgr : public rtl::Static<BulletsTypeMgr, theBulletsTypeMgr> {}; + +} + +BulletsTypeMgr& BulletsTypeMgr::GetInstance() +{ + return theBulletsTypeMgr::get(); +} + +void BulletsTypeMgr::Init() +{ + const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont(); + + for (sal_uInt16 i=0;i<DEFAULT_BULLET_TYPES;i++) + { + pActualBullets[i] = new BulletsSettings; + pActualBullets[i]->cBulletChar = aDefaultBulletTypes[i]; + pActualBullets[i]->aFont = rActBulletFont; + pActualBullets[i]->sDescription = SvxResId( RID_SVXSTR_BULLET_DESCRIPTION_0 + i ); + } +} +sal_uInt16 BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex) +{ + if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0) + return sal_uInt16(0xFFFF); + //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF; + + sal_uInt16 nActLv = IsSingleLevel(mLevel); + + if ( nActLv == sal_uInt16(0xFFFF) ) + return sal_uInt16(0xFFFF); + + const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv)); + sal_Unicode cChar = aFmt.GetBulletChar(); + for(sal_uInt16 i = nFromIndex; i < DEFAULT_BULLET_TYPES; i++) + { + if ( (cChar == pActualBullets[i]->cBulletChar) || + (cChar == 9830 && 57356 == pActualBullets[i]->cBulletChar) || + (cChar == 9632 && 57354 == pActualBullets[i]->cBulletChar) ) + { + return i+1; + } + } + + return sal_uInt16(0xFFFF); +} + +void BulletsTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) +{ + if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0) + return; + + if ( GetNBOIndexForNumRule(aNum,mLevel) != sal_uInt16(0xFFFF) ) + return; + + sal_uInt16 nActLv = IsSingleLevel(mLevel); + + if ( nActLv == sal_uInt16(0xFFFF) ) + return; + + SvxNumberFormat aFmt(aNum.GetLevel(nActLv)); + sal_Unicode cChar = aFmt.GetBulletChar(); + const vcl::Font* pFont = aFmt.GetBulletFont(); + if ( nIndex >= DEFAULT_BULLET_TYPES ) + return; + + pActualBullets[nIndex]->cBulletChar = cChar; + if ( pFont ) + pActualBullets[nIndex]->aFont = *pFont; + pActualBullets[nIndex]->bIsCustomized = true; +} + +void BulletsTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool /*isDefault*/, bool isResetSize) +{ + if ( nIndex >= DEFAULT_BULLET_TYPES ) + return; + sal_Unicode cChar = pActualBullets[nIndex]->cBulletChar; + const vcl::Font& rActBulletFont = pActualBullets[nIndex]->aFont; + + sal_uInt16 nMask = 1; + OUString sBulletCharFormatName = GetBulletCharFmtName(); + for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++) + { + if(mLevel & nMask) + { + SvxNumberFormat aFmt(aNum.GetLevel(i)); + aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL ); + aFmt.SetBulletFont(&rActBulletFont); + aFmt.SetBulletChar(cChar ); + aFmt.SetCharFormatName(sBulletCharFormatName); + aFmt.SetPrefix( "" ); + aFmt.SetSuffix( "" ); + if (isResetSize) aFmt.SetBulletRelSize(45); + aNum.SetLevel(i, aFmt); + } + nMask <<= 1; + } +} + +OUString BulletsTypeMgr::GetDescription(sal_uInt16 nIndex, bool /*isDefault*/) +{ + OUString sRet; + + if ( nIndex >= DEFAULT_BULLET_TYPES ) + return sRet; + else + sRet = pActualBullets[nIndex]->sDescription; + + return sRet; +} + +bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex) +{ + bool bRet = false; + + if ( nIndex >= DEFAULT_BULLET_TYPES ) + bRet = false; + else + bRet = pActualBullets[nIndex]->bIsCustomized; + + return bRet; +} + +// Numbering Type lib +NumberingTypeMgr::NumberingTypeMgr() + : NBOTypeMgrBase() +{ + Init(); + maDefaultNumberSettingsArr = maNumberSettingsArr; + ImplLoad("standard.syb"); +} + +NumberingTypeMgr::~NumberingTypeMgr() +{ +} + +static const char* RID_SVXSTR_SINGLENUM_DESCRIPTIONS[] = +{ + RID_SVXSTR_SINGLENUM_DESCRIPTION_0, + RID_SVXSTR_SINGLENUM_DESCRIPTION_1, + RID_SVXSTR_SINGLENUM_DESCRIPTION_2, + RID_SVXSTR_SINGLENUM_DESCRIPTION_3, + RID_SVXSTR_SINGLENUM_DESCRIPTION_4, + RID_SVXSTR_SINGLENUM_DESCRIPTION_5, + RID_SVXSTR_SINGLENUM_DESCRIPTION_6, + RID_SVXSTR_SINGLENUM_DESCRIPTION_7 +}; + +namespace { + +class theNumberingTypeMgr : public rtl::Static<NumberingTypeMgr, theNumberingTypeMgr> {}; + +} + +NumberingTypeMgr& NumberingTypeMgr::GetInstance() +{ + return theNumberingTypeMgr::get(); +} + +void NumberingTypeMgr::Init() +{ + Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext(); + Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext ); + + Sequence< Sequence< PropertyValue > > aNumberings; + Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale()); + try + { + aNumberings = xDefNum->getDefaultContinuousNumberingLevels( aLocale ); + + sal_Int32 nLength = aNumberings.getLength(); + + const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray(); + for(sal_Int32 i = 0; i < nLength; i++) + { + NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(pValuesArr[i]); + std::shared_ptr<NumberSettings_Impl> pNumEntry = std::make_shared<NumberSettings_Impl>(); + pNumEntry->pNumSetting = pNew; + if ( i < 8 ) + pNumEntry->sDescription = SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS[i]); + maNumberSettingsArr.push_back(pNumEntry); + } + } + catch(Exception&) + { + } +} + +sal_uInt16 NumberingTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex) +{ + if ( mLevel == sal_uInt16(0xFFFF) || mLevel > aNum.GetLevelCount() || mLevel == 0) + return sal_uInt16(0xFFFF); + + sal_uInt16 nActLv = IsSingleLevel(mLevel); + + if ( nActLv == sal_uInt16(0xFFFF) ) + return sal_uInt16(0xFFFF); + + const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv)); + //sal_Unicode cPrefix = OUString(aFmt.GetPrefix())[0]; + //sal_Unicode cSuffix = :OUString(aFmt.GetSuffix())[0]; + const OUString& sPrefix = aFmt.GetPrefix(); + const OUString& sLclSuffix = aFmt.GetSuffix(); + sal_Int16 eNumType = aFmt.GetNumberingType(); + + sal_uInt16 nCount = maNumberSettingsArr.size(); + for(sal_uInt16 i = nFromIndex; i < nCount; ++i) + { + NumberSettings_Impl* _pSet = maNumberSettingsArr[i].get(); + sal_Int16 eNType = _pSet->pNumSetting->nNumberType; + OUString sLocalPrefix = _pSet->pNumSetting->sPrefix; + OUString sLocalSuffix = _pSet->pNumSetting->sSuffix; + if (sPrefix == sLocalPrefix && + sLclSuffix == sLocalSuffix && + eNumType == eNType ) + { + return i+1; + } + } + + + return sal_uInt16(0xFFFF); +} + +void NumberingTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) +{ + sal_uInt16 nActLv = IsSingleLevel(mLevel); + + if ( nActLv == sal_uInt16(0xFFFF) ) + return; + + const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv)); + SvxNumType eNumType = aFmt.GetNumberingType(); + + sal_uInt16 nCount = maNumberSettingsArr.size(); + if ( nIndex >= nCount ) + return; + + NumberSettings_Impl* _pSet = maNumberSettingsArr[nIndex].get(); + + _pSet->pNumSetting->sPrefix = aFmt.GetPrefix(); + _pSet->pNumSetting->sSuffix = aFmt.GetSuffix(); + _pSet->pNumSetting->nNumberType = eNumType; + _pSet->bIsCustomized = true; + + SvxNumRule aTmpRule1(aNum); + SvxNumRule aTmpRule2(aNum); + ApplyNumRule(aTmpRule1,nIndex,mLevel,true); + ApplyNumRule(aTmpRule2,nIndex,mLevel); + if (aTmpRule1==aTmpRule2) _pSet->bIsCustomized=false; + if (!_pSet->bIsCustomized) { + _pSet->sDescription = GetDescription(nIndex,true); + } + ImplStore("standard.syb"); +} + +void NumberingTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault, bool isResetSize) +{ + if(maNumberSettingsArr.size() <= nIndex) + return; + NumberSettingsArr_Impl* pCurrentNumberSettingsArr = &maNumberSettingsArr; + if (isDefault) pCurrentNumberSettingsArr = &maDefaultNumberSettingsArr; + NumberSettings_Impl* _pSet = (*pCurrentNumberSettingsArr)[nIndex].get(); + SvxNumType eNewType = _pSet->pNumSetting->nNumberType; + + sal_uInt16 nMask = 1; + OUString sNumCharFmtName = GetNumCharFmtName(); + for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++) + { + if(mLevel & nMask) + { + SvxNumberFormat aFmt(aNum.GetLevel(i)); + if (eNewType!=aFmt.GetNumberingType()) isResetSize=true; + aFmt.SetNumberingType(eNewType); + aFmt.SetPrefix(_pSet->pNumSetting->sPrefix); + aFmt.SetSuffix(_pSet->pNumSetting->sSuffix); + + aFmt.SetCharFormatName(sNumCharFmtName); + if (isResetSize) aFmt.SetBulletRelSize(100); + aNum.SetLevel(i, aFmt); + } + nMask <<= 1 ; + } +} + +OUString NumberingTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault) +{ + OUString sRet; + sal_uInt16 nLength = maNumberSettingsArr.size(); + + if ( nIndex >= nLength ) + return sRet; + else + sRet = maNumberSettingsArr[nIndex]->sDescription; + if (isDefault) sRet = maDefaultNumberSettingsArr[nIndex]->sDescription; + + return sRet; +} + +bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex) +{ + bool bRet = false; + sal_uInt16 nLength = maNumberSettingsArr.size(); + + if ( nIndex >= nLength ) + bRet = false; + else + bRet = maNumberSettingsArr[nIndex]->bIsCustomized; + + return bRet; +} +// Multi-level /Outline Type lib +OutlineTypeMgr::OutlineTypeMgr() + : NBOTypeMgrBase() +{ + Init(); + for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ ) + { + pDefaultOutlineSettingsArrs[nItem] = pOutlineSettingsArrs[nItem]; + } + //Initial the first time to store the default value. Then do it again for customized value + Init(); + ImplLoad("standard.syc"); +} + +namespace { + +class theOutlineTypeMgr : public rtl::Static<OutlineTypeMgr, theOutlineTypeMgr> {}; + +} + +OutlineTypeMgr& OutlineTypeMgr::GetInstance() +{ + return theOutlineTypeMgr::get(); +} + +void OutlineTypeMgr::Init() +{ + Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext(); + Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext ); + + Sequence<Reference<XIndexAccess> > aOutlineAccess; + Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale()); + try + { + aOutlineAccess = xDefNum->getDefaultOutlineNumberings( aLocale ); + + SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR, + 10, false, + SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT); + + auto nSize = std::min<sal_Int32>(aOutlineAccess.getLength(), DEFAULT_NUM_VALUSET_COUNT); + for(sal_Int32 nItem = 0; nItem < nSize; nItem++ ) + { + pOutlineSettingsArrs[ nItem ] = new OutlineSettings_Impl; + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[ nItem ]; + pItemArr->sDescription = SvxResId( RID_SVXSTR_OUTLINENUM_DESCRIPTION_0 + nItem ); + pItemArr->pNumSettingsArr = new NumSettingsArr_Impl; + Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem]; + for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++) + { + Any aValueAny = xLevel->getByIndex(nLevel); + Sequence<PropertyValue> aLevelProps; + aValueAny >>= aLevelProps; + NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(aLevelProps); + const SvxNumberFormat& aNumFmt( aDefNumRule.GetLevel( nLevel) ); + pNew->eLabelFollowedBy = aNumFmt.GetLabelFollowedBy(); + pNew->nTabValue = aNumFmt.GetListtabPos(); + pNew->eNumAlign = aNumFmt.GetNumAdjust(); + pNew->nNumAlignAt = aNumFmt.GetFirstLineIndent(); + pNew->nNumIndentAt = aNumFmt.GetIndentAt(); + pItemArr->pNumSettingsArr->push_back(std::shared_ptr<NumSettings_Impl>(pNew)); + } + } + } + catch(Exception&) + { + } +} + +sal_uInt16 OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 /*mLevel*/,sal_uInt16 nFromIndex) +{ + sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs); + for(sal_uInt16 iDex = nFromIndex; iDex < nLength; iDex++) + { + bool bNotMatch = false; + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[iDex]; + sal_uInt16 nCount = pItemArr->pNumSettingsArr->size(); + for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++) + { + NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get(); + sal_Int16 eNType = _pSet->nNumberType; + + const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel)); + const OUString& sPrefix = aFmt.GetPrefix(); + const OUString& sLclSuffix = aFmt.GetSuffix(); + sal_Int16 eNumType = aFmt.GetNumberingType(); + if( eNumType == SVX_NUM_CHAR_SPECIAL) + { + sal_Unicode cChar = aFmt.GetBulletChar(); + sal_Unicode ccChar = _pSet->sBulletChar[0]; + if ( !((cChar == ccChar) && + _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() && + _pSet->nTabValue == aFmt.GetListtabPos() && + _pSet->eNumAlign == aFmt.GetNumAdjust() && + _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() && + _pSet->nNumIndentAt == aFmt.GetIndentAt())) + { + bNotMatch = true; + break; + } + }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) { + const SvxBrushItem* pBrsh1 = aFmt.GetBrush(); + const SvxBrushItem* pBrsh2 = _pSet->pBrushItem; + bool bIsMatch = false; + if (pBrsh1==pBrsh2) bIsMatch = true; + if (pBrsh1 && pBrsh2) { + const Graphic* pGrf1 = pBrsh1->GetGraphic(); + const Graphic* pGrf2 = pBrsh2->GetGraphic(); + if (pGrf1==pGrf2) bIsMatch = true; + if (pGrf1 && pGrf2) { + if ( pGrf1->GetBitmapEx() == pGrf2->GetBitmapEx() && + _pSet->aSize == aFmt.GetGraphicSize()) + bIsMatch = true; + } + } + if (!bIsMatch) { + bNotMatch = true; + break; + } + } else + { + if (!(sPrefix == _pSet->sPrefix && + sLclSuffix == _pSet->sSuffix && + eNumType == eNType && + _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() && + _pSet->nTabValue == aFmt.GetListtabPos() && + _pSet->eNumAlign == aFmt.GetNumAdjust() && + _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() && + _pSet->nNumIndentAt == aFmt.GetIndentAt())) + { + bNotMatch = true; + break; + } + } + } + if ( !bNotMatch ) + return iDex+1; + } + + + return sal_uInt16(0xFFFF); +} + +void OutlineTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) +{ + sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs); + if ( nIndex >= nLength ) + return; + + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex]; + sal_uInt16 nCount = pItemArr->pNumSettingsArr->size(); + for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++) + { + const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel)); + SvxNumType eNumType = aFmt.GetNumberingType(); + + NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get(); + + _pSet->eLabelFollowedBy = aFmt.GetLabelFollowedBy(); + _pSet->nTabValue = aFmt.GetListtabPos(); + _pSet->eNumAlign = aFmt.GetNumAdjust(); + _pSet->nNumAlignAt = aFmt.GetFirstLineIndent(); + _pSet->nNumIndentAt = aFmt.GetIndentAt(); + + if( eNumType == SVX_NUM_CHAR_SPECIAL) + { + sal_Unicode cChar = aFmt.GetBulletChar(); + OUString sChar(cChar); + _pSet->sBulletChar = sChar; + if ( aFmt.GetBulletFont() ) + _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName(); + _pSet->nNumberType = eNumType; + pItemArr->bIsCustomized = true; + }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) { + if (_pSet->pBrushItem) { + delete _pSet->pBrushItem; + _pSet->pBrushItem=nullptr; + } + if (aFmt.GetBrush()) + _pSet->pBrushItem = new SvxBrushItem(*aFmt.GetBrush()); + _pSet->aSize = aFmt.GetGraphicSize(); + _pSet->nNumberType = eNumType; + } else + { + _pSet->sPrefix = aFmt.GetPrefix(); + _pSet->sSuffix = aFmt.GetSuffix(); + _pSet->nNumberType = eNumType; + if ( aFmt.GetBulletFont() ) + _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName(); + pItemArr->bIsCustomized = true; + } + } + SvxNumRule aTmpRule1(aNum); + SvxNumRule aTmpRule2(aNum); + ApplyNumRule(aTmpRule1,nIndex,mLevel,true); + ApplyNumRule(aTmpRule2,nIndex,mLevel); + if (aTmpRule1==aTmpRule2) pItemArr->bIsCustomized=false; + if (!pItemArr->bIsCustomized) { + pItemArr->sDescription = GetDescription(nIndex,true); + } + ImplStore("standard.syc"); +} + +void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 /*mLevel*/, bool isDefault, bool isResetSize) +{ + DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT > nIndex, "wrong index"); + if(DEFAULT_NUM_VALUSET_COUNT <= nIndex) + return; + + const FontList* pList = nullptr; + + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex]; + if (isDefault) pItemArr=pDefaultOutlineSettingsArrs[nIndex]; + + NumSettingsArr_Impl *pNumSettingsArr=pItemArr->pNumSettingsArr; + + NumSettings_Impl* pLevelSettings = nullptr; + for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++) + { + if(pNumSettingsArr->size() > i) + pLevelSettings = (*pNumSettingsArr)[i].get(); + + if(!pLevelSettings) + break; + + SvxNumberFormat aFmt(aNum.GetLevel(i)); + const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont(); + if (pLevelSettings->nNumberType !=aFmt.GetNumberingType()) isResetSize=true; + aFmt.SetNumberingType( pLevelSettings->nNumberType ); + sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering); + if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL) + { + if( pLevelSettings->sBulletFont.getLength() && + pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName() ) + { + //search for the font + if(!pList) + { + SfxObjectShell* pCurDocShell = SfxObjectShell::Current(); + const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>( pCurDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) ); + pList = pFontListItem ? pFontListItem->GetFontList() : nullptr; + } + if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) ) + { + FontMetric aFontMetric = pList->Get(pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE); + vcl::Font aFont(aFontMetric); + aFmt.SetBulletFont(&aFont); + } + else + { + //if it cannot be found then create a new one + vcl::Font aCreateFont( pLevelSettings->sBulletFont, OUString(), Size( 0, 14 ) ); + aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW ); + aCreateFont.SetFamily( FAMILY_DONTKNOW ); + aCreateFont.SetPitch( PITCH_DONTKNOW ); + aCreateFont.SetWeight( WEIGHT_DONTKNOW ); + aCreateFont.SetTransparent( true ); + aFmt.SetBulletFont( &aCreateFont ); + } + }else + aFmt.SetBulletFont( &rActBulletFont ); + + sal_Unicode cChar = 0; + if( !pLevelSettings->sBulletChar.isEmpty() ) + cChar = pLevelSettings->sBulletChar[0]; + if( AllSettings::GetLayoutRTL() ) + { + if( 0 == i && cChar == BulletsTypeMgr::aDynamicBulletTypes[5] ) + cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[5]; + else if( 1 == i ) + { + const SvxNumberFormat& numberFmt = aNum.GetLevel(0); + if( numberFmt.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes[5] ) + cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[4]; + } + } + + aFmt.SetBulletChar(cChar); + aFmt.SetCharFormatName( GetBulletCharFmtName() ); + if (isResetSize) aFmt.SetBulletRelSize(45); + }else if ((aFmt.GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) { + if (pLevelSettings->pBrushItem) { + const Graphic* pGrf = pLevelSettings->pBrushItem->GetGraphic(); + Size aSize = pLevelSettings->aSize; + sal_Int16 eOrient = text::VertOrientation::LINE_CENTER; + if (!isResetSize && aFmt.GetGraphicSize()!=Size(0,0))\ + aSize = aFmt.GetGraphicSize(); + else if (aSize.IsEmpty() && pGrf) + aSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf ); + aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(GetMapUnit())); + aFmt.SetGraphicBrush( pLevelSettings->pBrushItem, &aSize, &eOrient ); + } + } else + { + aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? aNum.GetLevelCount() : 0)); + aFmt.SetCharFormatName(GetNumCharFmtName()); + if (isResetSize) aFmt.SetBulletRelSize(100); + } + if(pNumSettingsArr->size() > i) { + aFmt.SetLabelFollowedBy(pLevelSettings->eLabelFollowedBy); + aFmt.SetListtabPos(pLevelSettings->nTabValue); + aFmt.SetNumAdjust(pLevelSettings->eNumAlign); + aFmt.SetFirstLineIndent(pLevelSettings->nNumAlignAt); + aFmt.SetIndentAt(pLevelSettings->nNumIndentAt); + } + aFmt.SetPrefix(pLevelSettings->sPrefix); + aFmt.SetSuffix(pLevelSettings->sSuffix); + aNum.SetLevel(i, aFmt); + } +} + +OUString OutlineTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault) +{ + OUString sRet; + + if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) ) + return sRet; + else + { + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex]; + if (isDefault) pItemArr = pDefaultOutlineSettingsArrs[nIndex]; + if ( pItemArr ) + { + sRet = pItemArr->sDescription; + } + } + return sRet; +} + +bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex) +{ + bool bRet = false; + + if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) ) + return bRet; + else + { + OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex]; + if ( pItemArr ) + { + bRet = pItemArr->bIsCustomized; + } + } + + return bRet; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/nbdtmgfact.cxx b/svx/source/sidebar/nbdtmgfact.cxx new file mode 100644 index 000000000..b5263c761 --- /dev/null +++ b/svx/source/sidebar/nbdtmgfact.cxx @@ -0,0 +1,43 @@ +/* -*- 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 <svx/nbdtmgfact.hxx> + +namespace svx::sidebar::NBOutlineTypeMgrFact { + +NBOTypeMgrBase* CreateInstance(const NBOType aType) +{ + if ( aType == NBOType::Bullets ) + { + return &BulletsTypeMgr::GetInstance(); + } + else if ( aType == NBOType::Numbering ) + { + return &NumberingTypeMgr::GetInstance(); + } + else if ( aType == NBOType::Outline ) + { + return &OutlineTypeMgr::GetInstance(); + } + return nullptr; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx new file mode 100644 index 000000000..4e52822f7 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.cxx @@ -0,0 +1,414 @@ +/* -*- 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 "ParaLineSpacingControl.hxx" + +#include <editeng/editids.hrc> +#include <editeng/lspcitem.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/module.hxx> +#include <sfx2/sfxsids.hrc> +#include <sfx2/viewfrm.hxx> +#include <svtools/unitconv.hxx> + +#include <svl/intitem.hxx> +#include <svl/itempool.hxx> + +#include <svx/ParaLineSpacingPopup.hxx> + +#define DEFAULT_LINE_SPACING 200 +#define FIX_DIST_DEF 283 +#define LINESPACE_1 100 +#define LINESPACE_15 150 +#define LINESPACE_2 200 +#define LINESPACE_115 115 + +// values of the mxLineDist listbox +#define LLINESPACE_1 0 +#define LLINESPACE_115 1 +#define LLINESPACE_15 2 +#define LLINESPACE_2 3 +#define LLINESPACE_PROP 4 +#define LLINESPACE_MIN 5 +#define LLINESPACE_DURCH 6 +#define LLINESPACE_FIX 7 + +#define MIN_FIXED_DISTANCE 28 + +using namespace svx; + +ParaLineSpacingControl::ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pControl, weld::Widget* pParent) + : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/paralinespacingcontrol.ui", "ParaLineSpacingControl") + , mxControl(pControl) + , meLNSpaceUnit(MapUnit::Map100thMM) + , mxSpacing1Button(m_xBuilder->weld_button("spacing_1")) + , mxSpacing115Button(m_xBuilder->weld_button("spacing_115")) + , mxSpacing15Button(m_xBuilder->weld_button("spacing_15")) + , mxSpacing2Button(m_xBuilder->weld_button("spacing_2")) + , mxLineDist(m_xBuilder->weld_combo_box("line_dist")) + , mxLineDistLabel(m_xBuilder->weld_label("value_label")) + , mxLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("percent_box", FieldUnit::PERCENT)) + , mxLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("metric_box", FieldUnit::CM)) + , mpActLineDistFld(mxLineDistAtPercentBox.get()) +{ + Link<weld::Button&,void> aLink = LINK(this, ParaLineSpacingControl, PredefinedValuesHandler); + mxSpacing1Button->connect_clicked(aLink); + mxSpacing115Button->connect_clicked(aLink); + mxSpacing15Button->connect_clicked(aLink); + mxSpacing2Button->connect_clicked(aLink); + + Link<weld::ComboBox&,void> aLink3 = LINK( this, ParaLineSpacingControl, LineSPDistHdl_Impl ); + mxLineDist->connect_changed(aLink3); + SelectEntryPos(LLINESPACE_1); + + Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, ParaLineSpacingControl, LineSPDistAtHdl_Impl ); + mxLineDistAtPercentBox->connect_value_changed( aLink2 ); + mxLineDistAtMetricBox->connect_value_changed( aLink2 ); + + FieldUnit eUnit = FieldUnit::INCH; + const SfxPoolItem* pItem = nullptr; + SfxViewFrame* pCurrent = SfxViewFrame::Current(); + if (pCurrent && pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_METRIC, pItem) >= SfxItemState::DEFAULT) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue()); + else + eUnit = SfxModule::GetCurrentFieldUnit(); + + SetFieldUnit(*mxLineDistAtMetricBox, eUnit); + + Initialize(); +} + +void ParaLineSpacingControl::GrabFocus() +{ + mxSpacing1Button->grab_focus(); +} + +ParaLineSpacingControl::~ParaLineSpacingControl() +{ +} + +void ParaLineSpacingControl::Initialize() +{ + const SfxPoolItem* pItem(nullptr); + SfxViewFrame* pCurrent = SfxViewFrame::Current(); + SfxItemState eState = pCurrent ? pCurrent->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PARA_LINESPACE, pItem) : SfxItemState::UNKNOWN; + + const SvxLineSpacingItem* currSPItem = static_cast<const SvxLineSpacingItem*>(pItem); + + mxLineDist->set_sensitive(true); + + if( eState >= SfxItemState::DEFAULT ) + { + MapUnit eUnit = SfxViewFrame::Current()->GetPool().GetMetric( currSPItem->Which() ); + meLNSpaceUnit = eUnit; + + switch( currSPItem->GetLineSpaceRule() ) + { + case SvxLineSpaceRule::Auto: + { + SvxInterLineSpaceRule eInter = currSPItem->GetInterLineSpaceRule(); + + switch( eInter ) + { + case SvxInterLineSpaceRule::Off: + SelectEntryPos(LLINESPACE_1); + break; + + case SvxInterLineSpaceRule::Prop: + { + if ( LINESPACE_1 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_1); + } + else if ( LINESPACE_115 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_115); + } + else if ( LINESPACE_15 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_15); + } + else if ( LINESPACE_2 == currSPItem->GetPropLineSpace() ) + { + SelectEntryPos(LLINESPACE_2); + } + else + { + SelectEntryPos(LLINESPACE_PROP); + mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(currSPItem->GetPropLineSpace()), FieldUnit::PERCENT); + } + } + break; + + case SvxInterLineSpaceRule::Fix: + { + SelectEntryPos(LLINESPACE_DURCH); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetInterLineSpace(), eUnit); + } + break; + default: + break; + } + } + break; + case SvxLineSpaceRule::Fix: + { + SelectEntryPos(LLINESPACE_FIX); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit); + } + break; + + case SvxLineSpaceRule::Min: + { + SelectEntryPos(LLINESPACE_MIN); + SetMetricValue(*mxLineDistAtMetricBox, currSPItem->GetLineHeight(), eUnit); + } + break; + default: + break; + } + } + else if( eState == SfxItemState::DISABLED ) + { + mxLineDist->set_sensitive(false); + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + + } + else + { + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + mxLineDist->set_active(-1); + } + + mxLineDist->save_value(); +} + +void ParaLineSpacingControl::UpdateMetricFields() +{ + switch (mxLineDist->get_active()) + { + case LLINESPACE_1: + case LLINESPACE_115: + case LLINESPACE_15: + case LLINESPACE_2: + if (mpActLineDistFld == mxLineDistAtPercentBox.get()) + mxLineDistAtMetricBox->hide(); + else + mxLineDistAtPercentBox->hide(); + + mxLineDistLabel->set_sensitive(false); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(false); + mpActLineDistFld->set_text(""); + break; + + case LLINESPACE_DURCH: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE); + + if (mxLineDistAtMetricBox->get_text().isEmpty()) + mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::NONE); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_MIN: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + mxLineDistAtMetricBox->set_min(0, FieldUnit::NONE); + + if (mxLineDistAtMetricBox->get_text().isEmpty()) + mxLineDistAtMetricBox->set_value(mxLineDistAtMetricBox->normalize(0), FieldUnit::TWIP); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_PROP: + mxLineDistAtMetricBox->hide(); + + mpActLineDistFld = mxLineDistAtPercentBox.get(); + + if (mxLineDistAtPercentBox->get_text().isEmpty()) + mxLineDistAtPercentBox->set_value(mxLineDistAtPercentBox->normalize(100), FieldUnit::TWIP); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + + case LLINESPACE_FIX: + mxLineDistAtPercentBox->hide(); + + mpActLineDistFld = mxLineDistAtMetricBox.get(); + sal_Int64 nTemp = mxLineDistAtMetricBox->get_value(FieldUnit::NONE); + mxLineDistAtMetricBox->set_min(mxLineDistAtMetricBox->normalize(MIN_FIXED_DISTANCE), FieldUnit::TWIP); + + if (mxLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp) + SetMetricValue(*mxLineDistAtMetricBox, FIX_DIST_DEF, MapUnit::MapTwip); + + mxLineDistLabel->set_sensitive(true); + mpActLineDistFld->show(); + mpActLineDistFld->set_sensitive(true); + break; + } +} + +void ParaLineSpacingControl::SelectEntryPos(sal_Int32 nPos) +{ + mxLineDist->set_active(nPos); + UpdateMetricFields(); +} + +IMPL_LINK_NOARG(ParaLineSpacingControl, LineSPDistHdl_Impl, weld::ComboBox&, void) +{ + UpdateMetricFields(); + ExecuteLineSpace(); +} + +IMPL_LINK_NOARG( ParaLineSpacingControl, LineSPDistAtHdl_Impl, weld::MetricSpinButton&, void ) +{ + ExecuteLineSpace(); +} + +void ParaLineSpacingControl::ExecuteLineSpace() +{ + mxLineDist->save_value(); + + SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE); + const sal_Int32 nPos = mxLineDist->get_active(); + + switch ( nPos ) + { + case LLINESPACE_1: + case LLINESPACE_115: + case LLINESPACE_15: + case LLINESPACE_2: + SetLineSpace(aSpacing, nPos); + break; + + case LLINESPACE_PROP: + SetLineSpace(aSpacing, nPos, mxLineDistAtPercentBox->denormalize(static_cast<long>(mxLineDistAtPercentBox->get_value(FieldUnit::PERCENT)))); + break; + + case LLINESPACE_MIN: + case LLINESPACE_DURCH: + case LLINESPACE_FIX: + SetLineSpace(aSpacing, nPos, GetCoreValue(*mxLineDistAtMetricBox, meLNSpaceUnit)); + break; + + default: + break; + } + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing }); +} + +void ParaLineSpacingControl::SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, long lValue) +{ + switch ( eSpace ) + { + case LLINESPACE_1: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + + case LLINESPACE_115: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_115 ); + break; + + case LLINESPACE_15: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_15 ); + break; + + case LLINESPACE_2: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( LINESPACE_2 ); + break; + + case LLINESPACE_PROP: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) ); + break; + + case LLINESPACE_MIN: + rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + + case LLINESPACE_DURCH: + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto ); + rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) ); + break; + + case LLINESPACE_FIX: + rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue)); + rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix ); + rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); + break; + } +} + +IMPL_LINK(ParaLineSpacingControl, PredefinedValuesHandler, weld::Button&, rControl, void) +{ + if (&rControl == mxSpacing1Button.get()) + { + ExecuteLineSpacing(LLINESPACE_1); + } + else if (&rControl == mxSpacing115Button.get()) + { + ExecuteLineSpacing(LLINESPACE_115); + } + else if (&rControl == mxSpacing15Button.get()) + { + ExecuteLineSpacing(LLINESPACE_15); + } + else if (&rControl == mxSpacing2Button.get()) + { + ExecuteLineSpacing(LLINESPACE_2); + } +} + +void ParaLineSpacingControl::ExecuteLineSpacing(sal_Int32 nEntry) +{ + SvxLineSpacingItem aSpacing(DEFAULT_LINE_SPACING, SID_ATTR_PARA_LINESPACE); + + SetLineSpace(aSpacing, nEntry); + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LINESPACE, SfxCallMode::RECORD, { &aSpacing }); + + // close when the user used the buttons + mxControl->EndPopupMode(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx new file mode 100644 index 000000000..14b335a37 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingControl.hxx @@ -0,0 +1,79 @@ +/* -*- 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 . + */ +#pragma once + +#include <svtools/toolbarmenu.hxx> + +class SvxLineSpacingItem; + +namespace svx +{ +class SvxLineSpacingToolBoxControl; + +class ParaLineSpacingControl : public WeldToolbarPopup +{ +public: + explicit ParaLineSpacingControl(SvxLineSpacingToolBoxControl* pControl, weld::Widget* pParent); + virtual ~ParaLineSpacingControl() override; + + /// Setup the widgets with values from the document. + void Initialize(); + + virtual void GrabFocus() override; + +private: + rtl::Reference<SvxLineSpacingToolBoxControl> mxControl; + + MapUnit meLNSpaceUnit; + + std::unique_ptr<weld::Button> mxSpacing1Button; + std::unique_ptr<weld::Button> mxSpacing115Button; + std::unique_ptr<weld::Button> mxSpacing15Button; + std::unique_ptr<weld::Button> mxSpacing2Button; + + std::unique_ptr<weld::ComboBox> mxLineDist; + + std::unique_ptr<weld::Label> mxLineDistLabel; + std::unique_ptr<weld::MetricSpinButton> mxLineDistAtPercentBox; + std::unique_ptr<weld::MetricSpinButton> mxLineDistAtMetricBox; + weld::MetricSpinButton* mpActLineDistFld; + +private: + /// Take the values from the widgets, and update the paragraph accordingly. + void ExecuteLineSpace(); + + /// Set one particular value. + static void SetLineSpace(SvxLineSpacingItem& rLineSpace, sal_Int32 eSpace, long lValue = 0); + + /// For the buttons - set the values, and close the popup. + void ExecuteLineSpacing(sal_Int32 aEntry); + + /// Set mpActlineDistFld and visibility of mpLineDist* fields according to what is just selected. + void UpdateMetricFields(); + + /// Set the entry and update the metric fields. + void SelectEntryPos(sal_Int32 nPos); + + DECL_LINK(LineSPDistHdl_Impl, weld::ComboBox&, void); + DECL_LINK(LineSPDistAtHdl_Impl, weld::MetricSpinButton&, void); + DECL_LINK(PredefinedValuesHandler, weld::Button&, void); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx new file mode 100644 index 000000000..28bbf44c1 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaLineSpacingPopup.cxx @@ -0,0 +1,98 @@ +/* -*- 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 "ParaLineSpacingControl.hxx" + +#include <svx/ParaLineSpacingPopup.hxx> +#include <vcl/toolbox.hxx> + +using namespace svx; + +SvxLineSpacingToolBoxControl::SvxLineSpacingToolBoxControl(const css::uno::Reference<css::uno::XComponentContext>& rContext) + : PopupWindowController(rContext, nullptr, OUString()) +{ +} + +SvxLineSpacingToolBoxControl::~SvxLineSpacingToolBoxControl() {} + +void SvxLineSpacingToolBoxControl::initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) +{ + PopupWindowController::initialize(rArguments); + + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + } + + ToolBox* pToolBox = nullptr; + sal_uInt16 nId = 0; + if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL) + pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWNONLY | pToolBox->GetItemBits(nId)); +} + +void SAL_CALL SvxLineSpacingToolBoxControl::execute(sal_Int16 /*KeyModifier*/) +{ + if (m_pToolbar) + { + // Toggle the popup also when toolbutton is activated + const OString aId(m_aCommandURL.toUtf8()); + m_pToolbar->set_menu_item_active(aId, !m_pToolbar->get_menu_item_active(aId)); + } + else + { + // Open the popup also when Enter key is pressed. + createPopupWindow(); + } +} + +std::unique_ptr<WeldToolbarPopup> SvxLineSpacingToolBoxControl::weldPopupWindow() +{ + return std::make_unique<ParaLineSpacingControl>(this, m_pToolbar); +} + +VclPtr<vcl::Window> SvxLineSpacingToolBoxControl::createVclPopupWindow( vcl::Window* pParent ) +{ + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<ParaLineSpacingControl>(this, pParent->GetFrameWeld())); + + mxInterimPopover->Show(); + + return mxInterimPopover; +} + +OUString SvxLineSpacingToolBoxControl::getImplementationName() +{ + return "com.sun.star.comp.svx.LineSpacingToolBoxControl"; +} + +css::uno::Sequence<OUString> SvxLineSpacingToolBoxControl::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_svx_LineSpacingToolBoxControl_get_implementation( + css::uno::XComponentContext* rContext, + css::uno::Sequence<css::uno::Any> const & ) +{ + return cppu::acquire( new SvxLineSpacingToolBoxControl( rContext ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx new file mode 100644 index 000000000..12a9eba7e --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx @@ -0,0 +1,509 @@ +/* -*- 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 "ParaPropertyPanel.hxx" +#include <sfx2/dispatch.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/weldutils.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <svx/dlgctrl.hxx> +#include <svx/svxids.hrc> +#include <svl/intitem.hxx> +#include <sfx2/objsh.hxx> +#include <svtools/unitconv.hxx> +#include <sal/log.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { +#define DEFAULT_VALUE 0 + +#define MAX_DURCH 5670 + +#define MAX_SW 1709400 +#define MAX_SC_SD 116220200 +#define NEGA_MAXVALUE -10000000 + +VclPtr<vcl::Window> ParaPropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to ParaPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to ParaPropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to ParaPropertyPanel::Create", nullptr, 2); + + return VclPtr<ParaPropertyPanel>::Create( + pParent, + rxFrame, + pBindings, + rxSidebar); +} + +void ParaPropertyPanel::HandleContextChange ( + const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + { + // Nothing to do. + return; + } + + maContext = rContext; + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + mxTBxVertAlign->show(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + mxTBxVertAlign->show(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + mxTBxVertAlign->hide(); + mxTBxBackColor->show(); + mxTBxNumBullet->show(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Table): + mxTBxVertAlign->show(); + mxTBxBackColor->show(); + mxTBxNumBullet->show(); + ReSize(); + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + mxTBxVertAlign->hide(); + mxTBxBackColor->hide(); + mxTBxNumBullet->hide(); + ReSize(); + break; + + case CombinedEnumContext(Application::Calc, Context::EditCell): + case CombinedEnumContext(Application::Calc, Context::Cell): + case CombinedEnumContext(Application::Calc, Context::Pivot): + case CombinedEnumContext(Application::DrawImpress, Context::Text): + case CombinedEnumContext(Application::DrawImpress, Context::OutlineText): + break; + + default: + break; + } +} + +void ParaPropertyPanel::DataChanged (const DataChangedEvent&) {} + +void ParaPropertyPanel::ReSize() +{ + if (mxSidebar.is()) + mxSidebar->requestLayout(); +} + +void ParaPropertyPanel::InitToolBoxIndent() +{ + Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ModifyIndentHdl_Impl ); + mxLeftIndent->connect_value_changed( aLink ); + mxRightIndent->connect_value_changed( aLink ); + mxFLineIndent->connect_value_changed( aLink ); + + m_eLRSpaceUnit = maLRSpaceControl.GetCoreMetric(); +} + +void ParaPropertyPanel::InitToolBoxSpacing() +{ + Link<weld::MetricSpinButton&,void> aLink = LINK( this, ParaPropertyPanel, ULSpaceHdl_Impl ); + mxTopDist->connect_value_changed(aLink); + mxBottomDist->connect_value_changed( aLink ); + + m_eULSpaceUnit = maULSpaceControl.GetCoreMetric(); +} + +void ParaPropertyPanel::initial() +{ + limitMetricWidths(); + + //toolbox + InitToolBoxIndent(); + InitToolBoxSpacing(); +} + +// for Paragraph Indent +IMPL_LINK_NOARG( ParaPropertyPanel, ModifyIndentHdl_Impl, weld::MetricSpinButton&, void) +{ + SvxLRSpaceItem aMargin( SID_ATTR_PARA_LRSPACE ); + aMargin.SetTextLeft(mxLeftIndent->GetCoreValue(m_eLRSpaceUnit)); + aMargin.SetRight(mxRightIndent->GetCoreValue(m_eLRSpaceUnit)); + aMargin.SetTextFirstLineOffset(static_cast<short>(mxFLineIndent->GetCoreValue(m_eLRSpaceUnit))); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_PARA_LRSPACE, SfxCallMode::RECORD, { &aMargin }); +} + + +// for Paragraph Spacing +IMPL_LINK_NOARG( ParaPropertyPanel, ULSpaceHdl_Impl, weld::MetricSpinButton&, void) +{ + SvxULSpaceItem aMargin( SID_ATTR_PARA_ULSPACE ); + aMargin.SetUpper( static_cast<sal_uInt16>(mxTopDist->GetCoreValue(m_eULSpaceUnit))); + aMargin.SetLower( static_cast<sal_uInt16>(mxBottomDist->GetCoreValue(m_eULSpaceUnit))); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_PARA_ULSPACE, SfxCallMode::RECORD, { &aMargin }); +} + +// for Paragraph State change +void ParaPropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_ATTR_METRIC: + { + m_eMetricUnit = GetCurrentUnit(eState,pState); + if( m_eMetricUnit!=m_last_eMetricUnit ) + { + mxLeftIndent->SetFieldUnit(m_eMetricUnit); + mxRightIndent->SetFieldUnit(m_eMetricUnit); + mxFLineIndent->SetFieldUnit(m_eMetricUnit); + mxTopDist->SetFieldUnit(m_eMetricUnit); + mxBottomDist->SetFieldUnit(m_eMetricUnit); + + limitMetricWidths(); + } + m_last_eMetricUnit = m_eMetricUnit; + } + break; + + case SID_ATTR_PARA_LRSPACE: + StateChangedIndentImpl( eState, pState ); + break; + + case SID_ATTR_PARA_ULSPACE: + StateChangedULImpl( eState, pState ); + break; + } +} + +void ParaPropertyPanel::StateChangedIndentImpl( SfxItemState eState, const SfxPoolItem* pState ) +{ + switch (maContext.GetCombinedContext_DI()) + { + + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + { + mxLeftIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + mxRightIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + mxFLineIndent->set_min( DEFAULT_VALUE, FieldUnit::NONE ); + } + break; + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + { + mxLeftIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + mxRightIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + mxFLineIndent->set_min( NEGA_MAXVALUE, FieldUnit::MM_100TH ); + } + break; + } + + bool bDisabled = eState == SfxItemState::DISABLED; + mxLeftIndent->set_sensitive(!bDisabled); + mxRightIndent->set_sensitive(!bDisabled); + mxFLineIndent->set_sensitive(!bDisabled); + + if (pState && eState >= SfxItemState::DEFAULT) + { + const SvxLRSpaceItem* pSpace = static_cast<const SvxLRSpaceItem*>(pState); + maTxtLeft = pSpace->GetTextLeft(); + maTxtLeft = OutputDevice::LogicToLogic( maTxtLeft, m_eLRSpaceUnit, MapUnit::Map100thMM ); + maTxtLeft = OutputDevice::LogicToLogic( maTxtLeft, MapUnit::Map100thMM, MapUnit::MapTwip ); + + long aTxtRight = pSpace->GetRight(); + aTxtRight = OutputDevice::LogicToLogic( aTxtRight, m_eLRSpaceUnit, MapUnit::Map100thMM ); + aTxtRight = OutputDevice::LogicToLogic( aTxtRight, MapUnit::Map100thMM, MapUnit::MapTwip ); + + long aTxtFirstLineOfst = pSpace->GetTextFirstLineOffset(); + aTxtFirstLineOfst = OutputDevice::LogicToLogic( aTxtFirstLineOfst, m_eLRSpaceUnit, MapUnit::Map100thMM ); + aTxtFirstLineOfst = OutputDevice::LogicToLogic( aTxtFirstLineOfst, MapUnit::Map100thMM, MapUnit::MapTwip ); + + long nVal = OutputDevice::LogicToLogic( maTxtLeft, MapUnit::MapTwip, MapUnit::Map100thMM ); + nVal = static_cast<long>(mxLeftIndent->normalize( nVal )); + + if ( maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Text) + && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Default) + && maContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Table)) + { + mxFLineIndent->set_min( nVal*-1, FieldUnit::MM_100TH ); + } + + long nrVal = OutputDevice::LogicToLogic( aTxtRight, MapUnit::MapTwip, MapUnit::Map100thMM ); + nrVal = static_cast<long>(mxRightIndent->normalize( nrVal )); + + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + { + mxLeftIndent->set_max( MAX_SW - nrVal, FieldUnit::MM_100TH ); + mxRightIndent->set_max( MAX_SW - nVal, FieldUnit::MM_100TH ); + mxFLineIndent->set_max( MAX_SW - nVal - nrVal, FieldUnit::MM_100TH ); + } + break; + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + { + mxLeftIndent->set_max( MAX_SC_SD - nrVal, FieldUnit::MM_100TH ); + mxRightIndent->set_max( MAX_SC_SD - nVal, FieldUnit::MM_100TH ); + mxFLineIndent->set_max( MAX_SC_SD - nVal - nrVal, FieldUnit::MM_100TH ); + } + } + + mxLeftIndent->set_value( nVal, FieldUnit::MM_100TH ); + mxRightIndent->set_value( nrVal, FieldUnit::MM_100TH ); + + long nfVal = OutputDevice::LogicToLogic( aTxtFirstLineOfst, MapUnit::MapTwip, MapUnit::Map100thMM ); + nfVal = static_cast<long>(mxFLineIndent->normalize( nfVal )); + mxFLineIndent->set_value( nfVal, FieldUnit::MM_100TH ); + } + else if (eState != SfxItemState::DISABLED ) + { + mxLeftIndent->set_text(""); + mxRightIndent->set_text(""); + mxFLineIndent->set_text(""); + } + + limitMetricWidths(); +} + +void ParaPropertyPanel::StateChangedULImpl( SfxItemState eState, const SfxPoolItem* pState ) +{ + mxTopDist->set_max( mxTopDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) ); + mxBottomDist->set_max( mxBottomDist->normalize( MAX_DURCH ), MapToFieldUnit(m_eULSpaceUnit) ); + + bool bDisabled = eState == SfxItemState::DISABLED; + mxTopDist->set_sensitive(!bDisabled); + mxBottomDist->set_sensitive(!bDisabled); + + if( pState && eState >= SfxItemState::DEFAULT ) + { + const SvxULSpaceItem* pOldItem = static_cast<const SvxULSpaceItem*>(pState); + + maUpper = pOldItem->GetUpper(); + maUpper = OutputDevice::LogicToLogic( maUpper, m_eULSpaceUnit, MapUnit::Map100thMM ); + maUpper = OutputDevice::LogicToLogic( maUpper, MapUnit::Map100thMM, MapUnit::MapTwip ); + + maLower = pOldItem->GetLower(); + maLower = OutputDevice::LogicToLogic( maLower, m_eULSpaceUnit, MapUnit::Map100thMM ); + maLower = OutputDevice::LogicToLogic( maLower, MapUnit::Map100thMM, MapUnit::MapTwip ); + + sal_Int64 nVal = OutputDevice::LogicToLogic( maUpper, MapUnit::MapTwip, MapUnit::Map100thMM ); + nVal = mxTopDist->normalize( nVal ); + mxTopDist->set_value( nVal, FieldUnit::MM_100TH ); + + nVal = OutputDevice::LogicToLogic( maLower, MapUnit::MapTwip, MapUnit::Map100thMM ); + nVal = mxBottomDist->normalize( nVal ); + mxBottomDist->set_value( nVal, FieldUnit::MM_100TH ); + } + else if (eState != SfxItemState::DISABLED ) + { + mxTopDist->set_text(""); + mxBottomDist->set_text(""); + } + limitMetricWidths(); +} + +FieldUnit ParaPropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ) +{ + FieldUnit eUnit = FieldUnit::NONE; + + if ( pState && eState >= SfxItemState::DEFAULT ) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pState)->GetValue()); + else + { + SfxViewFrame* pFrame = SfxViewFrame::Current(); + SfxObjectShell* pSh = nullptr; + if ( pFrame ) + pSh = pFrame->GetObjectShell(); + if ( pSh ) //the object shell is not always available during reload + { + SfxModule* pModule = pSh->GetModule(); + if ( pModule ) + { + const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC ); + if ( pItem ) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue()); + } + else + { + SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found"); + } + } + } + + return eUnit; +} + +ParaPropertyPanel::ParaPropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) + : PanelLayout(pParent, "ParaPropertyPanel", "svx/ui/sidebarparagraph.ui", rxFrame), + //Alignment + mxTBxHorzAlign(m_xBuilder->weld_toolbar("horizontalalignment")), + mxHorzAlignDispatch(new ToolbarUnoDispatcher(*mxTBxHorzAlign, *m_xBuilder, rxFrame)), + mxTBxVertAlign(m_xBuilder->weld_toolbar("verticalalignment")), + mxVertAlignDispatch(new ToolbarUnoDispatcher(*mxTBxVertAlign, *m_xBuilder, rxFrame)), + //NumBullet&Backcolor + mxTBxNumBullet(m_xBuilder->weld_toolbar("numberbullet")), + mxNumBulletDispatch(new ToolbarUnoDispatcher(*mxTBxNumBullet, *m_xBuilder, rxFrame)), + mxTBxBackColor(m_xBuilder->weld_toolbar("backgroundcolor")), + mxBackColorDispatch(new ToolbarUnoDispatcher(*mxTBxBackColor, *m_xBuilder, rxFrame)), + mxTBxWriteDirection(m_xBuilder->weld_toolbar("writedirection")), + mxWriteDirectionDispatch(new ToolbarUnoDispatcher(*mxTBxWriteDirection, *m_xBuilder, rxFrame)), + mxTBxParaSpacing(m_xBuilder->weld_toolbar("paraspacing")), + mxParaSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxParaSpacing, *m_xBuilder, rxFrame)), + mxTBxLineSpacing(m_xBuilder->weld_toolbar("linespacing")), + mxLineSpacingDispatch(new ToolbarUnoDispatcher(*mxTBxLineSpacing, *m_xBuilder, rxFrame)), + mxTBxIndent(m_xBuilder->weld_toolbar("indent")), + mxIndentDispatch(new ToolbarUnoDispatcher(*mxTBxIndent, *m_xBuilder, rxFrame)), + //Paragraph spacing + mxTopDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("aboveparaspacing", FieldUnit::CM))), + mxBottomDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("belowparaspacing", FieldUnit::CM))), + mxLeftIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("beforetextindent", FieldUnit::CM))), + mxRightIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("aftertextindent", FieldUnit::CM))), + mxFLineIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("firstlineindent", FieldUnit::CM))), + maTxtLeft (0), + maUpper (0), + maLower (0), + m_eMetricUnit(FieldUnit::NONE), + m_last_eMetricUnit(FieldUnit::NONE), + m_eLRSpaceUnit(), + m_eULSpaceUnit(), + maLRSpaceControl (SID_ATTR_PARA_LRSPACE,*pBindings,*this), + maULSpaceControl (SID_ATTR_PARA_ULSPACE, *pBindings,*this), + m_aMetricCtl (SID_ATTR_METRIC, *pBindings,*this), + maContext(), + mpBindings(pBindings), + mxSidebar(rxSidebar) +{ + // tdf#130197 We want to give this toolbar a width as if it had 5 entries + // (the parent grid has homogeneous width set so both columns will have the + // same width). This ParaPropertyPanel is a default panel in writer, so + // subsequent panels, e.g. the TableEditPanel panel can have up to 5 + // entries in each of its column and remain in alignment with this panel + padWidthForSidebar(*mxTBxIndent, rxFrame); + + initial(); + m_aMetricCtl.RequestUpdate(); +} + +void ParaPropertyPanel::limitMetricWidths() +{ + limitWidthForSidebar(*mxTopDist); + limitWidthForSidebar(*mxBottomDist); + limitWidthForSidebar(*mxLeftIndent); + limitWidthForSidebar(*mxRightIndent); + limitWidthForSidebar(*mxFLineIndent); +} + +ParaPropertyPanel::~ParaPropertyPanel() +{ + disposeOnce(); +} + +void ParaPropertyPanel::dispose() +{ + mxHorzAlignDispatch.reset(); + mxTBxHorzAlign.reset(); + + mxVertAlignDispatch.reset(); + mxTBxVertAlign.reset(); + + mxNumBulletDispatch.reset(); + mxTBxNumBullet.reset(); + + mxBackColorDispatch.reset(); + mxTBxBackColor.reset(); + + mxWriteDirectionDispatch.reset(); + mxTBxWriteDirection.reset(); + + mxParaSpacingDispatch.reset(); + mxTBxParaSpacing.reset(); + + mxLineSpacingDispatch.reset(); + mxTBxLineSpacing.reset(); + + mxIndentDispatch.reset(); + mxTBxIndent.reset(); + + mxTopDist.reset(); + mxBottomDist.reset(); + mxLeftIndent.reset(); + mxRightIndent.reset(); + mxFLineIndent.reset(); + + maLRSpaceControl.dispose(); + maULSpaceControl.dispose(); + m_aMetricCtl.dispose(); + + PanelLayout::dispose(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx new file mode 100644 index 000000000..d59712360 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx @@ -0,0 +1,137 @@ +/* -*- 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 . + */ +#pragma once + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <svx/relfld.hxx> + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/ui/XSidebar.hpp> + +#include <svl/poolitem.hxx> +#include <tools/fldunit.hxx> +#include <vcl/EnumContext.hxx> + +class ToolbarUnoDispatcher; + +namespace svx::sidebar { + +class ParaPropertyPanel + : public PanelLayout, + public ::sfx2::sidebar::IContextChangeReceiver, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~ParaPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + + virtual void DataChanged (const DataChangedEvent& rEvent) override; + SfxBindings* GetBindings() { return mpBindings;} + + virtual void HandleContextChange ( + const vcl::EnumContext& rContext) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + static FieldUnit GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ); + + ParaPropertyPanel ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + +private: + // UI controls + //Alignment + std::unique_ptr<weld::Toolbar> mxTBxHorzAlign; + std::unique_ptr<ToolbarUnoDispatcher> mxHorzAlignDispatch; + std::unique_ptr<weld::Toolbar> mxTBxVertAlign; + std::unique_ptr<ToolbarUnoDispatcher> mxVertAlignDispatch; + //NumBullet&Backcolor + std::unique_ptr<weld::Toolbar> mxTBxNumBullet; + std::unique_ptr<ToolbarUnoDispatcher> mxNumBulletDispatch; + std::unique_ptr<weld::Toolbar> mxTBxBackColor; + std::unique_ptr<ToolbarUnoDispatcher> mxBackColorDispatch; + + std::unique_ptr<weld::Toolbar> mxTBxWriteDirection; + std::unique_ptr<ToolbarUnoDispatcher> mxWriteDirectionDispatch; + std::unique_ptr<weld::Toolbar> mxTBxParaSpacing; + std::unique_ptr<ToolbarUnoDispatcher> mxParaSpacingDispatch; + std::unique_ptr<weld::Toolbar> mxTBxLineSpacing; + std::unique_ptr<ToolbarUnoDispatcher> mxLineSpacingDispatch; + std::unique_ptr<weld::Toolbar> mxTBxIndent; + std::unique_ptr<ToolbarUnoDispatcher> mxIndentDispatch; + + //Paragraph spacing + std::unique_ptr<SvxRelativeField> mxTopDist; + std::unique_ptr<SvxRelativeField> mxBottomDist; + std::unique_ptr<SvxRelativeField> mxLeftIndent; + std::unique_ptr<SvxRelativeField> mxRightIndent; + std::unique_ptr<SvxRelativeField> mxFLineIndent; + + // Data Member + long maTxtLeft; + long maUpper; + long maLower; + + FieldUnit m_eMetricUnit; + FieldUnit m_last_eMetricUnit; + MapUnit m_eLRSpaceUnit; + MapUnit m_eULSpaceUnit; + // Control Items + ::sfx2::sidebar::ControllerItem maLRSpaceControl; + ::sfx2::sidebar::ControllerItem maULSpaceControl; + ::sfx2::sidebar::ControllerItem m_aMetricCtl; + + vcl::EnumContext maContext; + SfxBindings* mpBindings; + css::uno::Reference<css::ui::XSidebar> mxSidebar; + + DECL_LINK(ModifyIndentHdl_Impl, weld::MetricSpinButton&, void); + DECL_LINK(ULSpaceHdl_Impl, weld::MetricSpinButton&, void); + + void StateChangedIndentImpl( SfxItemState eState, const SfxPoolItem* pState ); + void StateChangedULImpl( SfxItemState eState, const SfxPoolItem* pState ); + + void initial(); + void ReSize(); + void InitToolBoxIndent(); + void InitToolBoxSpacing(); + void limitMetricWidths(); +}; + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingControl.cxx b/svx/source/sidebar/paragraph/ParaSpacingControl.cxx new file mode 100644 index 000000000..118d14010 --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingControl.cxx @@ -0,0 +1,257 @@ +/* -*- 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 "ParaSpacingWindow.hxx" + +#include <cppuhelper/queryinterface.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/editids.hrc> +#include <svx/ParaSpacingControl.hxx> +#include <vcl/toolbox.hxx> +#include <sfx2/sfxsids.hrc> +#include <svl/intitem.hxx> +#include <comphelper/processfactory.hxx> + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> +#include <com/sun/star/ui/XContextChangeEventMultiplexer.hpp> + +using namespace svx; + +SFX_IMPL_TOOLBOX_CONTROL(ParaAboveSpacingControl, SvxULSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaBelowSpacingControl, SvxULSpaceItem); + +SFX_IMPL_TOOLBOX_CONTROL(ParaLeftSpacingControl, SvxLRSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaRightSpacingControl, SvxLRSpaceItem); +SFX_IMPL_TOOLBOX_CONTROL(ParaFirstLineSpacingControl, SvxLRSpaceItem); + +ParaULSpacingControl::ParaULSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ + addStatusListener(".uno:MetricUnit"); +} + +ParaULSpacingControl::~ParaULSpacingControl() +{ +} + +void ParaULSpacingControl::StateChanged(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + sal_uInt16 nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaULSpacingWindow* pWindow = static_cast<ParaULSpacingWindow*>(rTbx.GetItemWindow(nId)); + + DBG_ASSERT( pWindow, "Control not found!" ); + + if(SfxItemState::DISABLED == eState) + pWindow->Disable(); + else + pWindow->Enable(); + + rTbx.EnableItem(nId, SfxItemState::DISABLED != eState); + + if(nSID == SID_ATTR_METRIC && pState && eState >= SfxItemState::DEFAULT) + { + const SfxUInt16Item* pMetricItem = static_cast<const SfxUInt16Item*>(pState); + pWindow->SetUnit(static_cast<FieldUnit>(pMetricItem->GetValue())); + } + else if((nSID == SID_ATTR_PARA_ULSPACE + || nSID == SID_ATTR_PARA_ABOVESPACE + || nSID == SID_ATTR_PARA_BELOWSPACE ) + && pState && eState >= SfxItemState::DEFAULT) + pWindow->SetValue(static_cast<const SvxULSpaceItem*>(pState)); +} + +// ParaAboveSpacingControl + +ParaAboveSpacingControl::ParaAboveSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + : ParaULSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaAboveSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaAboveSpacingWindow> pWindow = VclPtr<ParaAboveSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaBelowSpacingControl + +ParaBelowSpacingControl::ParaBelowSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + : ParaULSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaBelowSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaBelowSpacingWindow> pWindow = VclPtr<ParaBelowSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaLRSpacingControl + +ParaLRSpacingControl::ParaLRSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) + : SfxToolBoxControl(nSlotId, nId, rTbx) +{ + addStatusListener(".uno:MetricUnit"); +} + +ParaLRSpacingControl::~ParaLRSpacingControl() +{ +} + +void SAL_CALL ParaLRSpacingControl::dispose() +{ + if(m_xMultiplexer.is()) + { + m_xMultiplexer->removeAllContextChangeEventListeners(this); + m_xMultiplexer.clear(); + } + + SfxToolBoxControl::dispose(); +} + +void ParaLRSpacingControl::StateChanged(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + sal_uInt16 nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaLRSpacingWindow* pWindow = static_cast<ParaLRSpacingWindow*>(rTbx.GetItemWindow(nId)); + + DBG_ASSERT( pWindow, "Control not found!" ); + + if(SfxItemState::DISABLED == eState) + pWindow->Disable(); + else + pWindow->Enable(); + + if(!m_xMultiplexer.is() && m_xFrame.is()) + { + m_xMultiplexer = css::ui::ContextChangeEventMultiplexer::get( + ::comphelper::getProcessComponentContext()); + + m_xMultiplexer->addContextChangeEventListener(this, m_xFrame->getController()); + } + + if(nSID == SID_ATTR_METRIC && pState && eState >= SfxItemState::DEFAULT) + { + const SfxUInt16Item* pMetricItem = static_cast<const SfxUInt16Item*>(pState); + pWindow->SetUnit(static_cast<FieldUnit>(pMetricItem->GetValue())); + } + else if(nSID == SID_ATTR_PARA_LRSPACE + || nSID == SID_ATTR_PARA_LEFTSPACE + || nSID == SID_ATTR_PARA_RIGHTSPACE + || nSID == SID_ATTR_PARA_FIRSTLINESPACE + ) + { + pWindow->SetValue(eState, pState); + } +} + +void SAL_CALL ParaLRSpacingControl::notifyContextChangeEvent(const css::ui::ContextChangeEventObject& rEvent) +{ + sal_uInt16 nId = GetId(); + ToolBox& rTbx = GetToolBox(); + ParaLRSpacingWindow* pWindow = static_cast<ParaLRSpacingWindow*>(rTbx.GetItemWindow(nId)); + + if(pWindow) + { + vcl::EnumContext eContext( + vcl::EnumContext::GetApplicationEnum(rEvent.ApplicationName), + vcl::EnumContext::GetContextEnum(rEvent.ContextName)); + pWindow->SetContext(eContext); + } +} + +::css::uno::Any SAL_CALL ParaLRSpacingControl::queryInterface(const ::css::uno::Type& aType) +{ + ::css::uno::Any a(SfxToolBoxControl::queryInterface(aType)); + if (a.hasValue()) + return a; + + return ::cppu::queryInterface(aType, static_cast<css::ui::XContextChangeEventListener*>(this)); +} + +void SAL_CALL ParaLRSpacingControl::acquire() throw () +{ + SfxToolBoxControl::acquire(); +} + +void SAL_CALL ParaLRSpacingControl::disposing(const ::css::lang::EventObject&) +{ + SfxToolBoxControl::disposing(); +} + +void SAL_CALL ParaLRSpacingControl::release() throw () +{ + SfxToolBoxControl::release(); +} + +// ParaLeftSpacingControl + +ParaLeftSpacingControl::ParaLeftSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaLeftSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaLeftSpacingWindow> pWindow = VclPtr<ParaLeftSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaRightSpacingControl + +ParaRightSpacingControl::ParaRightSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaRightSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaRightSpacingWindow> pWindow = VclPtr<ParaRightSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +// ParaFirstLineSpacingControl + +ParaFirstLineSpacingControl::ParaFirstLineSpacingControl(sal_uInt16 nSlotId, sal_uInt16 nId, ToolBox& rTbx) +: ParaLRSpacingControl(nSlotId, nId, rTbx) +{ +} + +VclPtr<InterimItemWindow> ParaFirstLineSpacingControl::CreateItemWindow(vcl::Window* pParent) +{ + VclPtr<ParaFirstLineSpacingWindow> pWindow = VclPtr<ParaFirstLineSpacingWindow>::Create(pParent); + pWindow->Show(); + + return pWindow; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx new file mode 100644 index 000000000..d887a942d --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.cxx @@ -0,0 +1,368 @@ +/* -*- 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 "ParaSpacingWindow.hxx" +#include <editeng/editids.hrc> +#include <editeng/lrspitem.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/app.hxx> +#include <sfx2/viewfrm.hxx> +#include <svl/itempool.hxx> + +using namespace svx; + +#define DEFAULT_VALUE 0 +#define MAX_DURCH 5670 +#define MAX_SW 1709400 +#define MAX_SC_SD 116220200 +#define NEGA_MAXVALUE -10000000 + +// ParaULSpacingWindow + +ParaULSpacingWindow::ParaULSpacingWindow(vcl::Window* pParent) + : InterimItemWindow(pParent, "svx/ui/paraulspacing.ui", "ParaULSpacingWindow") + , m_eUnit(MapUnit::MapTwip) +{ + m_xAboveSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("aboveparaspacing", FieldUnit::CM)); + m_xBelowSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("belowparaspacing", FieldUnit::CM)); + m_xAboveContainer = m_xBuilder->weld_container("above"); + m_xBelowContainer = m_xBuilder->weld_container("below"); + + Link<weld::MetricSpinButton&,void> aLink = LINK(this, ParaULSpacingWindow, ModifySpacingHdl); + m_xAboveSpacing->connect_value_changed(aLink); + m_xBelowSpacing->connect_value_changed(aLink); + + /// set the initial values of max width + m_xAboveSpacing->set_max(m_xAboveSpacing->normalize(MAX_DURCH), FieldUnit::CM); + m_xBelowSpacing->set_max(m_xBelowSpacing->normalize(MAX_DURCH), FieldUnit::CM); +} + +ParaULSpacingWindow::~ParaULSpacingWindow() +{ + disposeOnce(); +} + +void ParaULSpacingWindow::dispose() +{ + m_xAboveSpacing.reset(); + m_xBelowSpacing.reset(); + m_xAboveContainer.reset(); + m_xBelowContainer.reset(); + + InterimItemWindow::dispose(); +} + +void ParaULSpacingWindow::SetUnit(FieldUnit eUnit) +{ + m_xAboveSpacing->SetFieldUnit(eUnit); + m_xBelowSpacing->SetFieldUnit(eUnit); + + SfxItemPool &rPool = SfxGetpApp()->GetPool(); + sal_uInt16 nWhich = rPool.GetWhich(SID_ATTR_PARA_ULSPACE); + m_eUnit = rPool.GetMetric(nWhich); + + m_xAboveSpacing->set_max(m_xAboveSpacing->normalize(MAX_DURCH), MapToFieldUnit(m_eUnit)); + m_xBelowSpacing->set_max(m_xBelowSpacing->normalize(MAX_DURCH), MapToFieldUnit(m_eUnit)); +} + +void ParaULSpacingWindow::SetValue(const SvxULSpaceItem* pItem) +{ + sal_Int64 nVal = pItem->GetUpper(); + nVal = m_xAboveSpacing->normalize(nVal); + m_xAboveSpacing->set_value(nVal, FieldUnit::MM_100TH); + + nVal = pItem->GetLower(); + nVal = m_xBelowSpacing->normalize(nVal); + m_xBelowSpacing->set_value(nVal, FieldUnit::MM_100TH); +} + +IMPL_LINK_NOARG(ParaULSpacingWindow, ModifySpacingHdl, weld::MetricSpinButton&, void) +{ + SfxDispatcher* pDisp = SfxViewFrame::Current()->GetBindings().GetDispatcher(); + if(pDisp) + { + SvxULSpaceItem aMargin(SID_ATTR_PARA_ULSPACE); + aMargin.SetUpper(m_xAboveSpacing->GetCoreValue(m_eUnit)); + aMargin.SetLower(m_xBelowSpacing->GetCoreValue(m_eUnit)); + pDisp->ExecuteList(SID_ATTR_PARA_ULSPACE, SfxCallMode::RECORD, {&aMargin}); + } +} + +// ParaAboveSpacingWindow + +ParaAboveSpacingWindow::ParaAboveSpacingWindow(vcl::Window* pParent) + : ParaULSpacingWindow(pParent) +{ + m_xAboveContainer->show(); + m_xBelowContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +void ParaAboveSpacingWindow::GetFocus() +{ + if (m_xAboveSpacing) + m_xAboveSpacing->grab_focus(); + ParaULSpacingWindow::GetFocus(); +} + +// ParaBelowSpacingWindow + +ParaBelowSpacingWindow::ParaBelowSpacingWindow(vcl::Window* pParent) + : ParaULSpacingWindow(pParent) +{ + m_xAboveContainer->hide(); + m_xBelowContainer->show(); + + SetSizePixel(get_preferred_size()); +} + +void ParaBelowSpacingWindow::GetFocus() +{ + if (m_xBelowSpacing) + m_xBelowSpacing->grab_focus(); + ParaULSpacingWindow::GetFocus(); +} + +// ParaLRSpacingWindow + +ParaLRSpacingWindow::ParaLRSpacingWindow(vcl::Window* pParent) + : InterimItemWindow(pParent, "svx/ui/paralrspacing.ui", "ParaLRSpacingWindow") + , m_eUnit(MapUnit::MapTwip) +{ + m_xBeforeSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("beforetextindent", FieldUnit::CM)); + m_xAfterSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("aftertextindent", FieldUnit::CM)); + m_xFLSpacing = std::make_unique<SvxRelativeField>(m_xBuilder->weld_metric_spin_button("firstlineindent", FieldUnit::CM)); + m_xBeforeContainer = m_xBuilder->weld_container("before"); + m_xAfterContainer = m_xBuilder->weld_container("after"); + m_xFirstLineContainer = m_xBuilder->weld_container("firstline"); + + Link<weld::MetricSpinButton&,void> aLink = LINK(this, ParaLRSpacingWindow, ModifySpacingHdl); + m_xBeforeSpacing->connect_value_changed(aLink); + m_xAfterSpacing->connect_value_changed(aLink); + m_xFLSpacing->connect_value_changed(aLink); + + /// set the initial values of max width + m_xBeforeSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xAfterSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xFLSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); +} + +ParaLRSpacingWindow::~ParaLRSpacingWindow() +{ + disposeOnce(); +} + +void ParaLRSpacingWindow::dispose() +{ + m_xBeforeSpacing.reset(); + m_xAfterSpacing.reset(); + m_xFLSpacing.reset(); + m_xBeforeContainer.reset(); + m_xAfterContainer.reset(); + m_xFirstLineContainer.reset(); + + InterimItemWindow::dispose(); +} + +void ParaLRSpacingWindow::SetContext(const vcl::EnumContext& eContext) +{ + m_aContext = eContext; +} + +void ParaLRSpacingWindow::SetValue(SfxItemState eState, const SfxPoolItem* pState) +{ + switch(m_aContext.GetCombinedContext_DI()) + { + + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + { + m_xBeforeSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + m_xAfterSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + m_xFLSpacing->set_min(DEFAULT_VALUE, FieldUnit::NONE); + } + break; + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + { + m_xBeforeSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xAfterSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + m_xFLSpacing->set_min(NEGA_MAXVALUE, FieldUnit::MM_100TH); + } + break; + } + + if(pState && eState >= SfxItemState::DEFAULT) + { + m_xBeforeSpacing->set_sensitive(true); + m_xAfterSpacing->set_sensitive(true); + m_xFLSpacing->set_sensitive(true); + + const SvxLRSpaceItem* pSpace = static_cast<const SvxLRSpaceItem*>(pState); + long aTxtLeft = pSpace->GetTextLeft(); + long aTxtRight = pSpace->GetRight(); + long aTxtFirstLineOfst = pSpace->GetTextFirstLineOffset(); + + aTxtLeft = m_xBeforeSpacing->normalize(aTxtLeft); + + if(m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Text) + && m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Default) + && m_aContext.GetCombinedContext_DI() != CombinedEnumContext(Application::WriterVariants, Context::Table)) + { + m_xFLSpacing->set_min(aTxtLeft*-1, FieldUnit::MM_100TH); + } + + aTxtRight = m_xAfterSpacing->normalize(aTxtRight); + + switch(m_aContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Default): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + { + m_xBeforeSpacing->set_max(MAX_SW - aTxtRight, FieldUnit::MM_100TH); + m_xAfterSpacing->set_max(MAX_SW - aTxtLeft, FieldUnit::MM_100TH); + m_xFLSpacing->set_max(MAX_SW - aTxtLeft - aTxtRight, FieldUnit::MM_100TH); + } + break; + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + { + m_xBeforeSpacing->set_max(MAX_SC_SD - aTxtRight, FieldUnit::MM_100TH); + m_xAfterSpacing->set_max(MAX_SC_SD - aTxtLeft, FieldUnit::MM_100TH); + m_xFLSpacing->set_max(MAX_SC_SD - aTxtLeft - aTxtRight, FieldUnit::MM_100TH); + } + } + + m_xBeforeSpacing->set_value(aTxtLeft, FieldUnit::MM_100TH); + m_xAfterSpacing->set_value(aTxtRight, FieldUnit::MM_100TH); + + aTxtFirstLineOfst = m_xFLSpacing->normalize(aTxtFirstLineOfst); + m_xFLSpacing->set_value(aTxtFirstLineOfst, FieldUnit::MM_100TH); + } + else if(eState == SfxItemState::DISABLED) + { + m_xBeforeSpacing->set_sensitive(false); + m_xAfterSpacing->set_sensitive(false); + m_xFLSpacing->set_sensitive(false); + } + else + { + m_xBeforeSpacing->set_text(""); + m_xAfterSpacing->set_text(""); + m_xFLSpacing->set_text(""); + } +} + +void ParaLRSpacingWindow::SetUnit(FieldUnit eUnit) +{ + m_xBeforeSpacing->SetFieldUnit(eUnit); + m_xAfterSpacing->SetFieldUnit(eUnit); + m_xFLSpacing->SetFieldUnit(eUnit); + + SfxItemPool &rPool = SfxGetpApp()->GetPool(); + sal_uInt16 nWhich = rPool.GetWhich(SID_ATTR_PARA_LRSPACE); + m_eUnit = rPool.GetMetric(nWhich); +} + +IMPL_LINK_NOARG(ParaLRSpacingWindow, ModifySpacingHdl, weld::MetricSpinButton&, void) +{ + SfxDispatcher* pDisp = SfxViewFrame::Current()->GetBindings().GetDispatcher(); + if(pDisp) + { + SvxLRSpaceItem aMargin(SID_ATTR_PARA_LRSPACE); + aMargin.SetTextLeft(m_xBeforeSpacing->GetCoreValue(m_eUnit)); + aMargin.SetRight(m_xAfterSpacing->GetCoreValue(m_eUnit)); + aMargin.SetTextFirstLineOffset(m_xFLSpacing->GetCoreValue(m_eUnit)); + + pDisp->ExecuteList(SID_ATTR_PARA_LRSPACE, SfxCallMode::RECORD, {&aMargin}); + } +} + +// ParaLeftSpacingWindow + +ParaLeftSpacingWindow::ParaLeftSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + m_xBeforeContainer->show(); + m_xAfterContainer->hide(); + m_xFirstLineContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +void ParaLeftSpacingWindow::GetFocus() +{ + if (m_xBeforeSpacing) + m_xBeforeSpacing->grab_focus(); + ParaLRSpacingWindow::GetFocus(); +} + +// ParaRightSpacingWindow + +ParaRightSpacingWindow::ParaRightSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + m_xBeforeContainer->hide(); + m_xAfterContainer->show(); + m_xFirstLineContainer->hide(); + + SetSizePixel(get_preferred_size()); +} + +void ParaRightSpacingWindow::GetFocus() +{ + if (m_xAfterSpacing) + m_xAfterSpacing->grab_focus(); + ParaLRSpacingWindow::GetFocus(); +} + +// ParaFirstLineSpacingWindow + +ParaFirstLineSpacingWindow::ParaFirstLineSpacingWindow(vcl::Window* pParent) + : ParaLRSpacingWindow(pParent) +{ + m_xBeforeContainer->hide(); + m_xAfterContainer->hide(); + m_xFirstLineContainer->show(); + + SetSizePixel(get_preferred_size()); +} + +void ParaFirstLineSpacingWindow::GetFocus() +{ + if (m_xFLSpacing) + m_xFLSpacing->grab_focus(); + ParaLRSpacingWindow::GetFocus(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx new file mode 100644 index 000000000..3f18dbb3e --- /dev/null +++ b/svx/source/sidebar/paragraph/ParaSpacingWindow.hxx @@ -0,0 +1,115 @@ +/* -*- 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 . + */ +#pragma once + +#include <editeng/ulspitem.hxx> +#include <vcl/EnumContext.hxx> +#include <vcl/InterimItemWindow.hxx> +#include <svx/relfld.hxx> + +using namespace com::sun::star; + +namespace svx +{ +class ParaULSpacingWindow : public InterimItemWindow +{ +public: + virtual ~ParaULSpacingWindow() override; + virtual void dispose() override; + + void SetValue(const SvxULSpaceItem* pItem); + void SetUnit(FieldUnit eUnit); + +protected: + ParaULSpacingWindow(vcl::Window* pParent); + + std::unique_ptr<SvxRelativeField> m_xAboveSpacing; + std::unique_ptr<SvxRelativeField> m_xBelowSpacing; + std::unique_ptr<weld::Container> m_xAboveContainer; + std::unique_ptr<weld::Container> m_xBelowContainer; + + MapUnit m_eUnit; + + DECL_LINK(ModifySpacingHdl, weld::MetricSpinButton&, void); +}; + +class ParaAboveSpacingWindow : public ParaULSpacingWindow +{ +public: + explicit ParaAboveSpacingWindow(vcl::Window* pParent); + virtual void GetFocus() override; +}; + +class ParaBelowSpacingWindow : public ParaULSpacingWindow +{ +public: + explicit ParaBelowSpacingWindow(vcl::Window* pParent); + virtual void GetFocus() override; +}; + +class ParaLRSpacingWindow : public InterimItemWindow +{ +public: + virtual ~ParaLRSpacingWindow() override; + virtual void dispose() override; + + void SetValue(SfxItemState eState, const SfxPoolItem* pState); + void SetUnit(FieldUnit eUnit); + void SetContext(const vcl::EnumContext& eContext); + +protected: + ParaLRSpacingWindow(vcl::Window* pParent); + + std::unique_ptr<SvxRelativeField> m_xBeforeSpacing; + std::unique_ptr<SvxRelativeField> m_xAfterSpacing; + std::unique_ptr<SvxRelativeField> m_xFLSpacing; + std::unique_ptr<weld::Container> m_xBeforeContainer; + std::unique_ptr<weld::Container> m_xAfterContainer; + std::unique_ptr<weld::Container> m_xFirstLineContainer; + + MapUnit m_eUnit; + + vcl::EnumContext m_aContext; + + DECL_LINK(ModifySpacingHdl, weld::MetricSpinButton&, void); +}; + +class ParaLeftSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaLeftSpacingWindow(vcl::Window* pParent); + virtual void GetFocus() override; +}; + +class ParaRightSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaRightSpacingWindow(vcl::Window* pParent); + virtual void GetFocus() override; +}; + +class ParaFirstLineSpacingWindow : public ParaLRSpacingWindow +{ +public: + explicit ParaFirstLineSpacingWindow(vcl::Window* pParent); + virtual void GetFocus() override; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/possize/PosSizePropertyPanel.cxx b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx new file mode 100644 index 000000000..f6f6b242e --- /dev/null +++ b/svx/source/sidebar/possize/PosSizePropertyPanel.cxx @@ -0,0 +1,1088 @@ +/* -*- 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 <algorithm> + +#include "PosSizePropertyPanel.hxx" +#include <sal/log.hxx> +#include <svx/svxids.hrc> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/module.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/weldutils.hxx> +#include <svx/dialcontrol.hxx> +#include <svx/rectenum.hxx> +#include <unotools/viewoptions.hxx> +#include <unotools/localedatawrapper.hxx> +#include <vcl/canvastools.hxx> +#include <vcl/fieldvalues.hxx> +#include <svl/intitem.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/transfrmhelper.hxx> +#include <boost/property_tree/json_parser.hpp> + +#include <svtools/unitconv.hxx> + +using namespace css; +using namespace css::uno; + +const char USERITEM_NAME[] = "FitItem"; + +namespace svx::sidebar { + +PosSizePropertyPanel::PosSizePropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) +: PanelLayout(pParent, "PosSizePropertyPanel", "svx/ui/sidebarpossize.ui", rxFrame), + mxFtPosX(m_xBuilder->weld_label("horizontallabel")), + mxMtrPosX(m_xBuilder->weld_metric_spin_button("horizontalpos", FieldUnit::CM)), + mxFtPosY(m_xBuilder->weld_label("verticallabel")), + mxMtrPosY(m_xBuilder->weld_metric_spin_button("verticalpos", FieldUnit::CM)), + mxFtWidth(m_xBuilder->weld_label("widthlabel")), + mxMtrWidth(m_xBuilder->weld_metric_spin_button("selectwidth", FieldUnit::CM)), + mxFtHeight(m_xBuilder->weld_label("heightlabel")), + mxMtrHeight(m_xBuilder->weld_metric_spin_button("selectheight", FieldUnit::CM)), + mxCbxScale(m_xBuilder->weld_check_button("ratio")), + mxFtAngle(m_xBuilder->weld_label("rotationlabel")), + mxMtrAngle(m_xBuilder->weld_metric_spin_button("rotation", FieldUnit::DEGREE)), + mxCtrlDial(new DialControl), + mxDial(new weld::CustomWeld(*m_xBuilder, "orientationcontrol", *mxCtrlDial)), + mxFtFlip(m_xBuilder->weld_label("fliplabel")), + mxFlipTbx(m_xBuilder->weld_toolbar("selectrotationtype")), + mxFlipDispatch(new ToolbarUnoDispatcher(*mxFlipTbx, *m_xBuilder, rxFrame)), + mxArrangeTbx(m_xBuilder->weld_toolbar("arrangetoolbar")), + mxArrangeDispatch(new ToolbarUnoDispatcher(*mxArrangeTbx, *m_xBuilder, rxFrame)), + mxArrangeTbx2(m_xBuilder->weld_toolbar("arrangetoolbar2")), + mxArrangeDispatch2(new ToolbarUnoDispatcher(*mxArrangeTbx2, *m_xBuilder, rxFrame)), + mxAlignTbx(m_xBuilder->weld_toolbar("aligntoolbar")), + mxAlignDispatch(new ToolbarUnoDispatcher(*mxAlignTbx, *m_xBuilder, rxFrame)), + mxAlignTbx2(m_xBuilder->weld_toolbar("aligntoolbar2")), + mxAlignDispatch2(new ToolbarUnoDispatcher(*mxAlignTbx2, *m_xBuilder, rxFrame)), + mxBtnEditChart(m_xBuilder->weld_button("btnEditChart")), + maRect(), + mpView(nullptr), + mlOldWidth(1), + mlOldHeight(1), + mlRotX(0), + mlRotY(0), + maUIScale(), + mePoolUnit(), + meDlgUnit(FieldUnit::INCH), // #i124409# init with fallback default + maTransfPosXControl(SID_ATTR_TRANSFORM_POS_X, *pBindings, *this), + maTransfPosYControl(SID_ATTR_TRANSFORM_POS_Y, *pBindings, *this), + maTransfWidthControl(SID_ATTR_TRANSFORM_WIDTH, *pBindings, *this), + maTransfHeightControl(SID_ATTR_TRANSFORM_HEIGHT, *pBindings, *this), + maSvxAngleControl( SID_ATTR_TRANSFORM_ANGLE, *pBindings, *this), + maRotXControl(SID_ATTR_TRANSFORM_ROT_X, *pBindings, *this), + maRotYControl(SID_ATTR_TRANSFORM_ROT_Y, *pBindings, *this), + maProPosControl(SID_ATTR_TRANSFORM_PROTECT_POS, *pBindings, *this), + maProSizeControl(SID_ATTR_TRANSFORM_PROTECT_SIZE, *pBindings, *this), + maAutoWidthControl(SID_ATTR_TRANSFORM_AUTOWIDTH, *pBindings, *this), + maAutoHeightControl(SID_ATTR_TRANSFORM_AUTOHEIGHT, *pBindings, *this), + m_aMetricCtl(SID_ATTR_METRIC, *pBindings, *this), + maContext(), + mpBindings(pBindings), + mbSizeProtected(false), + mbPositionProtected(false), + mbAutoWidth(false), + mbAutoHeight(false), + mbAdjustEnabled(false), + mxSidebar(rxSidebar) +{ + Initialize(); + + mpBindings->Update( SID_ATTR_METRIC ); + mpBindings->Update( SID_ATTR_TRANSFORM_WIDTH ); + mpBindings->Update( SID_ATTR_TRANSFORM_HEIGHT ); + mpBindings->Update( SID_ATTR_TRANSFORM_PROTECT_SIZE ); +} + +PosSizePropertyPanel::~PosSizePropertyPanel() +{ + disposeOnce(); +} + +void PosSizePropertyPanel::dispose() +{ + mxFtPosX.reset(); + mxMtrPosX.reset(); + mxFtPosY.reset(); + mxMtrPosY.reset(); + mxFtWidth.reset(); + mxMtrWidth.reset(); + mxFtHeight.reset(); + mxMtrHeight.reset(); + mxCbxScale.reset(); + mxFtAngle.reset(); + mxMtrAngle.reset(); + mxDial.reset(); + mxCtrlDial.reset(); + mxFtFlip.reset(); + mxFlipDispatch.reset(); + mxFlipTbx.reset(); + mxAlignDispatch.reset(); + mxAlignDispatch2.reset(); + mxAlignTbx.reset(); + mxAlignTbx2.reset(); + mxArrangeDispatch.reset(); + mxArrangeDispatch2.reset(); + mxArrangeTbx.reset(); + mxArrangeTbx2.reset(); + mxBtnEditChart.reset(); + + maTransfPosXControl.dispose(); + maTransfPosYControl.dispose(); + maTransfWidthControl.dispose(); + maTransfHeightControl.dispose(); + + maSvxAngleControl.dispose(); + maRotXControl.dispose(); + maRotYControl.dispose(); + maProPosControl.dispose(); + maProSizeControl.dispose(); + maAutoWidthControl.dispose(); + maAutoHeightControl.dispose(); + m_aMetricCtl.dispose(); + + PanelLayout::dispose(); +} + + +namespace +{ + bool hasText(const SdrView& rSdrView) + { + const SdrMarkList& rMarkList = rSdrView.GetMarkedObjectList(); + + if(1 == rMarkList.GetMarkCount()) + { + const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + const SdrObjKind eKind(static_cast<SdrObjKind>(pObj->GetObjIdentifier())); + + if((pObj->GetObjInventor() == SdrInventor::Default) && (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind)) + { + const SdrTextObj* pSdrTextObj = dynamic_cast< const SdrTextObj* >(pObj); + + if(pSdrTextObj && pSdrTextObj->HasText()) + { + return true; + } + } + } + + return false; + } +} // end of anonymous namespace + + +void PosSizePropertyPanel::Initialize() +{ + //Position : Horizontal / Vertical + mxMtrPosX->connect_value_changed( LINK( this, PosSizePropertyPanel, ChangePosXHdl ) ); + mxMtrPosY->connect_value_changed( LINK( this, PosSizePropertyPanel, ChangePosYHdl ) ); + + //Size : Width / Height + mxMtrWidth->connect_value_changed( LINK( this, PosSizePropertyPanel, ChangeWidthHdl ) ); + mxMtrHeight->connect_value_changed( LINK( this, PosSizePropertyPanel, ChangeHeightHdl ) ); + + //Size : Keep ratio + mxCbxScale->connect_toggled( LINK( this, PosSizePropertyPanel, ClickAutoHdl ) ); + + //rotation control + mxCtrlDial->SetLinkedField(mxMtrAngle.get()); + mxCtrlDial->SetModifyHdl(LINK( this, PosSizePropertyPanel, RotationHdl)); + + //use same logic as DialControl_Impl::SetSize + weld::DrawingArea* pDrawingArea = mxCtrlDial->GetDrawingArea(); + int nDim = (std::min<int>(pDrawingArea->get_approximate_digit_width() * 6, + pDrawingArea->get_text_height() * 3) - 1) | 1; + Size aSize(nDim, nDim); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + mxCtrlDial->Init(aSize); + + mxBtnEditChart->connect_clicked( LINK( this, PosSizePropertyPanel, ClickChartEditHdl ) ); + + SfxViewShell* pCurSh = SfxViewShell::Current(); + if ( pCurSh ) + mpView = pCurSh->GetDrawView(); + else + mpView = nullptr; + + if ( mpView != nullptr ) + { + maUIScale = mpView->GetModel()->GetUIScale(); + mbAdjustEnabled = hasText(*mpView); + } + + mePoolUnit = maTransfWidthControl.GetCoreMetric(); +} + +VclPtr<vcl::Window> PosSizePropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to PosSizePropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to PosSizePropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to PosSizePropertyPanel::Create", nullptr, 2); + + return VclPtr<PosSizePropertyPanel>::Create( + pParent, + rxFrame, + pBindings, + rxSidebar); +} + + +void PosSizePropertyPanel::DataChanged( + const DataChangedEvent& /*rEvent*/) +{ +} + +void PosSizePropertyPanel::HandleContextChange( + const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + { + // Nothing to do. + return; + } + + maContext = rContext; + + bool bShowPosition = false; + bool bShowAngle = false; + bool bShowFlip = false; + bool bShowEditChart = false; + bool bShowArrangeTbx2 = false; + + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::WriterVariants, Context::Draw): + bShowAngle = true; + bShowFlip = true; + bShowArrangeTbx2 = true; + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Graphic): + bShowFlip = true; + bShowAngle = true; // RotGrfFlyFrame: Writer FlyFrames for Graphics now support angle + break; + + case CombinedEnumContext(Application::Calc, Context::Draw): + case CombinedEnumContext(Application::Calc, Context::DrawLine): + case CombinedEnumContext(Application::Calc, Context::Graphic): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::DrawLine): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + bShowPosition = true; + bShowAngle = true; + bShowFlip = true; + break; + + case CombinedEnumContext(Application::WriterVariants, Context::OLE): + bShowEditChart = true; + break; + + case CombinedEnumContext(Application::Calc, Context::OLE): + case CombinedEnumContext(Application::DrawImpress, Context::OLE): + bShowPosition = true; + bShowEditChart = true; + break; + + case CombinedEnumContext(Application::Calc, Context::Chart): + case CombinedEnumContext(Application::Calc, Context::Form): + case CombinedEnumContext(Application::Calc, Context::Media): + case CombinedEnumContext(Application::Calc, Context::MultiObject): + case CombinedEnumContext(Application::DrawImpress, Context::Media): + case CombinedEnumContext(Application::DrawImpress, Context::Form): + case CombinedEnumContext(Application::DrawImpress, Context::ThreeDObject): + case CombinedEnumContext(Application::DrawImpress, Context::MultiObject): + bShowPosition = true; + break; + } + + // Position + mxFtPosX->set_visible(bShowPosition); + mxMtrPosX->set_visible(bShowPosition); + mxFtPosY->set_visible(bShowPosition); + mxMtrPosY->set_visible(bShowPosition); + + // Rotation + mxFtAngle->set_visible(bShowAngle); + mxMtrAngle->set_visible(bShowAngle); + mxCtrlDial->set_visible(bShowAngle); + + // Flip + mxFtFlip->set_visible(bShowFlip); + mxFlipTbx->set_visible(bShowFlip); + + // Edit Chart + mxBtnEditChart->set_visible(bShowEditChart); + + // Arrange tool bar 2 + mxArrangeTbx2->set_visible(bShowArrangeTbx2); + + if (mxSidebar.is()) + mxSidebar->requestLayout(); +} + + +IMPL_LINK_NOARG( PosSizePropertyPanel, ChangeWidthHdl, weld::MetricSpinButton&, void ) +{ + if( mxCbxScale->get_active() && + mxCbxScale->get_sensitive() ) + { + long nHeight = static_cast<long>( (static_cast<double>(mlOldHeight) * static_cast<double>(mxMtrWidth->get_value(FieldUnit::NONE))) / static_cast<double>(mlOldWidth) ); + if( nHeight <= mxMtrHeight->get_max( FieldUnit::NONE ) ) + { + mxMtrHeight->set_value( nHeight, FieldUnit::NONE ); + } + else + { + nHeight = static_cast<long>(mxMtrHeight->get_max( FieldUnit::NONE )); + mxMtrHeight->set_value(nHeight, FieldUnit::NONE); + const long nWidth = static_cast<long>( (static_cast<double>(mlOldWidth) * static_cast<double>(nHeight)) / static_cast<double>(mlOldHeight) ); + mxMtrWidth->set_value( nWidth, FieldUnit::NONE ); + } + } + executeSize(); +} + + +IMPL_LINK_NOARG( PosSizePropertyPanel, ChangeHeightHdl, weld::MetricSpinButton&, void ) +{ + if( mxCbxScale->get_active() && + mxCbxScale->get_sensitive() ) + { + long nWidth = static_cast<long>( (static_cast<double>(mlOldWidth) * static_cast<double>(mxMtrHeight->get_value(FieldUnit::NONE))) / static_cast<double>(mlOldHeight) ); + if( nWidth <= mxMtrWidth->get_max( FieldUnit::NONE ) ) + { + mxMtrWidth->set_value( nWidth, FieldUnit::NONE ); + } + else + { + nWidth = static_cast<long>(mxMtrWidth->get_max( FieldUnit::NONE )); + mxMtrWidth->set_value( nWidth, FieldUnit::NONE ); + const long nHeight = static_cast<long>( (static_cast<double>(mlOldHeight) * static_cast<double>(nWidth)) / static_cast<double>(mlOldWidth) ); + mxMtrHeight->set_value( nHeight, FieldUnit::NONE ); + } + } + executeSize(); +} + + +IMPL_LINK_NOARG( PosSizePropertyPanel, ChangePosXHdl, weld::MetricSpinButton&, void ) +{ + if ( mxMtrPosX->get_value_changed_from_saved()) + { + long lX = GetCoreValue( *mxMtrPosX, mePoolUnit ); + + Fraction aUIScale = mpView->GetModel()->GetUIScale(); + lX = long( lX * aUIScale ); + + SfxInt32Item aPosXItem( SID_ATTR_TRANSFORM_POS_X,static_cast<sal_uInt32>(lX)); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_TRANSFORM, SfxCallMode::RECORD, { &aPosXItem }); + } +} + +IMPL_LINK_NOARG( PosSizePropertyPanel, ChangePosYHdl, weld::MetricSpinButton&, void ) +{ + if ( mxMtrPosY->get_value_changed_from_saved() ) + { + long lY = GetCoreValue( *mxMtrPosY, mePoolUnit ); + + Fraction aUIScale = mpView->GetModel()->GetUIScale(); + lY = long( lY * aUIScale ); + + SfxInt32Item aPosYItem( SID_ATTR_TRANSFORM_POS_Y,static_cast<sal_uInt32>(lY)); + + GetBindings()->GetDispatcher()->ExecuteList( + SID_ATTR_TRANSFORM, SfxCallMode::RECORD, { &aPosYItem }); + } +} + +IMPL_LINK_NOARG( PosSizePropertyPanel, ClickAutoHdl, weld::ToggleButton&, void ) +{ + if ( mxCbxScale->get_active() ) + { + mlOldWidth = std::max(GetCoreValue(*mxMtrWidth, mePoolUnit), 1); + mlOldHeight = std::max(GetCoreValue(*mxMtrHeight, mePoolUnit), 1); + } + + // mxCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog + SvtViewOptions aPageOpt(EViewType::TabPage, "cui/ui/possizetabpage/PositionAndSize"); + aPageOpt.SetUserItem( USERITEM_NAME, css::uno::makeAny( OUString::number( int(mxCbxScale->get_active()) ) ) ); +} + +IMPL_LINK_NOARG( PosSizePropertyPanel, RotationHdl, DialControl&, void ) +{ + sal_Int32 nTmp = mxCtrlDial->GetRotation(); + + // #i123993# Need to take UIScale into account when executing rotations + const double fUIScale(mpView && mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0); + SfxInt32Item aAngleItem( SID_ATTR_TRANSFORM_ANGLE,static_cast<sal_uInt32>(nTmp)); + SfxInt32Item aRotXItem( SID_ATTR_TRANSFORM_ROT_X, basegfx::fround(mlRotX * fUIScale)); + SfxInt32Item aRotYItem( SID_ATTR_TRANSFORM_ROT_Y, basegfx::fround(mlRotY * fUIScale)); + + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, + SfxCallMode::RECORD, { &aAngleItem, &aRotXItem, &aRotYItem }); +} + +IMPL_STATIC_LINK_NOARG( PosSizePropertyPanel, ClickChartEditHdl, weld::Button&, void ) +{ + SfxViewShell* pCurSh = SfxViewShell::Current(); + if ( pCurSh) + { + pCurSh->DoVerb( -1 ); + } +} + +namespace +{ + void limitWidth(weld::MetricSpinButton& rMetricSpinButton) + { + // space is limited in the sidebar, so limit MetricSpinButtons to a width of 7 digits + const int nMaxDigits = 7; + + weld::SpinButton& rSpinButton = rMetricSpinButton.get_widget(); + rSpinButton.set_width_chars(std::min(rSpinButton.get_width_chars(), nMaxDigits)); + } +} + +void PosSizePropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + mxFtAngle->set_sensitive(true); + mxMtrAngle->set_sensitive(true); + mxDial->set_sensitive(true); + mxFtFlip->set_sensitive(true); + mxFlipTbx->set_sensitive(true); + + const SfxUInt32Item* pWidthItem; + const SfxUInt32Item* pHeightItem; + + SfxViewShell* pCurSh = SfxViewShell::Current(); + if ( pCurSh ) + mpView = pCurSh->GetDrawView(); + else + mpView = nullptr; + + if ( mpView == nullptr ) + return; + + mbAdjustEnabled = hasText(*mpView); + + // Pool unit and dialog unit may have changed, make sure that we + // have the current values. + mePoolUnit = maTransfWidthControl.GetCoreMetric(); + + switch (nSID) + { + case SID_ATTR_TRANSFORM_WIDTH: + if ( SfxItemState::DEFAULT == eState ) + { + pWidthItem = dynamic_cast< const SfxUInt32Item* >(pState); + + if(pWidthItem) + { + long lOldWidth1 = long( pWidthItem->GetValue() / maUIScale ); + SetFieldUnit( *mxMtrWidth, meDlgUnit, true ); + SetMetricValue( *mxMtrWidth, lOldWidth1, mePoolUnit ); + limitWidth(*mxMtrWidth); + mlOldWidth = lOldWidth1; + mxMtrWidth->save_value(); + break; + } + } + + mxMtrWidth->set_text( "" ); + break; + + case SID_ATTR_TRANSFORM_HEIGHT: + if ( SfxItemState::DEFAULT == eState ) + { + pHeightItem = dynamic_cast< const SfxUInt32Item* >(pState); + + if(pHeightItem) + { + long nTmp = long( pHeightItem->GetValue() / maUIScale); + SetFieldUnit( *mxMtrHeight, meDlgUnit, true ); + SetMetricValue( *mxMtrHeight, nTmp, mePoolUnit ); + limitWidth(*mxMtrHeight); + mlOldHeight = nTmp; + mxMtrHeight->save_value(); + break; + } + } + + mxMtrHeight->set_text( ""); + break; + + case SID_ATTR_TRANSFORM_POS_X: + if(SfxItemState::DEFAULT == eState) + { + const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); + + if(pItem) + { + long nTmp = long(pItem->GetValue() / maUIScale); + SetFieldUnit( *mxMtrPosX, meDlgUnit, true ); + SetMetricValue( *mxMtrPosX, nTmp, mePoolUnit ); + limitWidth(*mxMtrPosX); + mxMtrPosX->save_value(); + break; + } + } + + mxMtrPosX->set_text( "" ); + break; + + case SID_ATTR_TRANSFORM_POS_Y: + if(SfxItemState::DEFAULT == eState) + { + const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); + + if(pItem) + { + long nTmp = long(pItem->GetValue() / maUIScale); + SetFieldUnit( *mxMtrPosY, meDlgUnit, true ); + SetMetricValue( *mxMtrPosY, nTmp, mePoolUnit ); + limitWidth(*mxMtrPosY); + mxMtrPosY->save_value(); + break; + } + } + + mxMtrPosY->set_text( "" ); + break; + + case SID_ATTR_TRANSFORM_ROT_X: + if (SfxItemState::DEFAULT == eState) + { + const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); + + if(pItem) + { + mlRotX = pItem->GetValue(); + mlRotX = long( mlRotX / maUIScale ); + } + } + break; + + case SID_ATTR_TRANSFORM_ROT_Y: + if (SfxItemState::DEFAULT == eState) + { + const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); + + if(pItem) + { + mlRotY = pItem->GetValue(); + mlRotY = long( mlRotY / maUIScale ); + } + } + break; + + case SID_ATTR_TRANSFORM_PROTECT_POS: + if(SfxItemState::DEFAULT == eState) + { + const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); + + if(pItem) + { + // record the state of position protect + mbPositionProtected = pItem->GetValue(); + break; + } + } + + mbPositionProtected = false; + break; + + case SID_ATTR_TRANSFORM_PROTECT_SIZE: + if(SfxItemState::DEFAULT == eState) + { + const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); + + if(pItem) + { + // record the state of size protect + mbSizeProtected = pItem->GetValue(); + break; + } + } + + mbSizeProtected = false; + break; + + case SID_ATTR_TRANSFORM_AUTOWIDTH: + if(SfxItemState::DEFAULT == eState) + { + const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); + + if(pItem) + { + mbAutoWidth = pItem->GetValue(); + } + } + break; + + case SID_ATTR_TRANSFORM_AUTOHEIGHT: + if(SfxItemState::DEFAULT == eState) + { + const SfxBoolItem* pItem = dynamic_cast< const SfxBoolItem* >(pState); + + if(pItem) + { + mbAutoHeight = pItem->GetValue(); + } + } + break; + + case SID_ATTR_TRANSFORM_ANGLE: + if (eState >= SfxItemState::DEFAULT) + { + const SfxInt32Item* pItem = dynamic_cast< const SfxInt32Item* >(pState); + + if(pItem) + { + long nTmp = pItem->GetValue(); + nTmp = nTmp < 0 ? 36000+nTmp : nTmp; + + mxMtrAngle->set_value(nTmp, FieldUnit::DEGREE); + mxCtrlDial->SetRotation(nTmp); + + break; + } + } + + mxMtrAngle->set_text( "" ); + mxCtrlDial->SetRotation( 0 ); + break; + + case SID_ATTR_METRIC: + MetricState( eState, pState ); + UpdateUIScale(); + break; + + default: + break; + } + + const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI()); + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + + switch (rMarkList.GetMarkCount()) + { + case 0: + break; + + case 1: + { + const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + const SdrObjKind eKind(static_cast<SdrObjKind>(pObj->GetObjIdentifier())); + + if(((nCombinedContext == CombinedEnumContext(Application::DrawImpress, Context::Draw) + || nCombinedContext == CombinedEnumContext(Application::DrawImpress, Context::TextObject) + ) && OBJ_EDGE == eKind) + || OBJ_CAPTION == eKind) + { + mxFtAngle->set_sensitive(false); + mxMtrAngle->set_sensitive(false); + mxDial->set_sensitive(false); + mxFlipTbx->set_sensitive(false); + mxFtFlip->set_sensitive(false); + } + break; + } + + default: + { + sal_uInt16 nMarkObj = 0; + bool isNoEdge = true; + + while(isNoEdge && rMarkList.GetMark(nMarkObj)) + { + const SdrObject* pObj = rMarkList.GetMark(nMarkObj)->GetMarkedSdrObj(); + const SdrObjKind eKind(static_cast<SdrObjKind>(pObj->GetObjIdentifier())); + + if(((nCombinedContext == CombinedEnumContext(Application::DrawImpress, Context::Draw) + || nCombinedContext == CombinedEnumContext(Application::DrawImpress, Context::TextObject) + ) && OBJ_EDGE == eKind) + || OBJ_CAPTION == eKind) + { + isNoEdge = false; + break; + } + nMarkObj++; + } + + if(!isNoEdge) + { + mxFtAngle->set_sensitive(false); + mxMtrAngle->set_sensitive(false); + mxDial->set_sensitive(false); + mxFlipTbx->set_sensitive(false); + mxFtFlip->set_sensitive(false); + } + break; + } + } + + if(nCombinedContext == CombinedEnumContext(Application::DrawImpress, Context::TextObject)) + { + mxFlipTbx->set_sensitive(false); + mxFtFlip->set_sensitive(false); + } + + DisableControls(); + + // mxCbxScale must synchronized with that on Position and Size tabpage on Shape Properties dialog + SvtViewOptions aPageOpt(EViewType::TabPage, "cui/ui/possizetabpage/PositionAndSize"); + OUString sUserData; + css::uno::Any aUserItem = aPageOpt.GetUserItem( USERITEM_NAME ); + OUString aTemp; + if ( aUserItem >>= aTemp ) + sUserData = aTemp; + mxCbxScale->set_active(static_cast<bool>(sUserData.toInt32())); +} + +void PosSizePropertyPanel::GetControlState(const sal_uInt16 nSID, boost::property_tree::ptree& rState) +{ + weld::MetricSpinButton* pControl = nullptr; + switch (nSID) + { + case SID_ATTR_TRANSFORM_POS_X: + pControl = mxMtrPosX.get(); + break; + case SID_ATTR_TRANSFORM_POS_Y: + pControl = mxMtrPosY.get(); + break; + case SID_ATTR_TRANSFORM_WIDTH: + pControl = mxMtrWidth.get(); + break; + case SID_ATTR_TRANSFORM_HEIGHT: + pControl = mxMtrHeight.get(); + break; + } + + if (pControl && !pControl->get_text().isEmpty()) + { + OUString sValue = Application::GetSettings().GetNeutralLocaleDataWrapper(). + getNum(pControl->get_value(pControl->get_unit()), pControl->get_digits(), false, false); + rState.put(pControl->get_buildable_name().getStr(), sValue.toUtf8().getStr()); + } +} + +void PosSizePropertyPanel::executeSize() +{ + if ( !mxMtrWidth->get_value_changed_from_saved() && !mxMtrHeight->get_value_changed_from_saved()) + return; + + Fraction aUIScale = mpView->GetModel()->GetUIScale(); + + // get Width + double nWidth = static_cast<double>(mxMtrWidth->get_value(FieldUnit::MM_100TH)); + long lWidth = long(nWidth * static_cast<double>(aUIScale)); + lWidth = OutputDevice::LogicToLogic( lWidth, MapUnit::Map100thMM, mePoolUnit ); + lWidth = static_cast<long>(mxMtrWidth->denormalize( lWidth )); + + // get Height + double nHeight = static_cast<double>(mxMtrHeight->get_value(FieldUnit::MM_100TH)); + long lHeight = long(nHeight * static_cast<double>(aUIScale)); + lHeight = OutputDevice::LogicToLogic( lHeight, MapUnit::Map100thMM, mePoolUnit ); + lHeight = static_cast<long>(mxMtrHeight->denormalize( lHeight )); + + // put Width & Height to itemset + SfxUInt32Item aWidthItem( SID_ATTR_TRANSFORM_WIDTH, static_cast<sal_uInt32>(lWidth)); + SfxUInt32Item aHeightItem( SID_ATTR_TRANSFORM_HEIGHT, static_cast<sal_uInt32>(lHeight)); + SfxUInt16Item aPointItem (SID_ATTR_TRANSFORM_SIZE_POINT, sal_uInt16(RectPoint::LT)); + const sal_Int32 nCombinedContext(maContext.GetCombinedContext_DI()); + + if( nCombinedContext == CombinedEnumContext(Application::WriterVariants, Context::Graphic) + || nCombinedContext == CombinedEnumContext(Application::WriterVariants, Context::OLE) + ) + { + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, + SfxCallMode::RECORD, { &aWidthItem, &aHeightItem, &aPointItem }); + } + else + { + if ( (mxMtrWidth->get_value_changed_from_saved()) && (mxMtrHeight->get_value_changed_from_saved())) + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, + SfxCallMode::RECORD, { &aWidthItem, &aHeightItem, &aPointItem }); + else if( mxMtrWidth->get_value_changed_from_saved()) + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, + SfxCallMode::RECORD, { &aWidthItem, &aPointItem }); + else if ( mxMtrHeight->get_value_changed_from_saved()) + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, + SfxCallMode::RECORD, { &aHeightItem, &aPointItem }); + } +} + +boost::property_tree::ptree PosSizePropertyPanel::DumpAsPropertyTree() +{ + if (meDlgUnit != GetCurrentUnit(SfxItemState::DEFAULT, nullptr)) + { + mpBindings->Update( SID_ATTR_METRIC ); + } + + return PanelLayout::DumpAsPropertyTree(); +} + +void PosSizePropertyPanel::MetricState( SfxItemState eState, const SfxPoolItem* pState ) +{ + bool bPosXBlank = false; + bool bPosYBlank = false; + bool bWidthBlank = false; + bool bHeightBlank = false; + + // #i124409# use the given Item to get the correct UI unit and initialize it + // and the Fields using it + meDlgUnit = GetCurrentUnit(eState,pState); + + if (mxMtrPosX->get_text().isEmpty()) + bPosXBlank = true; + SetFieldUnit( *mxMtrPosX, meDlgUnit, true ); + if(bPosXBlank) + mxMtrPosX->set_text(OUString()); + + if (mxMtrPosY->get_text().isEmpty()) + bPosYBlank = true; + SetFieldUnit( *mxMtrPosY, meDlgUnit, true ); + if(bPosYBlank) + mxMtrPosY->set_text(OUString()); + SetPosSizeMinMax(); + + if (mxMtrWidth->get_text().isEmpty()) + bWidthBlank = true; + SetFieldUnit( *mxMtrWidth, meDlgUnit, true ); + if(bWidthBlank) + mxMtrWidth->set_text(OUString()); + + if (mxMtrHeight->get_text().isEmpty()) + bHeightBlank = true; + SetFieldUnit( *mxMtrHeight, meDlgUnit, true ); + if(bHeightBlank) + mxMtrHeight->set_text(OUString()); +} + + +FieldUnit PosSizePropertyPanel::GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ) +{ + FieldUnit eUnit = FieldUnit::NONE; + + if ( pState && eState >= SfxItemState::DEFAULT ) + { + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pState)->GetValue()); + } + else + { + SfxViewFrame* pFrame = SfxViewFrame::Current(); + SfxObjectShell* pSh = nullptr; + if ( pFrame ) + pSh = pFrame->GetObjectShell(); + if ( pSh ) + { + SfxModule* pModule = pSh->GetModule(); + if ( pModule ) + { + const SfxPoolItem* pItem = pModule->GetItem( SID_ATTR_METRIC ); + if ( pItem ) + eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue()); + } + else + { + SAL_WARN("svx.sidebar", "GetModuleFieldUnit(): no module found"); + } + } + } + + return eUnit; +} + + +void PosSizePropertyPanel::DisableControls() +{ + if( mbPositionProtected ) + { + // the position is protected("Position protect" option in modal dialog is checked), + // disable all the Position controls in sidebar + mxFtPosX->set_sensitive(false); + mxMtrPosX->set_sensitive(false); + mxFtPosY->set_sensitive(false); + mxMtrPosY->set_sensitive(false); + mxFtAngle->set_sensitive(false); + mxMtrAngle->set_sensitive(false); + mxDial->set_sensitive(false); + mxFtFlip->set_sensitive(false); + mxFlipTbx->set_sensitive(false); + + mxFtWidth->set_sensitive(false); + mxMtrWidth->set_sensitive(false); + mxFtHeight->set_sensitive(false); + mxMtrHeight->set_sensitive(false); + mxCbxScale->set_sensitive(false); + } + else + { + mxFtPosX->set_sensitive(true); + mxMtrPosX->set_sensitive(true); + mxFtPosY->set_sensitive(true); + mxMtrPosY->set_sensitive(true); + + if( mbSizeProtected ) + { + mxFtWidth->set_sensitive(false); + mxMtrWidth->set_sensitive(false); + mxFtHeight->set_sensitive(false); + mxMtrHeight->set_sensitive(false); + mxCbxScale->set_sensitive(false); + } + else + { + if( mbAdjustEnabled ) + { + if( mbAutoWidth ) + { + mxFtWidth->set_sensitive(false); + mxMtrWidth->set_sensitive(false); + mxCbxScale->set_sensitive(false); + } + else + { + mxFtWidth->set_sensitive(true); + mxMtrWidth->set_sensitive(true); + } + if( mbAutoHeight ) + { + mxFtHeight->set_sensitive(false); + mxMtrHeight->set_sensitive(false); + mxCbxScale->set_sensitive(false); + } + else + { + mxFtHeight->set_sensitive(true); + mxMtrHeight->set_sensitive(true); + } + if( !mbAutoWidth && !mbAutoHeight ) + mxCbxScale->set_sensitive(true); + } + else + { + mxFtWidth->set_sensitive(true); + mxMtrWidth->set_sensitive(true); + mxFtHeight->set_sensitive(true); + mxMtrHeight->set_sensitive(true); + mxCbxScale->set_sensitive(true); + } + } + } +} + +void PosSizePropertyPanel::SetPosSizeMinMax() +{ + SdrPageView* pPV = mpView->GetSdrPageView(); + if (!pPV) + return; + tools::Rectangle aTmpRect(mpView->GetAllMarkedRect()); + pPV->LogicToPagePos(aTmpRect); + maRect = vcl::unotools::b2DRectangleFromRectangle(aTmpRect); + + tools::Rectangle aTmpRect2(mpView->GetWorkArea()); + pPV->LogicToPagePos(aTmpRect2); + maWorkArea = vcl::unotools::b2DRectangleFromRectangle(aTmpRect2); + + const Fraction aUIScale(mpView->GetModel()->GetUIScale()); + TransfrmHelper::ScaleRect( maWorkArea, aUIScale ); + TransfrmHelper::ScaleRect( maRect, aUIScale ); + + const sal_uInt16 nDigits(mxMtrPosX->get_digits()); + TransfrmHelper::ConvertRect( maWorkArea, nDigits, mePoolUnit, meDlgUnit ); + TransfrmHelper::ConvertRect( maRect, nDigits, mePoolUnit, meDlgUnit ); + + double fLeft(maWorkArea.getMinX()); + double fTop(maWorkArea.getMinY()); + double fRight(maWorkArea.getMaxX()); + double fBottom(maWorkArea.getMaxY()); + + // seems that sidebar defaults to top left reference point + // and there's no way to set it to something else + fRight -= maRect.getWidth(); + fBottom -= maRect.getHeight(); + + const double fMaxLong(static_cast<double>(vcl::ConvertValue( LONG_MAX, 0, MapUnit::Map100thMM, meDlgUnit ) - 1)); + fLeft = std::clamp(fLeft, -fMaxLong, fMaxLong); + fRight = std::clamp(fRight, -fMaxLong, fMaxLong); + fTop = std::clamp(fTop, - fMaxLong, fMaxLong); + fBottom = std::clamp(fBottom, -fMaxLong, fMaxLong); + + mxMtrPosX->set_range(basegfx::fround64(fLeft), basegfx::fround64(fRight), FieldUnit::NONE); + limitWidth(*mxMtrPosX); + mxMtrPosY->set_range(basegfx::fround64(fTop), basegfx::fround64(fBottom), FieldUnit::NONE); + limitWidth(*mxMtrPosY); + + double fMaxWidth = maWorkArea.getWidth() - (maRect.getWidth() - fLeft); + double fMaxHeight = maWorkArea.getHeight() - (maRect.getHeight() - fTop); + mxMtrWidth->set_max(std::min<sal_Int64>(INT_MAX, basegfx::fround64(fMaxWidth*100)), FieldUnit::NONE); + limitWidth(*mxMtrWidth); + mxMtrHeight->set_max(std::min<sal_Int64>(INT_MAX, basegfx::fround64(fMaxHeight*100)), FieldUnit::NONE); + limitWidth(*mxMtrHeight); +} + +void PosSizePropertyPanel::UpdateUIScale() +{ + const Fraction aUIScale (mpView->GetModel()->GetUIScale()); + if (maUIScale != aUIScale) + { + // UI scale has changed. + + // Remember the new UI scale. + maUIScale = aUIScale; + + // The content of the position and size boxes is only updated when item changes are notified. + // Request such notifications without changing the actual item values. + GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_X, true); + GetBindings()->Invalidate(SID_ATTR_TRANSFORM_POS_Y, true); + GetBindings()->Invalidate(SID_ATTR_TRANSFORM_WIDTH, true); + GetBindings()->Invalidate(SID_ATTR_TRANSFORM_HEIGHT, true); + } +} + + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/possize/PosSizePropertyPanel.hxx b/svx/source/sidebar/possize/PosSizePropertyPanel.hxx new file mode 100644 index 000000000..8abd1e0c8 --- /dev/null +++ b/svx/source/sidebar/possize/PosSizePropertyPanel.hxx @@ -0,0 +1,197 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_POSSIZE_POSSIZEPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_POSSIZE_POSSIZEPROPERTYPANEL_HXX + +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/weldutils.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> +#include <svl/poolitem.hxx> +#include <tools/fldunit.hxx> +#include <tools/fract.hxx> +#include <com/sun/star/ui/XSidebar.hpp> +#include <basegfx/range/b2drange.hxx> +#include <vcl/EnumContext.hxx> +#include <vcl/customweld.hxx> +#include <vcl/weld.hxx> + +class SdrView; + +namespace svx { +class DialControl; +}; + +namespace svx::sidebar { + +class PosSizePropertyPanel +: public PanelLayout, + public ::sfx2::sidebar::IContextChangeReceiver, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~PosSizePropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + + virtual void DataChanged( + const DataChangedEvent& rEvent) override; + + virtual void HandleContextChange( + const vcl::EnumContext& rContext) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual boost::property_tree::ptree DumpAsPropertyTree() override; + + SfxBindings* GetBindings() { return mpBindings;} + + // constructor/destructor + PosSizePropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings, + const css::uno::Reference<css::ui::XSidebar>& rxSidebar); + + virtual void GetControlState( + const sal_uInt16 nSId, + boost::property_tree::ptree& rState) override; + +private: + //Position + std::unique_ptr<weld::Label> mxFtPosX; + std::unique_ptr<weld::MetricSpinButton> mxMtrPosX; + std::unique_ptr<weld::Label> mxFtPosY; + std::unique_ptr<weld::MetricSpinButton> mxMtrPosY; + + // size + std::unique_ptr<weld::Label> mxFtWidth; + std::unique_ptr<weld::MetricSpinButton> mxMtrWidth; + std::unique_ptr<weld::Label> mxFtHeight; + std::unique_ptr<weld::MetricSpinButton> mxMtrHeight; + std::unique_ptr<weld::CheckButton> mxCbxScale; + + //rotation + std::unique_ptr<weld::Label> mxFtAngle; + std::unique_ptr<weld::MetricSpinButton> mxMtrAngle; + + //rotation control + std::unique_ptr<svx::DialControl> mxCtrlDial; + std::unique_ptr<weld::CustomWeld> mxDial; + + //flip + std::unique_ptr<weld::Label> mxFtFlip; + std::unique_ptr<weld::Toolbar> mxFlipTbx; + std::unique_ptr<ToolbarUnoDispatcher> mxFlipDispatch; + + std::unique_ptr<weld::Toolbar> mxArrangeTbx; + std::unique_ptr<ToolbarUnoDispatcher> mxArrangeDispatch; + std::unique_ptr<weld::Toolbar> mxArrangeTbx2; + std::unique_ptr<ToolbarUnoDispatcher> mxArrangeDispatch2; + + std::unique_ptr<weld::Toolbar> mxAlignTbx; + std::unique_ptr<ToolbarUnoDispatcher> mxAlignDispatch; + std::unique_ptr<weld::Toolbar> mxAlignTbx2; + std::unique_ptr<ToolbarUnoDispatcher> mxAlignDispatch2; + + //edit charts button for online's mobile view + std::unique_ptr<weld::Button> mxBtnEditChart; + + // Internal variables + basegfx::B2DRange maRect; + basegfx::B2DRange maWorkArea; + const SdrView* mpView; + sal_uInt32 mlOldWidth; + sal_uInt32 mlOldHeight; + long mlRotX; + long mlRotY; + Fraction maUIScale; + MapUnit mePoolUnit; + FieldUnit meDlgUnit; + + // Controller Items + ::sfx2::sidebar::ControllerItem maTransfPosXControl; + ::sfx2::sidebar::ControllerItem maTransfPosYControl; + ::sfx2::sidebar::ControllerItem maTransfWidthControl; + ::sfx2::sidebar::ControllerItem maTransfHeightControl; + + ::sfx2::sidebar::ControllerItem maSvxAngleControl; + ::sfx2::sidebar::ControllerItem maRotXControl; + ::sfx2::sidebar::ControllerItem maRotYControl; + ::sfx2::sidebar::ControllerItem maProPosControl; + ::sfx2::sidebar::ControllerItem maProSizeControl; + ::sfx2::sidebar::ControllerItem maAutoWidthControl; + ::sfx2::sidebar::ControllerItem maAutoHeightControl; + ::sfx2::sidebar::ControllerItem m_aMetricCtl; + + vcl::EnumContext maContext; + SfxBindings* mpBindings; + + bool mbSizeProtected : 1; + bool mbPositionProtected : 1; + bool mbAutoWidth : 1; + bool mbAutoHeight : 1; + bool mbAdjustEnabled : 1; + + css::uno::Reference<css::ui::XSidebar> mxSidebar; + + DECL_LINK( ChangePosXHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ChangePosYHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ChangeWidthHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ChangeHeightHdl, weld::MetricSpinButton&, void ); + DECL_LINK( ClickAutoHdl, weld::ToggleButton&, void ); + DECL_LINK( RotationHdl, svx::DialControl&, void ); + DECL_STATIC_LINK( PosSizePropertyPanel, ClickChartEditHdl, weld::Button&, void ); + + void Initialize(); + void executeSize(); + + void MetricState( SfxItemState eState, const SfxPoolItem* pState ); + static FieldUnit GetCurrentUnit( SfxItemState eState, const SfxPoolItem* pState ); + void DisableControls(); + void SetPosSizeMinMax(); + + /** Check if the UI scale has changed and handle such a change. + UI scale is an SD only feature. The UI scale is represented by items + ATTR_OPTIONS_SCALE_X and + ATTR_OPTIONS_SCALE_Y. + As we have no direct access (there is no dependency of svx on sd) we have to + use a small trick (aka hack): + a) call this method whenever a change of the metric item is notified, + b) check if the UI scale has changed (strangely, the UI scale value is available at the SdrModel. + c) invalidate the items for position and size to trigger notifications of their current values. + */ + void UpdateUIScale(); +}; + + +} // end of namespace svx::sidebar + + +#endif // INCLUDED_SVX_SOURCE_SIDEBAR_POSSIZE_POSSIZEPROPERTYPANEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx b/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx new file mode 100644 index 000000000..4fec06b5b --- /dev/null +++ b/svx/source/sidebar/shadow/ShadowPropertyPanel.cxx @@ -0,0 +1,334 @@ +/* -*- 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/. + */ + +#include "ShadowPropertyPanel.hxx" +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <svx/colorbox.hxx> +#include <svx/svxids.hrc> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <unotools/localedatawrapper.hxx> +#include <svx/sdooitm.hxx> +#include <svx/sdshitm.hxx> +#include <svx/sdshtitm.hxx> +#include <svx/sdprcitm.hxx> +#include <svx/sdsxyitm.hxx> +#include <svx/sdshcitm.hxx> + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { + +ShadowPropertyPanel::ShadowPropertyPanel( + vcl::Window* pParent, + const uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +: PanelLayout(pParent, "ShadowPropertyPanel", "svx/ui/sidebarshadow.ui", rxFrame), + maShadowController(SID_ATTR_FILL_SHADOW, *pBindings, *this), + maShadowTransController(SID_ATTR_SHADOW_TRANSPARENCE, *pBindings, *this), + maShadowColorController(SID_ATTR_SHADOW_COLOR, *pBindings, *this), + maShadowXDistanceController(SID_ATTR_SHADOW_XDISTANCE, *pBindings, *this), + maShadowYDistanceController(SID_ATTR_SHADOW_YDISTANCE, *pBindings, *this), + mpBindings(pBindings), + nX(0), + nY(0), + nXY(0), + mxShowShadow(m_xBuilder->weld_check_button("SHOW_SHADOW")), + mxShadowDistance(m_xBuilder->weld_metric_spin_button("LB_DISTANCE", FieldUnit::POINT)), + mxLBShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_SHADOW_COLOR"), GetFrameWeld())), + mxShadowAngle(m_xBuilder->weld_combo_box("LB_ANGLE")), + mxFTAngle(m_xBuilder->weld_label("angle")), + mxFTDistance(m_xBuilder->weld_label("distance")), + mxFTTransparency(m_xBuilder->weld_label("transparency_label")), + mxFTColor(m_xBuilder->weld_label("color")), + mxShadowTransSlider(m_xBuilder->weld_scale("transparency_slider")), + mxShadowTransMetric(m_xBuilder->weld_metric_spin_button("FIELD_TRANSPARENCY", FieldUnit::PERCENT)) +{ + Initialize(); +} + +ShadowPropertyPanel::~ShadowPropertyPanel() +{ + disposeOnce(); +} + +void ShadowPropertyPanel::dispose() +{ + mxShowShadow.reset(); + mxFTAngle.reset(); + mxShadowAngle.reset(); + mxFTDistance.reset(); + mxShadowDistance.reset(); + mxFTTransparency.reset(); + mxShadowTransSlider.reset(); + mxShadowTransMetric.reset(); + mxFTColor.reset(); + mxLBShadowColor.reset(); + + maShadowController.dispose(); + maShadowTransController.dispose(); + maShadowColorController.dispose(); + maShadowXDistanceController.dispose(); + maShadowYDistanceController.dispose(); + PanelLayout::dispose(); +} + +void ShadowPropertyPanel::Initialize() +{ + mxShowShadow->set_state( TRISTATE_FALSE ); + mxShowShadow->connect_toggled( LINK(this, ShadowPropertyPanel, ClickShadowHdl ) ); + mxShadowTransMetric->connect_value_changed( LINK(this, ShadowPropertyPanel, ModifyShadowTransMetricHdl) ); + mxLBShadowColor->SetSelectHdl( LINK( this, ShadowPropertyPanel, ModifyShadowColorHdl ) ); + mxShadowAngle->connect_changed( LINK(this, ShadowPropertyPanel, ModifyShadowAngleHdl) ); + mxShadowDistance->connect_value_changed( LINK(this, ShadowPropertyPanel, ModifyShadowDistanceHdl) ); + mxShadowTransSlider->set_range(0, 100); + mxShadowTransSlider->connect_value_changed( LINK(this, ShadowPropertyPanel, ModifyShadowTransSliderHdl) ); + InsertAngleValues(); +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ClickShadowHdl, weld::ToggleButton&, void) +{ + if( mxShowShadow->get_state() == TRISTATE_FALSE ) + { + SdrOnOffItem aItem(makeSdrShadowItem(false)); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_SHADOW, + SfxCallMode::RECORD, { &aItem }); + } + else + { + SdrOnOffItem aItem(makeSdrShadowItem(true)); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_FILL_SHADOW, + SfxCallMode::RECORD, { &aItem }); + } +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ModifyShadowColorHdl, ColorListBox&, void) +{ + XColorItem aItem(makeSdrShadowColorItem(mxLBShadowColor->GetSelectEntryColor())); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_SHADOW_COLOR, + SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ModifyShadowTransMetricHdl, weld::MetricSpinButton&, void) +{ + sal_uInt16 nVal = mxShadowTransMetric->get_value(FieldUnit::PERCENT); + SetTransparencyValue(nVal); + SdrPercentItem aItem( makeSdrShadowTransparenceItem(nVal) ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_SHADOW_TRANSPARENCE, + SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ModifyShadowTransSliderHdl, weld::Scale&, void) +{ + sal_uInt16 nVal = mxShadowTransSlider->get_value(); + SetTransparencyValue(nVal); + SdrPercentItem aItem( makeSdrShadowTransparenceItem(nVal) ); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_SHADOW_TRANSPARENCE, + SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ModifyShadowAngleHdl, weld::ComboBox&, void) +{ + ModifyShadowDistance(); +} + +IMPL_LINK_NOARG(ShadowPropertyPanel, ModifyShadowDistanceHdl, weld::MetricSpinButton&, void) +{ + ModifyShadowDistance(); +} + +void ShadowPropertyPanel::ModifyShadowDistance() +{ + auto nAngle = mxShadowAngle->get_active_id().toInt32(); + nXY = mxShadowDistance->get_value(FieldUnit::MM_100TH); + switch (nAngle) + { + case 0: nX = nXY; nY = 0; break; + case 45: nX = nXY; nY = -nXY; break; + case 90: nX = 0; nY = - nXY; break; + case 135: nX = nY = -nXY; break; + case 180: nX = -nXY; nY = 0; break; + case 225: nX = -nXY; nY = nXY; break; + case 270: nX = 0; nY = nXY; break; + case 315: nX = nY = nXY; break; + } + SdrMetricItem aXItem(makeSdrShadowXDistItem(nX)); + SdrMetricItem aYItem(makeSdrShadowYDistItem(nY)); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_SHADOW_XDISTANCE, + SfxCallMode::RECORD, { &aXItem }); + GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_SHADOW_YDISTANCE, + SfxCallMode::RECORD, { &aYItem }); +} + +void ShadowPropertyPanel::UpdateControls() +{ + if (mxShowShadow->get_state() == TRISTATE_FALSE) + { + mxShadowDistance->set_sensitive(false); + mxLBShadowColor->set_sensitive(false); + mxShadowAngle->set_sensitive(false); + mxFTAngle->set_sensitive(false); + mxFTDistance->set_sensitive(false); + mxFTTransparency->set_sensitive(false); + mxFTColor->set_sensitive(false); + mxShadowTransSlider->set_sensitive(false); + mxShadowTransMetric->set_sensitive(false); + return; + } + else + { + mxShadowDistance->set_sensitive(true); + mxLBShadowColor->set_sensitive(true); + mxShadowAngle->set_sensitive(true); + mxFTAngle->set_sensitive(true); + mxFTDistance->set_sensitive(true); + mxFTTransparency->set_sensitive(true); + mxFTColor->set_sensitive(true); + mxShadowTransSlider->set_sensitive(true); + mxShadowTransMetric->set_sensitive(true); + } + + if(nX > 0 && nY == 0) { mxShadowAngle->set_active(0); nXY = nX; } + else if( nX > 0 && nY < 0 ) { mxShadowAngle->set_active(1); nXY = nX; } + else if( nX == 0 && nY < 0 ) { mxShadowAngle->set_active(2); nXY = -nY; } + else if( nX < 0 && nY < 0 ) { mxShadowAngle->set_active(3); nXY = -nY; } + else if( nX < 0 && nY == 0 ) { mxShadowAngle->set_active(4); nXY = -nX; } + else if( nX < 0 && nY > 0 ) { mxShadowAngle->set_active(5); nXY = nY; } + else if( nX == 0 && nY > 0 ) { mxShadowAngle->set_active(6); nXY = nY; } + else if( nX > 0 && nY > 0 ) { mxShadowAngle->set_active(7); nXY = nX; } + else { nXY = 0; } + mxShadowDistance->set_value(nXY, FieldUnit::MM_100TH); +} + +void ShadowPropertyPanel::SetTransparencyValue(long nVal) +{ + mxShadowTransSlider->set_value(nVal); + mxShadowTransMetric->set_value(nVal, FieldUnit::PERCENT); +} + +void ShadowPropertyPanel::DataChanged(const DataChangedEvent& /*rEvent*/) +{ +} + +void ShadowPropertyPanel::InsertAngleValues() +{ + OUString sSuffix = weld::MetricSpinButton::MetricToString(FieldUnit::DEGREE); + + const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper(); + + mxShadowAngle->append(OUString::number(0), rLocaleData.getNum(0, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(45), rLocaleData.getNum(45, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(90), rLocaleData.getNum(90, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(135), rLocaleData.getNum(135, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(180), rLocaleData.getNum(180, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(225), rLocaleData.getNum(225, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(270), rLocaleData.getNum(270, 0, true, true) + sSuffix); + mxShadowAngle->append(OUString::number(315), rLocaleData.getNum(315, 0, true, true) + sSuffix); +} + +void ShadowPropertyPanel::NotifyItemUpdate( + sal_uInt16 nSID, + SfxItemState eState, + const SfxPoolItem* pState) +{ + switch(nSID) + { + case SID_ATTR_FILL_SHADOW: + { + if(eState >= SfxItemState::DEFAULT) + { + const SdrOnOffItem* pItem = dynamic_cast< const SdrOnOffItem* >(pState); + if(pItem) + { + if (pItem->GetValue()) + mxShowShadow->set_state(TRISTATE_TRUE); + else + mxShowShadow->set_state(TRISTATE_FALSE); + } + else + mxShowShadow.reset(); + } + } + break; + + case SID_ATTR_SHADOW_TRANSPARENCE: + { + if(eState >= SfxItemState::DEFAULT) + { + const SdrPercentItem* pTransparencyItem = dynamic_cast< const SdrPercentItem* >(pState); + if(pTransparencyItem) + { + const sal_uInt16 nVal = pTransparencyItem->GetValue(); + SetTransparencyValue(nVal); + } + else + SetTransparencyValue(0); + } + } + break; + + case SID_ATTR_SHADOW_COLOR: + { + if(eState >= SfxItemState::DEFAULT) + { + const XColorItem* pColorItem = dynamic_cast< const XColorItem* >(pState); + if(pColorItem) + { + mxLBShadowColor->SelectEntry(pColorItem->GetColorValue()); + } + } + } + break; + case SID_ATTR_SHADOW_XDISTANCE: + { + if(eState >= SfxItemState::DEFAULT) + { + const SdrMetricItem* pXDistItem = dynamic_cast< const SdrMetricItem* >(pState); + if(pXDistItem) + { + nX = pXDistItem->GetValue(); + } + } + } + break; + case SID_ATTR_SHADOW_YDISTANCE: + { + if(eState >= SfxItemState::DEFAULT) + { + const SdrMetricItem* pYDistItem = dynamic_cast< const SdrMetricItem* >(pState); + if(pYDistItem) + { + nY = pYDistItem->GetValue(); + } + } + } + break; + } + UpdateControls(); +} + +VclPtr<vcl::Window> ShadowPropertyPanel::Create ( + vcl::Window* pParent, + const uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if(pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to ShadowPropertyPanel::Create", nullptr, 0); + if( !rxFrame.is() ) + throw lang::IllegalArgumentException("no XFrame given to ShadowPropertyPanel::Create", nullptr, 1); + if(pBindings == nullptr) + throw lang::IllegalArgumentException("no SfxBindings given to ShadowPropertyPanel::Create", nullptr, 2); + + return VclPtr<ShadowPropertyPanel>::Create(pParent, rxFrame, pBindings); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx b/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx new file mode 100644 index 000000000..89260581d --- /dev/null +++ b/svx/source/sidebar/shadow/ShadowPropertyPanel.hxx @@ -0,0 +1,92 @@ +/* -*- 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/. + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_AREA_SHADOWPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_AREA_SHADOWPROPERTYPANEL_HXX + +#include <vcl/vclptr.hxx> +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> + +class ColorListBox; + +namespace svx::sidebar { + +class ShadowPropertyPanel +: public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + virtual ~ShadowPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void DataChanged( + const DataChangedEvent& rEvent) override; + + virtual void NotifyItemUpdate( + const sal_uInt16 nSId, + const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState( + const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override {}; + + SfxBindings* GetBindings() { return mpBindings;} + + void Initialize(); + + ShadowPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + +private: + ::sfx2::sidebar::ControllerItem maShadowController; + ::sfx2::sidebar::ControllerItem maShadowTransController; + ::sfx2::sidebar::ControllerItem maShadowColorController; + ::sfx2::sidebar::ControllerItem maShadowXDistanceController; + ::sfx2::sidebar::ControllerItem maShadowYDistanceController; + + SfxBindings* mpBindings; + long nX,nY,nXY; + + std::unique_ptr<weld::CheckButton> mxShowShadow; + std::unique_ptr<weld::MetricSpinButton> mxShadowDistance; + std::unique_ptr<ColorListBox> mxLBShadowColor; + std::unique_ptr<weld::ComboBox> mxShadowAngle; + std::unique_ptr<weld::Label> mxFTAngle; + std::unique_ptr<weld::Label> mxFTDistance; + std::unique_ptr<weld::Label> mxFTTransparency; + std::unique_ptr<weld::Label> mxFTColor; + std::unique_ptr<weld::Scale> mxShadowTransSlider; + std::unique_ptr<weld::MetricSpinButton> mxShadowTransMetric; + + void InsertAngleValues(); + void SetTransparencyValue(long); + void UpdateControls(); + void ModifyShadowDistance(); + + DECL_LINK(ClickShadowHdl, weld::ToggleButton&, void); + DECL_LINK(ModifyShadowColorHdl, ColorListBox&, void); + DECL_LINK(ModifyShadowTransMetricHdl, weld::MetricSpinButton&, void); + DECL_LINK(ModifyShadowAngleHdl, weld::ComboBox&, void); + DECL_LINK(ModifyShadowDistanceHdl, weld::MetricSpinButton&, void); + DECL_LINK(ModifyShadowTransSliderHdl, weld::Scale&, void); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/shapes/DefaultShapesPanel.cxx b/svx/source/sidebar/shapes/DefaultShapesPanel.cxx new file mode 100644 index 000000000..9295d9b5a --- /dev/null +++ b/svx/source/sidebar/shapes/DefaultShapesPanel.cxx @@ -0,0 +1,160 @@ +/* -*- 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 <DefaultShapesPanel.hxx> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <comphelper/dispatchcommand.hxx> +#include <vcl/commandinfoprovider.hxx> +#include <vcl/settings.hxx> + +namespace svx::sidebar { + +DefaultShapesPanel::DefaultShapesPanel ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) + : PanelLayout(pParent, "DefaultShapesPanel", "svx/ui/defaultshapespanel.ui", rxFrame) + , SvxShapeCommandsMap() + , mxLineArrowSet(new ValueSet(nullptr)) + , mxLineArrowSetWin(new weld::CustomWeld(*m_xBuilder, "LinesArrows", *mxLineArrowSet)) + , mxCurveSet(new ValueSet(nullptr)) + , mxCurveSetWin(new weld::CustomWeld(*m_xBuilder, "Curves", *mxCurveSet)) + , mxConnectorSet(new ValueSet(nullptr)) + , mxConnectorSetWin(new weld::CustomWeld(*m_xBuilder, "Connectors", *mxConnectorSet)) + , mxBasicShapeSet(new ValueSet(nullptr)) + , mxBasicShapeSetWin(new weld::CustomWeld(*m_xBuilder, "BasicShapes", *mxBasicShapeSet)) + , mxSymbolShapeSet(new ValueSet(nullptr)) + , mxSymbolShapeSetWin(new weld::CustomWeld(*m_xBuilder, "SymbolShapes", *mxSymbolShapeSet)) + , mxBlockArrowSet(new ValueSet(nullptr)) + , mxBlockArrowSetWin(new weld::CustomWeld(*m_xBuilder, "BlockArrows", *mxBlockArrowSet)) + , mxFlowchartSet(new ValueSet(nullptr)) + , mxFlowchartSetWin(new weld::CustomWeld(*m_xBuilder, "Flowcharts", *mxFlowchartSet)) + , mxCalloutSet(new ValueSet(nullptr)) + , mxCalloutSetWin(new weld::CustomWeld(*m_xBuilder, "Callouts", *mxCalloutSet)) + , mxStarSet(new ValueSet(nullptr)) + , mxStarSetWin(new weld::CustomWeld(*m_xBuilder, "Stars", *mxStarSet)) + , mx3DObjectSet(new ValueSet(nullptr)) + , mx3DObjectSetWin(new weld::CustomWeld(*m_xBuilder, "3DObjects", *mx3DObjectSet)) + , mxFrame(rxFrame) +{ + Initialize(); +} + +VclPtr< vcl::Window > DefaultShapesPanel::Create( + vcl::Window* pParent, + const Reference< XFrame >& rxFrame) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to DefaultShapesPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to DefaultShapesPanel::Create", nullptr, 1); + + return VclPtr<DefaultShapesPanel>::Create( + pParent, + rxFrame); +} + +DefaultShapesPanel::~DefaultShapesPanel() +{ + disposeOnce(); +} + +void DefaultShapesPanel::Initialize() +{ + mpShapesSetMap = decltype(mpShapesSetMap){ + { mxLineArrowSet.get(), mpLineShapes }, + { mxCurveSet.get(), mpCurveShapes }, + { mxConnectorSet.get(), mpConnectorShapes }, + { mxBasicShapeSet.get(), mpBasicShapes }, + { mxSymbolShapeSet.get(), mpSymbolShapes }, + { mxBlockArrowSet.get(), mpBlockArrowShapes }, + { mxFlowchartSet.get(), mpFlowchartShapes }, + { mxCalloutSet.get(), mpCalloutShapes }, + { mxStarSet.get(), mpStarShapes }, + { mx3DObjectSet.get(), mp3DShapes } + }; + populateShapes(); + for(auto& aSetMap: mpShapesSetMap) + { + aSetMap.first->SetColor(GetSettings().GetStyleSettings().GetDialogColor()); + aSetMap.first->SetSelectHdl(LINK(this, DefaultShapesPanel, ShapeSelectHdl)); + } +} + +void DefaultShapesPanel::dispose() +{ + mpShapesSetMap.clear(); + mxLineArrowSetWin.reset(); + mxLineArrowSet.reset(); + mxCurveSetWin.reset(); + mxCurveSet.reset(); + mxConnectorSetWin.reset(); + mxConnectorSet.reset(); + mxBasicShapeSetWin.reset(); + mxBasicShapeSet.reset(); + mxSymbolShapeSetWin.reset(); + mxSymbolShapeSet.reset(); + mxBlockArrowSetWin.reset(); + mxBlockArrowSet.reset(); + mxFlowchartSetWin.reset(); + mxFlowchartSet.reset(); + mxCalloutSetWin.reset(); + mxCalloutSet.reset(); + mxStarSetWin.reset(); + mxStarSet.reset(); + mx3DObjectSetWin.reset(); + mx3DObjectSet.reset(); + PanelLayout::dispose(); +} + +IMPL_LINK(DefaultShapesPanel, ShapeSelectHdl, ValueSet*, rValueSet, void) +{ + for(auto& aSetMap : mpShapesSetMap) + { + if(rValueSet == aSetMap.first) + { + int aSelection = aSetMap.first->GetSelectedItemId(); + comphelper::dispatchCommand(aSetMap.second[aSelection], {}); + } + else + aSetMap.first->SetNoSelection(); + } +} + +void DefaultShapesPanel::populateShapes() +{ + OUString sSlotStr, sLabel; + Image aSlotImage; + for(auto& aSet : mpShapesSetMap) + { + aSet.first->SetColCount(6); + for(std::map<sal_uInt16, OUString>::size_type i = 0; i < aSet.second.size(); i++) + { + sSlotStr = aSet.second[i]; + aSlotImage = vcl::CommandInfoProvider::GetImageForCommand(sSlotStr, mxFrame); + auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(sSlotStr, + vcl::CommandInfoProvider::GetModuleIdentifier(mxFrame)); + sLabel = vcl::CommandInfoProvider::GetTooltipForCommand(sSlotStr, aProperties, mxFrame); + aSet.first->InsertItem(i, aSlotImage, sLabel); + } + } +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/shapes/ShapesUtil.cxx b/svx/source/sidebar/shapes/ShapesUtil.cxx new file mode 100644 index 000000000..ffd1acb62 --- /dev/null +++ b/svx/source/sidebar/shapes/ShapesUtil.cxx @@ -0,0 +1,212 @@ +/* -*- 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 <ShapesUtil.hxx> +#include <map> +#include <rtl/ustring.hxx> + +namespace svx::sidebar{ +SvxShapeCommandsMap::SvxShapeCommandsMap() +{ + mpLineShapes = decltype(mpLineShapes){ + {0, ".uno:Line"}, + {1, ".uno:LineArrowEnd"}, + {2, ".uno:LineCircleArrow"}, + {3, ".uno:LineSquareArrow"}, + {4, ".uno:LineArrows"}, + {5, ".uno:LineArrowStart"}, + {6, ".uno:LineArrowCircle"}, + {7, ".uno:LineArrowSquare"}, + {8, ".uno:MeasureLine"}, + {9, ".uno:Line_Diagonal"} + }; + + mpCurveShapes = decltype(mpCurveShapes){ + {0, ".uno:Freeline_Unfilled"}, + {1, ".uno:Bezier_Unfilled"}, + {2, ".uno:Polygon_Unfilled"}, + {3, ".uno:Polygon_Diagonal_Unfilled"}, + {4, ".uno:Freeline"}, + {5, ".uno:BezierFill"}, + {6, ".uno:Polygon"}, + {7, ".uno:Polygon_Diagonal"} + }; + + mpConnectorShapes = decltype(mpConnectorShapes){ + {0, ".uno:ConnectorArrowEnd"}, + {1, ".uno:ConnectorLineArrowEnd"}, + {2, ".uno:ConnectorCurveArrowEnd"}, + {3, ".uno:ConnectorLinesArrowEnd"}, + {4, ".uno:Connector"}, + {5, ".uno:ConnectorLine"}, + {6, ".uno:ConnectorCurve"}, + {7, ".uno:ConnectorLines"}, + {8, ".uno:ConnectorArrows"}, + {9, ".uno:ConnectorLineArrows"}, + {10, ".uno:ConnectorCurveArrows"}, + {11, ".uno:ConnectorLinesArrows"} + }; + + mpBasicShapes = decltype(mpBasicShapes){ + {0, ".uno:BasicShapes.rectangle"}, + {1, ".uno:BasicShapes.round-rectangle"}, + {2, ".uno:BasicShapes.quadrat"}, + {3, ".uno:BasicShapes.round-quadrat"}, + {4, ".uno:BasicShapes.parallelogram"}, + {5, ".uno:BasicShapes.trapezoid"}, + {6, ".uno:BasicShapes.ellipse"}, + {7, ".uno:BasicShapes.circle"}, + {8, ".uno:BasicShapes.circle-pie"}, + {9, ".uno:CircleCut"}, + {10, ".uno:Arc"}, + {11, ".uno:BasicShapes.block-arc"}, + {12, ".uno:BasicShapes.isosceles-triangle"}, + {13, ".uno:BasicShapes.right-triangle"}, + {14, ".uno:BasicShapes.diamond"}, + {15, ".uno:BasicShapes.pentagon"}, + {16, ".uno:BasicShapes.hexagon"}, + {17, ".uno:BasicShapes.octagon"}, + {18, ".uno:BasicShapes.cross"}, + {19, ".uno:BasicShapes.can"}, + {20, ".uno:BasicShapes.cube"}, + {21, ".uno:BasicShapes.paper"}, + {22, ".uno:BasicShapes.frame"}, + {23, ".uno:BasicShapes.ring"} + }; + + mpSymbolShapes = decltype(mpSymbolShapes){ + {0, ".uno:SymbolShapes.smiley"}, + {1, ".uno:SymbolShapes.sun"}, + {2, ".uno:SymbolShapes.moon"}, + {3, ".uno:SymbolShapes.lightning"}, + {4, ".uno:SymbolShapes.heart"}, + {5, ".uno:SymbolShapes.flower"}, + {6, ".uno:SymbolShapes.cloud"}, + {7, ".uno:SymbolShapes.forbidden"}, + {8, ".uno:SymbolShapes.puzzle"}, + {9, ".uno:SymbolShapes.bracket-pair"}, + {10, ".uno:SymbolShapes.left-bracket"}, + {11, ".uno:SymbolShapes.right-bracket"}, + {12, ".uno:SymbolShapes.brace-pair"}, + {13, ".uno:SymbolShapes.left-brace"}, + {14, ".uno:SymbolShapes.right-brace"}, + {15, ".uno:SymbolShapes.quad-bevel"}, + {16, ".uno:SymbolShapes.octagon-bevel"}, + {17, ".uno:SymbolShapes.diamond-bevel"} + }; + + mpBlockArrowShapes = decltype(mpBlockArrowShapes){ + {0, ".uno:ArrowShapes.left-arrow"}, + {1, ".uno:ArrowShapes.right-arrow"}, + {2, ".uno:ArrowShapes.up-arrow"}, + {3, ".uno:ArrowShapes.down-arrow"}, + {4, ".uno:ArrowShapes.left-right-arrow"}, + {5, ".uno:ArrowShapes.up-down-arrow"}, + {6, ".uno:ArrowShapes.up-right-arrow"}, + {7, ".uno:ArrowShapes.up-right-down-arrow"}, + {8, ".uno:ArrowShapes.quad-arrow"}, + {9, ".uno:ArrowShapes.corner-right-arrow"}, + {10, ".uno:ArrowShapes.split-arrow"}, + {11, ".uno:ArrowShapes.striped-right-arrow"}, + {12, ".uno:ArrowShapes.notched-right-arrow"}, + {13, ".uno:ArrowShapes.pentagon-right"}, + {14, ".uno:ArrowShapes.chevron"}, + {15, ".uno:ArrowShapes.right-arrow-callout"}, + {16, ".uno:ArrowShapes.left-arrow-callout"}, + {17, ".uno:ArrowShapes.up-arrow-callout"}, + {18, ".uno:ArrowShapes.left-right-arrow-callout"}, + {19, ".uno:ArrowShapes.up-down-arrow-callout"}, + {20, ".uno:ArrowShapes.up-right-arrow-callout"}, + {21, ".uno:ArrowShapes.quad-arrow-callout"}, + {22, ".uno:ArrowShapes.circular-arrow"}, + {23, ".uno:ArrowShapes.down-arrow-callout"}, + {24, ".uno:ArrowShapes.split-round-arrow"}, + {25, ".uno:ArrowShapes.s-sharped-arrow"} + }; + + mpFlowchartShapes = decltype(mpFlowchartShapes){ + {0, ".uno:FlowChartShapes.flowchart-process"}, + {1, ".uno:FlowChartShapes.flowchart-alternate-process"}, + {2, ".uno:FlowChartShapes.flowchart-decision"}, + {3, ".uno:FlowChartShapes.flowchart-data"}, + {4, ".uno:FlowChartShapes.flowchart-predefined-process"}, + {5, ".uno:FlowChartShapes.flowchart-internal-storage"}, + {6, ".uno:FlowChartShapes.flowchart-document"}, + {7, ".uno:FlowChartShapes.flowchart-multidocument"}, + {8, ".uno:FlowChartShapes.flowchart-terminator"}, + {9, ".uno:FlowChartShapes.flowchart-preparation"}, + {10, ".uno:FlowChartShapes.flowchart-manual-input"}, + {11, ".uno:FlowChartShapes.flowchart-manual-operation"}, + {12, ".uno:FlowChartShapes.flowchart-connector"}, + {13, ".uno:FlowChartShapes.flowchart-off-page-connector"}, + {14, ".uno:FlowChartShapes.flowchart-card"}, + {15, ".uno:FlowChartShapes.flowchart-punched-tape"}, + {16, ".uno:FlowChartShapes.flowchart-summing-junction"}, + {17, ".uno:FlowChartShapes.flowchart-or"}, + {18, ".uno:FlowChartShapes.flowchart-collate"}, + {19, ".uno:FlowChartShapes.flowchart-sort"}, + {20, ".uno:FlowChartShapes.flowchart-extract"}, + {21, ".uno:FlowChartShapes.flowchart-merge"}, + {22, ".uno:FlowChartShapes.flowchart-stored-data"}, + {23, ".uno:FlowChartShapes.flowchart-delay"}, + {24, ".uno:FlowChartShapes.flowchart-sequential-access"}, + {25, ".uno:FlowChartShapes.flowchart-magnetic-disk"}, + {26, ".uno:FlowChartShapes.flowchart-direct-access-storage"}, + {27, ".uno:FlowChartShapes.flowchart-display"} + }; + + mpCalloutShapes = decltype(mpCalloutShapes){ + {0, ".uno:CalloutShapes.rectangular-callout"}, + {1, ".uno:CalloutShapes.round-rectangular-callout"}, + {2, ".uno:CalloutShapes.round-callout"}, + {3, ".uno:CalloutShapes.cloud-callout"}, + {4, ".uno:CalloutShapes.line-callout-1"}, + {5, ".uno:CalloutShapes.line-callout-2"}, + {6, ".uno:CalloutShapes.line-callout-3"} + }; + + mpStarShapes = decltype(mpStarShapes){ + {0, ".uno:StarShapes.star4"}, + {1, ".uno:StarShapes.star5"}, + {2, ".uno:StarShapes.star6"}, + {3, ".uno:StarShapes.star8"}, + {4, ".uno:StarShapes.star12"}, + {5, ".uno:StarShapes.star24"}, + {6, ".uno:StarShapes.bang"}, + {7, ".uno:StarShapes.vertical-scroll"}, + {8, ".uno:StarShapes.horizontal-scroll"}, + {9, ".uno:StarShapes.signet"}, + {10, ".uno:StarShapes.doorplate"}, + {11, ".uno:StarShapes.concave-star6"} + }; + + mp3DShapes = decltype(mp3DShapes){ + {0, ".uno:Cube"}, + {1, ".uno:Sphere"}, + {2, ".uno:Cylinder"}, + {3, ".uno:Cone"}, + {4, ".uno:Cyramid"}, + {5, ".uno:Torus"}, + {6, ".uno:Shell3D"}, + {7, ".uno:HalfSphere"} + }; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
\ No newline at end of file diff --git a/svx/source/sidebar/softedge/SoftEdgePropertyPanel.cxx b/svx/source/sidebar/softedge/SoftEdgePropertyPanel.cxx new file mode 100644 index 000000000..35511498f --- /dev/null +++ b/svx/source/sidebar/softedge/SoftEdgePropertyPanel.cxx @@ -0,0 +1,96 @@ +/* -*- 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/. + */ + +#include <sal/config.h> + +#include "SoftEdgePropertyPanel.hxx" + +#include <sfx2/dispatch.hxx> +#include <svx/sdmetitm.hxx> +#include <svx/svddef.hxx> +#include <svx/svxids.hrc> +#include <svx/xcolit.hxx> + +namespace svx::sidebar +{ +SoftEdgePropertyPanel::SoftEdgePropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) + : PanelLayout(pParent, "SoftEdgePropertyPanel", "svx/ui/sidebarsoftedge.ui", rxFrame) + , maSoftEdgeRadiusController(SID_ATTR_SOFTEDGE_RADIUS, *pBindings, *this) + , mpBindings(pBindings) + , mxSoftEdgeRadius(m_xBuilder->weld_metric_spin_button("SB_SOFTEDGE_RADIUS", FieldUnit::POINT)) + , mxFTRadius(m_xBuilder->weld_label("radius")) +{ + Initialize(); +} + +SoftEdgePropertyPanel::~SoftEdgePropertyPanel() { disposeOnce(); } + +void SoftEdgePropertyPanel::dispose() +{ + mxFTRadius.reset(); + mxSoftEdgeRadius.reset(); + maSoftEdgeRadiusController.dispose(); + PanelLayout::dispose(); +} + +void SoftEdgePropertyPanel::Initialize() +{ + mxSoftEdgeRadius->connect_value_changed( + LINK(this, SoftEdgePropertyPanel, ModifySoftEdgeRadiusHdl)); +} + +IMPL_LINK_NOARG(SoftEdgePropertyPanel, ModifySoftEdgeRadiusHdl, weld::MetricSpinButton&, void) +{ + SdrMetricItem aItem(SDRATTR_SOFTEDGE_RADIUS, mxSoftEdgeRadius->get_value(FieldUnit::MM_100TH)); + mpBindings->GetDispatcher()->ExecuteList(SID_ATTR_SOFTEDGE_RADIUS, SfxCallMode::RECORD, + { &aItem }); +} + +void SoftEdgePropertyPanel::NotifyItemUpdate(sal_uInt16 nSID, SfxItemState eState, + const SfxPoolItem* pState) +{ + switch (nSID) + { + case SID_ATTR_SOFTEDGE_RADIUS: + { + if (eState >= SfxItemState::DEFAULT) + { + const SdrMetricItem* pRadiusItem = dynamic_cast<const SdrMetricItem*>(pState); + if (pRadiusItem) + { + mxSoftEdgeRadius->set_value(pRadiusItem->GetValue(), FieldUnit::MM_100TH); + } + } + } + break; + } +} + +VclPtr<vcl::Window> +SoftEdgePropertyPanel::Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings) +{ + if (pParent == nullptr) + throw css::lang::IllegalArgumentException( + "no parent Window given to SoftEdgePropertyPanel::Create", nullptr, 0); + if (!rxFrame.is()) + throw css::lang::IllegalArgumentException( + "no XFrame given to SoftEdgePropertyPanel::Create", nullptr, 1); + if (pBindings == nullptr) + throw css::lang::IllegalArgumentException( + "no SfxBindings given to SoftEdgePropertyPanel::Create", nullptr, 2); + + return VclPtr<SoftEdgePropertyPanel>::Create(pParent, rxFrame, pBindings); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/softedge/SoftEdgePropertyPanel.hxx b/svx/source/sidebar/softedge/SoftEdgePropertyPanel.hxx new file mode 100644 index 000000000..c7f3b698c --- /dev/null +++ b/svx/source/sidebar/softedge/SoftEdgePropertyPanel.hxx @@ -0,0 +1,56 @@ +/* -*- 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/. + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_SOFTEDGE_SOFTEDGEPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_SOFTEDGE_SOFTEDGEPROPERTYPANEL_HXX + +#include <vcl/vclptr.hxx> +#include <sfx2/sidebar/ControllerItem.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> + +class ColorListBox; + +namespace svx::sidebar +{ +class SoftEdgePropertyPanel : public PanelLayout, + public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface +{ +public: + SoftEdgePropertyPanel(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + virtual ~SoftEdgePropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create(vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame, + SfxBindings* pBindings); + + virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, + const SfxPoolItem* pState) override; + + virtual void GetControlState(const sal_uInt16 /*nSId*/, + boost::property_tree::ptree& /*rState*/) override{}; + +private: + sfx2::sidebar::ControllerItem maSoftEdgeRadiusController; + + SfxBindings* mpBindings; + + std::unique_ptr<weld::MetricSpinButton> mxSoftEdgeRadius; + std::unique_ptr<weld::Label> mxFTRadius; + + void Initialize(); + + DECL_LINK(ModifySoftEdgeRadiusHdl, weld::MetricSpinButton&, void); +}; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/styles/StylesPropertyPanel.cxx b/svx/source/sidebar/styles/StylesPropertyPanel.cxx new file mode 100644 index 000000000..a583e0603 --- /dev/null +++ b/svx/source/sidebar/styles/StylesPropertyPanel.cxx @@ -0,0 +1,53 @@ +#include <sal/config.h> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include "StylesPropertyPanel.hxx" + +using namespace css; +using namespace css::uno; + +namespace svx::sidebar { + +VclPtr<vcl::Window> StylesPropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to StylesPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to StylesPropertyPanel::Create", nullptr, 1); + + return VclPtr<StylesPropertyPanel>::Create(pParent,rxFrame); +} + +StylesPropertyPanel::StylesPropertyPanel ( vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame ) + : PanelLayout(pParent, "SidebarStylesPanel", "svx/ui/sidebarstylespanel.ui", rxFrame) + , m_xFontStyle(m_xBuilder->weld_toolbar("fontstyletoolbox")) + , m_xFontStyleDispatch(new ToolbarUnoDispatcher(*m_xFontStyle, *m_xBuilder, rxFrame)) + , m_xStyle(m_xBuilder->weld_toolbar("style")) + , m_xStyleDispatch(new ToolbarUnoDispatcher(*m_xStyle, *m_xBuilder, rxFrame)) +{ +} + +StylesPropertyPanel::~StylesPropertyPanel() +{ + disposeOnce(); +} + +void StylesPropertyPanel::dispose() +{ + m_xStyleDispatch.reset(); + m_xStyle.reset(); + m_xFontStyleDispatch.reset(); + m_xFontStyle.reset(); + + PanelLayout::dispose(); +} + +void StylesPropertyPanel::DataChanged( const DataChangedEvent& /*rEvent*/) +{ + +} + +} diff --git a/svx/source/sidebar/styles/StylesPropertyPanel.hxx b/svx/source/sidebar/styles/StylesPropertyPanel.hxx new file mode 100644 index 000000000..f9dd6b174 --- /dev/null +++ b/svx/source/sidebar/styles/StylesPropertyPanel.hxx @@ -0,0 +1,34 @@ +#pragma once + +#include <sfx2/sidebar/PanelLayout.hxx> +#include <sfx2/weldutils.hxx> + +namespace svx::sidebar{ + +class StylesPropertyPanel: + public PanelLayout +{ +private: + std::unique_ptr<weld::Toolbar> m_xFontStyle; + std::unique_ptr<ToolbarUnoDispatcher> m_xFontStyleDispatch; + + std::unique_ptr<weld::Toolbar> m_xStyle; + std::unique_ptr<ToolbarUnoDispatcher> m_xStyleDispatch; + +public: + virtual ~StylesPropertyPanel() override; + + static VclPtr<vcl::Window> Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + + virtual void DataChanged( const DataChangedEvent& rEvent ) override; + + virtual void dispose() override; + + StylesPropertyPanel( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); +}; + +} //end of namespace svx::sidebar diff --git a/svx/source/sidebar/text/TextCharacterSpacingControl.cxx b/svx/source/sidebar/text/TextCharacterSpacingControl.cxx new file mode 100644 index 000000000..72ef14ce8 --- /dev/null +++ b/svx/source/sidebar/text/TextCharacterSpacingControl.cxx @@ -0,0 +1,198 @@ +/* -*- 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 <sfx2/bindings.hxx> +#include "TextCharacterSpacingControl.hxx" +#include <unotools/viewoptions.hxx> +#include <editeng/editids.hrc> +#include <editeng/kernitem.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewfrm.hxx> +#include <svx/TextCharacterSpacingPopup.hxx> +#include <svl/itempool.hxx> +#include <helpids.h> + +#include <com/sun/star/beans/NamedValue.hpp> + +#define SPACING_VERY_TIGHT -30 +#define SPACING_TIGHT -15 +#define SPACING_NORMAL 0 +#define SPACING_LOOSE 30 +#define SPACING_VERY_LOOSE 60 + +namespace svx { + +TextCharacterSpacingControl::TextCharacterSpacingControl(TextCharacterSpacingPopup* pControl, weld::Widget* pParent) + : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/textcharacterspacingcontrol.ui", "TextCharacterSpacingControl") + , mnCustomKern(0) + , mnLastCus(SPACING_NOCUSTOM) + , mxEditKerning(m_xBuilder->weld_metric_spin_button("kerning", FieldUnit::POINT)) + , mxTight(m_xBuilder->weld_button("tight")) + , mxVeryTight(m_xBuilder->weld_button("very_tight")) + , mxNormal(m_xBuilder->weld_button("normal")) + , mxLoose(m_xBuilder->weld_button("loose")) + , mxVeryLoose(m_xBuilder->weld_button("very_loose")) + , mxLastCustom(m_xBuilder->weld_button("last_custom")) + , mxControl(pControl) +{ + mxEditKerning->connect_value_changed(LINK(this, TextCharacterSpacingControl, KerningModifyHdl)); + mxEditKerning->set_help_id(HID_SPACING_MB_KERN); + + Link<weld::Button&,void> aLink = LINK(this, TextCharacterSpacingControl, PredefinedValuesHdl); + mxNormal->connect_clicked(aLink); + mxVeryTight->connect_clicked(aLink); + mxTight->connect_clicked(aLink); + mxVeryLoose->connect_clicked(aLink); + mxLoose->connect_clicked(aLink); + mxLastCustom->connect_clicked(aLink); + + Initialize(); +} + +void TextCharacterSpacingControl::GrabFocus() +{ + mxVeryTight->grab_focus(); +} + +TextCharacterSpacingControl::~TextCharacterSpacingControl() +{ + if (mnLastCus == SPACING_CLOSE_BY_CUS_EDIT) + { + SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE); + css::uno::Sequence<css::beans::NamedValue> aSeq + { { "Spacing", css::uno::makeAny(OUString::number(mnCustomKern)) } }; + aWinOpt.SetUserData(aSeq); + } +} + +void TextCharacterSpacingControl::Initialize() +{ + const SfxPoolItem* pItem; + SfxItemState eState = SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_CHAR_KERNING, pItem); + + const SvxKerningItem* pKerningItem = static_cast<const SvxKerningItem*>(pItem); + long nKerning = 0; + + if(pKerningItem) + nKerning = pKerningItem->GetValue(); + + SvtViewOptions aWinOpt(EViewType::Window, SIDEBAR_SPACING_GLOBAL_VALUE); + if(aWinOpt.Exists()) + { + css::uno::Sequence<css::beans::NamedValue> aSeq = aWinOpt.GetUserData(); + OUString aTmp; + if(aSeq.hasElements()) + aSeq[0].Value >>= aTmp; + + OUString aWinData(aTmp); + mnCustomKern = aWinData.toInt32(); + mnLastCus = SPACING_CLOSE_BY_CUS_EDIT; + } + else + { + mnLastCus = SPACING_NOCUSTOM; + } + + if(eState >= SfxItemState::DEFAULT) + { + MapUnit eUnit = GetCoreMetric(); + MapUnit eOrgUnit = eUnit; + long nBig = mxEditKerning->normalize(nKerning); + nKerning = OutputDevice::LogicToLogic(nBig, eOrgUnit, MapUnit::MapPoint); + mxEditKerning->set_value(nKerning, FieldUnit::NONE); + } + else if(SfxItemState::DISABLED == eState) + { + mxEditKerning->set_text(OUString()); + mxEditKerning->set_sensitive(false); + } + else + { + mxEditKerning->set_text(OUString()); + mxEditKerning->set_sensitive(false); + } +} + +void TextCharacterSpacingControl::ExecuteCharacterSpacing(long nValue, bool bClose) +{ + MapUnit eUnit = GetCoreMetric(); + + long nSign = (nValue < 0) ? -1 : 1; + nValue = nValue * nSign; + + long nVal = OutputDevice::LogicToLogic(nValue, MapUnit::MapPoint, eUnit); + short nKern = (nValue == 0) ? 0 : static_cast<short>(mxEditKerning->denormalize(nVal)); + + SvxKerningItem aKernItem(nSign * nKern, SID_ATTR_CHAR_KERNING); + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->ExecuteList(SID_ATTR_CHAR_KERNING, + SfxCallMode::RECORD, { &aKernItem }); + + if (bClose) + mxControl->EndPopupMode(); +} + +IMPL_LINK(TextCharacterSpacingControl, PredefinedValuesHdl, weld::Button&, rControl, void) +{ + mnLastCus = SPACING_CLOSE_BY_CLICK_ICON; + + if (&rControl == mxNormal.get()) + { + ExecuteCharacterSpacing(SPACING_NORMAL); + } + else if (&rControl == mxVeryTight.get()) + { + ExecuteCharacterSpacing(SPACING_VERY_TIGHT); + } + else if (&rControl == mxTight.get()) + { + ExecuteCharacterSpacing(SPACING_TIGHT); + } + else if (&rControl == mxVeryLoose.get()) + { + ExecuteCharacterSpacing(SPACING_VERY_LOOSE); + } + else if (&rControl == mxLoose.get()) + { + ExecuteCharacterSpacing(SPACING_LOOSE); + } + else if (&rControl == mxLastCustom.get()) + { + ExecuteCharacterSpacing(mnCustomKern); + } +} + +IMPL_LINK_NOARG(TextCharacterSpacingControl, KerningModifyHdl, weld::MetricSpinButton&, void) +{ + mnLastCus = SPACING_CLOSE_BY_CUS_EDIT; + mnCustomKern = mxEditKerning->get_value(FieldUnit::NONE); + + ExecuteCharacterSpacing(mnCustomKern, false); +} + +MapUnit TextCharacterSpacingControl::GetCoreMetric() +{ + SfxItemPool &rPool = SfxGetpApp()->GetPool(); + sal_uInt16 nWhich = rPool.GetWhich(SID_ATTR_CHAR_KERNING); + return rPool.GetMetric(nWhich); +} + +} // end of namespace svx + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextCharacterSpacingControl.hxx b/svx/source/sidebar/text/TextCharacterSpacingControl.hxx new file mode 100644 index 000000000..f5ff964f0 --- /dev/null +++ b/svx/source/sidebar/text/TextCharacterSpacingControl.hxx @@ -0,0 +1,69 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTCHARACTERSPACINGCONTROL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTCHARACTERSPACINGCONTROL_HXX + +#include <svtools/toolbarmenu.hxx> + +namespace svx { +#define SPACING_NOCUSTOM 0 +#define SPACING_CLOSE_BY_CLICK_ICON -1 +#define SPACING_CLOSE_BY_CUS_EDIT 1 + +#define SIDEBAR_SPACING_GLOBAL_VALUE "PopupPanel_Spacing" + +class TextCharacterSpacingPopup; + +class TextCharacterSpacingControl final : public WeldToolbarPopup +{ +public: + explicit TextCharacterSpacingControl(TextCharacterSpacingPopup* pControl, weld::Widget* pParent); + + virtual void GrabFocus() override; + + virtual ~TextCharacterSpacingControl() override; + +private: + long mnCustomKern; + short mnLastCus; + + std::unique_ptr<weld::MetricSpinButton> mxEditKerning; + std::unique_ptr<weld::Button> mxTight; + std::unique_ptr<weld::Button> mxVeryTight; + std::unique_ptr<weld::Button> mxNormal; + std::unique_ptr<weld::Button> mxLoose; + std::unique_ptr<weld::Button> mxVeryLoose; + std::unique_ptr<weld::Button> mxLastCustom; + + rtl::Reference<TextCharacterSpacingPopup> mxControl; + + void Initialize(); + void ExecuteCharacterSpacing(long nValue, bool bClose = true); + + DECL_LINK(PredefinedValuesHdl, weld::Button&, void); + DECL_LINK(KerningModifyHdl, weld::MetricSpinButton&, void); + + static MapUnit GetCoreMetric(); +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextCharacterSpacingPopup.cxx b/svx/source/sidebar/text/TextCharacterSpacingPopup.cxx new file mode 100644 index 000000000..5c1bf67dc --- /dev/null +++ b/svx/source/sidebar/text/TextCharacterSpacingPopup.cxx @@ -0,0 +1,83 @@ +/* -*- 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 <svx/TextCharacterSpacingPopup.hxx> +#include "TextCharacterSpacingControl.hxx" +#include <vcl/toolbox.hxx> + +using namespace svx; + +TextCharacterSpacingPopup::TextCharacterSpacingPopup(const css::uno::Reference<css::uno::XComponentContext>& rContext) + : PopupWindowController(rContext, nullptr, OUString()) +{ +} + +void TextCharacterSpacingPopup::initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) +{ + PopupWindowController::initialize(rArguments); + + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + } + + ToolBox* pToolBox = nullptr; + sal_uInt16 nId = 0; + if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL) + pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWNONLY | pToolBox->GetItemBits(nId)); +} + +TextCharacterSpacingPopup::~TextCharacterSpacingPopup() +{ +} + +std::unique_ptr<WeldToolbarPopup> TextCharacterSpacingPopup::weldPopupWindow() +{ + return std::make_unique<TextCharacterSpacingControl>(this, m_pToolbar); +} + +VclPtr<vcl::Window> TextCharacterSpacingPopup::createVclPopupWindow( vcl::Window* pParent ) +{ + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<TextCharacterSpacingControl>(this, pParent->GetFrameWeld())); + + mxInterimPopover->Show(); + + return mxInterimPopover; +} + +OUString TextCharacterSpacingPopup::getImplementationName() +{ + return "com.sun.star.comp.svx.CharacterSpacingToolBoxControl"; +} + +css::uno::Sequence<OUString> TextCharacterSpacingPopup::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_svx_CharacterSpacingToolBoxControl_get_implementation( + css::uno::XComponentContext* rContext, + css::uno::Sequence<css::uno::Any> const & ) +{ + return cppu::acquire(new TextCharacterSpacingPopup(rContext)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextPropertyPanel.cxx b/svx/source/sidebar/text/TextPropertyPanel.cxx new file mode 100644 index 000000000..89292ea03 --- /dev/null +++ b/svx/source/sidebar/text/TextPropertyPanel.cxx @@ -0,0 +1,162 @@ +/* -*- 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 "TextPropertyPanel.hxx" + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <comphelper/lok.hxx> +#include <sfx2/lokhelper.hxx> + +using namespace css; + +namespace svx::sidebar { + +VclPtr<vcl::Window> TextPropertyPanel::Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame) +{ + if (pParent == nullptr) + throw lang::IllegalArgumentException("no parent Window given to TextPropertyPanel::Create", nullptr, 0); + if ( ! rxFrame.is()) + throw lang::IllegalArgumentException("no XFrame given to TextPropertyPanel::Create", nullptr, 1); + + return VclPtr<TextPropertyPanel>::Create(pParent, rxFrame); +} + +TextPropertyPanel::TextPropertyPanel ( vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame ) + : PanelLayout(pParent, "SidebarTextPanel", "svx/ui/sidebartextpanel.ui", rxFrame) + , mxFont(m_xBuilder->weld_toolbar("font")) + , mxFontDispatch(new ToolbarUnoDispatcher(*mxFont, *m_xBuilder, rxFrame)) + , mxFontHeight(m_xBuilder->weld_toolbar("fontheight")) + , mxFontHeightDispatch(new ToolbarUnoDispatcher(*mxFontHeight, *m_xBuilder, rxFrame)) + , mxFontEffects(m_xBuilder->weld_toolbar("fonteffects")) + , mxFontEffectsDispatch(new ToolbarUnoDispatcher(*mxFontEffects, *m_xBuilder, rxFrame)) + , mxFontAdjust(m_xBuilder->weld_toolbar("fontadjust")) + , mxFontAdjustDispatch(new ToolbarUnoDispatcher(*mxFontAdjust, *m_xBuilder, rxFrame)) + , mxToolBoxFontColorSw(m_xBuilder->weld_toolbar("colorbar_writer")) + , mxToolBoxFontColorSwDispatch(new ToolbarUnoDispatcher(*mxToolBoxFontColorSw, *m_xBuilder, rxFrame)) + , mxToolBoxFontColor(m_xBuilder->weld_toolbar("colorbar_others")) + , mxToolBoxFontColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxFontColor, *m_xBuilder, rxFrame)) + , mxToolBoxBackgroundColor(m_xBuilder->weld_toolbar("colorbar_background")) + , mxToolBoxBackgroundColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxBackgroundColor, *m_xBuilder, rxFrame)) + , mxResetBar(m_xBuilder->weld_toolbar("resetattr")) + , mxResetBarDispatch(new ToolbarUnoDispatcher(*mxResetBar, *m_xBuilder, rxFrame)) + , mxDefaultBar(m_xBuilder->weld_toolbar("defaultattr")) + , mxDefaultBarDispatch(new ToolbarUnoDispatcher(*mxDefaultBar, *m_xBuilder, rxFrame)) + , mxPositionBar(m_xBuilder->weld_toolbar("position")) + , mxPositionBarDispatch(new ToolbarUnoDispatcher(*mxPositionBar, *m_xBuilder, rxFrame)) + , mxSpacingBar(m_xBuilder->weld_toolbar("spacingbar")) + , mxSpacingBarDispatch(new ToolbarUnoDispatcher(*mxSpacingBar, *m_xBuilder, rxFrame)) +{ + bool isMobilePhone = false; + const SfxViewShell* pViewShell = SfxViewShell::Current(); + if (comphelper::LibreOfficeKit::isActive() && + pViewShell && pViewShell->isLOKMobilePhone()) + isMobilePhone = true; + mxSpacingBar->set_visible(!isMobilePhone); +} + +TextPropertyPanel::~TextPropertyPanel() +{ + disposeOnce(); +} + +void TextPropertyPanel::dispose() +{ + mxResetBarDispatch.reset(); + mxDefaultBarDispatch.reset(); + mxPositionBarDispatch.reset(); + mxSpacingBarDispatch.reset(); + mxToolBoxFontColorSwDispatch.reset(); + mxToolBoxFontColorDispatch.reset(); + mxToolBoxBackgroundColorDispatch.reset(); + mxFontAdjustDispatch.reset(); + mxFontEffectsDispatch.reset(); + mxFontHeightDispatch.reset(); + mxFontDispatch.reset(); + + mxResetBar.reset(); + mxDefaultBar.reset(); + mxPositionBar.reset(); + mxSpacingBar.reset(); + mxToolBoxFontColorSw.reset(); + mxToolBoxFontColor.reset(); + mxToolBoxBackgroundColor.reset(); + mxFontAdjust.reset(); + mxFontEffects.reset(); + mxFontHeight.reset(); + mxFont.reset(); + + PanelLayout::dispose(); +} + +void TextPropertyPanel::HandleContextChange ( + const vcl::EnumContext& rContext) +{ + if (maContext == rContext) + return; + + maContext = rContext; + + bool bWriterText = false; + bool bDrawText = false; + bool bCalcText = false; + + switch (maContext.GetCombinedContext_DI()) + { + case CombinedEnumContext(Application::Calc, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::DrawText): + case CombinedEnumContext(Application::WriterVariants, Context::Annotation): + case CombinedEnumContext(Application::DrawImpress, Context::DrawText): + case CombinedEnumContext(Application::DrawImpress, Context::Text): + case CombinedEnumContext(Application::DrawImpress, Context::Table): + case CombinedEnumContext(Application::DrawImpress, Context::OutlineText): + case CombinedEnumContext(Application::DrawImpress, Context::Draw): + case CombinedEnumContext(Application::DrawImpress, Context::TextObject): + case CombinedEnumContext(Application::DrawImpress, Context::Graphic): + bDrawText = true; + break; + + case CombinedEnumContext(Application::WriterVariants, Context::Text): + case CombinedEnumContext(Application::WriterVariants, Context::Table): + bWriterText = true; + break; + + case CombinedEnumContext(Application::Calc, Context::Text): + case CombinedEnumContext(Application::Calc, Context::Table): + case CombinedEnumContext(Application::Calc, Context::Cell): + case CombinedEnumContext(Application::Calc, Context::EditCell): + case CombinedEnumContext(Application::Calc, Context::Grid): + bCalcText = true; + break; + + default: + break; + } + + mxToolBoxFontColor->set_visible(!bWriterText); + mxToolBoxFontColorSw->set_visible(bWriterText); + mxToolBoxBackgroundColor->set_visible(bDrawText); + mxResetBar->set_visible(bWriterText || bCalcText); + mxDefaultBar->set_visible(bDrawText); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextPropertyPanel.hxx b/svx/source/sidebar/text/TextPropertyPanel.hxx new file mode 100644 index 000000000..437596145 --- /dev/null +++ b/svx/source/sidebar/text/TextPropertyPanel.hxx @@ -0,0 +1,79 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTPROPERTYPANEL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTPROPERTYPANEL_HXX + +#include <sfx2/sidebar/IContextChangeReceiver.hxx> +#include <sfx2/weldutils.hxx> +#include <vcl/EnumContext.hxx> +#include <sfx2/sidebar/PanelLayout.hxx> + +namespace svx::sidebar { + +class TextPropertyPanel + : public PanelLayout, + public ::sfx2::sidebar::IContextChangeReceiver +{ +public: + virtual ~TextPropertyPanel() override; + virtual void dispose() override; + + static VclPtr<vcl::Window> Create ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + + virtual void HandleContextChange ( + const vcl::EnumContext& rContext) override; + + TextPropertyPanel ( + vcl::Window* pParent, + const css::uno::Reference<css::frame::XFrame>& rxFrame); + +private: + std::unique_ptr<weld::Toolbar> mxFont; + std::unique_ptr<ToolbarUnoDispatcher> mxFontDispatch; + std::unique_ptr<weld::Toolbar> mxFontHeight; + std::unique_ptr<ToolbarUnoDispatcher> mxFontHeightDispatch; + std::unique_ptr<weld::Toolbar> mxFontEffects; + std::unique_ptr<ToolbarUnoDispatcher> mxFontEffectsDispatch; + std::unique_ptr<weld::Toolbar> mxFontAdjust; + std::unique_ptr<ToolbarUnoDispatcher> mxFontAdjustDispatch; + std::unique_ptr<weld::Toolbar> mxToolBoxFontColorSw; + std::unique_ptr<ToolbarUnoDispatcher> mxToolBoxFontColorSwDispatch; + std::unique_ptr<weld::Toolbar> mxToolBoxFontColor; + std::unique_ptr<ToolbarUnoDispatcher> mxToolBoxFontColorDispatch; + std::unique_ptr<weld::Toolbar> mxToolBoxBackgroundColor; + std::unique_ptr<ToolbarUnoDispatcher> mxToolBoxBackgroundColorDispatch; + std::unique_ptr<weld::Toolbar> mxResetBar; + std::unique_ptr<ToolbarUnoDispatcher> mxResetBarDispatch; + std::unique_ptr<weld::Toolbar> mxDefaultBar; + std::unique_ptr<ToolbarUnoDispatcher> mxDefaultBarDispatch; + std::unique_ptr<weld::Toolbar> mxPositionBar; + std::unique_ptr<ToolbarUnoDispatcher> mxPositionBarDispatch; + std::unique_ptr<weld::Toolbar> mxSpacingBar; + std::unique_ptr<ToolbarUnoDispatcher> mxSpacingBarDispatch; + + vcl::EnumContext maContext; +}; + +} // end of namespace svx::sidebar + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextUnderlineControl.cxx b/svx/source/sidebar/text/TextUnderlineControl.cxx new file mode 100644 index 000000000..1ae19e653 --- /dev/null +++ b/svx/source/sidebar/text/TextUnderlineControl.cxx @@ -0,0 +1,137 @@ +/* -*- 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 "TextUnderlineControl.hxx" +#include <svx/svxids.hrc> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewfrm.hxx> +#include <svx/TextUnderlinePopup.hxx> +#include <editeng/editids.hrc> +#include <editeng/udlnitem.hxx> +#include <helpids.h> + +namespace svx { + +TextUnderlineControl::TextUnderlineControl(TextUnderlinePopup* pControl, weld::Widget* pParent) + : WeldToolbarPopup(pControl->getFrameInterface(), pParent, "svx/ui/textunderlinecontrol.ui", "TextUnderlineControl") + , mxNone(m_xBuilder->weld_button("none")) + , mxSingle(m_xBuilder->weld_button("single")) + , mxDouble(m_xBuilder->weld_button("double")) + , mxBold(m_xBuilder->weld_button("bold")) + , mxDot(m_xBuilder->weld_button("dot")) + , mxDotBold(m_xBuilder->weld_button("dotbold")) + , mxDash(m_xBuilder->weld_button("dash")) + , mxDashLong(m_xBuilder->weld_button("dashlong")) + , mxDashDot(m_xBuilder->weld_button("dashdot")) + , mxDashDotDot(m_xBuilder->weld_button("dashdotdot")) + , mxWave(m_xBuilder->weld_button("wave")) + , mxMoreOptions(m_xBuilder->weld_button("moreoptions")) + , mxControl(pControl) +{ + mxMoreOptions->set_help_id(HID_UNDERLINE_BTN); + + Link<weld::Button&,void> aLink = LINK(this, TextUnderlineControl, PBClickHdl); + mxNone->connect_clicked(aLink); + mxSingle->connect_clicked(aLink); + mxDouble->connect_clicked(aLink); + mxBold->connect_clicked(aLink); + mxDot->connect_clicked(aLink); + mxDotBold->connect_clicked(aLink); + mxDash->connect_clicked(aLink); + mxDashLong->connect_clicked(aLink); + mxDashDot->connect_clicked(aLink); + mxDashDotDot->connect_clicked(aLink); + mxWave->connect_clicked(aLink); + mxMoreOptions->connect_clicked(aLink); +} + +void TextUnderlineControl::GrabFocus() +{ + mxNone->grab_focus(); +} + +TextUnderlineControl::~TextUnderlineControl() +{ +} + +FontLineStyle TextUnderlineControl::getLineStyle(const weld::Button& rButton) +{ + if (&rButton == mxSingle.get()) + return LINESTYLE_SINGLE; + else if (&rButton == mxDouble.get()) + return LINESTYLE_DOUBLE; + else if (&rButton == mxBold.get()) + return LINESTYLE_BOLD; + else if (&rButton == mxDot.get()) + return LINESTYLE_DOTTED; + else if (&rButton == mxDotBold.get()) + return LINESTYLE_BOLDDOTTED; + else if (&rButton == mxDash.get()) + return LINESTYLE_DASH; + else if (&rButton == mxDashLong.get()) + return LINESTYLE_LONGDASH; + else if (&rButton == mxDashDot.get()) + return LINESTYLE_DASHDOT; + else if (&rButton == mxDashDotDot.get()) + return LINESTYLE_DASHDOTDOT; + else if (&rButton == mxWave.get()) + return LINESTYLE_WAVE; + + return LINESTYLE_NONE; +} + +namespace { + +Color GetUnderlineColor() +{ + const SfxPoolItem* pItem; + SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_CHAR_UNDERLINE, pItem); + + const SvxUnderlineItem* pUnderlineItem = static_cast<const SvxUnderlineItem*>(pItem); + + if(pUnderlineItem) + return pUnderlineItem->GetColor(); + + return COL_AUTO; +} + +} + +IMPL_LINK(TextUnderlineControl, PBClickHdl, weld::Button&, rButton, void) +{ + if (&rButton == mxMoreOptions.get()) + { + SfxDispatcher* pDisp = SfxViewFrame::Current()->GetBindings().GetDispatcher(); + pDisp->Execute(SID_CHAR_DLG_EFFECT, SfxCallMode::ASYNCHRON); + } + else + { + const FontLineStyle eUnderline = getLineStyle(rButton); + + SvxUnderlineItem aLineItem(eUnderline, SID_ATTR_CHAR_UNDERLINE); + aLineItem.SetColor(GetUnderlineColor()); + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->ExecuteList(SID_ATTR_CHAR_UNDERLINE, + SfxCallMode::RECORD, { &aLineItem }); + } + mxControl->EndPopupMode(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextUnderlineControl.hxx b/svx/source/sidebar/text/TextUnderlineControl.hxx new file mode 100644 index 000000000..631b5c874 --- /dev/null +++ b/svx/source/sidebar/text/TextUnderlineControl.hxx @@ -0,0 +1,60 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTUNDERLINECONTROL_HXX +#define INCLUDED_SVX_SOURCE_SIDEBAR_TEXT_TEXTUNDERLINECONTROL_HXX + +#include <svtools/toolbarmenu.hxx> + +namespace svx +{ +class TextUnderlinePopup; + +class TextUnderlineControl final : public WeldToolbarPopup +{ +public: + explicit TextUnderlineControl(TextUnderlinePopup* pControl, weld::Widget* pParent); + virtual void GrabFocus() override; + virtual ~TextUnderlineControl() override; + +private: + std::unique_ptr<weld::Button> mxNone; + std::unique_ptr<weld::Button> mxSingle; + std::unique_ptr<weld::Button> mxDouble; + std::unique_ptr<weld::Button> mxBold; + std::unique_ptr<weld::Button> mxDot; + std::unique_ptr<weld::Button> mxDotBold; + std::unique_ptr<weld::Button> mxDash; + std::unique_ptr<weld::Button> mxDashLong; + std::unique_ptr<weld::Button> mxDashDot; + std::unique_ptr<weld::Button> mxDashDotDot; + std::unique_ptr<weld::Button> mxWave; + std::unique_ptr<weld::Button> mxMoreOptions; + + rtl::Reference<TextUnderlinePopup> mxControl; + + FontLineStyle getLineStyle(const weld::Button& rButton); + + DECL_LINK(PBClickHdl, weld::Button&, void); +}; +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/text/TextUnderlinePopup.cxx b/svx/source/sidebar/text/TextUnderlinePopup.cxx new file mode 100644 index 000000000..1da5bfe7f --- /dev/null +++ b/svx/source/sidebar/text/TextUnderlinePopup.cxx @@ -0,0 +1,83 @@ +/* -*- 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 <svx/TextUnderlinePopup.hxx> +#include "TextUnderlineControl.hxx" +#include <vcl/toolbox.hxx> + +using namespace svx; + +TextUnderlinePopup::TextUnderlinePopup(const css::uno::Reference<css::uno::XComponentContext>& rContext) + : PopupWindowController(rContext, nullptr, OUString()) +{ +} + +TextUnderlinePopup::~TextUnderlinePopup() +{ +} + +void TextUnderlinePopup::initialize( const css::uno::Sequence< css::uno::Any >& rArguments ) +{ + PopupWindowController::initialize(rArguments); + + if (m_pToolbar) + { + mxPopoverContainer.reset(new ToolbarPopupContainer(m_pToolbar)); + m_pToolbar->set_item_popover(m_aCommandURL.toUtf8(), mxPopoverContainer->getTopLevel()); + } + + ToolBox* pToolBox = nullptr; + sal_uInt16 nId = 0; + if (getToolboxId(nId, &pToolBox) && pToolBox->GetItemCommand(nId) == m_aCommandURL) + pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | pToolBox->GetItemBits(nId)); +} + +std::unique_ptr<WeldToolbarPopup> TextUnderlinePopup::weldPopupWindow() +{ + return std::make_unique<TextUnderlineControl>(this, m_pToolbar); +} + +VclPtr<vcl::Window> TextUnderlinePopup::createVclPopupWindow( vcl::Window* pParent ) +{ + mxInterimPopover = VclPtr<InterimToolbarPopup>::Create(getFrameInterface(), pParent, + std::make_unique<TextUnderlineControl>(this, pParent->GetFrameWeld())); + + mxInterimPopover->Show(); + + return mxInterimPopover; +} + +OUString TextUnderlinePopup::getImplementationName() +{ + return "com.sun.star.comp.svx.UnderlineToolBoxControl"; +} + +css::uno::Sequence<OUString> TextUnderlinePopup::getSupportedServiceNames() +{ + return { "com.sun.star.frame.ToolbarController" }; +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_svx_UnderlineToolBoxControl_get_implementation( + css::uno::XComponentContext* rContext, + css::uno::Sequence<css::uno::Any> const & ) +{ + return cppu::acquire(new TextUnderlinePopup(rContext)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/sidebar/tools/ValueSetWithTextControl.cxx b/svx/source/sidebar/tools/ValueSetWithTextControl.cxx new file mode 100644 index 000000000..962102ac5 --- /dev/null +++ b/svx/source/sidebar/tools/ValueSetWithTextControl.cxx @@ -0,0 +1,121 @@ +/* -*- 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 <svx/sidebar/ValueSetWithTextControl.hxx> +#include <sfx2/sidebar/Theme.hxx> + +#include <i18nlangtag/mslangid.hxx> +#include <svtools/valueset.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + +namespace svx::sidebar { + +ValueSetWithTextControl::ValueSetWithTextControl() + : ValueSet(nullptr) +{ +} + +void ValueSetWithTextControl::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + ValueSet::SetDrawingArea(pDrawingArea); + + Size aSize(250, 300); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + SetOutputSizePixel(aSize); + + SetColCount(); +} + +void ValueSetWithTextControl::AddItem( + const OUString& rItemText, + const OUString& rItemText2 ) +{ + ValueSetWithTextItem aItem; + aItem.maItemText = rItemText; + aItem.maItemText2 = rItemText2; + + maItems.push_back( aItem ); + + InsertItem( maItems.size() ); + SetItemText( maItems.size(), rItemText ); +} + +void ValueSetWithTextControl::UserDraw( const UserDrawEvent& rUDEvt ) +{ + const tools::Rectangle aRect = rUDEvt.GetRect(); + vcl::RenderContext* pDev = rUDEvt.GetRenderContext(); + pDev->Push(); + const sal_uInt16 nItemId = rUDEvt.GetItemId(); + + const long nRectHeight = aRect.GetHeight(); + + vcl::Font aFont(OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getSystemLanguage(), GetDefaultFontFlags::OnlyOne)); + { + Size aSize = aFont.GetFontSize(); + aSize.setHeight( (nRectHeight*4)/9 ); + aFont.SetFontSize( aSize ); + } + + { + //draw background + if ( GetSelectedItemId() == nItemId ) + { + tools::Rectangle aBackRect = aRect; + aBackRect.AdjustTop(3 ); + aBackRect.AdjustBottom( -2 ); + pDev->SetFillColor( sfx2::sidebar::Theme::GetColor( sfx2::sidebar::Theme::Color_Highlight ) ); + pDev->DrawRect(aBackRect); + } + else + { + pDev->SetFillColor( COL_TRANSPARENT ); + pDev->DrawRect(aRect); + } + + if ( GetSelectedItemId() == nItemId ) + { + aFont.SetColor( sfx2::sidebar::Theme::GetColor( sfx2::sidebar::Theme::Color_HighlightText ) ); + } + else + { + aFont.SetColor( Application::GetSettings().GetStyleSettings().GetFieldTextColor() ); + } + + tools::Rectangle aStrRect = aRect; + aStrRect.AdjustTop(nRectHeight/4 ); + aStrRect.AdjustBottom( -(nRectHeight/4) ); + + const long nRectWidth = aRect.GetWidth(); + aStrRect.AdjustLeft(8 ); + aStrRect.AdjustRight( -((nRectWidth*2)/3) ); + pDev->SetFont(aFont); + pDev->DrawText(aStrRect, maItems[nItemId-1].maItemText, DrawTextFlags::EndEllipsis); + aStrRect.AdjustLeft(nRectWidth/3 ); + aStrRect.AdjustRight((nRectWidth*2)/3 ); + pDev->DrawText(aStrRect, maItems[nItemId-1].maItemText2, DrawTextFlags::EndEllipsis); + } + + Invalidate( aRect ); + pDev->Pop(); +} + +} // end of namespace svx::sidebar + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |