diff options
Diffstat (limited to 'vcl/source/window')
29 files changed, 1845 insertions, 1262 deletions
diff --git a/vcl/source/window/arrange.cxx b/vcl/source/window/arrange.cxx index dad48235f8fb..f016ef2c053b 100644 --- a/vcl/source/window/arrange.cxx +++ b/vcl/source/window/arrange.cxx @@ -29,15 +29,37 @@ #include "vcl/arrange.hxx" #include "vcl/edit.hxx" +#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 //----------------------------------------- +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( 3, 3 ), MapMode( MAP_APPFONT ) ) ); + nResult = pSVData->maAppData.mnDefaultLayoutBorder = aBorder.Height(); + } + } + return nResult > 0 ? nResult : 0; +} + WindowArranger::~WindowArranger() {} @@ -156,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() += m_nLeftBorder + m_nRightBorder; - aResult.Height() += m_nTopBorder + 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; @@ -175,16 +207,74 @@ 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 ) 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 //----------------------------------------- @@ -201,6 +291,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 ) { @@ -211,7 +302,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(); @@ -220,7 +311,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(); @@ -233,13 +324,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; @@ -344,7 +436,9 @@ void RowOrColumn::resize() size_t nElements = m_aElements.size(); // get all element sizes for sizing std::vector<Size> 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() ) @@ -352,13 +446,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; } } } @@ -375,8 +469,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++ ) @@ -386,27 +480,27 @@ 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(); } } } -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<WindowArranger>(), i_nExpandPrio ) ); + m_aElements.push_back( WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), 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<WindowArranger>(), i_nExpandPrio ) ); + m_aElements.insert( it, WindowArranger::Element( i_pWindow, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) ); } return nIndex; } @@ -479,14 +573,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; } @@ -495,23 +589,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 @@ -578,18 +674,22 @@ 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(); } } } } - return nWidth + getBorderWidth(); + return nWidth + getBorderValue( getBorderWidth() ); } Size LabelColumn::getOptimalSize( WindowSizeType i_eType ) const { long nWidth = getLabelWidth(); + long nOuterBorder = getBorderValue( m_nOuterBorder ); Size aColumnSize; // every child is a LabeledElement @@ -622,19 +722,19 @@ 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(); } 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() += 2*m_nOuterBorder; + aColumnSize.Height() -= getBorderValue( getBorderWidth() ); // for the first element + aColumnSize.Height() += 2*nOuterBorder; } return aColumnSize; } @@ -667,12 +767,13 @@ size_t LabelColumn::addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> 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; @@ -690,19 +791,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 + 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 ); } @@ -728,9 +833,13 @@ MatrixArranger::~MatrixArranger() { } -Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights ) const +Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, + std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights, + std::vector<sal_Int32>& o_rColumnPrio, std::vector<sal_Int32>& o_rRowPrio + ) 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; @@ -746,6 +855,8 @@ Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector<long>& // now allocate row and column depth vectors o_rColumnWidths = std::vector< long >( nColumns, 0 ); o_rRowHeights = std::vector< long >( nRows, 0 ); + o_rColumnPrio = std::vector< sal_Int32 >( nColumns, 0 ); + o_rRowPrio = std::vector< sal_Int32 >( nRows, 0 ); // get sizes an allocate them into rows/columns for( std::vector< MatrixElement >::const_iterator it = m_aElements.begin(); @@ -756,18 +867,24 @@ Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector<long>& o_rColumnWidths[ it->m_nX ] = aSize.Width(); if( aSize.Height() > o_rRowHeights[ it->m_nY ] ) o_rRowHeights[ it->m_nY ] = aSize.Height(); + if( it->m_nExpandPriority > o_rColumnPrio[ it->m_nX ] ) + o_rColumnPrio[ it->m_nX ] = it->m_nExpandPriority; + if( it->m_nExpandPriority > o_rRowPrio[ it->m_nY ] ) + o_rRowPrio[ it->m_nY ] = it->m_nExpandPriority; } // 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; } @@ -775,9 +892,48 @@ Size MatrixArranger::getOptimalSize( WindowSizeType i_eType, std::vector<long>& Size MatrixArranger::getOptimalSize( WindowSizeType i_eType ) const { std::vector<long> aColumnWidths, aRowHeights; - return getOptimalSize( i_eType, aColumnWidths, aRowHeights ); + std::vector<sal_Int32> aColumnPrio, aRowPrio; + return getOptimalSize( i_eType, aColumnWidths, aRowHeights, aColumnPrio, aRowPrio ); } +void MatrixArranger::distributeExtraSize( std::vector<long>& io_rSizes, const std::vector<sal_Int32>& i_rPrios, long i_nExtraWidth ) +{ + if( ! io_rSizes.empty() && io_rSizes.size() == i_rPrios.size() ) // sanity check + { + // find all elements with the highest expand priority + size_t nElements = io_rSizes.size(); + std::vector< size_t > aIndices; + sal_Int32 nHighPrio = 0; + for( size_t i = 0; i < nElements; i++ ) + { + sal_Int32 nCurPrio = i_rPrios[ i ]; + if( nCurPrio > nHighPrio ) + { + aIndices.clear(); + nHighPrio = nCurPrio; + } + if( nCurPrio == nHighPrio ) + aIndices.push_back( i ); + } + + // distribute extra space evenly among collected elements + nElements = aIndices.size(); + if( nElements > 0 ) + { + long nDelta = i_nExtraWidth / nElements; + for( size_t i = 0; i < nElements; i++ ) + { + io_rSizes[ aIndices[i] ] += nDelta; + i_nExtraWidth -= nDelta; + } + // add the last pixels to the last row element + if( i_nExtraWidth > 0 && nElements > 0 ) + io_rSizes[aIndices.back()] += i_nExtraWidth; + } + } +} + + void MatrixArranger::resize() { // assure that we have at least one row and column @@ -786,30 +942,44 @@ void MatrixArranger::resize() // check if we can get optimal size, else fallback to minimal size std::vector<long> aColumnWidths, aRowHeights; - Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED, aColumnWidths, aRowHeights ) ); + std::vector<sal_Int32> aColumnPrio, aRowPrio; + Size aOptSize( getOptimalSize( WINDOWSIZE_PREFERRED, aColumnWidths, aRowHeights, aColumnPrio, aRowPrio ) ); if( aOptSize.Height() > m_aManagedArea.GetHeight() || aOptSize.Width() > m_aManagedArea.GetWidth() ) { std::vector<long> aMinColumnWidths, aMinRowHeights; - getOptimalSize( WINDOWSIZE_MINIMUM, aMinColumnWidths, aMinRowHeights ); + getOptimalSize( WINDOWSIZE_MINIMUM, aMinColumnWidths, aMinRowHeights, aColumnPrio, aRowPrio ); if( aOptSize.Height() > m_aManagedArea.GetHeight() ) aRowHeights = aMinRowHeights; if( aOptSize.Width() > m_aManagedArea.GetWidth() ) aColumnWidths = aMinColumnWidths; } - // FIXME: distribute extra space available + // distribute extra space available + long nExtraSize = m_aManagedArea.GetWidth(); + for( size_t i = 0; i < aColumnWidths.size(); ++i ) + nExtraSize -= aColumnWidths[i] + m_nBorderX; + if( nExtraSize > 0 ) + distributeExtraSize( aColumnWidths, aColumnPrio, nExtraSize ); + nExtraSize = m_aManagedArea.GetHeight(); + for( size_t i = 0; i < aRowHeights.size(); ++i ) + nExtraSize -= aRowHeights[i] + m_nBorderY; + if( nExtraSize > 0 ) + distributeExtraSize( aRowHeights, aRowPrio, nExtraSize ); // prepare offsets + long nDistanceX = getBorderValue( m_nBorderX ); + long nDistanceY = getBorderValue( m_nBorderY ); + long nOuterBorder = getBorderValue( m_nOuterBorder ); std::vector<long> 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<long> 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(); @@ -821,7 +991,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 ); @@ -829,7 +999,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<WindowArranger>(), i_nExpandPrio ) ); + m_aElements.push_back( MatrixElement( i_pWindow, i_nX, i_nY, boost::shared_ptr<WindowArranger>(), i_nExpandPrio, i_rMinSize ) ); } else { @@ -837,6 +1007,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; diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx index 8eedf76043da..2ff7d0a687e7 100644 --- a/vcl/source/window/brdwin.cxx +++ b/vcl/source/window/brdwin.cxx @@ -1151,15 +1151,13 @@ void ImplSmallBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHei if( mbNWFBorder ) { ImplControlValue aControlValue; - Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( mnWidth < 10 ? 10 : mnWidth, mnHeight < 10 ? 10 : mnHeight ) ) ); - Region aBoundingRgn( aCtrlRegion ); - Region aContentRgn( aCtrlRegion ); + Rectangle aCtrlRegion( (const Point&)Point(), Size( mnWidth < 10 ? 10 : mnWidth, mnHeight < 10 ? 10 : mnHeight ) ); + Rectangle aBounds( aCtrlRegion ); + Rectangle aContent( aCtrlRegion ); if( pWin->GetNativeControlRegion( aCtrlType, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), - aBoundingRgn, aContentRgn ) ) + aBounds, aContent ) ) { - Rectangle aBounds( aBoundingRgn.GetBoundRect() ); - Rectangle aContent( aContentRgn.GetBoundRect() ); mnLeftBorder = aContent.Left() - aBounds.Left(); mnRightBorder = aBounds.Right() - aContent.Right(); mnTopBorder = aContent.Top() - aBounds.Top(); @@ -1346,13 +1344,16 @@ void ImplSmallBorderWindowView::DrawWindow( USHORT nDrawFlags, OutputDevice*, co nState |= CTRL_STATE_ROLLOVER; Point aPoint; - Region aCtrlRegion( Rectangle( aPoint, Size( mnWidth, mnHeight ) ) ); - - Region aBoundingRgn( Rectangle( aPoint, Size( mnWidth, mnHeight ) ) ); - Region aContentRgn=aCtrlRegion; - if(pWin->GetNativeControlRegion( aCtrlType, aCtrlPart, aCtrlRegion, - nState, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn )) { - aCtrlRegion=aContentRgn; + Rectangle aCtrlRegion( aPoint, Size( mnWidth, mnHeight ) ); + + Rectangle aBoundingRgn( aPoint, Size( mnWidth, mnHeight ) ); + Rectangle aContentRgn( aCtrlRegion ); + if( ! ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize && + pWin->GetNativeControlRegion( aCtrlType, aCtrlPart, aCtrlRegion, + nState, aControlValue, rtl::OUString(), + aBoundingRgn, aContentRgn )) + { + aCtrlRegion=aContentRgn; } bNativeOK = pWin->DrawNativeControl( aCtrlType, aCtrlPart, aCtrlRegion, nState, diff --git a/vcl/source/window/btndlg.cxx b/vcl/source/window/btndlg.cxx index e835fe749ed1..9a0452027737 100644 --- a/vcl/source/window/btndlg.cxx +++ b/vcl/source/window/btndlg.cxx @@ -530,22 +530,19 @@ XubString ButtonDialog::GetButtonHelpText( USHORT nId ) const // ----------------------------------------------------------------------- -void ButtonDialog::SetButtonHelpId( USHORT nId, ULONG nHelpId ) +void ButtonDialog::SetButtonHelpId( USHORT nId, const rtl::OString& rHelpId ) { ImplBtnDlgItem* pItem = ImplGetItem( nId ); if ( pItem ) - pItem->mpPushButton->SetHelpId( nHelpId ); + pItem->mpPushButton->SetHelpId( rHelpId ); } // ----------------------------------------------------------------------- -ULONG ButtonDialog::GetButtonHelpId( USHORT nId ) const +rtl::OString ButtonDialog::GetButtonHelpId( USHORT nId ) const { ImplBtnDlgItem* pItem = ImplGetItem( nId ); - if ( pItem ) - return pItem->mpPushButton->GetHelpId(); - else - return 0; + return pItem ? rtl::OString( pItem->mpPushButton->GetHelpId() ) : rtl::OString(); } diff --git a/vcl/source/window/decoview.cxx b/vcl/source/window/decoview.cxx index a32790cfb0d4..d51988d4d5d3 100644 --- a/vcl/source/window/decoview.cxx +++ b/vcl/source/window/decoview.cxx @@ -44,71 +44,6 @@ // ======================================================================= -void ImplDrawOS2Symbol( OutputDevice* pDev, const Rectangle& rRect, - USHORT nStyle, BOOL bClose ) -{ - DecorationView aView( pDev ); - const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings(); - Rectangle aRect = rRect; - Color aColor1; - Color aColor2; - - pDev->SetFillColor(); - - if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) ) - { - aColor1 = rStyleSettings.GetShadowColor(); - aColor2 = rStyleSettings.GetLightColor(); - } - else - { - aColor1 = rStyleSettings.GetLightColor(); - aColor2 = rStyleSettings.GetShadowColor(); - } - aView.DrawFrame( aRect, aColor1, aColor2 ); - - aRect.Left() += 2; - aRect.Top() += 2; - aRect.Right() -= 2; - aRect.Bottom() -= 2; - - if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) ) - pDev->SetLineColor( rStyleSettings.GetLightColor() ); - else - pDev->SetLineColor( rStyleSettings.GetShadowColor() ); - if ( bClose ) - { - pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom()-2 ) ); - pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right()-2, aRect.Top() ) ); - pDev->DrawLine( Point( aRect.Left()+2, aRect.Bottom()-1 ), - Point( aRect.Right()-1, aRect.Top()+2 ) ); - } - else - { - pDev->DrawLine( aRect.TopLeft(), aRect.BottomLeft() ); - pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) ); - } - - if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) ) - pDev->SetLineColor( rStyleSettings.GetShadowColor() ); - else - pDev->SetLineColor( rStyleSettings.GetLightColor() ); - if ( bClose ) - { - pDev->DrawLine( Point( aRect.Right(), aRect.Top()+2 ), aRect.BottomRight() ); - pDev->DrawLine( Point( aRect.Left()+2, aRect.Bottom() ), aRect.BottomRight() ); - pDev->DrawLine( Point( aRect.Right()-2, aRect.Top()+1 ), - Point( aRect.Left()+1, aRect.Bottom()-2 ) ); - } - else - { - pDev->DrawLine( aRect.TopRight(), aRect.BottomRight() ); - pDev->DrawLine( Point( aRect.Left()+1, aRect.Bottom() ), aRect.BottomRight() ); - } -} - -// ======================================================================= - static void ImplDrawSymbol( OutputDevice* pDev, const Rectangle& rRect, SymbolType eType ) { @@ -630,41 +565,6 @@ static void ImplDrawSymbol( OutputDevice* pDev, const Rectangle& rRect, pDev->DrawRect( aRect ); } break; - - case SYMBOL_OS2CLOSE: - { - Rectangle aRect( nCenterX-n2, nCenterY-n2, - nCenterX+n2, nCenterY+n2 ); - ImplDrawOS2Symbol( pDev, aRect, 0, TRUE ); - } - break; - - case SYMBOL_OS2FLOAT: - { - Rectangle aRect( nCenterX-n2+4, nCenterY-n2+4, - nCenterX+n2-4, nCenterY+n2-3 ); - ImplDrawOS2Symbol( pDev, aRect, 0, FALSE ); - DecorationView aDecoView( pDev ); - Rectangle aRect2( nCenterX-n2, nCenterY-n2, - nCenterX-n2+2, nCenterY+n2 ); - aDecoView.DrawFrame( aRect2, - pDev->GetSettings().GetStyleSettings().GetLightColor(), - pDev->GetSettings().GetStyleSettings().GetShadowColor() ); - Rectangle aRect3( nCenterX+n2-2, nCenterY-n2, - nCenterX+n2, nCenterY+n2 ); - aDecoView.DrawFrame( aRect3, - pDev->GetSettings().GetStyleSettings().GetLightColor(), - pDev->GetSettings().GetStyleSettings().GetShadowColor() ); - } - break; - - case SYMBOL_OS2HIDE: - { - Rectangle aRect( nCenterX-n2+3, nCenterY-n2+3, - nCenterX+n2-3, nCenterY+n2-3 ); - ImplDrawOS2Symbol( pDev, aRect, 0, FALSE ); - } - break; } } @@ -877,12 +777,12 @@ static void ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect, if( pWin->GetType() == WINDOW_BORDERWINDOW ) nValueStyle |= FRAME_DRAW_BORDERWINDOWBORDER; ImplControlValue aControlValue( nValueStyle ); - Region aBound, aContent; - Region aNatRgn( rRect ); + Rectangle aBound, aContent; + Rectangle aNatRgn( rRect ); if(pWin && pWin->GetNativeControlRegion(CTRL_FRAME, PART_BORDER, aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { - rRect = aContent.GetBoundRect(); + rRect = aContent; } else if ( nStyle & FRAME_DRAW_MONO ) ImplDrawDPILineRect( pDev, rRect, NULL, bRound ); @@ -922,15 +822,15 @@ static void ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect, if( pWin->GetType() == WINDOW_BORDERWINDOW ) nValueStyle |= FRAME_DRAW_BORDERWINDOWBORDER; ImplControlValue aControlValue( nValueStyle ); - Region aBound, aContent; - Region aNatRgn( rRect ); + Rectangle aBound, aContent; + Rectangle aNatRgn( rRect ); if( pWin->GetNativeControlRegion(CTRL_FRAME, PART_BORDER, aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { if( pWin->DrawNativeControl( CTRL_FRAME, PART_BORDER, aContent, CTRL_STATE_ENABLED, aControlValue, rtl::OUString()) ) { - rRect = aContent.GetBoundRect(); + rRect = aContent; return; } } diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx index 64f2b7e0d2a1..055b7e9fe80b 100644 --- a/vcl/source/window/dlgctrl.cxx +++ b/vcl/source/window/dlgctrl.cxx @@ -1058,29 +1058,10 @@ static sal_Unicode getAccel( const String& rStr ) return nChar; } -Window* Window::GetLabelFor() const +static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel ) { - if ( mpWindowImpl->mbDisableAccessibleLabelForRelation ) - return NULL; - Window* pWindow = NULL; - Window* pFrameWindow = ImplGetFrameWindow(); - - WinBits nFrameStyle = pFrameWindow->GetStyle(); - if( ! ( nFrameStyle & WB_DIALOGCONTROL ) - || ( nFrameStyle & WB_NODIALOGCONTROL ) - ) - return NULL; - - if ( mpWindowImpl->mpRealParent ) - pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this ); - - if( pWindow ) - return pWindow; - sal_Unicode nAccel = getAccel( GetText() ); - - WindowType nMyType = GetType(); if( nMyType == WINDOW_FIXEDTEXT || nMyType == WINDOW_FIXEDLINE || nMyType == WINDOW_GROUPBOX ) @@ -1092,7 +1073,7 @@ Window* Window::GetLabelFor() const // get index, form start and form end USHORT nIndex=0, nFormStart=0, nFormEnd=0; pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow, - const_cast<Window*>(this), + pLabel, nIndex, nFormStart, nFormEnd ); @@ -1139,32 +1120,39 @@ Window* Window::GetLabelFor() const return pWindow; } -// ----------------------------------------------------------------------- - -Window* Window::GetLabeledBy() const +Window* Window::GetLabelFor() const { - if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation ) + if ( mpWindowImpl->mbDisableAccessibleLabelForRelation ) return NULL; Window* pWindow = NULL; Window* pFrameWindow = ImplGetFrameWindow(); + WinBits nFrameStyle = pFrameWindow->GetStyle(); + if( ! ( nFrameStyle & WB_DIALOGCONTROL ) + || ( nFrameStyle & WB_NODIALOGCONTROL ) + ) + return NULL; + if ( mpWindowImpl->mpRealParent ) - pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this ); + pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this ); if( pWindow ) return pWindow; - // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels - if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON ) - return NULL; + sal_Unicode nAccel = getAccel( GetText() ); -// if( ! ( GetType() == WINDOW_FIXEDTEXT || -// GetType() == WINDOW_FIXEDLINE || -// GetType() == WINDOW_GROUPBOX ) ) - // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. - // See tools/options/print for example. - WindowType nMyType = GetType(); + pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel ); + if( ! pWindow && mpWindowImpl->mpRealParent ) + pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel ); + return pWindow; +} + +// ----------------------------------------------------------------------- + +static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled ) +{ + Window* pWindow = NULL; if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) ) { // search for a control that labels this window @@ -1176,16 +1164,16 @@ Window* Window::GetLabeledBy() const // get form start and form end and index of this control USHORT nIndex, nFormStart, nFormEnd; Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow, - const_cast<Window*>(this), + pLabeled, nIndex, nFormStart, nFormEnd ); if( pSWindow && nIndex != nFormStart ) { - if( GetType() == WINDOW_PUSHBUTTON || - GetType() == WINDOW_HELPBUTTON || - GetType() == WINDOW_OKBUTTON || - GetType() == WINDOW_CANCELBUTTON ) + if( nMyType == WINDOW_PUSHBUTTON || + nMyType == WINDOW_HELPBUTTON || + nMyType == WINDOW_OKBUTTON || + nMyType == WINDOW_CANCELBUTTON ) { nFormStart = nIndex-1; } @@ -1217,6 +1205,39 @@ Window* Window::GetLabeledBy() const return pWindow; } +Window* Window::GetLabeledBy() const +{ + if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation ) + return NULL; + + Window* pWindow = NULL; + Window* pFrameWindow = ImplGetFrameWindow(); + + if ( mpWindowImpl->mpRealParent ) + { + pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this ); + + if( pWindow ) + return pWindow; + } + + // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels + if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON ) + return NULL; + +// if( ! ( GetType() == WINDOW_FIXEDTEXT || +// GetType() == WINDOW_FIXEDLINE || +// GetType() == WINDOW_GROUPBOX ) ) + // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. + // See tools/options/print for example. + + pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) ); + if( ! pWindow && mpWindowImpl->mpRealParent ) + pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) ); + + return pWindow; +} + // ----------------------------------------------------------------------- KeyEvent Window::GetActivationKey() const diff --git a/vcl/source/window/dndevdis.cxx b/vcl/source/window/dndevdis.cxx index efc49be6fbf8..e4d5a8c4c0eb 100644 --- a/vcl/source/window/dndevdis.cxx +++ b/vcl/source/window/dndevdis.cxx @@ -28,8 +28,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <dndevdis.hxx> -#include <dndlcon.hxx> +#include <vcl/dndevdis.hxx> +#include <vcl/dndlcon.hxx> #include <vcl/window.h> #include <vos/mutex.hxx> diff --git a/vcl/source/window/dndevdis.hxx b/vcl/source/window/dndevdis.hxx deleted file mode 100644 index 5b91bd0713ec..000000000000 --- a/vcl/source/window/dndevdis.hxx +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************* - * - * 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 - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _DNDEVDIS_HXX_ -#define _DNDEVDIS_HXX_ - -#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp> -#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> - -#ifndef _COM_SUN_STAR_DATATRANSFER_DND_XDRAGESTURERECOGNIZER_HPP_ -#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp> -#endif -#include <cppuhelper/implbase3.hxx> -#include <vcl/window.hxx> - -class DNDEventDispatcher: public ::cppu::WeakImplHelper3< - ::com::sun::star::datatransfer::dnd::XDropTargetListener, - ::com::sun::star::datatransfer::dnd::XDropTargetDragContext, - ::com::sun::star::datatransfer::dnd::XDragGestureListener > -{ - Window * m_pTopWindow; - Window * m_pCurrentWindow; - - ::osl::Mutex m_aMutex; - ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > m_aDataFlavorList; - - /* - * fire the events on the dnd listener container of the specified window - */ - - sal_Int32 fireDragEnterEvent( Window *pWindow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& xContext, - const sal_Int8 nDropAction, const Point& rLocation, const sal_Int8 nSourceAction, - const ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor >& aFlavorList ) throw(::com::sun::star::uno::RuntimeException); - - sal_Int32 fireDragOverEvent( Window *pWindow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& xContext, - const sal_Int8 nDropAction, const Point& rLocation, const sal_Int8 nSourceAction ) throw(::com::sun::star::uno::RuntimeException); - - sal_Int32 fireDragExitEvent( Window *pWindow ) throw(::com::sun::star::uno::RuntimeException); - - sal_Int32 fireDropActionChangedEvent( Window *pWindow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& xContext, - const sal_Int8 nDropAction, const Point& rLocation, const sal_Int8 nSourceAction ) throw(::com::sun::star::uno::RuntimeException); - - sal_Int32 fireDropEvent( Window *pWindow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDropContext >& xContext, - const sal_Int8 nDropAction, const Point& rLocation, const sal_Int8 nSourceAction, - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTransferable ) throw(::com::sun::star::uno::RuntimeException); - - sal_Int32 fireDragGestureEvent( Window *pWindow, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource >& xSource, - const ::com::sun::star::uno::Any event, const Point& rOrigin, const sal_Int8 nDragAction )throw(::com::sun::star::uno::RuntimeException); - -public: - - DNDEventDispatcher( Window * pTopWindow ); - virtual ~DNDEventDispatcher(); - - /* - * XDropTargetDragContext - */ - - virtual void SAL_CALL acceptDrag( sal_Int8 dropAction ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL rejectDrag() throw(::com::sun::star::uno::RuntimeException); - - /* - * XDropTargetListener - */ - - virtual void SAL_CALL drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& dte ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL dropActionChanged( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent& dtde ) throw(::com::sun::star::uno::RuntimeException); - - /* - * XDragGestureListener - */ - - virtual void SAL_CALL dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent& dge ) throw(::com::sun::star::uno::RuntimeException); - - - /* - * XEventListener - */ - - virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& eo ) throw(::com::sun::star::uno::RuntimeException); -}; - -//================================================================================================== -// -//================================================================================================== - -#endif diff --git a/vcl/source/window/dndlcon.cxx b/vcl/source/window/dndlcon.cxx index c5d78dd6bae3..07819e76f957 100644 --- a/vcl/source/window/dndlcon.cxx +++ b/vcl/source/window/dndlcon.cxx @@ -28,7 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include<dndlcon.hxx> +#include <vcl/dndlcon.hxx> using namespace ::cppu; using namespace ::com::sun::star::uno; diff --git a/vcl/source/window/dndlcon.hxx b/vcl/source/window/dndlcon.hxx deleted file mode 100644 index 5a41a20e4271..000000000000 --- a/vcl/source/window/dndlcon.hxx +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************************* - * - * 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 - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef _DNDLCON_HXX_ -#define _DNDLCON_HXX_ - -#include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp> -#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> -#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> -#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> -#include <com/sun/star/datatransfer/dnd/XDropTargetDropContext.hpp> -#include <cppuhelper/compbase4.hxx> - -#include <vcl/unohelp2.hxx> - -class DNDListenerContainer : public ::vcl::unohelper::MutexHelper, - public ::cppu::WeakComponentImplHelper4< - ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer, \ - ::com::sun::star::datatransfer::dnd::XDropTargetDragContext, - ::com::sun::star::datatransfer::dnd::XDropTargetDropContext, - ::com::sun::star::datatransfer::dnd::XDropTarget > -{ - sal_Bool m_bActive; - sal_Int8 m_nDefaultActions; - - ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext > m_xDropTargetDragContext; - ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDropContext > m_xDropTargetDropContext; - -public: - - DNDListenerContainer( sal_Int8 nDefaultActions ); - virtual ~DNDListenerContainer(); - - sal_uInt32 fireDropEvent( - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDropContext >& context, - sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions, - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& transferable ); - - sal_uInt32 fireDragExitEvent(); - - sal_uInt32 fireDragOverEvent( - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, - sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions ); - - sal_uInt32 fireDragEnterEvent( - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, - sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions, - const ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor >& dataFlavor ); - - sal_uInt32 fireDropActionChangedEvent( - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetDragContext >& context, - sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions ); - - sal_uInt32 fireDragGestureEvent( - sal_Int8 dragAction, sal_Int32 dragOriginX, sal_Int32 dragOriginY, - const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource >& dragSource, - const ::com::sun::star::uno::Any& triggerEvent ); - - /* - * XDragGestureRecognizer - */ - - virtual void SAL_CALL addDragGestureListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureListener >& dgl ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeDragGestureListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureListener >& dgl ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL resetRecognizer( ) throw(::com::sun::star::uno::RuntimeException); - - /* - * XDropTargetDragContext - */ - - virtual void SAL_CALL acceptDrag( sal_Int8 dragOperation ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL rejectDrag( ) throw (::com::sun::star::uno::RuntimeException); - - - /* - * XDropTargetDropContext - */ - - virtual void SAL_CALL acceptDrop( sal_Int8 dropOperation ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL rejectDrop( ) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL dropComplete( sal_Bool success ) throw (::com::sun::star::uno::RuntimeException); - - /* - * XDropTarget - */ - - virtual void SAL_CALL addDropTargetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener >& dtl ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL removeDropTargetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener >& dtl ) throw(::com::sun::star::uno::RuntimeException); - virtual sal_Bool SAL_CALL isActive( ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setActive( sal_Bool active ) throw(::com::sun::star::uno::RuntimeException); - virtual sal_Int8 SAL_CALL getDefaultActions( ) throw(::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) throw(::com::sun::star::uno::RuntimeException); -}; - - -//================================================================================================== -// -//================================================================================================== - -#endif diff --git a/vcl/source/window/dockingarea.cxx b/vcl/source/window/dockingarea.cxx index 95e6c6113c45..9ea407e52ee3 100644 --- a/vcl/source/window/dockingarea.cxx +++ b/vcl/source/window/dockingarea.cxx @@ -152,23 +152,21 @@ void DockingAreaWindow::Paint( const Rectangle& ) EnableNativeWidget( TRUE ); // only required because the toolkit curently switches this flag off if( IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) ) { - ImplControlValue aControlValue; - ToolbarValue aToolbarValue; + ToolbarValue aControlValue; if( GetAlign() == WINDOWALIGN_TOP && ImplGetSVData()->maNWFData.mbMenuBarDockingAreaCommonBG ) { // give NWF a hint that this dockingarea is adjacent to the menubar // useful for special gradient effects that should cover both windows - aToolbarValue.mbIsTopDockingArea = TRUE; + aControlValue.mbIsTopDockingArea = TRUE; } - aControlValue.setOptionalVal( (void *)(&aToolbarValue) ); ControlState nState = CTRL_STATE_ENABLED; if( !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB ) { // draw a single toolbar background covering the whole docking area Point tmp; - Region aCtrlRegion( Rectangle( tmp, GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( tmp, GetOutputSizePixel() ); DrawNativeControl( CTRL_TOOLBAR, IsHorizontal() ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT, aCtrlRegion, nState, aControlValue, rtl::OUString() ); @@ -231,7 +229,7 @@ void DockingAreaWindow::Paint( const Rectangle& ) aTBRect.Bottom() = aOutSz.Height() - 1; } DrawNativeControl( CTRL_TOOLBAR, IsHorizontal() ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT, - Region( aTBRect), nState, aControlValue, rtl::OUString() ); + aTBRect, nState, aControlValue, rtl::OUString() ); } } } diff --git a/vcl/source/window/javachild.cxx b/vcl/source/window/javachild.cxx index 2cd18b897ff5..aa198c85c138 100644 --- a/vcl/source/window/javachild.cxx +++ b/vcl/source/window/javachild.cxx @@ -2,10 +2,13 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: javachild.cxx,v $ + * $Revision: 1.12 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -28,32 +31,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" - -#ifdef SOLAR_JAVA -#include <jni.h> -#endif -#include <comphelper/processfactory.hxx> - -#include <vcl/unohelp.hxx> -#include <rtl/process.h> -#include <rtl/ref.hxx> -#include <jvmaccess/virtualmachine.hxx> -#include <com/sun/star/java/XJavaVM.hpp> -#include <com/sun/star/java/XJavaThreadRegister_11.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> - -#ifndef _SV_SVSYS_HXX -#include <svsys.h> -#endif -#include <vcl/salinst.hxx> -#include <vcl/salframe.hxx> -#include <vcl/window.hxx> -#include <vcl/salobj.hxx> #include <vcl/javachild.hxx> -#include <vcl/svdata.hxx> -#include <vcl/sysdata.hxx> - -using namespace ::com::sun::star; // ------------------- // - JavaChildWindow - @@ -79,129 +57,7 @@ JavaChildWindow::~JavaChildWindow() // ----------------------------------------------------------------------- -void JavaChildWindow::implTestJavaException( void* pEnv ) -{ -#ifdef SOLAR_JAVA - JNIEnv* pJavaEnv = reinterpret_cast< JNIEnv* >( pEnv ); - jthrowable jtThrowable = pJavaEnv->ExceptionOccurred(); - - if( jtThrowable ) - { // is it a java exception ? -#if OSL_DEBUG_LEVEL > 1 - pJavaEnv->ExceptionDescribe(); -#endif // OSL_DEBUG_LEVEL > 1 - pJavaEnv->ExceptionClear(); - - jclass jcThrowable = pJavaEnv->FindClass("java/lang/Throwable"); - jmethodID jmThrowable_getMessage = pJavaEnv->GetMethodID(jcThrowable, "getMessage", "()Ljava/lang/String;"); - jstring jsMessage = (jstring) pJavaEnv->CallObjectMethod(jtThrowable, jmThrowable_getMessage); - ::rtl::OUString ouMessage; - - if(jsMessage) - { - const jchar * jcMessage = pJavaEnv->GetStringChars(jsMessage, NULL); - ouMessage = ::rtl::OUString(jcMessage); - pJavaEnv->ReleaseStringChars(jsMessage, jcMessage); - } - - throw uno::RuntimeException(ouMessage, uno::Reference<uno::XInterface>()); - } -#endif // SOLAR_JAVA -} - -// ----------------------------------------------------------------------- - sal_IntPtr JavaChildWindow::getParentWindowHandleForJava() { - sal_IntPtr nRet = 0; - -#if defined WNT - nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->hWnd ); -#elif defined QUARTZ - // FIXME: this is wrong - nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->pView ); -#elif defined UNX -#ifdef SOLAR_JAVA - uno::Reference< lang::XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() ); - - if( xFactory.is() && ( GetSystemData()->aWindow > 0 ) ) - { - try - { - ::rtl::Reference< ::jvmaccess::VirtualMachine > xVM; - uno::Reference< java::XJavaVM > xJavaVM( xFactory->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine") ) ), uno::UNO_QUERY ); - uno::Sequence< sal_Int8 > aProcessID( 17 ); - - rtl_getGlobalProcessId( (sal_uInt8*) aProcessID.getArray() ); - aProcessID[ 16 ] = 0; - OSL_ENSURE(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *), "Pointer cannot be represented as sal_Int64"); - sal_Int64 nPointer = reinterpret_cast< sal_Int64 >( static_cast< jvmaccess::VirtualMachine * >(0)); - xJavaVM->getJavaVM(aProcessID) >>= nPointer; - xVM = reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer); - - if( xVM.is() ) - { - try - { - ::jvmaccess::VirtualMachine::AttachGuard aVMAttachGuard( xVM ); - JNIEnv* pEnv = aVMAttachGuard.getEnvironment(); - - jclass jcToolkit = pEnv->FindClass("java/awt/Toolkit"); - implTestJavaException(pEnv); - - jmethodID jmToolkit_getDefaultToolkit = pEnv->GetStaticMethodID( jcToolkit, "getDefaultToolkit", "()Ljava/awt/Toolkit;" ); - implTestJavaException(pEnv); - - pEnv->CallStaticObjectMethod(jcToolkit, jmToolkit_getDefaultToolkit); - implTestJavaException(pEnv); - - jclass jcMotifAppletViewer = pEnv->FindClass("sun/plugin/navig/motif/MotifAppletViewer"); - if( pEnv->ExceptionOccurred() ) - { - pEnv->ExceptionClear(); - - jcMotifAppletViewer = pEnv->FindClass( "sun/plugin/viewer/MNetscapePluginContext"); - implTestJavaException(pEnv); - } - - jclass jcClassLoader = pEnv->FindClass("java/lang/ClassLoader"); - implTestJavaException(pEnv); - - jmethodID jmClassLoader_loadLibrary = pEnv->GetStaticMethodID( jcClassLoader, "loadLibrary", "(Ljava/lang/Class;Ljava/lang/String;Z)V"); - implTestJavaException(pEnv); - - jstring jsplugin = pEnv->NewStringUTF("javaplugin_jni"); - implTestJavaException(pEnv); - - pEnv->CallStaticVoidMethod(jcClassLoader, jmClassLoader_loadLibrary, jcMotifAppletViewer, jsplugin, JNI_FALSE); - implTestJavaException(pEnv); - - jmethodID jmMotifAppletViewer_getWidget = pEnv->GetStaticMethodID( jcMotifAppletViewer, "getWidget", "(IIIII)I" ); - implTestJavaException(pEnv); - - const Size aSize( GetOutputSizePixel() ); - jint ji_widget = pEnv->CallStaticIntMethod( jcMotifAppletViewer, jmMotifAppletViewer_getWidget, - GetSystemData()->aWindow, 0, 0, aSize.Width(), aSize.Height() ); - implTestJavaException(pEnv); - - nRet = static_cast< sal_IntPtr >( ji_widget ); - } - catch( uno::RuntimeException& ) - { - } - - if( !nRet ) - nRet = static_cast< sal_IntPtr >( GetSystemData()->aWindow ); - } - } - catch( ... ) - { - } - } -#endif // SOLAR_JAVA -#else // WNT || QUARTZ || UNX - // TBD -#endif - - return nRet; + return SystemChildWindow::GetParentWindowHandle( sal_True ); } diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk index 82ce26f8e78e..1c63376dfda5 100644 --- a/vcl/source/window/makefile.mk +++ b/vcl/source/window/makefile.mk @@ -85,6 +85,8 @@ SLOFILES= \ $(SLO)$/winproc.obj \ $(SLO)$/window2.obj \ $(SLO)$/window3.obj \ + $(SLO)$/window4.obj \ + $(SLO)$/wpropset.obj \ $(SLO)$/wrkwin.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index cebe1d1f596c..5909ab9f8489 100644..100755 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -96,6 +96,7 @@ DBG_NAME( Menu ) #define EXTRASPACEY 2 #define EXTRAITEMHEIGHT 4 +#define GUTTERBORDER 8 // document closer #define IID_DOCUMENTCLOSE 1 @@ -157,7 +158,7 @@ struct MenuItemData XubString aTipHelpText; // TipHelp-String (eg, expanded filenames) XubString aCommandStr; // CommandString XubString aHelpCommandStr; // Help command string (to reference external help) - ULONG nHelpId; // Help-Id + rtl::OString aHelpId; // Help-Id ULONG nUserValue; // User value Image aImage; // Image KeyCode aAccelKey; // Accelerator-Key @@ -252,7 +253,6 @@ MenuItemData* MenuItemList::Insert( USHORT nId, MenuItemType eType, pData->nBits = nBits; pData->pSubMenu = NULL; pData->pAutoSubMenu = NULL; - pData->nHelpId = 0; pData->nUserValue = 0; pData->bChecked = FALSE; pData->bEnabled = TRUE; @@ -284,7 +284,6 @@ void MenuItemList::InsertSeparator( USHORT nPos ) pData->nBits = 0; pData->pSubMenu = NULL; pData->pAutoSubMenu = NULL; - pData->nHelpId = 0; pData->nUserValue = 0; pData->bChecked = FALSE; pData->bEnabled = TRUE; @@ -844,14 +843,14 @@ static BOOL ImplHandleHelpEvent( Window* pMenuWindow, Menu* pMenu, USHORT nHighl // Ist eine ID vorhanden, dann Hilfe mit der ID aufrufen, sonst // den Hilfe-Index String aCommand = pMenu->GetItemCommand( nId ); - ULONG nHelpId = pMenu->GetHelpId( nId ); + rtl::OString aHelpId( pMenu->GetHelpId( nId ) ); + if( ! aHelpId.getLength() ) + aHelpId = OOO_HELP_INDEX; if ( aCommand.Len() ) pHelp->Start( aCommand, NULL ); - else if ( nHelpId ) - pHelp->Start( nHelpId, NULL ); else - pHelp->Start( OOO_HELP_INDEX, NULL ); + pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), NULL ); } bDone = TRUE; } @@ -938,6 +937,14 @@ Menu::~Menu() if ( nEventId ) Application::RemoveUserEvent( nEventId ); + // Notify deletion of this menu + ImplMenuDelData* pDelData = mpFirstDel; + while ( pDelData ) + { + pDelData->mpMenu = NULL; + pDelData = pDelData->mpNext; + } + bKilled = TRUE; delete pItemList; @@ -970,9 +977,9 @@ void Menu::ImplInit() bInCallback = FALSE; bKilled = FALSE; mpLayoutData = NULL; - + mpFirstDel = NULL; // Dtor notification list // Native-support: returns NULL if not supported - mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu( bIsMenuBar ); + mpSalMenu = ImplGetSVData()->mpDefInst->CreateMenu( bIsMenuBar, this ); } Menu* Menu::ImplGetStartedFrom() const @@ -1034,19 +1041,29 @@ void Menu::CreateAutoMnemonics() void Menu::Activate() { bInCallback = TRUE; + + ImplMenuDelData aDelData( this ); + ImplCallEventListeners( VCLEVENT_MENU_ACTIVATE, ITEMPOS_INVALID ); - if ( !aActivateHdl.Call( this ) ) + + if( !aDelData.isDeleted() ) { - Menu* pStartMenu = ImplGetStartMenu(); - if ( pStartMenu && ( pStartMenu != this ) ) + if ( !aActivateHdl.Call( this ) ) { - pStartMenu->bInCallback = TRUE; - // MT 11/01: Call EventListener here? I don't know... - pStartMenu->aActivateHdl.Call( this ); - pStartMenu->bInCallback = FALSE; + if( !aDelData.isDeleted() ) + { + Menu* pStartMenu = ImplGetStartMenu(); + if ( pStartMenu && ( pStartMenu != this ) ) + { + pStartMenu->bInCallback = TRUE; + // MT 11/01: Call EventListener here? I don't know... + pStartMenu->aActivateHdl.Call( this ); + pStartMenu->bInCallback = FALSE; + } + } } + bInCallback = FALSE; } - bInCallback = FALSE; } void Menu::Deactivate() @@ -1059,33 +1076,49 @@ void Menu::Deactivate() } bInCallback = TRUE; + + ImplMenuDelData aDelData( this ); + Menu* pStartMenu = ImplGetStartMenu(); ImplCallEventListeners( VCLEVENT_MENU_DEACTIVATE, ITEMPOS_INVALID ); - if ( !aDeactivateHdl.Call( this ) ) + + if( !aDelData.isDeleted() ) { - if ( pStartMenu && ( pStartMenu != this ) ) + if ( !aDeactivateHdl.Call( this ) ) { - pStartMenu->bInCallback = TRUE; - pStartMenu->aDeactivateHdl.Call( this ); - pStartMenu->bInCallback = FALSE; + if( !aDelData.isDeleted() ) + { + if ( pStartMenu && ( pStartMenu != this ) ) + { + pStartMenu->bInCallback = TRUE; + pStartMenu->aDeactivateHdl.Call( this ); + pStartMenu->bInCallback = FALSE; + } + } } } - bInCallback = FALSE; - if ( this == pStartMenu ) - GetpApp()->HideHelpStatusText(); + if( !aDelData.isDeleted() ) + { + bInCallback = FALSE; + + if ( this == pStartMenu ) + GetpApp()->HideHelpStatusText(); + } } void Menu::Highlight() { + ImplMenuDelData aDelData( this ); + Menu* pStartMenu = ImplGetStartMenu(); - if ( !aHighlightHdl.Call( this ) ) + if ( !aHighlightHdl.Call( this ) && !aDelData.isDeleted() ) { if ( pStartMenu && ( pStartMenu != this ) ) pStartMenu->aHighlightHdl.Call( this ); } - if ( GetCurItemId() ) + if ( !aDelData.isDeleted() && GetCurItemId() ) GetpApp()->ShowHelpStatusText( GetHelpText( GetCurItemId() ) ); } @@ -1112,14 +1145,19 @@ void Menu::ImplSelect() void Menu::Select() { + ImplMenuDelData aDelData( this ); + ImplCallEventListeners( VCLEVENT_MENU_SELECT, GetItemPos( GetCurItemId() ) ); - if ( !aSelectHdl.Call( this ) ) + if ( !aDelData.isDeleted() && !aSelectHdl.Call( this ) ) { - Menu* pStartMenu = ImplGetStartMenu(); - if ( pStartMenu && ( pStartMenu != this ) ) + if( !aDelData.isDeleted() ) { - pStartMenu->nSelectedId = nSelectedId; - pStartMenu->aSelectHdl.Call( this ); + Menu* pStartMenu = ImplGetStartMenu(); + if ( pStartMenu && ( pStartMenu != this ) ) + { + pStartMenu->nSelectedId = nSelectedId; + pStartMenu->aSelectHdl.Call( this ); + } } } } @@ -1141,6 +1179,8 @@ void Menu::RequestHelp( const HelpEvent& ) void Menu::ImplCallEventListeners( ULONG nEvent, USHORT nPos ) { + ImplMenuDelData aDelData( this ); + VclMenuEvent aEvent( this, nEvent, nPos ); // This is needed by atk accessibility bridge @@ -1149,16 +1189,22 @@ void Menu::ImplCallEventListeners( ULONG nEvent, USHORT nPos ) ImplGetSVData()->mpApp->ImplCallEventListeners( &aEvent ); } - if ( !maEventListeners.empty() ) + if ( !aDelData.isDeleted() && !maEventListeners.empty() ) maEventListeners.Call( &aEvent ); - Menu* pMenu = this; - while ( pMenu ) + if( !aDelData.isDeleted() ) { - if ( !maChildEventListeners.empty() ) - maChildEventListeners.Call( &aEvent ); + Menu* pMenu = this; + while ( pMenu ) + { + if ( !maChildEventListeners.empty() ) + maChildEventListeners.Call( &aEvent ); - pMenu = ( pMenu->pStartedFrom != pMenu ) ? pMenu->pStartedFrom : NULL; + if( aDelData.isDeleted() ) + break; + + pMenu = ( pMenu->pStartedFrom != pMenu ) ? pMenu->pStartedFrom : NULL; + } } } @@ -1283,15 +1329,14 @@ void Menu::InsertItem( const ResId& rResId, USHORT nPos ) SetHelpText( nItemId, aHelpText ); } - ULONG nHelpId = 0; if ( nObjMask & RSC_MENUITEM_HELPID ) { - nHelpId = ReadLongRes(); + rtl::OString aHelpId( ReadByteStringRes() ); if ( !bSep ) - SetHelpId( nItemId, nHelpId ); + SetHelpId( nItemId, aHelpId ); } - if( !bSep /* && SvHelpSettings::HelpText( aHelpText, nHelpId ) */ ) + if( !bSep ) SetHelpText( nItemId, aHelpText ); if ( nObjMask & RSC_MENUITEM_KEYCODE ) @@ -1416,7 +1461,7 @@ void ImplCopyItem( Menu* pThis, const Menu& rMenu, USHORT nPos, USHORT nNewPos, pThis->CheckItem( nId, TRUE ); if ( !rMenu.IsItemEnabled( nId ) ) pThis->EnableItem( nId, FALSE ); - pThis->SetHelpId( nId, pData->nHelpId ); + pThis->SetHelpId( nId, pData->aHelpId ); pThis->SetHelpText( nId, pData->aHelpText ); pThis->SetAccelKey( nId, pData->aAccelKey ); pThis->SetItemCommand( nId, pData->aCommandStr ); @@ -1992,7 +2037,7 @@ const XubString& Menu::ImplGetHelpText( USHORT nItemId ) const if ( pData ) { if ( !pData->aHelpText.Len() && - (( pData->nHelpId ) || ( pData->aCommandStr.Len() ))) + (( pData->aHelpId.getLength() ) || ( pData->aCommandStr.Len() ))) { Help* pHelp = Application::GetHelp(); if ( pHelp ) @@ -2000,8 +2045,8 @@ const XubString& Menu::ImplGetHelpText( USHORT nItemId ) const if ( pData->aCommandStr.Len() ) pData->aHelpText = pHelp->GetHelpText( pData->aCommandStr, NULL ); - if( !pData->aHelpText.Len() && pData->nHelpId ) - pData->aHelpText = pHelp->GetHelpText( pData->nHelpId, NULL ); + if( !pData->aHelpText.Len() && pData->aHelpId.getLength() ) + pData->aHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pData->aHelpId, RTL_TEXTENCODING_UTF8 ), NULL ); } } @@ -2034,22 +2079,29 @@ const XubString& Menu::GetTipHelpText( USHORT nItemId ) const return ImplGetSVEmptyStr(); } -void Menu::SetHelpId( USHORT nItemId, ULONG nHelpId ) +void Menu::SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ) { MenuItemData* pData = pItemList->GetData( nItemId ); if ( pData ) - pData->nHelpId = nHelpId; + pData->aHelpId = rHelpId; } -ULONG Menu::GetHelpId( USHORT nItemId ) const +rtl::OString Menu::GetHelpId( USHORT nItemId ) const { + rtl::OString aRet; + MenuItemData* pData = pItemList->GetData( nItemId ); if ( pData ) - return pData->nHelpId; - else - return 0; + { + if ( pData->aHelpId.getLength() ) + aRet = pData->aHelpId; + else + aRet = ::rtl::OUStringToOString( pData->aCommandStr, RTL_TEXTENCODING_UTF8 ); + } + + return aRet; } Menu& Menu::operator=( const Menu& rMenu ) @@ -2221,10 +2273,10 @@ long Menu::ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, lon if( ! bIsMenuBar ) { ImplControlValue aVal; - Region aNativeBounds; - Region aNativeContent; + Rectangle aNativeBounds; + Rectangle aNativeContent; Point tmp( 0, 0 ); - Region aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) ); + Rectangle aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) ); if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) ) { if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP), @@ -2237,8 +2289,8 @@ long Menu::ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, lon aNativeContent ) ) { - rCheckHeight = aNativeBounds.GetBoundRect().GetHeight(); - rMaxWidth = aNativeContent.GetBoundRect().GetWidth(); + rCheckHeight = aNativeBounds.GetHeight(); + rMaxWidth = aNativeContent.GetWidth(); } } if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) ) @@ -2253,14 +2305,50 @@ long Menu::ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, lon aNativeContent ) ) { - rRadioHeight = aNativeBounds.GetBoundRect().GetHeight(); - rMaxWidth = Max (rMaxWidth, aNativeContent.GetBoundRect().GetWidth()); + rRadioHeight = aNativeBounds.GetHeight(); + rMaxWidth = Max (rMaxWidth, aNativeContent.GetWidth()); } } } return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight; } +// ----------------------------------------------------------------------- + +void Menu::ImplAddDel( ImplMenuDelData& rDel ) +{ + DBG_ASSERT( !rDel.mpMenu, "Menu::ImplAddDel(): cannot add ImplMenuDelData twice !" ); + if( !rDel.mpMenu ) + { + rDel.mpMenu = this; + rDel.mpNext = mpFirstDel; + mpFirstDel = &rDel; + } +} + +// ----------------------------------------------------------------------- + +void Menu::ImplRemoveDel( ImplMenuDelData& rDel ) +{ + rDel.mpMenu = NULL; + if ( mpFirstDel == &rDel ) + { + mpFirstDel = rDel.mpNext; + } + else + { + ImplMenuDelData* pData = mpFirstDel; + while ( pData && (pData->mpNext != &rDel) ) + pData = pData->mpNext; + + DBG_ASSERT( pData, "Menu::ImplRemoveDel(): ImplMenuDelData not registered !" ); + if( pData ) + pData->mpNext = rDel.mpNext; + } +} + +// ----------------------------------------------------------------------- + Size Menu::ImplCalcSize( Window* pWin ) { // | Checked| Image| Text| Accel/Popup| @@ -2397,6 +2485,16 @@ Size Menu::ImplCalcSize( Window* pWin ) if ( !bIsMenuBar ) { + // popup menus should not be wider than half the screen + // except on rather small screens + // TODO: move GetScreenNumber from SystemWindow to Window ? + // currently we rely on internal privileges + unsigned int nScreenNumber = pWin->ImplGetWindowImpl()->mpFrame->maGeometry.nScreenNumber; + Rectangle aDispRect( Application::GetScreenPosSizePixel( nScreenNumber ) ); + long nScreenWidth = aDispRect.GetWidth() >= 800 ? aDispRect.GetWidth() : 800; + if( nMaxWidth > nScreenWidth/2 ) + nMaxWidth = nScreenWidth/2; + USHORT gfxExtra = (USHORT) Max( nExtra, 7L ); // #107710# increase space between checkmarks/images/text nCheckPos = (USHORT)nExtra; if (nMenuFlags & MENU_FLAG_SHOWCHECKIMAGES) @@ -2433,10 +2531,10 @@ Size Menu::ImplCalcSize( Window* pWin ) if( pWindow->IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) ) { ImplControlValue aVal; - Region aNativeBounds; - Region aNativeContent; + Rectangle aNativeBounds; + Rectangle aNativeContent; Point tmp( 0, 0 ); - Region aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) ); + Rectangle aCtrlRegion( tmp, Size( 100, 15 ) ); if( pWindow->GetNativeControlRegion( ControlType(CTRL_MENUBAR), ControlPart(PART_ENTIRE_CONTROL), aCtrlRegion, @@ -2447,7 +2545,7 @@ Size Menu::ImplCalcSize( Window* pWin ) aNativeContent ) ) { - int nNativeHeight = aNativeBounds.GetBoundRect().GetHeight(); + int nNativeHeight = aNativeBounds.GetHeight(); if( nNativeHeight > aSz.Height() ) aSz.Height() = nNativeHeight; } @@ -2472,7 +2570,7 @@ static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRec if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) ) { ImplControlValue aControlValue; - Region aCtrlRegion( i_rRect ); + Rectangle aCtrlRegion( i_rRect ); ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED; aControlValue.setTristateVal( BUTTONVALUE_ON ); @@ -2490,6 +2588,26 @@ static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRec } } +static String getShortenedString( const String& i_rLong, Window* i_pWin, long i_nMaxWidth ) +{ + xub_StrLen nPos = STRING_NOTFOUND; + String aNonMnem( OutputDevice::GetNonMnemonicString( i_rLong, nPos ) ); + aNonMnem = i_pWin->GetEllipsisString( aNonMnem, i_nMaxWidth, TEXT_DRAW_CENTERELLIPSIS ); + // re-insert mnemonic + if( nPos != STRING_NOTFOUND ) + { + if( nPos < aNonMnem.Len() && i_rLong.GetChar(nPos+1) == aNonMnem.GetChar(nPos) ) + { + rtl::OUStringBuffer aBuf( i_rLong.Len() ); + aBuf.append( aNonMnem.GetBuffer(), nPos ); + aBuf.append( sal_Unicode('~') ); + aBuf.append( aNonMnem.GetBuffer()+nPos ); + aNonMnem = aBuf.makeStringAndClear(); + } + } + return aNonMnem; +} + void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* pThisItemOnly, BOOL bHighlighted, bool bLayout ) const { // Fuer Symbole: nFontHeight x nFontHeight @@ -2553,14 +2671,36 @@ void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* // Separator if ( !bLayout && !bIsMenuBar && ( pData->eType == MENUITEM_SEPARATOR ) ) { - aTmpPos.Y() = aPos.Y() + ((pData->aSz.Height()-2)/2); - aTmpPos.X() = aPos.X() + 2 + nOuterSpace; - pWin->SetLineColor( rSettings.GetShadowColor() ); - pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); - aTmpPos.Y()++; - pWin->SetLineColor( rSettings.GetLightColor() ); - pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); - pWin->SetLineColor(); + bool bNativeOk = false; + if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, + PART_MENU_SEPARATOR ) ) + { + ControlState nState = 0; + if ( pData->bEnabled ) + nState |= CTRL_STATE_ENABLED; + if ( bHighlighted ) + nState |= CTRL_STATE_SELECTED; + Size aSz( pData->aSz ); + aSz.Width() = aOutSz.Width() - 2*nOuterSpace; + Rectangle aItemRect( aPos, aSz ); + MenupopupValue aVal( nTextPos-GUTTERBORDER, aItemRect ); + bNativeOk = pWin->DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_SEPARATOR, + aItemRect, + nState, + aVal, + OUString() ); + } + if( ! bNativeOk ) + { + aTmpPos.Y() = aPos.Y() + ((pData->aSz.Height()-2)/2); + aTmpPos.X() = aPos.X() + 2 + nOuterSpace; + pWin->SetLineColor( rSettings.GetShadowColor() ); + pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); + aTmpPos.Y()++; + pWin->SetLineColor( rSettings.GetLightColor() ); + pWin->DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); + pWin->SetLineColor(); + } } Rectangle aOuterCheckRect( Point( aPos.X()+nCheckPos, aPos.Y() ), Size( pData->aSz.Height(), pData->aSz.Height() ) ); @@ -2605,10 +2745,11 @@ void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2; Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) ); + MenupopupValue aVal( nTextPos-GUTTERBORDER, Rectangle( aPos, pData->aSz ) ); pWin->DrawNativeControl( CTRL_MENU_POPUP, nPart, - Region( aCheckRect ), + aCheckRect, nState, - ImplControlValue(), + aVal, OUString() ); } else if ( pData->bChecked ) // by default do nothing for unchecked items @@ -2680,7 +2821,19 @@ void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* pWin->GetSettings().GetStyleSettings().GetMenuColor(); pWin->SetBackground( Wallpaper( aBg ) ); } - pWin->DrawCtrlText( aTmpPos, pData->aText, 0, pData->aText.Len(), nStyle, pVector, pDisplayText ); + // how much space is there for the text ? + long nMaxItemTextWidth = aOutSz.Width() - aTmpPos.X() - nExtra - nOuterSpace; + if( !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() ) + { + XubString aAccText = pData->aAccelKey.GetName(); + nMaxItemTextWidth -= pWin->GetTextWidth( aAccText ) + 3*nExtra; + } + if( !bIsMenuBar && pData->pSubMenu ) + { + nMaxItemTextWidth -= nFontHeight - nExtra; + } + String aItemText( getShortenedString( pData->aText, pWin, nMaxItemTextWidth ) ); + pWin->DrawCtrlText( aTmpPos, aItemText, 0, aItemText.Len(), nStyle, pVector, pDisplayText ); if( bSetTmpBackground ) pWin->SetBackground(); } @@ -2716,16 +2869,6 @@ void Menu::ImplPaint( Window* pWin, USHORT nBorder, long nStartY, MenuItemData* aDecoView.DrawSymbol( Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ), SYMBOL_SPIN_RIGHT, pWin->GetTextColor(), nSymbolStyle ); -// if ( pData->nBits & MIB_POPUPSELECT ) -// { -// aTmpPos.Y() += nFontHeight/2 ; -// pWin->SetLineColor( rSettings.GetShadowColor() ); -// pWin->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) ); -// pWin->SetLineColor( rSettings.GetLightColor() ); -// aTmpPos.Y()++; -// pWin->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) ); -// pWin->SetLineColor(); -// } } if ( pThisItemOnly && bHighlighted ) @@ -2790,13 +2933,19 @@ Menu* Menu::ImplGetStartMenu() void Menu::ImplCallHighlight( USHORT nHighlightedItem ) { + ImplMenuDelData aDelData( this ); + nSelectedId = 0; MenuItemData* pData = pItemList->GetDataFromPos( nHighlightedItem ); if ( pData ) nSelectedId = pData->nId; ImplCallEventListeners( VCLEVENT_MENU_HIGHLIGHT, GetItemPos( GetCurItemId() ) ); - Highlight(); - nSelectedId = 0; + + if( !aDelData.isDeleted() ) + { + Highlight(); + nSelectedId = 0; + } } IMPL_LINK( Menu, ImplCallSelect, Menu*, EMPTYARG ) @@ -3292,10 +3441,14 @@ BOOL MenuBar::HandleMenuActivateEvent( Menu *pMenu ) const { if( pMenu ) { + ImplMenuDelData aDelData( this ); + pMenu->pStartedFrom = (Menu*)this; pMenu->bInCallback = TRUE; pMenu->Activate(); - pMenu->bInCallback = FALSE; + + if( !aDelData.isDeleted() ) + pMenu->bInCallback = FALSE; } return TRUE; } @@ -3304,10 +3457,13 @@ BOOL MenuBar::HandleMenuDeActivateEvent( Menu *pMenu ) const { if( pMenu ) { + ImplMenuDelData aDelData( this ); + pMenu->pStartedFrom = (Menu*)this; pMenu->bInCallback = TRUE; pMenu->Deactivate(); - pMenu->bInCallback = FALSE; + if( !aDelData.isDeleted() ) + pMenu->bInCallback = FALSE; } return TRUE; } @@ -3318,13 +3474,18 @@ BOOL MenuBar::HandleMenuHighlightEvent( Menu *pMenu, USHORT nHighlightEventId ) pMenu = ((Menu*) this)->ImplFindMenu( nHighlightEventId ); if( pMenu ) { + ImplMenuDelData aDelData( pMenu ); + if( mnHighlightedItemPos != ITEMPOS_INVALID ) pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, mnHighlightedItemPos ); - pMenu->mnHighlightedItemPos = pMenu->GetItemPos( nHighlightEventId ); - pMenu->nSelectedId = nHighlightEventId; - pMenu->pStartedFrom = (Menu*)this; - pMenu->ImplCallHighlight( pMenu->mnHighlightedItemPos ); + if( !aDelData.isDeleted() ) + { + pMenu->mnHighlightedItemPos = pMenu->GetItemPos( nHighlightEventId ); + pMenu->nSelectedId = nHighlightEventId; + pMenu->pStartedFrom = (Menu*)this; + pMenu->ImplCallHighlight( pMenu->mnHighlightedItemPos ); + } return TRUE; } else @@ -3621,7 +3782,7 @@ USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupM if ( GetItemCount() ) { SalMenu* pMenu = ImplGetSalMenu(); - if( pMenu && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS ) ) + if( pMenu && bRealExecute && pMenu->ShowNativePopupMenu( pWin, aRect, nPopupModeFlags | FLOATWIN_POPUPMODE_GRABFOCUS ) ) { pWin->StopExecute(0); pWin->doShutdown(); @@ -4577,19 +4738,20 @@ void MenuFloatingWindow::HighlightItem( USHORT nPos, BOOL bHighlight ) Push( PUSH_CLIPREGION ); IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) ) ); Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) ); + MenupopupValue aVal( pMenu->nTextPos-GUTTERBORDER, aItemRect ); DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, - Region( aCtrlRect ), + aCtrlRect, CTRL_STATE_ENABLED, - ImplControlValue(), + aVal, OUString() ); if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) ) { bDrawItemRect = false; if( FALSE == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM, - Region( aItemRect ), + aItemRect, CTRL_STATE_SELECTED | ( pData->bEnabled? CTRL_STATE_ENABLED: 0 ), - ImplControlValue(), + aVal, OUString() ) ) { bDrawItemRect = bHighlight; @@ -4924,10 +5086,11 @@ void MenuFloatingWindow::Paint( const Rectangle& ) long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0; Size aPxSize( GetOutputSizePixel() ); aPxSize.Width() -= nX; + ImplControlValue aVal( pMenu->nTextPos-GUTTERBORDER ); DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, - Region( Rectangle( Point( nX, 0 ), aPxSize ) ), + Rectangle( Point( nX, 0 ), aPxSize ), CTRL_STATE_ENABLED, - ImplControlValue(), + aVal, OUString() ); ImplInitClipRegion(); } @@ -5439,23 +5602,21 @@ void MenuBarWindow::HighlightItem( USHORT nPos, BOOL bHighlight ) IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL ) ) { // draw background (transparency) - ImplControlValue aControlValue; - MenubarValue aMenubarValue; - aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - aControlValue.setOptionalVal( (void *)(&aMenubarValue) ); + MenubarValue aControlValue; + aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); Point tmp(0,0); - Region aBgRegion( Rectangle( tmp, GetOutputSizePixel() ) ); + Rectangle aBgRegion( tmp, GetOutputSizePixel() ); DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aBgRegion, CTRL_STATE_ENABLED, aControlValue, OUString() ); - ImplAddNWFSeparator( this, aMenubarValue ); + ImplAddNWFSeparator( this, aControlValue ); // draw selected item DrawNativeControl( CTRL_MENUBAR, PART_MENU_ITEM, - Region( aRect ), + aRect, CTRL_STATE_ENABLED | CTRL_STATE_SELECTED, aControlValue, OUString() ); @@ -5471,18 +5632,15 @@ void MenuBarWindow::HighlightItem( USHORT nPos, BOOL bHighlight ) { if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) ) { - ImplControlValue aControlValue; MenubarValue aMenubarValue; aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - aControlValue.setOptionalVal( (void *)(&aMenubarValue) ); // use full window size to get proper gradient // but clip accordingly Point aPt; Rectangle aCtrlRect( aPt, GetOutputSizePixel() ); - Region aCtrlRegion( aCtrlRect ); - DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString() ); + DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED, aMenubarValue, rtl::OUString() ); ImplAddNWFSeparator( this, aMenubarValue ); } else @@ -5713,14 +5871,12 @@ void MenuBarWindow::Paint( const Rectangle& ) if( IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) ) { Point aPt; - Region aCtrlRegion( Rectangle( aPt, GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aPt, GetOutputSizePixel() ); - ImplControlValue aControlValue; MenubarValue aMenubarValue; aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this ); - aControlValue.setOptionalVal( (void *)(&aMenubarValue) ); - DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString() ); + DrawNativeControl( CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aMenubarValue, rtl::OUString() ); ImplAddNWFSeparator( this, aMenubarValue ); } SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() ); @@ -5989,3 +6145,17 @@ bool MenuBarWindow::HandleMenuButtonEvent( USHORT i_nButtonId ) } return FALSE; } + +ImplMenuDelData::ImplMenuDelData( const Menu* pMenu ) +: mpNext( 0 ) +, mpMenu( 0 ) +{ + if( pMenu ) + const_cast< Menu* >( pMenu )->ImplAddDel( *this ); +} + +ImplMenuDelData::~ImplMenuDelData() +{ + if( mpMenu ) + const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this ); +} diff --git a/vcl/source/window/msgbox.cxx b/vcl/source/window/msgbox.cxx index 7f7a65cd7fb9..d00d569883d5 100644 --- a/vcl/source/window/msgbox.cxx +++ b/vcl/source/window/msgbox.cxx @@ -196,10 +196,9 @@ MessBox::MessBox( Window* pParent, const ResId& rResId ) : USHORT nLoButtons = ReadShortRes(); USHORT nHiDefButton = ReadShortRes(); USHORT nLoDefButton = ReadShortRes(); - USHORT nHiHelpId = ReadShortRes(); - USHORT nLoHelpId = ReadShortRes(); + rtl::OString aHelpId( ReadByteStringRes() ); /* USHORT bSysModal = */ ReadShortRes(); - SetHelpId( ((ULONG)nHiHelpId << 16) + nLoHelpId ); + SetHelpId( aHelpId ); WinBits nBits = (((ULONG)nHiButtons << 16) + nLoButtons) | (((ULONG)nHiDefButton << 16) + nLoDefButton); ImplInit( pParent, nBits | WB_MOVEABLE | WB_HORZ | WB_CENTER ); @@ -233,7 +232,7 @@ MessBox::~MessBox() void MessBox::ImplPosControls() { - if ( GetHelpId() ) + if ( GetHelpId().getLength() ) { if ( !mbHelpBtn ) { diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 35077b1cff0e..574cef4e5a07 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -46,7 +46,7 @@ #include "unotools/localedatawrapper.hxx" -#include "rtl/ustrbuf.hxx" +#include "rtl/strbuf.hxx" #include "com/sun/star/lang/XMultiServiceFactory.hpp" #include "com/sun/star/container/XNameAccess.hpp" @@ -60,15 +60,14 @@ using namespace com::sun::star::lang; using namespace com::sun::star::container; using namespace com::sun::star::beans; -#define HELPID_PREFIX ".HelpId:vcl:PrintDialog" -#define SMHID2( a, b ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ":" b ) ), HID_PRINTDLG ) ) -#define SMHID1( a ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ) ), HID_PRINTDLG ) ) - PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId ) : Window( i_pParent, i_rId ) , maOrigSize( 10, 10 ) , maPageVDev( *this ) , maToolTipString( String( VclResId( SV_PRINT_PRINTPREVIEW_TXT ) ) ) + , mbGreyscale( false ) + , maHorzDim( this, WB_HORZ | WB_CENTER ) + , maVertDim( this, WB_VERT | WB_VCENTER ) { SetPaintTransparent( TRUE ); SetBackground(); @@ -76,6 +75,11 @@ PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const Re maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); else maPageVDev.SetBackground( Color( COL_WHITE ) ); + maHorzDim.Show(); + maVertDim.Show(); + + maHorzDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) ); + maVertDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) ); } PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() @@ -162,9 +166,10 @@ void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDC void PrintDialog::PrintPreviewWindow::Resize() { Size aNewSize( GetSizePixel() ); + long nTextHeight = maHorzDim.GetTextHeight(); // leave small space for decoration - aNewSize.Width() -= 2; - aNewSize.Height() -= 2; + aNewSize.Width() -= nTextHeight + 2; + aNewSize.Height() -= nTextHeight + 2; Size aScaledSize; double fScale = 1.0; @@ -206,16 +211,28 @@ void PrintDialog::PrintPreviewWindow::Resize() } maPageVDev.SetOutputSizePixel( aScaledSize, FALSE ); + + // position dimension lines + Point aRef( nTextHeight + (aNewSize.Width() - maPreviewSize.Width())/2, + nTextHeight + (aNewSize.Height() - maPreviewSize.Height())/2 ); + maHorzDim.SetPosSizePixel( Point( aRef.X(), aRef.Y() - nTextHeight ), + Size( maPreviewSize.Width(), nTextHeight ) ); + maVertDim.SetPosSizePixel( Point( aRef.X() - nTextHeight, aRef.Y() ), + Size( nTextHeight, maPreviewSize.Height() ) ); + } void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) { + long nTextHeight = maHorzDim.GetTextHeight(); Size aSize( GetSizePixel() ); + aSize.Width() -= nTextHeight; + aSize.Height() -= nTextHeight; if( maReplacementString.getLength() != 0 ) { // replacement is active Push(); - Rectangle aTextRect( Point( 0, 0 ), aSize ); + Rectangle aTextRect( Point( nTextHeight, nTextHeight ), aSize ); DecorationView aVw( this ); aVw.DrawFrame( aTextRect, FRAME_DRAW_GROUP ); aTextRect.Left() += 2; @@ -233,8 +250,8 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) { GDIMetaFile aMtf( maMtf ); - Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2, - (aSize.Height() - maPreviewSize.Height()) / 2 ); + Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2 + nTextHeight, + (aSize.Height() - maPreviewSize.Height()) / 2 + nTextHeight ); Size aVDevSize( maPageVDev.GetOutputSizePixel() ); const Size aLogicSize( maPageVDev.PixelToLogic( aVDevSize, MapMode( MAP_100TH_MM ) ) ); @@ -249,6 +266,11 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) maPageVDev.Erase(); maPageVDev.Push(); maPageVDev.SetMapMode( MAP_100TH_MM ); + ULONG nOldDrawMode = maPageVDev.GetDrawMode(); + if( mbGreyscale ) + maPageVDev.SetDrawMode( maPageVDev.GetDrawMode() | + ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | + DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); aMtf.WindStart(); aMtf.Scale( fScale, fScale ); aMtf.WindStart(); @@ -258,6 +280,7 @@ void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) SetMapMode( MAP_PIXEL ); maPageVDev.SetMapMode( MAP_PIXEL ); DrawOutDev( aOffset, maPreviewSize, Point( 0, 0 ), aVDevSize, maPageVDev ); + maPageVDev.SetDrawMode( nOldDrawMode ); DecorationView aVw( this ); Rectangle aFrame( aOffset + Point( -1, -1 ), Size( maPreviewSize.Width() + 2, maPreviewSize.Height() + 2 ) ); @@ -289,18 +312,12 @@ void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPrevi const Size& i_rOrigSize, const rtl::OUString& i_rReplacement, sal_Int32 i_nDPIX, - sal_Int32 i_nDPIY + sal_Int32 i_nDPIY, + bool i_bGreyscale ) { rtl::OUStringBuffer aBuf( 256 ); aBuf.append( maToolTipString ); - #if OSL_DEBUG_LEVEL > 0 - aBuf.appendAscii( "\n---\nPageSize: " ); - aBuf.append( sal_Int32( i_rOrigSize.Width()/100) ); - aBuf.appendAscii( "mm x " ); - aBuf.append( sal_Int32( i_rOrigSize.Height()/100) ); - aBuf.appendAscii( "mm" ); - #endif SetQuickHelpText( aBuf.makeStringAndClear() ); maMtf = i_rNewPreview; if( useHCColorReplacement() ) @@ -310,8 +327,30 @@ void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPrevi maOrigSize = i_rOrigSize; maReplacementString = i_rReplacement; + mbGreyscale = i_bGreyscale; maPageVDev.SetReferenceDevice( i_nDPIX, i_nDPIY ); maPageVDev.EnableOutput( TRUE ); + + // use correct measurements + const LocaleDataWrapper& rLocWrap( GetSettings().GetLocaleDataWrapper() ); + MapUnit eUnit = MAP_MM; + int nDigits = 0; + if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US ) + { + eUnit = MAP_100TH_INCH; + nDigits = 2; + } + Size aLogicPaperSize( LogicToLogic( i_rOrigSize, MapMode( MAP_100TH_MM ), MapMode( eUnit ) ) ); + String aNumText( rLocWrap.getNum( aLogicPaperSize.Width(), nDigits ) ); + aBuf.append( aNumText ); + aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" ); + maHorzDim.SetText( aBuf.makeStringAndClear() ); + + aNumText = rLocWrap.getNum( aLogicPaperSize.Height(), nDigits ); + aBuf.append( aNumText ); + aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" ); + maVertDim.SetText( aBuf.makeStringAndClear() ); + Resize(); Invalidate(); } @@ -364,12 +403,18 @@ void PrintDialog::ShowNupOrderWindow::Paint( const Rectangle& i_rRect ) int nX = 0, nY = 0; switch( mnOrderMode ) { - case SV_PRINT_PRT_NUP_ORDER_LRTD: + case SV_PRINT_PRT_NUP_ORDER_LRTB: nX = (i % mnColumns); nY = (i / mnColumns); break; - case SV_PRINT_PRT_NUP_ORDER_TDLR: + case SV_PRINT_PRT_NUP_ORDER_TBLR: nX = (i / mnRows); nY = (i % mnRows); break; + case SV_PRINT_PRT_NUP_ORDER_RLTB: + nX = mnColumns - 1 - (i % mnColumns); nY = (i / mnColumns); + break; + case SV_PRINT_PRT_NUP_ORDER_TBRL: + nX = mnColumns - 1 - (i / mnRows); nY = (i % mnRows); + break; } Size aTextSize( GetTextWidth( aPageText ), nTextHeight ); int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2; @@ -429,28 +474,6 @@ PrintDialog::NUpTabPage::NUpTabPage( Window* i_pParent, const ResId& rResId ) maPageMarginEdt.SetDecimalDigits( nDigits ); maSheetMarginEdt.SetDecimalDigits( nDigits ); - SMHID1( "NUpPage" ); - maNupLine.SMHID2("NUpPage", "Layout"); - maBrochureBtn.SMHID2("NUpPage", "Brochure" ); - maPagesBtn.SMHID2( "NUpPage", "PagesPerSheet" ); - maPagesBoxTitleTxt.SMHID2( "NUpPage", "PagesPerSheetLabel" ); - maNupPagesBox.SMHID2( "NUpPage", "PagesPerSheetBox" ); - maNupNumPagesTxt.SMHID2( "NUpPage", "Columns" ); - maNupColEdt.SMHID2( "NUpPage", "ColumnsBox" ); - maNupTimesTxt.SMHID2( "NUpPage", "Rows" ); - maNupRowsEdt.SMHID2( "NUpPage", "RowsBox" ); - maPageMarginTxt1.SMHID2( "NUpPage", "PageMargin" ); - maPageMarginEdt.SMHID2( "NUpPage", "PageMarginBox" ); - maPageMarginTxt2.SMHID2( "NUpPage", "PageMarginCont" ); - maSheetMarginTxt1.SMHID2( "NUpPage", "SheetMargin" ); - maSheetMarginEdt.SMHID2( "NUpPage", "SheetMarginBox" ); - maSheetMarginTxt2.SMHID2( "NUpPage", "SheetMarginCont" ); - maNupOrientationTxt.SMHID2( "NUpPage", "Orientation" ); - maNupOrientationBox.SMHID2( "NUpPage", "OrientationBox" ); - maNupOrderTxt.SMHID2( "NUpPage", "Order" ); - maNupOrderBox.SMHID2( "NUpPage", "OrderBox" ); - maBorderCB.SMHID2( "NUpPage", "BorderBox" ); - setupLayout(); } @@ -493,20 +516,21 @@ 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() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - long nIndent = 3*aBorder.Width(); + boost::shared_ptr<vcl::RowOrColumn> xLayout = + boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); + Size aBorder( LogicToPixel( Size( 6, 6 ), MapMode( MAP_APPFONT ) ) ); + /* According to OOo style guide, the horizontal indentation of child + elements to their parent element should always be 6 map units. */ + long nIndent = aBorder.Width(); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( aBorder.Width() ); - - 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 ); @@ -542,7 +566,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 ) ); @@ -554,11 +578,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 ); @@ -599,28 +618,9 @@ 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(); - SMHID1( "JobPage" ); - maPrinterFL.SMHID2( "JobPage", "Printer" ); - maPrinters.SMHID2( "JobPage", "PrinterList" ); - maDetailsBtn.SMHID2( "JobPage", "DetailsBtn" ); - maStatusLabel.SMHID2( "JobPage", "StatusLabel" ); - maStatusTxt.SMHID2( "JobPage", "StatusText" ); - maLocationLabel.SMHID2( "JobPage", "LocationLabel" ); - maLocationTxt.SMHID2( "JobPage", "LocationText" ); - maCommentLabel.SMHID2( "JobPage", "CommentLabel" ); - maCommentTxt.SMHID2( "JobPage", "CommentText" ); - maSetupButton.SMHID2( "JobPage", "Properties" ); - maCopies.SMHID2( "JobPage", "CopiesLine" ); - maCopySpacer.SMHID2( "JobPage", "CopySpacer" ); - maCopyCount.SMHID2( "JobPage", "CopiesText" ); - maCopyCountField.SMHID2( "JobPage", "Copies" ); - maCollateBox.SMHID2( "JobPage", "Collate" ); - maCollateImage.SMHID2( "JobPage", "CollateImage" ); - maCopySpacer.Show(); maStatusTxt.Show(); maCommentTxt.Show(); @@ -639,39 +639,37 @@ 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() ); + boost::shared_ptr<vcl::RowOrColumn> xLayout = + boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); // add printer fixed line - maLayout.addWindow( &maPrinterFL ); + xLayout->addWindow( &maPrinterFL ); // add print LB - maLayout.addWindow( &maPrinters, 3 ); + xLayout->addWindow( &maPrinters, 3 ); // 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 - 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 ); xLabelCol->addRow( &maCommentLabel, &maCommentTxt ); // add print range and copies columns - maLayout.addWindow( &maCopies ); - boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false, aBorder.Width() ) ); - 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() ) ); @@ -738,11 +736,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 ) ) @@ -751,11 +744,6 @@ PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rRe , maReverseOrderBox( this, VclResId( SV_PRINT_OPT_REVERSE ) ) { FreeResource(); - SMHID1( "OptPage" ); - maOptionsLine.SMHID2( "OptPage", "Options" ); - maToFileBox.SMHID2( "OptPage", "ToFile" ); - maCollateSingleJobsBox.SMHID2( "OptPage", "SingleJobs" ); - maReverseOrderBox.SMHID2( "OptPage", "Reverse" ); setupLayout(); } @@ -766,15 +754,13 @@ PrintDialog::OutputOptPage::~OutputOptPage() void PrintDialog::OutputOptPage::setupLayout() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + boost::shared_ptr<vcl::RowOrColumn> xLayout = + boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); - maLayout.setParentWindow( this ); - maLayout.setOuterBorder( aBorder.Width() ); - - maLayout.addWindow( &maOptionsLine ); - boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( &maLayout, aBorder.Width() ) ); - maLayout.addChild( xIndent ); - boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get(), aBorder.Height() ) ); + xLayout->addWindow( &maOptionsLine ); + boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( xLayout.get(), -1 ) ); + xLayout->addChild( xIndent ); + boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get() ) ); xIndent->setChild( xCol ); mxOptGroup = xCol; xCol->addWindow( &maToFileBox ); @@ -802,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<PrinterController>& i_rController ) : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) ) , maOKButton( this, VclResId( SV_PRINT_OK ) ) @@ -855,9 +835,6 @@ PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterCont // init reverse print maOptionsPage.maReverseOrderBox.Check( maPController->getReversePrint() ); - // get the first page - preparePreview( true, true ); - // fill printer listbox const std::vector< rtl::OUString >& rQueues( Printer::GetPrinterQueues() ); for( std::vector< rtl::OUString >::const_iterator it = rQueues.begin(); @@ -888,6 +865,12 @@ PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterCont maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) ); } } + // not printing to file + maPController->resetPrinterOptions( false ); + + // get the first page + preparePreview( true, true ); + // update the text fields for the printer updatePrinterText(); @@ -975,18 +958,6 @@ PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterCont } } - // set HelpIDs - SMHID1( "Dialog" ); - maOKButton.SMHID1( "OK" ); - maCancelButton.SMHID1( "Cancel" ); - maHelpButton.SMHID1( "Help" ); - maPreviewWindow.SMHID1( "Preview" ); - maNumPagesText.SMHID1( "NumPagesText" ); - maPageEdit.SMHID1( "PageEdit" ); - maForwardBtn.SMHID1( "ForwardBtn" ); - maBackwardBtn.SMHID1( "BackwardBtn" ); - maTabCtrl.SMHID1( "TabPages" ); - // append further tab pages if( mbShowLayoutPage ) { @@ -1015,13 +986,14 @@ PrintDialog::~PrintDialog() void PrintDialog::setupLayout() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + boost::shared_ptr<vcl::RowOrColumn> xLayout = + boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() ); + xLayout->setOuterBorder( 0 ); - 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 ); + 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() ) ); @@ -1045,12 +1017,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, aBorder.Width(), 0, aBorder.Width(), aBorder.Width() ); + 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 @@ -1083,6 +1055,11 @@ void PrintDialog::readFromSettings() } } maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); + if( maOptionsPage.maToFileBox.IsChecked() ) + { + maPController->resetPrinterOptions( true ); + preparePreview( true, true ); + } } void PrintDialog::storeToSettings() @@ -1123,39 +1100,18 @@ bool PrintDialog::isSingleJobs() return maOptionsPage.maCollateSingleJobsBox.IsChecked(); } -static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId = -1, const rtl::OUString& i_rPropName = rtl::OUString() ) +void setHelpId( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpIds, sal_Int32 i_nIndex ) { - rtl::OUStringBuffer aBuf( 256 ); - aBuf.appendAscii( HELPID_PREFIX ); - if( i_rPropName.getLength() ) - { - aBuf.append( sal_Unicode( ':' ) ); - aBuf.append( i_rPropName ); - } - if( i_pType ) - { - aBuf.append( sal_Unicode( ':' ) ); - aBuf.appendAscii( i_pType ); - } - if( i_nId >= 0 ) - { - aBuf.append( sal_Unicode( ':' ) ); - aBuf.append( i_nId ); - } - i_pWindow->SetSmartHelpId( SmartId( aBuf.makeStringAndClear(), HID_PRINTDLG ) ); + if( i_nIndex >= 0 && i_nIndex < i_rHelpIds.getLength() ) + i_pWindow->SetHelpId( rtl::OUStringToOString( i_rHelpIds.getConstArray()[i_nIndex], RTL_TEXTENCODING_UTF8 ) ); } -static void setHelpText( Window* /*i_pWindow*/, const Sequence< rtl::OUString >& /*i_rHelpTexts*/, sal_Int32 /*i_nIndex*/ ) +static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex ) { // without a help text set and the correct smartID, // help texts will be retrieved from the online help system - - // passed help texts for optional UI is used only for native dialogs which currently - // cannot access the same (rather implicit) mechanism - #if 0 if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() ) i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] ); - #endif } void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) @@ -1168,17 +1124,15 @@ void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) void PrintDialog::setupOptionalUI() { - Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); - - std::vector<vcl::RowOrColumn*> aDynamicColumns; - vcl::RowOrColumn* pCurColumn = 0; + std::vector< boost::shared_ptr<vcl::RowOrColumn> > 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<vcl::RowOrColumn> > aPropertyToDependencyRowMap; const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() ); for( int i = 0; i < rOptions.getLength(); i++ ) @@ -1192,7 +1146,9 @@ void PrintDialog::setupOptionalUI() rtl::OUString aText; rtl::OUString aPropertyName; Sequence< rtl::OUString > aChoices; + Sequence< sal_Bool > aChoicesDisabled; Sequence< rtl::OUString > aHelpTexts; + Sequence< rtl::OUString > aHelpIds; sal_Int64 nMinValue = 0, nMaxValue = 0; sal_Int32 nCurHelpText = 0; rtl::OUString aGroupingHint; @@ -1215,6 +1171,10 @@ void PrintDialog::setupOptionalUI() { rEntry.Value >>= aChoices; } + else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) + { + rEntry.Value >>= aChoicesDisabled; + } else if( rEntry.Name.equalsAscii( "Property" ) ) { PropertyValue aVal; @@ -1263,6 +1223,18 @@ void PrintDialog::setupOptionalUI() } } } + else if( rEntry.Name.equalsAscii( "HelpId" ) ) + { + if( ! (rEntry.Value >>= aHelpIds ) ) + { + rtl::OUString aHelpId; + if( (rEntry.Value >>= aHelpId) ) + { + aHelpIds.realloc( 1 ); + *aHelpIds.getArray() = aHelpId; + } + } + } else if( rEntry.Name.equalsAscii( "HintNoLayoutPage" ) ) { sal_Bool bNoLayoutPage = sal_False; @@ -1284,37 +1256,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<vcl::RowOrColumn>(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<vcl::RowOrColumn>(maNUpPage.getLayout()); pCurParent = &maNUpPage; // set layout page as current parent bOnStaticPage = true; } else if( aGroupingHint.getLength() ) { - pCurColumn = &maJobPage.maLayout; + pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maJobPage.getLayout()); pCurParent = &maJobPage; // set job page as current parent bOnStaticPage = true; } @@ -1332,17 +1307,16 @@ void PrintDialog::setupOptionalUI() maTabCtrl.SetTabPage( nOptPageId, pNewGroup ); // set help id - setSmartId( pNewGroup, "TabPage", nOptPageId ); + setHelpId( pNewGroup, aHelpIds, 0 ); // set help text setHelpText( pNewGroup, aHelpTexts, 0 ); // reset subgroup counter nCurSubGroup = 0; - aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true, aBorder.Width() ) ); + aDynamicColumns.push_back( boost::dynamic_pointer_cast<vcl::RowOrColumn>(pNewGroup->getLayout()) ); pCurColumn = aDynamicColumns.back(); pCurColumn->setParentWindow( pNewGroup ); - pCurColumn->setOuterBorder( aBorder.Width() ); bSubgroupOnStaticPage = false; bOnStaticPage = false; } @@ -1364,7 +1338,7 @@ void PrintDialog::setupOptionalUI() pNewSub->Show(); // set help id - setSmartId( pNewSub, "FixedLine", sal_Int32( nCurSubGroup++ ) ); + setHelpId( pNewSub, aHelpIds, 0 ); // set help text setHelpText( pNewSub, aHelpTexts, 0 ); // add group to current column @@ -1372,10 +1346,10 @@ 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.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 @@ -1399,17 +1373,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<vcl::RowOrColumn> >( aPropertyName, maNUpPage.mxBrochureDep ) ); } else { - vcl::RowOrColumn* pSaveCurColumn = pCurColumn; + boost::shared_ptr<vcl::RowOrColumn> 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<vcl::RowOrColumn> >::iterator, + std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >::iterator > aDepRange; aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName ); if( aDepRange.first != aDepRange.second ) { @@ -1444,20 +1418,20 @@ void PrintDialog::setupOptionalUI() maControlToPropertyMap[pNewBox] = aPropertyName; // set help id - setSmartId( pNewBox, "CheckBox", -1, aPropertyName ); + setHelpId( pNewBox, aHelpIds, 0 ); // set help text setHelpText( pNewBox, aHelpTexts, 0 ); - vcl::RowOrColumn* pDependencyRow = new vcl::RowOrColumn( pCurColumn, false ); + boost::shared_ptr<vcl::RowOrColumn> 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<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) ); // add checkbox to current column pDependencyRow->addWindow( pNewBox ); } else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) { - vcl::RowOrColumn* pRadioColumn = pCurColumn; + boost::shared_ptr<vcl::RowOrColumn> pRadioColumn( pCurColumn ); if( aText.getLength() ) { // add a FixedText: @@ -1467,16 +1441,17 @@ void PrintDialog::setupOptionalUI() pHeading->Show(); // set help id - setSmartId( pHeading, "FixedText", -1, aPropertyName ); + setHelpId( pHeading, aHelpIds, nCurHelpText ); // set help text - setHelpText( pHeading, aHelpTexts, nCurHelpText++ ); + setHelpText( pHeading, aHelpTexts, nCurHelpText ); + nCurHelpText++; // 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 @@ -1486,26 +1461,29 @@ void PrintDialog::setupOptionalUI() pVal->Value >>= nSelectVal; for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) { - boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn, 1 ) ); + boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn.get(), 1 ) ); pRadioColumn->addChild( pLabel ); boost::shared_ptr<vcl::RowOrColumn> 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<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) ); RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 ); maControls.push_front( pBtn ); pBtn->SetText( aChoices[m] ); pBtn->Check( m == nSelectVal ); pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) ); + if( aChoicesDisabled.getLength() > m && aChoicesDisabled[m] == sal_True ) + pBtn->Enable( FALSE ); pBtn->Show(); maPropertyToWindowMap[ aPropertyName ].push_back( pBtn ); maControlToPropertyMap[pBtn] = aPropertyName; maControlToNumValMap[pBtn] = m; // set help id - setSmartId( pBtn, "RadioButton", m, aPropertyName ); + setHelpId( pBtn, aHelpIds, nCurHelpText ); // set help text - setHelpText( pBtn, aHelpTexts, nCurHelpText++ ); + setHelpText( pBtn, aHelpTexts, nCurHelpText ); + nCurHelpText++; // add the radio button to the column pLabel->setLabel( pBtn ); } @@ -1516,9 +1494,9 @@ void PrintDialog::setupOptionalUI() ) && pCurParent ) { // create a row in the current column - vcl::RowOrColumn* pFieldColumn = new vcl::RowOrColumn( pCurColumn, false ); + boost::shared_ptr<vcl::RowOrColumn> 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<vcl::RowOrColumn> >( aPropertyName, pFieldColumn ) ); vcl::LabeledElement* pLabel = NULL; if( aText.getLength() ) @@ -1529,11 +1507,8 @@ void PrintDialog::setupOptionalUI() pHeading->SetText( aText ); pHeading->Show(); - // set help id - 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 ); } @@ -1558,7 +1533,7 @@ void PrintDialog::setupOptionalUI() pList->Show(); // set help id - setSmartId( pList, "ListBox", -1, aPropertyName ); + setHelpId( pList, aHelpIds, 0 ); // set help text setHelpText( pList, aHelpTexts, 0 ); @@ -1591,7 +1566,7 @@ void PrintDialog::setupOptionalUI() pField->Show(); // set help id - setSmartId( pField, "NumericField", -1, aPropertyName ); + setHelpId( pField, aHelpIds, 0 ); // set help text setHelpText( pField, aHelpTexts, 0 ); @@ -1618,7 +1593,7 @@ void PrintDialog::setupOptionalUI() pField->Show(); // set help id - setSmartId( pField, "Edit", -1, aPropertyName ); + setHelpId( pField, aHelpIds, 0 ); // set help text setHelpText( pField, aHelpTexts, 0 ); @@ -1668,11 +1643,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 @@ -1682,13 +1657,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<vcl::RowOrColumn> >::iterator it = aDynamicColumns.begin(); it != aDynamicColumns.end(); ++it ) { Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) ); @@ -1716,19 +1691,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 ); } @@ -1763,7 +1726,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 ); @@ -1778,7 +1741,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 @@ -1792,7 +1755,7 @@ void PrintDialog::checkControlDependencies() aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X(); maJobPage.maPrinters.SetSizePixel( aPrinterSize ); maJobPage.maSetupButton.Hide(); - maLayout.resize(); + getLayout()->resize(); } } } @@ -1821,6 +1784,16 @@ void PrintDialog::checkOptionalControlDependencies() } } + if( bShouldbeEnabled && dynamic_cast<RadioButton*>(it->first) ) + { + std::map< Window*, sal_Int32 >::const_iterator r_it = maControlToNumValMap.find( it->first ); + if( r_it != maControlToNumValMap.end() ) + { + bShouldbeEnabled = maPController->isUIChoiceEnabled( it->second, r_it->second ); + } + } + + bool bIsEnabled = it->first->IsEnabled(); // Enable does not do a change check first, so can be less cheap than expected if( bShouldbeEnabled != bIsEnabled ) @@ -1910,7 +1883,8 @@ void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache ) Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ); maPreviewWindow.setPreview( aMtf, aCurPageSize, nPages > 0 ? rtl::OUString() : maNoPageStr, - aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY() + aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY(), + aPrt->GetPrinterOptions().IsConvertToGreyscales() ); maForwardBtn.Enable( mnCurPage < nPages-1 ); @@ -2023,7 +1997,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() ) { @@ -2059,10 +2033,14 @@ void PrintDialog::updateNup() int nOrderMode = int(sal_IntPtr(maNUpPage.maNupOrderBox.GetEntryData( maNUpPage.maNupOrderBox.GetSelectEntryPos() ))); - if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTD ) + if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTB ) aMPS.nOrder = PrinterController::LRTB; - else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TDLR ) + else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBLR ) aMPS.nOrder = PrinterController::TBLR; + else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_RLTB ) + aMPS.nOrder = PrinterController::RLTB; + else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBRL ) + aMPS.nOrder = PrinterController::TBRL; int nOrientationMode = int(sal_IntPtr(maNUpPage.maNupOrientationBox.GetEntryData( maNUpPage.maNupOrientationBox.GetSelectEntryPos() ))); @@ -2097,6 +2075,7 @@ IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox ) String aNewPrinter( pBox->GetSelectEntry() ); // set new printer maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) ); + maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() ); // update text fields updatePrinterText(); } @@ -2127,8 +2106,7 @@ IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) Help* pHelp = Application::GetHelp(); if( pHelp ) { - // FIXME: find out proper help URL and use here - pHelp->Start( HID_PRINTDLG, GetParent() ); + pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:OK" ) ), &maOKButton ); } } else if( pButton == &maForwardBtn ) @@ -2142,7 +2120,9 @@ IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) else if( pButton == &maOptionsPage.maToFileBox ) { maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); - maLayout.resize(); + maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() ); + getLayout()->resize(); + preparePreview( true, true ); } else if( pButton == &maNUpPage.maBrochureBtn ) { @@ -2178,7 +2158,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() ) { @@ -2452,7 +2432,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 ); @@ -2514,13 +2494,13 @@ void PrintProgressDialog::implCalcProgressRect() if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) { ImplControlValue aValue; - Region aControlRegion( Rectangle( Point(), Size( 100, mnProgressHeight ) ) ); - Region aNativeControlRegion, aNativeContentRegion; + Rectangle aControlRegion( Point(), Size( 100, mnProgressHeight ) ); + Rectangle aNativeControlRegion, aNativeContentRegion; if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, CTRL_STATE_ENABLED, aValue, rtl::OUString(), aNativeControlRegion, aNativeContentRegion ) ) { - mnProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + mnProgressHeight = aNativeControlRegion.GetHeight(); } mbNativeProgress = true; } @@ -2556,6 +2536,7 @@ void PrintProgressDialog::tick() void PrintProgressDialog::reset() { + mbCanceled = false; setProgress( 0 ); } diff --git a/vcl/source/window/seleng.cxx b/vcl/source/window/seleng.cxx index d4ee01c26d61..322b2937b5c9 100644 --- a/vcl/source/window/seleng.cxx +++ b/vcl/source/window/seleng.cxx @@ -218,8 +218,15 @@ BOOL SelectionEngine::SelMouseButtonDown( const MouseEvent& rMEvt ) Point aPos = rMEvt.GetPosPixel(); aLastMove = rMEvt; - pWin->CaptureMouse(); - nFlags |= SELENG_IN_SEL; + if( !rMEvt.IsRight() ) + { + pWin->CaptureMouse(); + nFlags |= SELENG_IN_SEL; + } + else + { + nModifier = 0; + } switch ( nModifier ) { @@ -327,7 +334,7 @@ BOOL SelectionEngine::SelMouseButtonDown( const MouseEvent& rMEvt ) |* *************************************************************************/ -BOOL SelectionEngine::SelMouseButtonUp( const MouseEvent& /* rMEvt */ ) +BOOL SelectionEngine::SelMouseButtonUp( const MouseEvent& rMEvt ) { aWTimer.Stop(); //DbgOut("Up"); @@ -336,7 +343,11 @@ BOOL SelectionEngine::SelMouseButtonUp( const MouseEvent& /* rMEvt */ ) nFlags &= ~(SELENG_CMDEVT | SELENG_WAIT_UPEVT | SELENG_IN_SEL); return FALSE; } - pWin->ReleaseMouse(); + + if( !rMEvt.IsRight() ) + { + pWin->ReleaseMouse(); + } if( (nFlags & SELENG_WAIT_UPEVT) && !(nFlags & SELENG_CMDEVT) && eSelMode != SINGLE_SELECTION) diff --git a/vcl/source/window/splitwin.cxx b/vcl/source/window/splitwin.cxx index 689c56cbe619..62fbe2e507f3 100644 --- a/vcl/source/window/splitwin.cxx +++ b/vcl/source/window/splitwin.cxx @@ -49,7 +49,8 @@ // ======================================================================= -// Achtung: Darf keine Objekte enthalten, da mit memmove/memcpy gearbeitet wird +// Attention: Must not contain non-PODs because array is enlarged/copied +// with the use of memmove/memcpy. struct ImplSplitItem { long mnSize; @@ -71,6 +72,10 @@ struct ImplSplitItem SplitWindowItemBits mnBits; BOOL mbFixed; BOOL mbSubSize; + /// Minimal width or height of the item. -1 means no restriction. + long mnMinSize; + /// Maximal width or height of the item. -1 means no restriction. + long mnMaxSize; }; struct ImplSplitSet @@ -85,6 +90,28 @@ struct ImplSplitSet BOOL mbCalcPix; }; + + +/** Check whether the given size is inside the valid range defined by + [rItem.mnMinSize,rItem.mnMaxSize]. When it is not inside it then return + the upper or lower bound, respectively. Otherwise return the given size + unmodified. + Note that either mnMinSize and/or mnMaxSize can be -1 in which case the + size has not lower or upper bound. +*/ +namespace { + long ValidateSize (const long nSize, const ImplSplitItem rItem) + { + if (rItem.mnMinSize>=0 && nSize<rItem.mnMinSize) + return rItem.mnMinSize; + else if (rItem.mnMaxSize>0 && nSize>rItem.mnMaxSize) + return rItem.mnMaxSize; + else + return nSize; + } +} + + #define SPLITWIN_SPLITSIZE 3 #define SPLITWIN_SPLITSIZEEX 4 #define SPLITWIN_SPLITSIZEEXLN 6 @@ -2850,7 +2877,7 @@ void SplitWindow::InsertItem( USHORT nId, Window* pWindow, long nSize, DBG_ASSERT( !ImplFindItem( mpMainSet, nId, nDbgDummy ), "SplitWindow::InsertItem() - Id already exists" ); #endif - // Size muss min. 1 sein + // Size has to be at least 1. if ( nSize < 1 ) nSize = 1; @@ -2858,7 +2885,7 @@ void SplitWindow::InsertItem( USHORT nId, Window* pWindow, long nSize, ImplSplitSet* pNewSet; ImplSplitItem* pItem; - // Platz fuer neues Item schaffen + // Make room for the new item. if ( nPos > pSet->mnItems ) nPos = pSet->mnItems; ImplSplitItem* pNewItems = new ImplSplitItem[pSet->mnItems+1]; @@ -2871,19 +2898,21 @@ void SplitWindow::InsertItem( USHORT nId, Window* pWindow, long nSize, pSet->mnItems++; pSet->mbCalcPix = TRUE; - // Item anlegen und erweitern + // Create and initialize item. pItem = &(pSet->mpItems[nPos]); memset( pItem, 0, sizeof( ImplSplitItem ) ); pItem->mnSize = nSize; pItem->mnId = nId; pItem->mnBits = nBits; + pItem->mnMinSize=-1; + pItem->mnMaxSize=-1; if ( pWindow ) { pItem->mpWindow = pWindow; pItem->mpOrgParent = pWindow->GetParent(); - // Window mit SplitWindow verbinden + // Attach window to SplitWindow. pWindow->Hide(); pWindow->SetParent( this ); } @@ -3251,6 +3280,10 @@ void SplitWindow::SplitItem( USHORT nId, long nNewSize, nItems = pSet->mnItems; pItems = pSet->mpItems; + // When there is an explicit minimum or maximum size then move nNewSize + // into that range (when it is not yet already in it.) + nNewSize = ValidateSize(nNewSize, pItems[nPos]); + if ( mbCalc ) { pItems[nPos].mnSize = nNewSize; @@ -3552,6 +3585,36 @@ long SplitWindow::GetItemSize( USHORT nId, SplitWindowItemBits nBits ) const return 0; } + + + +void SplitWindow::SetItemSizeRange (USHORT nId, const Range aRange) +{ + USHORT nPos; + ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos); + + if (pSet != NULL) + { + pSet->mpItems[nPos].mnMinSize = aRange.Min(); + pSet->mpItems[nPos].mnMaxSize = aRange.Max(); + } +} + + + + +Range SplitWindow::GetItemSizeRange (USHORT nId) const +{ + USHORT nPos; + ImplSplitSet* pSet = ImplFindItem(mpBaseSet, nId, nPos); + + if (pSet != NULL) + return Range (pSet->mpItems[nPos].mnMinSize, pSet->mpItems[nPos].mnMaxSize); + else + return Range(-1,-1); +} + + // ----------------------------------------------------------------------- void SplitWindow::SetItemBits( USHORT nId, SplitWindowItemBits nNewBits ) diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx index c139ae1ffb30..36f27b1ceee7 100644 --- a/vcl/source/window/status.cxx +++ b/vcl/source/window/status.cxx @@ -89,7 +89,7 @@ struct ImplStatusItem XubString maText; XubString maHelpText; XubString maQuickHelpText; - ULONG mnHelpId; + rtl::OString maHelpId; void* mpUserData; BOOL mbVisible; XubString maAccessibleName; @@ -320,6 +320,8 @@ void StatusBar::ImplFormat() nExtraWidth2 = 0; } nX = STATUSBAR_OFFSET_X; + if( ImplHasMirroredGraphics() && IsRTLEnabled() ) + nX += ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset; } pItem = mpItemList->First(); @@ -544,7 +546,7 @@ void DrawProgress( Window* pWindow, const Point& rPos, long nPerc = (nPercent2 > 10000) ? 10000 : nPercent2; ImplControlValue aValue( nFullWidth * (long)nPerc / 10000 ); Rectangle aDrawRect( rPos, Size( nFullWidth, nPrgsHeight ) ); - Region aControlRegion( aDrawRect ); + Rectangle aControlRegion( aDrawRect ); if( bNeedErase ) { Window* pEraseWindow = pWindow; @@ -711,13 +713,13 @@ void StatusBar::ImplCalcProgressRect() if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) { ImplControlValue aValue; - Region aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) ); - Region aNativeControlRegion, aNativeContentRegion; + Rectangle aControlRegion( Rectangle( (const Point&)Point(), maPrgsFrameRect.GetSize() ) ); + Rectangle aNativeControlRegion, aNativeContentRegion; if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, CTRL_STATE_ENABLED, aValue, rtl::OUString(), aNativeControlRegion, aNativeContentRegion ) ) != FALSE ) { - long nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + long nProgressHeight = aNativeControlRegion.GetHeight(); if( nProgressHeight > maPrgsFrameRect.GetHeight() ) { long nDelta = nProgressHeight - maPrgsFrameRect.GetHeight(); @@ -833,7 +835,7 @@ void StatusBar::Resize() { // Breite und Hoehe abfragen und merken Size aSize = GetOutputSizePixel(); - mnDX = aSize.Width(); + mnDX = aSize.Width() - ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset; mnDY = aSize.Height(); mnCalcHeight = mnDY; // subtract border @@ -904,9 +906,9 @@ void StatusBar::RequestHelp( const HelpEvent& rHEvt ) else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) { String aCommand = GetItemCommand( nItemId ); - ULONG nHelpId = GetHelpId( nItemId ); + rtl::OString aHelpId( GetHelpId( nItemId ) ); - if ( aCommand.Len() || nHelpId ) + if ( aCommand.Len() || aHelpId.getLength() ) { // Wenn eine Hilfe existiert, dann ausloesen Help* pHelp = Application::GetHelp(); @@ -914,8 +916,8 @@ void StatusBar::RequestHelp( const HelpEvent& rHEvt ) { if ( aCommand.Len() ) pHelp->Start( aCommand, this ); - else if ( nHelpId ) - pHelp->Start( nHelpId, this ); + else if ( aHelpId.getLength() ) + pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this ); } return; } @@ -1031,7 +1033,6 @@ void StatusBar::InsertItem( USHORT nItemId, ULONG nWidth, pItem->mnBits = nBits; pItem->mnWidth = (long)nWidth+nFudge+STATUSBAR_OFFSET; pItem->mnOffset = nOffset; - pItem->mnHelpId = 0; pItem->mpUserData = 0; pItem->mbVisible = TRUE; @@ -1473,15 +1474,15 @@ const XubString& StatusBar::GetHelpText( USHORT nItemId ) const if ( nPos != STATUSBAR_ITEM_NOTFOUND ) { ImplStatusItem* pItem = mpItemList->GetObject( nPos ); - if ( !pItem->maHelpText.Len() && ( pItem->mnHelpId || pItem->maCommand.Len() )) + if ( !pItem->maHelpText.Len() && ( pItem->maHelpId.getLength() || pItem->maCommand.Len() )) { Help* pHelp = Application::GetHelp(); if ( pHelp ) { if ( pItem->maCommand.Len() ) pItem->maHelpText = pHelp->GetHelpText( pItem->maCommand, this ); - if ( !pItem->maHelpText.Len() && pItem->mnHelpId ) - pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this ); + if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) + pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); } } @@ -1518,24 +1519,31 @@ const XubString& StatusBar::GetQuickHelpText( USHORT nItemId ) const // ----------------------------------------------------------------------- -void StatusBar::SetHelpId( USHORT nItemId, ULONG nHelpId ) +void StatusBar::SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ) { USHORT nPos = GetItemPos( nItemId ); if ( nPos != STATUSBAR_ITEM_NOTFOUND ) - mpItemList->GetObject( nPos )->mnHelpId = nHelpId; + mpItemList->GetObject( nPos )->maHelpId = rHelpId; } // ----------------------------------------------------------------------- -ULONG StatusBar::GetHelpId( USHORT nItemId ) const +rtl::OString StatusBar::GetHelpId( USHORT nItemId ) const { USHORT nPos = GetItemPos( nItemId ); + rtl::OString aRet; if ( nPos != STATUSBAR_ITEM_NOTFOUND ) - return mpItemList->GetObject( nPos )->mnHelpId; - else - return 0; + { + ImplStatusItem* pItem = mpItemList->GetObject( nPos ); + if ( pItem->maHelpId.getLength() ) + aRet = pItem->maHelpId; + else + aRet = ::rtl::OUStringToOString( pItem->maCommand, RTL_TEXTENCODING_UTF8 ); + } + + return aRet; } // ----------------------------------------------------------------------- @@ -1723,13 +1731,13 @@ Size StatusBar::CalcWindowSizePixel() const if( pThis->IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) { ImplControlValue aValue; - Region aControlRegion( Rectangle( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) ) ); - Region aNativeControlRegion, aNativeContentRegion; + Rectangle aControlRegion( (const Point&)Point(), Size( nCalcWidth, nMinHeight ) ); + Rectangle aNativeControlRegion, aNativeContentRegion; if( pThis->GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, CTRL_STATE_ENABLED, aValue, rtl::OUString(), aNativeControlRegion, aNativeContentRegion ) ) { - nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + nProgressHeight = aNativeControlRegion.GetHeight(); } } @@ -1737,14 +1745,13 @@ Size StatusBar::CalcWindowSizePixel() const pThis->IsNativeControlSupported( CTRL_FRAME, PART_BORDER ) ) { ImplControlValue aControlValue( FRAME_DRAW_NODRAW ); - Region aBound, aContent; - Region aNatRgn( Rectangle( Point( 0, 0 ), Size( 150, 50 ) ) ); + Rectangle aBound, aContent; + Rectangle aNatRgn( Point( 0, 0 ), Size( 150, 50 ) ); if( pThis->GetNativeControlRegion(CTRL_FRAME, PART_BORDER, aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { mpImplData->mnItemBorderWidth = - ( aBound.GetBoundRect().GetHeight() - - aContent.GetBoundRect().GetHeight() ) / 2; + ( aBound.GetHeight() - aContent.GetHeight() ) / 2; } } diff --git a/vcl/source/window/syschild.cxx b/vcl/source/window/syschild.cxx index ef71f83df1ee..4e897eef4a8b 100644 --- a/vcl/source/window/syschild.cxx +++ b/vcl/source/window/syschild.cxx @@ -28,25 +28,34 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#ifndef _SV_SVSYS_HXX #include <svsys.h> -#endif +#include <rtl/process.h> +#include <rtl/ref.hxx> +#include <tools/rc.h> +#include <vcl/window.h> #include <vcl/salinst.hxx> #include <vcl/salframe.hxx> #include <vcl/window.hxx> #include <vcl/salobj.hxx> - -#ifndef _SV_RC_H -#include <tools/rc.h> -#endif #include <vcl/svdata.hxx> -#ifndef _SV_WIDNOW_H -#include <vcl/window.h> -#endif +#include <vcl/sysdata.hxx> #include <vcl/svapp.hxx> #include <vcl/syschild.hxx> +#include <vcl/unohelp.hxx> +#ifdef SOLAR_JAVA +#include <jni.h> +#endif + +#include <comphelper/processfactory.hxx> +#include <jvmaccess/virtualmachine.hxx> +#include <com/sun/star/java/XJavaVM.hpp> +#include <com/sun/star/java/XJavaThreadRegister_11.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <vcl/syschild.hxx> +using namespace ::com::sun::star; // ======================================================================= @@ -183,6 +192,8 @@ void SystemChildWindow::EnableEraseBackground( BOOL bEnable ) mpWindowImpl->mpSysObj->EnableEraseBackground( bEnable ); } +// ----------------------------------------------------------------------- + BOOL SystemChildWindow::IsEraseBackgroundEnabled() { if ( mpWindowImpl->mpSysObj ) @@ -190,3 +201,138 @@ BOOL SystemChildWindow::IsEraseBackgroundEnabled() else return FALSE; } + +// ----------------------------------------------------------------------- + +void SystemChildWindow::ImplTestJavaException( void* pEnv ) +{ +#ifdef SOLAR_JAVA + JNIEnv* pJavaEnv = reinterpret_cast< JNIEnv* >( pEnv ); + jthrowable jtThrowable = pJavaEnv->ExceptionOccurred(); + + if( jtThrowable ) + { // is it a java exception ? +#if OSL_DEBUG_LEVEL > 1 + pJavaEnv->ExceptionDescribe(); +#endif // OSL_DEBUG_LEVEL > 1 + pJavaEnv->ExceptionClear(); + + jclass jcThrowable = pJavaEnv->FindClass("java/lang/Throwable"); + jmethodID jmThrowable_getMessage = pJavaEnv->GetMethodID(jcThrowable, "getMessage", "()Ljava/lang/String;"); + jstring jsMessage = (jstring) pJavaEnv->CallObjectMethod(jtThrowable, jmThrowable_getMessage); + ::rtl::OUString ouMessage; + + if(jsMessage) + { + const jchar * jcMessage = pJavaEnv->GetStringChars(jsMessage, NULL); + ouMessage = ::rtl::OUString(jcMessage); + pJavaEnv->ReleaseStringChars(jsMessage, jcMessage); + } + + throw uno::RuntimeException(ouMessage, uno::Reference<uno::XInterface>()); + } +#endif // SOLAR_JAVA +} + +// ----------------------------------------------------------------------- + +sal_IntPtr SystemChildWindow::GetParentWindowHandle( sal_Bool bUseJava ) +{ + sal_IntPtr nRet = 0; + +#if defined WNT + nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->hWnd ); +#elif defined QUARTZ + // FIXME: this is wrong + nRet = reinterpret_cast< sal_IntPtr >( GetSystemData()->pView ); +#elif defined UNX + if( !bUseJava ) + { + nRet = (sal_IntPtr) GetSystemData()->aWindow; + } +#ifdef SOLAR_JAVA + else + { + uno::Reference< lang::XMultiServiceFactory > xFactory( vcl::unohelper::GetMultiServiceFactory() ); + + if( xFactory.is() && ( GetSystemData()->aWindow > 0 ) ) + { + try + { + ::rtl::Reference< ::jvmaccess::VirtualMachine > xVM; + uno::Reference< java::XJavaVM > xJavaVM( xFactory->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine") ) ), uno::UNO_QUERY ); + uno::Sequence< sal_Int8 > aProcessID( 17 ); + + rtl_getGlobalProcessId( (sal_uInt8*) aProcessID.getArray() ); + aProcessID[ 16 ] = 0; + OSL_ENSURE(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *), "Pointer cannot be represented as sal_Int64"); + sal_Int64 nPointer = reinterpret_cast< sal_Int64 >( static_cast< jvmaccess::VirtualMachine * >(0)); + xJavaVM->getJavaVM(aProcessID) >>= nPointer; + xVM = reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer); + + if( xVM.is() ) + { + try + { + ::jvmaccess::VirtualMachine::AttachGuard aVMAttachGuard( xVM ); + JNIEnv* pEnv = aVMAttachGuard.getEnvironment(); + + jclass jcToolkit = pEnv->FindClass("java/awt/Toolkit"); + ImplTestJavaException(pEnv); + + jmethodID jmToolkit_getDefaultToolkit = pEnv->GetStaticMethodID( jcToolkit, "getDefaultToolkit", "()Ljava/awt/Toolkit;" ); + ImplTestJavaException(pEnv); + + pEnv->CallStaticObjectMethod(jcToolkit, jmToolkit_getDefaultToolkit); + ImplTestJavaException(pEnv); + + jclass jcMotifAppletViewer = pEnv->FindClass("sun/plugin/navig/motif/MotifAppletViewer"); + if( pEnv->ExceptionOccurred() ) + { + pEnv->ExceptionClear(); + + jcMotifAppletViewer = pEnv->FindClass( "sun/plugin/viewer/MNetscapePluginContext"); + ImplTestJavaException(pEnv); + } + + jclass jcClassLoader = pEnv->FindClass("java/lang/ClassLoader"); + ImplTestJavaException(pEnv); + + jmethodID jmClassLoader_loadLibrary = pEnv->GetStaticMethodID( jcClassLoader, "loadLibrary", "(Ljava/lang/Class;Ljava/lang/String;Z)V"); + ImplTestJavaException(pEnv); + + jstring jsplugin = pEnv->NewStringUTF("javaplugin_jni"); + ImplTestJavaException(pEnv); + + pEnv->CallStaticVoidMethod(jcClassLoader, jmClassLoader_loadLibrary, jcMotifAppletViewer, jsplugin, JNI_FALSE); + ImplTestJavaException(pEnv); + + jmethodID jmMotifAppletViewer_getWidget = pEnv->GetStaticMethodID( jcMotifAppletViewer, "getWidget", "(IIIII)I" ); + ImplTestJavaException(pEnv); + + const Size aSize( GetOutputSizePixel() ); + jint ji_widget = pEnv->CallStaticIntMethod( jcMotifAppletViewer, jmMotifAppletViewer_getWidget, + GetSystemData()->aWindow, 0, 0, aSize.Width(), aSize.Height() ); + ImplTestJavaException(pEnv); + + nRet = static_cast< sal_IntPtr >( ji_widget ); + } + catch( uno::RuntimeException& ) + { + } + + if( !nRet ) + nRet = static_cast< sal_IntPtr >( GetSystemData()->aWindow ); + } + } + catch( ... ) + { + } + } + } +#endif // SOLAR_JAVA +#else // WNT || QUARTZ || UNX +#endif + + return nRet; +} diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx index f3624ef56f59..f6a37658b79f 100644 --- a/vcl/source/window/syswin.cxx +++ b/vcl/source/window/syswin.cxx @@ -773,7 +773,7 @@ void SystemWindow::SetWindowStateData( const WindowStateData& rData ) BOOL bWrapped = FALSE; while( pWin ) { - if( !pWin->ImplIsRealParentPath( this ) && + if( !pWin->ImplIsRealParentPath( this ) && ( pWin != this ) && pWin->ImplGetWindow()->IsTopWindow() && pWin->mpWindowImpl->mbReallyVisible ) { SalFrameGeometry g = pWin->mpWindowImpl->mpFrame->GetGeometry(); diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx index 7bfd115af8f9..0589d57009f4 100644 --- a/vcl/source/window/tabpage.cxx +++ b/vcl/source/window/tabpage.cxx @@ -149,7 +149,7 @@ void TabPage::Paint( const Rectangle& ) // draw native tabpage only inside tabcontrols, standalone tabpages look ugly (due to bad dialog design) if( IsNativeControlSupported(CTRL_TAB_BODY, PART_ENTIRE_CONTROL) && GetParent() && (GetParent()->GetType() == WINDOW_TABCONTROL) ) { - const ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); + const ImplControlValue aControlValue; ControlState nState = CTRL_STATE_ENABLED; int part = PART_ENTIRE_CONTROL; @@ -160,7 +160,7 @@ void TabPage::Paint( const Rectangle& ) Point aPoint; // pass the whole window region to NWF as the tab body might be a gradient or bitmap // that has to be scaled properly, clipping makes sure that we do not paint too much - Region aCtrlRegion( Rectangle( aPoint, GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aPoint, GetOutputSizePixel() ); DrawNativeControl( CTRL_TAB_BODY, part, aCtrlRegion, nState, aControlValue, rtl::OUString() ); } diff --git a/vcl/source/window/taskpanelist.cxx b/vcl/source/window/taskpanelist.cxx index c09dc464b809..1adabe487492 100644 --- a/vcl/source/window/taskpanelist.cxx +++ b/vcl/source/window/taskpanelist.cxx @@ -206,7 +206,7 @@ BOOL TaskPaneList::HandleKeyEvent( KeyEvent aKeyEvent ) BOOL bFocusInList = FALSE; KeyCode aKeyCode = aKeyEvent.GetKeyCode(); BOOL bForward = !aKeyCode.IsShift(); - if( aKeyCode.GetCode() == KEY_F6 ) // F6 + if( aKeyCode.GetCode() == KEY_F6 && ! aKeyCode.IsMod2() ) // F6 { bSplitterOnly = aKeyCode.IsMod1() && aKeyCode.IsShift(); diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx index 9ad0b8734437..b71cf1c13c8d 100644 --- a/vcl/source/window/toolbox.cxx +++ b/vcl/source/window/toolbox.cxx @@ -215,13 +215,13 @@ int ToolBox::ImplGetDragWidth( ToolBox* pThis ) ImplControlValue aControlValue; Point aPoint; - Region aContent, aBound; - Region aArea( Rectangle(aPoint, pThis->GetOutputSizePixel()) ); + Rectangle aContent, aBound; + Rectangle aArea( aPoint, pThis->GetOutputSizePixel() ); if ( pThis->GetNativeControlRegion(CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { - width = pThis->mbHorz ? aContent.GetBoundRect().GetWidth() : aContent.GetBoundRect().GetHeight(); + width = pThis->mbHorz ? aContent.GetWidth() : aContent.GetHeight(); } } return width; @@ -338,16 +338,14 @@ void ToolBox::ImplDrawGrip( ToolBox* pThis ) BOOL bNativeOk = FALSE; if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_HORZ : PART_THUMB_VERT ) ) { - ImplControlValue aControlValue; ToolbarValue aToolbarValue; aToolbarValue.maGripRect = pWrapper->GetDragArea(); - aControlValue.setOptionalVal( (void *)(&aToolbarValue) ); Point aPt; - Region aCtrlRegion( Rectangle( aPt, pThis->GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aPt, pThis->GetOutputSizePixel() ); ControlState nState = CTRL_STATE_ENABLED; bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ, - aCtrlRegion, nState, aControlValue, rtl::OUString() ); + aCtrlRegion, nState, aToolbarValue, rtl::OUString() ); } if( bNativeOk ) @@ -557,7 +555,7 @@ BOOL ToolBox::ImplDrawNativeBackground( ToolBox* pThis, const Region & ) { // use NWF Point aPt; - Region aCtrlRegion( Rectangle( aPt, pThis->GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aPt, pThis->GetOutputSizePixel() ); ControlState nState = CTRL_STATE_ENABLED; return pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT, @@ -1918,9 +1916,9 @@ BOOL ToolBox::ImplCalcItem() // determine minimum size necessary in NWF { Rectangle aRect( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) ); - Region aReg = aRect; + Rectangle aReg( aRect ); ImplControlValue aVal; - Region aNativeBounds, aNativeContent; + Rectangle aNativeBounds, aNativeContent; if( IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) ) { if( GetNativeControlRegion( CTRL_TOOLBAR, PART_BUTTON, @@ -1929,7 +1927,7 @@ BOOL ToolBox::ImplCalcItem() aVal, OUString(), aNativeBounds, aNativeContent ) ) { - aRect = aNativeBounds.GetBoundRect(); + aRect = aNativeBounds; if( aRect.GetWidth() > nMinWidth ) nMinWidth = aRect.GetWidth(); if( aRect.GetHeight() > nMinHeight ) @@ -1954,7 +1952,7 @@ BOOL ToolBox::ImplCalcItem() aVal, OUString(), aNativeBounds, aNativeContent ) ) { - aRect = aNativeBounds.GetBoundRect(); + aRect = aNativeBounds; if( aRect.GetHeight() > mnWinHeight ) mnWinHeight = aRect.GetHeight(); } @@ -1966,7 +1964,7 @@ BOOL ToolBox::ImplCalcItem() aVal, OUString(), aNativeBounds, aNativeContent ) ) { - aRect = aNativeBounds.GetBoundRect(); + aRect = aNativeBounds; if( aRect.GetHeight() > mnWinHeight ) mnWinHeight = aRect.GetHeight(); } @@ -1978,7 +1976,7 @@ BOOL ToolBox::ImplCalcItem() aVal, OUString(), aNativeBounds, aNativeContent ) ) { - aRect = aNativeBounds.GetBoundRect(); + aRect = aNativeBounds; if( aRect.GetHeight() > mnWinHeight ) mnWinHeight = aRect.GetHeight(); } @@ -3418,7 +3416,6 @@ static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, USHORT highl if( !bIsWindow && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) ) { ImplControlValue aControlValue; - Region aCtrlRegion( rRect ); ControlState nState = 0; if ( highlight == 1 ) nState |= CTRL_STATE_PRESSED; @@ -3429,7 +3426,7 @@ static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, USHORT highl bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON, - aCtrlRegion, nState, aControlValue, rtl::OUString() ); + rRect, nState, aControlValue, rtl::OUString() ); } if( !bNativeOk ) @@ -3454,6 +3451,8 @@ void ToolBox::ImplDrawItem( USHORT nPos, BOOL bHighlight, BOOL bPaint, BOOL bLay MetricVector* pVector = bLayout ? &mpData->m_pLayoutData->m_aUnicodeBoundRects : NULL; String* pDisplayText = bLayout ? &mpData->m_pLayoutData->m_aDisplayText : NULL; + bHighlight = bHighlight && pItem->mbEnabled; + // Falls Rechteck ausserhalb des sichbaren Bereichs liegt if ( pItem->maRect.IsEmpty() ) return; @@ -4821,15 +4820,15 @@ const XubString& ToolBox::ImplGetHelpText( USHORT nItemId ) const if ( pItem ) { - if ( !pItem->maHelpText.Len() && ( pItem->mnHelpId || pItem->maCommandStr.Len() )) + if ( !pItem->maHelpText.Len() && ( pItem->maHelpId.getLength() || pItem->maCommandStr.Len() )) { Help* pHelp = Application::GetHelp(); if ( pHelp ) { if ( pItem->maCommandStr.Len() ) pItem->maHelpText = pHelp->GetHelpText( pItem->maCommandStr, this ); - if ( !pItem->maHelpText.Len() && pItem->mnHelpId ) - pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this ); + if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) + pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); } } @@ -4895,9 +4894,9 @@ void ToolBox::RequestHelp( const HelpEvent& rHEvt ) else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) { String aCommand = GetItemCommand( nItemId ); - ULONG nHelpId = GetHelpId( nItemId ); + rtl::OString aHelpId( GetHelpId( nItemId ) ); - if ( aCommand.Len() || nHelpId ) + if ( aCommand.Len() || aHelpId.getLength() ) { // Wenn eine Hilfe existiert, dann ausloesen Help* pHelp = Application::GetHelp(); @@ -4905,8 +4904,8 @@ void ToolBox::RequestHelp( const HelpEvent& rHEvt ) { if ( aCommand.Len() ) pHelp->Start( aCommand, this ); - else if ( nHelpId ) - pHelp->Start( nHelpId, this ); + else if ( aHelpId.getLength() ) + pHelp->Start( rtl::OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this ); } return; } diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx index 334cdd2d0a64..35a39676353a 100644 --- a/vcl/source/window/toolbox2.cxx +++ b/vcl/source/window/toolbox2.cxx @@ -99,7 +99,6 @@ ImplToolItem::ImplToolItem() mnId = 0; mpWindow = NULL; mpUserData = NULL; - mnHelpId = 0; meType = TOOLBOXITEM_BUTTON; mnBits = 0; meState = STATE_NOCHECK; @@ -124,7 +123,6 @@ ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage, mnId = nItemId; mpWindow = NULL; mpUserData = NULL; - mnHelpId = 0; meType = TOOLBOXITEM_BUTTON; mnBits = nItemBits; meState = STATE_NOCHECK; @@ -149,7 +147,6 @@ ImplToolItem::ImplToolItem( USHORT nItemId, const XubString& rText, mnId = nItemId; mpWindow = NULL; mpUserData = NULL; - mnHelpId = 0; meType = TOOLBOXITEM_BUTTON; mnBits = nItemBits; meState = STATE_NOCHECK; @@ -175,7 +172,6 @@ ImplToolItem::ImplToolItem( USHORT nItemId, const Image& rImage, mnId = nItemId; mpWindow = NULL; mpUserData = NULL; - mnHelpId = 0; meType = TOOLBOXITEM_BUTTON; mnBits = nItemBits; meState = STATE_NOCHECK; @@ -204,7 +200,7 @@ ImplToolItem::ImplToolItem( const ImplToolItem& rItem ) : maQuickHelpText ( rItem.maQuickHelpText ), maHelpText ( rItem.maHelpText ), maCommandStr ( rItem.maCommandStr ), - mnHelpId ( rItem.mnHelpId ), + maHelpId ( rItem.maHelpId ), maRect ( rItem.maRect ), maCalcRect ( rItem.maCalcRect ), maItemSize ( rItem.maItemSize ), @@ -243,7 +239,7 @@ ImplToolItem& ImplToolItem::operator=( const ImplToolItem& rItem ) maQuickHelpText = rItem.maQuickHelpText; maHelpText = rItem.maHelpText; maCommandStr = rItem.maCommandStr; - mnHelpId = rItem.mnHelpId; + maHelpId = rItem.maHelpId; maRect = rItem.maRect; maCalcRect = rItem.maCalcRect; mnSepSize = rItem.mnSepSize; @@ -595,7 +591,7 @@ void ToolBox::InsertItem( const ResId& rResId, USHORT nPos ) aItem.mnBits = (ToolBoxItemBits)ReadLongRes(); if( nObjMask & RSC_TOOLBOXITEM_HELPID ) - aItem.mnHelpId = ReadLongRes(); + aItem.maHelpId = ReadByteStringRes(); if ( nObjMask & RSC_TOOLBOXITEM_TEXT ) { @@ -1923,24 +1919,31 @@ const XubString& ToolBox::GetHelpText( USHORT nItemId ) const // ----------------------------------------------------------------------- -void ToolBox::SetHelpId( USHORT nItemId, ULONG nHelpId ) +void ToolBox::SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ) { ImplToolItem* pItem = ImplGetItem( nItemId ); if ( pItem ) - pItem->mnHelpId = nHelpId; + pItem->maHelpId = rHelpId; } // ----------------------------------------------------------------------- -ULONG ToolBox::GetHelpId( USHORT nItemId ) const +rtl::OString ToolBox::GetHelpId( USHORT nItemId ) const { + rtl::OString aRet; + ImplToolItem* pItem = ImplGetItem( nItemId ); if ( pItem ) - return pItem->mnHelpId; - else - return 0; + { + if ( pItem->maHelpId.getLength() ) + aRet = pItem->maHelpId; + else + aRet = ::rtl::OUStringToOString( pItem->maCommandStr, RTL_TEXTENCODING_UTF8 ); + } + + return aRet; } // ----------------------------------------------------------------------- diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index ca92d9ed6c5b..0762a07476e2 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -35,7 +35,6 @@ #include "vcl/salinst.hxx" #include "vcl/salgtype.hxx" #include "vcl/salgdi.hxx" -#include "vcl/salctrlhandle.hxx" #include "vcl/unohelp.hxx" #include "tools/time.hxx" @@ -44,7 +43,6 @@ #include "tools/rc.h" #endif #include "vcl/svdata.hxx" -#include "vcl/windata.hxx" #include "vcl/dbggui.hxx" #include "vcl/outfont.hxx" #include "vcl/outdev.h" @@ -68,6 +66,7 @@ #include "unotools/fontcfg.hxx" #include "vcl/sysdata.hxx" #include "vcl/sallayout.hxx" +#include "vcl/salctype.hxx" #include "vcl/button.hxx" // Button::GetStandardText #include "vcl/taskpanelist.hxx" #include "com/sun/star/awt/XWindowPeer.hpp" @@ -88,9 +87,8 @@ #include "vcl/dialog.hxx" #include "vcl/unowrap.hxx" -#include "dndlcon.hxx" -#include "dndevdis.hxx" -#include "vcl/impbmpconv.hxx" +#include "vcl/dndlcon.hxx" +#include "vcl/dndevdis.hxx" #include "unotools/confignode.hxx" #include "vcl/gdimtf.hxx" @@ -243,18 +241,17 @@ void Window::ImplInitAppFontData( Window* pWindow ) // of control sizes, if yes, make app font scalings larger // so dialog positioning is not completely off ImplControlValue aControlValue; - Region aCtrlRegion( (const Rectangle&)Rectangle( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) ) ); - Region aBoundingRgn( aCtrlRegion ); - Region aContentRgn( aCtrlRegion ); + Rectangle aCtrlRegion( Point(), Size( nTextWidth < 10 ? 10 : nTextWidth, nTextHeight < 10 ? 10 : nTextHeight ) ); + Rectangle aBoundingRgn( aCtrlRegion ); + Rectangle aContentRgn( aCtrlRegion ); if( pWindow->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aContentRect( aContentRgn.GetBoundRect() ); // comment: the magical +6 is for the extra border in bordered // (which is the standard) edit fields - if( aContentRect.GetHeight() - nTextHeight > (nTextHeight+4)/4 ) - pSVData->maGDIData.mnAppFontY = (aContentRect.GetHeight()-4) * 10; + if( aContentRgn.GetHeight() - nTextHeight > (nTextHeight+4)/4 ) + pSVData->maGDIData.mnAppFontY = (aContentRgn.GetHeight()-4) * 10; } } @@ -271,19 +268,41 @@ bool Window::ImplCheckUIFont( const Font& rFont ) if( ImplGetSVData()->maGDIData.mbNativeFontConfig ) return true; + // create a text string using the localized text of important buttons String aTestText; - aTestText.Append( Button::GetStandardText( BUTTON_OK ) ); - aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) ); - aTestText.Append( Button::GetStandardText( BUTTON_YES ) ); - aTestText.Append( Button::GetStandardText( BUTTON_NO ) ); - aTestText.Append( Button::GetStandardText( BUTTON_RETRY ) ); - aTestText.Append( Button::GetStandardText( BUTTON_HELP ) ); - aTestText.Append( Button::GetStandardText( BUTTON_CLOSE ) ); - aTestText.Append( Button::GetStandardText( BUTTON_MORE ) ); - aTestText.Append( Button::GetStandardText( BUTTON_LESS ) ); - aTestText.Append( Button::GetStandardText( BUTTON_ABORT ) ); + static const StandardButtonType aTestButtons[] = + { + BUTTON_OK, BUTTON_CANCEL, BUTTON_CLOSE, BUTTON_ABORT, + BUTTON_YES, BUTTON_NO, BUTTON_MORE, BUTTON_IGNORE, + BUTTON_RETRY, BUTTON_HELP + }; + + const int nTestButtonCount = sizeof(aTestButtons)/sizeof(*aTestButtons); + for( int n = 0; n < nTestButtonCount; ++n ) + { + String aButtonStr = Button::GetStandardText( aTestButtons[n] ); + // #i115432# ignore mnemonic+accelerator part of each string + // TODO: use a string filtering method when it becomes available + const int nLen = aButtonStr.Len(); + bool bInside = false; + for( int i = 0; i < nLen; ++i ) { + const sal_Unicode c = aButtonStr.GetChar( i ); + if( (c == '(')) + bInside = true; + if( (c == ')')) + bInside = false; + if( (c == '~') + || (c == '(') || (c == ')') + || ((c >= 'A') && (c <= 'Z') && bInside) ) + aButtonStr.SetChar( i, ' ' ); + } + // append sanitized button text to test string + aTestText.Append( aButtonStr ); + } - return HasGlyphs( rFont, aTestText ) >= aTestText.Len(); + const int nFirstChar = HasGlyphs( rFont, aTestText ); + const bool bUIFontOk = (nFirstChar >= aTestText.Len()); + return bUIFontOk; } // ----------------------------------------------------------------------- @@ -296,6 +315,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; @@ -600,6 +621,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; @@ -613,8 +635,6 @@ void Window::ImplInitWindowData( WindowType nType ) mpWindowImpl->mnX = 0; // X-Position to Parent mpWindowImpl->mnY = 0; // Y-Position to Parent mpWindowImpl->mnAbsScreenX = 0; // absolute X-position on screen, used for RTL window positioning - mpWindowImpl->mnHelpId = 0; // help id - mpWindowImpl->mnUniqId = 0; // unique id mpWindowImpl->mpChildClipRegion = NULL; // Child-Clip-Region when ClipChildren mpWindowImpl->mpPaintRegion = NULL; // Paint-ClipRegion mpWindowImpl->mnStyle = 0; // style (init in ImplInitWindow) @@ -1132,6 +1152,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(); } // ----------------------------------------------------------------------- @@ -1180,20 +1202,14 @@ void Window::ImplCallMove() // ----------------------------------------------------------------------- -static ULONG ImplAutoHelpID( ResMgr* pResMgr ) +static rtl::OString ImplAutoHelpID( ResMgr* pResMgr ) { - if ( !Application::IsAutoHelpIdEnabled() ) - return 0; - - ULONG nHID = 0; - - DBG_ASSERT( pResMgr, "No res mgr for auto help id" ); - if( ! pResMgr ) - return 0; + rtl::OString aRet; - nHID = pResMgr->GetAutoHelpId(); + if( pResMgr && Application::IsAutoHelpIdEnabled() ) + aRet = pResMgr->GetAutoHelpId(); - return nHID; + return aRet; } // ----------------------------------------------------------------------- @@ -1213,22 +1229,23 @@ WinBits Window::ImplInitRes( const ResId& rResId ) void Window::ImplLoadRes( const ResId& rResId ) { - // newer move this line after IncrementRes - char* pRes = (char*)GetClassRes(); - pRes += 12; - sal_uInt32 nHelpId = (sal_uInt32)GetLongRes( (void*)pRes ); - if ( !nHelpId ) - nHelpId = ImplAutoHelpID( rResId.GetResMgr() ); - SetHelpId( nHelpId ); - ULONG nObjMask = ReadLongRes(); + // we need to calculate auto helpids before the resource gets closed + // if the resource only contains flags, it will be closed before we try to read a help id + // so we always create an auto help id that might be overwritten later + // HelpId + rtl::OString aHelpId = ImplAutoHelpID( rResId.GetResMgr() ); + // ResourceStyle ULONG nRSStyle = ReadLongRes(); // WinBits ReadLongRes(); - // HelpId - ReadLongRes(); + + if( nObjMask & WINDOW_HELPID ) + aHelpId = ReadByteStringRes(); + + SetHelpId( aHelpId ); BOOL bPos = FALSE; BOOL bSize = FALSE; @@ -1295,7 +1312,7 @@ void Window::ImplLoadRes( const ResId& rResId ) if ( nObjMask & WINDOW_EXTRALONG ) SetData( (void*)ReadLongRes() ); if ( nObjMask & WINDOW_UNIQUEID ) - SetUniqueId( (ULONG)ReadLongRes() ); + SetUniqueId( ReadByteStringRes() ); if ( nObjMask & WINDOW_BORDER_STYLE ) { @@ -1323,8 +1340,6 @@ ImplWinData* Window::ImplGetWinData() const mpWindowImpl->mpWinData->mnIsTopWindow = (USHORT) ~0; // not initialized yet, 0/1 will indicate TopWindow (see IsTopWindow()) mpWindowImpl->mpWinData->mbMouseOver = FALSE; mpWindowImpl->mpWinData->mbEnableNativeWidget = (pNoNWF && *pNoNWF) ? FALSE : TRUE; // TRUE: try to draw this control with native theme API - mpWindowImpl->mpWinData->mpSmartHelpId = NULL; - mpWindowImpl->mpWinData->mpSmartUniqueId = NULL; } return mpWindowImpl->mpWinData; @@ -4352,6 +4367,8 @@ namespace Window::~Window() { + ImplFreeExtWindowImpl(); + vcl::LazyDeletor<Window>::Undelete( this ); DBG_DTOR( Window, ImplDbgCheckWindow ); @@ -4735,10 +4752,6 @@ Window::~Window() delete mpWindowImpl->mpWinData->mpFocusRect; if ( mpWindowImpl->mpWinData->mpTrackRect ) delete mpWindowImpl->mpWinData->mpTrackRect; - if ( mpWindowImpl->mpWinData->mpSmartHelpId ) - delete mpWindowImpl->mpWinData->mpSmartHelpId; - if ( mpWindowImpl->mpWinData->mpSmartUniqueId ) - delete mpWindowImpl->mpWinData->mpSmartUniqueId; delete mpWindowImpl->mpWinData; } @@ -4793,6 +4806,13 @@ void Window::doLazyDelete() } // ----------------------------------------------------------------------- +void Window::InterceptChildWindowKeyDown( sal_Bool bIntercept ) +{ + if( mpWindowImpl->mpSysObj ) + mpWindowImpl->mpSysObj->InterceptChildWindowKeyDown( bIntercept ); +} + +// ----------------------------------------------------------------------- void Window::MouseMove( const MouseEvent& rMEvt ) { @@ -4876,6 +4896,12 @@ void Window::Paint( const Rectangle& rRect ) // ----------------------------------------------------------------------- +void Window::PostPaint() +{ +} + +// ----------------------------------------------------------------------- + void Window::Draw( OutputDevice*, const Point&, const Size&, ULONG ) { DBG_CHKTHIS( Window, ImplDbgCheckWindow ); @@ -4980,29 +5006,18 @@ void Window::RequestHelp( const HelpEvent& rHEvt ) } else { - SmartId aSmartId = GetSmartHelpId(); - - ULONG nNumHelpId = 0; - String aStrHelpId; - if( aSmartId.HasString() ) - aStrHelpId = aSmartId.GetStr(); - if( aSmartId.HasNumeric() ) - nNumHelpId = aSmartId.GetNum(); - - if ( !nNumHelpId && aStrHelpId.Len() == 0 && ImplGetParent() ) + String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) ); + if ( aStrHelpId.Len() == 0 && ImplGetParent() ) ImplGetParent()->RequestHelp( rHEvt ); else { - if ( !nNumHelpId && aStrHelpId.Len() == 0 ) - nNumHelpId = OOO_HELP_INDEX; - Help* pHelp = Application::GetHelp(); if ( pHelp ) { if( aStrHelpId.Len() > 0 ) pHelp->Start( aStrHelpId, this ); else - pHelp->Start( nNumHelpId, this ); + pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OOO_HELP_INDEX ) ), this ); } } } @@ -8131,32 +8146,22 @@ const XubString& Window::GetHelpText() const { DBG_CHKTHIS( Window, ImplDbgCheckWindow ); - SmartId aSmartId = GetSmartHelpId(); - - ULONG nNumHelpId = 0; - String aStrHelpId; - if( aSmartId.HasString() ) - aStrHelpId = aSmartId.GetStr(); - if( aSmartId.HasNumeric() ) - nNumHelpId = aSmartId.GetNum(); + String aStrHelpId( rtl::OStringToOUString( GetHelpId(), RTL_TEXTENCODING_UTF8 ) ); bool bStrHelpId = (aStrHelpId.Len() > 0); - if ( !mpWindowImpl->maHelpText.Len() && (nNumHelpId || bStrHelpId) ) + if ( !mpWindowImpl->maHelpText.Len() && bStrHelpId ) { if ( !IsDialog() && (mpWindowImpl->mnType != WINDOW_TABPAGE) && (mpWindowImpl->mnType != WINDOW_FLOATINGWINDOW) ) { Help* pHelp = Application::GetHelp(); if ( pHelp ) { - if( bStrHelpId ) - ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this ); - else - ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( nNumHelpId, this ); + ((Window*)this)->mpWindowImpl->maHelpText = pHelp->GetHelpText( aStrHelpId, this ); mpWindowImpl->mbHelpTextDynamic = FALSE; } } } - else if( mpWindowImpl->mbHelpTextDynamic && (nNumHelpId || bStrHelpId) ) + else if( mpWindowImpl->mbHelpTextDynamic && bStrHelpId ) { static const char* pEnv = getenv( "HELP_DEBUG" ); if( pEnv && *pEnv ) @@ -8164,10 +8169,7 @@ const XubString& Window::GetHelpText() const rtl::OUStringBuffer aTxt( 64+mpWindowImpl->maHelpText.Len() ); aTxt.append( mpWindowImpl->maHelpText ); aTxt.appendAscii( "\n------------------\n" ); - if( bStrHelpId ) - aTxt.append( rtl::OUString( aStrHelpId ) ); - else - aTxt.append( sal_Int32( nNumHelpId ) ); + aTxt.append( rtl::OUString( aStrHelpId ) ); mpWindowImpl->maHelpText = aTxt.makeStringAndClear(); } mpWindowImpl->mbHelpTextDynamic = FALSE; @@ -8650,7 +8652,10 @@ Reference< XClipboard > Window::GetClipboard() if( xFactory.is() ) { - mpWindowImpl->mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY ); + mpWindowImpl->mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboardExt" ) ), UNO_QUERY ); + + if( !mpWindowImpl->mpFrameData->mxClipboard.is() ) + mpWindowImpl->mpFrameData->mxClipboard = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.SystemClipboard" ) ), UNO_QUERY ); #if defined(UNX) && !defined(QUARTZ) // unix clipboard needs to be initialized if( mpWindowImpl->mpFrameData->mxClipboard.is() ) @@ -8713,6 +8718,9 @@ Reference< XClipboard > Window::GetPrimarySelection() static Reference< XClipboard > s_xSelection; if ( !s_xSelection.is() ) + s_xSelection = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboardExt" ) ), UNO_QUERY ); + + if ( !s_xSelection.is() ) s_xSelection = Reference< XClipboard >( xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ) ), UNO_QUERY ); mpWindowImpl->mpFrameData->mxSelection = s_xSelection; @@ -9396,7 +9404,7 @@ void Window::DrawSelectionBackground( const Rectangle& rRect, if( bDark ) aSelectionFillCol = COL_BLACK; else - nPercent = bRoundEdges ? 90 : 80; // just checked (light) + nPercent = 80; // just checked (light) } else { @@ -9411,7 +9419,7 @@ void Window::DrawSelectionBackground( const Rectangle& rRect, nPercent = 0; } else - nPercent = bRoundEdges ? 50 : 20; // selected, pressed or checked ( very dark ) + nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark ) } else if( bChecked || highlight == 1 ) { @@ -9424,7 +9432,7 @@ void Window::DrawSelectionBackground( const Rectangle& rRect, nPercent = 0; } else - nPercent = bRoundEdges ? 70 : 35; // selected, pressed or checked ( very dark ) + nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark ) } else { @@ -9440,7 +9448,7 @@ void Window::DrawSelectionBackground( const Rectangle& rRect, nPercent = 0; } else - nPercent = bRoundEdges ? 80 : 70; // selected ( dark ) + nPercent = 70; // selected ( dark ) } } @@ -9728,11 +9736,14 @@ Reference< rendering::XCanvas > Window::ImplGetCanvas( const Size& rFullscreenSi // ========================================= if ( xFactory.is() ) { - static Reference<lang::XMultiServiceFactory> xCanvasFactory( - xFactory->createInstance( - OUString( RTL_CONSTASCII_USTRINGPARAM( - "com.sun.star." - "rendering.CanvasFactory") ) ), UNO_QUERY ); + static ::vcl::DeleteUnoReferenceOnDeinit<XMultiServiceFactory> xStaticCanvasFactory( + Reference<XMultiServiceFactory>( + xFactory->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.rendering.CanvasFactory") ) ), + UNO_QUERY )); + uno::Reference<XMultiServiceFactory> xCanvasFactory(xStaticCanvasFactory.get()); + if(xCanvasFactory.is()) { #ifdef WNT diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index 02b2713b01cc..e5b58a8b6f3c 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -1442,115 +1442,31 @@ Window* Window::ImplGetTopmostFrameWindow() return pTopmostParent->mpWindowImpl->mpFrameWindow; } -// making these Methods out of line to be able to change them lateron without complete rebuild -// TODO: Set the SmartId in here and remove mpWindowImpl->mnHelpId -void Window::SetHelpId( ULONG nHelpId ) +void Window::SetHelpId( const rtl::OString& rHelpId ) { - SetSmartHelpId(SmartId(nHelpId)); + mpWindowImpl->maHelpId = rHelpId; } -ULONG Window::GetHelpId() const +const rtl::OString& Window::GetHelpId() const { - return mpWindowImpl->mnHelpId; + return mpWindowImpl->maHelpId; } -void Window::SetSmartHelpId( const SmartId& aId, SmartIdUpdateMode aMode ) +void Window::SetUniqueId( const rtl::OString& rUniqueId ) { - // create SmartId if required - if ( (aMode == SMART_SET_STR) || (aMode == SMART_SET_ALL) || ( (aMode == SMART_SET_SMART) && aId.HasString() ) ) - { - if ( !ImplGetWinData()->mpSmartHelpId ) - ImplGetWinData()->mpSmartHelpId = new SmartId(); - } - - // if we have a SmartId (eather from earlier call or just created) fill with new values - if ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartHelpId ) - ImplGetWinData()->mpSmartHelpId->UpdateId( aId, aMode ); - - if ( (aMode == SMART_SET_NUM) || (aMode == SMART_SET_ALL) || ( (aMode == SMART_SET_SMART) && aId.HasNumeric() ) ) - { - mpWindowImpl->mnHelpId = aId.GetNum(); - } -} - -SmartId Window::GetSmartHelpId() const -{ - if ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartHelpId ) - { - if ( mpWindowImpl->mnHelpId || mpWindowImpl->mpWinData->mpSmartHelpId->HasNumeric() ) - mpWindowImpl->mpWinData->mpSmartHelpId->UpdateId( SmartId( mpWindowImpl->mnHelpId ), SMART_SET_NUM ); - return *mpWindowImpl->mpWinData->mpSmartHelpId; - } - else - { - if ( mpWindowImpl->mnHelpId ) - return SmartId( mpWindowImpl->mnHelpId ); - else - return SmartId(); - } -} - - -// making these Methods out of line to be able to change them lateron without complete rebuild -// TODO: Set the SmartId in here and remove mpWindowImpl->mnUniqId -void Window::SetUniqueId( ULONG nUniqueId ) { mpWindowImpl->mnUniqId = nUniqueId; } -ULONG Window::GetUniqueId() const { return mpWindowImpl->mnUniqId; } - - -void Window::SetSmartUniqueId( const SmartId& aId, SmartIdUpdateMode aMode ) -{ - // create SmartId if required - if ( (aMode == SMART_SET_STR) || (aMode == SMART_SET_ALL) || ( (aMode == SMART_SET_SMART) && aId.HasString() ) ) - { - if ( !ImplGetWinData()->mpSmartUniqueId ) - ImplGetWinData()->mpSmartUniqueId = new SmartId(); - } - - // if we have a SmartId (eather from earlier call or just created) fill with new values - if ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartUniqueId ) - ImplGetWinData()->mpSmartUniqueId->UpdateId( aId, aMode ); - - if ( (aMode == SMART_SET_NUM) || (aMode == SMART_SET_ALL) || ( (aMode == SMART_SET_SMART) && aId.HasNumeric() ) ) - mpWindowImpl->mnUniqId = aId.GetNum(); + mpWindowImpl->maUniqId = rUniqueId; } -SmartId Window::GetSmartUniqueId() const +const rtl::OString& Window::GetUniqueId() const { - if ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartUniqueId ) - { - if ( mpWindowImpl->mnUniqId || mpWindowImpl->mpWinData->mpSmartUniqueId->HasNumeric() ) - mpWindowImpl->mpWinData->mpSmartUniqueId->UpdateId( SmartId( mpWindowImpl->mnUniqId ), SMART_SET_NUM ); - return *mpWindowImpl->mpWinData->mpSmartUniqueId; - } - else - { - if ( mpWindowImpl->mnUniqId ) - return SmartId( mpWindowImpl->mnUniqId ); - else - return SmartId(); - } + return mpWindowImpl->maUniqId; } -SmartId Window::GetSmartUniqueOrHelpId() const +const rtl::OString& Window::GetUniqueOrHelpId() const { - if ( ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartHelpId ) || mpWindowImpl->mnHelpId ) - { - if ( ( mpWindowImpl->mpWinData && mpWindowImpl->mpWinData->mpSmartUniqueId ) || mpWindowImpl->mnUniqId ) - { - SmartId aTemp = GetSmartHelpId(); - aTemp.UpdateId( GetSmartUniqueId() ); - return aTemp; - } - else - return GetSmartHelpId(); - } - else - return GetSmartUniqueId(); + return mpWindowImpl->maUniqId.getLength() ? mpWindowImpl->maUniqId : mpWindowImpl->maHelpId; } - - - // --------- old inline methods --------------- Window* Window::ImplGetWindow() diff --git a/vcl/source/window/window4.cxx b/vcl/source/window/window4.cxx new file mode 100644 index 000000000000..577a573c2015 --- /dev/null +++ b/vcl/source/window/window4.cxx @@ -0,0 +1,224 @@ +/************************************************************************* + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_vcl.hxx" + +#include "vcl/window.hxx" +#include "vcl/window.h" +#include "vcl/svdata.hxx" +#include "vcl/arrange.hxx" + +#include "com/sun/star/beans/PropertyValue.hpp" + +#include <map> +#include <vector> + +using namespace com::sun::star; + +namespace vcl +{ + struct ExtWindowImpl + { + ExtWindowImpl() + : mbOwnedByParent( false ) + {} + ~ExtWindowImpl() + {} + + boost::shared_ptr< WindowArranger > mxLayout; + bool mbOwnedByParent; + rtl::OUString maIdentifier; + }; +} + +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; + mpWindowImpl->mpExtImpl = NULL; + } +} + +vcl::ExtWindowImpl* Window::ImplGetExtWindowImpl() const +{ + vcl::ExtWindowImpl* pImpl = NULL; + if( mpWindowImpl ) + { + if( ! mpWindowImpl->mpExtImpl && ! mpWindowImpl->mbInDtor ) + 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; +} + +void Window::addWindow( Window* i_pWin, 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; + } + } +} + +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; + i_pWin->SetParent( i_pNewParent ); + pRet = i_pWin; + } + } + } + return pRet; +} + +Window* Window::findWindow( const rtl::OUString& i_rIdentifier ) const +{ + if( getIdentifier() == i_rIdentifier ) + return const_cast<Window*>(this); + + Window* pChild = mpWindowImpl->mpFirstChild; + while ( pChild ) + { + Window* pResult = pChild->findWindow( i_rIdentifier ); + if( pResult ) + return pResult; + pChild = pChild->mpWindowImpl->mpNext; + } + + return NULL; +} + +const rtl::OUString& Window::getIdentifier() const +{ + static rtl::OUString aEmptyStr; + + return (mpWindowImpl && mpWindowImpl->mpExtImpl) ? mpWindowImpl->mpExtImpl->maIdentifier : aEmptyStr; +} + +void Window::setIdentifier( const rtl::OUString& i_rIdentifier ) +{ + vcl::ExtWindowImpl* pImpl = ImplGetExtWindowImpl(); + 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++ ) + { + if( pVals[i].Name.equalsAscii( "Enabled" ) ) + { + 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 ); + } + } +} + +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/winproc.cxx b/vcl/source/window/winproc.cxx index 7b0512a1320b..2fce7e52f24c 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -42,7 +42,6 @@ #include <unotools/localedatawrapper.hxx> #include <vcl/svdata.hxx> #include <vcl/dbggui.hxx> -#include <vcl/windata.hxx> #include <vcl/timer.hxx> #include <vcl/event.hxx> #include <vcl/sound.hxx> @@ -62,7 +61,7 @@ #include <vcl/salgdi.hxx> #include <vcl/menu.hxx> -#include <dndlcon.hxx> +#include <vcl/dndlcon.hxx> #include <com/sun/star/datatransfer/dnd/XDragSource.hpp> #include <com/sun/star/awt/MouseEvent.hpp> diff --git a/vcl/source/window/wpropset.cxx b/vcl/source/window/wpropset.cxx new file mode 100644 index 000000000000..4aaa3f987b77 --- /dev/null +++ b/vcl/source/window/wpropset.cxx @@ -0,0 +1,346 @@ +/************************************************************************* + * + * 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 + * <http://www.openoffice.org/license.html> + * 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 <map> + +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() + { + } + + using cppu::WeakComponentImplHelperBase::disposing; + 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<WindowArranger> mpLayout; + uno::Sequence< beans::PropertyValue > maSavedValues; + + PropertyMapEntry( Window* i_pWindow = NULL, + const boost::shared_ptr<WindowArranger>& i_pLayout = boost::shared_ptr<WindowArranger>() ) + : 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; +} |