Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / sfx2 / source / view / classificationcontroller.cxx
blob56e404560f484648cc8b4105f9497f200781eb2a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <cppuhelper/implbase.hxx>
11 #include <svtools/toolboxcontroller.hxx>
12 #include <com/sun/star/lang/XServiceInfo.hpp>
14 #include <com/sun/star/uno/XComponentContext.hpp>
15 #include <com/sun/star/frame/XFrame.hpp>
17 #include <vcl/vclptr.hxx>
18 #include <vcl/lstbox.hxx>
19 #include <vcl/svapp.hxx>
20 #include <toolkit/helper/vclunohelper.hxx>
21 #include <vcl/toolbox.hxx>
22 #include <vcl/fixed.hxx>
23 #include <sfx2/viewfrm.hxx>
24 #include <sfx2/classificationhelper.hxx>
25 #include <sfx2/strings.hrc>
26 #include <sfx2/sfxresid.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <comphelper/propertysequence.hxx>
29 #include <comphelper/dispatchcommand.hxx>
30 #include <comphelper/configurationlistener.hxx>
32 using namespace com::sun::star;
34 namespace sfx2
37 class ClassificationCategoriesController;
38 using ClassificationPropertyListenerBase = comphelper::ConfigurationListenerProperty<OUString>;
40 /// Listens to configuration changes, so no restart is needed after setting the classification path.
41 class ClassificationPropertyListener : public ClassificationPropertyListenerBase
43 ClassificationCategoriesController& m_rController;
45 public:
46 ClassificationPropertyListener(const rtl::Reference<comphelper::ConfigurationListener>& xListener, ClassificationCategoriesController& rController);
47 void setProperty(const uno::Any& rProperty) override;
50 using ClassificationCategoriesControllerBase = cppu::ImplInheritanceHelper<svt::ToolboxController, lang::XServiceInfo>;
52 class ClassificationControl;
54 /// Controller for .uno:ClassificationApply.
55 class ClassificationCategoriesController : public ClassificationCategoriesControllerBase
57 VclPtr<ClassificationControl> m_pClassification;
58 rtl::Reference<comphelper::ConfigurationListener> m_xListener;
59 ClassificationPropertyListener m_aPropertyListener;
61 DECL_LINK(SelectHdl, ListBox&, void);
63 public:
64 explicit ClassificationCategoriesController(const uno::Reference<uno::XComponentContext>& rContext);
66 // XServiceInfo
67 OUString SAL_CALL getImplementationName() override;
68 sal_Bool SAL_CALL supportsService(const OUString& rServiceName) override;
69 uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
71 // XComponent
72 void SAL_CALL dispose() override;
74 // XToolbarController
75 uno::Reference<awt::XWindow> SAL_CALL createItemWindow(const uno::Reference<awt::XWindow>& rParent) override;
77 // XStatusListener
78 void SAL_CALL statusChanged(const frame::FeatureStateEvent& rEvent) override;
80 void removeEntries();
83 /// Classification control is the parent of all widgets that belongs to ClassificationCategoriesController.
84 class SAL_WARN_UNUSED ClassificationControl : public vcl::Window
86 VclPtr<FixedText> m_pLabel;
87 VclPtr<ListBox> m_pCategory;
88 void SetOptimalSize();
89 void DataChanged(const DataChangedEvent& rEvent) override;
91 public:
92 explicit ClassificationControl(vcl::Window* pParent);
93 ~ClassificationControl() override;
94 void dispose() override;
95 void Resize() override;
96 const VclPtr<ListBox>& getCategory()
98 return m_pCategory;
100 sfx::ClassificationCreationOrigin getExistingClassificationOrigin();
101 void toggleInteractivityOnOrigin();
102 void setCategoryStateFromPolicy(SfxClassificationHelper & rHelper);
105 namespace
108 OUString const & getCategoryType()
110 return SfxClassificationHelper::policyTypeToString(SfxClassificationHelper::getPolicyType());
113 } // end anonymous namespace
115 ClassificationPropertyListener::ClassificationPropertyListener(const rtl::Reference<comphelper::ConfigurationListener>& xListener, ClassificationCategoriesController& rController)
116 : ClassificationPropertyListenerBase(xListener, "WritePath")
117 , m_rController(rController)
121 void ClassificationPropertyListener::setProperty(const uno::Any& /*rProperty*/)
123 // So that its gets re-filled with entries from the new policy.
124 m_rController.removeEntries();
127 ClassificationCategoriesController::ClassificationCategoriesController(const uno::Reference<uno::XComponentContext>& rContext)
128 : ClassificationCategoriesControllerBase(rContext, uno::Reference<frame::XFrame>(), OUString(".uno:ClassificationApply"))
129 , m_pClassification(nullptr)
130 , m_xListener(new comphelper::ConfigurationListener("/org.openoffice.Office.Paths/Paths/Classification"))
131 , m_aPropertyListener(m_xListener, *this)
136 OUString ClassificationCategoriesController::getImplementationName()
138 return OUString("com.sun.star.comp.sfx2.ClassificationCategoriesController");
141 sal_Bool ClassificationCategoriesController::supportsService(const OUString& rServiceName)
143 return cppu::supportsService(this, rServiceName);
146 uno::Sequence<OUString> ClassificationCategoriesController::getSupportedServiceNames()
148 return { "com.sun.star.frame.ToolbarController" };
151 void ClassificationCategoriesController::dispose()
153 SolarMutexGuard aSolarMutexGuard;
155 svt::ToolboxController::dispose();
156 m_pClassification.disposeAndClear();
157 m_aPropertyListener.dispose();
158 m_xListener->dispose();
161 uno::Reference<awt::XWindow> ClassificationCategoriesController::createItemWindow(const uno::Reference<awt::XWindow>& rParent)
163 VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
164 auto pToolbar = dynamic_cast<ToolBox*>(pParent.get());
165 if (pToolbar)
167 m_pClassification = VclPtr<ClassificationControl>::Create(pToolbar);
168 m_pClassification->getCategory()->SetSelectHdl(LINK(this, ClassificationCategoriesController, SelectHdl));
171 return VCLUnoHelper::GetInterface(m_pClassification);
174 IMPL_LINK(ClassificationCategoriesController, SelectHdl, ListBox&, rCategory, void)
176 m_pClassification->toggleInteractivityOnOrigin();
178 if (m_pClassification->getExistingClassificationOrigin() == sfx::ClassificationCreationOrigin::MANUAL)
180 SfxObjectShell* pObjectShell = SfxObjectShell::Current();
181 if (!pObjectShell)
182 return;
183 SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
184 m_pClassification->setCategoryStateFromPolicy(aHelper);
186 else
188 OUString aEntry = rCategory.GetSelectedEntry();
190 OUString aType = getCategoryType();
191 uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence({
192 {"Name", uno::makeAny(aEntry)},
193 {"Type", uno::makeAny(aType)},
194 }));
195 comphelper::dispatchCommand(".uno:ClassificationApply", aPropertyValues);
199 void ClassificationCategoriesController::statusChanged(const frame::FeatureStateEvent& /*rEvent*/)
201 if (!m_pClassification)
202 return;
204 SfxObjectShell* pObjectShell = SfxObjectShell::Current();
205 if (!pObjectShell)
206 return;
208 SfxClassificationHelper aHelper(pObjectShell->getDocProperties());
210 //toggle if the pop-up is enabled/disabled
211 m_pClassification->toggleInteractivityOnOrigin();
213 // check if classification was set via the advanced dialog
214 if (m_pClassification->getExistingClassificationOrigin() != sfx::ClassificationCreationOrigin::MANUAL)
216 VclPtr<ListBox> pCategories = m_pClassification->getCategory();
217 if (pCategories->GetEntryCount() == 0)
219 std::vector<OUString> aNames = aHelper.GetBACNames();
220 for (const OUString& rName : aNames)
221 pCategories->InsertEntry(rName);
222 // Normally VclBuilder::makeObject() does this.
223 pCategories->EnableAutoSize(true);
227 // Restore state based on the doc. model.
228 m_pClassification->setCategoryStateFromPolicy(aHelper);
232 void ClassificationCategoriesController::removeEntries()
234 m_pClassification->getCategory()->Clear();
237 // WB_NOLABEL means here that the control won't be replaced with a label
238 // when it wouldn't fit the available space.
239 ClassificationControl::ClassificationControl(vcl::Window* pParent)
240 : Window(pParent, WB_DIALOGCONTROL | WB_NOLABEL)
242 m_pLabel = VclPtr<FixedText>::Create(this, WB_CENTER);
243 m_pCategory = VclPtr<ListBox>::Create(this, WB_CLIPCHILDREN|WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_DROPDOWN|WB_SIMPLEMODE);
245 OUString aText;
246 switch (SfxClassificationHelper::getPolicyType())
248 case SfxClassificationPolicyType::IntellectualProperty:
249 aText = SfxResId(STR_CLASSIFIED_INTELLECTUAL_PROPERTY);
250 break;
251 case SfxClassificationPolicyType::NationalSecurity:
252 aText = SfxResId(STR_CLASSIFIED_NATIONAL_SECURITY);
253 break;
254 case SfxClassificationPolicyType::ExportControl:
255 aText = SfxResId(STR_CLASSIFIED_EXPORT_CONTROL);
256 break;
258 Size aTextSize(m_pLabel->GetTextWidth(aText), m_pLabel->GetTextHeight());
260 // Padding.
261 aTextSize.AdjustWidth(12 );
262 m_pLabel->SetText(aText);
263 m_pLabel->SetSizePixel(aTextSize);
264 m_pLabel->Show();
266 m_pCategory->Show();
268 SetOptimalSize();
271 ClassificationControl::~ClassificationControl()
273 disposeOnce();
276 void ClassificationControl::dispose()
278 m_pLabel.disposeAndClear();
279 m_pCategory.disposeAndClear();
280 vcl::Window::dispose();
283 void ClassificationControl::Resize()
285 // Give the label what it wants, and the remaining size to the listbox.
286 Size aSize(GetOutputSizePixel());
288 long nWLabel = m_pLabel->GetOutputSizePixel().Width();
289 long nW = aSize.Width();
290 long nH = aSize.Height();
292 long nPrefHeight = m_pLabel->get_preferred_size().Height();
293 long nOffset = (nH - nPrefHeight) / 2;
294 m_pLabel->SetPosSizePixel(Point(0, nOffset), Size(nWLabel, nPrefHeight));
296 nPrefHeight = m_pCategory->get_preferred_size().Height();
297 nOffset = (nH - nPrefHeight) / 2;
298 m_pCategory->SetPosSizePixel(Point(0 + nWLabel, nOffset), Size(nW - nWLabel, nPrefHeight));
301 void ClassificationControl::SetOptimalSize()
303 // Same as SvxColorDockingWindow.
304 const Size aLogicalAttrSize(150, 0);
305 Size aSize(LogicToPixel(aLogicalAttrSize, MapMode(MapUnit::MapAppFont)));
307 Point aPosition = m_pCategory->GetPosPixel();
309 aSize.setHeight( std::max(aSize.Height(), m_pLabel->get_preferred_size().Height()) );
310 aSize.setHeight( std::max(aSize.Height(), m_pCategory->get_preferred_size().Height()) );
312 aSize.setWidth( aPosition.X() + aSize.Width() );
314 SetSizePixel(aSize);
317 void ClassificationControl::DataChanged(const DataChangedEvent& rEvent)
319 if ((rEvent.GetType() == DataChangedEventType::SETTINGS) && (rEvent.GetFlags() & AllSettingsFlags::STYLE))
320 SetOptimalSize();
322 toggleInteractivityOnOrigin();
324 Window::DataChanged(rEvent);
327 sfx::ClassificationCreationOrigin ClassificationControl::getExistingClassificationOrigin()
329 SfxObjectShell* pObjectShell = SfxObjectShell::Current();
330 if (!pObjectShell)
331 return sfx::ClassificationCreationOrigin::NONE;
333 uno::Reference<document::XDocumentProperties> xDocumentProperties = pObjectShell->getDocProperties();
334 uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties();
336 sfx::ClassificationKeyCreator aKeyCreator(SfxClassificationHelper::getPolicyType());
337 return sfx::getCreationOriginProperty(xPropertyContainer, aKeyCreator);
340 void ClassificationControl::toggleInteractivityOnOrigin()
342 if (getExistingClassificationOrigin() == sfx::ClassificationCreationOrigin::MANUAL)
344 Disable();
346 else
348 Enable();
352 void ClassificationControl::setCategoryStateFromPolicy(SfxClassificationHelper & rHelper)
354 const OUString& rCategoryName = rHelper.GetBACName(SfxClassificationHelper::getPolicyType());
355 if (!rCategoryName.isEmpty())
357 getCategory()->SelectEntry(rCategoryName);
361 } // namespace sfx2
363 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* com_sun_star_sfx2_ClassificationCategoriesController_get_implementation(uno::XComponentContext* pContext, const uno::Sequence<uno::Any>&)
365 return cppu::acquire(new sfx2::ClassificationCategoriesController(pContext));
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */