diff options
author | Philipp Lohmann [pl] <Philipp.Lohmann@Sun.COM> | 2010-05-20 16:06:12 +0200 |
---|---|---|
committer | Philipp Lohmann [pl] <Philipp.Lohmann@Sun.COM> | 2010-05-20 16:06:12 +0200 |
commit | 8c2460cc2c472d0edac48bd9a186f7d44a0563a6 (patch) | |
tree | 8b063a0056f476dbaa850c5f0278cdf6e42be110 /vcl/aqua | |
parent | e2c090708e089258087396d46acacf513f70e809 (diff) | |
parent | 51066323fd14918f65ea7ba66e14b9c7604eb978 (diff) |
rebase to DEV300_m78
Diffstat (limited to 'vcl/aqua')
-rw-r--r-- | vcl/aqua/inc/salframe.h | 2 | ||||
-rw-r--r-- | vcl/aqua/inc/salinst.h | 2 | ||||
-rw-r--r-- | vcl/aqua/source/a11y/aqua11yfactory.mm | 3 | ||||
-rw-r--r-- | vcl/aqua/source/a11y/aqua11ytablewrapper.h | 10 | ||||
-rw-r--r-- | vcl/aqua/source/a11y/aqua11ytablewrapper.mm | 182 | ||||
-rw-r--r-- | vcl/aqua/source/a11y/aqua11ywrapper.mm | 31 | ||||
-rw-r--r-- | vcl/aqua/source/app/salinst.cxx | 15 | ||||
-rw-r--r-- | vcl/aqua/source/dtrans/aqua_clipboard.cxx | 13 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/aquaprintaccessoryview.mm | 9 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/salgdi.cxx | 10 | ||||
-rw-r--r-- | vcl/aqua/source/gdi/salprn.cxx | 202 | ||||
-rw-r--r-- | vcl/aqua/source/window/salframe.cxx | 17 | ||||
-rwxr-xr-x | vcl/aqua/source/window/salframeview.mm | 78 |
13 files changed, 392 insertions, 182 deletions
diff --git a/vcl/aqua/inc/salframe.h b/vcl/aqua/inc/salframe.h index fd783270875e..c2ded3267f45 100644 --- a/vcl/aqua/inc/salframe.h +++ b/vcl/aqua/inc/salframe.h @@ -184,6 +184,8 @@ public: NSView* getView() const { return mpView; } unsigned int getStyleMask() const { return mnStyleMask; } + void getResolution( long& o_rDPIX, long& o_rDPIY ); + // actually the follwing methods do the same thing: flipping y coordinates // but having two of them makes clearer what the coordinate system // is supposed to be before and after diff --git a/vcl/aqua/inc/salinst.h b/vcl/aqua/inc/salinst.h index 8a44f7ef3304..0bceb99d1d0e 100644 --- a/vcl/aqua/inc/salinst.h +++ b/vcl/aqua/inc/salinst.h @@ -32,6 +32,7 @@ #include "vos/mutex.hxx" #include "vos/thread.hxx" #include "vcl/salinst.hxx" +#include "osl/conditn.h" #include "aquavcltypes.h" @@ -96,6 +97,7 @@ public: int mnActivePrintJobs; std::list< SalUserEvent > maUserEvents; oslMutex maUserEventListMutex; + oslCondition maWaitingYieldCond; typedef std::list<const ApplicationEvent*> AppEventList; static AppEventList aAppEventList; diff --git a/vcl/aqua/source/a11y/aqua11yfactory.mm b/vcl/aqua/source/a11y/aqua11yfactory.mm index eb745ea24aa5..7732ce202cd2 100644 --- a/vcl/aqua/source/a11y/aqua11yfactory.mm +++ b/vcl/aqua/source/a11y/aqua11yfactory.mm @@ -48,6 +48,7 @@ #include "aqua11ywrappersplitter.h" #include "aqua11ywrappertabgroup.h" #include "aqua11ywrappertoolbar.h" +#include "aqua11ytablewrapper.h" #include <com/sun/star/accessibility/AccessibleStateType.hpp> using namespace ::com::sun::star::accessibility; @@ -142,6 +143,8 @@ static bool enabled = false; aWrapper = [ [ AquaA11yWrapperList alloc ] initWithAccessibleContext: rxAccessibleContext ]; } else if ( [ nativeRole isEqualToString: NSAccessibilitySplitterRole ] ) { aWrapper = [ [ AquaA11yWrapperSplitter alloc ] initWithAccessibleContext: rxAccessibleContext ]; + } else if ( [ nativeRole isEqualToString: NSAccessibilityTableRole ] ) { + aWrapper = [ [ AquaA11yTableWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ]; } else { aWrapper = [ [ AquaA11yWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ]; } diff --git a/vcl/aqua/source/a11y/aqua11ytablewrapper.h b/vcl/aqua/source/a11y/aqua11ytablewrapper.h index 8753365377e3..7bf3e44a2945 100644 --- a/vcl/aqua/source/a11y/aqua11ytablewrapper.h +++ b/vcl/aqua/source/a11y/aqua11ytablewrapper.h @@ -30,9 +30,15 @@ #include "aqua11ywrapper.h" -@interface AquaA11yTableWrapper : NSObject +#define MAXIMUM_ACCESSIBLE_TABLE_CELLS 1000 + +@interface AquaA11yTableWrapper : AquaA11yWrapper { } -+(id)childrenAttributeForElement:(AquaA11yWrapper *)wrapper; ++(id)childrenAttributeForElement:(AquaA11yTableWrapper *)wrapper; ++(void)addAttributeNamesTo: (NSMutableArray *)attributeNames object: (AquaA11yWrapper*)pObject; + +-(id)rowsAttribute; +-(id)columnsAttribute; @end #endif // _SV_AQUA11TABLEWRAPPER_H diff --git a/vcl/aqua/source/a11y/aqua11ytablewrapper.mm b/vcl/aqua/source/a11y/aqua11ytablewrapper.mm index 08205ac8a66b..98454ab8d57b 100644 --- a/vcl/aqua/source/a11y/aqua11ytablewrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ytablewrapper.mm @@ -35,38 +35,120 @@ using namespace ::com::sun::star::accessibility; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::uno; -@implementation AquaA11yTableWrapper : NSObject +@implementation AquaA11yTableWrapper : AquaA11yWrapper -+(id)childrenAttributeForElement:(AquaA11yWrapper *)wrapper ++(id)childrenAttributeForElement:(AquaA11yTableWrapper *)wrapper { - try + XAccessibleTable * accessibleTable = [ wrapper accessibleTable ]; + NSArray* pResult = nil; + if( accessibleTable ) { NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; - XAccessibleComponent * accessibleComponent = [ wrapper accessibleComponent ]; - XAccessibleTable * accessibleTable = [ wrapper accessibleTable ]; - // find out which cells are actually visible by determining the top-left-cell and the bottom-right-cell - Size tableSize = accessibleComponent -> getSize(); - Point point; - point.X = 0; - point.Y = 0; - Reference < XAccessible > rAccessibleTopLeft = accessibleComponent -> getAccessibleAtPoint ( point ); - point.X = tableSize.Width - 1; - point.Y = tableSize.Height - 1; - Reference < XAccessible > rAccessibleBottomRight = accessibleComponent -> getAccessibleAtPoint ( point ); - if ( rAccessibleTopLeft.is() && rAccessibleBottomRight.is() ) + try { - sal_Int32 idxTopLeft = rAccessibleTopLeft -> getAccessibleContext() -> getAccessibleIndexInParent(); - sal_Int32 idxBottomRight = rAccessibleBottomRight -> getAccessibleContext() -> getAccessibleIndexInParent(); - sal_Int32 rowTopLeft = accessibleTable -> getAccessibleRow ( idxTopLeft ); - sal_Int32 columnTopLeft = accessibleTable -> getAccessibleColumn ( idxTopLeft ); - sal_Int32 rowBottomRight = accessibleTable -> getAccessibleRow ( idxBottomRight ); - sal_Int32 columnBottomRight = accessibleTable -> getAccessibleColumn ( idxBottomRight ); - // create an array containing the visible cells - for ( sal_Int32 rowCount = rowTopLeft; rowCount <= rowBottomRight; rowCount++ ) + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) { - for ( sal_Int32 columnCount = columnTopLeft; columnCount <= columnBottomRight; columnCount++ ) + // make all children visible to the hierarchy + for ( sal_Int32 rowCount = 0; rowCount < nRows; rowCount++ ) { - Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + for ( sal_Int32 columnCount = 0; columnCount < nCols; columnCount++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + } + } + else + { + XAccessibleComponent * accessibleComponent = [ wrapper accessibleComponent ]; + // find out which cells are actually visible by determining the top-left-cell and the bottom-right-cell + Size tableSize = accessibleComponent -> getSize(); + Point point; + point.X = 0; + point.Y = 0; + Reference < XAccessible > rAccessibleTopLeft = accessibleComponent -> getAccessibleAtPoint ( point ); + point.X = tableSize.Width - 1; + point.Y = tableSize.Height - 1; + Reference < XAccessible > rAccessibleBottomRight = accessibleComponent -> getAccessibleAtPoint ( point ); + if ( rAccessibleTopLeft.is() && rAccessibleBottomRight.is() ) + { + sal_Int32 idxTopLeft = rAccessibleTopLeft -> getAccessibleContext() -> getAccessibleIndexInParent(); + sal_Int32 idxBottomRight = rAccessibleBottomRight -> getAccessibleContext() -> getAccessibleIndexInParent(); + sal_Int32 rowTopLeft = accessibleTable -> getAccessibleRow ( idxTopLeft ); + sal_Int32 columnTopLeft = accessibleTable -> getAccessibleColumn ( idxTopLeft ); + sal_Int32 rowBottomRight = accessibleTable -> getAccessibleRow ( idxBottomRight ); + sal_Int32 columnBottomRight = accessibleTable -> getAccessibleColumn ( idxBottomRight ); + // create an array containing the visible cells + for ( sal_Int32 rowCount = rowTopLeft; rowCount <= rowBottomRight; rowCount++ ) + { + for ( sal_Int32 columnCount = columnTopLeft; columnCount <= columnBottomRight; columnCount++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + } + } + } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + } + [cells autorelease]; + } + + return pResult; +} + ++(void)addAttributeNamesTo: (NSMutableArray *)attributeNames object: (AquaA11yWrapper*)pObject +{ + XAccessibleTable * accessibleTable = [ pObject accessibleTable ]; + if( accessibleTable ) + { + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + + + if( nRows*nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + [ attributeNames addObject: NSAccessibilityRowsAttribute ]; + [ attributeNames addObject: NSAccessibilityColumnsAttribute ]; + } + } +} + +-(id)rowsAttribute +{ + NSArray* pResult = nil; + + XAccessibleTable * accessibleTable = [ self accessibleTable ]; + if( accessibleTable ) + { + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; + try + { + // find out number of rows + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + for( sal_Int32 n = 0; n < nRows; n++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( n, 0 ); if ( rAccessibleCell.is() ) { id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; @@ -74,16 +156,56 @@ using namespace ::com::sun::star::uno; [ cell_wrapper release ]; } } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + pResult = nil; } + [ cells autorelease ]; } - [ cells autorelease ]; - return NSAccessibilityUnignoredChildren( cells ); } - catch (const Exception &e) + + return pResult; +} + +-(id)columnsAttribute +{ + NSArray* pResult = nil; + + XAccessibleTable * accessibleTable = [ self accessibleTable ]; + + if( accessibleTable ) { - // TODO: Log - return nil; + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; + try + { + // find out number of columns + for( sal_Int32 n = 0; n < nCols; n++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( 0, n ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + pResult = nil; + } + [ cells autorelease ]; + } } + + return pResult; } @end diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm b/vcl/aqua/source/a11y/aqua11ywrapper.mm index 959746d533dc..e86676e725f2 100644 --- a/vcl/aqua/source/a11y/aqua11ywrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm @@ -29,6 +29,8 @@ #include "precompiled_vcl.hxx" #include "salinst.h" +#include "saldata.hxx" + #include "aqua11ywrapper.h" #include "aqua11yactionwrapper.h" #include "aqua11ycomponentwrapper.h" @@ -41,6 +43,7 @@ #include "aqua11yfocuslistener.hxx" #include "aqua11yfocustracker.hxx" #include "aqua11yrolehelper.h" + #include <com/sun/star/accessibility/AccessibleRole.hpp> #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> @@ -217,7 +220,8 @@ static MacOSBOOL isPopupMenuOpen = NO; -(id)roleAttribute { if ( mActsAsRadioGroup ) { return NSAccessibilityRadioGroupRole; - } else { + } + else { return [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ]; } } @@ -323,8 +327,10 @@ static MacOSBOOL isPopupMenuOpen = NO; } } return children; - } else if ( [ self accessibleTable ] != nil ) { - return [ AquaA11yTableWrapper childrenAttributeForElement: self ]; + } else if ( [ self accessibleTable ] != nil ) + { + AquaA11yTableWrapper* pTable = [self isKindOfClass: [AquaA11yTableWrapper class]] ? (AquaA11yTableWrapper*)self : nil; + return [ AquaA11yTableWrapper childrenAttributeForElement: pTable ]; } else { try { NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; @@ -663,6 +669,7 @@ static MacOSBOOL isPopupMenuOpen = NO; if ( isPopupMenuOpen ) { return nil; } + id value = nil; // if we are no longer in the wrapper repository, we have been disposed AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ self accessibleContext ] createIfNotExists: NO ]; @@ -717,6 +724,7 @@ static MacOSBOOL isPopupMenuOpen = NO; NSString * nativeSubrole = nil; NSString * title = nil; NSMutableArray * attributeNames = nil; + sal_Int32 nAccessibleChildren = 0; try { // Default Attributes attributeNames = [ NSMutableArray arrayWithObjects: @@ -737,8 +745,9 @@ static MacOSBOOL isPopupMenuOpen = NO; } try { - if ( [ self accessibleContext ] -> getAccessibleChildCount() > 0 ) { - [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; + nAccessibleChildren = [ self accessibleContext ] -> getAccessibleChildCount(); + if ( nAccessibleChildren > 0 ) { + [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; } } catch( DisposedException& ) {} @@ -754,6 +763,9 @@ static MacOSBOOL isPopupMenuOpen = NO; [ attributeNames addObject: NSAccessibilityServesAsTitleForUIElementsAttribute ]; } // Special Attributes depending on interface + if( [self accessibleContext ] -> getAccessibleRole() == AccessibleRole::TABLE ) + [AquaA11yTableWrapper addAttributeNamesTo: attributeNames object: self]; + if ( [ self accessibleText ] != nil ) { [ AquaA11yTextWrapper addAttributeNamesTo: attributeNames ]; } @@ -953,14 +965,15 @@ static MacOSBOOL isPopupMenuOpen = NO; return hit; } -Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAccessibleContext > rxAccessibleContext ) { +Reference < XAccessibleContext > hitTestRunner ( com::sun::star::awt::Point point, + Reference < XAccessibleContext > rxAccessibleContext ) { Reference < XAccessibleContext > hitChild; Reference < XAccessibleContext > emptyReference; try { Reference < XAccessibleComponent > rxAccessibleComponent ( rxAccessibleContext, UNO_QUERY ); if ( rxAccessibleComponent.is() ) { - Point location = rxAccessibleComponent -> getLocationOnScreen(); - Point hitPoint ( point.X - location.X , point.Y - location.Y); + com::sun::star::awt::Point location = rxAccessibleComponent -> getLocationOnScreen(); + com::sun::star::awt::Point hitPoint ( point.X - location.X , point.Y - location.Y); Reference < XAccessible > rxAccessible = rxAccessibleComponent -> getAccessibleAtPoint ( hitPoint ); if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) { if ( rxAccessible -> getAccessibleContext() -> getAccessibleChildCount() > 0 ) { @@ -999,7 +1012,7 @@ Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAcces } Reference < XAccessibleContext > hitChild; NSRect screenRect = [ [ NSScreen mainScreen ] frame ]; - Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); + com::sun::star::awt::Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); // check child windows first NSWindow * window = (NSWindow *) [ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ]; NSArray * childWindows = [ window childWindows ]; diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index 62c59e78c963..b8a2261ed9db 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -474,6 +474,7 @@ AquaSalInstance::AquaSalInstance() mbWaitingYield = false; maUserEventListMutex = osl_createMutex(); mnActivePrintJobs = 0; + maWaitingYieldCond = osl_createCondition(); } // ----------------------------------------------------------------------- @@ -484,6 +485,7 @@ AquaSalInstance::~AquaSalInstance() mpSalYieldMutex->release(); delete mpSalYieldMutex; osl_destroyMutex( maUserEventListMutex ); + osl_destroyCondition( maWaitingYieldCond ); } // ----------------------------------------------------------------------- @@ -713,6 +715,7 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( aEvent.mpFrame && AquaSalFrame::isAlive( aEvent.mpFrame ) ) { aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData ); + osl_setCondition( maWaitingYieldCond ); // return if only one event is asked for if( ! bHandleAllCurrentEvents ) return; @@ -785,6 +788,18 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) (*it)->maInvalidRect.SetEmpty(); } } + osl_setCondition( maWaitingYieldCond ); + } + else if( bWait ) + { + // #i103162# + // wait until any thread (most likely the main thread) + // has dispatched an event, cop out at 200 ms + osl_resetCondition( maWaitingYieldCond ); + TimeValue aVal = { 0, 200000000 }; + ULONG nCount = ReleaseYieldMutex(); + osl_waitCondition( maWaitingYieldCond, &aVal ); + AcquireYieldMutex( nCount ); } // we get some apple events way too early diff --git a/vcl/aqua/source/dtrans/aqua_clipboard.cxx b/vcl/aqua/source/dtrans/aqua_clipboard.cxx index d3a4e9bc604c..52fb13e1e11f 100644 --- a/vcl/aqua/source/dtrans/aqua_clipboard.cxx +++ b/vcl/aqua/source/dtrans/aqua_clipboard.cxx @@ -189,6 +189,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf const Reference<XClipboardOwner>& xClipboardOwner) throw( RuntimeException ) { + NSArray* types = xTransferable.is() ? + mpDataFlavorMapper->flavorSequenceToTypesArray(xTransferable->getTransferDataFlavors()) : + [NSArray array]; + ClearableMutexGuard aGuard(m_aMutex); Reference<XClipboardOwner> oldOwner(mXClipboardOwner); @@ -197,11 +201,10 @@ void SAL_CALL AquaClipboard::setContents(const Reference<XTransferable>& xTransf Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = xTransferable; - NSArray* types = mXClipboardContent.is() ? - mpDataFlavorMapper->flavorSequenceToTypesArray(mXClipboardContent->getTransferDataFlavors()) : - [NSArray array]; mPasteboardChangeCount = [mPasteboard declareTypes: types owner: mEventListener]; + aGuard.clear(); + // if we are already the owner of the clipboard // then fire lost ownership event if (oldOwner.is()) @@ -253,7 +256,7 @@ void SAL_CALL AquaClipboard::removeClipboardListener(const Reference< XClipboard void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) { - MutexGuard aGuard(m_aMutex); + ClearableMutexGuard aGuard(m_aMutex); int currentPboardChgCount = [mPasteboard changeCount]; @@ -270,6 +273,8 @@ void AquaClipboard::applicationDidBecomeActive(NSNotification* aNotification) Reference<XTransferable> oldContent(mXClipboardContent); mXClipboardContent = Reference<XTransferable>(); + aGuard.clear(); + if (oldOwner.is()) { fireLostClipboardOwnershipEvent(oldOwner, oldContent); diff --git a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm index 74c66ab1401d..d00fc9a6cd0e 100644 --- a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm +++ b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm @@ -318,6 +318,12 @@ class ControllerProperties double fScaleX = double(aLogicSize.Width())/double(aPageSize.aSize.Width()); double fScaleY = double(aLogicSize.Height())/double(aPageSize.aSize.Height()); double fScale = (fScaleX < fScaleY) ? fScaleX : fScaleY; + // #i104784# if we render the page too small then rounding issues result in + // layout artifacts looking really bad. So scale the page unto a device that is not + // full page size but not too small either. This also results in much better visual + // quality of the preview, e.g. when its height approaches the number of text lines + if( fScale < 0.1 ) + fScale = 0.1; aMtf.WindStart(); aMtf.Scale( fScale, fScale ); aMtf.WindStart(); @@ -358,9 +364,10 @@ class ControllerProperties NSSize aMargins = [mpPreviewBox contentViewMargins]; aPreviewFrame.origin.x = 0; aPreviewFrame.origin.y = 34; + aPreviewFrame.size.width -= 2*(aMargins.width+1); aPreviewFrame.size.height -= 61; mpPreview = [[NSImageView alloc] initWithFrame: aPreviewFrame]; - [mpPreview setImageScaling: NSScaleNone]; + [mpPreview setImageScaling: NSScaleProportionally]; [mpPreview setImageAlignment: NSImageAlignCenter]; [mpPreview setImageFrameStyle: NSImageFrameNone]; [mpPreviewBox addSubview: [mpPreview autorelease]]; diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index 9c4ae4a40165..5b1e24befc9b 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -700,6 +700,13 @@ void AquaSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) { + if( nX1 == nX2 && nY1 == nY2 ) + { + // #i109453# platform independent code expects at least one pixel to be drawn + drawPixel( nX1, nY1 ); + return; + } + if( !CheckContext() ) return; @@ -1101,7 +1108,8 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" ); const CGPoint aDstPoint = { +pPosAry->mnDestX - pPosAry->mnSrcX, pPosAry->mnDestY - pPosAry->mnSrcY }; - if( !mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth ) // workaround a Quartz crasher + if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && pPosAry->mnSrcHeight == pPosAry->mnDestHeight) && + (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher { // in XOR mode the drawing context is redirected to the XOR mask // if source and target are identical then copyBits() paints onto the target context though diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index cee243093ff3..1c0401f769b5 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -532,8 +532,6 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, PrintAccessoryViewState aAccViewState; sal_Int32 nAllPages = 0; - aAccViewState.bNeedRestart = true; - // reset IsLastPage i_rController.setLastPage( sal_False ); @@ -549,111 +547,133 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, if( ! i_rController.isShowDialogs() ) bShowProgressPanel = sal_False; + // possibly create one job for collated output + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + // FIXME: jobStarted() should be done after the print dialog has ended (if there is one) // how do I know when that might be ? i_rController.jobStarted(); - do - { - if( aAccViewState.bNeedRestart ) - { - mnCurPageRangeStart = 0; - mnCurPageRangeCount = 0; - nAllPages = i_rController.getFilteredPageCount(); - } - aAccViewState.bNeedRestart = false; - Size aCurSize( 21000, 29700 ); - if( nAllPages > 0 ) + int nCopies = i_rController.getPrinter()->GetCopyCount(); + int nJobs = 1; + if( bSinglePrintJobs ) + { + nJobs = nCopies; + nCopies = 1; + } + + for( int nCurJob = 0; nCurJob < nJobs; nCurJob++ ) + { + aAccViewState.bNeedRestart = true; + do { - mnCurPageRangeCount = 1; - aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); - Size aNextSize( aCurSize ); + if( aAccViewState.bNeedRestart ) + { + mnCurPageRangeStart = 0; + mnCurPageRangeCount = 0; + nAllPages = i_rController.getFilteredPageCount(); + } - // print pages up to a different size - while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) + aAccViewState.bNeedRestart = false; + + Size aCurSize( 21000, 29700 ); + if( nAllPages > 0 ) { - aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); - if( aCurSize == aNextSize // same page size - || - (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation - ) + mnCurPageRangeCount = 1; + aCurSize = getPageSize( i_rController, mnCurPageRangeStart ); + Size aNextSize( aCurSize ); + + // print pages up to a different size + while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages ) { - mnCurPageRangeCount++; + aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount ); + if( aCurSize == aNextSize // same page size + || + (aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation + ) + { + mnCurPageRangeCount++; + } + else + break; } - else - break; } - } - else - mnCurPageRangeCount = 0; - - // now for the current run - mnStartPageOffsetX = mnStartPageOffsetY = 0; - // setup the paper size and orientation - // do this on our associated Printer object, since that is - // out interface to the applications which occasionally rely on the paper - // information (e.g. brochure printing scales to the found paper size) - // also SetPaperSizeUser has the advantage that we can share a - // platform independent paper matching algorithm - boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); - pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); - pPrinter->SetPaperSizeUser( aCurSize, true ); - - // create view - NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; - - NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; - - // set filename - if( i_pFileName ) - { - [mpPrintInfo setJobDisposition: NSPrintSaveJob]; - NSString* pPath = CreateNSString( *i_pFileName ); - [pPrintDict setObject: pPath forKey: NSPrintSavePath]; - [pPath release]; - } + else + mnCurPageRangeCount = 0; + + // now for the current run + mnStartPageOffsetX = mnStartPageOffsetY = 0; + // setup the paper size and orientation + // do this on our associated Printer object, since that is + // out interface to the applications which occasionally rely on the paper + // information (e.g. brochure printing scales to the found paper size) + // also SetPaperSizeUser has the advantage that we can share a + // platform independent paper matching algorithm + boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); + pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); + pPrinter->SetPaperSizeUser( aCurSize, true ); + + // create view + NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this]; + + NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary]; + + // set filename + if( i_pFileName ) + { + [mpPrintInfo setJobDisposition: NSPrintSaveJob]; + NSString* pPath = CreateNSString( *i_pFileName ); + [pPrintDict setObject: pPath forKey: NSPrintSavePath]; + [pPath release]; + } - [pPrintDict setObject: [[NSNumber numberWithInt: (int)i_rController.getPrinter()->GetCopyCount()] autorelease] forKey: NSPrintCopies]; - [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; - [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; - // #i103253# weird: for some reason, autoreleasing the value below like the others above - // leads do a double free malloc error. Why this value should behave differently from all the others - // is a mystery. - [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; + [pPrintDict setObject: [[NSNumber numberWithInt: nCopies] autorelease] forKey: NSPrintCopies]; + [pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting]; + [pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage]; + // #i103253# weird: for some reason, autoreleasing the value below like the others above + // leads do a double free malloc error. Why this value should behave differently from all the others + // is a mystery. + [pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage]; - // create print operation - NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; + // create print operation + NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo]; - if( pPrintOperation ) - { - NSObject* pReleaseAfterUse = nil; - bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); - [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; - [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; - - // set job title (since MacOSX 10.5) - if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) - [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; - - if( bShowPanel && mnCurPageRangeStart == 0 ) // only the first range of pages gets the accesory view - pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; - - bSuccess = TRUE; - mbJob = true; - pInst->startedPrintJob(); - [pPrintOperation runOperation]; - pInst->endedPrintJob(); - bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; - mbJob = false; - if( pReleaseAfterUse ) - [pReleaseAfterUse release]; - } + if( pPrintOperation ) + { + NSObject* pReleaseAfterUse = nil; + bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() ); + [pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ]; + [pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO]; + + // set job title (since MacOSX 10.5) + if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] ) + [pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]]; + + if( bShowPanel && mnCurPageRangeStart == 0 && nCurJob == 0) // only the first range of pages (in the first job) gets the accesory view + pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState]; + + bSuccess = TRUE; + mbJob = true; + pInst->startedPrintJob(); + [pPrintOperation runOperation]; + pInst->endedPrintJob(); + bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame; + mbJob = false; + if( pReleaseAfterUse ) + [pReleaseAfterUse release]; + } - mnCurPageRangeStart += mnCurPageRangeCount; - mnCurPageRangeCount = 1; - } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + mnCurPageRangeStart += mnCurPageRangeCount; + mnCurPageRangeCount = 1; + } while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages ); + } // inform application that it can release its data // this is awkward, but the XRenderable interface has no method for this, diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx index 413b5bcd5490..b14354e1b4bd 100644 --- a/vcl/aqua/source/window/salframe.cxx +++ b/vcl/aqua/source/window/salframe.cxx @@ -1128,6 +1128,16 @@ static Font getFont( NSFont* pFont, long nDPIY, const Font& rDefault ) return aResult; } +void AquaSalFrame::getResolution( long& o_rDPIX, long& o_rDPIY ) +{ + if( ! mpGraphics ) + { + GetGraphics(); + ReleaseGraphics( mpGraphics ); + } + mpGraphics->GetResolution( o_rDPIX, o_rDPIY ); +} + // on OSX-Aqua the style settings are independent of the frame, so it does // not really belong here. Since the connection to the Appearance_Manager // is currently done in salnativewidgets.cxx this would be a good place. @@ -1157,13 +1167,8 @@ void AquaSalFrame::UpdateSettings( AllSettings& rSettings ) // get the system font settings Font aAppFont = aStyleSettings.GetAppFont(); - if( ! mpGraphics ) - { - GetGraphics(); - ReleaseGraphics( mpGraphics ); - } long nDPIX = 72, nDPIY = 72; - mpGraphics->GetResolution( nDPIX, nDPIY ); + getResolution( nDPIX, nDPIY ); aAppFont = getFont( [NSFont systemFontOfSize: 0], nDPIY, aAppFont ); // TODO: better mapping of aqua<->ooo font settings diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm index 67926a38608d..0dfa0fa356aa 100755 --- a/vcl/aqua/source/window/salframeview.mm +++ b/vcl/aqua/source/window/salframeview.mm @@ -37,7 +37,9 @@ #include "vcl/window.hxx" #include "vcl/svapp.hxx" - + +#define WHEEL_EVENT_FACTOR 1.5 + static USHORT ImplGetModifierMask( unsigned int nMask ) { USHORT nRet = 0; @@ -654,11 +656,12 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); - aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -667,11 +670,11 @@ private: if( dZ != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dZ)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dZ < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dZ < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; + aEvent.mnScrollLines = dZ > 0 ? dZ/WHEEL_EVENT_FACTOR : -dZ/WHEEL_EVENT_FACTOR; if( aEvent.mnScrollLines == 0 ) aEvent.mnScrollLines = 1; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -712,10 +715,11 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -724,9 +728,9 @@ private: if( dX != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dX)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dX < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = TRUE; aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -734,9 +738,9 @@ private: if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame )) { aEvent.mnDelta = static_cast<long>(floor(dY)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dY < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -771,10 +775,11 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -783,30 +788,27 @@ private: if( dX != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dX)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dX < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = TRUE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; + aEvent.mnScrollLines = dY > 0 ? dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR; if( aEvent.mnScrollLines == 0 ) aEvent.mnScrollLines = 1; - if( aEvent.mnScrollLines > 15 ) - aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); } if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) { aEvent.mnDelta = static_cast<long>(floor(dY)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dY < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; - if( aEvent.mnScrollLines == 0 ) + aEvent.mnScrollLines = dY > 0 ? dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR; + if( aEvent.mnScrollLines < 1 ) aEvent.mnScrollLines = 1; - if( aEvent.mnScrollLines > 15 ) - aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; - + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); } } |