| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sfx2.hxx" |
| |
| #include <com/sun/star/uno/Reference.hxx> |
| |
| #include <com/sun/star/document/XDocumentProperties.hpp> |
| #include <com/sun/star/document/UpdateDocMode.hpp> |
| #include <com/sun/star/frame/XLayoutManager.hpp> |
| #include <com/sun/star/embed/ElementModes.hpp> |
| #include <com/sun/star/document/XStandaloneDocumentInfo.hpp> |
| #include <com/sun/star/beans/XFastPropertySet.hpp> |
| #include <tools/cachestr.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <svl/style.hxx> |
| #include <vcl/wrkwin.hxx> |
| |
| #include <svl/stritem.hxx> |
| #include <svl/intitem.hxx> |
| #include <svl/rectitem.hxx> |
| #include <svl/eitem.hxx> |
| #include <svl/urihelper.hxx> |
| #include <svl/ctloptions.hxx> |
| #include <comphelper/storagehelper.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <unotools/securityoptions.hxx> |
| #include <svtools/sfxecode.hxx> |
| #include <svtools/ehdl.hxx> |
| #include <tools/datetime.hxx> |
| #include <math.h> |
| |
| #include <unotools/saveopt.hxx> |
| #include <unotools/useroptions.hxx> |
| #include <unotools/localfilehelper.hxx> |
| #include <vcl/virdev.hxx> |
| #include <vcl/oldprintadaptor.hxx> |
| |
| #include <sfx2/app.hxx> |
| #include "sfx2/sfxresid.hxx" |
| #include "appdata.hxx" |
| #include <sfx2/dinfdlg.hxx> |
| #include "fltfnc.hxx" |
| #include <sfx2/docfac.hxx> |
| #include <sfx2/viewsh.hxx> |
| #include <sfx2/objsh.hxx> |
| #include "objshimp.hxx" |
| #include <sfx2/evntconf.hxx> |
| #include "sfx2/sfxhelp.hxx" |
| #include <sfx2/dispatch.hxx> |
| #include <sfx2/printer.hxx> |
| #include "sfx2/basmgr.hxx" |
| #include <sfx2/viewfrm.hxx> |
| #include <sfx2/doctempl.hxx> |
| #include "doc.hrc" |
| #include <sfx2/sfxbasemodel.hxx> |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/request.hxx> |
| #include "openflag.hxx" |
| #include "querytemplate.hxx" |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| |
| //==================================================================== |
| |
| //==================================================================== |
| |
| static |
| bool operator> (const util::DateTime& i_rLeft, const util::DateTime& i_rRight) |
| { |
| if ( i_rLeft.Year != i_rRight.Year ) |
| return i_rLeft.Year > i_rRight.Year; |
| |
| if ( i_rLeft.Month != i_rRight.Month ) |
| return i_rLeft.Month > i_rRight.Month; |
| |
| if ( i_rLeft.Day != i_rRight.Day ) |
| return i_rLeft.Day > i_rRight.Day; |
| |
| if ( i_rLeft.Hours != i_rRight.Hours ) |
| return i_rLeft.Hours > i_rRight.Hours; |
| |
| if ( i_rLeft.Minutes != i_rRight.Minutes ) |
| return i_rLeft.Minutes > i_rRight.Minutes; |
| |
| if ( i_rLeft.Seconds != i_rRight.Seconds ) |
| return i_rLeft.Seconds > i_rRight.Seconds; |
| |
| if ( i_rLeft.HundredthSeconds != i_rRight.HundredthSeconds ) |
| return i_rLeft.HundredthSeconds > i_rRight.HundredthSeconds; |
| |
| return sal_False; |
| } |
| |
| |
| ::boost::shared_ptr<GDIMetaFile> |
| SfxObjectShell::GetPreviewMetaFile( sal_Bool bFullContent ) const |
| { |
| return CreatePreviewMetaFile_Impl( bFullContent, sal_False ); |
| } |
| |
| |
| ::boost::shared_ptr<GDIMetaFile> |
| SfxObjectShell::CreatePreviewMetaFile_Impl( sal_Bool bFullContent, sal_Bool bHighContrast ) const |
| { |
| // Nur wenn gerade nicht gedruckt wird, darf DoDraw aufgerufen |
| // werden, sonst wird u.U. der Printer abgeschossen ! |
| SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this ); |
| if ( pFrame && pFrame->GetViewShell() && |
| pFrame->GetViewShell()->GetPrinter() && |
| pFrame->GetViewShell()->GetPrinter()->IsPrinting() ) |
| return ::boost::shared_ptr<GDIMetaFile>(); |
| |
| ::boost::shared_ptr<GDIMetaFile> pFile(new GDIMetaFile); |
| |
| VirtualDevice aDevice; |
| aDevice.EnableOutput( sal_False ); |
| |
| // adjust the output device if HC-metafile is requested |
| if ( bHighContrast ) |
| aDevice.SetDrawMode( aDevice.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ); |
| |
| MapMode aMode( ((SfxObjectShell*)this)->GetMapUnit() ); |
| aDevice.SetMapMode( aMode ); |
| pFile->SetPrefMapMode( aMode ); |
| |
| Size aTmpSize; |
| sal_Int8 nAspect; |
| if ( bFullContent ) |
| { |
| nAspect = ASPECT_CONTENT; |
| aTmpSize = GetVisArea( nAspect ).GetSize(); |
| } |
| else |
| { |
| nAspect = ASPECT_THUMBNAIL; |
| aTmpSize = ((SfxObjectShell*)this)->GetFirstPageSize(); |
| } |
| |
| pFile->SetPrefSize( aTmpSize ); |
| DBG_ASSERT( aTmpSize.Height()*aTmpSize.Width(), |
| "size of first page is 0, overload GetFirstPageSize or set vis-area!" ); |
| |
| pFile->Record( &aDevice ); |
| |
| LanguageType eLang; |
| // #120038# use local incarnation, so deletion cannot be forgotten |
| const SvtCTLOptions aCTLOptions; |
| |
| if ( SvtCTLOptions::NUMERALS_HINDI == aCTLOptions.GetCTLTextNumerals() ) |
| eLang = LANGUAGE_ARABIC_SAUDI_ARABIA; |
| else if ( SvtCTLOptions::NUMERALS_ARABIC == aCTLOptions.GetCTLTextNumerals() ) |
| eLang = LANGUAGE_ENGLISH; |
| else |
| eLang = (LanguageType) Application::GetSettings().GetLanguage(); |
| |
| aDevice.SetDigitLanguage( eLang ); |
| |
| ((SfxObjectShell*)this)->DoDraw( &aDevice, Point(0,0), aTmpSize, JobSetup(), nAspect ); |
| pFile->Stop(); |
| |
| return pFile; |
| } |
| |
| //==================================================================== |
| |
| void SfxObjectShell::UpdateDocInfoForSave() |
| { |
| uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); |
| |
| // clear user data if recommend (see 'Tools - Options - Open/StarOffice - Security') |
| if ( SvtSecurityOptions().IsOptionSet( |
| SvtSecurityOptions::E_DOCWARN_REMOVEPERSONALINFO ) ) |
| { |
| xDocProps->resetUserData( ::rtl::OUString() ); |
| } |
| else if ( IsModified() ) |
| { |
| String aUserName = SvtUserOptions().GetFullName(); |
| if ( !IsUseUserData() ) |
| { |
| // remove all data pointing to the current user |
| if (xDocProps->getAuthor().equals(aUserName)) { |
| xDocProps->setAuthor( ::rtl::OUString() ); |
| } |
| xDocProps->setModifiedBy( ::rtl::OUString() ); |
| if (xDocProps->getPrintedBy().equals(aUserName)) { |
| xDocProps->setPrintedBy( ::rtl::OUString() ); |
| } |
| } |
| else |
| { |
| // update ModificationAuthor, revision and editing time |
| ::DateTime now; |
| xDocProps->setModificationDate( util::DateTime( |
| now.Get100Sec(), now.GetSec(), now.GetMin(), |
| now.GetHour(), now.GetDay(), now.GetMonth(), |
| now.GetYear() ) ); |
| xDocProps->setModifiedBy( aUserName ); |
| if ( !HasName() || pImp->bIsSaving ) |
| // QUESTION: not in case of "real" SaveAs as this is meant to create a new document |
| UpdateTime_Impl( xDocProps ); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| static void |
| lcl_add(util::Duration & rDur, Time const& rTime) |
| { |
| // here we don't care about overflow: rDur is converted back to seconds |
| // anyway, and Time cannot store more than ~4000 hours |
| rDur.Hours += rTime.GetHour(); |
| rDur.Minutes += rTime.GetMin(); |
| rDur.Seconds += rTime.GetSec(); |
| } |
| |
| // Bearbeitungszeit aktualisieren |
| void SfxObjectShell::UpdateTime_Impl( |
| const uno::Reference<document::XDocumentProperties> & i_xDocProps) |
| { |
| // Get old time from documentinfo |
| const sal_Int32 secs = i_xDocProps->getEditingDuration(); |
| util::Duration editDuration(sal_False, 0, 0, 0, |
| secs/3600, (secs%3600)/60, secs%60, 0); |
| |
| // Initialize some local member! Its neccessary for wollow operations! |
| DateTime aNow ; // Date and time at current moment |
| Time n24Time (24,0,0,0) ; // Time-value for 24 hours - see follow calculation |
| sal_uIntPtr nDays = 0 ; // Count of days between now and last editing |
| Time nAddTime (0) ; // Value to add on aOldTime |
| |
| // Safe impossible cases! |
| // User has changed time to the past between last editing and now ... its not possible!!! |
| DBG_ASSERT( !(aNow.GetDate()<pImp->nTime.GetDate()), "Timestamp of last change is in the past ?!..." ); |
| |
| // Do the follow only, if user has NOT changed time to the past. |
| // Else add a time of 0 to aOldTime ... !!! |
| if (aNow.GetDate()>=pImp->nTime.GetDate()) |
| { |
| // Get count of days last editing. |
| nDays = aNow.GetSecFromDateTime(pImp->nTime.GetDate())/86400 ; |
| |
| if (nDays==0) |
| { |
| // If no day between now and last editing - calculate time directly. |
| nAddTime = (const Time&)aNow - (const Time&)pImp->nTime ; |
| } |
| else |
| // If time of working without save greater then 1 month (!) .... |
| // we add 0 to aOldTime! |
| if (nDays<=31) |
| { |
| // If 1 or up to 31 days between now and last editing - calculate time indirectly. |
| // nAddTime = (24h - nTime) + (nDays * 24h) + aNow |
| --nDays; |
| nAddTime = nDays*n24Time.GetTime() ; |
| nAddTime += n24Time-(const Time&)pImp->nTime ; |
| nAddTime += aNow ; |
| } |
| |
| lcl_add(editDuration, nAddTime); |
| } |
| |
| pImp->nTime = aNow; |
| try { |
| const sal_Int32 newSecs( (editDuration.Hours*3600) |
| + (editDuration.Minutes*60) + editDuration.Seconds); |
| i_xDocProps->setEditingDuration(newSecs); |
| i_xDocProps->setEditingCycles(i_xDocProps->getEditingCycles() + 1); |
| } |
| catch (lang::IllegalArgumentException &) |
| { |
| // ignore overflow |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| SfxDocumentInfoDialog* SfxObjectShell::CreateDocumentInfoDialog |
| ( |
| Window* pParent, |
| const SfxItemSet& rSet |
| ) |
| { |
| return new SfxDocumentInfoDialog(pParent, rSet); |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| SfxStyleSheetBasePool* SfxObjectShell::GetStyleSheetPool() |
| { |
| return 0; |
| } |
| |
| void SfxObjectShell::SetOrganizerSearchMask( |
| SfxStyleSheetBasePool* pStylePool) const |
| { |
| pStylePool->SetSearchMask( |
| SFX_STYLE_FAMILY_ALL, |
| SFXSTYLEBIT_USERDEF | SFXSTYLEBIT_USED); |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| sal_uInt16 SfxObjectShell::GetContentCount( |
| sal_uInt16 nIdx1, |
| sal_uInt16 /*nIdx2*/) |
| { |
| switch(nIdx1) |
| { |
| case INDEX_IGNORE: |
| return DEF_CONTENT_COUNT; |
| case CONTENT_STYLE: |
| { |
| SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); |
| if(!pStylePool) |
| return 0; |
| SetOrganizerSearchMask(pStylePool); |
| return pStylePool->Count(); |
| } |
| case CONTENT_MACRO: |
| break; |
| /* |
| case CONTENT_CONFIG: |
| return ( GetConfigManager() ) ? |
| GetConfigManager()->GetItemCount() : 0; |
| break; |
| */ |
| } |
| return 0; |
| } |
| |
| |
| //-------------------------------------------------------------------- |
| //TODO/CLEANUP: remove this method (it's virtual) |
| void SfxObjectShell::TriggerHelpPI(sal_uInt16 nIdx1, sal_uInt16 nIdx2, sal_uInt16) |
| { |
| if(nIdx1==CONTENT_STYLE && nIdx2 != INDEX_IGNORE) //StyleSheets |
| { |
| SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); |
| SetOrganizerSearchMask(pStylePool); |
| } |
| } |
| |
| sal_Bool SfxObjectShell::CanHaveChilds(sal_uInt16 nIdx1, |
| sal_uInt16 nIdx2) |
| { |
| switch(nIdx1) { |
| case INDEX_IGNORE: |
| return sal_True; |
| case CONTENT_STYLE: |
| return INDEX_IGNORE == nIdx2 || !GetStyleSheetPool()? sal_False: sal_True; |
| case CONTENT_MACRO: |
| //!! return INDEX_IGNORE == nIdx2? sal_False: sal_True; |
| return sal_False; |
| /* |
| case CONTENT_CONFIG: |
| return INDEX_IGNORE == nIdx2 ? sal_False : sal_True; |
| */ |
| } |
| return sal_False; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| void SfxObjectShell::GetContent(String &rText, |
| Bitmap &rClosedBitmap, |
| Bitmap &rOpenedBitmap, |
| sal_Bool &bCanDel, |
| sal_uInt16 i, |
| sal_uInt16 nIdx1, |
| sal_uInt16 nIdx2 ) |
| { |
| DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" ); |
| SfxObjectShell::GetContent( rText, rClosedBitmap, rOpenedBitmap, BMP_COLOR_NORMAL, bCanDel, i, nIdx1, nIdx2 ); |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| void SfxObjectShell::GetContent(String &rText, |
| Bitmap &rClosedBitmap, |
| Bitmap &rOpenedBitmap, |
| BmpColorMode eColorMode, |
| sal_Bool &bCanDel, |
| sal_uInt16 i, |
| sal_uInt16 nIdx1, |
| sal_uInt16 /*nIdx2*/ ) |
| { |
| bCanDel=sal_True; |
| |
| switch(nIdx1) |
| { |
| case INDEX_IGNORE: |
| { |
| sal_uInt16 nTextResId = 0; |
| sal_uInt16 nClosedBitmapResId = 0; // evtl. sp"ater mal unterschiedliche |
| sal_uInt16 nOpenedBitmapResId = 0; // " " " " |
| switch(i) |
| { |
| case CONTENT_STYLE: |
| nTextResId = STR_STYLES; |
| if ( eColorMode == BMP_COLOR_NORMAL ) |
| { |
| nClosedBitmapResId= BMP_STYLES_CLOSED; |
| nOpenedBitmapResId= BMP_STYLES_OPENED; |
| } |
| else |
| { |
| nClosedBitmapResId= BMP_STYLES_CLOSED_HC; |
| nOpenedBitmapResId= BMP_STYLES_OPENED_HC; |
| } |
| break; |
| case CONTENT_MACRO: |
| nTextResId = STR_MACROS; |
| if ( eColorMode == BMP_COLOR_NORMAL ) |
| { |
| nClosedBitmapResId= BMP_STYLES_CLOSED; |
| nOpenedBitmapResId= BMP_STYLES_OPENED; |
| } |
| else |
| { |
| nClosedBitmapResId= BMP_STYLES_CLOSED_HC; |
| nOpenedBitmapResId= BMP_STYLES_OPENED_HC; |
| } |
| break; |
| /* |
| case CONTENT_CONFIG: |
| nTextResId = STR_CONFIG; |
| nClosedBitmapResId= BMP_STYLES_CLOSED; |
| nOpenedBitmapResId= BMP_STYLES_OPENED; |
| break; |
| */ |
| } |
| |
| if ( nTextResId ) |
| { |
| rText = String(SfxResId(nTextResId)); |
| rClosedBitmap = Bitmap(SfxResId(nClosedBitmapResId)); |
| rOpenedBitmap = Bitmap(SfxResId(nOpenedBitmapResId)); |
| } |
| break; |
| } |
| |
| case CONTENT_STYLE: |
| { |
| SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); |
| SetOrganizerSearchMask(pStylePool); |
| SfxStyleSheetBase *pStyle = (*pStylePool)[i]; |
| rText = pStyle->GetName(); |
| bCanDel=((pStyle->GetMask() & SFXSTYLEBIT_USERDEF) |
| == SFXSTYLEBIT_USERDEF); |
| rClosedBitmap = rOpenedBitmap = |
| GetStyleFamilyBitmap(pStyle->GetFamily(), eColorMode ); |
| } |
| break; |
| case CONTENT_MACRO: |
| break; |
| /* |
| case CONTENT_CONFIG: |
| if ( GetConfigManager() ) |
| { |
| rText = GetConfigManager()->GetItem(i); |
| bCanDel = GetConfigManager()->CanDelete(i); |
| } |
| else |
| rText = String(); |
| rClosedBitmap = Bitmap(SfxResId(BMP_STYLES_CLOSED)); |
| rOpenedBitmap = Bitmap(SfxResId(BMP_STYLES_OPENED)); |
| break; |
| */ |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| Bitmap SfxObjectShell::GetStyleFamilyBitmap( SfxStyleFamily eFamily ) |
| { |
| DBG_ERRORFILE( "Non high contrast method called. Please update calling code!" ); |
| return SfxObjectShell::GetStyleFamilyBitmap( eFamily, BMP_COLOR_NORMAL ); |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| Bitmap SfxObjectShell::GetStyleFamilyBitmap(SfxStyleFamily eFamily, BmpColorMode eColorMode ) |
| { |
| sal_uInt16 nResId = 0; |
| switch(eFamily) |
| { |
| case SFX_STYLE_FAMILY_CHAR: |
| nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY1 : BMP_STYLES_FAMILY1_HC; |
| break; |
| case SFX_STYLE_FAMILY_PARA: |
| nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY2 : BMP_STYLES_FAMILY2_HC; |
| break; |
| case SFX_STYLE_FAMILY_FRAME: |
| nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY3 : BMP_STYLES_FAMILY3_HC; |
| break; |
| case SFX_STYLE_FAMILY_PAGE : |
| nResId = ( eColorMode == BMP_COLOR_NORMAL ) ? BMP_STYLES_FAMILY4 : BMP_STYLES_FAMILY4_HC; |
| break; |
| case SFX_STYLE_FAMILY_PSEUDO: |
| case SFX_STYLE_FAMILY_ALL: |
| break; |
| } |
| |
| if ( nResId ) |
| return Bitmap(SfxResId(nResId)); |
| else |
| return Bitmap(); |
| } |
| |
| |
| //-------------------------------------------------------------------- |
| |
| sal_Bool SfxObjectShell::Insert(SfxObjectShell &rSource, |
| sal_uInt16 nSourceIdx1, |
| sal_uInt16 nSourceIdx2, |
| sal_uInt16 /*nSourceIdx3*/, |
| sal_uInt16 &nIdx1, |
| sal_uInt16 &nIdx2, |
| sal_uInt16 &/*nIdx3*/, |
| sal_uInt16 &/*nDeleted*/) |
| { |
| sal_Bool bRet = sal_False; |
| |
| if (INDEX_IGNORE == nIdx1 && CONTENT_STYLE == nSourceIdx1) |
| nIdx1 = CONTENT_STYLE; |
| |
| if (CONTENT_STYLE == nSourceIdx1 && CONTENT_STYLE == nIdx1) |
| { |
| SfxStyleSheetBasePool* pHisPool = rSource.GetStyleSheetPool(); |
| SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool(); |
| SetOrganizerSearchMask(pHisPool); |
| SetOrganizerSearchMask(pMyPool); |
| SfxStyleSheetBase* pHisSheet = NULL; |
| |
| if ( pHisPool && pHisPool->Count() > nSourceIdx2 ) |
| pHisSheet = (*pHisPool)[nSourceIdx2]; |
| |
| // Einfuegen ist nur dann noetig, wenn ein StyleSheet |
| // zwischen unterschiedlichen(!) Pools bewegt wird |
| |
| if ( pHisSheet && pMyPool != pHisPool ) |
| { |
| if (INDEX_IGNORE == nIdx2) |
| { |
| nIdx2 = pMyPool->Count(); |
| } |
| |
| // wenn so eine Vorlage schon existiert: loeschen! |
| String aOldName(pHisSheet->GetName()); |
| SfxStyleFamily eOldFamily = pHisSheet->GetFamily(); |
| |
| SfxStyleSheetBase* pExist = pMyPool->Find(aOldName, eOldFamily); |
| // sal_uInt16 nOldHelpId = pExist->GetHelpId(??? VB ueberlegt sich was); |
| sal_Bool bUsedOrUserDefined; |
| if( pExist ) |
| { |
| bUsedOrUserDefined = |
| pExist->IsUsed() || pExist->IsUserDefined(); |
| if( ErrorHandler::HandleError( |
| *new MessageInfo( ERRCODE_SFXMSG_STYLEREPLACE, aOldName ) ) |
| != ERRCODE_BUTTON_OK ) |
| return sal_False; |
| else |
| { |
| pMyPool->Replace( *pHisSheet, *pExist ); |
| SetModified( sal_True ); |
| nIdx2 = nIdx1 = INDEX_IGNORE; |
| return sal_True; |
| } |
| } |
| |
| SfxStyleSheetBase& rNewSheet = pMyPool->Make( |
| aOldName, eOldFamily, |
| pHisSheet->GetMask(), nIdx2); |
| |
| // ItemSet der neuen Vorlage fuellen |
| rNewSheet.GetItemSet().Set(pHisSheet->GetItemSet()); |
| |
| // wer bekommt den Neuen als Parent? wer benutzt den Neuen als Follow? |
| SfxStyleSheetBase* pTestSheet = pMyPool->First(); |
| while (pTestSheet) |
| { |
| if (pTestSheet->GetFamily() == eOldFamily && |
| pTestSheet->HasParentSupport() && |
| pTestSheet->GetParent() == aOldName) |
| { |
| pTestSheet->SetParent(aOldName); |
| // Verknuepfung neu aufbauen |
| } |
| |
| if (pTestSheet->GetFamily() == eOldFamily && |
| pTestSheet->HasFollowSupport() && |
| pTestSheet->GetFollow() == aOldName) |
| { |
| pTestSheet->SetFollow(aOldName); |
| // Verknuepfung neu aufbauen |
| } |
| |
| pTestSheet = pMyPool->Next(); |
| } |
| bUsedOrUserDefined = |
| rNewSheet.IsUsed() || rNewSheet.IsUserDefined(); |
| |
| |
| // hat der Neue einen Parent? wenn ja, mit gleichem Namen bei uns suchen |
| if (pHisSheet->HasParentSupport()) |
| { |
| const String& rParentName = pHisSheet->GetParent(); |
| if (0 != rParentName.Len()) |
| { |
| SfxStyleSheetBase* pParentOfNew = |
| pMyPool->Find(rParentName, eOldFamily); |
| if (pParentOfNew) |
| rNewSheet.SetParent(rParentName); |
| } |
| } |
| |
| // hat der Neue einen Follow? wenn ja, mit gleichem |
| // Namen bei uns suchen |
| if (pHisSheet->HasFollowSupport()) |
| { |
| const String& rFollowName = pHisSheet->GetFollow(); |
| if (0 != rFollowName.Len()) |
| { |
| SfxStyleSheetBase* pFollowOfNew = |
| pMyPool->Find(rFollowName, eOldFamily); |
| if (pFollowOfNew) |
| rNewSheet.SetFollow(rFollowName); |
| } |
| } |
| |
| SetModified( sal_True ); |
| if( !bUsedOrUserDefined ) nIdx2 = nIdx1 = INDEX_IGNORE; |
| |
| bRet = sal_True; |
| } |
| else |
| bRet = sal_False; |
| } |
| /* |
| else if (nSourceIdx1 == CONTENT_CONFIG) |
| { |
| nIdx1 = CONTENT_CONFIG; |
| |
| SfxConfigManager *pCfgMgr = SFX_CFGMANAGER(); |
| if ( !GetConfigManager() ) |
| { |
| SetConfigManager(new SfxConfigManager(0, pCfgMgr)); |
| SetTemplateConfig(sal_False); |
| if (this == Current()) |
| GetConfigManager()->Activate(pCfgMgr); |
| } |
| |
| if (GetConfigManager()->CopyItem( |
| nSourceIdx2, nIdx2, rSource.GetConfigManager())) |
| { |
| SetModified(sal_True); |
| bRet = sal_True; |
| SFX_APP()->GetDispatcher_Impl()->Update_Impl(sal_True); |
| } |
| } |
| */ |
| return bRet; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| sal_Bool SfxObjectShell::Remove |
| ( |
| sal_uInt16 nIdx1, |
| sal_uInt16 nIdx2, |
| sal_uInt16 /*nIdx3*/ |
| ) |
| { |
| sal_Bool bRet = sal_False; |
| |
| if (CONTENT_STYLE == nIdx1) |
| { |
| SfxStyleSheetBasePool* pMyPool = GetStyleSheetPool(); |
| |
| SetOrganizerSearchMask(pMyPool); |
| |
| SfxStyleSheetBase* pMySheet = (*pMyPool)[nIdx2]; |
| String aName(pMySheet->GetName()); |
| String aEmpty; |
| SfxStyleFamily eFamily = pMySheet->GetFamily(); |
| pMyPool->Remove(pMySheet); |
| bRet = sal_True; |
| |
| SfxStyleSheetBase* pTestSheet = pMyPool->First(); |
| while (pTestSheet) |
| { |
| if (pTestSheet->GetFamily() == eFamily && |
| pTestSheet->HasParentSupport() && |
| pTestSheet->GetParent() == aName) |
| { |
| pTestSheet->SetParent(aEmpty); // Verknuepfung aufloesen |
| } |
| |
| if (pTestSheet->GetFamily() == eFamily && |
| pTestSheet->HasFollowSupport() && |
| pTestSheet->GetFollow() == aName) |
| { |
| pTestSheet->SetFollow(aEmpty); // Verknuepfung aufloesen |
| } |
| |
| pTestSheet = pMyPool->Next(); |
| } |
| |
| SetModified( sal_True ); |
| } |
| |
| return bRet; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| sal_Bool SfxObjectShell::Print |
| ( |
| Printer& rPrt, |
| sal_uInt16 nIdx1, |
| sal_uInt16 /*nIdx2*/, |
| sal_uInt16 /*nIdx3*/, |
| const String* pObjectName |
| ) |
| |
| /* [Beschreibung] |
| */ |
| |
| { |
| switch(nIdx1) |
| { |
| case CONTENT_STYLE: |
| { |
| SfxStyleSheetBasePool *pStylePool = GetStyleSheetPool(); |
| SetOrganizerSearchMask(pStylePool); |
| SfxStyleSheetIteratorPtr pIter = pStylePool->CreateIterator( pStylePool->GetSearchFamily(), pStylePool->GetSearchMask() ); |
| sal_uInt16 nStyles = pIter->Count(); |
| SfxStyleSheetBase *pStyle = pIter->First(); |
| if ( !pStyle ) |
| return sal_True; |
| |
| // pepare adaptor for old style StartPage/EndPage printing |
| boost::shared_ptr< Printer > pPrinter( new Printer( rPrt.GetJobSetup() ) ); |
| vcl::OldStylePrintAdaptor* pAdaptor = new vcl::OldStylePrintAdaptor( pPrinter ); |
| boost::shared_ptr< vcl::PrinterController > pController( pAdaptor ); |
| |
| pAdaptor->StartPage(); |
| |
| pPrinter->SetMapMode(MapMode(MAP_10TH_MM)); |
| Font aFont( DEFINE_CONST_UNICODE( "Arial" ), Size(0, 64)); // 18pt |
| aFont.SetWeight(WEIGHT_BOLD); |
| pPrinter->SetFont(aFont); |
| const Size aPageSize(pPrinter->GetOutputSize()); |
| const sal_uInt16 nXIndent = 200; |
| sal_uInt16 nYIndent = 200; |
| Point aOutPos(nXIndent, nYIndent); |
| String aHeader(SfxResId(STR_PRINT_STYLES_HEADER)); |
| if ( pObjectName ) |
| aHeader += *pObjectName; |
| else |
| aHeader += GetTitle(); |
| long nTextHeight( pPrinter->GetTextHeight() ); |
| pPrinter->DrawText(aOutPos, aHeader); |
| aOutPos.Y() += nTextHeight; |
| aOutPos.Y() += nTextHeight/2; |
| aFont.SetSize(Size(0, 35)); // 10pt |
| nStyles = 1; |
| while(pStyle) |
| { |
| // print template name |
| String aStr(pStyle->GetName()); |
| aFont.SetWeight(WEIGHT_BOLD); |
| pPrinter->SetFont(aFont); |
| nTextHeight = pPrinter->GetTextHeight(); |
| // check for new page |
| if ( aOutPos.Y() + nTextHeight*2 > |
| aPageSize.Height() - (long) nYIndent ) |
| { |
| pAdaptor->EndPage(); |
| pAdaptor->StartPage(); |
| aOutPos.Y() = nYIndent; |
| } |
| pPrinter->DrawText(aOutPos, aStr); |
| aOutPos.Y() += nTextHeight; |
| |
| // print template description |
| aFont.SetWeight(WEIGHT_NORMAL); |
| pPrinter->SetFont(aFont); |
| aStr = pStyle->GetDescription(); |
| const char cDelim = ' '; |
| sal_uInt16 nStart = 0, nIdx = 0; |
| |
| nTextHeight = pPrinter->GetTextHeight(); |
| // break text into lines |
| while(nIdx < aStr.Len()) |
| { |
| sal_uInt16 nOld = nIdx; |
| long nTextWidth; |
| nIdx = aStr.Search(cDelim, nStart); |
| nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart); |
| while(nIdx != STRING_NOTFOUND && |
| aOutPos.X() + nTextWidth < |
| aPageSize.Width() - (long) nXIndent) |
| { |
| nOld = nIdx; |
| nIdx = aStr.Search(cDelim, nIdx+1); |
| nTextWidth = pPrinter->GetTextWidth(aStr, nStart, nIdx-nStart); |
| } |
| String aTmp(aStr, nStart, nIdx == STRING_NOTFOUND? |
| STRING_LEN : |
| nOld-nStart); |
| if ( aTmp.Len() ) |
| { |
| nStart = nOld+1; // trailing space |
| } |
| else |
| { |
| sal_uInt16 nChar = 1; |
| while( |
| nStart + nChar < aStr.Len() && |
| aOutPos.X() + pPrinter->GetTextWidth( |
| aStr, nStart, nChar) < |
| aPageSize.Width() - nXIndent) |
| ++nChar; |
| aTmp = String(aStr, nStart, nChar-1); |
| nIdx = nStart + nChar; |
| nStart = nIdx; |
| } |
| if ( aOutPos.Y() + nTextHeight*2 > |
| aPageSize.Height() - nYIndent ) |
| { |
| pAdaptor->EndPage(); |
| pAdaptor->StartPage(); |
| aOutPos.Y() = nYIndent; |
| } |
| pPrinter->DrawText(aOutPos, aTmp); |
| aOutPos.Y() += pPrinter->GetTextHeight(); |
| } |
| pStyle = pIter->Next(); |
| } |
| pAdaptor->EndPage(); |
| |
| Printer::PrintJob( pController, rPrt.GetJobSetup() ); |
| |
| break; |
| } |
| default: |
| return sal_False; |
| } |
| return sal_True; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| void SfxObjectShell::LoadStyles |
| ( |
| SfxObjectShell &rSource /* die Dokument-Vorlage, aus der |
| die Styles geladen werden sollen */ |
| ) |
| |
| /* [Beschreibung] |
| |
| Diese Methode wird vom SFx gerufen, wenn aus einer Dokument-Vorlage |
| Styles nachgeladen werden sollen. Bestehende Styles soll dabei |
| "uberschrieben werden. Das Dokument mu"s daher neu formatiert werden. |
| Daher werden die Applikationen in der Regel diese Methode "uberladen |
| und in ihrer Implementierung die Implementierung der Basisklasse |
| rufen. |
| */ |
| |
| { |
| struct Styles_Impl |
| { |
| SfxStyleSheetBase *pSource; |
| SfxStyleSheetBase *pDest; |
| // Styles_Impl () : pSource(0), pDest(0) {} |
| }; |
| |
| SfxStyleSheetBasePool *pSourcePool = rSource.GetStyleSheetPool(); |
| DBG_ASSERT(pSourcePool, "Source-DocumentShell ohne StyleSheetPool"); |
| SfxStyleSheetBasePool *pMyPool = GetStyleSheetPool(); |
| DBG_ASSERT(pMyPool, "Dest-DocumentShell ohne StyleSheetPool"); |
| pSourcePool->SetSearchMask(SFX_STYLE_FAMILY_ALL, 0xffff); |
| Styles_Impl *pFound = new Styles_Impl[pSourcePool->Count()]; |
| sal_uInt16 nFound = 0; |
| |
| SfxStyleSheetBase *pSource = pSourcePool->First(); |
| while ( pSource ) |
| { |
| SfxStyleSheetBase *pDest = |
| pMyPool->Find( pSource->GetName(), pSource->GetFamily() ); |
| if ( !pDest ) |
| { |
| pDest = &pMyPool->Make( pSource->GetName(), |
| pSource->GetFamily(), pSource->GetMask()); |
| // Setzen des Parents, der Folgevorlage |
| } |
| pFound[nFound].pSource = pSource; |
| pFound[nFound].pDest = pDest; |
| ++nFound; |
| pSource = pSourcePool->Next(); |
| } |
| |
| for ( sal_uInt16 i = 0; i < nFound; ++i ) |
| { |
| pFound[i].pDest->GetItemSet().PutExtended(pFound[i].pSource->GetItemSet(), SFX_ITEM_DONTCARE, SFX_ITEM_DEFAULT); |
| // pFound[i].pDest->SetHelpId(pFound[i].pSource->GetHelpId()); |
| if(pFound[i].pSource->HasParentSupport()) |
| pFound[i].pDest->SetParent(pFound[i].pSource->GetParent()); |
| if(pFound[i].pSource->HasFollowSupport()) |
| pFound[i].pDest->SetFollow(pFound[i].pSource->GetParent()); |
| } |
| delete [] pFound; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| void SfxObjectShell::UpdateFromTemplate_Impl( ) |
| |
| /* [Beschreibung] |
| |
| Diese interne Methode pr"uft, ob das Dokument aus einem Template |
| erzeugt wurde, und ob dieses neuer ist als das Dokument. Ist dies |
| der Fall, wird der Benutzer gefragt, ob die Vorlagen (StyleSheets) |
| updated werden sollen. Wird dies positiv beantwortet, werden die |
| StyleSheets updated. |
| */ |
| |
| { |
| // Storage-medium? |
| SfxMedium *pFile = GetMedium(); |
| DBG_ASSERT( pFile, "cannot UpdateFromTemplate without medium" ); |
| if ( !pFile ) |
| return; |
| |
| if ( !::utl::LocalFileHelper::IsLocalFile( pFile->GetName() ) ) |
| // update only for documents loaded from the local file system |
| return; |
| |
| // only for own storage formats |
| uno::Reference< embed::XStorage > xDocStor = pFile->GetStorage(); |
| if ( !pFile->GetFilter() || !pFile->GetFilter()->IsOwnFormat() ) |
| return; |
| |
| SFX_ITEMSET_ARG( pFile->GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False); |
| sal_Int16 bCanUpdateFromTemplate = pUpdateDocItem ? pUpdateDocItem->GetValue() : document::UpdateDocMode::NO_UPDATE; |
| |
| // created from template? |
| uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); |
| ::rtl::OUString aTemplName( xDocProps->getTemplateName() ); |
| ::rtl::OUString aTemplURL( xDocProps->getTemplateURL() ); |
| String aFoundName; |
| |
| if ( aTemplName.getLength() || (aTemplURL.getLength() && !IsReadOnly()) ) |
| { |
| // try to locate template, first using filename |
| // this must be done because writer global document uses this "great" idea to manage the templates of all parts |
| // in the master document |
| // but it is NOT an error if the template filename points not to a valid file |
| SfxDocumentTemplates aTempl; |
| aTempl.Construct(); |
| if ( aTemplURL.getLength() ) |
| { |
| String aURL; |
| if( ::utl::LocalFileHelper::ConvertSystemPathToURL( aTemplURL, GetMedium()->GetName(), aURL ) ) |
| aFoundName = aURL; |
| } |
| |
| if( !aFoundName.Len() && aTemplName.getLength() ) |
| // if the template filename did not lead to success, try to get a file name for the logical template name |
| aTempl.GetFull( String(), aTemplName, aFoundName ); |
| } |
| |
| if ( aFoundName.Len() ) |
| { |
| // check existence of template storage |
| aTemplURL = aFoundName; |
| sal_Bool bLoad = sal_False; |
| |
| // should the document checked against changes in the template ? |
| if ( IsQueryLoadTemplate() ) |
| { |
| // load document info of template |
| sal_Bool bOK = sal_False; |
| util::DateTime aTemplDate; |
| try |
| { |
| Reference < document::XStandaloneDocumentInfo > xDocInfo ( |
| ::comphelper::getProcessServiceFactory()->createInstance( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.document.StandaloneDocumentInfo") ) ), |
| UNO_QUERY_THROW ); |
| Reference < beans::XFastPropertySet > xSet( xDocInfo, |
| UNO_QUERY_THROW ); |
| xDocInfo->loadFromURL( aTemplURL ); |
| Any aAny = xSet->getFastPropertyValue( WID_DATE_MODIFIED ); |
| ::com::sun::star::util::DateTime aTmp; |
| if ( aAny >>= aTemplDate ) |
| { |
| // get modify date from document info |
| bOK = sal_True; |
| } |
| } |
| catch ( Exception& ) |
| { |
| } |
| |
| // if modify date was read successfully |
| if ( bOK ) |
| { |
| // compare modify data of template with the last check date of the document |
| const util::DateTime aInfoDate( xDocProps->getTemplateDate() ); |
| if ( aTemplDate > aInfoDate ) |
| { |
| // ask user |
| if( bCanUpdateFromTemplate == document::UpdateDocMode::QUIET_UPDATE |
| || bCanUpdateFromTemplate == document::UpdateDocMode::FULL_UPDATE ) |
| bLoad = sal_True; |
| else if ( bCanUpdateFromTemplate == document::UpdateDocMode::ACCORDING_TO_CONFIG ) |
| { |
| String sMessage( SfxResId( STR_QRYTEMPL_MESSAGE ) ); |
| sMessage.SearchAndReplace( String::CreateFromAscii("$(ARG1)"), aTemplName ); |
| sfx2::QueryTemplateBox aBox( GetDialogParent(), sMessage ); |
| if ( RET_YES == aBox.Execute() ) |
| bLoad = sal_True; |
| } |
| |
| if( !bLoad ) |
| { |
| // user refuses, so don't ask again for this document |
| SetQueryLoadTemplate(sal_False); |
| SetModified( sal_True ); |
| } |
| } |
| } |
| |
| if ( bLoad ) |
| { |
| // styles should be updated, create document in organizer mode to read in the styles |
| //TODO: testen! |
| SfxObjectShellLock xTemplDoc = CreateObjectByFactoryName( GetFactory().GetFactoryName(), SFX_CREATE_MODE_ORGANIZER ); |
| xTemplDoc->DoInitNew(0); |
| |
| // TODO/MBA: do we need a BaseURL? Then LoadFrom must be extended! |
| //xTemplDoc->SetBaseURL( aFoundName ); |
| |
| // TODO/LATER: make sure that we don't use binary templates! |
| SfxMedium aMedium( aFoundName, STREAM_STD_READ ); |
| if ( xTemplDoc->LoadFrom( aMedium ) ) |
| { |
| // transfer styles from xTemplDoc to this document |
| // TODO/MBA: make sure that no BaseURL is needed in *this* document |
| LoadStyles(*xTemplDoc); |
| |
| // remember date/time of check |
| xDocProps->setTemplateDate(aTemplDate); |
| // TODO/LATER: new functionality to store document info is required ( didn't work for SO7 XML format ) |
| //REPLACE pInfo->Save(xDocStor); |
| } |
| } |
| } |
| } |
| } |
| |
| sal_Bool SfxObjectShell::IsHelpDocument() const |
| { |
| const SfxFilter* pFilter = GetMedium()->GetFilter(); |
| return ( pFilter && pFilter->GetFilterName().CompareToAscii("writer_web_HTML_help") == COMPARE_EQUAL ); |
| } |
| |
| void SfxObjectShell::ResetFromTemplate( const String& rTemplateName, const String& rFileName ) |
| { |
| // only care about reseting this data for openoffice formats otherwise |
| if ( IsOwnStorageFormat_Impl( *GetMedium()) ) |
| { |
| uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties()); |
| xDocProps->setTemplateURL( ::rtl::OUString() ); |
| xDocProps->setTemplateName( ::rtl::OUString() ); |
| xDocProps->setTemplateDate( util::DateTime() ); |
| xDocProps->resetUserData( ::rtl::OUString() ); |
| |
| // TODO/REFACTOR: |
| // Title? |
| |
| if( ::utl::LocalFileHelper::IsLocalFile( rFileName ) ) |
| { |
| String aFoundName; |
| if( SFX_APP()->Get_Impl()->GetDocumentTemplates()->GetFull( String(), rTemplateName, aFoundName ) ) |
| { |
| INetURLObject aObj( rFileName ); |
| xDocProps->setTemplateURL( aObj.GetMainURL(INetURLObject::DECODE_TO_IURI) ); |
| xDocProps->setTemplateName( rTemplateName ); |
| |
| ::DateTime now; |
| xDocProps->setTemplateDate( util::DateTime( |
| now.Get100Sec(), now.GetSec(), now.GetMin(), |
| now.GetHour(), now.GetDay(), now.GetMonth(), |
| now.GetYear() ) ); |
| |
| SetQueryLoadTemplate( sal_True ); |
| } |
| } |
| } |
| } |
| |
| sal_Bool SfxObjectShell::IsQueryLoadTemplate() const |
| { |
| return pImp->bQueryLoadTemplate; |
| } |
| |
| sal_Bool SfxObjectShell::IsUseUserData() const |
| { |
| return pImp->bUseUserData; |
| } |
| |
| void SfxObjectShell::SetQueryLoadTemplate( sal_Bool bNew ) |
| { |
| if ( pImp->bQueryLoadTemplate != bNew ) |
| SetModified( sal_True ); |
| pImp->bQueryLoadTemplate = bNew; |
| } |
| |
| void SfxObjectShell::SetUseUserData( sal_Bool bNew ) |
| { |
| if ( pImp->bUseUserData != bNew ) |
| SetModified( sal_True ); |
| pImp->bUseUserData = bNew; |
| } |
| |
| sal_Bool SfxObjectShell::IsLoadReadonly() const |
| { |
| return pImp->bLoadReadonly; |
| } |
| |
| sal_Bool SfxObjectShell::IsSaveVersionOnClose() const |
| { |
| return pImp->bSaveVersionOnClose; |
| } |
| |
| void SfxObjectShell::SetLoadReadonly( sal_Bool bNew ) |
| { |
| if ( pImp->bLoadReadonly != bNew ) |
| SetModified( sal_True ); |
| pImp->bLoadReadonly = bNew; |
| } |
| |
| void SfxObjectShell::SetSaveVersionOnClose( sal_Bool bNew ) |
| { |
| if ( pImp->bSaveVersionOnClose != bNew ) |
| SetModified( sal_True ); |
| pImp->bSaveVersionOnClose = bNew; |
| } |
| |
| sal_uInt32 SfxObjectShell::GetModifyPasswordHash() const |
| { |
| return pImp->m_nModifyPasswordHash; |
| } |
| |
| sal_Bool SfxObjectShell::SetModifyPasswordHash( sal_uInt32 nHash ) |
| { |
| if ( ( !IsReadOnly() && !IsReadOnlyUI() ) |
| || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) ) |
| { |
| // the hash can be changed only in editable documents, |
| // or during loading of document |
| pImp->m_nModifyPasswordHash = nHash; |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| uno::Sequence< beans::PropertyValue > SfxObjectShell::GetModifyPasswordInfo() const |
| { |
| return pImp->m_aModifyPasswordInfo; |
| } |
| |
| sal_Bool SfxObjectShell::SetModifyPasswordInfo( const uno::Sequence< beans::PropertyValue >& aInfo ) |
| { |
| if ( ( !IsReadOnly() && !IsReadOnlyUI() ) |
| || !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ) ) |
| { |
| // the hash can be changed only in editable documents, |
| // or during loading of document |
| pImp->m_aModifyPasswordInfo = aInfo; |
| return sal_True; |
| } |
| |
| return sal_False; |
| } |
| |
| void SfxObjectShell::SetModifyPasswordEntered( sal_Bool bEntered ) |
| { |
| pImp->m_bModifyPasswordEntered = bEntered; |
| } |
| |
| sal_Bool SfxObjectShell::IsModifyPasswordEntered() |
| { |
| return pImp->m_bModifyPasswordEntered; |
| } |
| |