1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <com/sun/star/uno/Reference.hxx>
32 #include <com/sun/star/document/XDocumentProperties.hpp>
33 #include <com/sun/star/document/UpdateDocMode.hpp>
34 #include <com/sun/star/frame/XLayoutManager.hpp>
35 #include <com/sun/star/embed/ElementModes.hpp>
36 #include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
37 #include <com/sun/star/beans/XFastPropertySet.hpp>
38 #include <vcl/msgbox.hxx>
39 #include <svl/style.hxx>
40 #include <vcl/wrkwin.hxx>
42 #include <svl/stritem.hxx>
43 #include <svl/intitem.hxx>
44 #include <svl/rectitem.hxx>
45 #include <svl/eitem.hxx>
46 #include <svl/urihelper.hxx>
47 #include <svl/ctloptions.hxx>
48 #include <comphelper/storagehelper.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <unotools/securityoptions.hxx>
51 #include <svtools/sfxecode.hxx>
52 #include <svtools/ehdl.hxx>
53 #include <tools/datetime.hxx>
54 #include <rtl/logfile.hxx>
57 #include <unotools/saveopt.hxx>
58 #include <unotools/useroptions.hxx>
59 #include <unotools/localfilehelper.hxx>
60 #include <vcl/virdev.hxx>
61 #include <vcl/oldprintadaptor.hxx>
63 #include <sfx2/app.hxx>
64 #include "sfx2/sfxresid.hxx"
65 #include "appdata.hxx"
66 #include <sfx2/dinfdlg.hxx>
68 #include <sfx2/docfac.hxx>
69 #include <sfx2/viewsh.hxx>
70 #include <sfx2/objsh.hxx>
71 #include "objshimp.hxx"
72 #include <sfx2/evntconf.hxx>
73 #include "sfx2/sfxhelp.hxx"
74 #include <sfx2/dispatch.hxx>
75 #include <sfx2/printer.hxx>
76 #include "sfx2/basmgr.hxx"
77 #include <sfx2/viewfrm.hxx>
78 #include <sfx2/doctempl.hxx>
80 #include <sfx2/sfxbasemodel.hxx>
81 #include <sfx2/docfile.hxx>
82 #include <sfx2/request.hxx>
83 #include "openflag.hxx"
84 #include "querytemplate.hxx"
86 using namespace ::com::sun::star
;
87 using namespace ::com::sun::star::uno
;
89 //====================================================================
92 bool operator> (const util::DateTime
& i_rLeft
, const util::DateTime
& i_rRight
)
94 if ( i_rLeft
.Year
!= i_rRight
.Year
)
95 return i_rLeft
.Year
> i_rRight
.Year
;
97 if ( i_rLeft
.Month
!= i_rRight
.Month
)
98 return i_rLeft
.Month
> i_rRight
.Month
;
100 if ( i_rLeft
.Day
!= i_rRight
.Day
)
101 return i_rLeft
.Day
> i_rRight
.Day
;
103 if ( i_rLeft
.Hours
!= i_rRight
.Hours
)
104 return i_rLeft
.Hours
> i_rRight
.Hours
;
106 if ( i_rLeft
.Minutes
!= i_rRight
.Minutes
)
107 return i_rLeft
.Minutes
> i_rRight
.Minutes
;
109 if ( i_rLeft
.Seconds
!= i_rRight
.Seconds
)
110 return i_rLeft
.Seconds
> i_rRight
.Seconds
;
112 if ( i_rLeft
.HundredthSeconds
!= i_rRight
.HundredthSeconds
)
113 return i_rLeft
.HundredthSeconds
> i_rRight
.HundredthSeconds
;
118 ::boost::shared_ptr
<GDIMetaFile
>
119 SfxObjectShell::GetPreviewMetaFile( sal_Bool bFullContent
) const
121 return CreatePreviewMetaFile_Impl( bFullContent
);
124 ::boost::shared_ptr
<GDIMetaFile
>
125 SfxObjectShell::CreatePreviewMetaFile_Impl( sal_Bool bFullContent
) const
127 // DoDraw can only be called when no printing is done, otherwise
128 // the printer may be turned off
129 SfxViewFrame
*pFrame
= SfxViewFrame::GetFirst( this );
130 if ( pFrame
&& pFrame
->GetViewShell() &&
131 pFrame
->GetViewShell()->GetPrinter() &&
132 pFrame
->GetViewShell()->GetPrinter()->IsPrinting() )
133 return ::boost::shared_ptr
<GDIMetaFile
>();
135 ::boost::shared_ptr
<GDIMetaFile
> pFile(new GDIMetaFile
);
137 VirtualDevice aDevice
;
138 aDevice
.EnableOutput( sal_False
);
140 MapMode
aMode( ((SfxObjectShell
*)this)->GetMapUnit() );
141 aDevice
.SetMapMode( aMode
);
142 pFile
->SetPrefMapMode( aMode
);
148 nAspect
= ASPECT_CONTENT
;
149 aTmpSize
= GetVisArea( nAspect
).GetSize();
153 nAspect
= ASPECT_THUMBNAIL
;
154 aTmpSize
= ((SfxObjectShell
*)this)->GetFirstPageSize();
157 pFile
->SetPrefSize( aTmpSize
);
158 DBG_ASSERT( aTmpSize
.Height()*aTmpSize
.Width(),
159 "size of first page is 0, overload GetFirstPageSize or set vis-area!" );
161 pFile
->Record( &aDevice
);
164 SvtCTLOptions aCTLOptions
;
165 if ( SvtCTLOptions::NUMERALS_HINDI
== aCTLOptions
.GetCTLTextNumerals() )
166 eLang
= LANGUAGE_ARABIC_SAUDI_ARABIA
;
167 else if ( SvtCTLOptions::NUMERALS_ARABIC
== aCTLOptions
.GetCTLTextNumerals() )
168 eLang
= LANGUAGE_ENGLISH
;
170 eLang
= (LanguageType
) Application::GetSettings().GetLanguage();
172 aDevice
.SetDigitLanguage( eLang
);
175 RTL_LOGFILE_PRODUCT_CONTEXT( aLog
, "PERFORMANCE SfxObjectShell::CreatePreviewMetaFile_Impl" );
176 ((SfxObjectShell
*)this)->DoDraw( &aDevice
, Point(0,0), aTmpSize
, JobSetup(), nAspect
);
183 //====================================================================
185 void SfxObjectShell::UpdateDocInfoForSave()
187 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
189 // clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security')
190 if ( SvtSecurityOptions().IsOptionSet(
191 SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO
) )
193 xDocProps
->resetUserData( ::rtl::OUString() );
195 else if ( IsModified() )
197 String aUserName
= SvtUserOptions().GetFullName();
198 if ( !IsUseUserData() )
200 // remove all data pointing to the current user
201 if (xDocProps
->getAuthor().equals(aUserName
)) {
202 xDocProps
->setAuthor( ::rtl::OUString() );
204 xDocProps
->setModifiedBy( ::rtl::OUString() );
205 if (xDocProps
->getPrintedBy().equals(aUserName
)) {
206 xDocProps
->setPrintedBy( ::rtl::OUString() );
211 // update ModificationAuthor, revision and editing time
212 ::DateTime
now( ::DateTime::SYSTEM
);
213 xDocProps
->setModificationDate( util::DateTime(
214 now
.Get100Sec(), now
.GetSec(), now
.GetMin(),
215 now
.GetHour(), now
.GetDay(), now
.GetMonth(),
217 xDocProps
->setModifiedBy( aUserName
);
218 if ( !HasName() || pImp
->bIsSaving
)
219 // QUESTION: not in case of "real" SaveAs as this is meant to create a new document
220 UpdateTime_Impl( xDocProps
);
225 //--------------------------------------------------------------------
228 lcl_add(util::Duration
& rDur
, Time
const& rTime
)
230 // here we don't care about overflow: rDur is converted back to seconds
231 // anyway, and Time cannot store more than ~4000 hours
232 rDur
.Hours
+= rTime
.GetHour();
233 rDur
.Minutes
+= rTime
.GetMin();
234 rDur
.Seconds
+= rTime
.GetSec();
237 // Update the processing time
238 void SfxObjectShell::UpdateTime_Impl(
239 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
)
241 // Get old time from documentinfo
242 const sal_Int32 secs
= i_xDocProps
->getEditingDuration();
243 util::Duration
editDuration(sal_False
, 0, 0, 0,
244 secs
/3600, (secs
%3600)/60, secs
%60, 0);
246 // Initialize some local member! Its neccessary for wollow operations!
247 DateTime
aNow( DateTime::SYSTEM
); // Date and time at current moment
248 Time
n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation
249 sal_uIntPtr nDays
= 0 ; // Count of days between now and last editing
250 Time
nAddTime (0) ; // Value to add on aOldTime
252 // Safe impossible cases!
253 // User has changed time to the past between last editing and now ... its not possible!!!
254 DBG_ASSERT( !(aNow
.GetDate()<pImp
->nTime
.GetDate()), "Timestamp of last change is in the past ?!..." );
256 // Do the follow only, if user has NOT changed time to the past.
257 // Else add a time of 0 to aOldTime ... !!!
258 if (aNow
.GetDate()>=pImp
->nTime
.GetDate())
260 // Get count of days last editing.
261 nDays
= aNow
.GetSecFromDateTime(pImp
->nTime
.GetDate())/86400 ;
265 // If no day between now and last editing - calculate time directly.
266 nAddTime
= (const Time
&)aNow
- (const Time
&)pImp
->nTime
;
269 // If time of working without save greater then 1 month (!) ....
270 // we add 0 to aOldTime!
273 // If 1 or up to 31 days between now and last editing - calculate time indirectly.
274 // nAddTime = (24h - nTime) + (nDays * 24h) + aNow
276 nAddTime
= nDays
*n24Time
.GetTime() ;
277 nAddTime
+= n24Time
-(const Time
&)pImp
->nTime
;
281 lcl_add(editDuration
, nAddTime
);
286 const sal_Int32
newSecs( (editDuration
.Hours
*3600)
287 + (editDuration
.Minutes
*60) + editDuration
.Seconds
);
288 i_xDocProps
->setEditingDuration(newSecs
);
289 i_xDocProps
->setEditingCycles(i_xDocProps
->getEditingCycles() + 1);
291 catch (const lang::IllegalArgumentException
&)
297 //--------------------------------------------------------------------
299 SfxDocumentInfoDialog
* SfxObjectShell::CreateDocumentInfoDialog
302 const SfxItemSet
& rSet
305 return new SfxDocumentInfoDialog(pParent
, rSet
);
308 //--------------------------------------------------------------------
310 SfxStyleSheetBasePool
* SfxObjectShell::GetStyleSheetPool()
315 void SfxObjectShell::SetOrganizerSearchMask(
316 SfxStyleSheetBasePool
* pStylePool
) const
318 pStylePool
->SetSearchMask(
319 SFX_STYLE_FAMILY_ALL
,
320 SFXSTYLEBIT_USERDEF
| SFXSTYLEBIT_USED
);
323 //--------------------------------------------------------------------
325 sal_uInt16
SfxObjectShell::GetContentCount(sal_uInt16 nIdx
)
330 return DEF_CONTENT_COUNT
;
333 SfxStyleSheetBasePool
*pStylePool
= GetStyleSheetPool();
336 SetOrganizerSearchMask(pStylePool
);
337 return pStylePool
->Count();
346 //--------------------------------------------------------------------
347 //TODO/CLEANUP: remove this method
348 void SfxObjectShell::TriggerHelpPI(sal_uInt16 nIdx1
, sal_uInt16 nIdx2
)
350 if(nIdx1
==CONTENT_STYLE
&& nIdx2
!= INDEX_IGNORE
) //StyleSheets
352 SfxStyleSheetBasePool
*pStylePool
= GetStyleSheetPool();
353 SetOrganizerSearchMask(pStylePool
);
357 sal_Bool
SfxObjectShell::CanHaveChildren(sal_uInt16 nIdx1
, sal_uInt16 nIdx2
)
364 return INDEX_IGNORE
== nIdx2
|| !GetStyleSheetPool() ? false : true;
371 //--------------------------------------------------------------------
373 void SfxObjectShell::GetContent(String
&rText
,
374 Bitmap
&rClosedBitmap
,
375 Bitmap
&rOpenedBitmap
,
387 sal_uInt16 nTextResId
= 0;
388 sal_uInt16 nClosedBitmapResId
= 0; // evtl. sp"ater mal unterschiedliche
389 sal_uInt16 nOpenedBitmapResId
= 0; // " " " "
393 nTextResId
= STR_STYLES
;
394 nClosedBitmapResId
= BMP_STYLES_CLOSED
;
395 nOpenedBitmapResId
= BMP_STYLES_OPENED
;
398 nTextResId
= STR_MACROS
;
399 nClosedBitmapResId
= BMP_STYLES_CLOSED
;
400 nOpenedBitmapResId
= BMP_STYLES_OPENED
;
406 rText
= String(SfxResId(nTextResId
));
407 rClosedBitmap
= Bitmap(SfxResId(nClosedBitmapResId
));
408 rOpenedBitmap
= Bitmap(SfxResId(nOpenedBitmapResId
));
415 SfxStyleSheetBasePool
*pStylePool
= GetStyleSheetPool();
416 SetOrganizerSearchMask(pStylePool
);
417 SfxStyleSheetBase
*pStyle
= (*pStylePool
)[i
];
418 rText
= pStyle
->GetName();
419 bCanDel
=((pStyle
->GetMask() & SFXSTYLEBIT_USERDEF
)
420 == SFXSTYLEBIT_USERDEF
);
421 rClosedBitmap
= rOpenedBitmap
=
422 GetStyleFamilyBitmap(pStyle
->GetFamily());
430 //--------------------------------------------------------------------
432 Bitmap
SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily
)
434 sal_uInt16 nResId
= 0;
437 case SFX_STYLE_FAMILY_CHAR
:
438 nResId
= BMP_STYLES_FAMILY1
;
440 case SFX_STYLE_FAMILY_PARA
:
441 nResId
= BMP_STYLES_FAMILY2
;
443 case SFX_STYLE_FAMILY_FRAME
:
444 nResId
= BMP_STYLES_FAMILY3
;
446 case SFX_STYLE_FAMILY_PAGE
:
447 nResId
= BMP_STYLES_FAMILY4
;
449 case SFX_STYLE_FAMILY_PSEUDO
:
450 case SFX_STYLE_FAMILY_ALL
:
455 return Bitmap(SfxResId(nResId
));
461 //--------------------------------------------------------------------
463 sal_Bool
SfxObjectShell::Insert(SfxObjectShell
&rSource
,
464 sal_uInt16 nSourceIdx1
,
465 sal_uInt16 nSourceIdx2
,
466 sal_uInt16
/*nSourceIdx3*/,
469 sal_uInt16
&/*nIdx3*/,
470 sal_uInt16
&/*nDeleted*/)
472 sal_Bool bRet
= sal_False
;
474 if (INDEX_IGNORE
== nIdx1
&& CONTENT_STYLE
== nSourceIdx1
)
475 nIdx1
= CONTENT_STYLE
;
477 if (CONTENT_STYLE
== nSourceIdx1
&& CONTENT_STYLE
== nIdx1
)
479 SfxStyleSheetBasePool
* pHisPool
= rSource
.GetStyleSheetPool();
480 SfxStyleSheetBasePool
* pMyPool
= GetStyleSheetPool();
481 SetOrganizerSearchMask(pHisPool
);
482 SetOrganizerSearchMask(pMyPool
);
483 SfxStyleSheetBase
* pHisSheet
= NULL
;
485 if ( pHisPool
&& pHisPool
->Count() > nSourceIdx2
)
486 pHisSheet
= (*pHisPool
)[nSourceIdx2
];
488 // Pasting is only needed if a style sheet is moved between
489 // different (!) Pools
491 if ( pHisSheet
&& pMyPool
!= pHisPool
)
493 if (INDEX_IGNORE
== nIdx2
)
495 nIdx2
= pMyPool
->Count();
498 // if such a template already exists: delete!
499 String
aOldName(pHisSheet
->GetName());
500 SfxStyleFamily eOldFamily
= pHisSheet
->GetFamily();
502 SfxStyleSheetBase
* pExist
= pMyPool
->Find(aOldName
, eOldFamily
);
503 sal_Bool bUsedOrUserDefined
;
507 pExist
->IsUsed() || pExist
->IsUserDefined();
508 if( ErrorHandler::HandleError(
509 *new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE
, aOldName
) )
510 != ERRCODE_BUTTON_OK
)
514 pMyPool
->Replace( *pHisSheet
, *pExist
);
515 SetModified( sal_True
);
516 nIdx2
= nIdx1
= INDEX_IGNORE
;
521 SfxStyleSheetBase
& rNewSheet
= pMyPool
->Make(
522 aOldName
, eOldFamily
,
523 pHisSheet
->GetMask(), nIdx2
);
525 // Fill the Itemset of the new template
526 rNewSheet
.GetItemSet().Set(pHisSheet
->GetItemSet());
528 // Who gets the new one as a Parent?
529 // Who is using the new one as Follow?
530 SfxStyleSheetBase
* pTestSheet
= pMyPool
->First();
533 if (pTestSheet
->GetFamily() == eOldFamily
&&
534 pTestSheet
->HasParentSupport() &&
535 pTestSheet
->GetParent() == aOldName
)
537 pTestSheet
->SetParent(aOldName
);
541 if (pTestSheet
->GetFamily() == eOldFamily
&&
542 pTestSheet
->HasFollowSupport() &&
543 pTestSheet
->GetFollow() == aOldName
)
545 pTestSheet
->SetFollow(aOldName
);
549 pTestSheet
= pMyPool
->Next();
552 rNewSheet
.IsUsed() || rNewSheet
.IsUserDefined();
555 // has a New Parent? if so, start search with the same name
556 if (pHisSheet
->HasParentSupport())
558 const String
& rParentName
= pHisSheet
->GetParent();
559 if (0 != rParentName
.Len())
561 SfxStyleSheetBase
* pParentOfNew
=
562 pMyPool
->Find(rParentName
, eOldFamily
);
564 rNewSheet
.SetParent(rParentName
);
568 // Has the new got a Follow? if so start search
569 // with the same name.
570 if (pHisSheet
->HasFollowSupport())
572 const String
& rFollowName
= pHisSheet
->GetFollow();
573 if (0 != rFollowName
.Len())
575 SfxStyleSheetBase
* pFollowOfNew
=
576 pMyPool
->Find(rFollowName
, eOldFamily
);
578 rNewSheet
.SetFollow(rFollowName
);
582 SetModified( sal_True
);
583 if( !bUsedOrUserDefined
) nIdx2
= nIdx1
= INDEX_IGNORE
;
594 //--------------------------------------------------------------------
596 sal_Bool
SfxObjectShell::Remove
603 sal_Bool bRet
= sal_False
;
605 if (CONTENT_STYLE
== nIdx1
)
607 SfxStyleSheetBasePool
* pMyPool
= GetStyleSheetPool();
609 SetOrganizerSearchMask(pMyPool
);
611 SfxStyleSheetBase
* pMySheet
= (*pMyPool
)[nIdx2
];
612 String
aName(pMySheet
->GetName());
614 SfxStyleFamily eFamily
= pMySheet
->GetFamily();
615 pMyPool
->Remove(pMySheet
);
618 SfxStyleSheetBase
* pTestSheet
= pMyPool
->First();
621 if (pTestSheet
->GetFamily() == eFamily
&&
622 pTestSheet
->HasParentSupport() &&
623 pTestSheet
->GetParent() == aName
)
625 pTestSheet
->SetParent(aEmpty
); // Remove link
628 if (pTestSheet
->GetFamily() == eFamily
&&
629 pTestSheet
->HasFollowSupport() &&
630 pTestSheet
->GetFollow() == aName
)
632 pTestSheet
->SetFollow(aEmpty
); // Remove link
635 pTestSheet
= pMyPool
->Next();
638 SetModified( sal_True
);
644 //--------------------------------------------------------------------
646 sal_Bool
SfxObjectShell::Print
650 sal_uInt16
/*nIdx2*/,
651 sal_uInt16
/*nIdx3*/,
652 const String
* pObjectName
659 SfxStyleSheetBasePool
*pStylePool
= GetStyleSheetPool();
660 SetOrganizerSearchMask(pStylePool
);
661 SfxStyleSheetIterator
* pIter
= pStylePool
->CreateIterator(
662 pStylePool
->GetSearchFamily(), pStylePool
->GetSearchMask() );
663 SfxStyleSheetBase
*pStyle
= pIter
->First();
667 // prepare adaptor for old style StartPage/EndPage printing
668 boost::shared_ptr
< Printer
> pPrinter( new Printer( rPrt
.GetJobSetup() ) );
669 vcl::OldStylePrintAdaptor
* pAdaptor
= new vcl::OldStylePrintAdaptor( pPrinter
);
670 boost::shared_ptr
< vcl::PrinterController
> pController( pAdaptor
);
672 pAdaptor
->StartPage();
674 pPrinter
->SetMapMode(MapMode(MAP_10TH_MM
));
675 Font
aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64)); // 18pt
676 aFont
.SetWeight(WEIGHT_BOLD
);
677 pPrinter
->SetFont(aFont
);
678 const Size
aPageSize(pPrinter
->GetOutputSize());
679 const sal_uInt16 nXIndent
= 200;
680 sal_uInt16 nYIndent
= 200;
681 Point
aOutPos(nXIndent
, nYIndent
);
682 String
aHeader(SfxResId(STR_PRINT_STYLES_HEADER
));
684 aHeader
+= *pObjectName
;
686 aHeader
+= GetTitle();
687 long nTextHeight( pPrinter
->GetTextHeight() );
688 pPrinter
->DrawText(aOutPos
, aHeader
);
689 aOutPos
.Y() += nTextHeight
;
690 aOutPos
.Y() += nTextHeight
/2;
691 aFont
.SetSize(Size(0, 35)); // 10pt
694 // print template name
695 String
aStr(pStyle
->GetName());
696 aFont
.SetWeight(WEIGHT_BOLD
);
697 pPrinter
->SetFont(aFont
);
698 nTextHeight
= pPrinter
->GetTextHeight();
699 // check for new page
700 if ( aOutPos
.Y() + nTextHeight
*2 >
701 aPageSize
.Height() - (long) nYIndent
)
704 pAdaptor
->StartPage();
705 aOutPos
.Y() = nYIndent
;
707 pPrinter
->DrawText(aOutPos
, aStr
);
708 aOutPos
.Y() += nTextHeight
;
710 // print template description
711 aFont
.SetWeight(WEIGHT_NORMAL
);
712 pPrinter
->SetFont(aFont
);
713 aStr
= pStyle
->GetDescription();
714 const char cDelim
= ' ';
715 sal_uInt16 nStart
= 0, nIdx
= 0;
717 nTextHeight
= pPrinter
->GetTextHeight();
718 // break text into lines
719 while(nIdx
< aStr
.Len())
721 sal_uInt16 nOld
= nIdx
;
723 nIdx
= aStr
.Search(cDelim
, nStart
);
724 nTextWidth
= pPrinter
->GetTextWidth(aStr
, nStart
, nIdx
-nStart
);
725 while(nIdx
!= STRING_NOTFOUND
&&
726 aOutPos
.X() + nTextWidth
<
727 aPageSize
.Width() - (long) nXIndent
)
730 nIdx
= aStr
.Search(cDelim
, nIdx
+1);
731 nTextWidth
= pPrinter
->GetTextWidth(aStr
, nStart
, nIdx
-nStart
);
733 String
aTmp(aStr
, nStart
, nIdx
== STRING_NOTFOUND
?
738 nStart
= nOld
+1; // trailing space
742 sal_uInt16 nChar
= 1;
744 nStart
+ nChar
< aStr
.Len() &&
745 aOutPos
.X() + pPrinter
->GetTextWidth(
746 aStr
, nStart
, nChar
) <
747 aPageSize
.Width() - nXIndent
)
749 aTmp
= String(aStr
, nStart
, nChar
-1);
750 nIdx
= nStart
+ nChar
;
753 if ( aOutPos
.Y() + nTextHeight
*2 >
754 aPageSize
.Height() - nYIndent
)
757 pAdaptor
->StartPage();
758 aOutPos
.Y() = nYIndent
;
760 pPrinter
->DrawText(aOutPos
, aTmp
);
761 aOutPos
.Y() += pPrinter
->GetTextHeight();
763 pStyle
= pIter
->Next();
767 Printer::PrintJob( pController
, rPrt
.GetJobSetup() );
778 //--------------------------------------------------------------------
780 void SfxObjectShell::LoadStyles
782 SfxObjectShell
&rSource
/* the document template from which
783 the styles are to be loaded */
788 This method is called by the SFx if template styles are to be loaded.
789 Existing styles are in this case overwritten. The document has then to be
790 newly formatted. Therefore, the application of this method is usually
791 overloaded and its implementation is calling the implementation in
798 SfxStyleSheetBase
*pSource
;
799 SfxStyleSheetBase
*pDest
;
802 SfxStyleSheetBasePool
*pSourcePool
= rSource
.GetStyleSheetPool();
803 DBG_ASSERT(pSourcePool
, "Source-DocumentShell ohne StyleSheetPool");
804 SfxStyleSheetBasePool
*pMyPool
= GetStyleSheetPool();
805 DBG_ASSERT(pMyPool
, "Dest-DocumentShell ohne StyleSheetPool");
806 pSourcePool
->SetSearchMask(SFX_STYLE_FAMILY_ALL
, 0xffff);
807 Styles_Impl
*pFound
= new Styles_Impl
[pSourcePool
->Count()];
808 sal_uInt16 nFound
= 0;
810 SfxStyleSheetBase
*pSource
= pSourcePool
->First();
813 SfxStyleSheetBase
*pDest
=
814 pMyPool
->Find( pSource
->GetName(), pSource
->GetFamily() );
817 pDest
= &pMyPool
->Make( pSource
->GetName(),
818 pSource
->GetFamily(), pSource
->GetMask());
819 // Setting of Parents, the next style
821 pFound
[nFound
].pSource
= pSource
;
822 pFound
[nFound
].pDest
= pDest
;
824 pSource
= pSourcePool
->Next();
827 for ( sal_uInt16 i
= 0; i
< nFound
; ++i
)
829 pFound
[i
].pDest
->GetItemSet().PutExtended(pFound
[i
].pSource
->GetItemSet(), SFX_ITEM_DONTCARE
, SFX_ITEM_DEFAULT
);
830 if(pFound
[i
].pSource
->HasParentSupport())
831 pFound
[i
].pDest
->SetParent(pFound
[i
].pSource
->GetParent());
832 if(pFound
[i
].pSource
->HasFollowSupport())
833 pFound
[i
].pDest
->SetFollow(pFound
[i
].pSource
->GetParent());
838 //--------------------------------------------------------------------
840 void SfxObjectShell::UpdateFromTemplate_Impl( )
844 This internal method checks whether the document was created from a
845 template, and if this is newer than the document. If this is the case,
846 the user is asked if the Templates (StyleSheets) should be updated.
847 If this is answered positively, the StyleSheets are updated.
852 SfxMedium
*pFile
= GetMedium();
853 DBG_ASSERT( pFile
, "cannot UpdateFromTemplate without medium" );
857 if ( !::utl::LocalFileHelper::IsLocalFile( pFile
->GetName() ) )
858 // update only for documents loaded from the local file system
861 // only for own storage formats
862 uno::Reference
< embed::XStorage
> xDocStor
= pFile
->GetStorage();
863 if ( !pFile
->GetFilter() || !pFile
->GetFilter()->IsOwnFormat() )
866 SFX_ITEMSET_ARG( pFile
->GetItemSet(), pUpdateDocItem
, SfxUInt16Item
, SID_UPDATEDOCMODE
, sal_False
);
867 sal_Int16 bCanUpdateFromTemplate
= pUpdateDocItem
? pUpdateDocItem
->GetValue() : document::UpdateDocMode::NO_UPDATE
;
869 // created from template?
870 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
871 ::rtl::OUString
aTemplName( xDocProps
->getTemplateName() );
872 ::rtl::OUString
aTemplURL( xDocProps
->getTemplateURL() );
875 if ( !aTemplName
.isEmpty() || (!aTemplURL
.isEmpty() && !IsReadOnly()) )
877 // try to locate template, first using filename this must be done
878 // because writer global document uses this "great" idea to manage
879 // the templates of all parts in the master document but it is NOT
880 // an error if the template filename points not to a valid file
881 SfxDocumentTemplates aTempl
;
883 if ( !aTemplURL
.isEmpty() )
886 if( ::utl::LocalFileHelper::ConvertSystemPathToURL( aTemplURL
, GetMedium()->GetName(), aURL
) )
890 if( !aFoundName
.Len() && !aTemplName
.isEmpty() )
891 // if the template filename did not lead to success,
892 // try to get a file name for the logical template name
893 aTempl
.GetFull( String(), aTemplName
, aFoundName
);
896 if ( aFoundName
.Len() )
898 // check existence of template storage
899 aTemplURL
= aFoundName
;
900 sal_Bool bLoad
= sal_False
;
902 // should the document checked against changes in the template ?
903 if ( IsQueryLoadTemplate() )
905 // load document info of template
906 sal_Bool bOK
= sal_False
;
907 util::DateTime aTemplDate
;
910 Reference
< document::XStandaloneDocumentInfo
> xDocInfo (
911 ::comphelper::getProcessServiceFactory()->createInstance(
912 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
913 "com.sun.star.document.StandaloneDocumentInfo") ) ),
915 Reference
< beans::XFastPropertySet
> xSet( xDocInfo
,
917 xDocInfo
->loadFromURL( aTemplURL
);
918 Any aAny
= xSet
->getFastPropertyValue( WID_DATE_MODIFIED
);
919 ::com::sun::star::util::DateTime aTmp
;
920 if ( aAny
>>= aTemplDate
)
922 // get modify date from document info
926 catch (const Exception
&)
930 // if modify date was read successfully
933 // compare modify data of template with the last check date of the document
934 const util::DateTime
aInfoDate( xDocProps
->getTemplateDate() );
935 if ( aTemplDate
> aInfoDate
)
938 if( bCanUpdateFromTemplate
== document::UpdateDocMode::QUIET_UPDATE
939 || bCanUpdateFromTemplate
== document::UpdateDocMode::FULL_UPDATE
)
941 else if ( bCanUpdateFromTemplate
== document::UpdateDocMode::ACCORDING_TO_CONFIG
)
943 String
sMessage( SfxResId( STR_QRYTEMPL_MESSAGE
) );
944 sMessage
.SearchAndReplace( String::CreateFromAscii("$(ARG1)"), aTemplName
);
945 sfx2::QueryTemplateBox
aBox( GetDialogParent(), sMessage
);
946 if ( RET_YES
== aBox
.Execute() )
952 // user refuses, so don't ask again for this document
953 SetQueryLoadTemplate(sal_False
);
954 SetModified( sal_True
);
961 // styles should be updated, create document in organizer mode to read in the styles
963 SfxObjectShellLock xTemplDoc
= CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER
);
964 xTemplDoc
->DoInitNew(0);
966 // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended!
967 //xTemplDoc->SetBaseURL( aFoundName );
969 // TODO/LATER: make sure that we don't use binary templates!
970 SfxMedium
aMedium( aFoundName
, STREAM_STD_READ
);
971 if ( xTemplDoc
->LoadFrom( aMedium
) )
973 // transfer styles from xTemplDoc to this document
974 // TODO/MBA: make sure that no BaseURL is needed in *this* document
975 LoadStyles(*xTemplDoc
);
977 // remember date/time of check
978 xDocProps
->setTemplateDate(aTemplDate
);
979 // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format )
986 sal_Bool
SfxObjectShell::IsHelpDocument() const
988 const SfxFilter
* pFilter
= GetMedium()->GetFilter();
989 return ( pFilter
&& pFilter
->GetFilterName().CompareToAscii("writer_web_HTML_help") == COMPARE_EQUAL
);
992 void SfxObjectShell::ResetFromTemplate( const String
& rTemplateName
, const String
& rFileName
)
994 // only care about reseting this data for openoffice formats otherwise
995 if ( IsOwnStorageFormat_Impl( *GetMedium()) )
997 uno::Reference
<document::XDocumentProperties
> xDocProps(getDocProperties());
998 xDocProps
->setTemplateURL( ::rtl::OUString() );
999 xDocProps
->setTemplateName( ::rtl::OUString() );
1000 xDocProps
->setTemplateDate( util::DateTime() );
1001 xDocProps
->resetUserData( ::rtl::OUString() );
1006 if( ::utl::LocalFileHelper::IsLocalFile( rFileName
) )
1009 if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName
, aFoundName
) )
1011 INetURLObject
aObj( rFileName
);
1012 xDocProps
->setTemplateURL( aObj
.GetMainURL(INetURLObject::DECODE_TO_IURI
) );
1013 xDocProps
->setTemplateName( rTemplateName
);
1015 ::DateTime
now( ::DateTime::SYSTEM
);
1016 xDocProps
->setTemplateDate( util::DateTime(
1017 now
.Get100Sec(), now
.GetSec(), now
.GetMin(),
1018 now
.GetHour(), now
.GetDay(), now
.GetMonth(),
1021 SetQueryLoadTemplate( sal_True
);
1027 sal_Bool
SfxObjectShell::IsQueryLoadTemplate() const
1029 return pImp
->bQueryLoadTemplate
;
1032 sal_Bool
SfxObjectShell::IsUseUserData() const
1034 return pImp
->bUseUserData
;
1037 void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew
)
1039 if ( pImp
->bQueryLoadTemplate
!= bNew
)
1040 SetModified( sal_True
);
1041 pImp
->bQueryLoadTemplate
= bNew
;
1044 void SfxObjectShell::SetUseUserData( sal_Bool bNew
)
1046 if ( pImp
->bUseUserData
!= bNew
)
1047 SetModified( sal_True
);
1048 pImp
->bUseUserData
= bNew
;
1051 sal_Bool
SfxObjectShell::IsLoadReadonly() const
1053 return pImp
->bLoadReadonly
;
1056 sal_Bool
SfxObjectShell::IsSaveVersionOnClose() const
1058 return pImp
->bSaveVersionOnClose
;
1061 void SfxObjectShell::SetLoadReadonly( sal_Bool bNew
)
1063 if ( pImp
->bLoadReadonly
!= bNew
)
1064 SetModified( sal_True
);
1065 pImp
->bLoadReadonly
= bNew
;
1068 void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew
)
1070 if ( pImp
->bSaveVersionOnClose
!= bNew
)
1071 SetModified( sal_True
);
1072 pImp
->bSaveVersionOnClose
= bNew
;
1075 sal_uInt32
SfxObjectShell::GetModifyPasswordHash() const
1077 return pImp
->m_nModifyPasswordHash
;
1080 sal_Bool
SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash
)
1082 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1083 || !(pImp
->nFlagsInProgress
& SFX_LOADED_MAINDOCUMENT
) )
1085 // the hash can be changed only in editable documents,
1086 // or during loading of document
1087 pImp
->m_nModifyPasswordHash
= nHash
;
1094 uno::Sequence
< beans::PropertyValue
> SfxObjectShell::GetModifyPasswordInfo() const
1096 return pImp
->m_aModifyPasswordInfo
;
1099 sal_Bool
SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence
< beans::PropertyValue
>& aInfo
)
1101 if ( ( !IsReadOnly() && !IsReadOnlyUI() )
1102 || !(pImp
->nFlagsInProgress
& SFX_LOADED_MAINDOCUMENT
) )
1104 // the hash can be changed only in editable documents,
1105 // or during loading of document
1106 pImp
->m_aModifyPasswordInfo
= aInfo
;
1113 void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered
)
1115 pImp
->m_bModifyPasswordEntered
= bEntered
;
1118 sal_Bool
SfxObjectShell::IsModifyPasswordEntered()
1120 return pImp
->m_bModifyPasswordEntered
;
1123 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */