1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "handlerhelper.hxx"
21 #include "propertyeditor.hxx"
22 #include "browserpage.hxx"
23 #include "linedescriptor.hxx"
25 #include <tools/debug.hxx>
27 #include <osl/diagnose.h>
31 using ::com::sun::star::uno::Any
;
32 using ::com::sun::star::inspection::XPropertyControl
;
33 using ::com::sun::star::uno::Reference
;
35 OPropertyEditor::OPropertyEditor(const css::uno::Reference
<css::uno::XComponentContext
>& rContext
, weld::Builder
& rBuilder
)
36 : m_xContainer(rBuilder
.weld_container(u
"box"_ustr
))
37 , m_xTabControl(rBuilder
.weld_notebook(u
"tabcontrol"_ustr
))
38 , m_xControlHoldingParent(rBuilder
.weld_container(u
"controlparent"_ustr
)) // controls initially have this parent before they are moved
39 , m_xContext(rContext
)
40 , m_pListener(nullptr)
41 , m_pObserver(nullptr)
43 , m_bHasHelpSection(false)
45 PropertyHandlerHelper::setBuilderParent(rContext
, m_xControlHoldingParent
.get());
47 m_xTabControl
->connect_leave_page(LINK(this, OPropertyEditor
, OnPageDeactivate
));
48 m_xTabControl
->connect_enter_page(LINK(this, OPropertyEditor
, OnPageActivate
));
51 OPropertyEditor::~OPropertyEditor()
53 PropertyHandlerHelper::clearBuilderParent(m_xContext
);
57 void OPropertyEditor::ClearAll()
61 m_aPropertyPageIds
.clear();
62 m_aShownPages
.clear();
63 m_aHiddenPages
.clear();
65 int nCount
= m_xTabControl
->get_n_pages();
66 for (int i
= nCount
- 1; i
>= 0; --i
)
68 OUString sID
= m_xTabControl
->get_page_ident(i
);
69 m_xTabControl
->remove_page(sID
);
72 assert(m_xTabControl
->get_n_pages() == 0);
75 Size
OPropertyEditor::get_preferred_size() const
77 return m_xTabControl
->get_preferred_size();
80 void OPropertyEditor::CommitModified()
82 // commit all of my pages, if necessary
83 for (const auto& page
: m_aShownPages
)
85 OBrowserPage
* pPage
= page
.second
.xPage
.get();
86 if (pPage
&& pPage
->getListBox().IsModified() )
87 pPage
->getListBox().CommitModified();
91 OBrowserPage
* OPropertyEditor::getPage(const OUString
& rPropertyName
)
93 OBrowserPage
* pPage
= nullptr;
94 MapStringToPageId::const_iterator aPropertyPageIdPos
= m_aPropertyPageIds
.find(rPropertyName
);
95 if (aPropertyPageIdPos
!= m_aPropertyPageIds
.end())
96 pPage
= getPage(aPropertyPageIdPos
->second
);
100 const OBrowserPage
* OPropertyEditor::getPage( const OUString
& _rPropertyName
) const
102 return const_cast< OPropertyEditor
* >( this )->getPage( _rPropertyName
);
105 OBrowserPage
* OPropertyEditor::getPage(sal_uInt16 rPageId
)
107 OBrowserPage
* pPage
= nullptr;
108 auto aPagePos
= m_aShownPages
.find(rPageId
);
109 if (aPagePos
!= m_aShownPages
.end())
110 pPage
= aPagePos
->second
.xPage
.get();
114 const OBrowserPage
* OPropertyEditor::getPage(sal_uInt16 rPageId
) const
116 return const_cast<OPropertyEditor
*>(this)->getPage(rPageId
);
119 sal_uInt16
OPropertyEditor::AppendPage(const OUString
& rText
, const OUString
& rHelpId
)
122 sal_uInt16 nId
= m_nNextId
++;
124 OUString sIdent
= OUString::number(nId
);
125 m_xTabControl
->append_page(sIdent
, rText
);
128 auto xPage
= std::make_unique
<OBrowserPage
>(m_xTabControl
->get_page(sIdent
), m_xControlHoldingParent
.get());
130 xPage
->getListBox().SetListener(m_pListener
);
131 xPage
->getListBox().SetObserver(m_pObserver
);
132 xPage
->getListBox().EnableHelpSection(m_bHasHelpSection
);
133 xPage
->SetHelpId(rHelpId
);
135 m_aShownPages
[nId
] = PropertyPage(m_xTabControl
->get_n_pages() - 1, rText
, std::move(xPage
));
137 // immediately activate the page
138 m_xTabControl
->set_current_page(sIdent
);
143 void OPropertyEditor::SetHelpId( const OUString
& rHelpId
)
145 m_xTabControl
->set_help_id(rHelpId
);
148 void OPropertyEditor::RemovePage(sal_uInt16 nID
)
150 auto aPagePos
= m_aShownPages
.find(nID
);
151 if (aPagePos
== m_aShownPages
.end())
154 m_aShownPages
.erase(aPagePos
);
155 OUString
sIdent(OUString::number(nID
));
156 m_xTabControl
->remove_page(sIdent
);
159 void OPropertyEditor::SetPage(sal_uInt16 nId
)
161 m_xTabControl
->set_current_page(OUString::number(nId
));
164 sal_uInt16
OPropertyEditor::GetCurPage() const
166 return m_xTabControl
->get_current_page_ident().toUInt32();
169 void OPropertyEditor::forEachPage( PageOperation _pOperation
)
171 int nCount
= m_xTabControl
->get_n_pages();
172 for (int i
= 0; i
< nCount
; ++i
)
174 sal_uInt16 nID
= m_xTabControl
->get_page_ident(i
).toUInt32();
175 OBrowserPage
* pPage
= getPage(nID
);
178 (this->*_pOperation
)( *pPage
, nullptr );
182 void OPropertyEditor::setPageLineListener( OBrowserPage
& rPage
, const void* )
184 rPage
.getListBox().SetListener( m_pListener
);
187 void OPropertyEditor::SetLineListener(IPropertyLineListener
* pListener
)
189 m_pListener
= pListener
;
190 forEachPage( &OPropertyEditor::setPageLineListener
);
193 void OPropertyEditor::setPageControlObserver( OBrowserPage
& rPage
, const void* )
195 rPage
.getListBox().SetObserver( m_pObserver
);
198 void OPropertyEditor::SetControlObserver( IPropertyControlObserver
* _pObserver
)
200 m_pObserver
= _pObserver
;
201 forEachPage( &OPropertyEditor::setPageControlObserver
);
204 void OPropertyEditor::EnableHelpSection( bool bEnable
)
206 m_bHasHelpSection
= bEnable
;
207 forEachPage( &OPropertyEditor::enableHelpSection
);
210 void OPropertyEditor::SetHelpText( const OUString
& rHelpText
)
212 int nCount
= m_xTabControl
->get_n_pages();
213 for (int i
= 0; i
< nCount
; ++i
)
215 sal_uInt16 nID
= m_xTabControl
->get_page_ident(i
).toUInt32();
216 OBrowserPage
* pPage
= getPage(nID
);
219 setHelpSectionText( *pPage
, &rHelpText
);
223 void OPropertyEditor::enableHelpSection( OBrowserPage
& rPage
, const void* )
225 rPage
.getListBox().EnableHelpSection( m_bHasHelpSection
);
228 void OPropertyEditor::setHelpSectionText( OBrowserPage
& rPage
, const void* pPointerToOUString
)
230 OSL_ENSURE( pPointerToOUString
, "OPropertyEditor::setHelpSectionText: invalid argument!" );
231 if ( !pPointerToOUString
)
234 const OUString
& rText( *static_cast<const OUString
*>(pPointerToOUString
) );
235 rPage
.getListBox().SetHelpText( rText
);
238 void OPropertyEditor::InsertEntry( const OLineDescriptor
& rData
, sal_uInt16 nPageId
, sal_uInt16 nPos
)
240 // let the current page handle this
241 OBrowserPage
* pPage
= getPage(nPageId
);
242 DBG_ASSERT( pPage
, "OPropertyEditor::InsertEntry: don't have such a page!" );
246 pPage
->getListBox().InsertEntry( rData
, nPos
);
248 OSL_ENSURE( m_aPropertyPageIds
.find( rData
.sName
) == m_aPropertyPageIds
.end(),
249 "OPropertyEditor::InsertEntry: property already present in the map!" );
250 m_aPropertyPageIds
.emplace( rData
.sName
, nPageId
);
253 void OPropertyEditor::RemoveEntry( const OUString
& rName
)
255 OBrowserPage
* pPage
= getPage( rName
);
258 OSL_VERIFY( pPage
->getListBox().RemoveEntry( rName
) );
260 OSL_ENSURE( m_aPropertyPageIds
.find( rName
) != m_aPropertyPageIds
.end(),
261 "OPropertyEditor::RemoveEntry: property not present in the map!" );
262 m_aPropertyPageIds
.erase( rName
);
266 void OPropertyEditor::ChangeEntry( const OLineDescriptor
& rData
)
268 OBrowserPage
* pPage
= getPage( rData
.sName
);
270 pPage
->getListBox().ChangeEntry( rData
, EDITOR_LIST_REPLACE_EXISTING
);
273 void OPropertyEditor::SetPropertyValue( const OUString
& rEntryName
, const Any
& _rValue
, bool _bUnknownValue
)
275 OBrowserPage
* pPage
= getPage( rEntryName
);
277 pPage
->getListBox().SetPropertyValue( rEntryName
, _rValue
, _bUnknownValue
);
280 sal_uInt16
OPropertyEditor::GetPropertyPos( const OUString
& rEntryName
) const
282 sal_uInt16 nVal
=EDITOR_LIST_ENTRY_NOTFOUND
;
283 const OBrowserPage
* pPage
= getPage( rEntryName
);
285 nVal
= pPage
->getListBox().GetPropertyPos( rEntryName
);
289 void OPropertyEditor::ShowPropertyPage(sal_uInt16 nPageId
, bool bShow
)
291 assert((m_aHiddenPages
.find(nPageId
) != m_aHiddenPages
.end() ||
292 m_aShownPages
.find(nPageId
) != m_aShownPages
.end()) && "page doesn't exist");
293 OUString
sIdent(OUString::number(nPageId
));
296 auto aPagePos
= m_aShownPages
.find(nPageId
);
297 if (aPagePos
!= m_aShownPages
.end())
299 aPagePos
->second
.xPage
->detach();
300 m_xTabControl
->remove_page(sIdent
);
302 m_aHiddenPages
[nPageId
] = std::move(aPagePos
->second
);
303 m_aShownPages
.erase(aPagePos
);
308 auto aPagePos
= m_aHiddenPages
.find(nPageId
);
309 if (aPagePos
!= m_aHiddenPages
.end())
311 m_xTabControl
->insert_page(sIdent
, aPagePos
->second
.sLabel
, aPagePos
->second
.nPos
);
312 aPagePos
->second
.xPage
->reattach(m_xTabControl
->get_page(sIdent
));
314 m_aShownPages
[nPageId
] = std::move(aPagePos
->second
);
315 m_aHiddenPages
.erase(aPagePos
);
320 void OPropertyEditor::EnablePropertyControls( const OUString
& rEntryName
, sal_Int16 nControls
, bool bEnable
)
322 for (const auto& rPage
: m_aShownPages
)
324 OBrowserPage
* pPage
= rPage
.second
.xPage
.get();
326 pPage
->getListBox().EnablePropertyControls( rEntryName
, nControls
, bEnable
);
330 void OPropertyEditor::EnablePropertyLine( const OUString
& rEntryName
, bool bEnable
)
332 for (const auto& rPage
: m_aShownPages
)
334 OBrowserPage
* pPage
= rPage
.second
.xPage
.get();
336 pPage
->getListBox().EnablePropertyLine( rEntryName
, bEnable
);
340 Reference
< XPropertyControl
> OPropertyEditor::GetPropertyControl(const OUString
& rEntryName
)
342 Reference
< XPropertyControl
> xControl
;
343 // let the current page handle this
344 OBrowserPage
* pPage
= getPage(m_xTabControl
->get_current_page_ident().toUInt32());
346 xControl
= pPage
->getListBox().GetPropertyControl(rEntryName
);
350 IMPL_LINK(OPropertyEditor
, OnPageActivate
, const OUString
&, rNewPage
, void)
352 m_aPageActivationHandler
.Call(rNewPage
);
355 IMPL_LINK(OPropertyEditor
, OnPageDeactivate
, const OUString
&, rIdent
, bool)
357 // commit the data on the current (to-be-deactivated) tab page
359 OBrowserPage
* pCurrentPage
= getPage(rIdent
.toUInt32());
363 if (pCurrentPage
->getListBox().IsModified())
364 pCurrentPage
->getListBox().CommitModified();
369 OPropertyEditor::PropertyPage::PropertyPage()
374 OPropertyEditor::PropertyPage::PropertyPage(sal_uInt16 nPagePos
, OUString aLabel
, std::unique_ptr
<OBrowserPage
> pPage
)
375 : nPos(nPagePos
), sLabel(std::move(aLabel
)), xPage(std::move(pPage
))
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */