1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 #include "propertyeditor.hxx"
27 #include "browserpage.hxx"
28 #include "linedescriptor.hxx"
29 
30 /** === begin UNO includes === **/
31 /** === end UNO includes === **/
32 #include <tools/debug.hxx>
33 
34 //............................................................................
35 namespace pcr
36 {
37 //............................................................................
38 
39     #define LAYOUT_BORDER_LEFT      3
40     #define LAYOUT_BORDER_TOP       3
41     #define LAYOUT_BORDER_RIGHT     3
42     #define LAYOUT_BORDER_BOTTOM    3
43 
44     /** === begin UNO using === **/
45     using ::com::sun::star::uno::Any;
46     using ::com::sun::star::inspection::XPropertyControl;
47     using ::com::sun::star::uno::Reference;
48     /** === end UNO using === **/
49 
50     //==================================================================
51     // class OPropertyEditor
52     //==================================================================
DBG_NAME(OPropertyEditor)53     DBG_NAME(OPropertyEditor)
54     //------------------------------------------------------------------
55     OPropertyEditor::OPropertyEditor( Window* pParent, WinBits nWinStyle)
56             :Control(pParent, nWinStyle)
57             ,m_aTabControl( this )
58             ,m_nNextId(1)
59             ,m_bHasHelpSection( false )
60             ,m_nMinHelpLines( 0 )
61             ,m_nMaxHelpLines( 0 )
62     {
63         DBG_CTOR(OPropertyEditor,NULL);
64 
65         m_aTabControl.Show();
66         m_aTabControl.SetDeactivatePageHdl(LINK(this, OPropertyEditor, OnPageDeactivate));
67         m_aTabControl.SetActivatePageHdl(LINK(this, OPropertyEditor, OnPageActivate));
68         m_aTabControl.SetBackground(GetBackground());
69         m_aTabControl.SetPaintTransparent(sal_True);
70     }
71 
72     //------------------------------------------------------------------
~OPropertyEditor()73     OPropertyEditor::~OPropertyEditor()
74     {
75         Hide();
76         ClearAll();
77         DBG_DTOR(OPropertyEditor,NULL);
78     }
79 
80     //------------------------------------------------------------------
ClearAll()81     void OPropertyEditor::ClearAll()
82     {
83         m_nNextId=1;
84         sal_uInt16 nCount = m_aTabControl.GetPageCount();
85         for(long i = nCount-1; i >= 0; --i)
86         {
87             sal_uInt16 nID = m_aTabControl.GetPageId((sal_uInt16)i);
88             OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID));
89             if (pPage)
90             {
91                 pPage->EnableInput(sal_False);
92                 m_aTabControl.RemovePage(nID);
93                 delete pPage;
94             }
95         }
96         m_aTabControl.Clear();
97 
98         {
99             MapStringToPageId aEmpty;
100             m_aPropertyPageIds.swap( aEmpty );
101         }
102 
103         while ( !m_aHiddenPages.empty() )
104         {
105             delete m_aHiddenPages.begin()->second.pPage;
106             m_aHiddenPages.erase( m_aHiddenPages.begin() );
107         }
108     }
109 
110     //------------------------------------------------------------------
getMinimumHeight()111     sal_Int32 OPropertyEditor::getMinimumHeight()
112     {
113         sal_Int32 nMinHeight( LAYOUT_BORDER_TOP + LAYOUT_BORDER_BOTTOM );
114 
115         if ( m_aTabControl.GetPageCount() > 0 )
116         {
117             sal_uInt16 nFirstID = m_aTabControl.GetPageId( 0 );
118 
119             // reserve space for the tabs themself
120             Rectangle aTabArea( m_aTabControl.GetTabBounds( nFirstID ) );
121             nMinHeight += aTabArea.GetHeight();
122 
123             // ask the page how much it requires
124             OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nFirstID ) );
125             if ( pPage )
126                 nMinHeight += pPage->getMinimumHeight();
127         }
128         else
129             nMinHeight += 250;  // arbitrary ...
130 
131         return nMinHeight;
132     }
133 
134     //------------------------------------------------------------------
getMinimumWidth()135     sal_Int32 OPropertyEditor::getMinimumWidth()
136     {
137         sal_uInt16 nCount = m_aTabControl.GetPageCount();
138         sal_Int32 nPageMinWidth = 0;
139         for(long i = nCount-1; i >= 0; --i)
140         {
141             sal_uInt16 nID = m_aTabControl.GetPageId((sal_uInt16)i);
142             OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID));
143             if (pPage)
144             {
145                 sal_Int32 nCurPageMinWidth = pPage->getMinimumWidth();
146                 if( nCurPageMinWidth > nPageMinWidth )
147                     nPageMinWidth = nCurPageMinWidth;
148             }
149         }
150         return nPageMinWidth+6;
151     }
152 
153     //------------------------------------------------------------------
CommitModified()154     void OPropertyEditor::CommitModified()
155     {
156         // commit all of my pages, if necessary
157 
158         sal_uInt16 nCount = m_aTabControl.GetPageCount();
159         for ( sal_uInt16 i=0; i<nCount; ++i )
160         {
161             sal_uInt16 nID = m_aTabControl.GetPageId( i );
162             OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nID ) );
163 
164             if ( pPage && pPage->getListBox().IsModified() )
165                 pPage->getListBox().CommitModified();
166         }
167     }
168 
169     //------------------------------------------------------------------
GetFocus()170     void OPropertyEditor::GetFocus()
171     {
172         m_aTabControl.GrabFocus();
173     }
174 
175     //------------------------------------------------------------------
getPage(const::rtl::OUString & _rPropertyName)176     OBrowserPage* OPropertyEditor::getPage( const ::rtl::OUString& _rPropertyName )
177     {
178         OBrowserPage* pPage = NULL;
179         MapStringToPageId::const_iterator aPropertyPageIdPos = m_aPropertyPageIds.find( _rPropertyName );
180         if ( aPropertyPageIdPos != m_aPropertyPageIds.end() )
181             pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( aPropertyPageIdPos->second ) );
182         return pPage;
183     }
184 
185     //------------------------------------------------------------------
getPage(const::rtl::OUString & _rPropertyName) const186     const OBrowserPage* OPropertyEditor::getPage( const ::rtl::OUString& _rPropertyName ) const
187     {
188         return const_cast< OPropertyEditor* >( this )->getPage( _rPropertyName );
189     }
190 
191     //------------------------------------------------------------------
getPage(sal_uInt16 & _rPageId)192     OBrowserPage* OPropertyEditor::getPage( sal_uInt16& _rPageId )
193     {
194         return static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( _rPageId ) );
195     }
196 
197     //------------------------------------------------------------------
getPage(sal_uInt16 & _rPageId) const198     const OBrowserPage* OPropertyEditor::getPage( sal_uInt16& _rPageId ) const
199     {
200         return const_cast< OPropertyEditor* >( this )->getPage( _rPageId );
201     }
202 
203     //------------------------------------------------------------------
Resize()204     void OPropertyEditor::Resize()
205     {
206         Rectangle aPlayground(
207             Point( LAYOUT_BORDER_LEFT, LAYOUT_BORDER_TOP ),
208             Size(
209                 GetOutputSizePixel().Width() - LAYOUT_BORDER_LEFT - LAYOUT_BORDER_RIGHT,
210                 GetOutputSizePixel().Height() - LAYOUT_BORDER_TOP - LAYOUT_BORDER_BOTTOM
211             )
212         );
213 
214         Rectangle aTabArea( aPlayground );
215         m_aTabControl.SetPosSizePixel( aTabArea.TopLeft(), aTabArea.GetSize() );
216     }
217 
218     //------------------------------------------------------------------
AppendPage(const String & _rText,const rtl::OString & _rHelpId)219     sal_uInt16 OPropertyEditor::AppendPage( const String & _rText, const rtl::OString& _rHelpId )
220     {
221         // obtain a new id
222         sal_uInt16 nId = m_nNextId++;
223         // insert the id
224         m_aTabControl.InsertPage(nId, _rText);
225 
226         // create a new page
227         OBrowserPage* pPage = new OBrowserPage(&m_aTabControl);
228         pPage->SetText( _rText );
229         // some knittings
230         pPage->SetSizePixel(m_aTabControl.GetTabPageSizePixel());
231         pPage->getListBox().SetListener(m_pListener);
232         pPage->getListBox().SetObserver(m_pObserver);
233         pPage->getListBox().EnableHelpSection( m_bHasHelpSection );
234         pPage->getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
235         pPage->SetHelpId( _rHelpId );
236 
237         // immediately activate the page
238         m_aTabControl.SetTabPage(nId, pPage);
239         m_aTabControl.SetCurPageId(nId);
240 
241         return nId;
242     }
243 
244     //------------------------------------------------------------------
SetHelpId(const rtl::OString & rHelpId)245     void OPropertyEditor::SetHelpId( const rtl::OString& rHelpId )
246     {
247         Control::SetHelpId("");
248         m_aTabControl.SetHelpId(rHelpId);
249     }
250 
251     //------------------------------------------------------------------
RemovePage(sal_uInt16 nID)252     void OPropertyEditor::RemovePage(sal_uInt16 nID)
253     {
254         OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID));
255 
256         if (pPage)
257             pPage->EnableInput(sal_False);
258         m_aTabControl.RemovePage(nID);
259         if (pPage)
260             delete pPage;
261     }
262 
263     //------------------------------------------------------------------
SetPage(sal_uInt16 nId)264     void OPropertyEditor::SetPage(sal_uInt16 nId)
265     {
266         m_aTabControl.SetCurPageId(nId);
267     }
268 
269     //------------------------------------------------------------------
GetCurPage()270     sal_uInt16 OPropertyEditor::GetCurPage()
271     {
272         if(m_aTabControl.GetPageCount()>0)
273             return m_aTabControl.GetCurPageId();
274         else
275             return 0;
276     }
277 
278     //------------------------------------------------------------------
Update(const::std::mem_fun_t<void,OBrowserListBox> & _aUpdateFunction)279     void OPropertyEditor::Update(const ::std::mem_fun_t<void,OBrowserListBox>& _aUpdateFunction)
280     {
281         // forward this to all our pages
282         sal_uInt16 nCount = m_aTabControl.GetPageCount();
283         for (sal_uInt16 i=0;i<nCount;++i)
284         {
285             sal_uInt16 nID = m_aTabControl.GetPageId(i);
286             OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(nID));
287             if (pPage)
288                 _aUpdateFunction(&pPage->getListBox());
289         }
290     }
291     //------------------------------------------------------------------
EnableUpdate()292     void OPropertyEditor::EnableUpdate()
293     {
294         Update(::std::mem_fun(&OBrowserListBox::EnableUpdate));
295     }
296     //------------------------------------------------------------------
DisableUpdate()297     void OPropertyEditor::DisableUpdate()
298     {
299         Update(::std::mem_fun(&OBrowserListBox::DisableUpdate));
300     }
301 
302     //------------------------------------------------------------------
forEachPage(PageOperation _pOperation,const void * _pArgument)303     void OPropertyEditor::forEachPage( PageOperation _pOperation, const void* _pArgument )
304     {
305         sal_uInt16 nCount = m_aTabControl.GetPageCount();
306         for ( sal_uInt16 i=0; i<nCount; ++i )
307         {
308             sal_uInt16 nID = m_aTabControl.GetPageId(i);
309             OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( nID ) );
310             if ( !pPage )
311                 continue;
312             (this->*_pOperation)( *pPage, _pArgument );
313         }
314     }
315 
316     //------------------------------------------------------------------
setPageLineListener(OBrowserPage & _rPage,const void *)317     void OPropertyEditor::setPageLineListener( OBrowserPage& _rPage, const void* )
318     {
319         _rPage.getListBox().SetListener( m_pListener );
320     }
321 
322     //------------------------------------------------------------------
SetLineListener(IPropertyLineListener * _pListener)323     void OPropertyEditor::SetLineListener(IPropertyLineListener* _pListener)
324     {
325         m_pListener = _pListener;
326         forEachPage( &OPropertyEditor::setPageLineListener );
327     }
328 
329     //------------------------------------------------------------------
setPageControlObserver(OBrowserPage & _rPage,const void *)330     void OPropertyEditor::setPageControlObserver( OBrowserPage& _rPage, const void* )
331     {
332         _rPage.getListBox().SetObserver( m_pObserver );
333     }
334 
335     //------------------------------------------------------------------
SetControlObserver(IPropertyControlObserver * _pObserver)336     void OPropertyEditor::SetControlObserver( IPropertyControlObserver* _pObserver )
337     {
338         m_pObserver = _pObserver;
339         forEachPage( &OPropertyEditor::setPageControlObserver );
340     }
341 
342     //------------------------------------------------------------------
EnableHelpSection(bool _bEnable)343     void OPropertyEditor::EnableHelpSection( bool _bEnable )
344     {
345         m_bHasHelpSection = _bEnable;
346         forEachPage( &OPropertyEditor::enableHelpSection );
347     }
348 
349     //------------------------------------------------------------------
HasHelpSection() const350     bool OPropertyEditor::HasHelpSection() const
351     {
352         return m_bHasHelpSection;
353     }
354 
355     //------------------------------------------------------------------
SetHelpText(const::rtl::OUString & _rHelpText)356     void OPropertyEditor::SetHelpText( const ::rtl::OUString& _rHelpText )
357     {
358         forEachPage( &OPropertyEditor::setHelpSectionText, &_rHelpText );
359     }
360 
361     //------------------------------------------------------------------
SetHelpLineLimites(sal_Int32 _nMinLines,sal_Int32 _nMaxLines)362     void OPropertyEditor::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
363     {
364         m_nMinHelpLines = _nMinLines;
365         m_nMaxHelpLines = _nMaxLines;
366         forEachPage( &OPropertyEditor::setHelpLineLimits );
367     }
368 
369     //------------------------------------------------------------------
enableHelpSection(OBrowserPage & _rPage,const void *)370     void OPropertyEditor::enableHelpSection( OBrowserPage& _rPage, const void* )
371     {
372         _rPage.getListBox().EnableHelpSection( m_bHasHelpSection );
373     }
374 
375     //------------------------------------------------------------------
setHelpSectionText(OBrowserPage & _rPage,const void * _pPointerToOUString)376     void OPropertyEditor::setHelpSectionText( OBrowserPage& _rPage, const void* _pPointerToOUString )
377     {
378         OSL_ENSURE( _pPointerToOUString, "OPropertyEditor::setHelpSectionText: invalid argument!" );
379         if ( !_pPointerToOUString )
380             return;
381 
382         const ::rtl::OUString& rText( *(const ::rtl::OUString*)_pPointerToOUString );
383         _rPage.getListBox().SetHelpText( rText );
384     }
385 
386     //------------------------------------------------------------------
setHelpLineLimits(OBrowserPage & _rPage,const void *)387     void OPropertyEditor::setHelpLineLimits( OBrowserPage& _rPage, const void* )
388     {
389         _rPage.getListBox().SetHelpLineLimites( m_nMinHelpLines, m_nMaxHelpLines );
390     }
391 
392     //------------------------------------------------------------------
InsertEntry(const OLineDescriptor & rData,sal_uInt16 _nPageId,sal_uInt16 nPos)393     sal_uInt16 OPropertyEditor::InsertEntry( const OLineDescriptor& rData, sal_uInt16 _nPageId, sal_uInt16 nPos )
394     {
395         // let the current page handle this
396         OBrowserPage* pPage = getPage( _nPageId );
397         DBG_ASSERT( pPage, "OPropertyEditor::InsertEntry: don't have such a page!" );
398         if ( !pPage )
399             return LISTBOX_ENTRY_NOTFOUND;
400 
401         sal_uInt16 nEntry = pPage->getListBox().InsertEntry( rData, nPos );
402 
403         OSL_ENSURE( m_aPropertyPageIds.find( rData.sName ) == m_aPropertyPageIds.end(),
404             "OPropertyEditor::InsertEntry: property already present in the map!" );
405         m_aPropertyPageIds.insert( MapStringToPageId::value_type( rData.sName, _nPageId ) );
406 
407         return nEntry;
408     }
409 
410     //------------------------------------------------------------------
RemoveEntry(const::rtl::OUString & _rName)411     void OPropertyEditor::RemoveEntry( const ::rtl::OUString& _rName )
412     {
413         OBrowserPage* pPage = getPage( _rName );
414         if ( pPage )
415         {
416             OSL_VERIFY( pPage->getListBox().RemoveEntry( _rName ) );
417 
418             OSL_ENSURE( m_aPropertyPageIds.find( _rName ) != m_aPropertyPageIds.end(),
419                 "OPropertyEditor::RemoveEntry: property not present in the map!" );
420             m_aPropertyPageIds.erase( _rName );
421         }
422     }
423 
424     //------------------------------------------------------------------
ChangeEntry(const OLineDescriptor & rData)425     void OPropertyEditor::ChangeEntry( const OLineDescriptor& rData )
426     {
427         OBrowserPage* pPage = getPage( rData.sName );
428         if ( pPage )
429             pPage->getListBox().ChangeEntry( rData, EDITOR_LIST_REPLACE_EXISTING );
430     }
431 
432     //------------------------------------------------------------------
SetPropertyValue(const::rtl::OUString & rEntryName,const Any & _rValue,bool _bUnknownValue)433     void OPropertyEditor::SetPropertyValue( const ::rtl::OUString& rEntryName, const Any& _rValue, bool _bUnknownValue )
434     {
435         OBrowserPage* pPage = getPage( rEntryName );
436         if ( pPage )
437             pPage->getListBox().SetPropertyValue( rEntryName, _rValue, _bUnknownValue );
438     }
439 
440     //------------------------------------------------------------------
GetPropertyPos(const::rtl::OUString & rEntryName) const441     sal_uInt16 OPropertyEditor::GetPropertyPos( const ::rtl::OUString& rEntryName ) const
442     {
443         sal_uInt16 nVal=LISTBOX_ENTRY_NOTFOUND;
444         const OBrowserPage* pPage = getPage( rEntryName );
445         if ( pPage )
446             nVal = pPage->getListBox().GetPropertyPos( rEntryName );
447         return nVal;
448     }
449 
450     //------------------------------------------------------------------
ShowPropertyPage(sal_uInt16 _nPageId,bool _bShow)451     void OPropertyEditor::ShowPropertyPage( sal_uInt16 _nPageId, bool _bShow )
452     {
453         if ( !_bShow )
454         {
455             sal_uInt16 nPagePos = m_aTabControl.GetPagePos( _nPageId );
456             if ( TAB_PAGE_NOTFOUND == nPagePos )
457                 return;
458             DBG_ASSERT( m_aHiddenPages.find( _nPageId ) == m_aHiddenPages.end(), "OPropertyEditor::ShowPropertyPage: page already hidden!" );
459 
460             m_aHiddenPages[ _nPageId ] = HiddenPage( nPagePos, m_aTabControl.GetTabPage( _nPageId ) );
461             m_aTabControl.RemovePage( _nPageId );
462         }
463         else
464         {
465             ::std::map< sal_uInt16, HiddenPage >::iterator aPagePos = m_aHiddenPages.find( _nPageId );
466             if ( aPagePos == m_aHiddenPages.end() )
467                 return;
468 
469             aPagePos->second.pPage->SetSizePixel( m_aTabControl.GetTabPageSizePixel() );
470             m_aTabControl.InsertPage( aPagePos->first, aPagePos->second.pPage->GetText(), aPagePos->second.nPos );
471             m_aTabControl.SetTabPage( aPagePos->first, aPagePos->second.pPage );
472 
473             m_aHiddenPages.erase( aPagePos );
474         }
475     }
476 
477     //------------------------------------------------------------------
EnablePropertyControls(const::rtl::OUString & _rEntryName,sal_Int16 _nControls,bool _bEnable)478     void OPropertyEditor::EnablePropertyControls( const ::rtl::OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
479     {
480         for ( sal_uInt16 i = 0; i < m_aTabControl.GetPageCount(); ++i )
481         {
482             OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( m_aTabControl.GetPageId( i ) ) );
483             if ( pPage )
484                 pPage->getListBox().EnablePropertyControls( _rEntryName, _nControls, _bEnable );
485         }
486     }
487 
488     //------------------------------------------------------------------
EnablePropertyLine(const::rtl::OUString & _rEntryName,bool _bEnable)489     void OPropertyEditor::EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable )
490     {
491         for ( sal_uInt16 i = 0; i < m_aTabControl.GetPageCount(); ++i )
492         {
493             OBrowserPage* pPage = static_cast< OBrowserPage* >( m_aTabControl.GetTabPage( m_aTabControl.GetPageId( i ) ) );
494             if ( pPage )
495                 pPage->getListBox().EnablePropertyLine( _rEntryName, _bEnable );
496         }
497     }
498 
499     //------------------------------------------------------------------
GetPropertyControl(const::rtl::OUString & rEntryName)500     Reference< XPropertyControl > OPropertyEditor::GetPropertyControl(const ::rtl::OUString& rEntryName)
501     {
502         Reference< XPropertyControl > xControl;
503         // let the current page handle this
504         OBrowserPage* pPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage(m_aTabControl.GetCurPageId()));
505         if (pPage)
506             xControl = pPage->getListBox().GetPropertyControl(rEntryName);
507         return xControl;
508     }
509 
510     //------------------------------------------------------------------
IMPL_LINK(OPropertyEditor,OnPageActivate,TabControl *,EMPTYARG)511     IMPL_LINK(OPropertyEditor, OnPageActivate, TabControl*, EMPTYARG)
512     {
513         if (m_aPageActivationHandler.IsSet())
514             m_aPageActivationHandler.Call(NULL);
515         return 0L;
516     }
517 
518     //------------------------------------------------------------------
IMPL_LINK(OPropertyEditor,OnPageDeactivate,TabControl *,EMPTYARG)519     IMPL_LINK(OPropertyEditor, OnPageDeactivate, TabControl*, EMPTYARG)
520     {
521         // commit the data on the current (to-be-decativated) tab page
522         // (79404)
523         sal_Int32 nCurrentId = m_aTabControl.GetCurPageId();
524         OBrowserPage* pCurrentPage = static_cast<OBrowserPage*>(m_aTabControl.GetTabPage((sal_uInt16)nCurrentId));
525         if ( !pCurrentPage )
526             return 1L;
527 
528         if ( pCurrentPage->getListBox().IsModified() )
529             pCurrentPage->getListBox().CommitModified();
530 
531         return 1L;
532     }
533 
534 //............................................................................
535 } // namespace pcr
536 //............................................................................
537 
538 
539