diff options
-rwxr-xr-x | sd/source/core/sdpage.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | sd/source/filter/ppt/propread.cxx | 128 | ||||
-rwxr-xr-x | sd/source/ui/toolpanel/ToolPanelViewShell.cxx | 17 | ||||
-rwxr-xr-x | sd/source/ui/toolpanel/controls/DocumentHelper.cxx | 93 | ||||
-rwxr-xr-x | sd/source/ui/view/sdwindow.cxx | 4 |
5 files changed, 164 insertions, 80 deletions
diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx index 6e0da072d..9eeb12c7b 100755 --- a/sd/source/core/sdpage.cxx +++ b/sd/source/core/sdpage.cxx @@ -2355,7 +2355,7 @@ SdrObject* SdPage::InsertAutoLayoutShape( SdrObject* pObj, PresObjKind eObjKind, } } - if ( pObj && ( pObj->IsEmptyPresObj() || !pObj->ISA(SdrGrafObj) ) ) + if ( pObj && (pObj->GetUserCall() || bInit) && ( pObj->IsEmptyPresObj() || !pObj->ISA(SdrGrafObj) ) ) pObj->AdjustToMaxRect( aRect ); return pObj; diff --git a/sd/source/filter/ppt/propread.cxx b/sd/source/filter/ppt/propread.cxx index ae64ac437..873d4abf5 100644..100755 --- a/sd/source/filter/ppt/propread.cxx +++ b/sd/source/filter/ppt/propread.cxx @@ -29,6 +29,7 @@ #include "precompiled_sd.hxx" #include <propread.hxx> #include <tools/bigint.hxx> +#include "tools/debug.hxx" #include "rtl/tencinfo.h" #include "rtl/textenc.h" @@ -90,6 +91,17 @@ void PropItem::Clear() // ----------------------------------------------------------------------- +static xub_StrLen lcl_getMaxSafeStrLen(sal_uInt32 nSize) +{ + nSize -= 1; //Drop NULL terminator + + //If it won't fit in a string, clip it to the max size that does + if (nSize > STRING_MAXLEN) + nSize = STRING_MAXLEN; + + return nSize; +} + BOOL PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign ) { sal_uInt32 i, nItemSize, nType, nItemPos; @@ -108,36 +120,43 @@ BOOL PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign ) { case VT_LPSTR : { - if ( (sal_uInt16)nItemSize ) + if ( nItemSize ) { - sal_Char* pString = new sal_Char[ (sal_uInt16)nItemSize ]; - if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + try { - nItemSize >>= 1; - if ( (sal_uInt16)nItemSize > 1 ) + sal_Char* pString = new sal_Char[ nItemSize ]; + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) { - sal_Unicode* pWString = (sal_Unicode*)pString; - for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) - *this >> pWString[ i ]; - rString = String( pWString, (sal_uInt16)nItemSize - 1 ); - } - else - rString = String(); - bRetValue = sal_True; - } - else - { - SvMemoryStream::Read( pString, (sal_uInt16)nItemSize ); - if ( pString[ (sal_uInt16)nItemSize - 1 ] == 0 ) - { - if ( (sal_uInt16)nItemSize > 1 ) - rString = String( ByteString( pString ), mnTextEnc ); + nItemSize >>= 1; + if ( nItemSize > 1 ) + { + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < nItemSize; i++ ) + *this >> pWString[ i ]; + rString = String( pWString, lcl_getMaxSafeStrLen(nItemSize) ); + } else rString = String(); bRetValue = sal_True; } + else + { + SvMemoryStream::Read( pString, nItemSize ); + if ( pString[ nItemSize - 1 ] == 0 ) + { + if ( nItemSize > 1 ) + rString = String( ByteString( pString ), mnTextEnc ); + else + rString = String(); + bRetValue = sal_True; + } + } + delete[] pString; + } + catch( const std::bad_alloc& ) + { + DBG_ERROR( "sd PropItem::Read bad alloc" ); } - delete[] pString; } if ( bAlign ) SeekRel( ( 4 - ( nItemSize & 3 ) ) & 3 ); // dword align @@ -148,18 +167,25 @@ BOOL PropItem::Read( String& rString, sal_uInt32 nStringType, sal_Bool bAlign ) { if ( nItemSize ) { - sal_Unicode* pString = new sal_Unicode[ (sal_uInt16)nItemSize ]; - for ( i = 0; i < (sal_uInt16)nItemSize; i++ ) - *this >> pString[ i ]; - if ( pString[ i - 1 ] == 0 ) + try { - if ( (sal_uInt16)nItemSize > 1 ) - rString = String( pString, (sal_uInt16)nItemSize - 1 ); - else - rString = String(); - bRetValue = sal_True; + sal_Unicode* pString = new sal_Unicode[ nItemSize ]; + for ( i = 0; i < nItemSize; i++ ) + *this >> pString[ i ]; + if ( pString[ i - 1 ] == 0 ) + { + if ( (sal_uInt16)nItemSize > 1 ) + rString = String( pString, lcl_getMaxSafeStrLen(nItemSize) ); + else + rString = String(); + bRetValue = sal_True; + } + delete[] pString; + } + catch( const std::bad_alloc& ) + { + DBG_ERROR( "sd PropItem::Read bad alloc" ); } - delete[] pString; } if ( bAlign && ( nItemSize & 1 ) ) SeekRel( 2 ); // dword align @@ -349,24 +375,31 @@ sal_Bool Section::GetDictionary( Dictionary& rDict ) for ( sal_uInt32 i = 0; i < nDictCount; i++ ) { aStream >> nId >> nSize; - if ( (sal_uInt16)nSize ) + if ( nSize ) { String aString; nPos = aStream.Tell(); - sal_Char* pString = new sal_Char[ (sal_uInt16)nSize ]; - aStream.Read( pString, (sal_uInt16)nSize ); - if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + try { - nSize >>= 1; - aStream.Seek( nPos ); - sal_Unicode* pWString = (sal_Unicode*)pString; - for ( i = 0; i < (sal_uInt16)nSize; i++ ) - aStream >> pWString[ i ]; - aString = String( pWString, (sal_uInt16)nSize - 1 ); + sal_Char* pString = new sal_Char[ nSize ]; + aStream.Read( pString, nSize ); + if ( mnTextEnc == RTL_TEXTENCODING_UCS2 ) + { + nSize >>= 1; + aStream.Seek( nPos ); + sal_Unicode* pWString = (sal_Unicode*)pString; + for ( i = 0; i < nSize; i++ ) + aStream >> pWString[ i ]; + aString = String( pWString, lcl_getMaxSafeStrLen(nSize) ); + } + else + aString = String( ByteString( pString, lcl_getMaxSafeStrLen(nSize) ), mnTextEnc ); + delete[] pString; + } + catch( const std::bad_alloc& ) + { + DBG_ERROR( "sd Section::GetDictionary bad alloc" ); } - else - aString = String( ByteString( pString, (sal_uInt16)nSize - 1 ), mnTextEnc ); - delete[] pString; if ( !aString.Len() ) break; aDict.AddProperty( nId, aString ); @@ -500,6 +533,11 @@ void Section::Read( SvStorageStream *pStrm ) } if ( nPropSize ) { + if ( nPropSize > nStrmSize ) + { + nPropCount = 0; + break; + } pStrm->Seek( nPropOfs + nSecOfs ); sal_uInt8* pBuf = new sal_uInt8[ nPropSize ]; pStrm->Read( pBuf, nPropSize ); diff --git a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx index e8cdd0619..4e7e55eea 100755 --- a/sd/source/ui/toolpanel/ToolPanelViewShell.cxx +++ b/sd/source/ui/toolpanel/ToolPanelViewShell.cxx @@ -512,12 +512,20 @@ ToolPanelViewShell::ToolPanelViewShell( SfxViewFrame* pFrame, ViewShellBase& rVi SetName( String( RTL_CONSTASCII_USTRINGPARAM( "ToolPanelViewShell" ) ) ); + // Some recent changes to the toolpanel make it necessary to create the + // accessibility object now. Creating it on demand would lead to a + // pointer cycle in the tree of accessibility objects and would lead + // e.g. the accerciser AT tool into an infinite loop. + // It would be nice to get rid of this workaround in the future. + if (mpContentWindow.get()) + mpContentWindow->SetAccessible(mpImpl->CreateAccessible(*mpContentWindow)); + // For accessibility we have to shortly hide the content window. This // triggers the construction of a new accessibility object for the new // view shell. (One is created earlier while the construtor of the base // class is executed. At that time the correct accessibility object can // not be constructed.) - if ( mpContentWindow.get() ) + if (mpContentWindow.get()) { mpContentWindow->Hide(); mpContentWindow->Show(); @@ -633,7 +641,12 @@ DockingWindow* ToolPanelViewShell::GetDockingWindow() Reference< XAccessible > ToolPanelViewShell::CreateAccessibleDocumentView( ::sd::Window* i_pWindow ) { ENSURE_OR_RETURN( i_pWindow, "ToolPanelViewShell::CreateAccessibleDocumentView: illegal window!", NULL ); - return mpImpl->CreateAccessible( *i_pWindow ); + // As said above, we have to create the accessibility object + // (unconditionally) in the constructor, not here on demand, or + // otherwise we would create a cycle in the tree of accessible objects + // which could lead to infinite loops in AT tools. + // return mpImpl->CreateAccessible( *i_pWindow ); + return Reference<XAccessible>(); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/sd/source/ui/toolpanel/controls/DocumentHelper.cxx b/sd/source/ui/toolpanel/controls/DocumentHelper.cxx index 7267c9722..2c29399a3 100755 --- a/sd/source/ui/toolpanel/controls/DocumentHelper.cxx +++ b/sd/source/ui/toolpanel/controls/DocumentHelper.cxx @@ -503,45 +503,78 @@ SdPage* DocumentHelper::ProvideMasterPage ( SdPage* pMasterPage, const ::boost::shared_ptr<std::vector<SdPage*> >& rpPageList) { - SdPage* pMasterPageInDocument = NULL; - - // Get notes master page. + // Make sure that both the master page and its notes master exist + // in the source document. If one is missing then return without + // making any changes. + if (pMasterPage == NULL) + { + // The caller should make sure that the master page is valid. + OSL_ASSERT(pMasterPage != NULL); + return NULL; + } SdDrawDocument* pSourceDocument = static_cast<SdDrawDocument*>(pMasterPage->GetModel()); + if (pSourceDocument == NULL) + return NULL; SdPage* pNotesMasterPage = static_cast<SdPage*>( - pSourceDocument->GetMasterPage (pMasterPage->GetPageNum()+1)); - if (pNotesMasterPage != NULL) + pSourceDocument->GetMasterPage(pMasterPage->GetPageNum()+1)); + if (pNotesMasterPage == NULL) + { + // The model is not in a valid state. Maybe a new master page + // is being (not finished yet) created? Return without making + // any changes. + return NULL; + } + + SdPage* pMasterPageInDocument = NULL; + // Search for a master page with the same name as the given one in + // the target document. + const XubString sMasterPageLayoutName (pMasterPage->GetLayoutName()); + for (USHORT nIndex=0,nCount=rTargetDocument.GetMasterPageCount(); nIndex<nCount; ++nIndex) { - // When the given master page or its associated notes master page do - // not already belong to the document we have to create copies of - // them and insert them into the document. - - // Determine the position where the new master pages are inserted. - // By default they are inserted at the end. When we assign to a - // master page then insert after the last of the (selected) pages. - USHORT nInsertionIndex = rTargetDocument.GetMasterPageCount(); - if (rpPageList->front()->IsMasterPage()) + SdPage* pCandidate = static_cast<SdPage*>(rTargetDocument.GetMasterPage(nIndex)); + if (pCandidate!=NULL + && sMasterPageLayoutName==pCandidate->GetLayoutName()) { - nInsertionIndex = rpPageList->back()->GetPageNum(); + // The requested master page does already exist in the + // target document, return it. + return pCandidate; } + } + + // The given master page does not already belong to the target + // document so we have to create copies and insert them into the + // targer document. + + // Determine the position where the new master pages are inserted. + // By default they are inserted at the end. When we assign to a + // master page then insert after the last of the (selected) pages. + USHORT nInsertionIndex = rTargetDocument.GetMasterPageCount(); + if (rpPageList->front()->IsMasterPage()) + { + nInsertionIndex = rpPageList->back()->GetPageNum(); + } - if (pMasterPage->GetModel() != &rTargetDocument) - { - pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex); - if( rTargetDocument.IsUndoEnabled() ) + // Clone the master page. + if (pMasterPage->GetModel() != &rTargetDocument) + { + pMasterPageInDocument = AddMasterPage (rTargetDocument, pMasterPage, nInsertionIndex); + if( rTargetDocument.IsUndoEnabled() ) rTargetDocument.AddUndo( rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pMasterPageInDocument)); - } - else - pMasterPageInDocument = pMasterPage; - if (pNotesMasterPage->GetModel() != &rTargetDocument) - { - SdPage* pClonedNotesMasterPage - = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1); - if( rTargetDocument.IsUndoEnabled() ) - rTargetDocument.AddUndo( - rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage)); - } } + else + pMasterPageInDocument = pMasterPage; + + // Clone the notes master. + if (pNotesMasterPage->GetModel() != &rTargetDocument) + { + SdPage* pClonedNotesMasterPage + = AddMasterPage (rTargetDocument, pNotesMasterPage, nInsertionIndex+1); + if( rTargetDocument.IsUndoEnabled() ) + rTargetDocument.AddUndo( + rTargetDocument.GetSdrUndoFactory().CreateUndoNewPage(*pClonedNotesMasterPage)); + } + return pMasterPageInDocument; } diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index 4f8dfe917..9290bc6c1 100755 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -1165,11 +1165,11 @@ void Window::DropScroll(const Point& rMousePos) Window::CreateAccessible (void) { if (mpViewShell != NULL) - return mpViewShell->CreateAccessibleDocumentView (this); + return mpViewShell->CreateAccessibleDocumentView (this); else { OSL_TRACE ("::sd::Window::CreateAccessible: no view shell"); - return ::Window::CreateAccessible (); + return ::Window::CreateAccessible (); } } |