Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / extensions / source / propctrlr / propertyeditor.cxx
blobe0b6abb3ce99fbf51fc5b431e86fc626a7e0be4f
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/.
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 "propertyeditor.hxx"
21 #include "browserpage.hxx"
22 #include "linedescriptor.hxx"
24 #include <tools/debug.hxx>
25 #include <osl/diagnose.h>
28 namespace pcr
32 #define LAYOUT_BORDER_LEFT 3
33 #define LAYOUT_BORDER_TOP 3
34 #define LAYOUT_BORDER_RIGHT 3
35 #define LAYOUT_BORDER_BOTTOM 3
37 using ::com::sun::star::uno::Any;
38 using ::com::sun::star::inspection::XPropertyControl;
39 using ::com::sun::star::uno::Reference;
42 // class OPropertyEditor
45 OPropertyEditor::OPropertyEditor( vcl::Window* pParent)
46 :Control(pParent, WB_DIALOGCONTROL)
47 ,m_aTabControl( VclPtr<TabControl>::Create(this) )
48 ,m_pListener(nullptr)
49 ,m_pObserver(nullptr)
50 ,m_nNextId(1)
51 ,m_bHasHelpSection( false )
52 ,m_nMinHelpLines( 0 )
53 ,m_nMaxHelpLines( 0 )
56 m_aTabControl->Show();
57 m_aTabControl->SetDeactivatePageHdl(LINK(this, OPropertyEditor, OnPageDeactivate));
58 m_aTabControl->SetActivatePageHdl(LINK(this, OPropertyEditor, OnPageActivate));
59 m_aTabControl->SetBackground(GetBackground());
60 m_aTabControl->SetPaintTransparent(true);
64 OPropertyEditor::~OPropertyEditor()
66 disposeOnce();
69 void OPropertyEditor::dispose()
71 Hide();
72 ClearAll();
73 m_aTabControl.disposeAndClear();
74 Control::dispose();
78 void OPropertyEditor::ClearAll()
80 m_nNextId=1;
81 sal_uInt16 nCount = m_aTabControl->GetPageCount();
82 for(long i = nCount-1; i >= 0; --i)
84 sal_uInt16 nID = m_aTabControl->GetPageId(static_cast<sal_uInt16>(i));
85 VclPtr<OBrowserPage> pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
86 if (pPage)
88 pPage->EnableInput(false);
89 m_aTabControl->RemovePage(nID);
90 pPage.disposeAndClear();
93 m_aTabControl->Clear();
96 MapStringToPageId aEmpty;
97 m_aPropertyPageIds.swap( aEmpty );
100 for (auto& rEntry : m_aHiddenPages)
101 rEntry.second.pPage.disposeAndClear();
102 m_aHiddenPages.clear();
106 sal_Int32 OPropertyEditor::getMinimumHeight() const
108 sal_Int32 nMinHeight( LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM );
110 if ( m_aTabControl->GetPageCount() > 0 )
112 sal_uInt16 nFirstID = m_aTabControl->GetPageId( 0 );
114 // reserve space for the tabs themself
115 tools::Rectangle aTabArea( m_aTabControl->GetTabBounds( nFirstID ) );
116 nMinHeight += aTabArea.GetHeight();
118 // ask the page how much it requires
119 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nFirstID ) );
120 if ( pPage )
121 nMinHeight += pPage->getMinimumHeight();
123 else
124 nMinHeight += 250; // arbitrary ...
126 return nMinHeight;
130 sal_Int32 OPropertyEditor::getMinimumWidth() const
132 sal_uInt16 nCount = m_aTabControl->GetPageCount();
133 sal_Int32 nPageMinWidth = 0;
134 for(long i = nCount-1; i >= 0; --i)
136 sal_uInt16 nID = m_aTabControl->GetPageId(static_cast<sal_uInt16>(i));
137 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
138 if (pPage)
140 sal_Int32 nCurPageMinWidth = pPage->getMinimumWidth();
141 if( nCurPageMinWidth > nPageMinWidth )
142 nPageMinWidth = nCurPageMinWidth;
145 return nPageMinWidth+6;
149 void OPropertyEditor::CommitModified()
151 // commit all of my pages, if necessary
153 sal_uInt16 nCount = m_aTabControl->GetPageCount();
154 for ( sal_uInt16 i=0; i<nCount; ++i )
156 sal_uInt16 nID = m_aTabControl->GetPageId( i );
157 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );
159 if ( pPage && pPage->getListBox().IsModified() )
160 pPage->getListBox().CommitModified();
165 void OPropertyEditor::GetFocus()
167 if ( m_aTabControl )
168 m_aTabControl->GrabFocus();
172 OBrowserPage* OPropertyEditor::getPage( const OUString& _rPropertyName )
174 OBrowserPage* pPage = nullptr;
175 MapStringToPageId::const_iterator aPropertyPageIdPos = m_aPropertyPageIds.find( _rPropertyName );
176 if ( aPropertyPageIdPos != m_aPropertyPageIds.end() )
177 pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( aPropertyPageIdPos->second ) );
178 return pPage;
182 const OBrowserPage* OPropertyEditor::getPage( const OUString& _rPropertyName ) const
184 return const_cast< OPropertyEditor* >( this )->getPage( _rPropertyName );
188 OBrowserPage* OPropertyEditor::getPage( sal_uInt16 _rPageId )
190 return static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( _rPageId ) );
194 const OBrowserPage* OPropertyEditor::getPage( sal_uInt16 _rPageId ) const
196 return const_cast< OPropertyEditor* >( this )->getPage( _rPageId );
200 void OPropertyEditor::Resize()
202 tools::Rectangle aPlayground(
203 Point( LAYOUT_BORDER_LEFT, LAYOUT_BORDER_TOP ),
204 Size(
205 GetOutputSizePixel().Width() - LAYOUT_BORDER_LEFT - LAYOUT_BORDER_RIGHT,
206 GetOutputSizePixel().Height() - LAYOUT_BORDER_TOP - LAYOUT_BORDER_BOTTOM
210 tools::Rectangle aTabArea( aPlayground );
211 m_aTabControl->SetPosSizePixel( aTabArea.TopLeft(), aTabArea.GetSize() );
215 sal_uInt16 OPropertyEditor::AppendPage( const OUString & _rText, const OString& _rHelpId )
217 // obtain a new id
218 sal_uInt16 nId = m_nNextId++;
219 // insert the id
220 m_aTabControl->InsertPage(nId, _rText);
222 // create a new page
223 VclPtrInstance<OBrowserPage> pPage(m_aTabControl.get());
224 pPage->SetText( _rText );
225 // some knittings
226 pPage->SetSizePixel(m_aTabControl->GetTabPageSizePixel());
227 pPage->getListBox().SetListener(m_pListener);
228 pPage->getListBox().SetObserver(m_pObserver);
229 pPage->getListBox().EnableHelpSection( m_bHasHelpSection );
230 pPage->getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
231 pPage->SetHelpId( _rHelpId );
233 // immediately activate the page
234 m_aTabControl->SetTabPage(nId, pPage);
235 m_aTabControl->SetCurPageId(nId);
237 return nId;
241 void OPropertyEditor::SetHelpId( const OString& rHelpId )
243 Control::SetHelpId("");
244 m_aTabControl->SetHelpId(rHelpId);
248 void OPropertyEditor::RemovePage(sal_uInt16 nID)
250 VclPtr<OBrowserPage> pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
252 if (pPage)
253 pPage->EnableInput(false);
254 m_aTabControl->RemovePage(nID);
255 pPage.disposeAndClear();
259 void OPropertyEditor::SetPage(sal_uInt16 nId)
261 m_aTabControl->SetCurPageId(nId);
265 sal_uInt16 OPropertyEditor::GetCurPage() const
267 if(m_aTabControl->GetPageCount()>0)
268 return m_aTabControl->GetCurPageId();
269 else
270 return 0;
274 void OPropertyEditor::Update(const std::function<void(OBrowserListBox *)>& _aUpdateFunction)
276 // forward this to all our pages
277 sal_uInt16 nCount = m_aTabControl->GetPageCount();
278 for (sal_uInt16 i=0;i<nCount;++i)
280 sal_uInt16 nID = m_aTabControl->GetPageId(i);
281 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(nID));
282 if (pPage)
283 _aUpdateFunction(&pPage->getListBox());
287 void OPropertyEditor::EnableUpdate()
289 Update(std::mem_fn(&OBrowserListBox::EnableUpdate));
292 void OPropertyEditor::DisableUpdate()
294 Update(std::mem_fn(&OBrowserListBox::DisableUpdate));
298 void OPropertyEditor::forEachPage( PageOperation _pOperation )
300 sal_uInt16 nCount = m_aTabControl->GetPageCount();
301 for ( sal_uInt16 i=0; i<nCount; ++i )
303 sal_uInt16 nID = m_aTabControl->GetPageId(i);
304 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );
305 if ( !pPage )
306 continue;
307 (this->*_pOperation)( *pPage, nullptr );
312 void OPropertyEditor::setPageLineListener( OBrowserPage& _rPage, const void* )
314 _rPage.getListBox().SetListener( m_pListener );
318 void OPropertyEditor::SetLineListener(IPropertyLineListener* _pListener)
320 m_pListener = _pListener;
321 forEachPage( &OPropertyEditor::setPageLineListener );
325 void OPropertyEditor::setPageControlObserver( OBrowserPage& _rPage, const void* )
327 _rPage.getListBox().SetObserver( m_pObserver );
331 void OPropertyEditor::SetControlObserver( IPropertyControlObserver* _pObserver )
333 m_pObserver = _pObserver;
334 forEachPage( &OPropertyEditor::setPageControlObserver );
338 void OPropertyEditor::EnableHelpSection( bool _bEnable )
340 m_bHasHelpSection = _bEnable;
341 forEachPage( &OPropertyEditor::enableHelpSection );
345 void OPropertyEditor::SetHelpText( const OUString& _rHelpText )
347 sal_uInt16 nCount = m_aTabControl->GetPageCount();
348 for ( sal_uInt16 i=0; i<nCount; ++i )
350 sal_uInt16 nID = m_aTabControl->GetPageId(i);
351 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( nID ) );
352 if ( !pPage )
353 continue;
354 setHelpSectionText( *pPage, &_rHelpText );
359 void OPropertyEditor::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
361 m_nMinHelpLines = _nMinLines;
362 m_nMaxHelpLines = _nMaxLines;
363 forEachPage( &OPropertyEditor::setHelpLineLimits );
367 void OPropertyEditor::enableHelpSection( OBrowserPage& _rPage, const void* )
369 _rPage.getListBox().EnableHelpSection( m_bHasHelpSection );
373 void OPropertyEditor::setHelpSectionText( OBrowserPage& _rPage, const void* _pPointerToOUString )
375 OSL_ENSURE( _pPointerToOUString, "OPropertyEditor::setHelpSectionText: invalid argument!" );
376 if ( !_pPointerToOUString )
377 return;
379 const OUString& rText( *static_cast<const OUString*>(_pPointerToOUString) );
380 _rPage.getListBox().SetHelpText( rText );
384 void OPropertyEditor::setHelpLineLimits( OBrowserPage& _rPage, const void* )
386 _rPage.getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
390 void OPropertyEditor::InsertEntry( const OLineDescriptor& rData, sal_uInt16 _nPageId, sal_uInt16 nPos )
392 // let the current page handle this
393 OBrowserPage* pPage = getPage( _nPageId );
394 DBG_ASSERT( pPage, "OPropertyEditor::InsertEntry: don't have such a page!" );
395 if ( !pPage )
396 return;
398 pPage->getListBox().InsertEntry( rData, nPos );
400 OSL_ENSURE( m_aPropertyPageIds.find( rData.sName ) == m_aPropertyPageIds.end(),
401 "OPropertyEditor::InsertEntry: property already present in the map!" );
402 m_aPropertyPageIds.emplace( rData.sName, _nPageId );
406 void OPropertyEditor::RemoveEntry( const OUString& _rName )
408 OBrowserPage* pPage = getPage( _rName );
409 if ( pPage )
411 OSL_VERIFY( pPage->getListBox().RemoveEntry( _rName ) );
413 OSL_ENSURE( m_aPropertyPageIds.find( _rName ) != m_aPropertyPageIds.end(),
414 "OPropertyEditor::RemoveEntry: property not present in the map!" );
415 m_aPropertyPageIds.erase( _rName );
420 void OPropertyEditor::ChangeEntry( const OLineDescriptor& rData )
422 OBrowserPage* pPage = getPage( rData.sName );
423 if ( pPage )
424 pPage->getListBox().ChangeEntry( rData, EDITOR_LIST_REPLACE_EXISTING );
428 void OPropertyEditor::SetPropertyValue( const OUString& rEntryName, const Any& _rValue, bool _bUnknownValue )
430 OBrowserPage* pPage = getPage( rEntryName );
431 if ( pPage )
432 pPage->getListBox().SetPropertyValue( rEntryName, _rValue, _bUnknownValue );
436 sal_uInt16 OPropertyEditor::GetPropertyPos( const OUString& rEntryName ) const
438 sal_uInt16 nVal=EDITOR_LIST_ENTRY_NOTFOUND;
439 const OBrowserPage* pPage = getPage( rEntryName );
440 if ( pPage )
441 nVal = pPage->getListBox().GetPropertyPos( rEntryName );
442 return nVal;
446 void OPropertyEditor::ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow )
448 if ( !_bShow )
450 sal_uInt16 nPagePos = m_aTabControl->GetPagePos( _nPageId );
451 if ( TAB_PAGE_NOTFOUND == nPagePos )
452 return;
453 DBG_ASSERT( m_aHiddenPages.find( _nPageId ) == m_aHiddenPages.end(), "OPropertyEditor::ShowPropertyPage: page already hidden!" );
455 m_aHiddenPages[ _nPageId ] = HiddenPage( nPagePos, m_aTabControl->GetTabPage( _nPageId ) );
456 m_aTabControl->RemovePage( _nPageId );
458 else
460 std::map< sal_uInt16, HiddenPage >::iterator aPagePos = m_aHiddenPages.find( _nPageId );
461 if ( aPagePos == m_aHiddenPages.end() )
462 return;
464 aPagePos->second.pPage->SetSizePixel( m_aTabControl->GetTabPageSizePixel() );
465 m_aTabControl->InsertPage( aPagePos->first, aPagePos->second.pPage->GetText(), aPagePos->second.nPos );
466 m_aTabControl->SetTabPage( aPagePos->first, aPagePos->second.pPage );
468 m_aHiddenPages.erase( aPagePos );
473 void OPropertyEditor::EnablePropertyControls( const OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
475 for ( sal_uInt16 i = 0; i < m_aTabControl->GetPageCount(); ++i )
477 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( m_aTabControl->GetPageId( i ) ) );
478 if ( pPage )
479 pPage->getListBox().EnablePropertyControls( _rEntryName, _nControls, _bEnable );
484 void OPropertyEditor::EnablePropertyLine( const OUString& _rEntryName, bool _bEnable )
486 for ( sal_uInt16 i = 0; i < m_aTabControl->GetPageCount(); ++i )
488 OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl->GetTabPage( m_aTabControl->GetPageId( i ) ) );
489 if ( pPage )
490 pPage->getListBox().EnablePropertyLine( _rEntryName, _bEnable );
495 Reference< XPropertyControl > OPropertyEditor::GetPropertyControl(const OUString& rEntryName)
497 Reference< XPropertyControl > xControl;
498 // let the current page handle this
499 OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(m_aTabControl->GetCurPageId()));
500 if (pPage)
501 xControl = pPage->getListBox().GetPropertyControl(rEntryName);
502 return xControl;
506 IMPL_LINK_NOARG(OPropertyEditor, OnPageActivate, TabControl*, void)
508 m_aPageActivationHandler.Call(nullptr);
512 IMPL_LINK_NOARG(OPropertyEditor, OnPageDeactivate, TabControl *, bool)
514 // commit the data on the current (to-be-deactivated) tab page
515 // (79404)
516 sal_Int32 nCurrentId = m_aTabControl->GetCurPageId();
517 OBrowserPage* pCurrentPage = static_cast<OBrowserPage*>(m_aTabControl->GetTabPage(static_cast<sal_uInt16>(nCurrentId)));
518 if ( !pCurrentPage )
519 return true;
521 if ( pCurrentPage->getListBox().IsModified() )
522 pCurrentPage->getListBox().CommitModified();
524 return true;
528 } // namespace pcr
531 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */