Files
odfstudio/sfx2/source/view/classificationcontroller.cxx
T
Michael Weghorn f26084217a weld: Move weld::Button to own header/Rename weld.hxx
In the past, weld.hxx used to contain the class
definitions for weld::Widget and all subclasses.

By now, weld::Widget and almost all subclasses have
been moved to separate headers, to make it easier
to keep the overview and to avoid having to
recompile ~all UI code when one class changes.

By now, only weld::Button is left in weld.hxx.
Rename the header to Button.hxx.
Drop weld.hxx includes and instead add Button.hxx
includes (or weld::Button forward declarations) where
weld::Button is used.
(Don't simply replace all weld.hxx includes with
Button.hxx ones, since many of them were for the
use of other widgets that have since been moved
to their own headers.)

Add further includes where needed now that the
(direct or transitive) includes of weld.hxx were removed.

Change-Id: I8ea6201446a418d5e38b46337059dcd517ee29d7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205937
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
2026-06-05 07:58:07 +02:00

372 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <cppuhelper/implbase.hxx>
#include <svtools/toolboxcontroller.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <sfx2/classificationhelper.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/strings.hrc>
#include <sfx2/sfxresid.hxx>
#include <tools/mapunit.hxx>
#include <vcl/event.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/svapp.hxx>
#include <vcl/vclptr.hxx>
#include <vcl/weld/Builder.hxx>
#include <vcl/weld/ComboBox.hxx>
#include <vcl/weld/Container.hxx>
#include <vcl/weld/Label.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/unique_unlock.hxx>
#include <comphelper/dispatchcommand.hxx>
#include <comphelper/configurationlistener.hxx>
using namespace com::sun::star;
namespace sfx2
{
namespace {
class ClassificationCategoriesController;
}
using ClassificationPropertyListenerBase = comphelper::ConfigurationListenerProperty<OUString>;
namespace {
/// Listens to configuration changes, so no restart is needed after setting the classification path.
class ClassificationPropertyListener : public ClassificationPropertyListenerBase
{
ClassificationCategoriesController& m_rController;
public:
ClassificationPropertyListener(const rtl::Reference<comphelper::ConfigurationListener>& xListener, ClassificationCategoriesController& rController);
void setProperty(const uno::Any& rProperty) override;
};
}
using ClassificationCategoriesControllerBase = cppu::ImplInheritanceHelper<svt::ToolboxController, lang::XServiceInfo>;
namespace {
class ClassificationControl;
/// Controller for .uno:ClassificationApply.
class ClassificationCategoriesController : public ClassificationCategoriesControllerBase
{
VclPtr<ClassificationControl> m_pClassification;
rtl::Reference<comphelper::ConfigurationListener> m_xListener;
ClassificationPropertyListener m_aPropertyListener;
DECL_LINK(SelectHdl, weld::ComboBox&, void);
public:
explicit ClassificationCategoriesController(const uno::Reference<uno::XComponentContext>& rContext);
// XServiceInfo
OUString SAL_CALL getImplementationName() override;
sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
// WeakComponentImplHelperBase
using ClassificationCategoriesControllerBase::disposing;
void disposing(std::unique_lock<std::mutex>& rGuard) override;
// XToolbarController
uno::Reference<awt::XWindow> SAL_CALL createItemWindow(const uno::Reference<awt::XWindow>& rParent) override;
// XStatusListener
void SAL_CALL statusChanged(const frame::FeatureStateEvent& rEvent) override;
void removeEntries();
};
/// Classification control is the parent of all widgets that belongs to ClassificationCategoriesController.
class SAL_WARN_UNUSED ClassificationControl final : public InterimItemWindow
{
std::unique_ptr<weld::Label> m_xLabel;
std::unique_ptr<weld::ComboBox> m_xCategory;
DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
void SetOptimalSize();
void DataChanged(const DataChangedEvent& rEvent) override;
public:
explicit ClassificationControl(vcl::Window* pParent);
~ClassificationControl() override;
void dispose() override;
weld::ComboBox& getCategory()
{
return *m_xCategory;
}
void set_sensitive(bool bSensitive)
{
Enable(bSensitive);
m_xContainer->set_sensitive(bSensitive);
}
static sfx::ClassificationCreationOrigin getExistingClassificationOrigin();
void toggleInteractivityOnOrigin();
void setCategoryStateFromPolicy(const SfxClassificationHelper & rHelper);
};
OUString const & getCategoryType()
{
return SfxClassificationHelper::policyTypeToString(SfxClassificationHelper::getPolicyType());
}
} // end anonymous namespace
ClassificationPropertyListener::ClassificationPropertyListener(const rtl::Reference<comphelper::ConfigurationListener>& xListener, ClassificationCategoriesController& rController)
: ClassificationPropertyListenerBase(xListener, u"WritePath"_ustr)
, m_rController(rController)
{
}
void ClassificationPropertyListener::setProperty(const uno::Any& /*rProperty*/)
{
// So that its gets re-filled with entries from the new policy.
m_rController.removeEntries();
}
ClassificationCategoriesController::ClassificationCategoriesController(const uno::Reference<uno::XComponentContext>& rContext)
: ClassificationCategoriesControllerBase(rContext, uno::Reference<frame::XFrame>(), u".uno:ClassificationApply"_ustr)
, m_pClassification(nullptr)
, m_xListener(new comphelper::ConfigurationListener(u"/org.openoffice.Office.Paths/Paths/Classification"_ustr))
, m_aPropertyListener(m_xListener, *this)
{
}
OUString ClassificationCategoriesController::getImplementationName()
{
return u"com.sun.star.comp.sfx2.ClassificationCategoriesController"_ustr;
}
sal_Bool ClassificationCategoriesController::supportsService(const OUString& rServiceName)
{
return cppu::supportsService(this, rServiceName);
}
uno::Sequence<OUString> ClassificationCategoriesController::getSupportedServiceNames()
{
return { u"com.sun.star.frame.ToolbarController"_ustr };
}
void ClassificationCategoriesController::disposing(std::unique_lock<std::mutex>& rGuard)
{
svt::ToolboxController::disposing(rGuard);
comphelper::unique_unlock aUnlock(rGuard);
SolarMutexGuard aSolarMutexGuard;
m_pClassification.disposeAndClear();
m_aPropertyListener.dispose();
m_xListener->dispose();
}
uno::Reference<awt::XWindow> ClassificationCategoriesController::createItemWindow(const uno::Reference<awt::XWindow>& rParent)
{
VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
auto pToolbar = dynamic_cast<ToolBox*>(pParent.get());
if (pToolbar)
{
m_pClassification = VclPtr<ClassificationControl>::Create(pToolbar);
m_pClassification->getCategory().connect_changed(LINK(this, ClassificationCategoriesController, SelectHdl));
m_pClassification->Show();
}
return VCLUnoHelper::GetInterface(m_pClassification);
}
IMPL_LINK(ClassificationCategoriesController, SelectHdl, weld::ComboBox&, rCategory, void)
{
m_pClassification->toggleInteractivityOnOrigin();
if (ClassificationControl::getExistingClassificationOrigin() == sfx::ClassificationCreationOrigin::MANUAL)
{
SfxObjectShell* pObjectShell = SfxObjectShell::Current();
if (!pObjectShell)
return;
SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
m_pClassification->setCategoryStateFromPolicy(aHelper);
}
else
{
OUString aEntry = rCategory.get_active_text();
const OUString& aType = getCategoryType();
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
{"Name", uno::Any(aEntry)},
{"Type", uno::Any(aType)},
}));
comphelper::dispatchCommand(u".uno:ClassificationApply"_ustr, aPropertyValues);
}
}
void ClassificationCategoriesController::statusChanged(const frame::FeatureStateEvent& /*rEvent*/)
{
if (!m_pClassification)
return;
SfxObjectShell* pObjectShell = SfxObjectShell::Current();
if (!pObjectShell)
return;
SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
//toggle if the pop-up is enabled/disabled
m_pClassification->toggleInteractivityOnOrigin();
// check if classification was set via the advanced dialog
if (ClassificationControl::getExistingClassificationOrigin() != sfx::ClassificationCreationOrigin::MANUAL)
{
weld::ComboBox& rCategories = m_pClassification->getCategory();
if (rCategories.get_count() == 0)
{
std::vector<OUString> aNames = aHelper.GetBACNames();
for (const OUString& rName : aNames)
rCategories.append_text(rName);
}
}
// Restore state based on the doc. model.
m_pClassification->setCategoryStateFromPolicy(aHelper);
}
void ClassificationCategoriesController::removeEntries()
{
m_pClassification->getCategory().clear();
}
ClassificationControl::ClassificationControl(vcl::Window* pParent)
: InterimItemWindow(pParent, u"sfx/ui/classificationbox.ui"_ustr, u"ClassificationBox"_ustr)
, m_xLabel(m_xBuilder->weld_label(u"label"_ustr))
, m_xCategory(m_xBuilder->weld_combo_box(u"combobox"_ustr))
{
InitControlBase(m_xCategory.get());
m_xCategory->connect_key_press(LINK(this, ClassificationControl, KeyInputHdl));
// WB_NOLABEL means here that the control won't be replaced with a label
// when it wouldn't fit the available space.
SetStyle(GetStyle() | WB_DIALOGCONTROL | WB_NOLABEL);
OUString aText;
switch (SfxClassificationHelper::getPolicyType())
{
case SfxClassificationPolicyType::IntellectualProperty:
aText = SfxResId(STR_CLASSIFIED_INTELLECTUAL_PROPERTY);
break;
case SfxClassificationPolicyType::NationalSecurity:
aText = SfxResId(STR_CLASSIFIED_NATIONAL_SECURITY);
break;
case SfxClassificationPolicyType::ExportControl:
aText = SfxResId(STR_CLASSIFIED_EXPORT_CONTROL);
break;
}
m_xLabel->set_label(aText);
// Same as SvxColorDockingWindow.
const Size aLogicalAttrSize(150, 0);
Size aSize(LogicToPixel(aLogicalAttrSize, MapMode(MapUnit::MapAppFont)));
m_xCategory->set_size_request(aSize.Width() - m_xLabel->get_preferred_size().Width(), -1);
SetOptimalSize();
}
IMPL_LINK(ClassificationControl, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
return ChildKeyInput(rKEvt);
}
ClassificationControl::~ClassificationControl()
{
disposeOnce();
}
void ClassificationControl::dispose()
{
m_xLabel.reset();
m_xCategory.reset();
InterimItemWindow::dispose();
}
void ClassificationControl::SetOptimalSize()
{
SetSizePixel(get_preferred_size());
}
void ClassificationControl::DataChanged(const DataChangedEvent& rEvent)
{
if ((rEvent.GetType() == DataChangedEventType::SETTINGS) && (rEvent.GetFlags() & AllSettingsFlags::STYLE))
SetOptimalSize();
toggleInteractivityOnOrigin();
InterimItemWindow::DataChanged(rEvent);
}
sfx::ClassificationCreationOrigin ClassificationControl::getExistingClassificationOrigin()
{
SfxObjectShell* pObjectShell = SfxObjectShell::Current();
if (!pObjectShell)
return sfx::ClassificationCreationOrigin::NONE;
uno::Reference<document::XDocumentProperties> xDocumentProperties = pObjectShell->getDocProperties();
uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
sfx::ClassificationKeyCreator aKeyCreator(SfxClassificationHelper::getPolicyType());
return sfx::getCreationOriginProperty(xPropertyContainer, aKeyCreator);
}
void ClassificationControl::toggleInteractivityOnOrigin()
{
if (getExistingClassificationOrigin() == sfx::ClassificationCreationOrigin::MANUAL)
{
set_sensitive(false);
}
else
{
set_sensitive(true);
}
}
void ClassificationControl::setCategoryStateFromPolicy(const SfxClassificationHelper & rHelper)
{
const OUString& rCategoryName = rHelper.GetBACName(SfxClassificationHelper::getPolicyType());
if (!rCategoryName.isEmpty())
{
getCategory().set_active_text(rCategoryName);
}
}
} // namespace sfx2
extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* com_sun_star_sfx2_ClassificationCategoriesController_get_implementation(uno::XComponentContext* pContext, const uno::Sequence<uno::Any>&)
{
return cppu::acquire(new sfx2::ClassificationCategoriesController(pContext));
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */