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_sfx2.hxx"
26 
27 #include "sfx2/securitypage.hxx"
28 
29 #include "securitypage.hrc"
30 #include "sfxresid.hxx"
31 
32 #include <sfx2/sfx.hrc>
33 #include <sfx2/sfxsids.hrc>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/viewsh.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/passwd.hxx>
38 
39 #include <vcl/button.hxx>
40 #include <vcl/edit.hxx>
41 #include <vcl/fixed.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <svl/eitem.hxx>
44 #include <svl/poolitem.hxx>
45 #include <svl/intitem.hxx>
46 #include <svl/PasswordHelper.hxx>
47 #include <svtools/xwindowitem.hxx>
48 
49 
50 using namespace ::com::sun::star;
51 
52 //////////////////////////////////////////////////////////////////////
53 
54 
55 namespace
56 {
57     enum RedliningMode  { RL_NONE, RL_WRITER, RL_CALC };
58     enum RedlineFunc    { RF_ON, RF_PROTECT };
59 
60 /*
61     bool QueryIsEnabled( sal_uInt16 _nSlot )
62     {
63         bool bRes = false;
64         SfxViewShell* pViewSh = SfxViewShell::Current();
65         if (pViewSh)
66         {
67             const SfxPoolItem* pItem;
68             SfxDispatcher* pDisp = pViewSh->GetDispatcher();
69             SfxItemState eState = pDisp->QueryState( _nSlot, pItem );
70             bRes = (eState & SFX_ITEM_DISABLED) == 0;
71         }
72         return bRes;
73     }
74 */
75 
QueryState(sal_uInt16 _nSlot,bool & _rValue)76     bool QueryState( sal_uInt16 _nSlot, bool& _rValue )
77     {
78         bool bRet = false;
79         SfxViewShell* pViewSh = SfxViewShell::Current();
80         if (pViewSh)
81         {
82             const SfxPoolItem* pItem;
83             SfxDispatcher* pDisp = pViewSh->GetDispatcher();
84             SfxItemState nState = pDisp->QueryState( _nSlot, pItem );
85             bRet = SFX_ITEM_AVAILABLE <= nState;
86             if (bRet)
87                 _rValue = ( static_cast< const SfxBoolItem* >( pItem ) )->GetValue();
88         }
89         return bRet;
90     }
91 
92 
QueryRecordChangesProtectionState(RedliningMode _eMode,bool & _rValue)93     bool QueryRecordChangesProtectionState( RedliningMode _eMode, bool& _rValue )
94     {
95         bool bRet = false;
96         if (_eMode != RL_NONE)
97         {
98             sal_uInt16 nSlot = _eMode == RL_WRITER ? FN_REDLINE_PROTECT : SID_CHG_PROTECT;
99             bRet = QueryState( nSlot, _rValue );
100         }
101         return bRet;
102     }
103 
104 
QueryRecordChangesState(RedliningMode _eMode,bool & _rValue)105     bool QueryRecordChangesState( RedliningMode _eMode, bool& _rValue )
106     {
107         bool bRet = false;
108         if (_eMode != RL_NONE)
109         {
110             sal_uInt16 nSlot = _eMode == RL_WRITER ? FN_REDLINE_ON : FID_CHG_RECORD;
111             bRet = QueryState( nSlot, _rValue );
112         }
113         return bRet;
114     }
115 }
116 
117 
118 //////////////////////////////////////////////////////////////////////
119 
120 
lcl_GetPassword(Window * pParent,bool bProtect,String & rPassword)121 static short lcl_GetPassword(
122     Window *pParent,
123     bool bProtect,
124     /*out*/String &rPassword )
125 {
126     bool bRes = false;
127     SfxPasswordDialog aPasswdDlg( pParent );
128     const String aTitle( SfxResId( bProtect ? RID_SFX_PROTECT_RECORDS : RID_SFX_UNPROTECT_RECORDS ) );
129     aPasswdDlg.SetText( aTitle );
130     aPasswdDlg.SetMinLen( 1 );
131     if (bProtect)
132         aPasswdDlg.ShowExtras( SHOWEXTRAS_CONFIRM );
133     if (RET_OK == aPasswdDlg.Execute() && aPasswdDlg.GetPassword().Len() > 0)
134     {
135         rPassword = aPasswdDlg.GetPassword();
136         bRes = true;
137     }
138     return bRes;
139 }
140 
141 
lcl_IsPasswordCorrect(const String & rPassword)142 static bool lcl_IsPasswordCorrect( const String &rPassword )
143 {
144     bool bRes = false;
145 
146     SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
147     uno::Sequence< sal_Int8 >   aPasswordHash;
148     pCurDocShell->GetProtectionHash( aPasswordHash );
149 
150     // check if supplied password was correct
151     uno::Sequence< sal_Int8 > aNewPasswd( aPasswordHash );
152     SvPasswordHelper::GetHashPassword( aNewPasswd, rPassword );
153     if (SvPasswordHelper::CompareHashPassword( aPasswordHash, rPassword ))
154         bRes = true;    // password was correct
155     else
156         InfoBox( NULL, String( SfxResId( RID_SFX_INCORRECT_PASSWORD ) ) ).Execute();
157 
158     return bRes;
159 }
160 
161 
162 //////////////////////////////////////////////////////////////////////
163 
164 
165 struct SfxSecurityPage_Impl
166 {
167     SfxSecurityPage &   m_rMyTabPage;
168 
169     FixedLine           m_aNewPasswordToOpenFL;
170     FixedText           m_aNewPasswordToOpenFT;
171     Edit                m_aNewPasswordToOpenED;
172     FixedText           m_aConfirmPasswordToOpenFT;
173     Edit                m_aConfirmPasswordToOpenED;
174     FixedText           m_aNewPasswordInfoFT;
175 
176     FixedLine           m_aNewPasswordToModifyFL;
177     FixedText           m_aNewPasswordToModifyFT;
178     Edit                m_aNewPasswordToModifyED;
179     FixedText           m_aConfirmPasswordToModifyFT;
180     Edit                m_aConfirmPasswordToModifyED;
181 
182     FixedLine           m_aOptionsFL;
183     CheckBox            m_aOpenReadonlyCB;
184     CheckBox            m_aRecordChangesCB;         // for record changes
185     PushButton          m_aChangeProtectionPB;      // for record changes
186     String              m_aProtectSTR;              // for record changes
187     String              m_aUnProtectSTR;            // for record changes
188     RedliningMode       m_eRedlingMode;             // for record changes
189 
190     bool                m_bOrigPasswordIsConfirmed;
191     bool                m_bNewPasswordIsValid;
192     String              m_aNewPassword;
193 
194     String              m_aEndRedliningWarning;
195     bool                m_bEndRedliningWarningDone;
196 
197     DECL_LINK( RecordChangesCBToggleHdl, void* );
198     DECL_LINK( ChangeProtectionPBHdl, void* );
199 
200     SfxSecurityPage_Impl( SfxSecurityPage &rDlg, const SfxItemSet &rItemSet );
201     ~SfxSecurityPage_Impl();
202 
203     sal_Bool    FillItemSet_Impl( SfxItemSet & );
204     void    Reset_Impl( const SfxItemSet & );
205 };
206 
207 
SfxSecurityPage_Impl(SfxSecurityPage & rTabPage,const SfxItemSet &)208 SfxSecurityPage_Impl::SfxSecurityPage_Impl( SfxSecurityPage &rTabPage, const SfxItemSet & ) :
209     m_rMyTabPage                    (rTabPage),
210     m_aNewPasswordToOpenFL          (&rTabPage, SfxResId( PASSWORD_TO_OPEN_FL ) ),
211     m_aNewPasswordToOpenFT          (&rTabPage, SfxResId( PASSWORD_TO_OPEN_FT ) ),
212     m_aNewPasswordToOpenED          (&rTabPage, SfxResId( PASSWORD_TO_OPEN_ED ) ),
213     m_aConfirmPasswordToOpenFT      (&rTabPage, SfxResId( CONFIRM_PASSWORD_TO_OPEN_FT ) ),
214     m_aConfirmPasswordToOpenED      (&rTabPage, SfxResId( CONFIRM_PASSWORD_TO_OPEN_ED ) ),
215     m_aNewPasswordInfoFT            (&rTabPage, SfxResId( PASSWORD_INFO_FT ) ),
216     m_aNewPasswordToModifyFL        (&rTabPage, SfxResId( PASSWORD_TO_MODIFY_FL ) ),
217     m_aNewPasswordToModifyFT        (&rTabPage, SfxResId( PASSWORD_TO_MODIFY_FT ) ),
218     m_aNewPasswordToModifyED        (&rTabPage, SfxResId( PASSWORD_TO_MODIFY_ED ) ),
219     m_aConfirmPasswordToModifyFT    (&rTabPage, SfxResId( CONFIRM_PASSWORD_TO_MODIFY_FT ) ),
220     m_aConfirmPasswordToModifyED    (&rTabPage, SfxResId( CONFIRM_PASSWORD_TO_MODIFY_ED ) ),
221     m_aOptionsFL                    (&rTabPage, SfxResId( OPTIONS_FL ) ),
222     m_aOpenReadonlyCB               (&rTabPage, SfxResId( OPEN_READONLY_CB ) ),
223     m_aRecordChangesCB              (&rTabPage, SfxResId( RECORD_CHANGES_CB ) ),
224     m_aChangeProtectionPB           (&rTabPage, SfxResId( CHANGE_PROTECTION_PB ) ),
225     m_aProtectSTR                   ( SfxResId( STR_PROTECT ) ),
226     m_aUnProtectSTR                 ( SfxResId( STR_UNPROTECT ) ),
227     m_eRedlingMode                  ( RL_NONE ),
228     m_bOrigPasswordIsConfirmed      ( false ),
229     m_bNewPasswordIsValid           ( false ),
230     m_aEndRedliningWarning          ( SfxResId( STR_END_REDLINING_WARNING ) ),
231     m_bEndRedliningWarningDone      ( false )
232 {
233     m_aChangeProtectionPB.SetText( m_aProtectSTR );
234     // adjust button width if necessary
235     long nBtnTextWidth = 0;
236     long nTemp = m_aChangeProtectionPB.GetCtrlTextWidth( m_aChangeProtectionPB.GetText() );
237     if (nTemp > nBtnTextWidth)
238         nBtnTextWidth = nTemp;
239 
240     // force toggle hdl called before visual change of checkbox
241     m_aRecordChangesCB.SetStyle( m_aRecordChangesCB.GetStyle() | WB_EARLYTOGGLE );
242     m_aRecordChangesCB.SetToggleHdl( LINK( this, SfxSecurityPage_Impl, RecordChangesCBToggleHdl ) );
243     m_aChangeProtectionPB.SetClickHdl( LINK( this, SfxSecurityPage_Impl, ChangeProtectionPBHdl ) );
244 
245 
246     // #i112277: for the time being (OOO 3.3) the following options should not
247     // be available. In the long run however it is planned to implement the yet
248     // missing functionality. Thus now we hide them and move the remaining ones up.
249     m_aNewPasswordToOpenFL.Hide();
250     m_aNewPasswordToOpenFT.Hide();
251     m_aNewPasswordToOpenED.Hide();
252     m_aConfirmPasswordToOpenFT.Hide();
253     m_aConfirmPasswordToOpenED.Hide();
254     m_aNewPasswordInfoFT.Hide();
255     m_aNewPasswordToModifyFL.Hide();
256     m_aNewPasswordToModifyFT.Hide();
257     m_aNewPasswordToModifyED.Hide();
258     m_aConfirmPasswordToModifyFT.Hide();
259     m_aConfirmPasswordToModifyED.Hide();
260     const long nDelta = m_aOptionsFL.GetPosPixel().Y() - m_aNewPasswordToOpenFL.GetPosPixel().Y();
261     Point aPos;
262     aPos = m_aOptionsFL.GetPosPixel();
263     aPos.Y() -= nDelta;
264     m_aOptionsFL.SetPosPixel( aPos );
265     aPos = m_aOpenReadonlyCB.GetPosPixel();
266     aPos.Y() -= nDelta;
267     m_aOpenReadonlyCB.SetPosPixel( aPos );
268     aPos = m_aRecordChangesCB.GetPosPixel();
269     aPos.Y() -= nDelta;
270     m_aRecordChangesCB.SetPosPixel( aPos );
271     aPos = m_aChangeProtectionPB.GetPosPixel();
272     aPos.Y() -= nDelta;
273     m_aChangeProtectionPB.SetPosPixel( aPos );
274 }
275 
276 
~SfxSecurityPage_Impl()277 SfxSecurityPage_Impl::~SfxSecurityPage_Impl()
278 {
279 }
280 
281 
FillItemSet_Impl(SfxItemSet &)282 sal_Bool SfxSecurityPage_Impl::FillItemSet_Impl( SfxItemSet & )
283 {
284     bool bModified = false;
285 
286     SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
287     if (pCurDocShell&& !pCurDocShell->IsReadOnly())
288     {
289         if (m_eRedlingMode != RL_NONE )
290         {
291             const bool bDoRecordChanges     = m_aRecordChangesCB.IsChecked();
292             const bool bDoChangeProtection  = m_aChangeProtectionPB.GetText() != m_aProtectSTR;
293 
294             // sanity checks
295             DBG_ASSERT( bDoRecordChanges || !bDoChangeProtection, "no change recording should imply no change protection" );
296             DBG_ASSERT( bDoChangeProtection || !bDoRecordChanges, "no change protection should imply no change recording" );
297             DBG_ASSERT( !bDoChangeProtection || m_aNewPassword.Len() > 0, "change protection should imply password length is > 0" );
298             DBG_ASSERT( bDoChangeProtection || m_aNewPassword.Len() == 0, "no change protection should imply password length is 0" );
299 
300             // change recording
301             if (bDoRecordChanges != pCurDocShell->IsChangeRecording())
302             {
303                 pCurDocShell->SetChangeRecording( bDoRecordChanges );
304                 bModified = true;
305             }
306 
307             // change record protection
308             if (m_bNewPasswordIsValid &&
309                 bDoChangeProtection != pCurDocShell->HasChangeRecordProtection())
310             {
311                 DBG_ASSERT( !bDoChangeProtection || bDoRecordChanges,
312                         "change protection requires record changes to be active!" );
313                 pCurDocShell->SetProtectionPassword( m_aNewPassword );
314                 bModified = true;
315             }
316         }
317 
318         // open read-only?
319         const sal_Bool bDoOpenReadonly = m_aOpenReadonlyCB.IsChecked();
320         if (pCurDocShell->HasSecurityOptOpenReadOnly() &&
321             bDoOpenReadonly != pCurDocShell->IsSecurityOptOpenReadOnly())
322         {
323             pCurDocShell->SetSecurityOptOpenReadOnly( bDoOpenReadonly );
324             bModified = true;
325         }
326     }
327 
328     return bModified;
329 }
330 
331 
Reset_Impl(const SfxItemSet &)332 void SfxSecurityPage_Impl::Reset_Impl( const SfxItemSet & )
333 {
334     SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
335 
336     String sNewText = m_aProtectSTR;
337     if (!pCurDocShell)
338     {
339         // no doc -> hide document settings
340         m_aOpenReadonlyCB.Disable();
341         m_aRecordChangesCB.Disable();
342         m_aChangeProtectionPB.Disable();
343     }
344     else
345     {
346         bool bIsHTMLDoc = false;
347         SfxViewShell* pViewSh = SfxViewShell::Current();
348         if (pViewSh)
349         {
350             const SfxPoolItem* pItem;
351             SfxDispatcher* pDisp = pViewSh->GetDispatcher();
352             if (SFX_ITEM_AVAILABLE <= pDisp->QueryState( SID_HTML_MODE, pItem ))
353             {
354                 sal_uInt16 nMode = static_cast< const SfxUInt16Item* >( pItem )->GetValue();
355                 bIsHTMLDoc = ( ( nMode & HTMLMODE_ON ) != 0 );
356             }
357         }
358 
359         sal_Bool bIsReadonly = pCurDocShell->IsReadOnly();
360         if (pCurDocShell->HasSecurityOptOpenReadOnly() && !bIsHTMLDoc)
361         {
362             m_aOpenReadonlyCB.Check( pCurDocShell->IsSecurityOptOpenReadOnly() );
363             m_aOpenReadonlyCB.Enable( !bIsReadonly );
364         }
365         else
366             m_aOpenReadonlyCB.Disable();
367 
368         bool bRecordChanges;
369         if (QueryRecordChangesState( RL_WRITER, bRecordChanges ) && !bIsHTMLDoc)
370             m_eRedlingMode = RL_WRITER;
371         else if (QueryRecordChangesState( RL_CALC, bRecordChanges ))
372             m_eRedlingMode = RL_CALC;
373         else
374             m_eRedlingMode = RL_NONE;
375 
376         if (m_eRedlingMode != RL_NONE)
377         {
378             bool bProtection;
379             QueryRecordChangesProtectionState( m_eRedlingMode, bProtection );
380 
381             m_aChangeProtectionPB.Enable( !bIsReadonly );
382             // set the right text
383             if (bProtection)
384                 sNewText = m_aUnProtectSTR;
385 
386             m_aRecordChangesCB.Check( bRecordChanges );
387             m_aRecordChangesCB.Enable( /*!bProtection && */!bIsReadonly );
388 
389             m_bOrigPasswordIsConfirmed = true;   // default case if no password is set
390             uno::Sequence< sal_Int8 > aPasswordHash;
391             // check if password is available
392             if (pCurDocShell->GetProtectionHash( aPasswordHash ) &&
393                 aPasswordHash.getLength() > 0)
394                 m_bOrigPasswordIsConfirmed = false;  // password found, needs to be confirmed later on
395         }
396         else
397         {
398             // A Calc document that is shared will have 'm_eRedlingMode == RL_NONE'
399             // In shared documents change recording and protection must be disabled,
400             // similar to documents that do not support change recording at all.
401             m_aRecordChangesCB.Check( sal_False );
402             m_aRecordChangesCB.Disable();
403             m_aChangeProtectionPB.Check( sal_False );
404             m_aChangeProtectionPB.Disable();
405         }
406     }
407 
408     m_aChangeProtectionPB.SetText( sNewText );
409 }
410 
411 
IMPL_LINK(SfxSecurityPage_Impl,RecordChangesCBToggleHdl,void *,EMPTYARG)412 IMPL_LINK( SfxSecurityPage_Impl, RecordChangesCBToggleHdl, void*, EMPTYARG )
413 {
414     // when change recording gets disabled protection must be disabled as well
415     if (!m_aRecordChangesCB.IsChecked())    // the new check state is already present, thus the '!'
416     {
417         bool bAlreadyDone = false;
418         if (!m_bEndRedliningWarningDone)
419         {
420 		    WarningBox aBox( m_rMyTabPage.GetParent(), WinBits(WB_YES_NO | WB_DEF_NO),
421                     m_aEndRedliningWarning );
422             if (aBox.Execute() != RET_YES)
423                 bAlreadyDone = true;
424             else
425                 m_bEndRedliningWarningDone = true;
426         }
427 
428         const bool bNeedPasssword = !m_bOrigPasswordIsConfirmed
429                 && m_aChangeProtectionPB.GetText() != m_aProtectSTR;
430         if (!bAlreadyDone && bNeedPasssword)
431         {
432             String aPasswordText;
433 
434             // dialog canceled or no password provided
435             if (!lcl_GetPassword( m_rMyTabPage.GetParent(), false, aPasswordText ))
436                 bAlreadyDone = true;
437 
438             // ask for password and if dialog is canceled or no password provided return
439             if (lcl_IsPasswordCorrect( aPasswordText ))
440                 m_bOrigPasswordIsConfirmed = true;
441             else
442                 bAlreadyDone = true;
443         }
444 
445         if (bAlreadyDone)
446             m_aRecordChangesCB.Check( true );     // restore original state
447         else
448         {
449             // remember required values to change protection and change recording in
450             // FillItemSet_Impl later on if password was correct.
451             m_bNewPasswordIsValid = true;
452             m_aNewPassword = String();
453 
454             m_aChangeProtectionPB.SetText( m_aProtectSTR );
455         }
456     }
457 
458     return 0;
459 }
460 
461 
IMPL_LINK(SfxSecurityPage_Impl,ChangeProtectionPBHdl,void *,EMPTYARG)462 IMPL_LINK( SfxSecurityPage_Impl, ChangeProtectionPBHdl, void*, EMPTYARG )
463 {
464     if (m_eRedlingMode == RL_NONE)
465         return 0;
466 
467     // the push button text is always the opposite of the current state. Thus:
468     const bool bCurrentProtection = m_aChangeProtectionPB.GetText() != m_aProtectSTR;
469 
470     // ask user for password (if still necessary)
471     String aPasswordText;
472     bool bNewProtection = !bCurrentProtection;
473     const bool bNeedPassword = bNewProtection || !m_bOrigPasswordIsConfirmed;
474     if (bNeedPassword)
475     {
476         // ask for password and if dialog is canceled or no password provided return
477         if (!lcl_GetPassword( m_rMyTabPage.GetParent(), bNewProtection, aPasswordText ))
478             return 0;
479 
480         // provided password still needs to be checked?
481         if (!bNewProtection && !m_bOrigPasswordIsConfirmed)
482         {
483             if (lcl_IsPasswordCorrect( aPasswordText ))
484                 m_bOrigPasswordIsConfirmed = true;
485             else
486                 return 0;
487         }
488     }
489     DBG_ASSERT( m_bOrigPasswordIsConfirmed, "ooops... this should not have happened!" );
490 
491     // remember required values to change protection and change recording in
492     // FillItemSet_Impl later on if password was correct.
493     m_bNewPasswordIsValid = true;
494     m_aNewPassword = bNewProtection? aPasswordText : String();
495 
496 //    // RecordChangesCB is enabled if protection is off
497 //    m_aRecordChangesCB.Enable( !bNewProtection );
498     m_aRecordChangesCB.Check( bNewProtection );
499     // toggle text of button "Protect" <-> "Unprotect"
500     m_aChangeProtectionPB.SetText( bNewProtection ? m_aUnProtectSTR : m_aProtectSTR );
501 
502     return 0;
503 }
504 
505 
506 //////////////////////////////////////////////////////////////////////
507 
508 
Create(Window * pParent,const SfxItemSet & rItemSet)509 SfxTabPage* SfxSecurityPage::Create( Window * pParent, const SfxItemSet & rItemSet )
510 {
511     return new SfxSecurityPage( pParent, rItemSet );
512 }
513 
514 
SfxSecurityPage(Window * pParent,const SfxItemSet & rItemSet)515 SfxSecurityPage::SfxSecurityPage( Window* pParent, const SfxItemSet& rItemSet ) :
516     SfxTabPage( pParent, SfxResId( TP_DOCINFOSECURITY ), rItemSet )
517 {
518     m_pImpl = std::auto_ptr< SfxSecurityPage_Impl >(new SfxSecurityPage_Impl( *this, rItemSet ));
519 
520     FreeResource();
521 }
522 
523 
~SfxSecurityPage()524 SfxSecurityPage::~SfxSecurityPage()
525 {
526 }
527 
528 
FillItemSet(SfxItemSet & rItemSet)529 sal_Bool SfxSecurityPage::FillItemSet( SfxItemSet & rItemSet )
530 {
531     bool bModified = false;
532     DBG_ASSERT( m_pImpl.get(), "implementation pointer is 0. Still in c-tor?" );
533     if (m_pImpl.get() != 0)
534         bModified =  m_pImpl->FillItemSet_Impl( rItemSet );
535     return bModified;
536 }
537 
538 
Reset(const SfxItemSet & rItemSet)539 void SfxSecurityPage::Reset( const SfxItemSet & rItemSet )
540 {
541     DBG_ASSERT( m_pImpl.get(), "implementation pointer is 0. Still in c-tor?" );
542     if (m_pImpl.get() != 0)
543         m_pImpl->Reset_Impl( rItemSet );
544 }
545 
546 
547 //////////////////////////////////////////////////////////////////////
548 
549 
550