From 69c363daff7def74bb91b72bc778ace0e698f0e3 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Fri, 19 Mar 2010 16:19:31 +0100 Subject: gozer1: #161853# add default border depending on App font --- vcl/inc/vcl/arrange.hxx | 17 ++++-- vcl/inc/vcl/svdata.hxx | 2 + vcl/source/app/svdata.cxx | 3 + vcl/source/window/arrange.cxx | 129 ++++++++++++++++++++++++++--------------- vcl/source/window/printdlg.cxx | 38 +++++------- vcl/source/window/window.cxx | 2 + 6 files changed, 114 insertions(+), 77 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index 309d0bf930ea..cd4a513987aa 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -110,6 +110,11 @@ namespace vcl public: + static long getDefaultBorder(); + + static long getBorderValue( long nBorder ) + { return nBorder >= 0 ? nBorder : getDefaultBorder(); } + WindowArranger( WindowArranger* i_pParent = NULL ) : m_pParentWindow( i_pParent ? i_pParent->m_pParentWindow : NULL ) , m_pParentArranger( i_pParent ) @@ -207,7 +212,7 @@ namespace vcl public: RowOrColumn( WindowArranger* i_pParent = NULL, - bool bColumn = true, long i_nBorderWidth = 5 ) + bool bColumn = true, long i_nBorderWidth = -1 ) : WindowArranger( i_pParent ) , m_nBorderWidth( i_nBorderWidth ) , m_bColumn( bColumn ) @@ -251,7 +256,7 @@ namespace vcl } public: - LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = 5 ) + LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = -1 ) : WindowArranger( i_pParent ) , m_nDistance( i_nDistance ) , m_nLabelColumnWidth( 0 ) @@ -281,7 +286,7 @@ namespace vcl { long getLabelWidth() const; public: - LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = 5 ) + LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = -1 ) : RowOrColumn( i_pParent, true, i_nBorderWidth ) {} virtual ~LabelColumn(); @@ -304,7 +309,7 @@ namespace vcl { return i_nIndex == 0 ? &m_aElement : NULL; } public: - Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 15 ) + Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 3*getDefaultBorder() ) : WindowArranger( i_pParent ) , m_nIndent( i_nIndent ) {} @@ -395,8 +400,8 @@ namespace vcl public: MatrixArranger( WindowArranger* i_pParent = NULL, - long i_nBorderX = 5, - long i_nBorderY = 5 ) + long i_nBorderX = -1, + long i_nBorderY = -1 ) : WindowArranger( i_pParent ) , m_nBorderX( i_nBorderX ) , m_nBorderY( i_nBorderY ) diff --git a/vcl/inc/vcl/svdata.hxx b/vcl/inc/vcl/svdata.hxx index 081b2fffca0b..69ba1a5c3013 100644 --- a/vcl/inc/vcl/svdata.hxx +++ b/vcl/inc/vcl/svdata.hxx @@ -171,6 +171,8 @@ struct ImplSVAppData BOOL mbDialogCancel; // TRUE: Alle Dialog::Execute()-Aufrufe werden mit return FALSE sofort beendet BOOL mbNoYield; // Application::Yield will not wait for events if the queue is empty // essentially that makes it the same as Application::Reschedule + long mnDefaultLayoutBorder; // default value in pixel for layout distances used + // in window arrangers /** Controls whether showing any IME status window is toggled on or off. diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index e8e56c6ee5a8..0600d081d04b 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -131,6 +131,9 @@ void ImplInitSVData() break; } } + + // mark default layout border as unitialized + pImplSVData->maAppData.mnDefaultLayoutBorder = -1; } // ----------------------------------------------------------------------- diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx index 0199af7ed50d..76e2d3f28747 100644 --- a/vcl/source/window/arrange.cxx +++ b/vcl/source/window/arrange.cxx @@ -32,6 +32,8 @@ #include "vcl/arrange.hxx" #include "vcl/edit.hxx" +#include "vcl/svdata.hxx" +#include "vcl/svapp.hxx" #include "osl/diagnose.h" @@ -41,6 +43,22 @@ using namespace vcl; // vcl::WindowArranger //----------------------------------------- +long WindowArranger::getDefaultBorder() +{ + ImplSVData* pSVData = ImplGetSVData(); + long nResult = pSVData->maAppData.mnDefaultLayoutBorder; + if( nResult < 0 ) + { + OutputDevice* pDefDev = Application::GetDefaultDevice(); + if( pDefDev ) + { + Size aBorder( pDefDev->LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + nResult = pSVData->maAppData.mnDefaultLayoutBorder = aBorder.Height(); + } + } + return nResult > 0 ? nResult : 0; +} + WindowArranger::~WindowArranger() {} @@ -167,8 +185,8 @@ Size WindowArranger::Element::getOptimalSize( WindowSizeType i_eType ) const aResult.Width() = m_aMinSize.Width(); if( aResult.Height() < m_aMinSize.Height() ) aResult.Height() = m_aMinSize.Height(); - aResult.Width() += m_nLeftBorder + m_nRightBorder; - aResult.Height() += m_nTopBorder + m_nBottomBorder; + aResult.Width() += getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); + aResult.Height() += getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); } return aResult; @@ -178,10 +196,10 @@ void WindowArranger::Element::setPosSize( const Point& i_rPos, const Size& i_rSi { Point aPoint( i_rPos ); Size aSize( i_rSize ); - aPoint.X() += m_nLeftBorder; - aPoint.Y() += m_nTopBorder; - aSize.Width() -= m_nLeftBorder + m_nRightBorder; - aSize.Height() -= m_nTopBorder + m_nBottomBorder; + aPoint.X() += getBorderValue( m_nLeftBorder ); + aPoint.Y() += getBorderValue( m_nTopBorder ); + aSize.Width() -= getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); + aSize.Height() -= getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); if( m_pElement ) m_pElement->SetPosSizePixel( aPoint, aSize ); else if( m_pChild ) @@ -204,6 +222,7 @@ RowOrColumn::~RowOrColumn() Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const { Size aRet( 0, 0 ); + long nDistance = getBorderValue( m_nBorderWidth ); for( std::vector< WindowArranger::Element >::const_iterator it = m_aElements.begin(); it != m_aElements.end(); ++it ) { @@ -214,7 +233,7 @@ Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const if( m_bColumn ) { // add the distance between elements - aRet.Height() += m_nBorderWidth; + aRet.Height() += nDistance; // check if the width needs adjustment if( aRet.Width() < aElementSize.Width() ) aRet.Width() = aElementSize.Width(); @@ -223,7 +242,7 @@ Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const else { // add the distance between elements - aRet.Width() += m_nBorderWidth; + aRet.Width() += nDistance; // check if the height needs adjustment if( aRet.Height() < aElementSize.Height() ) aRet.Height() = aElementSize.Height(); @@ -236,13 +255,14 @@ Size RowOrColumn::getOptimalSize( WindowSizeType i_eType ) const { // subtract the border for the first element if( m_bColumn ) - aRet.Height() -= m_nBorderWidth; + aRet.Height() -= nDistance; else - aRet.Width() -= m_nBorderWidth; + aRet.Width() -= nDistance; // add the outer border - aRet.Width() += 2*m_nOuterBorder; - aRet.Height() += 2*m_nOuterBorder; + long nOuterBorder = getBorderValue( m_nOuterBorder ); + aRet.Width() += 2*nOuterBorder; + aRet.Height() += 2*nOuterBorder; } return aRet; @@ -347,7 +367,9 @@ void RowOrColumn::resize() size_t nElements = m_aElements.size(); // get all element sizes for sizing std::vector aElementSizes( nElements ); - long nUsedWidth = 2*m_nOuterBorder - (nElements ? m_nBorderWidth : 0); + long nDistance = getBorderValue( m_nBorderWidth ); + long nOuterBorder = getBorderValue( m_nOuterBorder ); + long nUsedWidth = 2*nOuterBorder - (nElements ? nDistance : 0); for( size_t i = 0; i < nElements; i++ ) { if( m_aElements[i].isVisible() ) @@ -355,13 +377,13 @@ void RowOrColumn::resize() aElementSizes[i] = m_aElements[i].getOptimalSize( eType ); if( m_bColumn ) { - aElementSizes[i].Width() = m_aManagedArea.GetWidth() - 2* m_nOuterBorder; - nUsedWidth += aElementSizes[i].Height() + m_nBorderWidth; + aElementSizes[i].Width() = m_aManagedArea.GetWidth() - 2 * nOuterBorder; + nUsedWidth += aElementSizes[i].Height() + nDistance; } else { - aElementSizes[i].Height() = m_aManagedArea.GetHeight() - 2* m_nOuterBorder; - nUsedWidth += aElementSizes[i].Width() + m_nBorderWidth; + aElementSizes[i].Height() = m_aManagedArea.GetHeight() - 2 * nOuterBorder; + nUsedWidth += aElementSizes[i].Width() + nDistance; } } } @@ -378,8 +400,8 @@ void RowOrColumn::resize() // get starting position Point aElementPos( m_aManagedArea.TopLeft() ); // outer border - aElementPos.X() += m_nOuterBorder; - aElementPos.Y() += m_nOuterBorder; + aElementPos.X() += nOuterBorder; + aElementPos.Y() += nOuterBorder; // position managed windows for( size_t i = 0; i < nElements; i++ ) @@ -389,9 +411,9 @@ void RowOrColumn::resize() { m_aElements[i].setPosSize( aElementPos, aElementSizes[i] ); if( m_bColumn ) - aElementPos.Y() += m_nBorderWidth + aElementSizes[i].Height(); + aElementPos.Y() += nDistance + aElementSizes[i].Height(); else - aElementPos.X() += m_nBorderWidth + aElementSizes[i].Width(); + aElementPos.X() += nDistance + aElementSizes[i].Width(); } } } @@ -482,14 +504,14 @@ Size LabeledElement::getOptimalSize( WindowSizeType i_eType ) const if( m_nLabelColumnWidth != 0 ) aRet.Width() = m_nLabelColumnWidth; else - aRet.Width() += m_nDistance; + aRet.Width() += getBorderValue( m_nDistance ); } Size aElementSize( m_aElement.getOptimalSize( i_eType ) ); aRet.Width() += aElementSize.Width(); if( aElementSize.Height() > aRet.Height() ) aRet.Height() = aElementSize.Height(); if( aRet.Height() != 0 ) - aRet.Height() += 2*m_nOuterBorder; + aRet.Height() += 2 * getBorderValue( m_nOuterBorder ); return aRet; } @@ -498,23 +520,25 @@ void LabeledElement::resize() { Size aLabelSize( m_aLabel.getOptimalSize( WINDOWSIZE_MINIMUM ) ); Size aElementSize( m_aElement.getOptimalSize( WINDOWSIZE_PREFERRED ) ); - if( m_nDistance + aLabelSize.Width() + aElementSize.Width() > m_aManagedArea.GetWidth() ) + long nDistance = getBorderValue( m_nDistance ); + long nOuterBorder = getBorderValue( m_nOuterBorder ); + if( nDistance + aLabelSize.Width() + aElementSize.Width() > m_aManagedArea.GetWidth() ) aElementSize = m_aElement.getOptimalSize( WINDOWSIZE_MINIMUM ); // align label and element vertically in LabeledElement - long nYOff = (m_aManagedArea.GetHeight() - 2*m_nOuterBorder - aLabelSize.Height()) / 2; + long nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aLabelSize.Height()) / 2; Point aPos( m_aManagedArea.Left(), - m_aManagedArea.Top() + m_nOuterBorder + nYOff ); + m_aManagedArea.Top() + nOuterBorder + nYOff ); Size aSize( aLabelSize ); if( m_nLabelColumnWidth != 0 ) aSize.Width() = m_nLabelColumnWidth; m_aLabel.setPosSize( aPos, aSize ); - aPos.X() += aSize.Width() + m_nDistance; - nYOff = (m_aManagedArea.GetHeight() - 2*m_nOuterBorder - aElementSize.Height()) / 2; - aPos.Y() = m_aManagedArea.Top() + m_nOuterBorder + nYOff; + aPos.X() += aSize.Width() + nDistance; + nYOff = (m_aManagedArea.GetHeight() - 2*nOuterBorder - aElementSize.Height()) / 2; + aPos.Y() = m_aManagedArea.Top() + nOuterBorder + nYOff; aSize.Width() = aElementSize.Width(); - aSize.Height() = m_aManagedArea.GetHeight() - 2*m_nOuterBorder; + aSize.Height() = m_aManagedArea.GetHeight() - 2*nOuterBorder; // label style // 0: position left and right @@ -593,6 +617,7 @@ long LabelColumn::getLabelWidth() const Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const { long nWidth = getLabelWidth(); + long nOuterBorder = getBorderValue( m_nOuterBorder ); Size aColumnSize; // every child is a LabeledElement @@ -625,7 +650,7 @@ Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const } if( aElementSize.Width() ) { - aElementSize.Width() += 2*m_nOuterBorder; + aElementSize.Width() += 2*nOuterBorder; if( aElementSize.Width() > aColumnSize.Width() ) aColumnSize.Width() = aElementSize.Width(); } @@ -637,7 +662,7 @@ Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const if( nEle > 0 && aColumnSize.Height() ) { aColumnSize.Height() -= getBorderWidth(); // for the first element - aColumnSize.Height() += 2*m_nOuterBorder; + aColumnSize.Height() += 2*nOuterBorder; } return aColumnSize; } @@ -693,19 +718,23 @@ Indenter::~Indenter() Size Indenter::getOptimalSize( WindowSizeType i_eType ) const { Size aSize( m_aElement.getOptimalSize( i_eType ) ); - aSize.Width() += 2*m_nOuterBorder + m_nIndent; - aSize.Height() += 2*m_nOuterBorder; + long nOuterBorder = getBorderValue( m_nOuterBorder ); + long nIndent = getBorderValue( m_nIndent ); + aSize.Width() += 2*nOuterBorder + nIndent; + aSize.Height() += 2*nOuterBorder; return aSize; } void Indenter::resize() { + long nOuterBorder = getBorderValue( m_nOuterBorder ); + long nIndent = getBorderValue( m_nIndent ); Point aPt( m_aManagedArea.TopLeft() ); - aPt.X() += m_nOuterBorder + m_nIndent; - aPt.Y() += m_nOuterBorder; + aPt.X() += nOuterBorder + m_nIndent; + aPt.Y() += nOuterBorder; Size aSz( m_aManagedArea.GetSize() ); - aSz.Width() -= 2*m_nOuterBorder + m_nIndent; - aSz.Height() -= 2*m_nOuterBorder; + aSz.Width() -= 2*nOuterBorder + nIndent; + aSz.Height() -= 2*nOuterBorder; m_aElement.setPosSize( aPt, aSz ); } @@ -733,7 +762,8 @@ MatrixArranger::~MatrixArranger() Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector& o_rColumnWidths, std::vector& o_rRowHeights ) const { - Size aMatrixSize( 2*m_nOuterBorder, 2*m_nOuterBorder ); + long nOuterBorder = getBorderValue( m_nOuterBorder ); + Size aMatrixSize( 2*nOuterBorder, 2*nOuterBorder ); // first find out the current number of rows and columns sal_uInt32 nRows = 0, nColumns = 0; @@ -762,15 +792,17 @@ Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector& } // add up sizes + long nDistanceX = getBorderValue( m_nBorderX ); + long nDistanceY = getBorderValue( m_nBorderY ); for( sal_uInt32 i = 0; i < nColumns; i++ ) - aMatrixSize.Width() += o_rColumnWidths[i] + m_nBorderX; + aMatrixSize.Width() += o_rColumnWidths[i] + nDistanceX; if( nColumns > 0 ) - aMatrixSize.Width() -= m_nBorderX; + aMatrixSize.Width() -= nDistanceX; for( sal_uInt32 i = 0; i < nRows; i++ ) - aMatrixSize.Height() += o_rRowHeights[i] + m_nBorderY; + aMatrixSize.Height() += o_rRowHeights[i] + nDistanceY; if( nRows > 0 ) - aMatrixSize.Height() -= m_nBorderY; + aMatrixSize.Height() -= nDistanceY; return aMatrixSize; } @@ -804,15 +836,18 @@ void MatrixArranger::resize() // FIXME: distribute extra space available // prepare offsets + long nDistanceX = getBorderValue( m_nBorderX ); + long nDistanceY = getBorderValue( m_nBorderY ); + long nOuterBorder = getBorderValue( m_nOuterBorder ); std::vector aColumnX( aColumnWidths.size() ); - aColumnX[0] = m_aManagedArea.Left() + m_nOuterBorder; + aColumnX[0] = m_aManagedArea.Left() + nOuterBorder; for( size_t i = 1; i < aColumnX.size(); i++ ) - aColumnX[i] = aColumnX[i-1] + aColumnWidths[i-1] + m_nBorderX; + aColumnX[i] = aColumnX[i-1] + aColumnWidths[i-1] + nDistanceX; std::vector aRowY( aRowHeights.size() ); - aRowY[0] = m_aManagedArea.Top() + m_nOuterBorder; + aRowY[0] = m_aManagedArea.Top() + nOuterBorder; for( size_t i = 1; i < aRowY.size(); i++ ) - aRowY[i] = aRowY[i-1] + aRowHeights[i-1] + m_nBorderY; + aRowY[i] = aRowY[i-1] + aRowHeights[i-1] + nDistanceY; // now iterate over the elements and assign their positions for( std::vector< MatrixElement >::iterator it = m_aElements.begin(); diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 649ca21a32b8..9d7e714ede11 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -411,11 +411,9 @@ void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow ) void PrintDialog::NUpTabPage::setupLayout() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - long nIndent = 3*aBorder.Width(); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( aBorder.Width() ); + maLayout.setOuterBorder( -1 ); + long nIndent = 3*WindowArranger::getDefaultBorder(); maLayout.addWindow( &maNupLine ); boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( &maLayout, false ) ); @@ -455,7 +453,7 @@ void PrintDialog::NUpTabPage::setupLayout() xMainCol->addRow( &maNupOrderTxt, &maNupOrderBox, nIndent ); xMainCol->setBorders( xMainCol->addWindow( &maBorderCB ), nIndent, 0, 0, 0 ); - xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, aBorder.Width() ) ) ); + xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, WindowArranger::getDefaultBorder() ) ) ); xMainCol->addChild( xSpacer ); xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) ); @@ -552,10 +550,8 @@ void PrintDialog::JobTabPage::setupLayout() // sets the results of GetOptimalSize in a normal ListBox maPrinters.SetDropDownLineCount( 4 ); - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( aBorder.Width() ); + maLayout.setOuterBorder( -1 ); // add printer fixed line maLayout.addWindow( &maPrinterFL ); @@ -575,7 +571,7 @@ void PrintDialog::JobTabPage::setupLayout() // remember details controls mxDetails = xIndent; // create a column for the details - boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get(), aBorder.Height() ) ); + boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get() ) ); xIndent->setChild( xLabelCol ); xLabelCol->addRow( &maStatusLabel, &maStatusTxt ); xLabelCol->addRow( &maLocationLabel, &maLocationTxt ); @@ -583,7 +579,7 @@ void PrintDialog::JobTabPage::setupLayout() // add print range and copies columns maLayout.addWindow( &maCopies ); - boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false, aBorder.Width() ) ); + boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false ) ); maLayout.addChild( xRangeRow ); // create print range and add to range row @@ -679,15 +675,13 @@ PrintDialog::OutputOptPage::~OutputOptPage() void PrintDialog::OutputOptPage::setupLayout() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( aBorder.Width() ); + maLayout.setOuterBorder( -1 ); maLayout.addWindow( &maOptionsLine ); - boost::shared_ptr xIndent( new vcl::Indenter( &maLayout, aBorder.Width() ) ); + boost::shared_ptr xIndent( new vcl::Indenter( &maLayout, -1 ) ); maLayout.addChild( xIndent ); - boost::shared_ptr xCol( new vcl::RowOrColumn( xIndent.get(), aBorder.Height() ) ); + boost::shared_ptr xCol( new vcl::RowOrColumn( xIndent.get() ) ); xIndent->setChild( xCol ); mxOptGroup = xCol; xCol->addWindow( &maToFileBox ); @@ -927,13 +921,11 @@ PrintDialog::~PrintDialog() void PrintDialog::setupLayout() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - maLayout.setParentWindow( this ); boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( &maLayout, false ) ); size_t nIndex = maLayout.addChild( xPreviewAndTab, 5 ); - maLayout.setBorders( nIndex, aBorder.Width(), aBorder.Width(), aBorder.Width(), 0 ); + maLayout.setBorders( nIndex, -1, -1, -1, 0 ); // setup column for preview and sub controls boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) ); @@ -962,7 +954,7 @@ void PrintDialog::setupLayout() // add the row for the buttons boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( &maLayout, false ) ); nIndex = maLayout.addChild( xButtons ); - maLayout.setBorders( nIndex, aBorder.Width(), 0, aBorder.Width(), aBorder.Width() ); + maLayout.setBorders( nIndex, -1, 0, -1, -1 ); Size aMinSize( maCancelButton.GetSizePixel() ); // insert help button @@ -1068,8 +1060,6 @@ void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) void PrintDialog::setupOptionalUI() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - std::vector aDynamicColumns; vcl::RowOrColumn* pCurColumn = 0; @@ -1239,10 +1229,10 @@ void PrintDialog::setupOptionalUI() // reset subgroup counter nCurSubGroup = 0; - aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true, aBorder.Width() ) ); + aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true ) ); pCurColumn = aDynamicColumns.back(); pCurColumn->setParentWindow( pNewGroup ); - pCurColumn->setOuterBorder( aBorder.Width() ); + pCurColumn->setOuterBorder( -1 ); bSubgroupOnStaticPage = false; bOnStaticPage = false; } @@ -1272,7 +1262,7 @@ void PrintDialog::setupOptionalUI() } // add an indent to the current column - vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, aBorder.Width() ); + vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, -1 ); pCurColumn->addChild( pIndent ); // and create a column inside the indent pCurColumn = new vcl::RowOrColumn( pIndent ); diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 5689972e69d6..3c9767639538 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -298,6 +298,8 @@ void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, BOOL bCallHdl ) aTmpSt.SetHighContrastMode( FALSE ); rSettings.SetStyleSettings( aTmpSt ); ImplGetFrame()->UpdateSettings( rSettings ); + // reset default border width for layouters + ImplGetSVData()->maAppData.mnDefaultLayoutBorder = -1; // Verify availability of the configured UI font, otherwise choose "Andale Sans UI" String aUserInterfaceFont; -- cgit v1.2.3 From d345375cfcda1022aeb867e32f0eef24436e2dfa Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Mon, 22 Mar 2010 19:53:06 +0100 Subject: gozer1: #161853# put an on demand WindowArranger on Window --- vcl/inc/vcl/arrange.hxx | 2 +- vcl/inc/vcl/prndlg.hxx | 10 +-- vcl/inc/vcl/window.h | 6 +- vcl/inc/vcl/window.hxx | 16 +++- vcl/source/window/arrange.cxx | 10 +-- vcl/source/window/makefile.mk | 1 + vcl/source/window/printdlg.cxx | 178 ++++++++++++++++++----------------------- vcl/source/window/window.cxx | 5 ++ vcl/source/window/window4.cxx | 94 ++++++++++++++++++++++ 9 files changed, 206 insertions(+), 116 deletions(-) create mode 100644 vcl/source/window/window4.cxx (limited to 'vcl') diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index cd4a513987aa..5b9a1d296513 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -113,7 +113,7 @@ namespace vcl static long getDefaultBorder(); static long getBorderValue( long nBorder ) - { return nBorder >= 0 ? nBorder : getDefaultBorder(); } + { return nBorder >= 0 ? nBorder : -nBorder * getDefaultBorder(); } WindowArranger( WindowArranger* i_pParent = NULL ) : m_pParentWindow( i_pParent ? i_pParent->m_pParentWindow : NULL ) diff --git a/vcl/inc/vcl/prndlg.hxx b/vcl/inc/vcl/prndlg.hxx index 6ac22e0708db..c2876ca0040f 100644 --- a/vcl/inc/vcl/prndlg.hxx +++ b/vcl/inc/vcl/prndlg.hxx @@ -129,7 +129,6 @@ namespace vcl // border around each page CheckBox maBorderCB; - vcl::RowOrColumn maLayout; boost::shared_ptr< vcl::RowOrColumn > mxBrochureDep; boost::shared_ptr< vcl::LabeledElement >mxPagesBtnLabel; @@ -145,7 +144,7 @@ namespace vcl void showAdvancedControls( bool ); - virtual void Resize(); + // virtual void Resize(); }; class JobTabPage : public TabPage @@ -177,7 +176,6 @@ namespace vcl long mnCollateUIMode; - vcl::RowOrColumn maLayout; boost::shared_ptr mxPrintRange; boost::shared_ptr mxDetails; @@ -187,7 +185,7 @@ namespace vcl void readFromSettings(); void storeToSettings(); - virtual void Resize(); + // virtual void Resize(); void setupLayout(); }; @@ -200,7 +198,6 @@ namespace vcl CheckBox maCollateSingleJobsBox; CheckBox maReverseOrderBox; - vcl::RowOrColumn maLayout; boost::shared_ptr mxOptGroup; OutputOptPage( Window*, const ResId& ); @@ -209,7 +206,7 @@ namespace vcl void readFromSettings(); void storeToSettings(); - virtual void Resize(); + // virtual void Resize(); void setupLayout(); }; @@ -254,7 +251,6 @@ namespace vcl rtl::OUString maPrintText; rtl::OUString maDefPrtText; - vcl::RowOrColumn maLayout; boost::shared_ptr mxPreviewCtrls; Size maDetailsCollapsedSize; diff --git a/vcl/inc/vcl/window.h b/vcl/inc/vcl/window.h index 0fec51e2e702..2fc11f84026c 100644 --- a/vcl/inc/vcl/window.h +++ b/vcl/inc/vcl/window.h @@ -103,7 +103,10 @@ namespace dnd { class XDropTarget; } } } } } -namespace vcl { struct ControlLayoutData; } +namespace vcl { + struct ControlLayoutData; + struct ExtWindowImpl; +} @@ -244,6 +247,7 @@ public: ImplDelData* mpFirstDel; void* mpUserData; + vcl::ExtWindowImpl* mpExtImpl; Cursor* mpCursor; Pointer maPointer; Fraction maZoom; diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index c14ee7add4fb..8fa63633eeef 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -54,6 +54,7 @@ #include #include #include +#include class VirtualDevice; struct ImplDelData; @@ -125,7 +126,11 @@ namespace dnd { class XDropTarget; } } } } } -namespace vcl { struct ControlLayoutData; } +namespace vcl { + struct ControlLayoutData; + class WindowArranger; + struct ExtWindowImpl; +} // --------------- // - WindowTypes - @@ -475,6 +480,9 @@ public: SAL_DLLPRIVATE BOOL ImplUpdatePos(); SAL_DLLPRIVATE void ImplUpdateSysObjPos(); SAL_DLLPRIVATE WindowImpl* ImplGetWindowImpl() const { return mpWindowImpl; } + SAL_DLLPRIVATE void ImplFreeExtWindowImpl(); + // creates ExtWindowImpl on demand, but may return NULL (e.g. if mbInDtor) + SAL_DLLPRIVATE vcl::ExtWindowImpl* ImplGetExtWindowImpl() const; /** check whether a font is suitable for UI The font to be tested will be checked whether it could display a @@ -540,6 +548,7 @@ public: SAL_DLLPRIVATE BOOL ImplRegisterAccessibleNativeFrame(); SAL_DLLPRIVATE void ImplRevokeAccessibleNativeFrame(); SAL_DLLPRIVATE void ImplCallResize(); + SAL_DLLPRIVATE void ImplExtResize(); SAL_DLLPRIVATE void ImplCallMove(); SAL_DLLPRIVATE Rectangle ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle& rRect ) const; SAL_DLLPRIVATE void ImplMirrorFramePos( Point &pt ) const; @@ -1142,6 +1151,11 @@ public: virtual XubString GetSurroundingText() const; virtual Selection GetSurroundingTextSelection() const; + + // ExtImpl + + // layouting + boost::shared_ptr< vcl::WindowArranger > getLayout(); }; diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx index 76e2d3f28747..64db5426dc5b 100644 --- a/vcl/source/window/arrange.cxx +++ b/vcl/source/window/arrange.cxx @@ -52,7 +52,7 @@ long WindowArranger::getDefaultBorder() OutputDevice* pDefDev = Application::GetDefaultDevice(); if( pDefDev ) { - Size aBorder( pDefDev->LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + Size aBorder( pDefDev->LogicToPixel( Size( 3, 3 ), MapMode( MAP_APPFONT ) ) ); nResult = pSVData->maAppData.mnDefaultLayoutBorder = aBorder.Height(); } } @@ -611,7 +611,7 @@ long LabelColumn::getLabelWidth() const } } } - return nWidth + getBorderWidth(); + return nWidth + getBorderValue( getBorderWidth() ); } Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const @@ -656,12 +656,12 @@ Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const } if( aElementSize.Height() ) { - aColumnSize.Height() += getBorderWidth() + aElementSize.Height(); + aColumnSize.Height() += getBorderValue( getBorderWidth() ) + aElementSize.Height(); } } if( nEle > 0 && aColumnSize.Height() ) { - aColumnSize.Height() -= getBorderWidth(); // for the first element + aColumnSize.Height() -= getBorderValue( getBorderWidth() ); // for the first element aColumnSize.Height() += 2*nOuterBorder; } return aColumnSize; @@ -730,7 +730,7 @@ void Indenter::resize() long nOuterBorder = getBorderValue( m_nOuterBorder ); long nIndent = getBorderValue( m_nIndent ); Point aPt( m_aManagedArea.TopLeft() ); - aPt.X() += nOuterBorder + m_nIndent; + aPt.X() += nOuterBorder + nIndent; aPt.Y() += nOuterBorder; Size aSz( m_aManagedArea.GetSize() ); aSz.Width() -= 2*nOuterBorder + nIndent; diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk index 8b3c01f5721e..e74623ad0a03 100644 --- a/vcl/source/window/makefile.mk +++ b/vcl/source/window/makefile.mk @@ -89,6 +89,7 @@ SLOFILES= \ $(SLO)$/winproc.obj \ $(SLO)$/window2.obj \ $(SLO)$/window3.obj \ + $(SLO)$/window4.obj \ $(SLO)$/wrkwin.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 1fcdce0fdad5..88461f109fdb 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -496,18 +496,18 @@ void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow ) maSheetMarginTxt2.Show( i_bShow ); maNupOrientationTxt.Show( i_bShow ); maNupOrientationBox.Show( i_bShow ); - maLayout.resize(); + getLayout()->resize(); } void PrintDialog::NUpTabPage::setupLayout() { - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( -1 ); + boost::shared_ptr xLayout = + boost::dynamic_pointer_cast( getLayout() ); long nIndent = 3*WindowArranger::getDefaultBorder(); - maLayout.addWindow( &maNupLine ); - boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( &maLayout, false ) ); - maLayout.addChild( xRow ); + xLayout->addWindow( &maNupLine ); + boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( xLayout.get(), false ) ); + xLayout->addChild( xRow ); boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xRow.get() ) ); xRow->addChild( xIndent ); @@ -555,11 +555,6 @@ void PrintDialog::NUpTabPage::setupLayout() showAdvancedControls( false ); } -void PrintDialog::NUpTabPage::Resize() -{ - maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) ); -} - void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS ) { maSheetMarginEdt.SetValue( maSheetMarginEdt.Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM ); @@ -600,7 +595,6 @@ PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId ) , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) ) , maNoCollateHCImg( VclResId( SV_PRINT_NOCOLLATE_HC_IMG ) ) , mnCollateUIMode( 0 ) - , maLayout( NULL, true ) { FreeResource(); @@ -640,24 +634,24 @@ void PrintDialog::JobTabPage::setupLayout() // sets the results of GetOptimalSize in a normal ListBox maPrinters.SetDropDownLineCount( 4 ); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( -1 ); + boost::shared_ptr xLayout = + boost::dynamic_pointer_cast( getLayout() ); // add printer fixed line - maLayout.addWindow( &maPrinterFL ); + xLayout->addWindow( &maPrinterFL ); // add print LB - maLayout.addWindow( &maPrinters ); + xLayout->addWindow( &maPrinters ); // create a row for details button/text and properties button - boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( &maLayout, false ) ); - maLayout.addChild( xDetRow ); + boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( xLayout.get(), false ) ); + xLayout->addChild( xDetRow ); xDetRow->addWindow( &maDetailsBtn ); xDetRow->addChild( new vcl::Spacer( xDetRow.get(), 2 ) ); xDetRow->addWindow( &maSetupButton ); // create an indent for details - boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( &maLayout ) ); - maLayout.addChild( xIndent ); + boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xLayout.get() ) ); + xLayout->addChild( xIndent ); // remember details controls mxDetails = xIndent; // create a column for the details @@ -668,9 +662,9 @@ void PrintDialog::JobTabPage::setupLayout() xLabelCol->addRow( &maCommentLabel, &maCommentTxt ); // add print range and copies columns - maLayout.addWindow( &maCopies ); - boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false ) ); - maLayout.addChild( xRangeRow ); + xLayout->addWindow( &maCopies ); + boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( xLayout.get(), false ) ); + xLayout->addChild( xRangeRow ); // create print range and add to range row mxPrintRange.reset( new vcl::RowOrColumn( xRangeRow.get() ) ); @@ -737,11 +731,6 @@ void PrintDialog::JobTabPage::storeToSettings() rtl::OUString::createFromAscii( maCollateBox.IsChecked() ? "true" : "false" ) ); } -void PrintDialog::JobTabPage::Resize() -{ - maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); -} - PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rResId ) : TabPage( i_pParent, i_rResId ) , maOptionsLine( this, VclResId( SV_PRINT_OPT_PRINT_FL ) ) @@ -765,12 +754,12 @@ PrintDialog::OutputOptPage::~OutputOptPage() void PrintDialog::OutputOptPage::setupLayout() { - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( -1 ); + boost::shared_ptr xLayout = + boost::dynamic_pointer_cast( getLayout() ); - maLayout.addWindow( &maOptionsLine ); - boost::shared_ptr xIndent( new vcl::Indenter( &maLayout, -1 ) ); - maLayout.addChild( xIndent ); + xLayout->addWindow( &maOptionsLine ); + boost::shared_ptr xIndent( new vcl::Indenter( xLayout.get(), -1 ) ); + xLayout->addChild( xIndent ); boost::shared_ptr xCol( new vcl::RowOrColumn( xIndent.get() ) ); xIndent->setChild( xCol ); mxOptGroup = xCol; @@ -799,12 +788,6 @@ void PrintDialog::OutputOptPage::storeToSettings() rtl::OUString::createFromAscii( maToFileBox.IsChecked() ? "true" : "false" ) ); } -void PrintDialog::OutputOptPage::Resize() -{ - maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); -} - - PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr& i_rController ) : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) ) , maOKButton( this, VclResId( SV_PRINT_OK ) ) @@ -1012,11 +995,14 @@ PrintDialog::~PrintDialog() void PrintDialog::setupLayout() { - maLayout.setParentWindow( this ); + boost::shared_ptr xLayout = + boost::dynamic_pointer_cast( getLayout() ); + xLayout->setOuterBorder( 0 ); - boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( &maLayout, false ) ); - size_t nIndex = maLayout.addChild( xPreviewAndTab, 5 ); - maLayout.setBorders( nIndex, -1, -1, -1, 0 ); + + boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( xLayout.get(), false ) ); + size_t nIndex = xLayout->addChild( xPreviewAndTab, 5 ); + xLayout->setBorders( nIndex, -1, -1, -1, 0 ); // setup column for preview and sub controls boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) ); @@ -1040,12 +1026,12 @@ void PrintDialog::setupLayout() xPreviewAndTab->addWindow( &maTabCtrl ); // add the button line - maLayout.addWindow( &maButtonLine ); + xLayout->addWindow( &maButtonLine ); // add the row for the buttons - boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( &maLayout, false ) ); - nIndex = maLayout.addChild( xButtons ); - maLayout.setBorders( nIndex, -1, 0, -1, -1 ); + boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( xLayout.get(), false ) ); + nIndex = xLayout->addChild( xButtons ); + xLayout->setBorders( nIndex, -1, 0, -1, -1 ); Size aMinSize( maCancelButton.GetSizePixel() ); // insert help button @@ -1163,15 +1149,15 @@ void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) void PrintDialog::setupOptionalUI() { - std::vector aDynamicColumns; - vcl::RowOrColumn* pCurColumn = 0; + std::vector< boost::shared_ptr > aDynamicColumns; + boost::shared_ptr< vcl::RowOrColumn > pCurColumn; Window* pCurParent = 0, *pDynamicPageParent = 0; USHORT nOptPageId = 9, nCurSubGroup = 0; bool bOnStaticPage = false; bool bSubgroupOnStaticPage = false; - std::multimap< rtl::OUString, vcl::RowOrColumn* > aPropertyToDependencyRowMap; + std::multimap< rtl::OUString, boost::shared_ptr > aPropertyToDependencyRowMap; const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() ); for( int i = 0; i < rOptions.getLength(); i++ ) @@ -1277,37 +1263,40 @@ void PrintDialog::setupOptionalUI() { // restore to dynamic pCurParent = pDynamicPageParent; - pCurColumn = aDynamicColumns.empty() ? NULL : aDynamicColumns.back(); + if( ! aDynamicColumns.empty() ) + pCurColumn = aDynamicColumns.back(); + else + pCurColumn.reset(); bOnStaticPage = false; bSubgroupOnStaticPage = false; if( aGroupingHint.equalsAscii( "PrintRange" ) ) { - pCurColumn = maJobPage.mxPrintRange.get(); + pCurColumn = maJobPage.mxPrintRange; pCurParent = &maJobPage; // set job page as current parent bOnStaticPage = true; } else if( aGroupingHint.equalsAscii( "OptionsPage" ) ) { - pCurColumn = &maOptionsPage.maLayout; + pCurColumn = boost::dynamic_pointer_cast(maOptionsPage.getLayout()); pCurParent = &maOptionsPage; // set options page as current parent bOnStaticPage = true; } else if( aGroupingHint.equalsAscii( "OptionsPageOptGroup" ) ) { - pCurColumn = maOptionsPage.mxOptGroup.get(); + pCurColumn = maOptionsPage.mxOptGroup; pCurParent = &maOptionsPage; // set options page as current parent bOnStaticPage = true; } else if( aGroupingHint.equalsAscii( "LayoutPage" ) ) { - pCurColumn = &maNUpPage.maLayout; + pCurColumn = boost::dynamic_pointer_cast(maNUpPage.getLayout()); pCurParent = &maNUpPage; // set layout page as current parent bOnStaticPage = true; } else if( aGroupingHint.getLength() ) { - pCurColumn = &maJobPage.maLayout; + pCurColumn = boost::dynamic_pointer_cast(maJobPage.getLayout()); pCurParent = &maJobPage; // set job page as current parent bOnStaticPage = true; } @@ -1332,10 +1321,9 @@ void PrintDialog::setupOptionalUI() // reset subgroup counter nCurSubGroup = 0; - aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true ) ); + aDynamicColumns.push_back( boost::dynamic_pointer_cast(pNewGroup->getLayout()) ); pCurColumn = aDynamicColumns.back(); pCurColumn->setParentWindow( pNewGroup ); - pCurColumn->setOuterBorder( -1 ); bSubgroupOnStaticPage = false; bOnStaticPage = false; } @@ -1365,10 +1353,10 @@ void PrintDialog::setupOptionalUI() } // add an indent to the current column - vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, -1 ); + vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), -1 ); pCurColumn->addChild( pIndent ); // and create a column inside the indent - pCurColumn = new vcl::RowOrColumn( pIndent ); + pCurColumn.reset( new vcl::RowOrColumn( pIndent ) ); pIndent->setChild( pCurColumn ); } // EVIL @@ -1392,17 +1380,17 @@ void PrintDialog::setupOptionalUI() maPropertyToWindowMap[ aPropertyName ].push_back( &maNUpPage.maBrochureBtn ); maControlToPropertyMap[&maNUpPage.maBrochureBtn] = aPropertyName; - aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, maNUpPage.mxBrochureDep.get() ) ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr >( aPropertyName, maNUpPage.mxBrochureDep ) ); } else { - vcl::RowOrColumn* pSaveCurColumn = pCurColumn; + boost::shared_ptr pSaveCurColumn( pCurColumn ); if( bUseDependencyRow ) { // find the correct dependency row (if any) - std::pair< std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator, - std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator > aDepRange; + std::pair< std::multimap< rtl::OUString, boost::shared_ptr >::iterator, + std::multimap< rtl::OUString, boost::shared_ptr >::iterator > aDepRange; aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName ); if( aDepRange.first != aDepRange.second ) { @@ -1441,16 +1429,16 @@ void PrintDialog::setupOptionalUI() // set help text setHelpText( pNewBox, aHelpTexts, 0 ); - vcl::RowOrColumn* pDependencyRow = new vcl::RowOrColumn( pCurColumn, false ); + boost::shared_ptr pDependencyRow( new vcl::RowOrColumn( pCurColumn.get(), false ) ); pCurColumn->addChild( pDependencyRow ); - aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow ) ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr >( aPropertyName, pDependencyRow ) ); // add checkbox to current column pDependencyRow->addWindow( pNewBox ); } else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) { - vcl::RowOrColumn* pRadioColumn = pCurColumn; + boost::shared_ptr pRadioColumn( pCurColumn ); if( aText.getLength() ) { // add a FixedText: @@ -1466,10 +1454,10 @@ void PrintDialog::setupOptionalUI() // add fixed text to current column pCurColumn->addWindow( pHeading ); // add an indent to the current column - vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, 15 ); + vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), 15 ); pCurColumn->addChild( pIndent ); // and create a column inside the indent - pRadioColumn = new vcl::RowOrColumn( pIndent ); + pRadioColumn.reset( new vcl::RowOrColumn( pIndent ) ); pIndent->setChild( pRadioColumn ); } // iterate options @@ -1479,11 +1467,11 @@ void PrintDialog::setupOptionalUI() pVal->Value >>= nSelectVal; for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) { - boost::shared_ptr pLabel( new vcl::LabeledElement( pRadioColumn, 1 ) ); + boost::shared_ptr pLabel( new vcl::LabeledElement( pRadioColumn.get(), 1 ) ); pRadioColumn->addChild( pLabel ); boost::shared_ptr pDependencyRow( new vcl::RowOrColumn( pLabel.get(), false ) ); pLabel->setElement( pDependencyRow ); - aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow.get() ) ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr >( aPropertyName, pDependencyRow ) ); RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 ); maControls.push_front( pBtn ); @@ -1509,9 +1497,9 @@ void PrintDialog::setupOptionalUI() ) && pCurParent ) { // create a row in the current column - vcl::RowOrColumn* pFieldColumn = new vcl::RowOrColumn( pCurColumn, false ); + boost::shared_ptr pFieldColumn( new vcl::RowOrColumn( pCurColumn.get(), false ) ); pCurColumn->addChild( pFieldColumn ); - aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pFieldColumn ) ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr >( aPropertyName, pFieldColumn ) ); vcl::LabeledElement* pLabel = NULL; if( aText.getLength() ) @@ -1526,7 +1514,7 @@ void PrintDialog::setupOptionalUI() setSmartId( pHeading, "FixedText", -1, aPropertyName ); // add to row - pLabel = new vcl::LabeledElement( pFieldColumn, 2 ); + pLabel = new vcl::LabeledElement( pFieldColumn.get(), 2 ); pFieldColumn->addChild( pLabel ); pLabel->setLabel( pHeading ); } @@ -1661,11 +1649,11 @@ void PrintDialog::setupOptionalUI() // FIXME: the GetNativeControlRegion call on Windows has some issues // (which skew the results of GetOptimalSize()) // however fixing this thoroughly needs to take interaction with paint into - // acoount, making the right fix less simple. Fix this the right way + // account, making the right fix less simple. Fix this the right way // at some point. For now simply add some space at the lowest element - size_t nIndex = maJobPage.maLayout.countElements(); + size_t nIndex = maJobPage.getLayout()->countElements(); if( nIndex > 0 ) // sanity check - maJobPage.maLayout.setBorders( nIndex-1, 0, 0, 0, aBorder.Width() ); + maJobPage.getLayout()->setBorders( nIndex-1, 0, 0, 0, -1 ); #endif // create auto mnemomnics now so they can be calculated in layout @@ -1675,13 +1663,13 @@ void PrintDialog::setupOptionalUI() ImplWindowAutoMnemonic( this ); // calculate job page - Size aMaxSize = maJobPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); + Size aMaxSize = maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ); // and layout page - updateMaxSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); + updateMaxSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); // and options page - updateMaxSize( maOptionsPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); + updateMaxSize( maOptionsPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); - for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin(); + for( std::vector< boost::shared_ptr >::iterator it = aDynamicColumns.begin(); it != aDynamicColumns.end(); ++it ) { Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) ); @@ -1709,19 +1697,7 @@ void PrintDialog::setupOptionalUI() maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() ); } - // and finally arrange controls - for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin(); - it != aDynamicColumns.end(); ++it ) - { - (*it)->setManagedArea( Rectangle( Point(), aTabSize ) ); - delete *it; - *it = NULL; - } - maJobPage.Resize(); - maNUpPage.Resize(); - maOptionsPage.Resize(); - - Size aSz = maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); + Size aSz = getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ); SetOutputSizePixel( aSz ); } @@ -1756,7 +1732,7 @@ void PrintDialog::checkControlDependencies() maJobPage.maCollateImage.SetSizePixel( aImgSize ); maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg ); maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST ); - maJobPage.maLayout.resize(); + maJobPage.getLayout()->resize(); // enable setup button only for printers that can be setup bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ); @@ -1771,7 +1747,7 @@ void PrintDialog::checkControlDependencies() aPrinterSize.Width() = aSetupPos.X() - aPrinterPos.X() - LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ).Width(); maJobPage.maPrinters.SetSizePixel( aPrinterSize ); maJobPage.maSetupButton.Show(); - maLayout.resize(); + getLayout()->resize(); } } else @@ -1785,7 +1761,7 @@ void PrintDialog::checkControlDependencies() aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X(); maJobPage.maPrinters.SetSizePixel( aPrinterSize ); maJobPage.maSetupButton.Hide(); - maLayout.resize(); + getLayout()->resize(); } } } @@ -2016,7 +1992,7 @@ void PrintDialog::updateNupFromPages() if( bCustom ) { // see if we have to enlarge the dialog to make the tab page fit - Size aCurSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ) ); + Size aCurSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ) ); Size aTabSize( maTabCtrl.GetTabPageSizePixel() ); if( aTabSize.Height() < aCurSize.Height() ) { @@ -2135,7 +2111,7 @@ IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) else if( pButton == &maOptionsPage.maToFileBox ) { maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); - maLayout.resize(); + getLayout()->resize(); } else if( pButton == &maNUpPage.maBrochureBtn ) { @@ -2171,7 +2147,7 @@ IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) { maDetailsCollapsedSize = GetOutputSizePixel(); // enlarge dialog if necessary - Size aMinSize( maJobPage.maLayout.getOptimalSize( WINDOWSIZE_MINIMUM ) ); + Size aMinSize( maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_MINIMUM ) ); Size aCurSize( maJobPage.GetSizePixel() ); if( aCurSize.Height() < aMinSize.Height() ) { @@ -2445,7 +2421,7 @@ void PrintDialog::Command( const CommandEvent& rEvt ) void PrintDialog::Resize() { - maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); + // maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); // and do the preview; however the metafile does not need to be gotten anew preparePreview( false ); diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 7fea5ef78757..e69a086f91d3 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -597,6 +597,7 @@ void Window::ImplInitWindowData( WindowType nType ) mpWindowImpl->mpDlgCtrlDownWindow = NULL; // window for dialog control mpWindowImpl->mpFirstDel = NULL; // Dtor notification list mpWindowImpl->mpUserData = NULL; // user data + mpWindowImpl->mpExtImpl = NULL; // extended implementation data mpWindowImpl->mpCursor = NULL; // cursor mpWindowImpl->mpControlFont = NULL; // font propertie mpWindowImpl->mpVCLXWindow = NULL; @@ -1129,6 +1130,8 @@ void Window::ImplCallResize() // #88419# Most classes don't call the base class in Resize() and Move(), // => Call ImpleResize/Move instead of Resize/Move directly... ImplCallEventListeners( VCLEVENT_WINDOW_RESIZE ); + + ImplExtResize(); } // ----------------------------------------------------------------------- @@ -4329,6 +4332,8 @@ Window::Window( Window* pParent, const ResId& rResId ) Window::~Window() { + ImplFreeExtWindowImpl(); + vcl::LazyDeletor::Undelete( this ); DBG_DTOR( Window, ImplDbgCheckWindow ); diff --git a/vcl/source/window/window4.cxx b/vcl/source/window/window4.cxx new file mode 100644 index 000000000000..79476e9f59c3 --- /dev/null +++ b/vcl/source/window/window4.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_vcl.hxx" + +#include "vcl/window.hxx" +#include "vcl/window.h" +#include "vcl/arrange.hxx" + +namespace vcl +{ + struct ExtWindowImpl + { + ExtWindowImpl() + {} + ~ExtWindowImpl() + {} + + boost::shared_ptr< WindowArranger > mxLayout; + }; +} + + +void Window::ImplFreeExtWindowImpl() +{ + if( mpWindowImpl ) + { + delete mpWindowImpl->mpExtImpl; + mpWindowImpl->mpExtImpl = NULL; + } +} + +vcl::ExtWindowImpl* Window::ImplGetExtWindowImpl() const +{ + vcl::ExtWindowImpl* pImpl = NULL; + if( mpWindowImpl ) + { + if( ! mpWindowImpl->mpExtImpl ) + mpWindowImpl->mpExtImpl = new vcl::ExtWindowImpl(); + pImpl = mpWindowImpl->mpExtImpl; + } + return pImpl; +} + +void Window::ImplExtResize() +{ + if( mpWindowImpl && mpWindowImpl->mpExtImpl ) + { + if( mpWindowImpl->mpExtImpl->mxLayout.get() ) + mpWindowImpl->mpExtImpl->mxLayout->setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); + } +} + +boost::shared_ptr< vcl::WindowArranger > Window::getLayout() +{ + boost::shared_ptr< vcl::WindowArranger > xRet; + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + if( pImpl ) + { + if( ! pImpl->mxLayout.get() ) + { + pImpl->mxLayout.reset( new vcl::LabelColumn() ); + pImpl->mxLayout->setParentWindow( this ); + pImpl->mxLayout->setOuterBorder( -1 ); + } + xRet = pImpl->mxLayout; + } + + return xRet; +} -- cgit v1.2.3 From 96c1ee636435baf4ea84e7bffd9acb0bc0e9b787 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Wed, 24 Mar 2010 19:41:38 +0100 Subject: gozer1: #161853# add hierarchichal named children --- vcl/inc/vcl/arrange.hxx | 14 ++-- vcl/inc/vcl/window.hxx | 39 +++++++++++ vcl/source/window/window4.cxx | 156 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 200 insertions(+), 9 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index 5b9a1d296513..72e33f3c4bf8 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -51,7 +51,7 @@ namespace vcl or a child WindowArranger (a node in the hierarchy), but never both */ - class WindowArranger + class VCL_DLLPUBLIC WindowArranger { protected: struct Element @@ -197,7 +197,7 @@ namespace vcl } }; - class RowOrColumn : public WindowArranger + class VCL_DLLPUBLIC RowOrColumn : public WindowArranger { long m_nBorderWidth; bool m_bColumn; @@ -238,7 +238,7 @@ namespace vcl long getBorderWidth() const { return m_nBorderWidth; } }; - class LabeledElement : public WindowArranger + class VCL_DLLPUBLIC LabeledElement : public WindowArranger { WindowArranger::Element m_aLabel; WindowArranger::Element m_aElement; @@ -282,7 +282,7 @@ namespace vcl { return m_aElement.getOptimalSize( i_eType ); } }; - class LabelColumn : public RowOrColumn + class VCL_DLLPUBLIC LabelColumn : public RowOrColumn { long getLabelWidth() const; public: @@ -299,7 +299,7 @@ namespace vcl size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0 ); }; - class Indenter : public WindowArranger + class VCL_DLLPUBLIC Indenter : public WindowArranger { long m_nIndent; WindowArranger::Element m_aElement; @@ -333,7 +333,7 @@ namespace vcl { setChild( boost::shared_ptr( i_pChild ), i_nExpandPrio ); } }; - class Spacer : public WindowArranger + class VCL_DLLPUBLIC Spacer : public WindowArranger { WindowArranger::Element m_aElement; Size m_aSize; @@ -359,7 +359,7 @@ namespace vcl virtual bool isVisible() const { return true; } }; - class MatrixArranger : public WindowArranger + class VCL_DLLPUBLIC MatrixArranger : public WindowArranger { long m_nBorderX; long m_nBorderY; diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index 8fa63633eeef..c757a20aece9 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -483,6 +483,7 @@ public: SAL_DLLPRIVATE void ImplFreeExtWindowImpl(); // creates ExtWindowImpl on demand, but may return NULL (e.g. if mbInDtor) SAL_DLLPRIVATE vcl::ExtWindowImpl* ImplGetExtWindowImpl() const; + SAL_DLLPRIVATE void ImplDeleteOwnedChildren(); /** check whether a font is suitable for UI The font to be tested will be checked whether it could display a @@ -1156,6 +1157,44 @@ public: // layouting boost::shared_ptr< vcl::WindowArranger > getLayout(); + + /* add a child Window + addWindow will do the following things + - insert the passed window into the child list (equivalent to i_pWin->SetParent( this )) + - assign a name to the passed window for identification purposes + the name is basically free style, only the '/' character must not be used as it is + used for concatenation to form hierarchical names + caution: the last non empty token repsctive to '/' will be the actual name used + - mark the window as "owned", meaning that the added Window will be destroyed by + the parent's desctructor. + This means: do not pass in member windows or stack objects here. Do not cause + the destructor of the added window to be called in any way. + + to avoid ownership pass i_bTakeOwnership as "false" + */ + void addWindow( Window* i_pWin, const rtl::OUString& i_rName, bool i_bTakeOwnership = true ); + + /* remove a child Window + the remove window functions will + - reparent the searched window (equivalent to i_pWin->SetParent( i_pNewParent )) + - return a pointer to the removed window or NULL if i_pWin was not found + caution: ownership passes to the new parent or the caller, if the new parent was NULL + */ + Window* removeWindow( Window* i_pWin, Window* i_pNewParent = NULL ); + /* removeWindow by name will only work for direct children. if i_rName + is a hierachical name, the last non empty token will be used to get the child window + */ + Window* removeWindow( const rtl::OUString& i_rName, Window* i_pNewParent = NULL ); + + /* find a child window by name + the name passed here can be hierarchical to find descendants in any depth + path delimiter is '/' + */ + Window* findWindow( const rtl::OUString& i_rName ) const; + + /* return the name of this window + */ + const rtl::OUString& getName() const; }; diff --git a/vcl/source/window/window4.cxx b/vcl/source/window/window4.cxx index 79476e9f59c3..587a99376943 100644 --- a/vcl/source/window/window4.cxx +++ b/vcl/source/window/window4.cxx @@ -31,22 +31,92 @@ #include "vcl/window.h" #include "vcl/arrange.hxx" +#include + namespace vcl { struct ExtWindowImpl { ExtWindowImpl() + : mbOwnedByParent( false ) {} ~ExtWindowImpl() {} - boost::shared_ptr< WindowArranger > mxLayout; + boost::shared_ptr< WindowArranger > mxLayout; + bool mbOwnedByParent; + rtl::OUString maName; + std::map< rtl::OUString, Window* > maNameToWindow; + std::map< Window*, rtl::OUString > maWindowToName; + + void insertName( const rtl::OUString& i_rName, Window* i_pWin ); + void removeWindow( Window* ); + Window* findName( const rtl::OUString& ) const; }; + + void ExtWindowImpl::insertName( const rtl::OUString& i_rName, Window* i_pWin ) + { + OSL_ENSURE( maNameToWindow.find( i_rName ) == maNameToWindow.end(), "duplicate named window inserted" ); + maNameToWindow[ i_rName ] = i_pWin; + maWindowToName[ i_pWin ] = i_rName; + } + + void ExtWindowImpl::removeWindow( Window* i_pWin ) + { + std::map< Window*, rtl::OUString >::iterator it = maWindowToName.find( i_pWin ); + if( it != maWindowToName.end() ) + { + maNameToWindow.erase( it->second ); + maWindowToName.erase( it ); + } + } + + Window* ExtWindowImpl::findName( const rtl::OUString& i_rName ) const + { + std::map< rtl::OUString, Window* >::const_iterator it = maNameToWindow.find( i_rName ); + return it != maNameToWindow.end() ? it->second : NULL; + } } +static rtl::OUString getLastNameToken( const rtl::OUString& i_rName ) +{ + sal_Int32 nIndex = i_rName.lastIndexOf( sal_Unicode('/') ); + if( nIndex != -1 ) + { + // if this is not an empty token, that is the name + if( nIndex < i_rName.getLength()-1 ) + return i_rName.copy( nIndex+1 ); + // we need to search backward + const sal_Unicode* pStr = i_rName.getStr(); + while( nIndex >= 0 && pStr[nIndex] == '/' ) + nIndex--; + if( nIndex < 0 ) // give up + return rtl::OUString(); + // search backward to next '/' or beginning + sal_Int32 nBeginIndex = nIndex-1; + while( nBeginIndex >= 0 && pStr[nBeginIndex] != '/' ) + nBeginIndex--; + return i_rName.copy( nBeginIndex+1, nIndex-nBeginIndex ); + } + return rtl::OUString( i_rName ); +} + +void Window::ImplDeleteOwnedChildren() +{ + Window* pChild = mpWindowImpl->mpFirstChild; + while ( pChild ) + { + Window* pDeleteCandidate = pChild; + pChild = pChild->mpWindowImpl->mpNext; + vcl::ExtWindowImpl* pDelImpl = pDeleteCandidate->ImplGetExtWindowImpl(); + if( pDelImpl && pDelImpl->mbOwnedByParent ) + delete pDeleteCandidate; + } +} void Window::ImplFreeExtWindowImpl() { + ImplDeleteOwnedChildren(); if( mpWindowImpl ) { delete mpWindowImpl->mpExtImpl; @@ -59,7 +129,7 @@ vcl::ExtWindowImpl* Window::ImplGetExtWindowImpl() const vcl::ExtWindowImpl* pImpl = NULL; if( mpWindowImpl ) { - if( ! mpWindowImpl->mpExtImpl ) + if( ! mpWindowImpl->mpExtImpl && ! mpWindowImpl->mbInDtor ) mpWindowImpl->mpExtImpl = new vcl::ExtWindowImpl(); pImpl = mpWindowImpl->mpExtImpl; } @@ -92,3 +162,85 @@ boost::shared_ptr< vcl::WindowArranger > Window::getLayout() return xRet; } + +void Window::addWindow( Window* i_pWin, const rtl::OUString& i_rName, bool i_bTakeOwnership ) +{ + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + if( pImpl && i_pWin ) + { + vcl::ExtWindowImpl* pChildImpl = i_pWin->ImplGetExtWindowImpl(); + if( pChildImpl ) + { + i_pWin->SetParent( this ); + pChildImpl->mbOwnedByParent = i_bTakeOwnership; + rtl::OUString aName( getLastNameToken( i_rName ) ); + if( aName.getLength() ) + { + pImpl->insertName( aName, i_pWin ); + } + } + } +} + +Window* Window::removeWindow( Window* i_pWin, Window* i_pNewParent ) +{ + Window* pRet = NULL; + if( i_pWin ) + { + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + if( pImpl ) + { + vcl::ExtWindowImpl* pChildImpl = i_pWin->ImplGetExtWindowImpl(); + if( pChildImpl ) + { + if( ! i_pNewParent ) + pChildImpl->mbOwnedByParent = false; + pImpl->removeWindow( i_pWin ); + i_pWin->SetParent( i_pNewParent ); + pRet = i_pWin; + } + } + } + return pRet; +} + +Window* Window::removeWindow( const rtl::OUString& i_rName, Window* i_pNewParent ) +{ + Window* pRet = NULL; + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + if( pImpl ) + { + rtl::OUString aName( getLastNameToken( i_rName ) ); + pRet = pImpl->findName( aName ); + pRet = removeWindow( pRet, i_pNewParent ); + } + return pRet; +} + +Window* Window::findWindow( const rtl::OUString& i_rName ) const +{ + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + Window* pSearch = const_cast(this); + if( pImpl ) + { + sal_Int32 nIndex = 0; + while( nIndex && pSearch ) + { + rtl::OUString aName( i_rName.getToken( 0, '/', nIndex ) ); + if( aName.getLength() ) + { + pSearch = pImpl->findName( aName ); + if( pSearch ) + { + pImpl = pSearch->ImplGetExtWindowImpl(); + if( ! pImpl ) + pSearch = NULL; + } + } + } + } + else + pSearch = NULL; + return pSearch != this ? pSearch : NULL; +} + -- cgit v1.2.3 From ff9196d0581845f8e7cb686bf93930676ba301fe Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Thu, 1 Apr 2010 16:51:09 +0200 Subject: gozer1: #161853# provide access to Window class and WindowArranger through XPropertySet --- vcl/inc/vcl/arrange.hxx | 11 ++ vcl/inc/vcl/window.hxx | 44 ++++-- vcl/inc/vcl/wpropset.hxx | 66 ++++++++ vcl/prj/d.lst | 4 +- vcl/source/window/arrange.cxx | 62 ++++++++ vcl/source/window/makefile.mk | 1 + vcl/source/window/window4.cxx | 150 ++++++++---------- vcl/source/window/wpropset.cxx | 345 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 581 insertions(+), 102 deletions(-) create mode 100644 vcl/inc/vcl/wpropset.hxx create mode 100644 vcl/source/window/wpropset.cxx (limited to 'vcl') diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index 72e33f3c4bf8..24775995b013 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -104,6 +104,8 @@ namespace vcl Rectangle m_aManagedArea; long m_nOuterBorder; + rtl::OUString m_aIdentifier; + virtual Element* getElement( size_t i_nIndex ) = 0; const Element* getConstElement( size_t i_nIndex ) const { return const_cast(this)->getElement( i_nIndex ); } @@ -149,6 +151,9 @@ namespace vcl virtual bool isVisible() const; // true if any element is visible + virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getProperties() const; + virtual void setProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& ); + sal_Int32 getExpandPriority( size_t i_nIndex ) const { const Element* pEle = getConstElement( i_nIndex ); @@ -195,6 +200,12 @@ namespace vcl m_nOuterBorder = i_nBorder; resize(); } + + const rtl::OUString getIdentifier() const + { return m_aIdentifier; } + + void setIdentifier( const rtl::OUString& i_rId ) + { m_aIdentifier = i_rId; } }; class VCL_DLLPUBLIC RowOrColumn : public WindowArranger diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index c757a20aece9..9516350527df 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -96,6 +96,13 @@ namespace accessibility { class XAccessible; }}}} +namespace com { +namespace sun { +namespace star { +namespace beans { + class PropertyValue; +}}}} + namespace com { namespace sun { namespace star { @@ -1156,15 +1163,11 @@ public: // ExtImpl // layouting - boost::shared_ptr< vcl::WindowArranger > getLayout(); + boost::shared_ptr< vcl::WindowArranger > getLayout(); /* add a child Window addWindow will do the following things - insert the passed window into the child list (equivalent to i_pWin->SetParent( this )) - - assign a name to the passed window for identification purposes - the name is basically free style, only the '/' character must not be used as it is - used for concatenation to form hierarchical names - caution: the last non empty token repsctive to '/' will be the actual name used - mark the window as "owned", meaning that the added Window will be destroyed by the parent's desctructor. This means: do not pass in member windows or stack objects here. Do not cause @@ -1172,7 +1175,7 @@ public: to avoid ownership pass i_bTakeOwnership as "false" */ - void addWindow( Window* i_pWin, const rtl::OUString& i_rName, bool i_bTakeOwnership = true ); + void addWindow( Window* i_pWin, bool i_bTakeOwnership = true ); /* remove a child Window the remove window functions will @@ -1181,20 +1184,31 @@ public: caution: ownership passes to the new parent or the caller, if the new parent was NULL */ Window* removeWindow( Window* i_pWin, Window* i_pNewParent = NULL ); - /* removeWindow by name will only work for direct children. if i_rName - is a hierachical name, the last non empty token will be used to get the child window + + /* return the identifier of this window + */ + const rtl::OUString& getIdentifier() const; + /* set an identifier + identifiers have only loosely defined rules per se + in context of Window they must be unique over the window + hierarchy you'd like to find them again using the findWindow method */ - Window* removeWindow( const rtl::OUString& i_rName, Window* i_pNewParent = NULL ); + void setIdentifier( const rtl::OUString& ); - /* find a child window by name - the name passed here can be hierarchical to find descendants in any depth - path delimiter is '/' + /* returns the first found descendant that matches + the passed identifier or NULL */ - Window* findWindow( const rtl::OUString& i_rName ) const; + Window* findWindow( const rtl::OUString& ) const; - /* return the name of this window + /* get/set properties + this will contain window properties (like visible, enabled) + as well as properties of derived classes (e.g. text of Edit fields) */ - const rtl::OUString& getName() const; + virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getProperties() const; + /* + */ + virtual void setProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& ); + }; diff --git a/vcl/inc/vcl/wpropset.hxx b/vcl/inc/vcl/wpropset.hxx new file mode 100644 index 000000000000..409b629496e6 --- /dev/null +++ b/vcl/inc/vcl/wpropset.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef VCL_WPROPSET_HXX +#define VCL_WPROPSET_HXX + +#include "vcl/dllapi.h" + +#include "tools/link.hxx" +#include "vcl/arrange.hxx" + +#include "com/sun/star/beans/XPropertySet.hpp" + +class VclWindowEvent; + +namespace vcl +{ + class WindowPropertySetData; + class WindowPropertySetListener; + + class VCL_DLLPUBLIC WindowPropertySet + { + WindowPropertySetData* mpImpl; + + void addWindowToSet( Window* ); + void addLayoutToSet( const boost::shared_ptr& ); + void setupProperties(); + + DECL_LINK( ChildEventListener, VclWindowEvent* ); + + void propertyChange( const com::sun::star::beans::PropertyChangeEvent& ); + friend class vcl::WindowPropertySetListener; + + public: + WindowPropertySet( Window* i_pTopWindow, bool i_bTakeOwnership ); + ~WindowPropertySet(); + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > getPropertySet() const; + }; +} + +#endif diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst index 8345b155ce58..0f429d0f5ec6 100644 --- a/vcl/prj/d.lst +++ b/vcl/prj/d.lst @@ -153,4 +153,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\ppdparser.hxx %_DEST%\inc%_EXT%\vcl\ppdparser.hxx ..\inc\vcl\helper.hxx %_DEST%\inc%_EXT%\vcl\helper.hxx ..\inc\vcl\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx -..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx \ No newline at end of file +..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx +..\inc\vcl\arrange.hxx %_DEST%\inc%_EXT%\vcl\arrange.hxx +..\inc\vcl\wpropset.hxx %_DEST%\inc%_EXT%\vcl\wpropset.hxx \ No newline at end of file diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx index 64db5426dc5b..2a01758220ed 100644 --- a/vcl/source/window/arrange.cxx +++ b/vcl/source/window/arrange.cxx @@ -35,9 +35,13 @@ #include "vcl/svdata.hxx" #include "vcl/svapp.hxx" +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/awt/Rectangle.hpp" + #include "osl/diagnose.h" using namespace vcl; +using namespace com::sun::star; // ---------------------------------------- // vcl::WindowArranger @@ -206,6 +210,64 @@ void WindowArranger::Element::setPosSize( const Point& i_rPos, const Size& i_rSi m_pChild->setManagedArea( Rectangle( aPoint, aSize ) ); } +uno::Sequence< beans::PropertyValue > WindowArranger::getProperties() const +{ + uno::Sequence< beans::PropertyValue > aRet( 3 ); + aRet[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OuterBorder" ) ); + aRet[0].Value = uno::makeAny( sal_Int32( getBorderValue( m_nOuterBorder ) ) ); + aRet[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ManagedArea" ) ); + awt::Rectangle aArea( m_aManagedArea.getX(), m_aManagedArea.getY(), m_aManagedArea.getWidth(), m_aManagedArea.getHeight() ); + aRet[1].Value = uno::makeAny( aArea ); + aRet[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ); + aRet[2].Value = uno::makeAny( sal_Bool( isVisible() ) ); + return aRet; +} + +void WindowArranger::setProperties( const uno::Sequence< beans::PropertyValue >& i_rProps ) +{ + const beans::PropertyValue* pProps = i_rProps.getConstArray(); + bool bResize = false; + for( sal_Int32 i = 0; i < i_rProps.getLength(); i++ ) + { + if( pProps[i].Name.equalsAscii( "OuterBorder" ) ) + { + sal_Int32 nVal = 0; + if( pProps[i].Value >>= nVal ) + { + if( getBorderValue( m_nOuterBorder ) != nVal ) + { + m_nOuterBorder = nVal; + bResize = true; + } + } + } + else if( pProps[i].Name.equalsAscii( "ManagedArea" ) ) + { + awt::Rectangle aArea( 0, 0, 0, 0 ); + if( pProps[i].Value >>= aArea ) + { + m_aManagedArea.setX( aArea.X ); + m_aManagedArea.setY( aArea.Y ); + m_aManagedArea.setWidth( aArea.Width ); + m_aManagedArea.setHeight( aArea.Height ); + bResize = true; + } + } + else if( pProps[i].Name.equalsAscii( "Visible" ) ) + { + sal_Bool bVal = sal_False; + if( pProps[i].Value >>= bVal ) + { + show( bVal, false ); + bResize = true; + } + } + } + if( bResize ) + resize(); +} + + // ---------------------------------------- // vcl::RowOrColumn //----------------------------------------- diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk index e74623ad0a03..3614e166537c 100644 --- a/vcl/source/window/makefile.mk +++ b/vcl/source/window/makefile.mk @@ -90,6 +90,7 @@ SLOFILES= \ $(SLO)$/window2.obj \ $(SLO)$/window3.obj \ $(SLO)$/window4.obj \ + $(SLO)$/wpropset.obj \ $(SLO)$/wrkwin.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/window/window4.cxx b/vcl/source/window/window4.cxx index 587a99376943..577a573c2015 100644 --- a/vcl/source/window/window4.cxx +++ b/vcl/source/window/window4.cxx @@ -29,9 +29,15 @@ #include "vcl/window.hxx" #include "vcl/window.h" +#include "vcl/svdata.hxx" #include "vcl/arrange.hxx" +#include "com/sun/star/beans/PropertyValue.hpp" + #include +#include + +using namespace com::sun::star; namespace vcl { @@ -45,60 +51,8 @@ namespace vcl boost::shared_ptr< WindowArranger > mxLayout; bool mbOwnedByParent; - rtl::OUString maName; - std::map< rtl::OUString, Window* > maNameToWindow; - std::map< Window*, rtl::OUString > maWindowToName; - - void insertName( const rtl::OUString& i_rName, Window* i_pWin ); - void removeWindow( Window* ); - Window* findName( const rtl::OUString& ) const; + rtl::OUString maIdentifier; }; - - void ExtWindowImpl::insertName( const rtl::OUString& i_rName, Window* i_pWin ) - { - OSL_ENSURE( maNameToWindow.find( i_rName ) == maNameToWindow.end(), "duplicate named window inserted" ); - maNameToWindow[ i_rName ] = i_pWin; - maWindowToName[ i_pWin ] = i_rName; - } - - void ExtWindowImpl::removeWindow( Window* i_pWin ) - { - std::map< Window*, rtl::OUString >::iterator it = maWindowToName.find( i_pWin ); - if( it != maWindowToName.end() ) - { - maNameToWindow.erase( it->second ); - maWindowToName.erase( it ); - } - } - - Window* ExtWindowImpl::findName( const rtl::OUString& i_rName ) const - { - std::map< rtl::OUString, Window* >::const_iterator it = maNameToWindow.find( i_rName ); - return it != maNameToWindow.end() ? it->second : NULL; - } -} - -static rtl::OUString getLastNameToken( const rtl::OUString& i_rName ) -{ - sal_Int32 nIndex = i_rName.lastIndexOf( sal_Unicode('/') ); - if( nIndex != -1 ) - { - // if this is not an empty token, that is the name - if( nIndex < i_rName.getLength()-1 ) - return i_rName.copy( nIndex+1 ); - // we need to search backward - const sal_Unicode* pStr = i_rName.getStr(); - while( nIndex >= 0 && pStr[nIndex] == '/' ) - nIndex--; - if( nIndex < 0 ) // give up - return rtl::OUString(); - // search backward to next '/' or beginning - sal_Int32 nBeginIndex = nIndex-1; - while( nBeginIndex >= 0 && pStr[nBeginIndex] != '/' ) - nBeginIndex--; - return i_rName.copy( nBeginIndex+1, nIndex-nBeginIndex ); - } - return rtl::OUString( i_rName ); } void Window::ImplDeleteOwnedChildren() @@ -163,7 +117,7 @@ boost::shared_ptr< vcl::WindowArranger > Window::getLayout() return xRet; } -void Window::addWindow( Window* i_pWin, const rtl::OUString& i_rName, bool i_bTakeOwnership ) +void Window::addWindow( Window* i_pWin, bool i_bTakeOwnership ) { vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); if( pImpl && i_pWin ) @@ -173,11 +127,6 @@ void Window::addWindow( Window* i_pWin, const rtl::OUString& i_rName, bool i_bTa { i_pWin->SetParent( this ); pChildImpl->mbOwnedByParent = i_bTakeOwnership; - rtl::OUString aName( getLastNameToken( i_rName ) ); - if( aName.getLength() ) - { - pImpl->insertName( aName, i_pWin ); - } } } } @@ -195,7 +144,6 @@ Window* Window::removeWindow( Window* i_pWin, Window* i_pNewParent ) { if( ! i_pNewParent ) pChildImpl->mbOwnedByParent = false; - pImpl->removeWindow( i_pWin ); i_pWin->SetParent( i_pNewParent ); pRet = i_pWin; } @@ -204,43 +152,73 @@ Window* Window::removeWindow( Window* i_pWin, Window* i_pNewParent ) return pRet; } -Window* Window::removeWindow( const rtl::OUString& i_rName, Window* i_pNewParent ) +Window* Window::findWindow( const rtl::OUString& i_rIdentifier ) const { - Window* pRet = NULL; - vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); - if( pImpl ) + if( getIdentifier() == i_rIdentifier ) + return const_cast(this); + + Window* pChild = mpWindowImpl->mpFirstChild; + while ( pChild ) { - rtl::OUString aName( getLastNameToken( i_rName ) ); - pRet = pImpl->findName( aName ); - pRet = removeWindow( pRet, i_pNewParent ); + Window* pResult = pChild->findWindow( i_rIdentifier ); + if( pResult ) + return pResult; + pChild = pChild->mpWindowImpl->mpNext; } - return pRet; + + return NULL; +} + +const rtl::OUString& Window::getIdentifier() const +{ + static rtl::OUString aEmptyStr; + + return (mpWindowImpl && mpWindowImpl->mpExtImpl) ? mpWindowImpl->mpExtImpl->maIdentifier : aEmptyStr; } -Window* Window::findWindow( const rtl::OUString& i_rName ) const +void Window::setIdentifier( const rtl::OUString& i_rIdentifier ) { vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); - Window* pSearch = const_cast(this); if( pImpl ) + pImpl->maIdentifier = i_rIdentifier; +} + +void Window::setProperties( const uno::Sequence< beans::PropertyValue >& i_rProps ) +{ + const beans::PropertyValue* pVals = i_rProps.getConstArray(); + for( sal_Int32 i = 0; i < i_rProps.getLength(); i++ ) { - sal_Int32 nIndex = 0; - while( nIndex && pSearch ) + if( pVals[i].Name.equalsAscii( "Enabled" ) ) { - rtl::OUString aName( i_rName.getToken( 0, '/', nIndex ) ); - if( aName.getLength() ) - { - pSearch = pImpl->findName( aName ); - if( pSearch ) - { - pImpl = pSearch->ImplGetExtWindowImpl(); - if( ! pImpl ) - pSearch = NULL; - } - } + sal_Bool bVal = sal_True; + if( pVals[i].Value >>= bVal ) + Enable( bVal ); + } + else if( pVals[i].Name.equalsAscii( "Visible" ) ) + { + sal_Bool bVal = sal_True; + if( pVals[i].Value >>= bVal ) + Show( bVal ); + } + else if( pVals[i].Name.equalsAscii( "Text" ) ) + { + rtl::OUString aText; + if( pVals[i].Value >>= aText ) + SetText( aText ); } } - else - pSearch = NULL; - return pSearch != this ? pSearch : NULL; +} + +uno::Sequence< beans::PropertyValue > Window::getProperties() const +{ + uno::Sequence< beans::PropertyValue > aProps( 3 ); + aProps[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Enabled" ) ); + aProps[0].Value = uno::makeAny( sal_Bool( IsEnabled() ) ); + aProps[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) ); + aProps[1].Value = uno::makeAny( sal_Bool( IsVisible() ) ); + aProps[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) ); + aProps[2].Value = uno::makeAny( rtl::OUString( GetText() ) ); + + return aProps; } diff --git a/vcl/source/window/wpropset.cxx b/vcl/source/window/wpropset.cxx new file mode 100644 index 000000000000..98c8a5b1dcfb --- /dev/null +++ b/vcl/source/window/wpropset.cxx @@ -0,0 +1,345 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_vcl.hxx" + +#include "vcl/wpropset.hxx" +#include "vcl/window.hxx" +#include "vcl/vclevent.hxx" +#include "vcl/svdata.hxx" + +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/beans/PropertyAttribute.hpp" +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/beans/XPropertyContainer.hpp" +#include "com/sun/star/beans/XPropertyAccess.hpp" + +#include "cppuhelper/basemutex.hxx" +#include "cppuhelper/compbase1.hxx" + +#include + +using namespace vcl; +using namespace com::sun::star; + +/* + +TODO: +- release solarmutex during outside UNO calls +- in ChildEventListener protect against reentry by using PostUserEvent + +*/ + +class vcl::WindowPropertySetListener : + public cppu::BaseMutex, + public cppu::WeakComponentImplHelper1< com::sun::star::beans::XPropertyChangeListener >, + private boost::noncopyable +{ + WindowPropertySet* mpParent; + bool mbSuspended; +public: + WindowPropertySetListener( WindowPropertySet* pParent ) + : cppu::WeakComponentImplHelper1< com::sun::star::beans::XPropertyChangeListener >( m_aMutex ) + , mpParent( pParent ) + , mbSuspended( false ) + {} + + virtual ~WindowPropertySetListener() + { + } + + virtual void SAL_CALL disposing( const lang::EventObject& ) throw() + { + } + + virtual void SAL_CALL propertyChange( const beans::PropertyChangeEvent& i_rEvent ) throw() + { + if( ! mbSuspended ) + mpParent->propertyChange( i_rEvent ); + } + + void suspend( bool i_bSuspended ) + { + mbSuspended = i_bSuspended; + } +}; + +class vcl::WindowPropertySetData +{ +public: + + struct PropertyMapEntry + { + Window* mpWindow; + boost::shared_ptr mpLayout; + uno::Sequence< beans::PropertyValue > maSavedValues; + + PropertyMapEntry( Window* i_pWindow = NULL, + const boost::shared_ptr& i_pLayout = boost::shared_ptr() ) + : mpWindow( i_pWindow ) + , mpLayout( i_pLayout ) + {} + + uno::Sequence< beans::PropertyValue > getProperties() const + { + if( mpWindow ) + return mpWindow->getProperties(); + else if( mpLayout.get() ) + return mpLayout->getProperties(); + return uno::Sequence< beans::PropertyValue >(); + } + + void setProperties( const uno::Sequence< beans::PropertyValue >& i_rProps ) const + { + if( mpWindow ) + mpWindow->setProperties( i_rProps ); + else if( mpLayout.get() ) + mpLayout->setProperties( i_rProps ); + } + }; + + Window* mpTopWindow; + bool mbOwner; + std::map< rtl::OUString, PropertyMapEntry > maProperties; + uno::Reference< beans::XPropertySet > mxPropSet; + uno::Reference< beans::XPropertyAccess > mxPropSetAccess; + uno::Reference< beans::XPropertyChangeListener > mxListener; + vcl::WindowPropertySetListener* mpListener; + + WindowPropertySetData() + : mpTopWindow( NULL ) + , mbOwner( false ) + , mpListener( NULL ) + {} + + ~WindowPropertySetData() + { + // release layouters, possibly interface properties before destroying + // the involved parent to be on the safe side + maProperties.clear(); + if( mbOwner ) + delete mpTopWindow; + } +}; + +static rtl::OUString getIdentifiedPropertyName( const rtl::OUString& i_rIdentifier, const rtl::OUString& i_rName ) +{ + rtl::OUStringBuffer aBuf( i_rIdentifier.getLength() + 1 + i_rName.getLength() ); + aBuf.append( i_rIdentifier ); + aBuf.append( sal_Unicode( '#' ) ); + aBuf.append( i_rName ); + return aBuf.makeStringAndClear(); +} + +static void spliceIdentifiedPropertyName( const rtl::OUString& i_rIdentifiedPropName, + rtl::OUString& o_rIdentifier, + rtl::OUString& o_rPropName ) +{ + sal_Int32 nIndex = 0; + o_rIdentifier = i_rIdentifiedPropName.getToken( 0, sal_Unicode( '#' ), nIndex ); + if( nIndex != -1 ) + o_rPropName = i_rIdentifiedPropName.copy( nIndex ); + else + o_rPropName = rtl::OUString(); +} + +WindowPropertySet::WindowPropertySet( Window* i_pTopWindow, bool i_bTakeOwnership ) +: mpImpl( new vcl::WindowPropertySetData ) +{ + mpImpl->mpTopWindow = i_pTopWindow; + mpImpl->mbOwner = i_bTakeOwnership; + + mpImpl->mpTopWindow->AddChildEventListener( LINK( this, WindowPropertySet, ChildEventListener ) ); + + mpImpl->mxPropSet = uno::Reference< beans::XPropertySet >( + ImplGetSVData()->maAppData.mxMSF->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.PropertyBag" ) ) ), + uno::UNO_QUERY ); + OSL_ENSURE( mpImpl->mxPropSet.is(), "could not create instance of com.sun.star.beans.PropertyBag" ); + mpImpl->mxPropSetAccess = uno::Reference< beans::XPropertyAccess >( mpImpl->mxPropSet, uno::UNO_QUERY ); + OSL_ENSURE( mpImpl->mxPropSet.is(), "could not query XPropertyAccess interface" ); + if( ! mpImpl->mxPropSetAccess.is() ) + mpImpl->mxPropSet.clear(); + + addWindowToSet( i_pTopWindow ); + + setupProperties(); + + if( mpImpl->mxPropSet.is() ) + { + mpImpl->mxListener.set( mpImpl->mpListener = new WindowPropertySetListener( this ) ); + } +} + +WindowPropertySet::~WindowPropertySet() +{ + mpImpl->mpTopWindow->RemoveChildEventListener( LINK( this, WindowPropertySet, ChildEventListener ) ); + + delete mpImpl; + mpImpl = NULL; +} + +uno::Reference< beans::XPropertySet > WindowPropertySet::getPropertySet() const +{ + return mpImpl->mxPropSet; +} + +void WindowPropertySet::addLayoutToSet( const boost::shared_ptr< WindowArranger >& i_pLayout ) +{ + if( i_pLayout.get() ) + { + if( i_pLayout->getIdentifier().getLength() ) + { + WindowPropertySetData::PropertyMapEntry& rEntry = mpImpl->maProperties[ i_pLayout->getIdentifier() ]; + OSL_ENSURE( rEntry.mpWindow == 0 && rEntry.mpLayout.get() == 0, "inserted layout has duplicate name" ); + rEntry.mpWindow = NULL; + rEntry.mpLayout = i_pLayout; + rEntry.maSavedValues = i_pLayout->getProperties(); + } + // insert child layouts + size_t nChildren = i_pLayout->countElements(); + for( size_t i = 0; i < nChildren; i++ ) + addLayoutToSet( i_pLayout->getChild( i ) ); + } +} + +void WindowPropertySet::addWindowToSet( Window* i_pWindow ) +{ + if( i_pWindow->getIdentifier().getLength() ) // no name, no properties + { + WindowPropertySetData::PropertyMapEntry& rEntry = mpImpl->maProperties[ i_pWindow->getIdentifier() ]; + OSL_ENSURE( rEntry.mpWindow == 0 && rEntry.mpLayout.get() == 0, "inserted window has duplicate name" ); + rEntry.mpWindow = i_pWindow; + rEntry.mpLayout.reset(); + rEntry.maSavedValues = i_pWindow->getProperties(); + } + addLayoutToSet( i_pWindow->getLayout() ); + + Window* pWin = i_pWindow->GetWindow( WINDOW_FIRSTCHILD ); + while( pWin ) + { + addWindowToSet( pWin ); + pWin = pWin->GetWindow( WINDOW_NEXT ); + } +} + +void WindowPropertySet::setupProperties() +{ + uno::Reference< beans::XPropertyContainer > xCont( mpImpl->mxPropSet, uno::UNO_QUERY ); + OSL_ENSURE( xCont.is(), "could not get XPropertyContainer interface" ); + if( ! xCont.is() ) + return; + + for( std::map< rtl::OUString, WindowPropertySetData::PropertyMapEntry >::iterator it + = mpImpl->maProperties.begin(); it != mpImpl->maProperties.end(); ++it ) + { + uno::Sequence< beans::PropertyValue > aOutsideValues( it->second.maSavedValues ); + beans::PropertyValue* pVal = aOutsideValues.getArray(); + for( sal_Int32 i = 0; i < aOutsideValues.getLength(); i++ ) + { + pVal[i].Name = getIdentifiedPropertyName( it->first, pVal[i].Name ); + xCont->addProperty( pVal[i].Name, + beans::PropertyAttribute::BOUND | beans:: PropertyAttribute::CONSTRAINED, + pVal[i].Value + ); + } + } +} + +void WindowPropertySet::propertyChange( const beans::PropertyChangeEvent& i_rEvent ) +{ + rtl::OUString aIdentifier, aProperty; + spliceIdentifiedPropertyName( i_rEvent.PropertyName, aIdentifier, aProperty ); + std::map< rtl::OUString, WindowPropertySetData::PropertyMapEntry >::iterator it = + mpImpl->maProperties.find( aIdentifier ); + if( it != mpImpl->maProperties.end() ) + { + uno::Sequence< beans::PropertyValue > aSet( 1 ); + aSet[0].Name = aProperty; + aSet[0].Value = i_rEvent.NewValue; + it->second.setProperties( aSet ); + } +} + +IMPL_LINK( vcl::WindowPropertySet, ChildEventListener, VclWindowEvent*, pEvent ) +{ + // find window in our properties + std::map< rtl::OUString, WindowPropertySetData::PropertyMapEntry >::iterator it + = mpImpl->maProperties.find( pEvent->GetWindow()->getIdentifier() ); + if( it != mpImpl->maProperties.end() ) // this is valid, some unnamed child may have sent an event + { + ULONG nId = pEvent->GetId(); + // check if anything interesting happened + if( + // general windowy things + nId == VCLEVENT_WINDOW_SHOW || + nId == VCLEVENT_WINDOW_HIDE || + nId == VCLEVENT_WINDOW_ENABLED || + nId == VCLEVENT_WINDOW_DISABLED || + // button thingies + nId == VCLEVENT_BUTTON_CLICK || + nId == VCLEVENT_PUSHBUTTON_TOGGLE || + nId == VCLEVENT_RADIOBUTTON_TOGGLE || + nId == VCLEVENT_CHECKBOX_TOGGLE || + // listbox + nId == VCLEVENT_LISTBOX_SELECT || + // edit + nId == VCLEVENT_EDIT_MODIFY + ) + { + WindowPropertySetData::PropertyMapEntry& rEntry = it->second; + // collect changes + uno::Sequence< beans::PropertyValue > aNewProps( rEntry.getProperties() ); + uno::Sequence< beans::PropertyValue > aNewPropsOut( aNewProps ); + + // translate to identified properties + beans::PropertyValue* pValues = aNewPropsOut.getArray(); + for( sal_Int32 i = 0; i < aNewPropsOut.getLength(); i++ ) + pValues[i].Name = getIdentifiedPropertyName( it->first, pValues[i].Name ); + + // broadcast changes + bool bWasVeto = false; + mpImpl->mpListener->suspend( true ); + try + { + mpImpl->mxPropSetAccess->setPropertyValues( aNewPropsOut ); + } + catch( beans::PropertyVetoException& ) + { + bWasVeto = true; + } + mpImpl->mpListener->suspend( false ); + + if( ! bWasVeto ) // changes accepted ? + rEntry.maSavedValues = rEntry.getProperties(); + else // no, reset + rEntry.setProperties( rEntry.maSavedValues ); + } + } + + return 0; +} -- cgit v1.2.3 From 86c8dc781b3a5aef3126931ee43d1f190a0143a5 Mon Sep 17 00:00:00 2001 From: Mathias Bauer Date: Mon, 19 Apr 2010 18:27:03 +0200 Subject: CWS gnumake2: remove duplicate header in solver: vcl/imagebtn.hxx is just a copy of vcl/button.hxx --- rsc/source/parser/rscdb.cxx | 2 +- svtools/inc/svtools/addresstemplate.hxx | 2 +- svtools/inc/svtools/editbrowsebox.hxx | 2 +- vcl/prj/d.lst | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'vcl') diff --git a/rsc/source/parser/rscdb.cxx b/rsc/source/parser/rscdb.cxx index 97d23d4e3b53..d003b9a1f321 100644 --- a/rsc/source/parser/rscdb.cxx +++ b/rsc/source/parser/rscdb.cxx @@ -902,7 +902,7 @@ ERRTYPE RscTypCont :: WriteHxx( FILE * fOutput, ULONG nFileKey ) fprintf( fOutput, "#include \n" ); fprintf( fOutput, "#include \n" ); fprintf( fOutput, "#include \n" ); - fprintf( fOutput, "#include \n" ); + fprintf( fOutput, "#include \n" ); fprintf( fOutput, "#include \n" ); fprintf( fOutput, "#include \n" ); fprintf( fOutput, "#include \n" ); diff --git a/svtools/inc/svtools/addresstemplate.hxx b/svtools/inc/svtools/addresstemplate.hxx index f29ea2478b4e..bb4ee44647e9 100644 --- a/svtools/inc/svtools/addresstemplate.hxx +++ b/svtools/inc/svtools/addresstemplate.hxx @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/svtools/inc/svtools/editbrowsebox.hxx b/svtools/inc/svtools/editbrowsebox.hxx index f97449e1880c..26ff11e11ca2 100644 --- a/svtools/inc/svtools/editbrowsebox.hxx +++ b/svtools/inc/svtools/editbrowsebox.hxx @@ -37,7 +37,7 @@ #include #ifndef _IMAGEBTN_HXX -#include +#include #endif #include #include diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst index 8345b155ce58..5d6a25d6323a 100644 --- a/vcl/prj/d.lst +++ b/vcl/prj/d.lst @@ -22,7 +22,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\bmpacc.hxx %_DEST%\inc%_EXT%\vcl\bmpacc.hxx ..\inc\vcl\btndlg.hxx %_DEST%\inc%_EXT%\vcl\btndlg.hxx ..\inc\vcl\button.hxx %_DEST%\inc%_EXT%\vcl\button.hxx -..\inc\vcl\button.hxx %_DEST%\inc%_EXT%\vcl\imagebtn.hxx ..\inc\vcl\cmdevt.h %_DEST%\inc%_EXT%\vcl\cmdevt.h ..\inc\vcl\cmdevt.hxx %_DEST%\inc%_EXT%\vcl\cmdevt.hxx ..\inc\vcl\combobox.h %_DEST%\inc%_EXT%\vcl\combobox.h @@ -153,4 +152,4 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\ppdparser.hxx %_DEST%\inc%_EXT%\vcl\ppdparser.hxx ..\inc\vcl\helper.hxx %_DEST%\inc%_EXT%\vcl\helper.hxx ..\inc\vcl\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx -..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx \ No newline at end of file +..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx -- cgit v1.2.3 From 841c2c37e5186b2de0b075a03528f11d8b06c6a7 Mon Sep 17 00:00:00 2001 From: Mikhail Voytenko Date: Mon, 23 Aug 2010 19:20:31 +0200 Subject: mib19: #163018# allow to intercept the messages to the system child windows --- vcl/inc/vcl/salframe.hxx | 1 - vcl/inc/vcl/salobj.hxx | 2 ++ vcl/inc/vcl/window.h | 3 ++- vcl/inc/vcl/window.hxx | 3 +++ vcl/source/window/window.cxx | 7 ++++++ vcl/win/inc/saldata.hxx | 1 + vcl/win/inc/salobj.h | 2 ++ vcl/win/source/app/salinst.cxx | 15 ++++++++---- vcl/win/source/gdi/salprn.cxx | 15 ++++++++---- vcl/win/source/window/salobj.cxx | 50 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 89 insertions(+), 10 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/salframe.hxx b/vcl/inc/vcl/salframe.hxx index 08548d7dda40..d82a2099f315 100644 --- a/vcl/inc/vcl/salframe.hxx +++ b/vcl/inc/vcl/salframe.hxx @@ -270,7 +270,6 @@ public: // done setting up the clipregion virtual void EndSetClipRegion() = 0; - // Callbacks (indepent part in vcl/source/window/winproc.cxx) // for default message handling return 0 void SetCallback( Window* pWindow, SALFRAMEPROC pProc ) diff --git a/vcl/inc/vcl/salobj.hxx b/vcl/inc/vcl/salobj.hxx index e453bf5c6f87..adf0e0a3d45d 100644 --- a/vcl/inc/vcl/salobj.hxx +++ b/vcl/inc/vcl/salobj.hxx @@ -73,6 +73,8 @@ public: virtual const SystemEnvData* GetSystemData() const = 0; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ) = 0; + void SetCallback( void* pInst, SALOBJECTPROC pProc ) { m_pInst = pInst; m_pCallback = pProc; } long CallCallback( USHORT nEvent, const void* pEvent ) diff --git a/vcl/inc/vcl/window.h b/vcl/inc/vcl/window.h index 691c3ed18421..c12dcd618d92 100644 --- a/vcl/inc/vcl/window.h +++ b/vcl/inc/vcl/window.h @@ -355,7 +355,8 @@ public: mbDisableAccessibleLabelForRelation:1, mbDisableAccessibleLabeledByRelation:1, mbHelpTextDynamic:1, - mbFakeFocusSet:1; + mbFakeFocusSet:1, + mbInterceptChildWindowKeyDown:1; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer; }; diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index 8264767e59ad..a7628da0b408 100644 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -1101,6 +1101,9 @@ public: */ void doLazyDelete(); + // let the window intercept the KeyDown messages of the system children + void InterceptChildWindowKeyDown( sal_Bool bIntercept ); + virtual XubString GetSurroundingText() const; virtual Selection GetSurroundingTextSelection() const; }; diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index adedbde4c0f2..370669d6969b 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -4791,6 +4791,13 @@ void Window::doLazyDelete() vcl::LazyDeletor::Delete( this ); } +// ----------------------------------------------------------------------- +void Window::InterceptChildWindowKeyDown( sal_Bool bIntercept ) +{ + if( mpWindowImpl->mpSysObj ) + mpWindowImpl->mpSysObj->InterceptChildWindowKeyDown( bIntercept ); +} + // ----------------------------------------------------------------------- void Window::MouseMove( const MouseEvent& rMEvt ) diff --git a/vcl/win/inc/saldata.hxx b/vcl/win/inc/saldata.hxx index ec67272ed07f..f95f1e0ca96b 100644 --- a/vcl/win/inc/saldata.hxx +++ b/vcl/win/inc/saldata.hxx @@ -213,6 +213,7 @@ void ImplSalYieldMutexAcquire(); void ImplSalYieldMutexRelease(); ULONG ImplSalReleaseYieldMutex(); void ImplSalAcquireYieldMutex( ULONG nCount ); +sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg ); // \\WIN\SOURCE\WINDOW\SALFRAME.CXX LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); diff --git a/vcl/win/inc/salobj.h b/vcl/win/inc/salobj.h index 11ae96931321..ae7ea5271800 100644 --- a/vcl/win/inc/salobj.h +++ b/vcl/win/inc/salobj.h @@ -46,6 +46,7 @@ public: RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data RECT* mpNextClipRect; // Naechstes ClipRegion-Rect BOOL mbFirstClipRect; // Flag for first cliprect to insert + sal_Bool mbInterceptChildWindowKeyDown; // Intercept the KeyDown event sent to system child window WinSalObject* mpNextObject; // pointer to next object @@ -64,6 +65,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx index 97dbb5285cca..9514bc9a2ace 100644 --- a/vcl/win/source/app/salinst.cxx +++ b/vcl/win/source/app/salinst.cxx @@ -721,8 +721,12 @@ void ImplSalYield( BOOL bWait, BOOL bHandleAllCurrentEvents ) { if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplSalDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } + bOneEvent = bWasMsg = true; } else @@ -733,8 +737,11 @@ void ImplSalYield( BOOL bWait, BOOL bHandleAllCurrentEvents ) { if ( ImplGetMessage( &aMsg, 0, 0, 0 ) ) { - TranslateMessage( &aMsg ); - ImplSalDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } } } } diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index 9d8d41723f64..702ff639ed84 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -1798,8 +1798,11 @@ WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ ) MSG aMsg; if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + } i++; if ( i > 15 ) bWhile = FALSE; @@ -2060,8 +2063,12 @@ BOOL WinSalPrinter::StartJob( const XubString* pFileName, MSG aMsg; if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + } + i++; if ( i > 15 ) bWhile = FALSE; diff --git a/vcl/win/source/window/salobj.cxx b/vcl/win/source/window/salobj.cxx index 2f657968284f..6d00242ef313 100644 --- a/vcl/win/source/window/salobj.cxx +++ b/vcl/win/source/window/salobj.cxx @@ -39,6 +39,7 @@ #include #include #include +#include // ======================================================================= @@ -101,6 +102,46 @@ WinSalFrame* ImplFindSalObjectFrame( HWND hWnd ) return pFrame; } +// ----------------------------------------------------------------------- + +sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg ) +{ + sal_Bool bResult = sal_False; + if ( rMsg.message == WM_KEYDOWN ) + { + wchar_t pClassName[10]; + sal_Int32 nLen = GetClassNameW( rMsg.hwnd, pClassName, 10 ); + if ( !( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) ) + { + // look for the first SalObject in the parent hierarchy + HWND hWin = rMsg.hwnd; + HWND hLastOLEWindow = hWin; + WinSalObject* pSalObj = NULL; + do + { + hLastOLEWindow = hWin; + hWin = ::GetParent( hWin ); + if ( hWin ) + { + nLen = GetClassNameW( hWin, pClassName, 10 ); + if ( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) + pSalObj = GetSalObjWindowPtr( hWin ); + } + } while( hWin && !pSalObj ); + + if ( pSalObj && pSalObj->mbInterceptChildWindowKeyDown && pSalObj->maSysData.hWnd ) + { + bResult = ( 1 == ImplSendMessage( pSalObj->maSysData.hWnd, rMsg.message, rMsg.wParam, rMsg.lParam ) ); + } + } + } + + return bResult; +} + +// ----------------------------------------------------------------------- + + // ----------------------------------------------------------------------- LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam ) @@ -623,6 +664,7 @@ WinSalObject::WinSalObject() mhLastFocusWnd = 0; maSysData.nSize = sizeof( SystemEnvData ); mpStdClipRgnData = NULL; + mbInterceptChildWindowKeyDown = sal_False; // Insert object in objectlist mpNextObject = pSalData->mpFirstObject; @@ -836,3 +878,11 @@ const SystemEnvData* WinSalObject::GetSystemData() const { return &maSysData; } + +// ----------------------------------------------------------------------- + +void WinSalObject::InterceptChildWindowKeyDown( sal_Bool bIntercept ) +{ + mbInterceptChildWindowKeyDown = bIntercept; +} + -- cgit v1.2.3 From 123175d154c725a8238a408abce8d6491ed7df1c Mon Sep 17 00:00:00 2001 From: Mikhail Voytenko Date: Mon, 23 Aug 2010 19:27:56 +0200 Subject: mib19: #163018# adjust other platforms --- vcl/aqua/inc/salobj.h | 1 + vcl/aqua/source/window/salobj.cxx | 6 ++++++ vcl/os2/inc/salobj.h | 1 + vcl/os2/source/window/salobj.cxx | 6 ++++++ vcl/unx/inc/salobj.h | 1 + vcl/unx/source/window/salobj.cxx | 7 +++++++ 6 files changed, 22 insertions(+) (limited to 'vcl') diff --git a/vcl/aqua/inc/salobj.h b/vcl/aqua/inc/salobj.h index 0041b22c16a0..56b07cea4262 100644 --- a/vcl/aqua/inc/salobj.h +++ b/vcl/aqua/inc/salobj.h @@ -81,6 +81,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/aqua/source/window/salobj.cxx b/vcl/aqua/source/window/salobj.cxx index 07d337dcc81a..f300929f04fe 100644 --- a/vcl/aqua/source/window/salobj.cxx +++ b/vcl/aqua/source/window/salobj.cxx @@ -237,3 +237,9 @@ const SystemEnvData* AquaSalObject::GetSystemData() const return &maSysData; } +// ----------------------------------------------------------------------- + +void AquaSalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/os2/inc/salobj.h b/vcl/os2/inc/salobj.h index 5b4ac21ccdd6..04fdef90bf67 100644 --- a/vcl/os2/inc/salobj.h +++ b/vcl/os2/inc/salobj.h @@ -64,6 +64,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/os2/source/window/salobj.cxx b/vcl/os2/source/window/salobj.cxx index 85ed1a606d08..e55ce448f7d0 100644 --- a/vcl/os2/source/window/salobj.cxx +++ b/vcl/os2/source/window/salobj.cxx @@ -566,3 +566,9 @@ void Os2SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc ) } #endif +// ----------------------------------------------------------------------- + +void Os2SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/unx/inc/salobj.h b/vcl/unx/inc/salobj.h index fa9f1309c8ca..d7d9334f281b 100644 --- a/vcl/unx/inc/salobj.h +++ b/vcl/unx/inc/salobj.h @@ -98,6 +98,7 @@ public: virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/unx/source/window/salobj.cxx b/vcl/unx/source/window/salobj.cxx index 647b95ae032c..2ff6d05c35c6 100644 --- a/vcl/unx/source/window/salobj.cxx +++ b/vcl/unx/source/window/salobj.cxx @@ -559,3 +559,10 @@ long X11SalObject::Dispatch( XEvent* pEvent ) } return 0; } + +// ----------------------------------------------------------------------- + +void X11SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + -- cgit v1.2.3 From 3036c496a1f303386d9d7eebe4317ea6c7d3cf0c Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Tue, 31 Aug 2010 11:29:02 +0200 Subject: mib19: missing implementations of abstract function --- vcl/unx/gtk/window/gtkobject.cxx | 5 +++++ vcl/unx/headless/svpdummies.cxx | 1 + vcl/unx/headless/svpdummies.hxx | 2 ++ vcl/unx/inc/plugins/gtk/gtkobject.hxx | 1 + 4 files changed, 9 insertions(+) (limited to 'vcl') diff --git a/vcl/unx/gtk/window/gtkobject.cxx b/vcl/unx/gtk/window/gtkobject.cxx index 2a2bbe78078a..c5f5a168f653 100644 --- a/vcl/unx/gtk/window/gtkobject.cxx +++ b/vcl/unx/gtk/window/gtkobject.cxx @@ -209,3 +209,8 @@ void GtkSalObject::signalDestroy( GtkObject* pObj, gpointer object ) pThis->m_pSocket = NULL; } } + +void GtkSalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/unx/headless/svpdummies.cxx b/vcl/unx/headless/svpdummies.cxx index 5983ff18c34f..0a67b147804a 100644 --- a/vcl/unx/headless/svpdummies.cxx +++ b/vcl/unx/headless/svpdummies.cxx @@ -61,6 +61,7 @@ void SvpSalObject::GrabFocus() {} void SvpSalObject::SetBackground() {} void SvpSalObject::SetBackground( SalColor ) {} const SystemEnvData* SvpSalObject::GetSystemData() const { return &m_aSystemChildData; } +void SvpSalObject::InterceptChildWindowKeyDown( sal_Bool ) {} // SalI18NImeStatus SvpImeStatus::~SvpImeStatus() {} diff --git a/vcl/unx/headless/svpdummies.hxx b/vcl/unx/headless/svpdummies.hxx index febf7eef6bbe..ea7667ce51ca 100644 --- a/vcl/unx/headless/svpdummies.hxx +++ b/vcl/unx/headless/svpdummies.hxx @@ -58,6 +58,8 @@ public: virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; class SvpImeStatus : public SalI18NImeStatus diff --git a/vcl/unx/inc/plugins/gtk/gtkobject.hxx b/vcl/unx/inc/plugins/gtk/gtkobject.hxx index ea740249f1c6..9d3f235b8894 100644 --- a/vcl/unx/inc/plugins/gtk/gtkobject.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkobject.hxx @@ -64,6 +64,7 @@ public: virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H -- cgit v1.2.3 From a555527edb34036835b167f0b3b7f6d515f098c4 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Thu, 2 Sep 2010 18:58:54 +0200 Subject: pl08: #i114277# enhance SfxPasswordDialog --- vcl/inc/vcl/arrange.hxx | 28 ++++++++++++++++++++++------ vcl/source/window/arrange.cxx | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 19 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index eed33e379e5b..d33bac7ccd7f 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -76,11 +76,13 @@ namespace vcl Element( Window* i_pWin, boost::shared_ptr const & i_pChild = boost::shared_ptr(), - sal_Int32 i_nExpandPriority = 0 + sal_Int32 i_nExpandPriority = 0, + const Size& i_rMinSize = Size() ) : m_pElement( i_pWin ) , m_pChild( i_pChild ) , m_nExpandPriority( i_nExpandPriority ) + , m_aMinSize( i_rMinSize ) , m_bHidden( false ) , m_nLeftBorder( 0 ) , m_nTopBorder( 0 ) @@ -183,6 +185,19 @@ namespace vcl } } + void getBorders( size_t i_nIndex, long* i_pLeft = NULL, long* i_pTop = NULL, long* i_pRight = NULL, long* i_pBottom = NULL ) const + { + const Element* pEle = getConstElement( i_nIndex ); + if( pEle ) + { + if( i_pLeft ) *i_pLeft = pEle->m_nLeftBorder; + if( i_pTop ) *i_pTop = pEle->m_nTopBorder; + if( i_pRight ) *i_pRight = pEle->m_nRightBorder; + if( i_pBottom ) *i_pBottom = pEle->m_nBottomBorder; + } + } + + void show( bool i_bShow = true, bool i_bImmediateUpdate = true ); void setManagedArea( const Rectangle& i_rArea ) @@ -234,7 +249,7 @@ namespace vcl // add a managed window at the given index // an index smaller than zero means add the window at the end - size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 ); + size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, const Size& i_rMinSize = Size(), size_t i_nIndex = ~0 ); void remove( Window* ); size_t addChild( boost::shared_ptr const &, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 ); @@ -304,7 +319,7 @@ namespace vcl // returns the index of the added label size_t addRow( Window* i_pLabel, boost::shared_ptr const& i_rElement, long i_nIndent = 0 ); - size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0 ); + size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0, const Size& i_rElementMinSize = Size() ); }; class VCL_DLLPUBLIC Indenter : public WindowArranger @@ -386,9 +401,10 @@ namespace vcl MatrixElement( Window* i_pWin, sal_uInt32 i_nX, sal_uInt32 i_nY, boost::shared_ptr const & i_pChild = boost::shared_ptr(), - sal_Int32 i_nExpandPriority = 0 + sal_Int32 i_nExpandPriority = 0, + const Size& i_rMinSize = Size() ) - : WindowArranger::Element( i_pWin, i_pChild, i_nExpandPriority ) + : WindowArranger::Element( i_pWin, i_pChild, i_nExpandPriority, i_rMinSize ) , m_nX( i_nX ) , m_nY( i_nY ) { @@ -422,7 +438,7 @@ namespace vcl virtual size_t countElements() const { return m_aElements.size(); } // add a managed window at the given matrix position - size_t addWindow( Window*, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 ); + size_t addWindow( Window*, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0, const Size& i_rMinSize = Size() ); void remove( Window* ); size_t addChild( boost::shared_ptr const &, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 ); diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx index ea827a224f4a..bba5eeb013a3 100644 --- a/vcl/source/window/arrange.cxx +++ b/vcl/source/window/arrange.cxx @@ -178,16 +178,26 @@ Size WindowArranger::Element::getOptimalSize( WindowSizeType i_eType ) const Size aResult; if( ! m_bHidden ) { + bool bVisible = false; if( m_pElement && m_pElement->IsVisible() ) + { aResult = m_pElement->GetOptimalSize( i_eType ); - else if( m_pChild ) + bVisible = true; + } + else if( m_pChild && m_pChild->isVisible() ) + { aResult = m_pChild->getOptimalSize( i_eType ); - if( aResult.Width() < m_aMinSize.Width() ) - aResult.Width() = m_aMinSize.Width(); - if( aResult.Height() < m_aMinSize.Height() ) - aResult.Height() = m_aMinSize.Height(); - aResult.Width() += getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); - aResult.Height() += getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); + bVisible = true; + } + if( bVisible ) + { + if( aResult.Width() < m_aMinSize.Width() ) + aResult.Width() = m_aMinSize.Width(); + if( aResult.Height() < m_aMinSize.Height() ) + aResult.Height() = m_aMinSize.Height(); + aResult.Width() += getBorderValue( m_nLeftBorder ) + getBorderValue( m_nRightBorder ); + aResult.Height() += getBorderValue( m_nTopBorder ) + getBorderValue( m_nBottomBorder ); + } } return aResult; @@ -477,20 +487,20 @@ void RowOrColumn::resize() } } -size_t RowOrColumn::addWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio, size_t i_nIndex ) +size_t RowOrColumn::addWindow( Window* i_pWindow, sal_Int32 i_nExpandPrio, const Size& i_rMinSize, size_t i_nIndex ) { size_t nIndex = i_nIndex; if( i_nIndex >= m_aElements.size() ) { nIndex = m_aElements.size(); - m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr(), i_nExpandPrio ) ); + m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr(), i_nExpandPrio, i_rMinSize ) ); } else { std::vector< WindowArranger::Element >::iterator it = m_aElements.begin(); while( i_nIndex-- ) ++it; - m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr(), i_nExpandPrio ) ); + m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr(), i_nExpandPrio, i_rMinSize ) ); } return nIndex; } @@ -664,6 +674,9 @@ long LabelColumn::getLabelWidth() const if( pLW ) { Size aLabSize( pLW->GetOptimalSize( WINDOWSIZE_MINIMUM ) ); + long nLB = 0; + pLabel->getBorders(0, &nLB); + aLabSize.Width() += getBorderValue( nLB ); if( aLabSize.Width() > nWidth ) nWidth = aLabSize.Width(); } @@ -754,12 +767,13 @@ size_t LabelColumn::addRow( Window* i_pLabel, boost::shared_ptr return nIndex; } -size_t LabelColumn::addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent ) +size_t LabelColumn::addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent, const Size& i_rElementMinSize ) { boost::shared_ptr< LabeledElement > xLabel( new LabeledElement( this, 1 ) ); xLabel->setLabel( i_pLabel ); xLabel->setBorders( 0, i_nIndent, 0, 0, 0 ); xLabel->setElement( i_pElement ); + xLabel->setMinimumSize( 1, i_rElementMinSize ); size_t nIndex = addChild( xLabel ); resize(); return nIndex; @@ -918,7 +932,7 @@ void MatrixArranger::resize() } } -size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio ) +size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio, const Size& i_rMinSize ) { sal_uInt64 nMapValue = getMap( i_nX, i_nY ); std::map< sal_uInt64, size_t >::const_iterator it = m_aMatrixMap.find( nMapValue ); @@ -926,7 +940,7 @@ size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 if( it == m_aMatrixMap.end() ) { m_aMatrixMap[ nMapValue ] = nIndex = m_aElements.size(); - m_aElements.push_back( MatrixElement( i_pWindow, i_nX, i_nY, boost::shared_ptr(), i_nExpandPrio ) ); + m_aElements.push_back( MatrixElement( i_pWindow, i_nX, i_nY, boost::shared_ptr(), i_nExpandPrio, i_rMinSize ) ); } else { @@ -934,6 +948,7 @@ size_t MatrixArranger::addWindow( Window* i_pWindow, sal_uInt32 i_nX, sal_uInt32 rEle.m_pElement = i_pWindow; rEle.m_pChild.reset(); rEle.m_nExpandPriority = i_nExpandPrio; + rEle.m_aMinSize = i_rMinSize; rEle.m_nX = i_nX; rEle.m_nY = i_nY; nIndex = it->second; -- cgit v1.2.3 From 4d25643942f30ad94b853a65338098d842767ed8 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Fri, 24 Sep 2010 14:28:04 +0200 Subject: step1: put encrpytion parameters into PDFContext --- vcl/inc/vcl/pdfwriter.hxx | 82 ++-- vcl/source/gdi/pdfwriter.cxx | 20 +- vcl/source/gdi/pdfwriter_impl.cxx | 817 +++++++++++++++++++++++--------------- vcl/source/gdi/pdfwriter_impl.hxx | 170 +++----- 4 files changed, 607 insertions(+), 482 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx index 419814e5ce97..cbb9c7c2fe93 100644 --- a/vcl/inc/vcl/pdfwriter.hxx +++ b/vcl/inc/vcl/pdfwriter.hxx @@ -61,16 +61,6 @@ class Wallpaper; namespace vcl { -struct PDFDocInfo -{ - String Title; // document title - String Author; // document author - String Subject; // subject - String Keywords; // keywords - String Creator; // application that created the original document - String Producer; // OpenOffice -}; - struct PDFNote { String Title; // optional title for the popup containing the note @@ -468,7 +458,7 @@ public: FitVisible, ActionZoom }; -// These emuns are treated as integer while reading/writing to configuration +// These enums are treated as integer while reading/writing to configuration enum PDFPageLayout { DefaultLayout, @@ -489,20 +479,35 @@ public: /* The following structure describes the permissions used in PDF security */ - struct PDFSecPermissions + struct PDFEncryptionProperties { -//for both 40 and 128 bit security, see 3.5.2 PDF v 1.4 table 3.15, v 1.5 and v 1.6 table 3.20. - bool CanPrintTheDocument; + + bool Security128bit; // true to select 128 bit encryption, false for 40 bit + //for both 40 and 128 bit security, see 3.5.2 PDF v 1.4 table 3.15, v 1.5 and v 1.6 table 3.20. + bool CanPrintTheDocument; bool CanModifyTheContent; bool CanCopyOrExtract; bool CanAddOrModify; -//for revision 3 (bit 128 security) only + //for revision 3 (bit 128 security) only bool CanFillInteractive; bool CanExtractForAccessibility; bool CanAssemble; bool CanPrintFull; -//permission default set for 128 bit, accessibility only - PDFSecPermissions() : + + // encryption will only happen if EncryptionKey is not empty + // EncryptionKey is actually a construct out of OValue, UValue and DocumentIdentifier + // if these do not match, behavior is undefined, most likely an invalid PDF will be produced + // OValue, UValue, EncryptionKey and DocumentIdentifier can be computed from + // PDFDocInfo, Owner password and User password usend the InitEncryption method which + // implements the algorithms described in the PDF reference chapter 3.5: Encryption + std::vector OValue; + std::vector UValue; + std::vector EncryptionKey; + std::vector DocumentIdentifier; + + //permission default set for 128 bit, accessibility only + PDFEncryptionProperties() : + Security128bit ( true ), CanPrintTheDocument ( false ), CanModifyTheContent ( false ), CanCopyOrExtract ( false ), @@ -512,6 +517,20 @@ The following structure describes the permissions used in PDF security CanAssemble ( false ), CanPrintFull ( false ) {} + + + bool Encrypt() const + { return ! OValue.empty() && ! UValue.empty() && ! DocumentIdentifier.empty(); } + }; + + struct PDFDocInfo + { + String Title; // document title + String Author; // document author + String Subject; // subject + String Keywords; // keywords + String Creator; // application that created the original document + String Producer; // OpenOffice }; struct PDFWriterContext @@ -570,12 +589,8 @@ The following structure describes the permissions used in PDF security sal_Int32 InitialPage; sal_Int32 OpenBookmarkLevels; // -1 means all levels - struct PDFSecPermissions AccessPermissions; - - bool Encrypt; // main encryption flag, must be true to encript - bool Security128bit; // true to select 128 bit encryption, false for 40 bit - rtl::OUString OwnerPassword; // owner password for PDF, in clear text - rtl::OUString UserPassword; // user password for PDF, in clear text + PDFWriter::PDFEncryptionProperties Encryption; + PDFWriter::PDFDocInfo DocumentInfo; com::sun::star::lang::Locale DocumentLocale; // defines the document default language @@ -604,9 +619,7 @@ The following structure describes the permissions used in PDF security FirstPageLeft( false ), InitialPage( 1 ), OpenBookmarkLevels( -1 ), - AccessPermissions( ), - Encrypt( false ), - Security128bit( true ) + Encryption() {} }; @@ -636,17 +649,6 @@ The following structure describes the permissions used in PDF security */ sal_Int32 NewPage( sal_Int32 nPageWidth = 0, sal_Int32 nPageHeight = 0, Orientation eOrientation = Inherit ); - /* - * set document info; due to the use of document information in building the PDF document ID, must be called before - * emitting anything. - */ - void SetDocInfo( const PDFDocInfo& rInfo ); - - /* - * get currently set document info - */ - const PDFDocInfo& GetDocInfo() const; - /* sets the document locale originally passed with the context to a new value * only affects the output if used before calling Emit/code>. */ @@ -664,6 +666,12 @@ The following structure describes the permissions used in PDF security PDFVersion GetVersion() const; + static bool InitEncryption( PDFWriter::PDFEncryptionProperties& io_rProperties, + const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + const PDFWriter::PDFDocInfo& i_rDocInfo + ); + /* functions for graphics state */ /* flag values: see vcl/outdev.hxx */ void Push( USHORT nFlags = 0xffff ); diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 5dcce25a0315..3b5e70d938a8 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -69,16 +69,6 @@ PDFWriter::PDFVersion PDFWriter::GetVersion() const return ((PDFWriterImpl*)pImplementation)->getVersion(); } -void PDFWriter::SetDocInfo( const PDFDocInfo& rInfo ) -{ - ((PDFWriterImpl*)pImplementation)->setDocInfo( rInfo ); -} - -const PDFDocInfo& PDFWriter::GetDocInfo() const -{ - return ((PDFWriterImpl*)pImplementation)->getDocInfo(); -} - void PDFWriter::SetDocumentLocale( const com::sun::star::lang::Locale& rLoc ) { ((PDFWriterImpl*)pImplementation)->setDocumentLocale( rLoc ); @@ -569,3 +559,13 @@ std::set< PDFWriter::ErrorCode > PDFWriter::GetErrors() { return ((PDFWriterImpl*)pImplementation)->getErrors(); } + +bool PDFWriter::InitEncryption( PDFWriter::PDFEncryptionProperties& io_rProperties, + const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + const PDFWriter::PDFDocInfo& i_rDocInfo + ) +{ + return PDFWriterImpl::initEncryption( io_rProperties, i_rOwnerPassword, i_rUserPassword, i_rDocInfo ); +} + diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 09cf1734eb6f..ff415ccfa98c 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -113,12 +113,10 @@ void doTestCode() aContext.Version = PDFWriter::PDF_1_4; aContext.Tagged = true; aContext.InitialPage = 2; + aContext.DocumentInfo.Title = OUString( RTL_CONSTASCII_USTRINGPARAM( "PDF export test document" ) ); + aContext.DocumentInfo.Producer = OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL" ) ); PDFWriter aWriter( aContext ); - PDFDocInfo aDocInfo; - aDocInfo.Title = OUString( RTL_CONSTASCII_USTRINGPARAM( "PDF export test document" ) ); - aDocInfo.Producer = OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL" ) ); - aWriter.SetDocInfo( aDocInfo ); aWriter.NewPage( 595, 842 ); aWriter.BeginStructureElement( PDFWriter::Document ); // set duration of 3 sec for first page @@ -496,6 +494,12 @@ static inline double pixelToPoint( sal_Int32 px ) { return double(px)/fDivisor; static inline double pixelToPoint( double px ) { return px/fDivisor; } static inline sal_Int32 pointToPixel( double pt ) { return sal_Int32(pt*fDivisor); } +const sal_uInt8 PDFWriterImpl::s_nPadString[32] = +{ + 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, + 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A +}; + static void appendHex( sal_Int8 nInt, OStringBuffer& rBuffer ) { static const sal_Char pHexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', @@ -1714,9 +1718,6 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_aCipher( (rtlCipher)NULL ), m_aDigest( NULL ), m_bEncryptThisStream( false ), - m_aDocID( 32 ), - m_aCreationDateString( 64 ), - m_aCreationMetaDateString( 64 ), m_pEncryptionBuffer( NULL ), m_nEncryptionBufferSize( 0 ), m_bIsPDF_A1( false ) @@ -1758,14 +1759,32 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_bOpen = true; -/* prepare the cypher engine, can be done in CTOR, free in DTOR */ + /* prepare the cypher engine, can be done in CTOR, free in DTOR */ m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); m_aDigest = rtl_digest_createMD5(); -/* the size of the Codec default maximum */ + /* the size of the Codec default maximum */ checkEncryptionBufferSize( 0x4000 ); + if( m_aContext.Encryption.Encrypt() ) + { + // sanity check + if( m_aContext.Encryption.OValue.size() != ENCRYPTED_PWD_SIZE || + m_aContext.Encryption.UValue.size() != ENCRYPTED_PWD_SIZE || + m_aContext.Encryption.EncryptionKey.size() != MAXIMUM_RC4_KEY_LENGTH + ) + { + // the field lengths are invalid ? This was not setup by initEncryption. + // do not encrypt after all + m_aContext.Encryption.OValue.clear(); + m_aContext.Encryption.UValue.clear(); + OSL_ENSURE( 0, "encryption data failed sanity check, encryption disabled" ); + } + else // setup key lengths + m_nAccessPermissions = computeAccessPermissions( m_aContext.Encryption, m_nKeyLength, m_nRC4KeyLength ); + } + // write header OStringBuffer aBuffer( 20 ); aBuffer.append( "%PDF-" ); @@ -1811,139 +1830,138 @@ PDFWriterImpl::~PDFWriterImpl() rtl_freeMemory( m_pEncryptionBuffer ); } -void PDFWriterImpl::setDocInfo( const PDFDocInfo& rInfo ) +void PDFWriterImpl::setupDocInfo() { - m_aDocInfo.Title = rInfo.Title; - m_aDocInfo.Author = rInfo.Author; - m_aDocInfo.Subject = rInfo.Subject; - m_aDocInfo.Keywords = rInfo.Keywords; - m_aDocInfo.Creator = rInfo.Creator; - m_aDocInfo.Producer = rInfo.Producer; + std::vector< sal_uInt8 > aId; + computeDocumentIdentifier( aId, m_aContext.DocumentInfo, m_aCreationDateString, m_aCreationMetaDateString ); + if( m_aContext.Encryption.DocumentIdentifier.empty() ) + m_aContext.Encryption.DocumentIdentifier = aId; +} + +void PDFWriterImpl::computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo, + rtl::OString& o_rCString1, + rtl::OString& o_rCString2 + ) +{ + o_rIdentifier.clear(); -//build the document id + //build the document id rtl::OString aInfoValuesOut; OStringBuffer aID( 1024 ); - if( m_aDocInfo.Title.Len() ) - appendUnicodeTextString( m_aDocInfo.Title, aID ); - if( m_aDocInfo.Author.Len() ) - appendUnicodeTextString( m_aDocInfo.Author, aID ); - if( m_aDocInfo.Subject.Len() ) - appendUnicodeTextString( m_aDocInfo.Subject, aID ); - if( m_aDocInfo.Keywords.Len() ) - appendUnicodeTextString( m_aDocInfo.Keywords, aID ); - if( m_aDocInfo.Creator.Len() ) - appendUnicodeTextString( m_aDocInfo.Creator, aID ); - if( m_aDocInfo.Producer.Len() ) - appendUnicodeTextString( m_aDocInfo.Producer, aID ); + if( i_rDocInfo.Title.Len() ) + appendUnicodeTextString( i_rDocInfo.Title, aID ); + if( i_rDocInfo.Author.Len() ) + appendUnicodeTextString( i_rDocInfo.Author, aID ); + if( i_rDocInfo.Subject.Len() ) + appendUnicodeTextString( i_rDocInfo.Subject, aID ); + if( i_rDocInfo.Keywords.Len() ) + appendUnicodeTextString( i_rDocInfo.Keywords, aID ); + if( i_rDocInfo.Creator.Len() ) + appendUnicodeTextString( i_rDocInfo.Creator, aID ); + if( i_rDocInfo.Producer.Len() ) + appendUnicodeTextString( i_rDocInfo.Producer, aID ); TimeValue aTVal, aGMT; oslDateTime aDT; osl_getSystemTime( &aGMT ); osl_getLocalTimeFromSystemTime( &aGMT, &aTVal ); osl_getDateTimeFromTimeValue( &aTVal, &aDT ); - m_aCreationDateString.append( "D:" ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); -//--> i59651, we fill the Metadata date string as well, if PDF/A is requested - if( m_bIsPDF_A1 ) - { -// according to ISO 19005-1:2005 6.7.3 the date is corrected for -// local time zone offset UTC only, whereas Acrobat 8 seems -// to use the localtime notation only -// according to a raccomandation in XMP Specification (Jan 2004, page 75) -// the Acrobat way seems the right approach - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); - m_aCreationMetaDateString.append( "-" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); - m_aCreationMetaDateString.append( "-" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); - m_aCreationMetaDateString.append( "T" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); - } + rtl::OStringBuffer aCreationDateString(64), aCreationMetaDateString(64); + aCreationDateString.append( "D:" ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); + + //--> i59651, we fill the Metadata date string as well, if PDF/A is requested + // according to ISO 19005-1:2005 6.7.3 the date is corrected for + // local time zone offset UTC only, whereas Acrobat 8 seems + // to use the localtime notation only + // according to a raccomandation in XMP Specification (Jan 2004, page 75) + // the Acrobat way seems the right approach + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); + aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); + aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); + aCreationMetaDateString.append( "T" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); + sal_uInt32 nDelta = 0; if( aGMT.Seconds > aTVal.Seconds ) { - m_aCreationDateString.append( "-" ); + aCreationDateString.append( "-" ); nDelta = aGMT.Seconds-aTVal.Seconds; - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( "-" ); } else if( aGMT.Seconds < aTVal.Seconds ) { - m_aCreationDateString.append( "+" ); + aCreationDateString.append( "+" ); nDelta = aTVal.Seconds-aGMT.Seconds; - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "+" ); + aCreationMetaDateString.append( "+" ); } else { - m_aCreationDateString.append( "Z" ); - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "Z" ); + aCreationDateString.append( "Z" ); + aCreationMetaDateString.append( "Z" ); } if( nDelta ) { - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); - m_aCreationDateString.append( "'" ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); - if( m_bIsPDF_A1 ) - { - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); - } + aCreationDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); + aCreationDateString.append( "'" ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); + + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); } - m_aCreationDateString.append( "'" ); - aID.append( m_aCreationDateString.getStr(), m_aCreationDateString.getLength() ); + aCreationDateString.append( "'" ); + aID.append( aCreationDateString.getStr(), aCreationDateString.getLength() ); aInfoValuesOut = aID.makeStringAndClear(); + o_rCString1 = aCreationDateString.makeStringAndClear(); + o_rCString2 = aCreationMetaDateString.makeStringAndClear(); - DBG_ASSERT( m_aDigest != NULL, "PDFWrite_Impl::setDocInfo: cannot obtain a digest object !" ); - - m_aDocID.setLength( 0 ); - if( m_aDigest ) + rtlDigest aDigest = rtl_digest_createMD5(); + OSL_ENSURE( aDigest != NULL, "PDFWriterImpl::computeDocumentIdentifier: cannot obtain a digest object !" ); + if( aDigest ) { - osl_getSystemTime( &aGMT ); - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, &aGMT, sizeof( aGMT ) ); + rtlDigestError nError = rtl_digest_updateMD5( aDigest, &aGMT, sizeof( aGMT ) ); if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_aContext.URL.getStr(), m_aContext.URL.getLength()*sizeof(sal_Unicode) ); - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, aInfoValuesOut.getStr(), aInfoValuesOut.getLength() ); + nError = rtl_digest_updateMD5( aDigest, aInfoValuesOut.getStr(), aInfoValuesOut.getLength() ); if( nError == rtl_Digest_E_None ) { -//the binary form of the doc id is needed for encryption stuff - rtl_digest_getMD5( m_aDigest, m_nDocID, 16 ); - for( unsigned int i = 0; i < 16; i++ ) - appendHex( m_nDocID[i], m_aDocID ); + o_rIdentifier = std::vector< sal_uInt8 >( 16, 0 ); + //the binary form of the doc id is needed for encryption stuff + rtl_digest_getMD5( aDigest, &o_rIdentifier[0], 16 ); } } } @@ -1956,7 +1974,7 @@ append the string as unicode hex, encrypted if needed inline void PDFWriterImpl::appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, OStringBuffer& rOutBuffer ) { rOutBuffer.append( "<" ); - if( m_aContext.Encrypt ) + if( m_aContext.Encryption.Encrypt() ) { const sal_Unicode* pStr = rInString.getStr(); sal_Int32 nLen = rInString.getLength(); @@ -1993,7 +2011,7 @@ inline void PDFWriterImpl::appendLiteralStringEncrypt( rtl::OStringBuffer& rInSt rOutBuffer.append( "(" ); sal_Int32 nChars = rInString.getLength(); //check for encryption, if ok, encrypt the string, then convert with appndLiteralString - if( m_aContext.Encrypt && checkEncryptionBufferSize( nChars ) ) + if( m_aContext.Encryption.Encrypt() && checkEncryptionBufferSize( nChars ) ) { //encrypt the string in a buffer, then append it enableStringEncryption( nInObjectNumber ); @@ -2380,9 +2398,6 @@ SalLayout* PDFWriterImpl::GetTextLayout( ImplLayoutArgs& rArgs, ImplFontSelectDa sal_Int32 PDFWriterImpl::newPage( sal_Int32 nPageWidth, sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation ) { - if( m_aContext.Encrypt && m_aPages.empty() ) - initEncryption(); - endPage(); m_nCurrentPage = m_aPages.size(); m_aPages.push_back( PDFPage(this, nPageWidth, nPageHeight, eOrientation ) ); @@ -5877,7 +5892,7 @@ bool PDFWriterImpl::emitCatalog() } // viewer preferences, if we had some, then emit if( m_aContext.HideViewerToolbar || - ( m_aContext.Version > PDFWriter::PDF_1_3 && m_aDocInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) || + ( m_aContext.Version > PDFWriter::PDF_1_3 && m_aContext.DocumentInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) || m_aContext.HideViewerMenubar || m_aContext.HideViewerWindowControls || m_aContext.FitWindow || m_aContext.CenterWindow || (m_aContext.FirstPageLeft && m_aContext.PageLayout == PDFWriter::ContinuousFacing ) || @@ -5894,7 +5909,7 @@ bool PDFWriterImpl::emitCatalog() aLine.append( "/FitWindow true\n" ); if( m_aContext.CenterWindow ) aLine.append( "/CenterWindow true\n" ); - if( m_aContext.Version > PDFWriter::PDF_1_3 && m_aDocInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) + if( m_aContext.Version > PDFWriter::PDF_1_3 && m_aContext.DocumentInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) aLine.append( "/DisplayDocTitle true\n" ); if( m_aContext.FirstPageLeft && m_aContext.PageLayout == PDFWriter::ContinuousFacing ) aLine.append( "/Direction/R2L\n" ); @@ -5998,40 +6013,40 @@ sal_Int32 PDFWriterImpl::emitInfoDict( ) aLine.append( nObject ); aLine.append( " 0 obj\n" "<<" ); - if( m_aDocInfo.Title.Len() ) + if( m_aContext.DocumentInfo.Title.Len() ) { aLine.append( "/Title" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Title, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Title, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Author.Len() ) + if( m_aContext.DocumentInfo.Author.Len() ) { aLine.append( "/Author" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Author, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Author, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Subject.Len() ) { aLine.append( "/Subject" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Subject, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Subject, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Keywords.Len() ) { aLine.append( "/Keywords" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Keywords, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Keywords, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Creator.Len() ) + if( m_aContext.DocumentInfo.Creator.Len() ) { aLine.append( "/Creator" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Creator, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Creator, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Producer.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() ) { aLine.append( "/Producer" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Producer, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Producer, nObject, aLine ); aLine.append( "\n" ); } @@ -6277,45 +6292,45 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " A\n" ); aMetadataStream.append( " \n" ); //... Dublin Core properties go here - if( m_aDocInfo.Title.Len() || - m_aDocInfo.Author.Len() || - m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Title.Len() || + m_aContext.DocumentInfo.Author.Len() || + m_aContext.DocumentInfo.Subject.Len() ) { aMetadataStream.append( " \n" ); - if( m_aDocInfo.Title.Len() ) + if( m_aContext.DocumentInfo.Title.Len() ) { // this is according to PDF/A-1, technical corrigendum 1 (2007-04-01) aMetadataStream.append( " \n" ); aMetadataStream.append( " \n" ); aMetadataStream.append( " " ); rtl::OUString aTitle; - escapeStringXML( m_aDocInfo.Title, aTitle ); + escapeStringXML( m_aContext.DocumentInfo.Title, aTitle ); aMetadataStream.append( OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); aMetadataStream.append( " \n" ); aMetadataStream.append( " \n" ); } - if( m_aDocInfo.Author.Len() ) + if( m_aContext.DocumentInfo.Author.Len() ) { aMetadataStream.append( " \n" ); aMetadataStream.append( " \n" ); aMetadataStream.append( " " ); rtl::OUString aAuthor; - escapeStringXML( m_aDocInfo.Author, aAuthor ); + escapeStringXML( m_aContext.DocumentInfo.Author, aAuthor ); aMetadataStream.append( OUStringToOString( aAuthor , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); aMetadataStream.append( " \n" ); aMetadataStream.append( " \n" ); } - if( m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Subject.Len() ) { // this is according to PDF/A-1, technical corrigendum 1 (2007-04-01) aMetadataStream.append( " \n" ); aMetadataStream.append( " \n" ); aMetadataStream.append( " " ); rtl::OUString aSubject; - escapeStringXML( m_aDocInfo.Subject, aSubject ); + escapeStringXML( m_aContext.DocumentInfo.Subject, aSubject ); aMetadataStream.append( OUStringToOString( aSubject , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); aMetadataStream.append( " \n" ); @@ -6325,24 +6340,24 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() } //... PDF properties go here - if( m_aDocInfo.Producer.Len() || - m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() || + m_aContext.DocumentInfo.Keywords.Len() ) { aMetadataStream.append( " \n" ); - if( m_aDocInfo.Producer.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() ) { aMetadataStream.append( " " ); rtl::OUString aProducer; - escapeStringXML( m_aDocInfo.Producer, aProducer ); + escapeStringXML( m_aContext.DocumentInfo.Producer, aProducer ); aMetadataStream.append( OUStringToOString( aProducer , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); } - if( m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Keywords.Len() ) { aMetadataStream.append( " " ); rtl::OUString aKeywords; - escapeStringXML( m_aDocInfo.Keywords, aKeywords ); + escapeStringXML( m_aContext.DocumentInfo.Keywords, aKeywords ); aMetadataStream.append( OUStringToOString( aKeywords , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); } @@ -6351,11 +6366,11 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " \n" ); - if( m_aDocInfo.Creator.Len() ) + if( m_aContext.DocumentInfo.Creator.Len() ) { aMetadataStream.append( " " ); rtl::OUString aCreator; - escapeStringXML( m_aDocInfo.Creator, aCreator ); + escapeStringXML( m_aContext.DocumentInfo.Creator, aCreator ); aMetadataStream.append( OUStringToOString( aCreator , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "\n" ); } @@ -6411,7 +6426,7 @@ bool PDFWriterImpl::emitTrailer() sal_Int32 nSecObject = 0; - if( m_aContext.Encrypt == true ) + if( m_aContext.Encryption.Encrypt() ) { //emit the security information //must be emitted as indirect dictionary object, since @@ -6425,16 +6440,16 @@ bool PDFWriterImpl::emitTrailer() aLineS.append( " 0 obj\n" "<>\nendobj\n\n" ); @@ -6500,13 +6515,21 @@ bool PDFWriterImpl::emitTrailer() aLine.append( nDocInfoObject ); aLine.append( " 0 R\n" ); } - if( m_aDocID.getLength() ) + if( ! m_aContext.Encryption.DocumentIdentifier.empty() ) { aLine.append( "/ID [ <" ); - aLine.append( m_aDocID.getStr(), m_aDocID.getLength() ); + for( std::vector< sal_uInt8 >::const_iterator it = m_aContext.Encryption.DocumentIdentifier.begin(); + it != m_aContext.Encryption.DocumentIdentifier.end(); ++it ) + { + appendHex( sal_Int8(*it), aLine ); + } aLine.append( ">\n" "<" ); - aLine.append( m_aDocID.getStr(), m_aDocID.getLength() ); + for( std::vector< sal_uInt8 >::const_iterator it = m_aContext.Encryption.DocumentIdentifier.begin(); + it != m_aContext.Encryption.DocumentIdentifier.end(); ++it ) + { + appendHex( sal_Int8(*it), aLine ); + } aLine.append( "> ]\n" ); } if( aDocChecksum.getLength() ) @@ -9653,7 +9676,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask ) aLine.append( "[ /Indexed/DeviceRGB " ); aLine.append( (sal_Int32)(pAccess->GetPaletteEntryCount()-1) ); aLine.append( "\n<" ); - if( m_aContext.Encrypt ) + if( m_aContext.Encryption.Encrypt() ) { enableStringEncryption( rObject.m_nObject ); //check encryption buffer size @@ -12039,30 +12062,169 @@ void PDFWriterImpl::addStream( const String& rMimeType, PDFOutputStream* pStream } } + +sal_Bool PDFWriterImpl::checkEncryptionBufferSize( register sal_Int32 newSize ) +{ + if( m_nEncryptionBufferSize < newSize ) + { + /* reallocate the buffer, the used function allocate as rtl_allocateMemory + if the pointer parameter is NULL */ + m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); + if( m_pEncryptionBuffer ) + m_nEncryptionBufferSize = newSize; + else + m_nEncryptionBufferSize = 0; + } + return ( m_nEncryptionBufferSize != 0 ); +} + +void PDFWriterImpl::checkAndEnableStreamEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + m_bEncryptThisStream = true; + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +void PDFWriterImpl::enableStringEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +/* init the encryption engine +1. init the document id, used both for building the document id and for building the encryption key(s) +2. build the encryption key following algorithms described in the PDF specification + */ +bool PDFWriterImpl::initEncryption( vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo + ) +{ + bool bSuccess = false; + rtl::OString aC1, aC2; + computeDocumentIdentifier( io_rProperties.DocumentIdentifier, i_rDocInfo, aC1, aC2 ); + if( i_rOwnerPassword.getLength() || i_rUserPassword.getLength() ) + { + sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; + sal_Int32 nAccessPermissions = computeAccessPermissions( io_rProperties, nKeyLength, nRC4KeyLength ); + // get padded passwords + sal_uInt8 aPadUPW[ENCRYPTED_PWD_SIZE], aPadOPW[ENCRYPTED_PWD_SIZE]; + padPassword( i_rOwnerPassword.getLength() ? i_rOwnerPassword : i_rUserPassword, aPadOPW ); + padPassword( i_rUserPassword, aPadUPW ); + bSuccess = computeODictionaryValue( aPadOPW, aPadUPW, io_rProperties, nKeyLength, nRC4KeyLength ) + && computeUDictionaryValue( aPadOPW, aPadUPW, io_rProperties, nKeyLength, nRC4KeyLength, nAccessPermissions ) + ; + + // trash temporary padded cleartext PWDs + rtl_zeroMemory( aPadOPW, sizeof(aPadOPW) ); + rtl_zeroMemory( aPadUPW, sizeof(aPadUPW) ); + + //clear out exceding key values, prepares for generation number default to 0 as well + // see checkAndEnableStreamEncryption in pdfwriter_impl.hxx + if( bSuccess ) + { + sal_Int32 i, y; + for( i = nKeyLength, y = 0; y < 5 ; y++ ) + io_rProperties.EncryptionKey[i++] = 0; + } + } + else + bSuccess = true; + + if( ! bSuccess ) // something failed, disable encrpytion + { + io_rProperties.OValue.clear(); + io_rProperties.UValue.clear(); + io_rProperties.EncryptionKey.clear(); + } + + return bSuccess; +} + +sal_Int32 PDFWriterImpl::computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, + sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ) +{ + /* + 2) compute the access permissions, in numerical form + + the default value depends on the revision 2 (40 bit) or 3 (128 bit security): + - for 40 bit security the unused bit must be set to 1, since they are not used + - for 128 bit security the same bit must be preset to 0 and set later if needed + according to the table 3.15, pdf v 1.4 */ + sal_Int32 nAccessPermissions = ( i_rProperties.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; + + /* check permissions for 40 bit security case */ + nAccessPermissions |= ( i_rProperties.CanPrintTheDocument ) ? 1 << 2 : 0; + nAccessPermissions |= ( i_rProperties.CanModifyTheContent ) ? 1 << 3 : 0; + nAccessPermissions |= ( i_rProperties.CanCopyOrExtract ) ? 1 << 4 : 0; + nAccessPermissions |= ( i_rProperties.CanAddOrModify ) ? 1 << 5 : 0; + o_rKeyLength = SECUR_40BIT_KEY; + o_rRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 + + if( i_rProperties.Security128bit ) + { + o_rKeyLength = SECUR_128BIT_KEY; + o_rRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum + // permitted value is 16 + nAccessPermissions |= ( i_rProperties.CanFillInteractive ) ? 1 << 8 : 0; + nAccessPermissions |= ( i_rProperties.CanExtractForAccessibility ) ? 1 << 9 : 0; + nAccessPermissions |= ( i_rProperties.CanAssemble ) ? 1 << 10 : 0; + nAccessPermissions |= ( i_rProperties.CanPrintFull ) ? 1 << 11 : 0; + } + return nAccessPermissions; +} + /************************************************************* begin i12626 methods Implements Algorithm 3.2, step 1 only */ -void PDFWriterImpl::padPassword( rtl::OUString aPassword, sal_uInt8 *paPasswordTarget ) +void PDFWriterImpl::padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ) { -// get ansi-1252 version of the password string CHECKIT ! i12626 - rtl::OString aString = rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_MS_1252 ); + // get ansi-1252 version of the password string CHECKIT ! i12626 + rtl::OString aString( rtl::OUStringToOString( i_rPassword, RTL_TEXTENCODING_MS_1252 ) ); -//copy the string to the target - sal_Int32 nToCopy = ( aString.getLength() < 32 ) ? aString.getLength() : 32; + //copy the string to the target + sal_Int32 nToCopy = ( aString.getLength() < ENCRYPTED_PWD_SIZE ) ? aString.getLength() : ENCRYPTED_PWD_SIZE; sal_Int32 nCurrentChar; for( nCurrentChar = 0; nCurrentChar < nToCopy; nCurrentChar++ ) - paPasswordTarget[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); + o_pPaddedPW[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); -//pad it - if( nCurrentChar < 32 ) - {//fill with standard byte string - sal_Int32 i,y; - for( i = nCurrentChar, y = 0 ; i < 32; i++, y++ ) - paPasswordTarget[i] = m_nPadString[y]; - } + //pad it with standard byte string + sal_Int32 i,y; + for( i = nCurrentChar, y = 0 ; i < ENCRYPTED_PWD_SIZE; i++, y++ ) + o_pPaddedPW[i] = s_nPadString[y]; + + // trash memory of temporary clear text password + rtl_zeroMemory( (sal_Char*)aString.getStr(), aString.getLength() ); } /********************************** @@ -12075,91 +12237,126 @@ it will be 16 byte long for 128 bit security; for 40 bit security only the first TODO: in pdf ver 1.5 and 1.6 the step 6 is different, should be implemented. See spec. */ -void PDFWriterImpl::computeEncryptionKey(sal_uInt8 *paThePaddedPassword, sal_uInt8 *paEncryptionKey ) +bool PDFWriterImpl::computeEncryptionKey( const sal_uInt8* i_pOPW, const sal_uInt8* i_pUPW, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ) { -//step 2 - if( m_aDigest ) + bool bSuccess = true; + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + + rtlDigest aDigest = rtl_digest_createMD5(); + if( aDigest ) { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, paThePaddedPassword, ENCRYPTED_PWD_SIZE ); -//step 3 - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nEncryptedOwnerPassword , sizeof( m_nEncryptedOwnerPassword ) ); -//Step 4 + //step 2 + rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pUPW, ENCRYPTED_PWD_SIZE ); + //step 3 + if( nError == rtl_Digest_E_None && ! io_rProperties.OValue.empty() ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.OValue[0] , sal_Int32(io_rProperties.OValue.size()) ); + else + bSuccess = false; + //Step 4 sal_uInt8 nPerm[4]; - nPerm[0] = (sal_uInt8)m_nAccessPermissions; - nPerm[1] = (sal_uInt8)( m_nAccessPermissions >> 8 ); - nPerm[2] = (sal_uInt8)( m_nAccessPermissions >> 16 ); - nPerm[3] = (sal_uInt8)( m_nAccessPermissions >> 24 ); + nPerm[0] = (sal_uInt8)i_nAccessPermissions; + nPerm[1] = (sal_uInt8)( i_nAccessPermissions >> 8 ); + nPerm[2] = (sal_uInt8)( i_nAccessPermissions >> 16 ); + nPerm[3] = (sal_uInt8)( i_nAccessPermissions >> 24 ); if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, nPerm , sizeof( nPerm ) ); + nError = rtl_digest_updateMD5( aDigest, nPerm , sizeof( nPerm ) ); -//step 5, get the document ID, binary form + //step 5, get the document ID, binary form if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nDocID , sizeof( m_nDocID ) ); -//get the digest - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + //get the digest if( nError == rtl_Digest_E_None ) { - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); -//step 6, only if 128 bit - if( m_aContext.Security128bit ) + //step 6, only if 128 bit + if( io_rProperties.Security128bit ) { for( sal_Int32 i = 0; i < 50; i++ ) { - nError = rtl_digest_updateMD5( m_aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); + nError = rtl_digest_updateMD5( aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); if( nError != rtl_Digest_E_None ) + { + bSuccess = false; break; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); } } } -//Step 7 + rtl_digest_destroyMD5( aDigest ); + } + else + bSuccess = false; + + //Step 7 + if( bSuccess ) + { + io_rProperties.EncryptionKey.resize( MAXIMUM_RC4_KEY_LENGTH ); for( sal_Int32 i = 0; i < MD5_DIGEST_SIZE; i++ ) - paEncryptionKey[i] = nMD5Sum[i]; + io_rProperties.EncryptionKey[i] = nMD5Sum[i]; } + else + io_rProperties.EncryptionKey.clear(); + + return bSuccess; } /********************************** Algorithm 3.3 Compute the encryption dictionary /O value, save into the class data member the step numbers down here correspond to the ones in PDF v.1.4 specfication */ -void PDFWriterImpl::computeODictionaryValue() +bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, + const sal_uInt8* i_pPaddedUserPassword, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, + sal_Int32 i_nRC4KeyLength + ) { -//step 1 already done, data is in m_nPaddedOwnerPassword -//step 2 - if( m_aDigest ) + bool bSuccess = true; + + io_rProperties.OValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher) { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, &m_nPaddedOwnerPassword, sizeof( m_nPaddedOwnerPassword ) ); + //step 1 already done, data is in i_pPaddedOwnerPassword + //step 2 + + rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pPaddedOwnerPassword, ENCRYPTED_PWD_SIZE ); if( nError == rtl_Digest_E_None ) { sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof(nMD5Sum) ); + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); //step 3, only if 128 bit - if( m_aContext.Security128bit ) + if( io_rProperties.Security128bit ) { sal_Int32 i; for( i = 0; i < 50; i++ ) { - nError = rtl_digest_updateMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + nError = rtl_digest_updateMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); if( nError != rtl_Digest_E_None ) + { + bSuccess = false; break; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); } } -//Step 4, the key is in nMD5Sum -//step 5 already done, data is in m_nPaddedUserPassword -//step 6 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - nMD5Sum, m_nKeyLength , NULL, 0 ); -// encrypt the user password using the key set above - rtl_cipher_encodeARCFOUR( m_aCipher, m_nPaddedUserPassword, sizeof( m_nPaddedUserPassword ), // the data to be encrypted - m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ) ); //encrypted data, stored in class data member -//Step 7, only if 128 bit - if( m_aContext.Security128bit ) + //Step 4, the key is in nMD5Sum + //step 5 already done, data is in i_pPaddedUserPassword + //step 6 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nMD5Sum, i_nKeyLength , NULL, 0 ); + // encrypt the user password using the key set above + rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted + &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()) ); //encrypted data + //Step 7, only if 128 bit + if( io_rProperties.Security128bit ) { sal_uInt32 i, y; sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key @@ -12169,138 +12366,116 @@ void PDFWriterImpl::computeODictionaryValue() for( y = 0; y < sizeof( nLocalKey ); y++ ) nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i ); - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, nLocalKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( m_aCipher, m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ), // the data to be encrypted - m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ) ); // encrypted data, can be the same as the input, encrypt "in place" -//step 8, store in class data member + rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()), // the data to be encrypted + &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place" + //step 8, store in class data member } } } + else + bSuccess = false; } + else + bSuccess = false; + + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); + + if( ! bSuccess ) + io_rProperties.OValue.clear(); + return bSuccess; } /********************************** Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into the class data member, revision 2 (40 bit) or 3 (128 bit) */ -void PDFWriterImpl::computeUDictionaryValue() +bool PDFWriterImpl::computeUDictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, + const sal_uInt8* i_pPaddedUserPassword, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, + sal_Int32 i_nRC4KeyLength, + sal_Int32 i_nAccessPermissions + ) { -//step 1, common to both 3.4 and 3.5 - computeEncryptionKey( m_nPaddedUserPassword , m_nEncryptionKey ); + bool bSuccess = true; - if( m_aContext.Security128bit == false ) - { -//3.4 -//step 2 and 3 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - m_nEncryptionKey, 5 , // key and key length - NULL, 0 ); //destination data area -// encrypt the user password using the key set above, save for later use - rtl_cipher_encodeARCFOUR( m_aCipher, m_nPadString, sizeof( m_nPadString ), // the data to be encrypted - m_nEncryptedUserPassword, sizeof( m_nEncryptedUserPassword ) ); //encrypted data, stored in class data member - } - else + io_rProperties.UValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher ) { -//or 3.5, for 128 bit security -//step6, initilize the last 16 bytes of the encrypted user password to 0 - for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sizeof( m_nEncryptedUserPassword ); i++) - m_nEncryptedUserPassword[i] = 0; -//step 2 - if( m_aDigest ) + //step 1, common to both 3.4 and 3.5 + if( computeEncryptionKey( i_pPaddedOwnerPassword, i_pPaddedUserPassword, io_rProperties, i_nAccessPermissions ) ) { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, m_nPadString, sizeof( m_nPadString ) ); -//step 3 - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nDocID , sizeof(m_nDocID) ); - - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof(nMD5Sum) ); -//Step 4 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - m_nEncryptionKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area - rtl_cipher_encodeARCFOUR( m_aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted - m_nEncryptedUserPassword, sizeof( nMD5Sum ) ); //encrypted data, stored in class data member -//step 5 - sal_uInt32 i, y; - sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; - - for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + if( io_rProperties.Security128bit == false ) + { + //3.4 + //step 2 and 3 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], 5 , // key and key length + NULL, 0 ); //destination data area + // encrypt the user password using the key set above, save for later use + rtl_cipher_encodeARCFOUR( aCipher, s_nPadString, sizeof( s_nPadString ), // the data to be encrypted + &io_rProperties.UValue[0], sal_Int32(io_rProperties.UValue.size()) ); //encrypted data, stored in class data member + } + else { - for( y = 0; y < sizeof( nLocalKey ) ; y++ ) - nLocalKey[y] = (sal_uInt8)( m_nEncryptionKey[y] ^ i ); - - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - nLocalKey, SECUR_128BIT_KEY, // key and key length - NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( m_aCipher, m_nEncryptedUserPassword, SECUR_128BIT_KEY, // the data to be encrypted - m_nEncryptedUserPassword, SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" + //or 3.5, for 128 bit security + //step6, initilize the last 16 bytes of the encrypted user password to 0 + for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sal_uInt32(io_rProperties.UValue.size()); i++) + io_rProperties.UValue[i] = 0; + //step 2 + rtlDigestError nError = rtl_digest_updateMD5( aDigest, s_nPadString, sizeof( s_nPadString ) ); + //step 3 + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + else + bSuccess = false; + + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); + //Step 4 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], SECUR_128BIT_KEY, NULL, 0 ); //destination data area + rtl_cipher_encodeARCFOUR( aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted + &io_rProperties.UValue[0], sizeof( nMD5Sum ) ); //encrypted data, stored in class data member + //step 5 + sal_uInt32 i, y; + sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; + + for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + { + for( y = 0; y < sizeof( nLocalKey ) ; y++ ) + nLocalKey[y] = (sal_uInt8)( io_rProperties.EncryptionKey[y] ^ i ); + + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nLocalKey, SECUR_128BIT_KEY, // key and key length + NULL, 0 ); //destination data area, on init can be NULL + rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.UValue[0], SECUR_128BIT_KEY, // the data to be encrypted + &io_rProperties.UValue[0], SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" + } } } + else + bSuccess = false; } -} - -/* init the encryption engine -1. init the document id, used both for building the document id and for building the encryption key(s) -2. build the encryption key following algorithms described in the PDF specification - */ -void PDFWriterImpl::initEncryption() -{ - m_aOwnerPassword = m_aContext.OwnerPassword; - m_aUserPassword = m_aContext.UserPassword; -/* password stuff computing, before sending out anything */ - DBG_ASSERT( m_aCipher != NULL, "PDFWriterImpl::initEncryption: a cipher (ARCFOUR) object is not available !" ); - DBG_ASSERT( m_aDigest != NULL, "PDFWriterImpl::initEncryption: a digest (MD5) object is not available !" ); + else + bSuccess = false; - if( m_aCipher && m_aDigest ) - { -//if there is no owner password, force it to the user password - if( m_aOwnerPassword.getLength() == 0 ) - m_aOwnerPassword = m_aUserPassword; + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); - initPadString(); -/* -1) pad passwords -*/ - padPassword( m_aOwnerPassword, m_nPaddedOwnerPassword ); - padPassword( m_aUserPassword, m_nPaddedUserPassword ); -/* -2) compute the access permissions, in numerical form - -the default value depends on the revision 2 (40 bit) or 3 (128 bit security): -- for 40 bit security the unused bit must be set to 1, since they are not used -- for 128 bit security the same bit must be preset to 0 and set later if needed -according to the table 3.15, pdf v 1.4 */ - m_nAccessPermissions = ( m_aContext.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; - -/* check permissions for 40 bit security case */ - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanPrintTheDocument ) ? 1 << 2 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanModifyTheContent ) ? 1 << 3 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanCopyOrExtract ) ? 1 << 4 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanAddOrModify ) ? 1 << 5 : 0; - m_nKeyLength = SECUR_40BIT_KEY; - m_nRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 - - if( m_aContext.Security128bit ) - { - m_nKeyLength = SECUR_128BIT_KEY; - m_nRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum - // permitted value is 16 - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanFillInteractive ) ? 1 << 8 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanExtractForAccessibility ) ? 1 << 9 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanAssemble ) ? 1 << 10 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanPrintFull ) ? 1 << 11 : 0; - } - computeODictionaryValue(); - computeUDictionaryValue(); - -//clear out exceding key values, prepares for generation number default to 0 as well -// see checkAndEnableStreamEncryption in pdfwriter_impl.hxx - sal_Int32 i, y; - for( i = m_nKeyLength, y = 0; y < 5 ; y++ ) - m_nEncryptionKey[i++] = 0; - } - else //either no cipher or no digest or both, something is wrong with memory or something else - m_aContext.Encrypt = false; //then turn the encryption off + if( ! bSuccess ) + io_rProperties.UValue.clear(); + return bSuccess; } + /* end i12626 methods */ diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 2eacdc215dd8..dd75ca4f1a47 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -595,7 +595,6 @@ private: MapMode m_aMapMode; // PDFWriterImpl scaled units std::vector< PDFPage > m_aPages; - PDFDocInfo m_aDocInfo; /* maps object numbers to file offsets (needed for xref) */ std::vector< sal_uInt64 > m_aObjects; /* contains Bitmaps until they are written to the @@ -796,116 +795,37 @@ i12626 /* used to cipher the stream data and for password management */ rtlCipher m_aCipher; rtlDigest m_aDigest; -/* pad string used for password in Standard security handler */ - sal_uInt8 m_nPadString[ENCRYPTED_PWD_SIZE]; -/* the owner password, in clear text */ - rtl::OUString m_aOwnerPassword; -/* the padded owner password */ - sal_uInt8 m_nPaddedOwnerPassword[ENCRYPTED_PWD_SIZE]; -/* the encryption dictionary owner password, according to algorithm 3.3 */ - sal_uInt8 m_nEncryptedOwnerPassword[ENCRYPTED_PWD_SIZE]; -/* the user password, in clear text */ - rtl::OUString m_aUserPassword; -/* the padded user password */ - sal_uInt8 m_nPaddedUserPassword[ENCRYPTED_PWD_SIZE]; -/* the encryption dictionary user password, according to algorithm 3.4 or 3.5 depending on the - security handler revision */ - sal_uInt8 m_nEncryptedUserPassword[ENCRYPTED_PWD_SIZE]; - -/* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2 - for 128 bit security */ - sal_uInt8 m_nEncryptionKey[MAXIMUM_RC4_KEY_LENGTH]; + /* pad string used for password in Standard security handler */ + static const sal_uInt8 s_nPadString[ENCRYPTED_PWD_SIZE]; + + /* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2 + for 128 bit security */ sal_Int32 m_nKeyLength; // key length, 16 or 5 sal_Int32 m_nRC4KeyLength; // key length, 16 or 10, to be input to the algorith 3.1 -/* set to true if the following stream must be encrypted, used inside writeBuffer() */ + /* set to true if the following stream must be encrypted, used inside writeBuffer() */ sal_Bool m_bEncryptThisStream; -/* the numerical value of the access permissions, according to PDF spec, must be signed */ + /* the numerical value of the access permissions, according to PDF spec, must be signed */ sal_Int32 m_nAccessPermissions; -/* the document ID, the raw MD5 hash */ - sal_uInt8 m_nDocID[MD5_DIGEST_SIZE]; -/* string buffer to hold document ID, this is the output string */ - rtl::OStringBuffer m_aDocID; -/* string to hold the PDF creation date */ - rtl::OStringBuffer m_aCreationDateString; -/* string to hold the PDF creation date, for PDF/A metadata */ - rtl::OStringBuffer m_aCreationMetaDateString; -/* the buffer where the data are encrypted, dynamically allocated */ + /* string to hold the PDF creation date */ + rtl::OString m_aCreationDateString; + /* string to hold the PDF creation date, for PDF/A metadata */ + rtl::OString m_aCreationMetaDateString; + /* the buffer where the data are encrypted, dynamically allocated */ sal_uInt8 *m_pEncryptionBuffer; -/* size of the buffer */ + /* size of the buffer */ sal_Int32 m_nEncryptionBufferSize; -/* check and reallocate the buffer for encryption */ - sal_Bool checkEncryptionBufferSize( register sal_Int32 newSize ) - { - if( m_nEncryptionBufferSize < newSize ) - { -/* reallocate the buffer, the used function allocate as rtl_allocateMemory - if the pointer parameter is NULL */ - m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); - if( m_pEncryptionBuffer ) - m_nEncryptionBufferSize = newSize; - else - m_nEncryptionBufferSize = 0; - } - return ( m_nEncryptionBufferSize != 0 ); - } -/* init the internal pad string */ - void initPadString() - { - static const sal_uInt8 nPadString[32] = - { - 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, - 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A - }; - - for(sal_uInt32 i = 0; i < sizeof( nPadString ); i++ ) - m_nPadString[i] = nPadString[i]; - - }; -/* initialize the encryption engine */ - void initEncryption(); - -/* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */ - void checkAndEnableStreamEncryption( register sal_Int32 nObject ) - { - if( m_aContext.Encrypt ) - { - m_bEncryptThisStream = true; - register sal_Int32 i = m_nKeyLength; - m_nEncryptionKey[i++] = (sal_uInt8)nObject; - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); -//the other location of m_nEncryptionKey are already set to 0, our fixed generation number -// do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) ); -// initialize the RC4 with the key -// key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - } - }; + /* check and reallocate the buffer for encryption */ + sal_Bool checkEncryptionBufferSize( register sal_Int32 newSize ); + /* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */ + void checkAndEnableStreamEncryption( register sal_Int32 nObject ); void disableStreamEncryption() { m_bEncryptThisStream = false; }; -/* */ - void enableStringEncryption( register sal_Int32 nObject ) - { - register sal_Int32 i = m_nKeyLength; - m_nEncryptionKey[i++] = (sal_uInt8)nObject; - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); -//the other location of m_nEncryptionKey are already set to 0, our fixed generation number -// do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) ); -// initialize the RC4 with the key -// key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - }; + /* */ + void enableStringEncryption( register sal_Int32 nObject ); // test if the encryption is active, if yes than encrypt the unicode string and add to the OStringBuffer parameter void appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer ); @@ -1096,23 +1016,47 @@ i12626 /* true if PDF/A-1a or PDF/A-1b is output */ sal_Bool m_bIsPDF_A1; -/* -i12626 -methods for PDF security - - pad a password according algorithm 3.2, step 1 */ - void padPassword( const rtl::OUString aPassword, sal_uInt8 *paPasswordTarget ); -/* algorithm 3.2: compute an encryption key */ - void computeEncryptionKey( sal_uInt8 *paThePaddedPassword, sal_uInt8 *paEncryptionKey ); -/* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ - void computeODictionaryValue(); -/* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ - void computeUDictionaryValue(); - + /* + i12626 + methods for PDF security + + pad a password according algorithm 3.2, step 1 */ + static void padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ); + /* algorithm 3.2: compute an encryption key */ + static bool computeEncryptionKey( const sal_uInt8* i_pOPW, const sal_uInt8* i_pUPW, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nAccessPermissions + ); + /* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ + static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength + ); + /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ + static bool computeUDictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength, + sal_Int32 i_nAccessPermissions + ); + + static void computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo, + rtl::OString& o_rCString1, + rtl::OString& o_rCString2 + ); + static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, + sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ); + void setupDocInfo(); public: PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ); ~PDFWriterImpl(); + static bool initEncryption( vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo + ); + /* for OutputDevice so the reference device can have a list * that contains only suitable fonts (subsettable or builtin) * produces a new font list @@ -1144,8 +1088,6 @@ public: } PDFWriter::PDFVersion getVersion() const { return m_aContext.Version; } - void setDocInfo( const PDFDocInfo& rInfo ); - const PDFDocInfo& getDocInfo() const { return m_aDocInfo; } void setDocumentLocale( const com::sun::star::lang::Locale& rLoc ) { m_aContext.DocumentLocale = rLoc; } -- cgit v1.2.3 From 208de777d5af30720ba212a233283ba4c1ac57cb Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Mon, 27 Sep 2010 19:58:20 +0200 Subject: limit password life time --- vcl/inc/vcl/pdfwriter.hxx | 17 +- vcl/source/gdi/makefile.mk | 1 + vcl/source/gdi/pdfwriter.cxx | 16 +- vcl/source/gdi/pdfwriter_impl.cxx | 425 +------------------------------------- vcl/source/gdi/pdfwriter_impl.hxx | 19 +- 5 files changed, 36 insertions(+), 442 deletions(-) (limited to 'vcl') diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx index cbb9c7c2fe93..204ddaa9e33c 100644 --- a/vcl/inc/vcl/pdfwriter.hxx +++ b/vcl/inc/vcl/pdfwriter.hxx @@ -38,7 +38,8 @@ #include #include -#include +#include "com/sun/star/io/XOutputStream.hpp" +#include "com/sun/star/beans/XMaterialHolder.hpp" #include #include @@ -498,7 +499,7 @@ The following structure describes the permissions used in PDF security // EncryptionKey is actually a construct out of OValue, UValue and DocumentIdentifier // if these do not match, behavior is undefined, most likely an invalid PDF will be produced // OValue, UValue, EncryptionKey and DocumentIdentifier can be computed from - // PDFDocInfo, Owner password and User password usend the InitEncryption method which + // PDFDocInfo, Owner password and User password used the InitEncryption method which // implements the algorithms described in the PDF reference chapter 3.5: Encryption std::vector OValue; std::vector UValue; @@ -623,7 +624,7 @@ The following structure describes the permissions used in PDF security {} }; - PDFWriter( const PDFWriterContext& rContext ); + PDFWriter( const PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); ~PDFWriter(); /** Returns an OutputDevice for formatting @@ -666,11 +667,11 @@ The following structure describes the permissions used in PDF security PDFVersion GetVersion() const; - static bool InitEncryption( PDFWriter::PDFEncryptionProperties& io_rProperties, - const rtl::OUString& i_rOwnerPassword, - const rtl::OUString& i_rUserPassword, - const PDFWriter::PDFDocInfo& i_rDocInfo - ); + static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > + InitEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ); /* functions for graphics state */ /* flag values: see vcl/outdev.hxx */ diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index 77df20976c73..ac2e586a41cb 100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -63,6 +63,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/impgraph.obj \ $(SLO)$/metric.obj \ $(SLO)$/pdfwriter_impl.obj \ + $(SLO)$/pdfwriter_impl2.obj \ $(SLO)$/pdffontcache.obj\ $(SLO)$/bmpconv.obj \ $(SLO)$/pdfextoutdevdata.obj \ diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 3b5e70d938a8..98627b448aed 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -38,9 +38,9 @@ PDFWriter::AnyWidget::~AnyWidget() { } -PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext ) +PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& xEnc ) : - pImplementation( new PDFWriterImpl( rContext ) ) + pImplementation( new PDFWriterImpl( rContext, xEnc ) ) { } @@ -560,12 +560,12 @@ std::set< PDFWriter::ErrorCode > PDFWriter::GetErrors() return ((PDFWriterImpl*)pImplementation)->getErrors(); } -bool PDFWriter::InitEncryption( PDFWriter::PDFEncryptionProperties& io_rProperties, - const rtl::OUString& i_rOwnerPassword, - const rtl::OUString& i_rUserPassword, - const PDFWriter::PDFDocInfo& i_rDocInfo - ) +com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > +PDFWriter::InitEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ) { - return PDFWriterImpl::initEncryption( io_rProperties, i_rOwnerPassword, i_rUserPassword, i_rDocInfo ); + return PDFWriterImpl::initEncryption( i_rOwnerPassword, i_rUserPassword, b128Bit ); } diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index ff415ccfa98c..1e39f0e46260 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -1697,7 +1697,8 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal * class PDFWriterImpl */ -PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) + PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, + const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& xEnc ) : m_pReferenceDevice( NULL ), m_aMapMode( MAP_POINT, Point(), Fraction( 1L, pointToPixel(1) ), Fraction( 1L, pointToPixel(1) ) ), @@ -1759,14 +1760,19 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_bOpen = true; - /* prepare the cypher engine, can be done in CTOR, free in DTOR */ + // setup DocInfo + setupDocInfo(); + /* prepare the cypher engine, can be done in CTOR, free in DTOR */ m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); m_aDigest = rtl_digest_createMD5(); /* the size of the Codec default maximum */ checkEncryptionBufferSize( 0x4000 ); + if( xEnc.is() ) + prepareEncryption( xEnc ); + if( m_aContext.Encryption.Encrypt() ) { // sanity check @@ -12063,419 +12069,4 @@ void PDFWriterImpl::addStream( const String& rMimeType, PDFOutputStream* pStream } -sal_Bool PDFWriterImpl::checkEncryptionBufferSize( register sal_Int32 newSize ) -{ - if( m_nEncryptionBufferSize < newSize ) - { - /* reallocate the buffer, the used function allocate as rtl_allocateMemory - if the pointer parameter is NULL */ - m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); - if( m_pEncryptionBuffer ) - m_nEncryptionBufferSize = newSize; - else - m_nEncryptionBufferSize = 0; - } - return ( m_nEncryptionBufferSize != 0 ); -} - -void PDFWriterImpl::checkAndEnableStreamEncryption( register sal_Int32 nObject ) -{ - if( m_aContext.Encryption.Encrypt() ) - { - m_bEncryptThisStream = true; - sal_Int32 i = m_nKeyLength; - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); - //the other location of m_nEncryptionKey are already set to 0, our fixed generation number - // do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); - // initialize the RC4 with the key - // key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - } -} - -void PDFWriterImpl::enableStringEncryption( register sal_Int32 nObject ) -{ - if( m_aContext.Encryption.Encrypt() ) - { - sal_Int32 i = m_nKeyLength; - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); - //the other location of m_nEncryptionKey are already set to 0, our fixed generation number - // do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); - // initialize the RC4 with the key - // key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - } -} - -/* init the encryption engine -1. init the document id, used both for building the document id and for building the encryption key(s) -2. build the encryption key following algorithms described in the PDF specification - */ -bool PDFWriterImpl::initEncryption( vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, - const rtl::OUString& i_rOwnerPassword, - const rtl::OUString& i_rUserPassword, - const vcl::PDFWriter::PDFDocInfo& i_rDocInfo - ) -{ - bool bSuccess = false; - rtl::OString aC1, aC2; - computeDocumentIdentifier( io_rProperties.DocumentIdentifier, i_rDocInfo, aC1, aC2 ); - if( i_rOwnerPassword.getLength() || i_rUserPassword.getLength() ) - { - sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; - sal_Int32 nAccessPermissions = computeAccessPermissions( io_rProperties, nKeyLength, nRC4KeyLength ); - // get padded passwords - sal_uInt8 aPadUPW[ENCRYPTED_PWD_SIZE], aPadOPW[ENCRYPTED_PWD_SIZE]; - padPassword( i_rOwnerPassword.getLength() ? i_rOwnerPassword : i_rUserPassword, aPadOPW ); - padPassword( i_rUserPassword, aPadUPW ); - bSuccess = computeODictionaryValue( aPadOPW, aPadUPW, io_rProperties, nKeyLength, nRC4KeyLength ) - && computeUDictionaryValue( aPadOPW, aPadUPW, io_rProperties, nKeyLength, nRC4KeyLength, nAccessPermissions ) - ; - - // trash temporary padded cleartext PWDs - rtl_zeroMemory( aPadOPW, sizeof(aPadOPW) ); - rtl_zeroMemory( aPadUPW, sizeof(aPadUPW) ); - - //clear out exceding key values, prepares for generation number default to 0 as well - // see checkAndEnableStreamEncryption in pdfwriter_impl.hxx - if( bSuccess ) - { - sal_Int32 i, y; - for( i = nKeyLength, y = 0; y < 5 ; y++ ) - io_rProperties.EncryptionKey[i++] = 0; - } - } - else - bSuccess = true; - - if( ! bSuccess ) // something failed, disable encrpytion - { - io_rProperties.OValue.clear(); - io_rProperties.UValue.clear(); - io_rProperties.EncryptionKey.clear(); - } - - return bSuccess; -} - -sal_Int32 PDFWriterImpl::computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, - sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ) -{ - /* - 2) compute the access permissions, in numerical form - - the default value depends on the revision 2 (40 bit) or 3 (128 bit security): - - for 40 bit security the unused bit must be set to 1, since they are not used - - for 128 bit security the same bit must be preset to 0 and set later if needed - according to the table 3.15, pdf v 1.4 */ - sal_Int32 nAccessPermissions = ( i_rProperties.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; - - /* check permissions for 40 bit security case */ - nAccessPermissions |= ( i_rProperties.CanPrintTheDocument ) ? 1 << 2 : 0; - nAccessPermissions |= ( i_rProperties.CanModifyTheContent ) ? 1 << 3 : 0; - nAccessPermissions |= ( i_rProperties.CanCopyOrExtract ) ? 1 << 4 : 0; - nAccessPermissions |= ( i_rProperties.CanAddOrModify ) ? 1 << 5 : 0; - o_rKeyLength = SECUR_40BIT_KEY; - o_rRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 - - if( i_rProperties.Security128bit ) - { - o_rKeyLength = SECUR_128BIT_KEY; - o_rRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum - // permitted value is 16 - nAccessPermissions |= ( i_rProperties.CanFillInteractive ) ? 1 << 8 : 0; - nAccessPermissions |= ( i_rProperties.CanExtractForAccessibility ) ? 1 << 9 : 0; - nAccessPermissions |= ( i_rProperties.CanAssemble ) ? 1 << 10 : 0; - nAccessPermissions |= ( i_rProperties.CanPrintFull ) ? 1 << 11 : 0; - } - return nAccessPermissions; -} - -/************************************************************* -begin i12626 methods - -Implements Algorithm 3.2, step 1 only -*/ -void PDFWriterImpl::padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ) -{ - // get ansi-1252 version of the password string CHECKIT ! i12626 - rtl::OString aString( rtl::OUStringToOString( i_rPassword, RTL_TEXTENCODING_MS_1252 ) ); - - //copy the string to the target - sal_Int32 nToCopy = ( aString.getLength() < ENCRYPTED_PWD_SIZE ) ? aString.getLength() : ENCRYPTED_PWD_SIZE; - sal_Int32 nCurrentChar; - - for( nCurrentChar = 0; nCurrentChar < nToCopy; nCurrentChar++ ) - o_pPaddedPW[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); - - //pad it with standard byte string - sal_Int32 i,y; - for( i = nCurrentChar, y = 0 ; i < ENCRYPTED_PWD_SIZE; i++, y++ ) - o_pPaddedPW[i] = s_nPadString[y]; - - // trash memory of temporary clear text password - rtl_zeroMemory( (sal_Char*)aString.getStr(), aString.getLength() ); -} - -/********************************** -Algorithm 3.2 Compute the encryption key used - -step 1 should already be done before calling, the paThePaddedPassword parameter should contain -the padded password and must be 32 byte long, the encryption key is returned into the paEncryptionKey parameter, -it will be 16 byte long for 128 bit security; for 40 bit security only the first 5 bytes are used - -TODO: in pdf ver 1.5 and 1.6 the step 6 is different, should be implemented. See spec. - -*/ -bool PDFWriterImpl::computeEncryptionKey( const sal_uInt8* i_pOPW, const sal_uInt8* i_pUPW, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ) -{ - bool bSuccess = true; - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - - rtlDigest aDigest = rtl_digest_createMD5(); - if( aDigest ) - { - //step 2 - rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pUPW, ENCRYPTED_PWD_SIZE ); - //step 3 - if( nError == rtl_Digest_E_None && ! io_rProperties.OValue.empty() ) - nError = rtl_digest_updateMD5( aDigest, &io_rProperties.OValue[0] , sal_Int32(io_rProperties.OValue.size()) ); - else - bSuccess = false; - //Step 4 - sal_uInt8 nPerm[4]; - - nPerm[0] = (sal_uInt8)i_nAccessPermissions; - nPerm[1] = (sal_uInt8)( i_nAccessPermissions >> 8 ); - nPerm[2] = (sal_uInt8)( i_nAccessPermissions >> 16 ); - nPerm[3] = (sal_uInt8)( i_nAccessPermissions >> 24 ); - - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( aDigest, nPerm , sizeof( nPerm ) ); - - //step 5, get the document ID, binary form - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); - //get the digest - if( nError == rtl_Digest_E_None ) - { - rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - - //step 6, only if 128 bit - if( io_rProperties.Security128bit ) - { - for( sal_Int32 i = 0; i < 50; i++ ) - { - nError = rtl_digest_updateMD5( aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); - if( nError != rtl_Digest_E_None ) - { - bSuccess = false; - break; - } - rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - } - } - } - rtl_digest_destroyMD5( aDigest ); - } - else - bSuccess = false; - - //Step 7 - if( bSuccess ) - { - io_rProperties.EncryptionKey.resize( MAXIMUM_RC4_KEY_LENGTH ); - for( sal_Int32 i = 0; i < MD5_DIGEST_SIZE; i++ ) - io_rProperties.EncryptionKey[i] = nMD5Sum[i]; - } - else - io_rProperties.EncryptionKey.clear(); - - return bSuccess; -} - -/********************************** -Algorithm 3.3 Compute the encryption dictionary /O value, save into the class data member -the step numbers down here correspond to the ones in PDF v.1.4 specfication -*/ -bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, - const sal_uInt8* i_pPaddedUserPassword, - vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, - sal_Int32 i_nKeyLength, - sal_Int32 i_nRC4KeyLength - ) -{ - bool bSuccess = true; - - io_rProperties.OValue.resize( ENCRYPTED_PWD_SIZE ); - - rtlDigest aDigest = rtl_digest_createMD5(); - rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); - if( aDigest && aCipher) - { - //step 1 already done, data is in i_pPaddedOwnerPassword - //step 2 - - rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pPaddedOwnerPassword, ENCRYPTED_PWD_SIZE ); - if( nError == rtl_Digest_E_None ) - { - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - - rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); -//step 3, only if 128 bit - if( io_rProperties.Security128bit ) - { - sal_Int32 i; - for( i = 0; i < 50; i++ ) - { - nError = rtl_digest_updateMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - if( nError != rtl_Digest_E_None ) - { - bSuccess = false; - break; - } - rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - } - } - //Step 4, the key is in nMD5Sum - //step 5 already done, data is in i_pPaddedUserPassword - //step 6 - rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, - nMD5Sum, i_nKeyLength , NULL, 0 ); - // encrypt the user password using the key set above - rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted - &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()) ); //encrypted data - //Step 7, only if 128 bit - if( io_rProperties.Security128bit ) - { - sal_uInt32 i, y; - sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key - - for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 - { - for( y = 0; y < sizeof( nLocalKey ); y++ ) - nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i ); - - rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, - nLocalKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()), // the data to be encrypted - &io_rProperties.OValue[0], sal_Int32(io_rProperties.OValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place" - //step 8, store in class data member - } - } - } - else - bSuccess = false; - } - else - bSuccess = false; - - if( aDigest ) - rtl_digest_destroyMD5( aDigest ); - if( aCipher ) - rtl_cipher_destroyARCFOUR( aCipher ); - - if( ! bSuccess ) - io_rProperties.OValue.clear(); - return bSuccess; -} - -/********************************** -Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into the class data member, revision 2 (40 bit) or 3 (128 bit) -*/ -bool PDFWriterImpl::computeUDictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, - const sal_uInt8* i_pPaddedUserPassword, - vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, - sal_Int32 i_nKeyLength, - sal_Int32 i_nRC4KeyLength, - sal_Int32 i_nAccessPermissions - ) -{ - bool bSuccess = true; - - io_rProperties.UValue.resize( ENCRYPTED_PWD_SIZE ); - - rtlDigest aDigest = rtl_digest_createMD5(); - rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); - if( aDigest && aCipher ) - { - //step 1, common to both 3.4 and 3.5 - if( computeEncryptionKey( i_pPaddedOwnerPassword, i_pPaddedUserPassword, io_rProperties, i_nAccessPermissions ) ) - { - if( io_rProperties.Security128bit == false ) - { - //3.4 - //step 2 and 3 - rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, - &io_rProperties.EncryptionKey[0], 5 , // key and key length - NULL, 0 ); //destination data area - // encrypt the user password using the key set above, save for later use - rtl_cipher_encodeARCFOUR( aCipher, s_nPadString, sizeof( s_nPadString ), // the data to be encrypted - &io_rProperties.UValue[0], sal_Int32(io_rProperties.UValue.size()) ); //encrypted data, stored in class data member - } - else - { - //or 3.5, for 128 bit security - //step6, initilize the last 16 bytes of the encrypted user password to 0 - for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sal_uInt32(io_rProperties.UValue.size()); i++) - io_rProperties.UValue[i] = 0; - //step 2 - rtlDigestError nError = rtl_digest_updateMD5( aDigest, s_nPadString, sizeof( s_nPadString ) ); - //step 3 - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); - else - bSuccess = false; - - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); - //Step 4 - rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, - &io_rProperties.EncryptionKey[0], SECUR_128BIT_KEY, NULL, 0 ); //destination data area - rtl_cipher_encodeARCFOUR( aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted - &io_rProperties.UValue[0], sizeof( nMD5Sum ) ); //encrypted data, stored in class data member - //step 5 - sal_uInt32 i, y; - sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; - - for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 - { - for( y = 0; y < sizeof( nLocalKey ) ; y++ ) - nLocalKey[y] = (sal_uInt8)( io_rProperties.EncryptionKey[y] ^ i ); - - rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, - nLocalKey, SECUR_128BIT_KEY, // key and key length - NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.UValue[0], SECUR_128BIT_KEY, // the data to be encrypted - &io_rProperties.UValue[0], SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" - } - } - } - else - bSuccess = false; - } - else - bSuccess = false; - - if( aDigest ) - rtl_digest_destroyMD5( aDigest ); - if( aCipher ) - rtl_cipher_destroyARCFOUR( aCipher ); - - if( ! bSuccess ) - io_rProperties.UValue.clear(); - return bSuccess; -} - -/* end i12626 methods */ diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index dd75ca4f1a47..9006a104b576 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -58,6 +58,7 @@ class ImplFontSelectData; class ImplFontMetricData; class FontSubsetInfo; class ZCodec; +class EncHashTransporter; // the maximum password length #define ENCRYPTED_PWD_SIZE 32 @@ -1023,17 +1024,17 @@ i12626 pad a password according algorithm 3.2, step 1 */ static void padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ); /* algorithm 3.2: compute an encryption key */ - static bool computeEncryptionKey( const sal_uInt8* i_pOPW, const sal_uInt8* i_pUPW, + static bool computeEncryptionKey( EncHashTransporter*, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ); /* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, - vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + std::vector< sal_uInt8 >& io_rOValue, sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength ); /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ - static bool computeUDictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, + static bool computeUDictionaryValue( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength, sal_Int32 i_nAccessPermissions @@ -1047,15 +1048,15 @@ i12626 static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ); void setupDocInfo(); + bool prepareEncryption( const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); public: - PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ); + PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); ~PDFWriterImpl(); - static bool initEncryption( vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, - const rtl::OUString& i_rOwnerPassword, - const rtl::OUString& i_rUserPassword, - const vcl::PDFWriter::PDFDocInfo& i_rDocInfo - ); + static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > + initEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit ); /* for OutputDevice so the reference device can have a list * that contains only suitable fonts (subsettable or builtin) -- cgit v1.2.3 From 40d960cbdba0dbd445d624f62a523b7e78d5f5c9 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Tue, 28 Sep 2010 16:18:13 +0200 Subject: divide pdfwriter_impl.cxx --- vcl/source/gdi/pdfwriter_impl2.cxx | 544 +++++++++++++++++++++++++++++++++++++ 1 file changed, 544 insertions(+) create mode 100644 vcl/source/gdi/pdfwriter_impl2.cxx (limited to 'vcl') diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx new file mode 100644 index 000000000000..c7996e3935b8 --- /dev/null +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -0,0 +1,544 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "pdfwriter_impl.hxx" + +#include "cppuhelper/implbase1.hxx" + +#include + +using namespace vcl; +using namespace rtl; +using namespace com::sun::star; + +/* a crutch to transport an rtlDigest safely though UNO API + this is needed for the PDF export dialog, which otherwise would have to pass + clear text passwords down till they can be used in PDFWriter. Unfortunately + the MD5 sum of the password (which is needed to create the PDF encryption key) + is not sufficient, since an rtl MD5 digest cannot be created in an arbitrary state + which would be needed in PDFWriterImpl::computeEncryptionKey. +*/ +class EncHashTransporter : public cppu::WeakImplHelper1 < com::sun::star::beans::XMaterialHolder > +{ + rtlDigest maUDigest; + sal_IntPtr maID; + std::vector< sal_uInt8 > maOValue; + + static std::map< sal_IntPtr, EncHashTransporter* > sTransporters; +public: + EncHashTransporter() + : maUDigest( rtl_digest_createMD5() ) + { + maID = reinterpret_cast< sal_IntPtr >(this); + while( sTransporters.find( maID ) != sTransporters.end() ) // paranoia mode + maID++; + sTransporters[ maID ] = this; + } + + virtual ~EncHashTransporter() + { + sTransporters.erase( maID ); + if( maUDigest ) + rtl_digest_destroyMD5( maUDigest ); + OSL_TRACE( "EncHashTransporter freed\n" ); + } + + rtlDigest getUDigest() const { return maUDigest; }; + std::vector< sal_uInt8 >& getOValue() { return maOValue; } + void invalidate() + { + if( maUDigest ) + { + rtl_digest_destroyMD5( maUDigest ); + maUDigest = NULL; + } + } + + // XMaterialHolder + virtual uno::Any SAL_CALL getMaterial() throw() + { + return uno::makeAny( sal_Int64(maID) ); + } + + static EncHashTransporter* getEncHashTransporter( const uno::Reference< beans::XMaterialHolder >& ); + +}; + +std::map< sal_IntPtr, EncHashTransporter* > EncHashTransporter::sTransporters; + +EncHashTransporter* EncHashTransporter::getEncHashTransporter( const uno::Reference< beans::XMaterialHolder >& xRef ) +{ + EncHashTransporter* pResult = NULL; + if( xRef.is() ) + { + uno::Any aMat( xRef->getMaterial() ); + sal_Int64 nMat = 0; + if( aMat >>= nMat ) + { + std::map< sal_IntPtr, EncHashTransporter* >::iterator it = sTransporters.find( static_cast(nMat) ); + if( it != sTransporters.end() ) + pResult = it->second; + } + } + return pResult; +} + +sal_Bool PDFWriterImpl::checkEncryptionBufferSize( register sal_Int32 newSize ) +{ + if( m_nEncryptionBufferSize < newSize ) + { + /* reallocate the buffer, the used function allocate as rtl_allocateMemory + if the pointer parameter is NULL */ + m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); + if( m_pEncryptionBuffer ) + m_nEncryptionBufferSize = newSize; + else + m_nEncryptionBufferSize = 0; + } + return ( m_nEncryptionBufferSize != 0 ); +} + +void PDFWriterImpl::checkAndEnableStreamEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + m_bEncryptThisStream = true; + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +void PDFWriterImpl::enableStringEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +/* init the encryption engine +1. init the document id, used both for building the document id and for building the encryption key(s) +2. build the encryption key following algorithms described in the PDF specification + */ +uno::Reference< beans::XMaterialHolder > PDFWriterImpl::initEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ) +{ + uno::Reference< beans::XMaterialHolder > xResult; + if( i_rOwnerPassword.getLength() || i_rUserPassword.getLength() ) + { + EncHashTransporter* pTransporter = new EncHashTransporter; + xResult = pTransporter; + + // get padded passwords + sal_uInt8 aPadUPW[ENCRYPTED_PWD_SIZE], aPadOPW[ENCRYPTED_PWD_SIZE]; + padPassword( i_rOwnerPassword.getLength() ? i_rOwnerPassword : i_rUserPassword, aPadOPW ); + padPassword( i_rUserPassword, aPadUPW ); + sal_Int32 nKeyLength = SECUR_40BIT_KEY, nRC4KeyLength = SECUR_40BIT_KEY+5; + if( b128Bit ) + { + nKeyLength = SECUR_128BIT_KEY; + nRC4KeyLength = 16; + } + + if( computeODictionaryValue( aPadOPW, aPadUPW, pTransporter->getOValue(), nKeyLength, nRC4KeyLength ) ) + { + rtlDigest aDig = pTransporter->getUDigest(); + if( rtl_digest_updateMD5( aDig, aPadUPW, ENCRYPTED_PWD_SIZE ) != rtl_Digest_E_None ) + xResult.clear(); + } + else + xResult.clear(); + + // trash temporary padded cleartext PWDs + rtl_zeroMemory( aPadOPW, sizeof(aPadOPW) ); + rtl_zeroMemory( aPadUPW, sizeof(aPadUPW) ); + + } + return xResult; +} + +bool PDFWriterImpl::prepareEncryption( const uno::Reference< beans::XMaterialHolder >& xEnc ) +{ + bool bSuccess = false; + EncHashTransporter* pTransporter = EncHashTransporter::getEncHashTransporter( xEnc ); + if( pTransporter ) + { + sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; + sal_Int32 nAccessPermissions = computeAccessPermissions( m_aContext.Encryption, nKeyLength, nRC4KeyLength ); + m_aContext.Encryption.OValue = pTransporter->getOValue(); + bSuccess = computeUDictionaryValue( pTransporter, m_aContext.Encryption, nKeyLength, nRC4KeyLength, nAccessPermissions ); + } + if( ! bSuccess ) + { + m_aContext.Encryption.OValue.clear(); + m_aContext.Encryption.UValue.clear(); + m_aContext.Encryption.EncryptionKey.clear(); + } + return bSuccess; +} + +sal_Int32 PDFWriterImpl::computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, + sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ) +{ + /* + 2) compute the access permissions, in numerical form + + the default value depends on the revision 2 (40 bit) or 3 (128 bit security): + - for 40 bit security the unused bit must be set to 1, since they are not used + - for 128 bit security the same bit must be preset to 0 and set later if needed + according to the table 3.15, pdf v 1.4 */ + sal_Int32 nAccessPermissions = ( i_rProperties.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; + + /* check permissions for 40 bit security case */ + nAccessPermissions |= ( i_rProperties.CanPrintTheDocument ) ? 1 << 2 : 0; + nAccessPermissions |= ( i_rProperties.CanModifyTheContent ) ? 1 << 3 : 0; + nAccessPermissions |= ( i_rProperties.CanCopyOrExtract ) ? 1 << 4 : 0; + nAccessPermissions |= ( i_rProperties.CanAddOrModify ) ? 1 << 5 : 0; + o_rKeyLength = SECUR_40BIT_KEY; + o_rRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 + + if( i_rProperties.Security128bit ) + { + o_rKeyLength = SECUR_128BIT_KEY; + o_rRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum + // permitted value is 16 + nAccessPermissions |= ( i_rProperties.CanFillInteractive ) ? 1 << 8 : 0; + nAccessPermissions |= ( i_rProperties.CanExtractForAccessibility ) ? 1 << 9 : 0; + nAccessPermissions |= ( i_rProperties.CanAssemble ) ? 1 << 10 : 0; + nAccessPermissions |= ( i_rProperties.CanPrintFull ) ? 1 << 11 : 0; + } + return nAccessPermissions; +} + +/************************************************************* +begin i12626 methods + +Implements Algorithm 3.2, step 1 only +*/ +void PDFWriterImpl::padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ) +{ + // get ansi-1252 version of the password string CHECKIT ! i12626 + rtl::OString aString( rtl::OUStringToOString( i_rPassword, RTL_TEXTENCODING_MS_1252 ) ); + + //copy the string to the target + sal_Int32 nToCopy = ( aString.getLength() < ENCRYPTED_PWD_SIZE ) ? aString.getLength() : ENCRYPTED_PWD_SIZE; + sal_Int32 nCurrentChar; + + for( nCurrentChar = 0; nCurrentChar < nToCopy; nCurrentChar++ ) + o_pPaddedPW[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); + + //pad it with standard byte string + sal_Int32 i,y; + for( i = nCurrentChar, y = 0 ; i < ENCRYPTED_PWD_SIZE; i++, y++ ) + o_pPaddedPW[i] = s_nPadString[y]; + + // trash memory of temporary clear text password + rtl_zeroMemory( (sal_Char*)aString.getStr(), aString.getLength() ); +} + +/********************************** +Algorithm 3.2 Compute the encryption key used + +step 1 should already be done before calling, the paThePaddedPassword parameter should contain +the padded password and must be 32 byte long, the encryption key is returned into the paEncryptionKey parameter, +it will be 16 byte long for 128 bit security; for 40 bit security only the first 5 bytes are used + +TODO: in pdf ver 1.5 and 1.6 the step 6 is different, should be implemented. See spec. + +*/ +bool PDFWriterImpl::computeEncryptionKey( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ) +{ + bool bSuccess = true; + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + + // transporter contains an MD5 digest with the padded user password already + rtlDigest aDigest = i_pTransporter->getUDigest(); + rtlDigestError nError = rtl_Digest_E_None; + if( aDigest ) + { + //step 3 + if( ! io_rProperties.OValue.empty() ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.OValue[0] , sal_Int32(io_rProperties.OValue.size()) ); + else + bSuccess = false; + //Step 4 + sal_uInt8 nPerm[4]; + + nPerm[0] = (sal_uInt8)i_nAccessPermissions; + nPerm[1] = (sal_uInt8)( i_nAccessPermissions >> 8 ); + nPerm[2] = (sal_uInt8)( i_nAccessPermissions >> 16 ); + nPerm[3] = (sal_uInt8)( i_nAccessPermissions >> 24 ); + + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, nPerm , sizeof( nPerm ) ); + + //step 5, get the document ID, binary form + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + //get the digest + if( nError == rtl_Digest_E_None ) + { + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + + //step 6, only if 128 bit + if( io_rProperties.Security128bit ) + { + for( sal_Int32 i = 0; i < 50; i++ ) + { + nError = rtl_digest_updateMD5( aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); + if( nError != rtl_Digest_E_None ) + { + bSuccess = false; + break; + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + } + } + } + else + bSuccess = false; + + i_pTransporter->invalidate(); + + //Step 7 + if( bSuccess ) + { + io_rProperties.EncryptionKey.resize( MAXIMUM_RC4_KEY_LENGTH ); + for( sal_Int32 i = 0; i < MD5_DIGEST_SIZE; i++ ) + io_rProperties.EncryptionKey[i] = nMD5Sum[i]; + } + else + io_rProperties.EncryptionKey.clear(); + + return bSuccess; +} + +/********************************** +Algorithm 3.3 Compute the encryption dictionary /O value, save into the class data member +the step numbers down here correspond to the ones in PDF v.1.4 specfication +*/ +bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, + const sal_uInt8* i_pPaddedUserPassword, + std::vector< sal_uInt8 >& io_rOValue, + sal_Int32 i_nKeyLength, + sal_Int32 i_nRC4KeyLength + ) +{ + bool bSuccess = true; + + io_rOValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher) + { + //step 1 already done, data is in i_pPaddedOwnerPassword + //step 2 + + rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pPaddedOwnerPassword, ENCRYPTED_PWD_SIZE ); + if( nError == rtl_Digest_E_None ) + { + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); +//step 3, only if 128 bit + if( i_nKeyLength == SECUR_128BIT_KEY ) + { + sal_Int32 i; + for( i = 0; i < 50; i++ ) + { + nError = rtl_digest_updateMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + if( nError != rtl_Digest_E_None ) + { + bSuccess = false; + break; + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + } + //Step 4, the key is in nMD5Sum + //step 5 already done, data is in i_pPaddedUserPassword + //step 6 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nMD5Sum, i_nKeyLength , NULL, 0 ); + // encrypt the user password using the key set above + rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted + &io_rOValue[0], sal_Int32(io_rOValue.size()) ); //encrypted data + //Step 7, only if 128 bit + if( i_nKeyLength == SECUR_128BIT_KEY ) + { + sal_uInt32 i, y; + sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key + + for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + { + for( y = 0; y < sizeof( nLocalKey ); y++ ) + nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i ); + + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nLocalKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area, on init can be NULL + rtl_cipher_encodeARCFOUR( aCipher, &io_rOValue[0], sal_Int32(io_rOValue.size()), // the data to be encrypted + &io_rOValue[0], sal_Int32(io_rOValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place" + //step 8, store in class data member + } + } + } + else + bSuccess = false; + } + else + bSuccess = false; + + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); + + if( ! bSuccess ) + io_rOValue.clear(); + return bSuccess; +} + +/********************************** +Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into the class data member, revision 2 (40 bit) or 3 (128 bit) +*/ +bool PDFWriterImpl::computeUDictionaryValue( EncHashTransporter* i_pTransporter, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, + sal_Int32 i_nRC4KeyLength, + sal_Int32 i_nAccessPermissions + ) +{ + bool bSuccess = true; + + io_rProperties.UValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher ) + { + //step 1, common to both 3.4 and 3.5 + if( computeEncryptionKey( i_pTransporter, io_rProperties, i_nAccessPermissions ) ) + { + // prepare encryption key for object + for( sal_Int32 i = i_nKeyLength, y = 0; y < 5 ; y++ ) + io_rProperties.EncryptionKey[i++] = 0; + + if( io_rProperties.Security128bit == false ) + { + //3.4 + //step 2 and 3 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], 5 , // key and key length + NULL, 0 ); //destination data area + // encrypt the user password using the key set above, save for later use + rtl_cipher_encodeARCFOUR( aCipher, s_nPadString, sizeof( s_nPadString ), // the data to be encrypted + &io_rProperties.UValue[0], sal_Int32(io_rProperties.UValue.size()) ); //encrypted data, stored in class data member + } + else + { + //or 3.5, for 128 bit security + //step6, initilize the last 16 bytes of the encrypted user password to 0 + for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sal_uInt32(io_rProperties.UValue.size()); i++) + io_rProperties.UValue[i] = 0; + //step 2 + rtlDigestError nError = rtl_digest_updateMD5( aDigest, s_nPadString, sizeof( s_nPadString ) ); + //step 3 + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + else + bSuccess = false; + + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); + //Step 4 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], SECUR_128BIT_KEY, NULL, 0 ); //destination data area + rtl_cipher_encodeARCFOUR( aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted + &io_rProperties.UValue[0], sizeof( nMD5Sum ) ); //encrypted data, stored in class data member + //step 5 + sal_uInt32 i, y; + sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; + + for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + { + for( y = 0; y < sizeof( nLocalKey ) ; y++ ) + nLocalKey[y] = (sal_uInt8)( io_rProperties.EncryptionKey[y] ^ i ); + + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nLocalKey, SECUR_128BIT_KEY, // key and key length + NULL, 0 ); //destination data area, on init can be NULL + rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.UValue[0], SECUR_128BIT_KEY, // the data to be encrypted + &io_rProperties.UValue[0], SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" + } + } + } + else + bSuccess = false; + } + else + bSuccess = false; + + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); + + if( ! bSuccess ) + io_rProperties.UValue.clear(); + return bSuccess; +} + +/* end i12626 methods */ + -- cgit v1.2.3 From ffa480fecf420f2a667538950defa87b2e562185 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Tue, 28 Sep 2010 18:39:54 +0200 Subject: remove warning --- vcl/source/gdi/pdfwriter_impl.hxx | 4 ++-- vcl/source/gdi/pdfwriter_impl2.cxx | 13 ++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'vcl') diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 9006a104b576..212a45c77033 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -1031,12 +1031,12 @@ i12626 /* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, std::vector< sal_uInt8 >& io_rOValue, - sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength + sal_Int32 i_nKeyLength ); /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ static bool computeUDictionaryValue( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, - sal_Int32 i_nKeyLength, sal_Int32 i_nRC4KeyLength, + sal_Int32 i_nKeyLength, sal_Int32 i_nAccessPermissions ); diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index c7996e3935b8..c0e9d905db3b 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -183,14 +183,11 @@ uno::Reference< beans::XMaterialHolder > PDFWriterImpl::initEncryption( const rt sal_uInt8 aPadUPW[ENCRYPTED_PWD_SIZE], aPadOPW[ENCRYPTED_PWD_SIZE]; padPassword( i_rOwnerPassword.getLength() ? i_rOwnerPassword : i_rUserPassword, aPadOPW ); padPassword( i_rUserPassword, aPadUPW ); - sal_Int32 nKeyLength = SECUR_40BIT_KEY, nRC4KeyLength = SECUR_40BIT_KEY+5; + sal_Int32 nKeyLength = SECUR_40BIT_KEY; if( b128Bit ) - { nKeyLength = SECUR_128BIT_KEY; - nRC4KeyLength = 16; - } - if( computeODictionaryValue( aPadOPW, aPadUPW, pTransporter->getOValue(), nKeyLength, nRC4KeyLength ) ) + if( computeODictionaryValue( aPadOPW, aPadUPW, pTransporter->getOValue(), nKeyLength ) ) { rtlDigest aDig = pTransporter->getUDigest(); if( rtl_digest_updateMD5( aDig, aPadUPW, ENCRYPTED_PWD_SIZE ) != rtl_Digest_E_None ) @@ -216,7 +213,7 @@ bool PDFWriterImpl::prepareEncryption( const uno::Reference< beans::XMaterialHol sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; sal_Int32 nAccessPermissions = computeAccessPermissions( m_aContext.Encryption, nKeyLength, nRC4KeyLength ); m_aContext.Encryption.OValue = pTransporter->getOValue(); - bSuccess = computeUDictionaryValue( pTransporter, m_aContext.Encryption, nKeyLength, nRC4KeyLength, nAccessPermissions ); + bSuccess = computeUDictionaryValue( pTransporter, m_aContext.Encryption, nKeyLength, nAccessPermissions ); } if( ! bSuccess ) { @@ -371,8 +368,7 @@ the step numbers down here correspond to the ones in PDF v.1.4 specfication bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, std::vector< sal_uInt8 >& io_rOValue, - sal_Int32 i_nKeyLength, - sal_Int32 i_nRC4KeyLength + sal_Int32 i_nKeyLength ) { bool bSuccess = true; @@ -456,7 +452,6 @@ Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into th bool PDFWriterImpl::computeUDictionaryValue( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nKeyLength, - sal_Int32 i_nRC4KeyLength, sal_Int32 i_nAccessPermissions ) { -- cgit v1.2.3 From ed7ea296b2f7338477806e25666a1f85e8e8ace2 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Tue, 28 Sep 2010 19:34:49 +0200 Subject: fix a warning --- vcl/source/window/wpropset.cxx | 1 + 1 file changed, 1 insertion(+) (limited to 'vcl') diff --git a/vcl/source/window/wpropset.cxx b/vcl/source/window/wpropset.cxx index 98c8a5b1dcfb..4aaa3f987b77 100644 --- a/vcl/source/window/wpropset.cxx +++ b/vcl/source/window/wpropset.cxx @@ -73,6 +73,7 @@ public: { } + using cppu::WeakComponentImplHelperBase::disposing; virtual void SAL_CALL disposing( const lang::EventObject& ) throw() { } -- cgit v1.2.3 From 9c90c77200562328c226f35cb14ee6ae9a135b71 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Wed, 29 Sep 2010 14:35:52 +0200 Subject: fix a warning --- vcl/inc/vcl/window.hxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 vcl/inc/vcl/window.hxx (limited to 'vcl') diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx old mode 100644 new mode 100755 index d3f2ec901cf4..be783f5457c4 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -97,7 +97,7 @@ namespace com { namespace sun { namespace star { namespace beans { - class PropertyValue; + struct PropertyValue; }}}} namespace com { -- cgit v1.2.3 From 056f830614e0642c8abc0cd036fdd7d0c4ca9770 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Thu, 21 Oct 2010 18:21:46 +0200 Subject: fix a merge conflict --- vcl/source/gdi/pdfwriter.cxx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'vcl') diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 2d9412cc93b4..23ce1dfa6169 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -560,23 +560,17 @@ std::set< PDFWriter::ErrorCode > PDFWriter::GetErrors() return ((PDFWriterImpl*)pImplementation)->getErrors(); } -<<<<<<< local com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > PDFWriter::InitEncryption( const rtl::OUString& i_rOwnerPassword, const rtl::OUString& i_rUserPassword, bool b128Bit ) -======= -void PDFWriter::PlayMetafile( const GDIMetaFile& i_rMTF, const vcl::PDFWriter::PlayMetafileContext& i_rPlayContext, PDFExtOutDevData* i_pData ) ->>>>>>> other { -<<<<<<< local return PDFWriterImpl::initEncryption( i_rOwnerPassword, i_rUserPassword, b128Bit ); -======= +} + +void PDFWriter::PlayMetafile( const GDIMetaFile& i_rMTF, const vcl::PDFWriter::PlayMetafileContext& i_rPlayContext, PDFExtOutDevData* i_pData ) +{ ((PDFWriterImpl*)pImplementation)->playMetafile( i_rMTF, i_pData, i_rPlayContext, NULL); ->>>>>>> other } -<<<<<<< local -======= ->>>>>>> other -- cgit v1.2.3 From 955e88c80e9abce3f15aa55d434dae6ae17d7d43 Mon Sep 17 00:00:00 2001 From: sb Date: Fri, 22 Oct 2010 10:37:46 +0200 Subject: sb131: #i115124# $(XSLTPROC) implies LIBXSLT:libxslt --- canvas/prj/build.lst | 2 +- comphelper/prj/build.lst | 2 +- dtrans/prj/build.lst | 2 +- i18npool/prj/build.lst | 2 +- sax/prj/build.lst | 2 +- sot/prj/build.lst | 2 +- svl/prj/build.lst | 2 +- svtools/prj/build.lst | 2 +- toolkit/prj/build.lst | 2 +- unotools/prj/build.lst | 2 +- vcl/prj/build.lst | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) (limited to 'vcl') diff --git a/canvas/prj/build.lst b/canvas/prj/build.lst index cacbdb5bb894..2adfe155e0b1 100644 --- a/canvas/prj/build.lst +++ b/canvas/prj/build.lst @@ -1,4 +1,4 @@ -cv canvas : javaunohelper comphelper cppuhelper offuh unoil tools svtools vcl AGG:agg basegfx CAIRO:cairo NULL +cv canvas : javaunohelper comphelper cppuhelper offuh unoil tools svtools vcl AGG:agg basegfx CAIRO:cairo LIBXSLT:libxslt NULL cv canvas usr1 - all cv_mkout NULL cv canvas\inc nmake - all cv_inc NULL cv canvas\source\tools nmake - all cv_tools cv_inc NULL diff --git a/comphelper/prj/build.lst b/comphelper/prj/build.lst index 793d8bf30e09..91e836cabd68 100644 --- a/comphelper/prj/build.lst +++ b/comphelper/prj/build.lst @@ -1,4 +1,4 @@ -ph comphelper : cppuhelper ucbhelper offuh vos salhelper NULL +ph comphelper : cppuhelper ucbhelper offuh vos salhelper LIBXSLT:libxslt NULL ph comphelper usr1 - all ph_mkout NULL ph comphelper\inc nmake - all ph_inc NULL ph comphelper\source\container nmake - all ph_container ph_inc NULL diff --git a/dtrans/prj/build.lst b/dtrans/prj/build.lst index bd9c73582361..e30eccd59d7e 100644 --- a/dtrans/prj/build.lst +++ b/dtrans/prj/build.lst @@ -1,4 +1,4 @@ -dr dtrans : unotools offapi offuh rdbmaker vos stoc NULL +dr dtrans : unotools offapi offuh rdbmaker vos stoc LIBXSLT:libxslt NULL dr dtrans usr1 - all dr_mkout NULL dr dtrans\inc nmake - all dr_inc NULL dr dtrans\source\cnttype nmake - all dr_cnttype dr_generic dr_inc NULL diff --git a/i18npool/prj/build.lst b/i18npool/prj/build.lst index 24e9607596ac..22609becbe86 100644 --- a/i18npool/prj/build.lst +++ b/i18npool/prj/build.lst @@ -1,4 +1,4 @@ -inp i18npool : bridges sax stoc comphelper ICU:icu i18nutil regexp NULL +inp i18npool : bridges sax stoc comphelper ICU:icu i18nutil regexp LIBXSLT:libxslt NULL inp i18npool usr1 - all inp_mkout NULL inp i18npool\inc nmake - all inp_inc NULL inp i18npool\source\registerservices nmake - all inp_rserv inp_inc NULL diff --git a/sax/prj/build.lst b/sax/prj/build.lst index 653d77ce9e25..849700087ae7 100644 --- a/sax/prj/build.lst +++ b/sax/prj/build.lst @@ -1,4 +1,4 @@ -ax sax : offapi cppuhelper EXPAT:expat comphelper NULL +ax sax : offapi cppuhelper EXPAT:expat comphelper LIBXSLT:libxslt NULL ax sax usr1 - all ax_mkout NULL ax sax\source\expatwrap nmake - all ax_expatwrap NULL ax sax\source\tools nmake - all ax_tools NULL diff --git a/sot/prj/build.lst b/sot/prj/build.lst index a5ebff311e9c..9d6e785898a5 100644 --- a/sot/prj/build.lst +++ b/sot/prj/build.lst @@ -1,4 +1,4 @@ -to sot : tools ucbhelper unotools NULL +to sot : LIBXSLT:libxslt tools ucbhelper unotools NULL to sot usr1 - all sot_mkout NULL to sot\inc nmake - all sot_inc NULL to sot\prj get - all sot_prj NULL diff --git a/svl/prj/build.lst b/svl/prj/build.lst index d5897d9e9883..6761837fa8f3 100644 --- a/svl/prj/build.lst +++ b/svl/prj/build.lst @@ -1,4 +1,4 @@ -sl svl : l10n rsc offuh ucbhelper unotools cppu cppuhelper comphelper sal sot NULL +sl svl : l10n rsc offuh ucbhelper unotools cppu cppuhelper comphelper sal sot LIBXSLT:libxslt NULL sl svl usr1 - all svl_mkout NULL sl svl\inc nmake - all svl_inc NULL sl svl\unx\source\svdde nmake - u svl_usdde svl_inc NULL diff --git a/svtools/prj/build.lst b/svtools/prj/build.lst index a7d8569de301..a48983013d73 100644 --- a/svtools/prj/build.lst +++ b/svtools/prj/build.lst @@ -1,4 +1,4 @@ -st svtools : l10n svl offuh toolkit ucbhelper unotools JPEG:jpeg cppu cppuhelper comphelper sal sot jvmfwk NULL +st svtools : l10n svl offuh toolkit ucbhelper unotools JPEG:jpeg cppu cppuhelper comphelper sal sot jvmfwk LIBXSLT:libxslt NULL st svtools usr1 - all st_mkout NULL st svtools\inc nmake - all st_inc NULL st svtools\bmpmaker nmake - all st_bmp st_inc NULL diff --git a/toolkit/prj/build.lst b/toolkit/prj/build.lst index f4854de8e0c4..36ece64d544a 100644 --- a/toolkit/prj/build.lst +++ b/toolkit/prj/build.lst @@ -1,4 +1,4 @@ -ti toolkit : vcl NULL +ti toolkit : LIBXSLT:libxslt vcl NULL ti toolkit usr1 - all ti_mkout NULL ti toolkit\prj get - all ti_prj NULL ti toolkit\inc nmake - all ti_inc NULL diff --git a/unotools/prj/build.lst b/unotools/prj/build.lst index 70402fb3dbd5..d6f10335c254 100644 --- a/unotools/prj/build.lst +++ b/unotools/prj/build.lst @@ -1,4 +1,4 @@ -ut unotools : comphelper cppuhelper offuh tools ucbhelper NULL +ut unotools : LIBXSLT:libxslt comphelper cppuhelper offuh tools ucbhelper NULL ut unotools usr1 - all ut_mkout NULL ut unotools\inc nmake - all ut_inc NULL ut unotools\source\misc nmake - all ut_misc ut_config ut_inc NULL diff --git a/vcl/prj/build.lst b/vcl/prj/build.lst index 0a6f6a95f605..af15ad73e19d 100644 --- a/vcl/prj/build.lst +++ b/vcl/prj/build.lst @@ -1,4 +1,4 @@ -vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools l10ntools icc SO:print_header cpputools shell svl NULL +vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools l10ntools icc SO:print_header cpputools shell svl LIBXSLT:libxslt NULL vc vcl usr1 - all vc_mkout NULL vc vcl\inc nmake - all vc_inc NULL vc vcl\source\glyphs nmake - all vc_glyphs vc_inc NULL -- cgit v1.2.3 From 91e34e4ccc6c61d0b64d250817af7f0d2263b89e Mon Sep 17 00:00:00 2001 From: Mathias Bauer Date: Fri, 29 Oct 2010 15:36:30 +0200 Subject: CWS gnumake2: resolve conflicts and make sources buildable on Linux --- rsc/source/parser/rscdb.cxx | 5 +- rsc/source/rsc/rsc.cxx | 12 +-- svl/Library_svl.mk | 2 - svl/Package_inc.mk | 1 - svl/prj/build.lst | 2 +- svl/source/misc/lngmisc.cxx | 6 -- svtools/AllLangResTarget_svt.mk | 4 - svtools/Library_svt.mk | 7 +- svtools/inc/svtools/svtdata.hxx | 16 ---- svtools/source/dialogs/printdlg.cxx | 4 - toolkit/Library_tk.mk | 1 + toolkit/prj/build.lst | 18 +--- tools/Package_inc.mk | 6 -- tools/inc/bootstrp/prj.hxx | 184 ------------------------------------ tools/prj/d.lst | 99 ------------------- vcl/prj/d.lst | 4 +- 16 files changed, 7 insertions(+), 364 deletions(-) (limited to 'vcl') diff --git a/rsc/source/parser/rscdb.cxx b/rsc/source/parser/rscdb.cxx index a8a9bff6aee2..af176fe24934 100644 --- a/rsc/source/parser/rscdb.cxx +++ b/rsc/source/parser/rscdb.cxx @@ -126,11 +126,7 @@ static sal_uInt32 getLangIdAndShortenLocale( RscTypCont* pTypCont, else rLang = rtl::OString(); #if OSL_DEBUG_LEVEL > 1 -<<<<<<< local - fprintf( stderr, " %s (0x%" SAL_PRIxUINT32 ")", aL.getStr(), nRet ); -======= fprintf( stderr, " %s (0x%hx)", aL.getStr(), (int)nRet ); ->>>>>>> other #endif return nRet; } @@ -1117,3 +1113,4 @@ sal_uInt32 RscTypCont::PutTranslatorKey( sal_uInt64 nKey ) aIdTranslator[ nKey ] = nFilePos; return nPMId++; } + diff --git a/rsc/source/rsc/rsc.cxx b/rsc/source/rsc/rsc.cxx index 25677c982c23..54073563403d 100644 --- a/rsc/source/rsc/rsc.cxx +++ b/rsc/source/rsc/rsc.cxx @@ -474,23 +474,12 @@ ERRTYPE RscCompiler::Start() ByteString* pString; RscFile* pFName; -<<<<<<< local - if( PRINTSYNTAX_FLAG & pCL->nCommands ) - { -#ifndef W30 - pTC->WriteSyntax( stdout ); -printf( "khg\n" ); -#endif - return ERR_OK; - } -======= if( PRINTSYNTAX_FLAG & pCL->nCommands ) { pTC->WriteSyntax( stdout ); printf( "khg\n" ); return ERR_OK; } ->>>>>>> other // Kein Parameter, dann Hilfe pString = pCL->aInputList.First(); @@ -1378,3 +1367,4 @@ void RscCompiler::PreprocessSrsFile( const RscCmdLine::OutputFile& rOutputFile, if( pSysListFile ) fclose( pSysListFile ); } + diff --git a/svl/Library_svl.mk b/svl/Library_svl.mk index bfa5cfaa96ee..e872c1cfec5b 100644 --- a/svl/Library_svl.mk +++ b/svl/Library_svl.mk @@ -80,7 +80,6 @@ $(eval $(call gb_Library_add_exception_objects,svl,\ svl/source/config/itemholder2 \ svl/source/config/languageoptions \ svl/source/config/srchcfg \ - svl/source/filepicker/pickerhelper \ svl/source/filepicker/pickerhistory \ svl/source/filerec/filerec \ svl/source/items/aeitem \ @@ -144,7 +143,6 @@ $(eval $(call gb_Library_add_exception_objects,svl,\ svl/source/notify/listeneriter \ svl/source/notify/lstner \ svl/source/notify/smplhint \ - svl/source/numbers/nbdll \ svl/source/numbers/numfmuno \ svl/source/numbers/numhead \ svl/source/numbers/numuno \ diff --git a/svl/Package_inc.mk b/svl/Package_inc.mk index e0f4b1835f95..e2f8473d46aa 100644 --- a/svl/Package_inc.mk +++ b/svl/Package_inc.mk @@ -109,7 +109,6 @@ $(eval $(call gb_Package_add_file,svl_inc,inc/svl/memberid.hrc,svl/memberid.hrc) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/nfsymbol.hxx,svl/nfsymbol.hxx)) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/numuno.hxx,svl/numuno.hxx)) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/outstrm.hxx,svl/outstrm.hxx)) -$(eval $(call gb_Package_add_file,svl_inc,inc/svl/pickerhelper.hxx,svl/pickerhelper.hxx)) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/pickerhistory.hxx,svl/pickerhistory.hxx)) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/pickerhistoryaccess.hxx,svl/pickerhistoryaccess.hxx)) $(eval $(call gb_Package_add_file,svl_inc,inc/svl/poolcach.hxx,svl/poolcach.hxx)) diff --git a/svl/prj/build.lst b/svl/prj/build.lst index 54eb363e906d..10b9cfe432f2 100644 --- a/svl/prj/build.lst +++ b/svl/prj/build.lst @@ -5,5 +5,5 @@ sl svl\prj nmake - all svl_prj NULL # complex test for ConfigItems are marked as defect # sl svl\qa\complex\ConfigItems\helper nmake - all svl_qa_complex_help svl_util svl_passcont NULL # sl svl\qa\complex\ConfigItems nmake - all svl_qa_complex svl_qa_complex_help svl_util svl_passcont NULL -sl svl\qa\complex\passwordcontainer nmake - all svl_qa_complex svl_util svl_passcont NULL +sl svl\qa\complex\passwordcontainer nmake - all svl_qa_complex svl_prj NULL diff --git a/svl/source/misc/lngmisc.cxx b/svl/source/misc/lngmisc.cxx index c0866b21e785..1324a8fa842c 100644 --- a/svl/source/misc/lngmisc.cxx +++ b/svl/source/misc/lngmisc.cxx @@ -27,19 +27,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svl.hxx" -<<<<<<< local #include -======= - -#include ->>>>>>> other #include #include #include #include #include - using namespace rtl; namespace linguistic diff --git a/svtools/AllLangResTarget_svt.mk b/svtools/AllLangResTarget_svt.mk index c198601f3ca7..3574b2e6c9ec 100644 --- a/svtools/AllLangResTarget_svt.mk +++ b/svtools/AllLangResTarget_svt.mk @@ -61,10 +61,6 @@ $(eval $(call gb_SrsTarget_add_files,svt/res,\ svtools/source/dialogs/prnsetup.src \ svtools/source/dialogs/so3res.src \ svtools/source/dialogs/wizardmachine.src \ - svtools/source/filter.vcl/filter/dlgejpg.src \ - svtools/source/filter.vcl/filter/dlgepng.src \ - svtools/source/filter.vcl/filter/dlgexpor.src \ - svtools/source/filter.vcl/filter/strings.src \ svtools/source/java/javaerror.src \ svtools/source/misc/ehdl.src \ svtools/source/misc/helpagent.src \ diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk index f8415a98b922..8fb07c2d8f49 100644 --- a/svtools/Library_svt.mk +++ b/svtools/Library_svt.mk @@ -105,7 +105,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/config/optionsdrawinglayer \ svtools/source/config/printoptions \ svtools/source/contnr/contentenumeration \ - svtools/source/contnr/ctrdll \ svtools/source/contnr/fileview \ svtools/source/contnr/imivctl1 \ svtools/source/contnr/imivctl2 \ @@ -124,7 +123,6 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/control/calendar \ svtools/source/control/collatorres \ svtools/source/control/ctrlbox \ - svtools/source/control/ctrldll \ svtools/source/control/ctrltool \ svtools/source/control/filectrl \ svtools/source/control/filectrl2 \ @@ -178,15 +176,12 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/edit/textwindowpeer \ svtools/source/edit/txtattr \ svtools/source/edit/xtextedt \ + svtools/source/filter.vcl/filter/exportdialog \ svtools/source/filter.vcl/filter/FilterConfigCache \ svtools/source/filter.vcl/filter/FilterConfigItem \ svtools/source/filter.vcl/filter/SvFilterOptionsDialog \ - svtools/source/filter.vcl/filter/dlgejpg \ - svtools/source/filter.vcl/filter/dlgepng \ - svtools/source/filter.vcl/filter/dlgexpor \ svtools/source/filter.vcl/filter/filter \ svtools/source/filter.vcl/filter/filter2 \ - svtools/source/filter.vcl/filter/fldll \ svtools/source/filter.vcl/filter/sgfbram \ svtools/source/filter.vcl/filter/sgvmain \ svtools/source/filter.vcl/filter/sgvspln \ diff --git a/svtools/inc/svtools/svtdata.hxx b/svtools/inc/svtools/svtdata.hxx index 91a50a15c666..ad7b60b3f2b7 100644 --- a/svtools/inc/svtools/svtdata.hxx +++ b/svtools/inc/svtools/svtdata.hxx @@ -57,23 +57,7 @@ public: }; //============================================================================ -<<<<<<< local - -class SvpResId: public ResId -{ -public: - SvpResId( USHORT nId, const ::com::sun::star::lang::Locale aLocale ): - ResId( nId, *ImpSvtData::GetSvtData().GetResMgr( aLocale ) ) {} - - // VCL dependant, only available in SVT, not in SVL! - SvpResId( USHORT nId ); -}; - - class SVT_DLLPUBLIC SvtResId: public ResId -======= -class SvtResId: public ResId ->>>>>>> other { public: SvtResId(USHORT nId, const ::com::sun::star::lang::Locale aLocale); diff --git a/svtools/source/dialogs/printdlg.cxx b/svtools/source/dialogs/printdlg.cxx index 779ff1da903b..ab8b69fdcda1 100644 --- a/svtools/source/dialogs/printdlg.cxx +++ b/svtools/source/dialogs/printdlg.cxx @@ -38,12 +38,8 @@ #include #include #include -<<<<<<< local #include #include "svl/pickerhelper.hxx" -======= -#include ->>>>>>> other #include #include #include diff --git a/toolkit/Library_tk.mk b/toolkit/Library_tk.mk index 60d13418fa5b..7fe38ac64dc7 100644 --- a/toolkit/Library_tk.mk +++ b/toolkit/Library_tk.mk @@ -84,6 +84,7 @@ $(eval $(call gb_Library_add_exception_objects,tk,\ toolkit/source/awt/vclxwindow \ toolkit/source/awt/vclxwindow1 \ toolkit/source/awt/vclxwindows \ + toolkit/source/awt/stylesettings \ toolkit/source/awt/xsimpleanimation \ toolkit/source/awt/xthrobber \ toolkit/source/controls/accessiblecontrolcontext \ diff --git a/toolkit/prj/build.lst b/toolkit/prj/build.lst index e1e9b370628f..7abd412d1103 100644 --- a/toolkit/prj/build.lst +++ b/toolkit/prj/build.lst @@ -1,28 +1,12 @@ -<<<<<<< local ti toolkit : vcl NULL ti toolkit usr1 - all ti_mkout NULL ti toolkit\prj nmake - all ti_prj NULL -======= -ti toolkit : vcl NULL -ti toolkit usr1 - all ti_mkout NULL -ti toolkit\prj get - all ti_prj NULL -ti toolkit\inc nmake - all ti_inc NULL -ti toolkit\uiconfig\layout nmake - all ti_uiconfig_layout NULL -ti toolkit\source\helper nmake - all ti_helper ti_inc NULL -ti toolkit\source\awt nmake - all ti_awt ti_inc NULL -ti toolkit\source\controls nmake - all ti_controls ti_inc NULL -ti toolkit\source\controls\tree nmake - all ti_tree NULL -ti toolkit\source\controls\grid nmake - all ti_grid NULL -ti toolkit\source\layout\core nmake - all ti_layout_core NULL -ti toolkit\source\layout\vcl nmake - all ti_layout_vcl NULL -ti toolkit\util nmake - all ti_util ti_awt ti_controls ti_layout_core ti_helper ti_tree ti_grid ti_layout_vcl NULL ti toolkit\qa\unoapi nmake - all ti_qa_unoapi NULL - # fail on unxsoli4 #ti toolkit\qa\complex\xunitconversion nmake - all ti_complex_conv ti_util NULL # fails # ti toolkit\qa\complex\toolkit nmake - all ti_complex_ti ti_qa_complex_toolkit_interface_tests ti_util NULL ->>>>>>> other + diff --git a/tools/Package_inc.mk b/tools/Package_inc.mk index 5deb59a7b0da..27088fd06a48 100644 --- a/tools/Package_inc.mk +++ b/tools/Package_inc.mk @@ -27,12 +27,9 @@ $(eval $(call gb_Package_Package,tools_inc,$(SRCDIR)/tools/inc)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/StringListResource.hxx,tools/StringListResource.hxx)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/agapi.hxx,tools/agapi.hxx)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/agitem.hxx,tools/agitem.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/appendunixshellword.hxx,tools/appendunixshellword.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/bigint.hxx,tools/bigint.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/cachestr.hxx,tools/cachestr.hxx)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/chapi.hxx,tools/chapi.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/color.hxx,tools/color.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/config.hxx,tools/config.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/contnr.hxx,tools/contnr.hxx)) @@ -40,9 +37,7 @@ $(eval $(call gb_Package_add_file,tools_inc,inc/tools/date.hxx,tools/date.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/datetime.hxx,tools/datetime.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/debug.hxx,tools/debug.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/diagnose_ex.h,tools/diagnose_ex.h)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/download.hxx,tools/download.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/dynary.hxx,tools/dynary.hxx)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/eacopier.hxx,tools/eacopier.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/errcode.hxx,tools/errcode.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/errinf.hxx,tools/errinf.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/extendapplicationenvironment.hxx,tools/extendapplicationenvironment.hxx)) @@ -103,7 +98,6 @@ $(eval $(call gb_Package_add_file,tools_inc,inc/tools/tools.h,tools/tools.h)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/toolsdllapi.h,tools/toolsdllapi.h)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/unqid.hxx,tools/unqid.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/unqidx.hxx,tools/unqidx.hxx)) -$(eval $(call gb_Package_add_file,tools_inc,inc/tools/urlkeys.hxx,tools/urlkeys.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/urlobj.hxx,tools/urlobj.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/vcompat.hxx,tools/vcompat.hxx)) $(eval $(call gb_Package_add_file,tools_inc,inc/tools/vector2d.hxx,tools/vector2d.hxx)) diff --git a/tools/inc/bootstrp/prj.hxx b/tools/inc/bootstrp/prj.hxx index a6ef7338472b..4b1ff91feb7b 100644 --- a/tools/inc/bootstrp/prj.hxx +++ b/tools/inc/bootstrp/prj.hxx @@ -55,188 +55,4 @@ public: ByteString GetCleanedNextLine( BOOL bReadComments = FALSE ); }; -<<<<<<< local -======= -#define ENV_GUI 0x00000000 -#define ENV_OS 0x00000001 -#define ENV_UPD 0x00000002 -#define ENV_UPDMIN 0x00000004 -#define ENV_INPATH 0x00000008 -#define ENV_OUTPATH 0x00000010 -#define ENV_GUIBASE 0x00000020 -#define ENV_CVER 0x00000040 -#define ENV_GVER 0x00000080 -#define ENV_GUIENV 0x00000100 -#define ENV_CPU 0x00000200 -#define ENV_CPUNAME 0x00000400 -#define ENV_DLLSUFF 0x00000800 -#define ENV_COMEX 0x00001000 -#define ENV_COMPATH 0x00002000 -#define ENV_INCLUDE 0x00004000 -#define ENV_LIB 0x00008000 -#define ENV_PATH 0x00010000 -#define ENV_SOLVER 0x00020000 -#define ENV_SOLENV 0x00040000 -#define ENV_SOLROOT 0x00080000 -#define ENV_DEVROOT 0x00100000 -#define ENV_EMERG 0x00200000 -#define ENV_STAND 0x00400000 - -/********************************************************************* -* -* class Prj -* alle Daten eines Projektes werden hier gehalten -* -*********************************************************************/ - -DECL_DEST_LIST ( PrjList_tmp, PrjList, CommandData * ) - -class Star; -class Prj : public PrjList -{ -friend class Star; -private: - BOOL bVisited; - - ByteString aPrjPath; - ByteString aProjectName; - ByteString aProjectPrefix; // max. 2-buchstabige Abk. - SByteStringList* pPrjInitialDepList; - SByteStringList* pPrjDepList; - BOOL bHardDependencies; - BOOL bSorted; - -public: - Prj(); - Prj( ByteString aName ); - ~Prj(); - void SetPreFix( ByteString aPre ){aProjectPrefix = aPre;} - ByteString GetPreFix(){return aProjectPrefix;} - ByteString GetProjectName() - {return aProjectName;} - void SetProjectName(ByteString aName) - {aProjectName = aName;} - BOOL InsertDirectory( ByteString aDirName , USHORT aWhat, - USHORT aWhatOS, ByteString aLogFileName, - const ByteString &rClientRestriction ); - CommandData* RemoveDirectory( ByteString aLogFileName ); - CommandData* GetDirectoryList ( USHORT nWhatOs, USHORT nCommand ); - CommandData* GetDirectoryData( ByteString aLogFileName ); - inline CommandData* GetData( ByteString aLogFileName ) - { return GetDirectoryData( aLogFileName ); }; - - SByteStringList* GetDependencies( BOOL bExpanded = TRUE ); - void AddDependencies( ByteString aStr ); - void HasHardDependencies( BOOL bHard ) { bHardDependencies = bHard; } - BOOL HasHardDependencies() { return bHardDependencies; } -}; - -/********************************************************************* -* -* class Star -* Diese Klasse liest die Projectstruktur aller StarDivision Projekte -* aus \\dev\data1\upenv\data\config\solar.lst aus -* -*********************************************************************/ - -DECL_DEST_LIST ( StarList_tmp, StarList, Prj* ) -DECLARE_LIST ( SolarFileList, String* ) - -class StarFile -{ -private: - String aFileName; - Date aDate; - Time aTime; - - BOOL bExists; - -public: - StarFile( const String &rFile ); - const String &GetName() { return aFileName; } - Date GetDate() { return aDate; } - Time GetTime() { return aTime; } - - BOOL NeedsUpdate(); - BOOL Exists() { return bExists; } -}; - -DECLARE_LIST( StarFileList, StarFile * ) - -#define STAR_MODE_SINGLE_PARSE 0x0000 -#define STAR_MODE_RECURSIVE_PARSE 0x0001 -#define STAR_MODE_MULTIPLE_PARSE 0x0002 - -class Star : public StarList -{ -private: - ByteString aStarName; - - static Link aDBNotFoundHdl; -protected: - vos:: OMutex aMutex; - - USHORT nStarMode; - SolarFileList aFileList; - StarFileList aLoadedFilesList; - String sSourceRoot; - - void InsertSolarList( String sProject ); - String CreateFileName( String sProject ); - - void Expand_Impl(); - void ExpandPrj_Impl( Prj *pPrj, Prj *pDepPrj ); - -private: - void Read( String &rFileName ); - void Read( SolarFileList *pSOlarFiles ); - -public: - Star(); - Star( String aFileName, USHORT nMode = STAR_MODE_SINGLE_PARSE ); - Star( SolarFileList *pSolarFiles ); - Star( GenericInformationList *pStandLst, ByteString &rVersion, BOOL bLocal = FALSE, - const char *pSourceRoot = NULL ); - - ~Star(); - - static void SetDBNotFoundHdl( const Link &rLink ) { aDBNotFoundHdl = rLink; } - - ByteString GetName(){ return aStarName; }; - - BOOL HasProject( ByteString aProjectName ); - Prj* GetPrj( ByteString aProjectName ); - ByteString GetPrjName( DirEntry &rPath ); - - void InsertToken( char *pChar ); - BOOL NeedsUpdate(); - - USHORT GetMode() { return nStarMode; } -}; - -class StarWriter : public Star -{ -private: - USHORT WritePrj( Prj *pPrj, SvFileStream& rStream ); - -public: - StarWriter( String aFileName, BOOL bReadComments = FALSE, USHORT nMode = STAR_MODE_SINGLE_PARSE ); - StarWriter( SolarFileList *pSolarFiles, BOOL bReadComments = FALSE ); - StarWriter( GenericInformationList *pStandLst, ByteString &rVersion, BOOL bLocal = FALSE, - const char *pSourceRoot = NULL ); - - void CleanUp(); - - BOOL InsertProject ( Prj* pNewPrj ); - Prj* RemoveProject ( ByteString aProjectName ); - - USHORT Read( String aFileName, BOOL bReadComments = FALSE, USHORT nMode = STAR_MODE_SINGLE_PARSE ); - USHORT Read( SolarFileList *pSolarFiles, BOOL bReadComments = FALSE ); - USHORT Write( String aFileName ); - USHORT WriteMultiple( String rSourceRoot ); - - void InsertTokenLine( ByteString& rString ); -}; - ->>>>>>> other #endif diff --git a/tools/prj/d.lst b/tools/prj/d.lst index a8e08784f199..1c0b5271071d 100644 --- a/tools/prj/d.lst +++ b/tools/prj/d.lst @@ -8,107 +8,8 @@ mkdir: %_DEST%\inc%_EXT%\tools ..\%__SRC%\lib\lib*.so.* %_DEST%\lib%_EXT%\lib*.so.* ..\%__SRC%\lib\lib*.dylib %_DEST%\lib%_EXT%\lib*.dylib -<<<<<<< local ..\inc\tools\*.h %_DEST%\inc%_EXT%\tools\*.h ..\inc\tools\*.hxx %_DEST%\inc%_EXT%\tools\*.hxx -======= -..\inc\bootstrp\command.hxx %_DEST%\inc%_EXT%\bootstrp\command.hxx -..\inc\bootstrp\inimgr.hxx %_DEST%\inc%_EXT%\bootstrp\inimgr.hxx -..\inc\bootstrp\listmacr.hxx %_DEST%\inc%_EXT%\bootstrp\listmacr.hxx -..\inc\bootstrp\mkcreate.hxx %_DEST%\inc%_EXT%\bootstrp\mkcreate.hxx -..\inc\bootstrp\prj.hxx %_DEST%\inc%_EXT%\bootstrp\prj.hxx -..\inc\bootstrp\sstring.hxx %_DEST%\inc%_EXT%\bootstrp\sstring.hxx - -..\inc\tools\toolsdllapi.h %_DEST%\inc%_EXT%\tools\toolsdllapi.h -..\inc\tools\weakbase.hxx %_DEST%\inc%_EXT%\tools\weakbase.hxx -..\inc\tools\weakbase.h %_DEST%\inc%_EXT%\tools\weakbase.h - -..\inc\tools\postwin.h %_DEST%\inc%_EXT%\tools\postwin.h -..\inc\tools\prewin.h %_DEST%\inc%_EXT%\tools\prewin.h - -..\inc\tools\postx.h %_DEST%\inc%_EXT%\tools\postx.h -..\inc\tools\prex.h %_DEST%\inc%_EXT%\tools\prex.h - -..\inc\tools\svlibrary.hxx %_DEST%\inc%_EXT%\tools\svlibrary.hxx -..\inc\tools\solarmutex.hxx %_DEST%\inc%_EXT%\tools\solarmutex.hxx -..\inc\tools\wintypes.hxx %_DEST%\inc%_EXT%\tools\wintypes.hxx -..\inc\tools\mapunit.hxx %_DEST%\inc%_EXT%\tools\mapunit.hxx -..\inc\tools\fldunit.hxx %_DEST%\inc%_EXT%\tools\fldunit.hxx -..\inc\tools\fontenum.hxx %_DEST%\inc%_EXT%\tools\fontenum.hxx -..\inc\tools\agapi.hxx %_DEST%\inc%_EXT%\tools\agapi.hxx -..\inc\tools\agitem.hxx %_DEST%\inc%_EXT%\tools\agitem.hxx -..\inc\tools\appendunixshellword.hxx %_DEST%\inc%_EXT%\tools\appendunixshellword.hxx -..\inc\tools\bigint.hxx %_DEST%\inc%_EXT%\tools\bigint.hxx -..\inc\tools\cachestr.hxx %_DEST%\inc%_EXT%\tools\cachestr.hxx -..\inc\tools\color.hxx %_DEST%\inc%_EXT%\tools\color.hxx -..\inc\tools\contnr.hxx %_DEST%\inc%_EXT%\tools\contnr.hxx -..\inc\tools\date.hxx %_DEST%\inc%_EXT%\tools\date.hxx -..\inc\tools\datetime.hxx %_DEST%\inc%_EXT%\tools\datetime.hxx -..\inc\tools\debug.hxx %_DEST%\inc%_EXT%\tools\debug.hxx -..\inc\tools\diagnose_ex.h %_DEST%\inc%_EXT%\tools\diagnose_ex.h -..\inc\tools\download.hxx %_DEST%\inc%_EXT%\tools\download.hxx -..\inc\tools\dynary.hxx %_DEST%\inc%_EXT%\tools\dynary.hxx -..\inc\tools\errcode.hxx %_DEST%\inc%_EXT%\tools\errcode.hxx -..\inc\tools\errinf.hxx %_DEST%\inc%_EXT%\tools\errinf.hxx -..\inc\tools\extendapplicationenvironment.hxx %_DEST%\inc%_EXT%\tools\extendapplicationenvironment.hxx -..\inc\tools\fract.hxx %_DEST%\inc%_EXT%\tools\fract.hxx -..\inc\tools\fsys.hxx %_DEST%\inc%_EXT%\tools\fsys.hxx -..\inc\tools\eacopier.hxx %_DEST%\inc%_EXT%\tools\eacopier.hxx -..\inc\tools\gen.hxx %_DEST%\inc%_EXT%\tools\gen.hxx -..\inc\tools\globname.hxx %_DEST%\inc%_EXT%\tools\globname.hxx -..\inc\tools\inetdef.hxx %_DEST%\inc%_EXT%\tools\inetdef.hxx -..\inc\tools\inetmime.hxx %_DEST%\inc%_EXT%\tools\inetmime.hxx -..\inc\tools\inetmsg.hxx %_DEST%\inc%_EXT%\tools\inetmsg.hxx -..\inc\tools\inetstrm.hxx %_DEST%\inc%_EXT%\tools\inetstrm.hxx -..\inc\tools\link.hxx %_DEST%\inc%_EXT%\tools\link.hxx -..\inc\tools\list.hxx %_DEST%\inc%_EXT%\tools\list.hxx -..\inc\tools\mempool.hxx %_DEST%\inc%_EXT%\tools\mempool.hxx -..\inc\tools\multisel.hxx %_DEST%\inc%_EXT%\tools\multisel.hxx -..\inc\tools\ownlist.hxx %_DEST%\inc%_EXT%\tools\ownlist.hxx -..\inc\tools\postsys.h %_DEST%\inc%_EXT%\tools\postsys.h -..\inc\tools\presys.h %_DEST%\inc%_EXT%\tools\presys.h -..\inc\tools\pstm.hxx %_DEST%\inc%_EXT%\tools\pstm.hxx -..\inc\tools\queue.hxx %_DEST%\inc%_EXT%\tools\queue.hxx -..\inc\tools\rc.h %_DEST%\inc%_EXT%\tools\rc.h -..\inc\tools\rc.hxx %_DEST%\inc%_EXT%\tools\rc.hxx -..\inc\tools\rcid.h %_DEST%\inc%_EXT%\tools\rcid.h -..\inc\tools\ref.hxx %_DEST%\inc%_EXT%\tools\ref.hxx -..\inc\tools\resid.hxx %_DEST%\inc%_EXT%\tools\resid.hxx -..\inc\tools\resmgr.hxx %_DEST%\inc%_EXT%\tools\resmgr.hxx -..\inc\tools\StringListResource.hxx %_DEST%\inc%_EXT%\tools\StringListResource.hxx -..\inc\tools\isofallback.hxx %_DEST%\inc%_EXT%\tools\isofallback.hxx -..\inc\tools\rtti.hxx %_DEST%\inc%_EXT%\tools\rtti.hxx -..\inc\tools\shl.hxx %_DEST%\inc%_EXT%\tools\shl.hxx -..\inc\tools\simplerm.hxx %_DEST%\inc%_EXT%\tools\simplerm.hxx -..\inc\tools\solar.h %_DEST%\inc%_EXT%\tools\solar.h -..\inc\tools\stack.hxx %_DEST%\inc%_EXT%\tools\stack.hxx -..\inc\tools\stream.hxx %_DEST%\inc%_EXT%\tools\stream.hxx -..\inc\tools\string.hxx %_DEST%\inc%_EXT%\tools\string.hxx -..\inc\tools\svwin.h %_DEST%\inc%_EXT%\tools\svwin.h -..\inc\tools\table.hxx %_DEST%\inc%_EXT%\tools\table.hxx -..\inc\tools\tenccvt.hxx %_DEST%\inc%_EXT%\tools\tenccvt.hxx -..\inc\tools\time.hxx %_DEST%\inc%_EXT%\tools\time.hxx -..\inc\tools\tools.h %_DEST%\inc%_EXT%\tools\tools.h -..\inc\tools\unqid.hxx %_DEST%\inc%_EXT%\tools\unqid.hxx -..\inc\tools\unqidx.hxx %_DEST%\inc%_EXT%\tools\unqidx.hxx -..\inc\tools\urlkeys.hxx %_DEST%\inc%_EXT%\tools\urlkeys.hxx -..\inc\tools\urlobj.hxx %_DEST%\inc%_EXT%\tools\urlobj.hxx -..\inc\tools\vcompat.hxx %_DEST%\inc%_EXT%\tools\vcompat.hxx -..\inc\tools\wldcrd.hxx %_DEST%\inc%_EXT%\tools\wldcrd.hxx -..\inc\tools\zcodec.hxx %_DEST%\inc%_EXT%\tools\zcodec.hxx -..\inc\tools\tempfile.hxx %_DEST%\inc%_EXT%\tools\tempfile.hxx -..\inc\tools\geninfo.hxx %_DEST%\inc%_EXT%\tools\geninfo.hxx -..\inc\tools\iparser.hxx %_DEST%\inc%_EXT%\tools\iparser.hxx -..\inc\tools\config.hxx %_DEST%\inc%_EXT%\tools\config.hxx -..\inc\tools\resary.hxx %_DEST%\inc%_EXT%\tools\resary.hxx -..\inc\tools\poly.hxx %_DEST%\inc%_EXT%\tools\poly.hxx -..\inc\tools\line.hxx %_DEST%\inc%_EXT%\tools\line.hxx -..\inc\tools\vector2d.hxx %_DEST%\inc%_EXT%\tools\vector2d.hxx -..\inc\tools\testtoolloader.hxx %_DEST%\inc%_EXT%\tools\testtoolloader.hxx -..\inc\tools\svborder.hxx %_DEST%\inc%_EXT%\tools\svborder.hxx -..\inc\tools\getprocessworkingdir.hxx %_DEST%\inc%_EXT%\tools\getprocessworkingdir.hxx -..\inc\tools\b3dtrans.hxx %_DEST%\inc%_EXT%\tools\b3dtrans.hxx ->>>>>>> other ..\%__SRC%\bin\rscdep.exe %_DEST%\bin%_EXT%\rscdep.exe ..\%__SRC%\bin\rscdep %_DEST%\bin%_EXT%\rscdep diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst index ae9c0364c895..bf6b36a7eaf7 100644 --- a/vcl/prj/d.lst +++ b/vcl/prj/d.lst @@ -152,7 +152,5 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\helper.hxx %_DEST%\inc%_EXT%\vcl\helper.hxx ..\inc\vcl\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx ..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx -<<<<<<< local -======= ..\%__SRC%\misc\vcl.component %_DEST%\xml%_EXT%\vcl.component ->>>>>>> other + -- cgit v1.2.3 From 2ce6a123f867943205e26c2976159fd4a23da9f7 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Tue, 2 Nov 2010 15:47:47 +0100 Subject: fix a merge problem --- vcl/unx/source/gdi/salprnpsp.cxx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'vcl') diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx index 417704eb3b69..ece724d717cb 100644 --- a/vcl/unx/source/gdi/salprnpsp.cxx +++ b/vcl/unx/source/gdi/salprnpsp.cxx @@ -1187,14 +1187,12 @@ BOOL PspSalPrinter::StartJob( const String* i_pFileName, const String& i_rJobNam aContext.Version = vcl::PDFWriter::PDF_1_4; aContext.Tagged = false; aContext.EmbedStandardFonts = true; - aContext.Encrypt = false; aContext.DocumentLocale = Application::GetSettings().GetLocale(); // prepare doc info - vcl::PDFDocInfo aDocInfo; - aDocInfo.Title = i_rJobName; - aDocInfo.Creator = i_rAppName; - aDocInfo.Producer = i_rAppName; + aContext.DocumentInfo.Title = i_rJobName; + aContext.DocumentInfo.Creator = i_rAppName; + aContext.DocumentInfo.Producer = i_rAppName; // define how we handle metafiles in PDFWriter vcl::PDFWriter::PlayMetafileContext aMtfContext; @@ -1271,11 +1269,10 @@ BOOL PspSalPrinter::StartJob( const String* i_pFileName, const String& i_rJobNam #if defined __SUNPRO_CC #pragma disable_warn #endif - pWriter.reset( new vcl::PDFWriter( aContext ) ); + pWriter.reset( new vcl::PDFWriter( aContext, uno::Reference< beans::XMaterialHolder >() ) ); #if defined __SUNPRO_CC #pragma enable_warn #endif - pWriter->SetDocInfo( aDocInfo ); } pWriter->NewPage( TenMuToPt( aNewParm.maPageSize.Width() ), -- cgit v1.2.3 From 831bb211b6d19b21848908114ced092fec5bd343 Mon Sep 17 00:00:00 2001 From: "Philipp Lohmann [pl]" Date: Fri, 12 Nov 2010 16:14:48 +0100 Subject: pl08: #i115553# fix a PDF/A and transparencies again --- vcl/source/gdi/print2.cxx | 1 + 1 file changed, 1 insertion(+) (limited to 'vcl') diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx index 25ba80003fd7..5c2a742a10ba 100644 --- a/vcl/source/gdi/print2.cxx +++ b/vcl/source/gdi/print2.cxx @@ -407,6 +407,7 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic { const MetaLineAction& rMetaLineAction = static_cast(rAct); aActionBounds = Rectangle( rMetaLineAction.GetStartPoint(), rMetaLineAction.GetEndPoint() ); + aActionBounds.Justify(); const long nLineWidth(rMetaLineAction.GetLineInfo().GetWidth()); if(nLineWidth) { -- cgit v1.2.3 From 7a4ec865eafbb8c0a6fb703d843a8f023c5a6a9c Mon Sep 17 00:00:00 2001 From: "Herbert Duerr [hdu]" Date: Fri, 19 Nov 2010 14:37:26 +0100 Subject: #i115618# fix bad PDF export regression for simple RTL cases --- vcl/source/gdi/pdfwriter_impl.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'vcl') diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 580161da8a4e..aa9f642f9fee 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -7398,7 +7398,14 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT // try to handle ligatures and such if( i < nGlyphs-1 ) { - pUnicodesPerGlyph[i] = nChars = pCharPosAry[i+1] - pCharPosAry[i]; + nChars = pCharPosAry[i+1] - pCharPosAry[i]; + // #i115618# fix for simple RTL+CTL cases + // TODO: sanitize for RTL ligatures, more complex CTL, etc. + if( nChars < 0 ) + nChars = -nChars; + else if( nChars == 0 ) + nChars = 1; + pUnicodesPerGlyph[i] = nChars; for( int n = 1; n < nChars; n++ ) aUnicodes.push_back( rText.GetChar( sal::static_int_cast(pCharPosAry[i]+n) ) ); } -- cgit v1.2.3 From a7efcc63895bb32164a9077a3e46b7cab33c3454 Mon Sep 17 00:00:00 2001 From: "Herbert Duerr [hdu]" Date: Mon, 22 Nov 2010 10:18:47 +0100 Subject: #i108584# workaround unexpected ATSUBreakLine error result --- vcl/aqua/source/gdi/salatslayout.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'vcl') diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx index 335505de85ac..0261ab3b56fa 100755 --- a/vcl/aqua/source/gdi/salatslayout.cxx +++ b/vcl/aqua/source/gdi/salatslayout.cxx @@ -753,10 +753,11 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons // initial measurement of text break position UniCharArrayOffset nBreakPos = mnMinCharPos; - const ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nPixelWidth ); + ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nPixelWidth ); + if( nATSUMaxWidth <= 0xFFFF ) // #i108584# avoid ATSU rejecting the parameter + return mnMinCharPos; // or do ATSUMaxWidth=0x10000; OSStatus eStatus = ATSUBreakLine( maATSULayout, mnMinCharPos, nATSUMaxWidth, false, &nBreakPos ); - if( (eStatus != noErr) && (eStatus != kATSULineBreakInWord) ) return STRING_LEN; -- cgit v1.2.3 From a26b166697b3486eebe005e33184b713689c3382 Mon Sep 17 00:00:00 2001 From: "Herbert Duerr [hdu]" Date: Mon, 22 Nov 2010 10:29:58 +0100 Subject: #i108584# workaround unexpected ATSUBreakLine error result --- vcl/aqua/source/gdi/salatslayout.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'vcl') diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx index 0261ab3b56fa..a355ff86d00e 100755 --- a/vcl/aqua/source/gdi/salatslayout.cxx +++ b/vcl/aqua/source/gdi/salatslayout.cxx @@ -753,7 +753,7 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons // initial measurement of text break position UniCharArrayOffset nBreakPos = mnMinCharPos; - ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nPixelWidth ); + const ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nPixelWidth ); if( nATSUMaxWidth <= 0xFFFF ) // #i108584# avoid ATSU rejecting the parameter return mnMinCharPos; // or do ATSUMaxWidth=0x10000; OSStatus eStatus = ATSUBreakLine( maATSULayout, mnMinCharPos, @@ -782,7 +782,7 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons if( eStatus != noErr ) return nBreakPos; const ATSUTextMeasurement nATSURemWidth = nATSUMaxWidth - (nRight - nLeft); - if( nATSURemWidth <= 0 ) + if( nATSURemWidth <= 0xFFFF ) // #i108584# avoid ATSU rejecting the parameter return nBreakPos; UniCharArrayOffset nBreakPosInWord = nBreakPos; eStatus = ATSUBreakLine( maATSULayout, nBreakPos, nATSURemWidth, false, &nBreakPosInWord ); -- cgit v1.2.3 From 13881ca76ecbbbef8ede8df923aaf2504a16c5f4 Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 22 Nov 2010 18:54:49 +0100 Subject: os145: #b7001888# fixing small svm problem --- vcl/source/gdi/metaact.cxx | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'vcl') diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 8c1545758c3b..79d875542509 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -1441,19 +1441,35 @@ void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData ) rIStm >> mnLen; rIStm >> nAryLen; + if ( mnIndex > mnLen ) + { + mnIndex = 0; + mpDXAry = 0; + return; + } + if( nAryLen ) { // #i9762#, #106172# Ensure that DX array is at least mnLen entries long - const ULONG nIntAryLen( Max(nAryLen, static_cast(mnLen)) ); - mpDXAry = new sal_Int32[ nIntAryLen ]; - - ULONG i; - for( i = 0UL; i < nAryLen; i++ ) - rIStm >> mpDXAry[ i ]; + if ( mnLen >= nAryLen ) + { + mpDXAry = new (std::nothrow)sal_Int32[ mnLen ]; + if ( mpDXAry ) + { + ULONG i; + for( i = 0UL; i < nAryLen; i++ ) + rIStm >> mpDXAry[ i ]; - // #106172# setup remainder - for( ; i < nIntAryLen; i++ ) - mpDXAry[ i ] = 0; + // #106172# setup remainder + for( ; i < mnLen; i++ ) + mpDXAry[ i ] = 0; + } + } + else + { + mpDXAry = NULL; + return; + } } else mpDXAry = NULL; -- cgit v1.2.3 From b9113ba2a8a4fca7d21b1268a250f4cdc70ba64d Mon Sep 17 00:00:00 2001 From: sj Date: Mon, 22 Nov 2010 19:00:24 +0100 Subject: os145: #b7001886# fixing small ppt import problem, improving png reader --- vcl/source/gdi/pngread.cxx | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'vcl') diff --git a/vcl/source/gdi/pngread.cxx b/vcl/source/gdi/pngread.cxx index 11971db34378..df67c4974d47 100644 --- a/vcl/source/gdi/pngread.cxx +++ b/vcl/source/gdi/pngread.cxx @@ -411,7 +411,9 @@ BitmapEx PNGReaderImpl::GetBitmapEx( const Size& rPreviewSizeHint ) case PNGCHUNK_IDAT : { - if ( !mbIDAT ) // the gfx is finished, but there may be left a zlibCRC of about 4Bytes + if ( !mpInflateInBuf ) // taking care that the header has properly been read + mbStatus = FALSE; + else if ( !mbIDAT ) // the gfx is finished, but there may be left a zlibCRC of about 4Bytes ImplReadIDAT(); } break; @@ -527,7 +529,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) mbIDAT = mbAlphaChannel = mbTransparent = FALSE; mbGrayScale = mbRGBTriple = FALSE; mnTargetDepth = mnPngDepth; - mnScansize = ( ( maOrigSize.Width() * mnPngDepth ) + 7 ) >> 3; + sal_uInt64 nScansize64 = ( ( static_cast< sal_uInt64 >( maOrigSize.Width() ) * mnPngDepth ) + 7 ) >> 3; // valid color types are 0,2,3,4 & 6 switch ( mnColorType ) @@ -557,7 +559,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 2 : // each pixel is an RGB triple { mbRGBTriple = TRUE; - mnScansize *= 3; + nScansize64 *= 3; switch ( mnPngDepth ) { case 16 : // we have to reduce the bitmap @@ -590,7 +592,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 4 : // each pixel is a grayscale sample followed by an alpha sample { - mnScansize *= 2; + nScansize64 *= 2; mbAlphaChannel = TRUE; switch ( mnPngDepth ) { @@ -608,7 +610,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 6 : // each pixel is an RGB triple followed by an alpha sample { mbRGBTriple = TRUE; - mnScansize *= 4; + nScansize64 *= 4; mbAlphaChannel = TRUE; switch (mnPngDepth ) { @@ -626,16 +628,24 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) return FALSE; } - mnBPP = mnScansize / maOrigSize.Width(); + mnBPP = static_cast< sal_uInt32 >( nScansize64 / maOrigSize.Width() ); if ( !mnBPP ) mnBPP = 1; - mnScansize++; // each scanline includes one filterbyte + nScansize64++; // each scanline includes one filterbyte + + if ( nScansize64 > SAL_MAX_UINT32 ) + return FALSE; + + mnScansize = static_cast< sal_uInt32 >( nScansize64 ); // TODO: switch between both scanlines instead of copying - mpInflateInBuf = new BYTE[ mnScansize ]; + mpInflateInBuf = new (std::nothrow) BYTE[ mnScansize ]; mpScanCurrent = mpInflateInBuf; - mpScanPrior = new BYTE[ mnScansize ]; + mpScanPrior = new (std::nothrow) BYTE[ mnScansize ]; + + if ( !mpInflateInBuf || !mpScanPrior ) + return FALSE; // calculate target size from original size and the preview hint if( rPreviewSizeHint.Width() || rPreviewSizeHint.Height() ) -- cgit v1.2.3 From 23cdc612ccef2d48c6c5abad534f40990e921003 Mon Sep 17 00:00:00 2001 From: sj Date: Tue, 30 Nov 2010 13:41:46 +0100 Subject: impress205: #i115825# fixed copy&paste problem of metafiles --- vcl/source/gdi/metaact.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'vcl') diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 79d875542509..9a7fb6527e26 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -1441,7 +1441,7 @@ void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData ) rIStm >> mnLen; rIStm >> nAryLen; - if ( mnIndex > mnLen ) + if ( mnIndex + mnLen > maStr.Len() ) { mnIndex = 0; mpDXAry = 0; -- cgit v1.2.3 From 2e512af879c769bd29ddaf00dbd3eae60d3d4813 Mon Sep 17 00:00:00 2001 From: sj Date: Thu, 2 Dec 2010 14:31:22 +0100 Subject: impress205: #i115825# fixed metatextarray issues --- vcl/source/gdi/metaact.cxx | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'vcl') diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 9a7fb6527e26..f398888a33b6 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -1481,6 +1481,12 @@ void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData ) sal_Unicode* pBuffer = maStr.AllocBuffer( nLen ); while ( nLen-- ) rIStm >> *pBuffer++; + + if ( mnIndex + mnLen > maStr.Len() ) + { + mnIndex = 0; + delete[] mpDXAry, mpDXAry = NULL; + } } } -- cgit v1.2.3