diff options
Diffstat (limited to 'vcl')
293 files changed, 10888 insertions, 12212 deletions
diff --git a/vcl/aqua/inc/salframeview.h b/vcl/aqua/inc/salframeview.h index 498c9679e97c..e7d9a14b52aa 100755 --- a/vcl/aqua/inc/salframeview.h +++ b/vcl/aqua/inc/salframeview.h @@ -37,6 +37,7 @@ } -(id)initWithSalFrame: (AquaSalFrame*)pFrame; -(MacOSBOOL)canBecomeKeyWindow; +-(void)displayIfNeeded; -(void)windowDidBecomeKey: (NSNotification*)pNotification; -(void)windowDidResignKey: (NSNotification*)pNotification; -(void)windowDidChangeScreen: (NSNotification*)pNotification; @@ -77,6 +78,10 @@ id mpMouseEventListener; id mDraggingDestinationHandler; NSEvent* mpLastSuperEvent; + + // #i102807# used by magnify event handler + NSTimeInterval mfLastMagnifyTime; + float mfMagnifyDeltaSum; } +(void)unsetMouseFrame: (AquaSalFrame*)pFrame; -(id)initWithSalFrame: (AquaSalFrame*)pFrame; @@ -108,6 +113,7 @@ -(MacOSBOOL)sendKeyToFrameDirect: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod; -(MacOSBOOL)sendSingleCharacter:(NSEvent*)pEvent; -(MacOSBOOL)handleKeyDownException:(NSEvent*)pEvent; +-(void)clearLastEvent; /* text action methods */ diff --git a/vcl/aqua/inc/salgdi.h b/vcl/aqua/inc/salgdi.h index 247de1b95dec..17c4aa7acd44 100644 --- a/vcl/aqua/inc/salgdi.h +++ b/vcl/aqua/inc/salgdi.h @@ -59,7 +59,7 @@ public: virtual ImplFontEntry* CreateFontInstance( ImplFontSelectData& ) const; virtual sal_IntPtr GetFontId() const; - ImplFontCharMap* GetImplFontCharMap() const; + const ImplFontCharMap* GetImplFontCharMap() const; bool HasChar( sal_uInt32 cChar ) const; void ReadOs2Table() const; @@ -68,7 +68,7 @@ public: private: const ATSUFontID mnFontId; - mutable ImplFontCharMap* mpCharMap; + mutable const ImplFontCharMap* mpCharMap; mutable bool mbOs2Read; // true if OS2-table related info is valid mutable bool mbHasOs2Table; mutable bool mbCmapEncodingRead; // true if cmap encoding of Mac font is read @@ -191,7 +191,7 @@ public: virtual sal_Bool drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolyPolygonBezier( ULONG nPoly, const ULONG* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ); // CopyArea --> No RasterOp, but ClipRegion virtual void copyArea( long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth, @@ -229,17 +229,17 @@ public: CGPoint* makeCGptArray(ULONG nPoints, const SalPoint* pPtAry); // native widget rendering methods that require mirroring - virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); - virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, + virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); // get device resolution virtual void GetResolution( long& rDPIX, long& rDPIY ); @@ -276,12 +276,12 @@ public: // set the font virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); // get the current font's etrics - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); // get kernign pairs of the current font // return only PairCount if (pKernPairs == NULL) virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); // get the repertoire of the current font - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; // graphics must fill supplied font list virtual void GetDevFontList( ImplDevFontList* ); // graphics should call ImplAddDevFontSubstitute on supplied diff --git a/vcl/aqua/inc/salinst.h b/vcl/aqua/inc/salinst.h index 0bceb99d1d0e..4b0385844eed 100644 --- a/vcl/aqua/inc/salinst.h +++ b/vcl/aqua/inc/salinst.h @@ -134,9 +134,10 @@ public: virtual vos::IMutex* GetYieldMutex(); virtual ULONG ReleaseYieldMutex(); virtual void AcquireYieldMutex( ULONG nCount ); + virtual bool CheckYieldMutex(); virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); virtual bool AnyInput( USHORT nType ); - virtual SalMenu* CreateMenu( BOOL bMenuBar ); + virtual SalMenu* CreateMenu( BOOL bMenuBar, Menu* pVCLMenu ); virtual void DestroyMenu( SalMenu* ); virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); virtual void DestroyMenuItem( SalMenuItem* ); diff --git a/vcl/aqua/inc/salobj.h b/vcl/aqua/inc/salobj.h index 0041b22c16a0..56b07cea4262 100644 --- a/vcl/aqua/inc/salobj.h +++ b/vcl/aqua/inc/salobj.h @@ -81,6 +81,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/aqua/inc/salsys.h b/vcl/aqua/inc/salsys.h index 6f5c45880e68..ae20706a1756 100644 --- a/vcl/aqua/inc/salsys.h +++ b/vcl/aqua/inc/salsys.h @@ -55,11 +55,6 @@ public: virtual Rectangle GetDisplayWorkAreaPosSizePixel( unsigned int nScreen ); virtual rtl::OUString GetScreenName( unsigned int nScreen ); - // overload pure virtual methods - virtual int ShowNativeDialog( const String& rTitle, - const String& rMessage, - const std::list< String >& rButtons, - int nDefButton ); virtual int ShowNativeMessageBox( const String& rTitle, const String& rMessage, int nButtonCombination, diff --git a/vcl/aqua/source/a11y/aqua11yselectionwrapper.mm b/vcl/aqua/source/a11y/aqua11yselectionwrapper.mm index 53ab6dd36128..804cf108dba8 100644 --- a/vcl/aqua/source/a11y/aqua11yselectionwrapper.mm +++ b/vcl/aqua/source/a11y/aqua11yselectionwrapper.mm @@ -40,20 +40,23 @@ using namespace ::com::sun::star::uno; +(id)selectedChildrenAttributeForElement:(AquaA11yWrapper *)wrapper { Reference< XAccessibleSelection > xAccessibleSelection = [ wrapper accessibleSelection ]; - NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; - - try { - sal_Int32 n = xAccessibleSelection -> getSelectedAccessibleChildCount(); - for ( sal_Int32 i=0 ; i < n ; ++i ) { - [ children addObject: [ AquaA11yFactory wrapperForAccessible: xAccessibleSelection -> getSelectedAccessibleChild( i ) ] ]; + if( xAccessibleSelection.is() ) + { + NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; + try { + sal_Int32 n = xAccessibleSelection -> getSelectedAccessibleChildCount(); + for ( sal_Int32 i=0 ; i < n ; ++i ) { + [ children addObject: [ AquaA11yFactory wrapperForAccessible: xAccessibleSelection -> getSelectedAccessibleChild( i ) ] ]; + } + + return children; + + } catch ( Exception& e) + { } - - return children; - - } catch ( Exception& e) { - return nil; } + return nil; } diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index b8a2261ed9db..5d2fc3f00741 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -371,13 +371,13 @@ SalYieldMutex::SalYieldMutex() void SalYieldMutex::acquire() { OMutex::acquire(); - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; } void SalYieldMutex::release() { - if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + if ( mnThreadId == vos::OThread::getCurrentIdentifier() ) { if ( mnCount == 1 ) mnThreadId = 0; @@ -390,7 +390,7 @@ sal_Bool SalYieldMutex::tryToAcquire() { if ( OMutex::tryToAcquire() ) { - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; return sal_True; } @@ -449,7 +449,7 @@ SalInstance* CreateSalInstance() ImplGetSVData()->maNWFData.mbCenteredTabs = true; ImplGetSVData()->maNWFData.mbProgressNeedsErase = true; ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase = true; - ImplGetSVData()->maGDIData.mbPrinterPullModel = true; + ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset = 10; ImplGetSVData()->maGDIData.mbNoXORClipping = true; ImplGetSVData()->maWinData.mbNoSaveBackground = true; @@ -536,7 +536,7 @@ ULONG AquaSalInstance::ReleaseYieldMutex() { SalYieldMutex* pYieldMutex = mpSalYieldMutex; if ( pYieldMutex->GetThreadId() == - NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + vos::OThread::getCurrentIdentifier() ) { ULONG nCount = pYieldMutex->GetAcquireCount(); ULONG n = nCount; @@ -566,6 +566,22 @@ void AquaSalInstance::AcquireYieldMutex( ULONG nCount ) // ----------------------------------------------------------------------- +bool AquaSalInstance::CheckYieldMutex() +{ + bool bRet = true; + + SalYieldMutex* pYieldMutex = mpSalYieldMutex; + if ( pYieldMutex->GetThreadId() != + vos::OThread::getCurrentIdentifier() ) + { + bRet = false; + } + + return bRet; +} + +// ----------------------------------------------------------------------- + bool AquaSalInstance::isNSAppThread() const { return vos::OThread::getCurrentIdentifier() == maMainThread; @@ -975,6 +991,9 @@ void AquaSalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo ) XubString AquaSalInstance::GetDefaultPrinter() { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( ! maDefaultPrinter.getLength() ) { NSPrintInfo* pPI = [NSPrintInfo sharedPrintInfo]; @@ -999,6 +1018,9 @@ XubString AquaSalInstance::GetDefaultPrinter() SalInfoPrinter* AquaSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueInfo, ImplJobSetup* pSetupData ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + SalInfoPrinter* pNewInfoPrinter = NULL; if( pQueueInfo ) { @@ -1014,6 +1036,9 @@ SalInfoPrinter* AquaSalInstance::CreateInfoPrinter( SalPrinterQueueInfo* pQueueI void AquaSalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + delete pPrinter; } diff --git a/vcl/aqua/source/app/salsys.cxx b/vcl/aqua/source/app/salsys.cxx index 3b548099feef..cf5cf00b7fe4 100644 --- a/vcl/aqua/source/app/salsys.cxx +++ b/vcl/aqua/source/app/salsys.cxx @@ -30,9 +30,11 @@ #include "tools/rc.hxx" #include "vcl/svids.hrc" +#include "vcl/button.hxx" #include "salsys.h" #include "saldata.hxx" +#include "salinst.h" #include "rtl/ustrbuf.hxx" using namespace rtl; @@ -114,12 +116,22 @@ rtl::OUString AquaSalSystem::GetScreenName( unsigned int nScreen ) return aRet; } -int AquaSalSystem::ShowNativeDialog( const String& rTitle, - const String& rMessage, - const std::list< String >& rButtons, - int nDefButton ) +static NSString* getStandardString( int nButtonId ) { - return 0; + rtl::OUString aText( Button::GetStandardText( nButtonId ) ); + if( ! aText.getLength() ) // this is for bad cases, we might be missing the vcl resource + { + switch( nButtonId ) + { + case BUTTON_OK: aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OK" ) );break; + case BUTTON_ABORT: aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Abort" ) );break; + case BUTTON_CANCEL: aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cancel" ) );break; + case BUTTON_RETRY: aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Retry" ) );break; + case BUTTON_YES: aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Yes" ) );break; + case BUTTON_NO : aText = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No" ) );break; + } + } + return aText.getLength() ? CreateNSString( aText) : nil; } int AquaSalSystem::ShowNativeMessageBox( const String& rTitle, @@ -127,5 +139,82 @@ int AquaSalSystem::ShowNativeMessageBox( const String& rTitle, int nButtonCombination, int nDefaultButton) { - return 0; + NSString* pTitle = CreateNSString( rTitle ); + NSString* pMessage = CreateNSString( rMessage ); + + struct id_entry + { + int nCombination; + int nDefaultButton; + int nTextIds[3]; + } aButtonIds[] = + { + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK, { BUTTON_OK, -1, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK, { BUTTON_OK, BUTTON_CANCEL, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_OK_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, { BUTTON_CANCEL, BUTTON_OK, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_ABORT_RETRY_IGNORE, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_ABORT, { BUTTON_ABORT, BUTTON_IGNORE, BUTTON_RETRY } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_ABORT_RETRY_IGNORE, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_RETRY, { BUTTON_RETRY, BUTTON_IGNORE, BUTTON_ABORT } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_ABORT_RETRY_IGNORE, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_IGNORE, { BUTTON_IGNORE, BUTTON_IGNORE, BUTTON_ABORT } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_YES_NO_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_YES, { BUTTON_YES, BUTTON_NO, BUTTON_CANCEL } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_YES_NO_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, { BUTTON_NO, BUTTON_YES, BUTTON_CANCEL } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_YES_NO_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, { BUTTON_CANCEL, BUTTON_YES, BUTTON_NO } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_YES_NO, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_YES, { BUTTON_YES, BUTTON_NO, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_YES_NO, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO, { BUTTON_NO, BUTTON_YES, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_RETRY, { BUTTON_RETRY, BUTTON_CANCEL, -1 } }, + { SALSYSTEM_SHOWNATIVEMSGBOX_BTNCOMBI_RETRY_CANCEL, SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL, { BUTTON_CANCEL, BUTTON_RETRY, -1 } } + }; + + NSString* pDefText = nil; + NSString* pAltText = nil; + NSString* pOthText = nil; + + unsigned int nC; + for( nC = 0; nC < sizeof(aButtonIds)/sizeof(aButtonIds[0]); nC++ ) + { + if( aButtonIds[nC].nCombination == nButtonCombination ) + { + if( aButtonIds[nC].nDefaultButton == nDefaultButton ) + { + if( aButtonIds[nC].nTextIds[0] != -1 ) + pDefText = getStandardString( aButtonIds[nC].nTextIds[0] ); + if( aButtonIds[nC].nTextIds[1] != -1 ) + pAltText = getStandardString( aButtonIds[nC].nTextIds[1] ); + if( aButtonIds[nC].nTextIds[2] != -1 ) + pOthText = getStandardString( aButtonIds[nC].nTextIds[2] ); + break; + } + } + } + + + int nResult = NSRunAlertPanel( pTitle, pMessage, pDefText, pAltText, pOthText ); + + if( pTitle ) + [pTitle release]; + if( pMessage ) + [pMessage release]; + if( pDefText ) + [pDefText release]; + if( pAltText ) + [pAltText release]; + if( pOthText ) + [pOthText release]; + + int nRet = 0; + if( nC < sizeof(aButtonIds)/sizeof(aButtonIds[0]) && nResult >= 1 && nResult <= 3 ) + { + int nPressed = aButtonIds[nC].nTextIds[nResult-1]; + switch( nPressed ) + { + case BUTTON_NO: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_NO; break; + case BUTTON_YES: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_YES; break; + case BUTTON_OK: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_OK; break; + case BUTTON_CANCEL: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_CANCEL; break; + case BUTTON_ABORT: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_ABORT; break; + case BUTTON_RETRY: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_RETRY; break; + case BUTTON_IGNORE: nRet = SALSYSTEM_SHOWNATIVEMSGBOX_BTN_IGNORE; break; + } + } + + return nRet; } diff --git a/vcl/aqua/source/app/vclnsapp.mm b/vcl/aqua/source/app/vclnsapp.mm index f33599fa086e..5a476e0a54cc 100755 --- a/vcl/aqua/source/app/vclnsapp.mm +++ b/vcl/aqua/source/app/vclnsapp.mm @@ -39,6 +39,8 @@ #include "vcl/cmdevt.hxx" #include "rtl/ustrbuf.hxx" +#include "vcl/impimagetree.hxx" + #include "premac.h" #import "Carbon/Carbon.h" #import "apple_remote/RemoteControl.h" @@ -358,69 +360,35 @@ -(NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication *) app { - SalData* pSalData = GetSalData(); - #if 1 // currently do some really bad hack - if( ! pSalData->maFrames.empty() ) + NSApplicationTerminateReply aReply = NSTerminateNow; { - /* #i92766# something really weird is going on with the retain count of - our windows; sometimes we get a duplicate free before exit on one of our - NSWindows. The reason is unclear; to avoid this currently we retain them once more - - FIXME: this is a really bad hack, relying on the system to catch the leaked - resources. Find out what really goes on here and fix it ! - */ - std::vector< NSWindow* > aHackRetainedWindows; - for( std::list< AquaSalFrame* >::iterator it = pSalData->maFrames.begin(); - it != pSalData->maFrames.end(); ++it ) + YIELD_GUARD; + + SalData* pSalData = GetSalData(); + if( ! pSalData->maFrames.empty() ) { - #if OSL_DEBUG_LEVEL > 1 - Window* pWin = (*it)->GetWindow(); - String aTitle = pWin->GetText(); - Window* pClient = pWin->ImplGetClientWindow(); - fprintf( stderr, "retaining %p (old count %d) windowtype=%s clienttyp=%s title=%s\n", - (*it)->mpWindow, [(*it)->mpWindow retainCount], - typeid(*pWin).name(), pClient ? typeid(*pClient).name() : "<nil>", - rtl::OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() - ); - #endif - [(*it)->mpWindow retain]; - aHackRetainedWindows.push_back( (*it)->mpWindow ); + // the following QueryExit will likely present a message box, activate application + [NSApp activateIgnoringOtherApps: YES]; + aReply = pSalData->maFrames.front()->CallCallback( SALEVENT_SHUTDOWN, NULL ) ? NSTerminateCancel : NSTerminateNow; } - if( pSalData->maFrames.front()->CallCallback( SALEVENT_SHUTDOWN, NULL ) ) + + if( aReply == NSTerminateNow ) { - for( std::vector< NSWindow* >::iterator it = aHackRetainedWindows.begin(); - it != aHackRetainedWindows.end(); ++it ) - { - // clean up the retaing count again from the shutdown workaround - #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "releasing %p\n", (*it) ); - #endif - [(*it) release]; - } - return NSTerminateCancel; + ApplicationEvent aEv( String(), ApplicationAddress(), ByteString( "PRIVATE:DOSHUTDOWN" ), String() ); + GetpApp()->AppEvent( aEv ); + ImplImageTreeSingletonRef()->shutDown(); + // DeInitVCL should be called in ImplSVMain - unless someon _exits first which + // can occur in Desktop::doShutdown for example } - #if OSL_DEBUG_LEVEL > 1 - for( std::list< AquaSalFrame* >::iterator it = pSalData->maFrames.begin(); - it != pSalData->maFrames.end(); ++it ) - { - Window* pWin = (*it)->GetWindow(); - String aTitle = pWin->GetText(); - Window* pClient = pWin->ImplGetClientWindow(); - fprintf( stderr, "frame still alive: NSWindow %p windowtype=%s clienttyp=%s title=%s\n", - (*it)->mpWindow, typeid(*pWin).name(), pClient ? typeid(*pClient).name() : "<nil>", - rtl::OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() - ); - } - #endif } - #else // the clean version follows - return pSalData->maFrames.front()->CallCallback( SALEVENT_SHUTDOWN, NULL ) ? NSTerminateCancel : NSTerminateNow; - #endif - return NSTerminateNow; + + return aReply; } -(void)systemColorsChanged: (NSNotification*) pNotification { + YIELD_GUARD; + const SalData* pSalData = GetSalData(); if( !pSalData->maFrames.empty() ) pSalData->maFrames.front()->CallCallback( SALEVENT_SETTINGSCHANGED, NULL ); @@ -428,6 +396,8 @@ -(void)screenParametersChanged: (NSNotification*) pNotification { + YIELD_GUARD; + SalData* pSalData = GetSalData(); std::list< AquaSalFrame* >::iterator it; for( it = pSalData->maFrames.begin(); it != pSalData->maFrames.end(); ++it ) diff --git a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx index e0a95a532bf8..01f989cbc1c1 100644 --- a/vcl/aqua/source/dtrans/DataFlavorMapping.cxx +++ b/vcl/aqua/source/dtrans/DataFlavorMapping.cxx @@ -575,11 +575,19 @@ DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Refe if (isByteSequenceType(data.getValueType())) { + /* + the HTMLFormatDataProvider prepends segment information to HTML + this is useful for exchange with MS Word (which brings this stuff from Windows) + but annoying for other applications. Since this extension is not a standard datatype + on the Mac, let us not provide but provide normal HTML + if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame) { dp = DataProviderPtr_t(new HTMLFormatDataProvider(data)); } - else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) + else + */ + if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) { dp = DataProviderPtr_t(new BMPDataProvider(data, PICTImageFileType)); } diff --git a/vcl/aqua/source/dtrans/DragSource.cxx b/vcl/aqua/source/dtrans/DragSource.cxx index adb247d70711..1a8f950e50d4 100644 --- a/vcl/aqua/source/dtrans/DragSource.cxx +++ b/vcl/aqua/source/dtrans/DragSource.cxx @@ -38,6 +38,7 @@ #include "DragSourceContext.hxx" #include "aqua_clipboard.hxx" #include "DragActionConversion.hxx" +#include "salframe.h" #include <rtl/ustring.h> #include <memory> @@ -158,6 +159,7 @@ Sequence<OUString> dragSource_getSupportedServiceNames() DragSource::DragSource(): WeakComponentImplHelper3<XDragSource, XInitialization, XServiceInfo>(m_aMutex), mView(NULL), + mpFrame(NULL), mLastMouseEventBeforeStartDrag(nil), m_MouseButton(0) { @@ -166,8 +168,9 @@ DragSource::DragSource(): DragSource::~DragSource() { - [(id <MouseEventListener>)mView unregisterMouseEventListener: mDragSourceHelper]; - [mDragSourceHelper release]; + if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) + [(id <MouseEventListener>)mView unregisterMouseEventListener: mDragSourceHelper]; + [mDragSourceHelper release]; } @@ -197,6 +200,13 @@ void SAL_CALL DragSource::initialize(const Sequence< Any >& aArguments) throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Provided view doesn't support mouse listener")), static_cast<OWeakObject*>(this)); } + NSWindow* pWin = [mView window]; + if( ! pWin || ![pWin respondsToSelector: @selector(getSalFrame)] ) + { + throw Exception(OUString(RTL_CONSTASCII_USTRINGPARAM("DragSource::initialize: Provided view is not attached to a vcl frame")), + static_cast<OWeakObject*>(this)); + } + mpFrame = (AquaSalFrame*)[pWin performSelector: @selector(getSalFrame)]; mDragSourceHelper = [[DragSourceHelper alloc] initWithDragSource: this]; diff --git a/vcl/aqua/source/dtrans/DragSource.hxx b/vcl/aqua/source/dtrans/DragSource.hxx index 5d02b9874149..f8f55176a308 100644 --- a/vcl/aqua/source/dtrans/DragSource.hxx +++ b/vcl/aqua/source/dtrans/DragSource.hxx @@ -46,6 +46,7 @@ class DragSource; +class AquaSalFrame; /* The functions declared in this protocol are actually declared in vcl/aqua/inc/salframe.h. Because we want @@ -120,6 +121,7 @@ public: com::sun::star::uno::Reference< com::sun::star::datatransfer::dnd::XDragSourceContext > mXCurrentContext; id mView; + AquaSalFrame* mpFrame; NSEvent* mLastMouseEventBeforeStartDrag; DragSourceHelper* mDragSourceHelper; com::sun::star::awt::MouseEvent mMouseEvent; diff --git a/vcl/aqua/source/dtrans/aqua_clipboard.cxx b/vcl/aqua/source/dtrans/aqua_clipboard.cxx index 52fb13e1e11f..abffeebcb6c1 100644 --- a/vcl/aqua/source/dtrans/aqua_clipboard.cxx +++ b/vcl/aqua/source/dtrans/aqua_clipboard.cxx @@ -322,14 +322,17 @@ void AquaClipboard::fireLostClipboardOwnershipEvent(Reference<XClipboardOwner> o void AquaClipboard::provideDataForType(NSPasteboard* sender, NSString* type) { - DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent); - NSData* pBoardData = NULL; - - if (dp.get() != NULL) - { - pBoardData = (NSData*)dp->getSystemData(); - [sender setData: pBoardData forType: type]; - } + if( mXClipboardContent.is() ) + { + DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent); + NSData* pBoardData = NULL; + + if (dp.get() != NULL) + { + pBoardData = (NSData*)dp->getSystemData(); + [sender setData: pBoardData forType: type]; + } + } } @@ -340,20 +343,21 @@ void AquaClipboard::provideDataForType(NSPasteboard* sender, NSString* type) void SAL_CALL AquaClipboard::flushClipboard() throw(RuntimeException) { - if (mXClipboardContent.is()) + if (mXClipboardContent.is()) { Sequence<DataFlavor> flavorList = mXClipboardContent->getTransferDataFlavors(); sal_uInt32 nFlavors = flavorList.getLength(); for (sal_uInt32 i = 0; i < nFlavors; i++) - { + { NSString* sysType = mpDataFlavorMapper->openOfficeToSystemFlavor(flavorList[i]); if (sysType != NULL) - { + { provideDataForType(mPasteboard, sysType); - } - } + } + } + mXClipboardContent.clear(); } } diff --git a/vcl/aqua/source/dtrans/aqua_service.cxx b/vcl/aqua/source/dtrans/aqua_service.cxx index 571bea2e554f..57ef1f11175c 100644 --- a/vcl/aqua/source/dtrans/aqua_service.cxx +++ b/vcl/aqua/source/dtrans/aqua_service.cxx @@ -58,28 +58,6 @@ void SAL_CALL component_getImplementationEnvironment( *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; } -sal_Bool SAL_CALL component_writeInfo( void* pServiceManager, void* pRegistryKey ) -{ - sal_Bool bRetVal = sal_False; - - if ( pRegistryKey ) - { - try - { - Reference< XRegistryKey > pXNewKey( static_cast< XRegistryKey* >( pRegistryKey ) ); - pXNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM( AQUA_CLIPBOARD_REGKEY_NAME ) ) ); - bRetVal = sal_True; - } - catch( InvalidRegistryException& ) - { - OSL_ENSURE(sal_False, "InvalidRegistryException caught"); - bRetVal = sal_False; - } - } - - return bRetVal; -} - void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* pRegistryKey ) { void* pRet = 0; diff --git a/vcl/aqua/source/dtrans/service_entry.cxx b/vcl/aqua/source/dtrans/service_entry.cxx index 16308951bcfe..222b5cf40e04 100644 --- a/vcl/aqua/source/dtrans/service_entry.cxx +++ b/vcl/aqua/source/dtrans/service_entry.cxx @@ -34,6 +34,7 @@ #include "DropTarget.hxx" #include "aqua_clipboard.hxx" #include "osl/diagnose.h" +#include "vcl/svapp.hxx" using namespace ::osl; using namespace ::rtl; @@ -45,6 +46,9 @@ using namespace ::com::sun::star::datatransfer::clipboard; Reference< XInterface > AquaSalInstance::CreateClipboard( const Sequence< Any >& i_rArguments ) { + if ( Application::IsHeadlessModeEnabled() ) + return SalInstance::CreateClipboard( i_rArguments ); + SalData* pSalData = GetSalData(); if( ! pSalData->mxClipboard.is() ) pSalData->mxClipboard = Reference<XInterface>(static_cast< XClipboard* >(new AquaClipboard()), UNO_QUERY); @@ -54,11 +58,17 @@ Reference< XInterface > AquaSalInstance::CreateClipboard( const Sequence< Any >& Reference<XInterface> AquaSalInstance::CreateDragSource() { + if ( Application::IsHeadlessModeEnabled() ) + return SalInstance::CreateDragSource(); + return Reference<XInterface>(static_cast< XInitialization* >(new DragSource()), UNO_QUERY); } Reference<XInterface> AquaSalInstance::CreateDropTarget() { - return Reference<XInterface>(static_cast< XInitialization* >(new DropTarget()), UNO_QUERY); + if ( Application::IsHeadlessModeEnabled() ) + return SalInstance::CreateDropTarget(); + + return Reference<XInterface>(static_cast< XInitialization* >(new DropTarget()), UNO_QUERY); } diff --git a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm index d00fc9a6cd0e..93945570dc96 100644 --- a/vcl/aqua/source/gdi/aquaprintaccessoryview.mm +++ b/vcl/aqua/source/gdi/aquaprintaccessoryview.mm @@ -112,7 +112,7 @@ class ControllerProperties maLocalizedStrings( VclResId( SV_PRINT_NATIVE_STRINGS ) ) { mpState->bNeedRestart = false; - DBG_ASSERT( maLocalizedStrings.Count() >= 4, "resources not found !" ); + DBG_ASSERT( maLocalizedStrings.Count() >= 5, "resources not found !" ); } rtl::OUString getMoreString() @@ -122,6 +122,13 @@ class ControllerProperties : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "More" ) ); } + rtl::OUString getPrintSelectionString() + { + return maLocalizedStrings.Count() >= 5 + ? rtl::OUString( maLocalizedStrings.GetString( 4 ) ) + : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Print selection only" ) ); + } + void updatePrintJob() { // TODO: refresh page count etc from mpController @@ -246,7 +253,11 @@ class ControllerProperties PropertyValue* pVal = mpController->getValue( name_it->second ); if( pVal ) { - pVal->Value <<= i_bValue; + // ugly + if( name_it->second.equalsAscii( "PrintContent" ) ) + pVal->Value <<= i_bValue ? sal_Int32(2) : sal_Int32(0); + else + pVal->Value <<= i_bValue; updatePrintJob(); } } @@ -283,7 +294,7 @@ class ControllerProperties -1; std::map< int, rtl::OUString >::const_iterator name_it = maTagToPropertyName.find( nTag ); - if( name_it != maTagToPropertyName.end() ) + if( name_it != maTagToPropertyName.end() && ! name_it->second.equalsAscii( "PrintContent" ) ) { MacOSBOOL bEnabled = mpController->isUIOptionEnabled( name_it->second ) ? YES : NO; if( pCtrl ) @@ -311,6 +322,9 @@ class ControllerProperties GDIMetaFile aMtf; PrinterController::PageSize aPageSize( mpController->getFilteredPageFile( i_nPage, aMtf, false ) ); VirtualDevice aDev; + if( mpController->getPrinter()->GetPrinterOptions().IsConvertToGreyscales() ) + aDev.SetDrawMode( aDev.GetDrawMode() | ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | + DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); // see salprn.cxx, currently we pretend to be a 720dpi device on printers aDev.SetReferenceDevice( 720, 720 ); aDev.EnableOutput( TRUE ); @@ -768,6 +782,319 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) } } +static void addSubgroup( NSView* pCurParent, long& rCurY, const rtl::OUString& rText ) +{ + NSControl* pTextView = createLabel( rText ); + [pCurParent addSubview: [pTextView autorelease]]; + NSRect aTextRect = [pTextView frame]; + // move to nCurY + aTextRect.origin.y = rCurY - aTextRect.size.height; + [pTextView setFrame: aTextRect]; + + NSRect aSepRect = { { aTextRect.size.width + 1, aTextRect.origin.y }, { 100, 6 } }; + NSBox* pBox = [[NSBox alloc] initWithFrame: aSepRect]; + [pBox setBoxType: NSBoxSeparator]; + [pCurParent addSubview: [pBox autorelease]]; + + // update nCurY + rCurY = aTextRect.origin.y - 5; +} + +static void addBool( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, + const rtl::OUString& rText, sal_Bool bEnabled, + const rtl::OUString& rProperty, sal_Bool bValue, + std::vector<ColumnItem >& rRightColumn, + ControllerProperties* pControllerProperties, + ControlTarget* pCtrlTarget + ) +{ + NSRect aCheckRect = { { rCurX + nAttachOffset, 0 }, { 0, 15 } }; + NSButton* pBtn = [[NSButton alloc] initWithFrame: aCheckRect]; + [pBtn setButtonType: NSSwitchButton]; + [pBtn setState: bValue ? NSOnState : NSOffState]; + if( ! bEnabled ) + [pBtn setEnabled: NO]; + linebreakCell( [pBtn cell], rText ); + [pBtn sizeToFit]; + [pCurParent addSubview: [pBtn autorelease]]; + + rRightColumn.push_back( ColumnItem( pBtn ) ); + + // connect target + [pBtn setTarget: pCtrlTarget]; + [pBtn setAction: @selector(triggered:)]; + int nTag = pControllerProperties->addNameTag( rProperty ); + pControllerProperties->addObservedControl( pBtn ); + [pBtn setTag: nTag]; + + aCheckRect = [pBtn frame]; + + // move to rCurY + aCheckRect.origin.y = rCurY - aCheckRect.size.height; + [pBtn setFrame: aCheckRect]; + + // update rCurY + rCurY = aCheckRect.origin.y - 5; +} + +static void addRadio( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, + const rtl::OUString& rText, + const rtl::OUString& rProperty, Sequence< rtl::OUString > rChoices, sal_Int32 nSelectValue, + std::vector<ColumnItem >& rLeftColumn, + std::vector<ColumnItem >& rRightColumn, + ControllerProperties* pControllerProperties, + ControlTarget* pCtrlTarget + ) +{ + sal_Int32 nOff = 0; + if( rText.getLength() ) + { + // add a label + NSControl* pTextView = createLabel( rText ); + NSRect aTextRect = [pTextView frame]; + aTextRect.origin.x = rCurX + nAttachOffset; + [pCurParent addSubview: [pTextView autorelease]]; + + rLeftColumn.push_back( ColumnItem( pTextView ) ); + + // move to nCurY + aTextRect.origin.y = rCurY - aTextRect.size.height; + [pTextView setFrame: aTextRect]; + + // update nCurY + rCurY = aTextRect.origin.y - 5; + + // indent the radio group relative to the text + // nOff = 20; + } + + // setup radio matrix + NSButtonCell* pProto = [[NSButtonCell alloc] init]; + + NSRect aRadioRect = { { rCurX + nOff, 0 }, { 280 - rCurX, 5*rChoices.getLength() } }; + [pProto setTitle: @"RadioButtonGroup"]; + [pProto setButtonType: NSRadioButton]; + NSMatrix* pMatrix = [[NSMatrix alloc] initWithFrame: aRadioRect + mode: NSRadioModeMatrix + prototype: (NSCell*)pProto + numberOfRows: rChoices.getLength() + numberOfColumns: 1]; + // set individual titles + NSArray* pCells = [pMatrix cells]; + for( sal_Int32 m = 0; m < rChoices.getLength(); m++ ) + { + NSCell* pCell = [pCells objectAtIndex: m]; + filterAccelerator( rChoices[m] ); + linebreakCell( pCell, rChoices[m] ); + // connect target and action + [pCell setTarget: pCtrlTarget]; + [pCell setAction: @selector(triggered:)]; + int nTag = pControllerProperties->addNameAndValueTag( rProperty, m ); + pControllerProperties->addObservedControl( pCell ); + [pCell setTag: nTag]; + // set current selection + if( nSelectValue == m ) + [pMatrix selectCellAtRow: m column: 0]; + } + [pMatrix sizeToFit]; + aRadioRect = [pMatrix frame]; + + // move it down, so it comes to the correct position + aRadioRect.origin.y = rCurY - aRadioRect.size.height; + [pMatrix setFrame: aRadioRect]; + [pCurParent addSubview: [pMatrix autorelease]]; + + rRightColumn.push_back( ColumnItem( pMatrix ) ); + + // update nCurY + rCurY = aRadioRect.origin.y - 5; + + [pProto release]; +} + +static void addList( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, + const rtl::OUString& rText, + const rtl::OUString& rProperty, const Sequence< rtl::OUString > rChoices, sal_Int32 nSelectValue, + std::vector<ColumnItem >& rLeftColumn, + std::vector<ColumnItem >& rRightColumn, + ControllerProperties* pControllerProperties, + ControlTarget* pCtrlTarget + ) +{ + // don't indent attached lists, looks bad in the existing cases + NSControl* pTextView = createLabel( rText ); + [pCurParent addSubview: [pTextView autorelease]]; + rLeftColumn.push_back( ColumnItem( pTextView ) ); + NSRect aTextRect = [pTextView frame]; + aTextRect.origin.x = rCurX /* + nAttachOffset*/; + + // don't indent attached lists, looks bad in the existing cases + NSRect aBtnRect = { { rCurX /*+ nAttachOffset*/ + aTextRect.size.width, 0 }, { 0, 15 } }; + NSPopUpButton* pBtn = [[NSPopUpButton alloc] initWithFrame: aBtnRect pullsDown: NO]; + + // iterate options + for( sal_Int32 m = 0; m < rChoices.getLength(); m++ ) + { + NSString* pItemText = CreateNSString( rChoices[m] ); + [pBtn addItemWithTitle: pItemText]; + NSMenuItem* pItem = [pBtn itemWithTitle: pItemText]; + int nTag = pControllerProperties->addNameAndValueTag( rProperty, m ); + [pItem setTag: nTag]; + [pItemText release]; + } + + [pBtn selectItemAtIndex: nSelectValue]; + + // add the button to observed controls for enabled state changes + // also add a tag just for this purpose + pControllerProperties->addObservedControl( pBtn ); + [pBtn setTag: pControllerProperties->addNameTag( rProperty )]; + + [pBtn sizeToFit]; + [pCurParent addSubview: [pBtn autorelease]]; + + rRightColumn.push_back( ColumnItem( pBtn ) ); + + // connect target and action + [pBtn setTarget: pCtrlTarget]; + [pBtn setAction: @selector(triggered:)]; + + // move to nCurY + aBtnRect = [pBtn frame]; + aBtnRect.origin.y = rCurY - aBtnRect.size.height; + [pBtn setFrame: aBtnRect]; + + // align label + aTextRect.origin.y = aBtnRect.origin.y + (aBtnRect.size.height - aTextRect.size.height)/2; + [pTextView setFrame: aTextRect]; + + // update rCurY + rCurY = aBtnRect.origin.y - 5; +} + +static void addEdit( NSView* pCurParent, long& rCurX, long& rCurY, long nAttachOffset, + const rtl::OUString rCtrlType, + const rtl::OUString& rText, + const rtl::OUString& rProperty, const PropertyValue* pValue, + sal_Int64 nMinValue, sal_Int64 nMaxValue, + std::vector<ColumnItem >& rLeftColumn, + std::vector<ColumnItem >& rRightColumn, + ControllerProperties* pControllerProperties, + ControlTarget* pCtrlTarget + ) +{ + sal_Int32 nOff = 0; + if( rText.getLength() ) + { + // add a label + NSControl* pTextView = createLabel( rText ); + [pCurParent addSubview: [pTextView autorelease]]; + + rLeftColumn.push_back( ColumnItem( pTextView ) ); + + // move to nCurY + NSRect aTextRect = [pTextView frame]; + aTextRect.origin.x = rCurX + nAttachOffset; + aTextRect.origin.y = rCurY - aTextRect.size.height; + [pTextView setFrame: aTextRect]; + + // update nCurY + rCurY = aTextRect.origin.y - 5; + + // and set the offset for the real edit field + nOff = aTextRect.size.width + 5; + } + + NSRect aFieldRect = { { rCurX + nOff + nAttachOffset, 0 }, { 100, 25 } }; + NSTextField* pFieldView = [[NSTextField alloc] initWithFrame: aFieldRect]; + [pFieldView setEditable: YES]; + [pFieldView setSelectable: YES]; + [pFieldView setDrawsBackground: YES]; + [pFieldView sizeToFit]; // FIXME: this does nothing + [pCurParent addSubview: [pFieldView autorelease]]; + + rRightColumn.push_back( ColumnItem( pFieldView ) ); + + // add the field to observed controls for enabled state changes + // also add a tag just for this purpose + pControllerProperties->addObservedControl( pFieldView ); + int nTag = pControllerProperties->addNameTag( rProperty ); + [pFieldView setTag: nTag]; + // pControllerProperties->addNamedView( pFieldView, aPropertyName ); + + // move to nCurY + aFieldRect.origin.y = rCurY - aFieldRect.size.height; + [pFieldView setFrame: aFieldRect]; + + if( rCtrlType.equalsAscii( "Range" ) ) + { + // add a stepper control + NSRect aStepFrame = { { aFieldRect.origin.x + aFieldRect.size.width + 5, + aFieldRect.origin.y }, + { 15, aFieldRect.size.height } }; + NSStepper* pStep = [[NSStepper alloc] initWithFrame: aStepFrame]; + [pStep setIncrement: 1]; + [pStep setValueWraps: NO]; + [pStep setTag: nTag]; + [pCurParent addSubview: [pStep autorelease]]; + + rRightColumn.back().pSubControl = pStep; + + pControllerProperties->addObservedControl( pStep ); + [pStep setTarget: pCtrlTarget]; + [pStep setAction: @selector(triggered:)]; + + // constrain the text field to decimal numbers + NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init]; + [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4]; + [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; + [pFormatter setAllowsFloats: NO]; + [pFormatter setMaximumFractionDigits: 0]; + if( nMinValue != nMaxValue ) + { + [pFormatter setMinimum: [[NSNumber numberWithInt: nMinValue] autorelease]]; + [pStep setMinValue: nMinValue]; + [pFormatter setMaximum: [[NSNumber numberWithInt: nMaxValue] autorelease]]; + [pStep setMaxValue: nMaxValue]; + } + [pFieldView setFormatter: pFormatter]; + + sal_Int64 nSelectVal = 0; + if( pValue && pValue->Value.hasValue() ) + pValue->Value >>= nSelectVal; + + [pFieldView setIntValue: nSelectVal]; + [pStep setIntValue: nSelectVal]; + + pControllerProperties->addViewPair( pFieldView, pStep ); + // connect target and action + [pFieldView setTarget: pCtrlTarget]; + [pFieldView setAction: @selector(triggeredNumeric:)]; + [pStep setTarget: pCtrlTarget]; + [pStep setAction: @selector(triggeredNumeric:)]; + } + else + { + // connect target and action + [pFieldView setTarget: pCtrlTarget]; + [pFieldView setAction: @selector(triggered:)]; + + if( pValue && pValue->Value.hasValue() ) + { + rtl::OUString aValue; + pValue->Value >>= aValue; + if( aValue.getLength() ) + { + NSString* pText = CreateNSString( aValue ); + [pFieldView setStringValue: pText]; + [pText release]; + } + } + } + + // update nCurY + rCurY = aFieldRect.origin.y - 5; +} @implementation AquaPrintAccessoryView +(NSObject*)setupPrinterPanel: (NSPrintOperation*)pOp withController: (vcl::PrinterController*)pController withState: (PrintAccessoryViewState*)pState; @@ -792,6 +1119,54 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) ControlTarget* pCtrlTarget = [[ControlTarget alloc] initWithControllerMap: pControllerProperties]; std::vector< ColumnItem > aLeftColumn, aRightColumn; + + // ugly: + // prepend a "selection" checkbox if the properties have such a selection in PrintContent + bool bAddSelectionCheckBox = false, bSelectionBoxEnabled = false, bSelectionBoxChecked = false; + for( int i = 0; i < rOptions.getLength(); i++ ) + { + Sequence< beans::PropertyValue > aOptProp; + rOptions[i].Value >>= aOptProp; + + rtl::OUString aCtrlType; + rtl::OUString aPropertyName; + Sequence< rtl::OUString > aChoices; + Sequence< sal_Bool > aChoicesDisabled; + sal_Int32 aSelectionChecked = 0; + for( int n = 0; n < aOptProp.getLength(); n++ ) + { + const beans::PropertyValue& rEntry( aOptProp[ n ] ); + if( rEntry.Name.equalsAscii( "ControlType" ) ) + { + rEntry.Value >>= aCtrlType; + } + else if( rEntry.Name.equalsAscii( "Choices" ) ) + { + rEntry.Value >>= aChoices; + } + else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) + { + rEntry.Value >>= aChoicesDisabled; + } + else if( rEntry.Name.equalsAscii( "Property" ) ) + { + PropertyValue aVal; + rEntry.Value >>= aVal; + aPropertyName = aVal.Name; + if( aPropertyName.equalsAscii( "PrintContent" ) ) + aVal.Value >>= aSelectionChecked; + } + } + if( aCtrlType.equalsAscii( "Radio" ) && + aPropertyName.equalsAscii( "PrintContent" ) && + aChoices.getLength() > 2 ) + { + bAddSelectionCheckBox = true; + bSelectionBoxEnabled = aChoicesDisabled.getLength() < 2 || ! aChoicesDisabled[2]; + bSelectionBoxChecked = (aSelectionChecked==2); + break; + } + } for( int i = 0; i < rOptions.getLength(); i++ ) { @@ -803,6 +1178,7 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) rtl::OUString aCtrlType; rtl::OUString aText; rtl::OUString aPropertyName; + rtl::OUString aGroupHint; Sequence< rtl::OUString > aChoices; sal_Int64 nMinValue = 0, nMaxValue = 0; long nAttachOffset = 0; @@ -852,6 +1228,10 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) { rEntry.Value >>= bIgnore; } + else if( rEntry.Name.equalsAscii( "GroupingHint" ) ) + { + rEntry.Value >>= aGroupHint; + } } if( aCtrlType.equalsAscii( "Group" ) || @@ -894,6 +1274,15 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) // clear columns aLeftColumn.clear(); aRightColumn.clear(); + + if( bAddSelectionCheckBox ) + { + addBool( pCurParent, nCurX, nCurY, 0, + pControllerProperties->getPrintSelectionString(), bSelectionBoxEnabled, + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ), bSelectionBoxChecked, + aRightColumn, pControllerProperties, pCtrlTarget ); + bAddSelectionCheckBox = false; + } } if( aCtrlType.equalsAscii( "Subgroup" ) && pCurParent ) @@ -902,302 +1291,56 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) if( bIgnore ) continue; - NSControl* pTextView = createLabel( aText ); - [pCurParent addSubview: [pTextView autorelease]]; - NSRect aTextRect = [pTextView frame]; - // move to nCurY - aTextRect.origin.y = nCurY - aTextRect.size.height; - [pTextView setFrame: aTextRect]; - - NSRect aSepRect = { { aTextRect.size.width + 1, aTextRect.origin.y }, { 100, 6 } }; - NSBox* pBox = [[NSBox alloc] initWithFrame: aSepRect]; - [pBox setBoxType: NSBoxSeparator]; - [pCurParent addSubview: [pBox autorelease]]; - - // update nCurY - nCurY = aTextRect.origin.y - 5; + addSubgroup( pCurParent, nCurY, aText ); } else if( bIgnoreSubgroup || bIgnore ) + { continue; + } else if( aCtrlType.equalsAscii( "Bool" ) && pCurParent ) { - NSRect aCheckRect = { { nCurX + nAttachOffset, 0 }, { 0, 15 } }; - NSButton* pBtn = [[NSButton alloc] initWithFrame: aCheckRect]; - [pBtn setButtonType: NSSwitchButton]; sal_Bool bVal = sal_False; PropertyValue* pVal = pController->getValue( aPropertyName ); if( pVal ) pVal->Value >>= bVal; - [pBtn setState: bVal ? NSOnState : NSOffState]; - linebreakCell( [pBtn cell], aText ); - [pBtn sizeToFit]; - [pCurParent addSubview: [pBtn autorelease]]; - - aRightColumn.push_back( ColumnItem( pBtn ) ); - - // connect target - [pBtn setTarget: pCtrlTarget]; - [pBtn setAction: @selector(triggered:)]; - int nTag = pControllerProperties->addNameTag( aPropertyName ); - pControllerProperties->addObservedControl( pBtn ); - [pBtn setTag: nTag]; - - aCheckRect = [pBtn frame]; - - // move to nCurY - aCheckRect.origin.y = nCurY - aCheckRect.size.height; - [pBtn setFrame: aCheckRect]; - - // update nCurY - nCurY = aCheckRect.origin.y - 5; + addBool( pCurParent, nCurX, nCurY, nAttachOffset, + aText, true, aPropertyName, bVal, + aRightColumn, pControllerProperties, pCtrlTarget ); } else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) { - sal_Int32 nOff = 0; - if( aText.getLength() ) - { - // add a label - NSControl* pTextView = createLabel( aText ); - NSRect aTextRect = [pTextView frame]; - aTextRect.origin.x = nCurX + nAttachOffset; - [pCurParent addSubview: [pTextView autorelease]]; - - aLeftColumn.push_back( ColumnItem( pTextView ) ); - - // move to nCurY - aTextRect.origin.y = nCurY - aTextRect.size.height; - [pTextView setFrame: aTextRect]; - - // update nCurY - nCurY = aTextRect.origin.y - 5; - - // indent the radio group relative to the text - // nOff = 20; - } - - // setup radio matrix - NSButtonCell* pProto = [[NSButtonCell alloc] init]; - - NSRect aRadioRect = { { nCurX + nOff, 0 }, { 280 - nCurX, 5*aChoices.getLength() } }; - [pProto setTitle: @"RadioButtonGroup"]; - [pProto setButtonType: NSRadioButton]; - NSMatrix* pMatrix = [[NSMatrix alloc] initWithFrame: aRadioRect - mode: NSRadioModeMatrix - prototype: (NSCell*)pProto - numberOfRows: aChoices.getLength() - numberOfColumns: 1]; // get currently selected value sal_Int32 nSelectVal = 0; PropertyValue* pVal = pController->getValue( aPropertyName ); if( pVal && pVal->Value.hasValue() ) pVal->Value >>= nSelectVal; - // set individual titles - NSArray* pCells = [pMatrix cells]; - for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) - { - NSCell* pCell = [pCells objectAtIndex: m]; - filterAccelerator( aChoices[m] ); - linebreakCell( pCell, aChoices[m] ); - //NSString* pTitle = CreateNSString( aChoices[m] ); - //[pCell setTitle: pTitle]; - // connect target and action - [pCell setTarget: pCtrlTarget]; - [pCell setAction: @selector(triggered:)]; - int nTag = pControllerProperties->addNameAndValueTag( aPropertyName, m ); - pControllerProperties->addObservedControl( pCell ); - [pCell setTag: nTag]; - //[pTitle release]; - // set current selection - if( nSelectVal == m ) - [pMatrix selectCellAtRow: m column: 0]; - } - [pMatrix sizeToFit]; - aRadioRect = [pMatrix frame]; - // move it down, so it comes to the correct position - aRadioRect.origin.y = nCurY - aRadioRect.size.height; - [pMatrix setFrame: aRadioRect]; - [pCurParent addSubview: [pMatrix autorelease]]; - - aRightColumn.push_back( ColumnItem( pMatrix ) ); - - // update nCurY - nCurY = aRadioRect.origin.y - 5; - - [pProto release]; + addRadio( pCurParent, nCurX, nCurY, nAttachOffset, + aText, aPropertyName, aChoices, nSelectVal, + aLeftColumn, aRightColumn, + pControllerProperties, pCtrlTarget ); } else if( aCtrlType.equalsAscii( "List" ) && pCurParent ) { - // don't indent attached lists, looks bad in the existing cases - NSControl* pTextView = createLabel( aText ); - [pCurParent addSubview: [pTextView autorelease]]; - aLeftColumn.push_back( ColumnItem( pTextView ) ); - NSRect aTextRect = [pTextView frame]; - aTextRect.origin.x = nCurX /* + nAttachOffset*/; - - // don't indent attached lists, looks bad in the existing cases - NSRect aBtnRect = { { nCurX /*+ nAttachOffset*/ + aTextRect.size.width, 0 }, { 0, 15 } }; - NSPopUpButton* pBtn = [[NSPopUpButton alloc] initWithFrame: aBtnRect pullsDown: NO]; - - // iterate options - for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) - { - NSString* pItemText = CreateNSString( aChoices[m] ); - [pBtn addItemWithTitle: pItemText]; - NSMenuItem* pItem = [pBtn itemWithTitle: pItemText]; - int nTag = pControllerProperties->addNameAndValueTag( aPropertyName, m ); - [pItem setTag: nTag]; - [pItemText release]; - } - PropertyValue* pVal = pController->getValue( aPropertyName ); sal_Int32 aSelectVal = 0; if( pVal && pVal->Value.hasValue() ) pVal->Value >>= aSelectVal; - [pBtn selectItemAtIndex: aSelectVal]; - - // add the button to observed controls for enabled state changes - // also add a tag just for this purpose - pControllerProperties->addObservedControl( pBtn ); - [pBtn setTag: pControllerProperties->addNameTag( aPropertyName )]; - - [pBtn sizeToFit]; - [pCurParent addSubview: [pBtn autorelease]]; - - aRightColumn.push_back( ColumnItem( pBtn ) ); - - // connect target and action - [pBtn setTarget: pCtrlTarget]; - [pBtn setAction: @selector(triggered:)]; - - // move to nCurY - aBtnRect = [pBtn frame]; - aBtnRect.origin.y = nCurY - aBtnRect.size.height; - [pBtn setFrame: aBtnRect]; - - // align label - aTextRect.origin.y = aBtnRect.origin.y + (aBtnRect.size.height - aTextRect.size.height)/2; - [pTextView setFrame: aTextRect]; - // update nCurY - nCurY = aBtnRect.origin.y - 5; + addList( pCurParent, nCurX, nCurY, nAttachOffset, + aText, aPropertyName, aChoices, aSelectVal, + aLeftColumn, aRightColumn, + pControllerProperties, pCtrlTarget ); } else if( (aCtrlType.equalsAscii( "Edit" ) || aCtrlType.equalsAscii( "Range" )) && pCurParent ) { - sal_Int32 nOff = 0; - if( aText.getLength() ) - { - // add a label - NSControl* pTextView = createLabel( aText ); - [pCurParent addSubview: [pTextView autorelease]]; - - aLeftColumn.push_back( ColumnItem( pTextView ) ); - - // move to nCurY - NSRect aTextRect = [pTextView frame]; - aTextRect.origin.x = nCurX + nAttachOffset; - aTextRect.origin.y = nCurY - aTextRect.size.height; - [pTextView setFrame: aTextRect]; - - // update nCurY - nCurY = aTextRect.origin.y - 5; - - // and set the offset for the real edit field - nOff = aTextRect.size.width + 5; - } - - NSRect aFieldRect = { { nCurX + nOff + nAttachOffset, 0 }, { 100, 25 } }; - NSTextField* pFieldView = [[NSTextField alloc] initWithFrame: aFieldRect]; - [pFieldView setEditable: YES]; - [pFieldView setSelectable: YES]; - [pFieldView setDrawsBackground: YES]; - [pFieldView sizeToFit]; // FIXME: this does nothing - [pCurParent addSubview: [pFieldView autorelease]]; - - aRightColumn.push_back( ColumnItem( pFieldView ) ); - - // add the field to observed controls for enabled state changes - // also add a tag just for this purpose - pControllerProperties->addObservedControl( pFieldView ); - int nTag = pControllerProperties->addNameTag( aPropertyName ); - [pFieldView setTag: nTag]; - // pControllerProperties->addNamedView( pFieldView, aPropertyName ); - - // move to nCurY - aFieldRect.origin.y = nCurY - aFieldRect.size.height; - [pFieldView setFrame: aFieldRect]; - // current value PropertyValue* pVal = pController->getValue( aPropertyName ); - if( aCtrlType.equalsAscii( "Range" ) ) - { - // add a stepper control - NSRect aStepFrame = { { aFieldRect.origin.x + aFieldRect.size.width + 5, - aFieldRect.origin.y }, - { 15, aFieldRect.size.height } }; - NSStepper* pStep = [[NSStepper alloc] initWithFrame: aStepFrame]; - [pStep setIncrement: 1]; - [pStep setValueWraps: NO]; - [pStep setTag: nTag]; - [pCurParent addSubview: [pStep autorelease]]; - - aRightColumn.back().pSubControl = pStep; - - pControllerProperties->addObservedControl( pStep ); - [pStep setTarget: pCtrlTarget]; - [pStep setAction: @selector(triggered:)]; - - // constrain the text field to decimal numbers - NSNumberFormatter* pFormatter = [[NSNumberFormatter alloc] init]; - [pFormatter setFormatterBehavior: NSNumberFormatterBehavior10_4]; - [pFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; - [pFormatter setAllowsFloats: NO]; - [pFormatter setMaximumFractionDigits: 0]; - if( nMinValue != nMaxValue ) - { - [pFormatter setMinimum: [[NSNumber numberWithInt: nMinValue] autorelease]]; - [pStep setMinValue: nMinValue]; - [pFormatter setMaximum: [[NSNumber numberWithInt: nMaxValue] autorelease]]; - [pStep setMaxValue: nMaxValue]; - } - [pFieldView setFormatter: pFormatter]; - - sal_Int64 nSelectVal = 0; - if( pVal && pVal->Value.hasValue() ) - pVal->Value >>= nSelectVal; - - [pFieldView setIntValue: nSelectVal]; - [pStep setIntValue: nSelectVal]; - - pControllerProperties->addViewPair( pFieldView, pStep ); - // connect target and action - [pFieldView setTarget: pCtrlTarget]; - [pFieldView setAction: @selector(triggeredNumeric:)]; - [pStep setTarget: pCtrlTarget]; - [pStep setAction: @selector(triggeredNumeric:)]; - } - else - { - // connect target and action - [pFieldView setTarget: pCtrlTarget]; - [pFieldView setAction: @selector(triggered:)]; - - if( pVal && pVal->Value.hasValue() ) - { - rtl::OUString aValue; - pVal->Value >>= aValue; - if( aValue.getLength() ) - { - NSString* pText = CreateNSString( aValue ); - [pFieldView setStringValue: pText]; - [pText release]; - } - } - } - - // update nCurY - nCurY = aFieldRect.origin.y - 5; - + addEdit( pCurParent, nCurX, nCurY, nAttachOffset, + aCtrlType, aText, aPropertyName, pVal, + nMinValue, nMaxValue, + aLeftColumn, aRightColumn, + pControllerProperties, pCtrlTarget ); } } else @@ -1205,7 +1348,7 @@ static void linebreakCell( NSCell* pBtn, const rtl::OUString& i_rText ) DBG_ERROR( "Unsupported UI option" ); } } - + pControllerProperties->updateEnableState(); adjustViewAndChildren( pCurParent, aMaxTabSize, aLeftColumn, aRightColumn ); diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx index 335505de85ac..a355ff86d00e 100755 --- a/vcl/aqua/source/gdi/salatslayout.cxx +++ b/vcl/aqua/source/gdi/salatslayout.cxx @@ -754,9 +754,10 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons // initial measurement of text break position UniCharArrayOffset nBreakPos = mnMinCharPos; const ATSUTextMeasurement nATSUMaxWidth = Vcl2Fixed( nPixelWidth ); + if( nATSUMaxWidth <= 0xFFFF ) // #i108584# avoid ATSU rejecting the parameter + return mnMinCharPos; // or do ATSUMaxWidth=0x10000; OSStatus eStatus = ATSUBreakLine( maATSULayout, mnMinCharPos, nATSUMaxWidth, false, &nBreakPos ); - if( (eStatus != noErr) && (eStatus != kATSULineBreakInWord) ) return STRING_LEN; @@ -781,7 +782,7 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons if( eStatus != noErr ) return nBreakPos; const ATSUTextMeasurement nATSURemWidth = nATSUMaxWidth - (nRight - nLeft); - if( nATSURemWidth <= 0 ) + if( nATSURemWidth <= 0xFFFF ) // #i108584# avoid ATSU rejecting the parameter return nBreakPos; UniCharArrayOffset nBreakPosInWord = nBreakPos; eStatus = ATSUBreakLine( maATSULayout, nBreakPos, nATSURemWidth, false, &nBreakPosInWord ); diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index 5b1e24befc9b..070c0753637d 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -116,17 +116,15 @@ inline FourCharCode GetTag(const char aTagName[5]) static unsigned GetUShort( const unsigned char* p ){return((p[0]<<8)+p[1]);} static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);} -ImplFontCharMap* ImplMacFontData::GetImplFontCharMap() const +const ImplFontCharMap* ImplMacFontData::GetImplFontCharMap() const { + // return the cached charmap if( mpCharMap ) - { - // return the cached charmap - mpCharMap->AddReference(); return mpCharMap; - } // set the default charmap mpCharMap = ImplFontCharMap::GetDefaultMap(); + mpCharMap->AddReference(); // get the CMAP byte size ATSFontRef rFont = FMGetATSFontRefFromFont( mnFontId ); @@ -149,10 +147,14 @@ ImplFontCharMap* ImplMacFontData::GetImplFontCharMap() const // parse the CMAP CmapResult aCmapResult; - if( !ParseCMAP( &aBuffer[0], nRawLength, aCmapResult ) ) - return mpCharMap; + if( ParseCMAP( &aBuffer[0], nRawLength, aCmapResult ) ) + { + // create the matching charmap + mpCharMap->DeReference(); + mpCharMap = new ImplFontCharMap( aCmapResult ); + mpCharMap->AddReference(); + } - mpCharMap = new ImplFontCharMap( aCmapResult ); return mpCharMap; } @@ -988,6 +990,7 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol // ----------------------------------------------------------------------- bool AquaSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine, + double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin ) { @@ -1032,6 +1035,7 @@ bool AquaSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine, CGContextAddPath( mrContext, xPath ); // draw path with antialiased line CGContextSetShouldAntialias( mrContext, true ); + CGContextSetAlpha( mrContext, 1.0 - fTransparency ); CGContextSetLineJoin( mrContext, aCGLineJoin ); CGContextSetLineWidth( mrContext, rLineWidths.getX() ); CGContextDrawPath( mrContext, kCGPathStroke ); @@ -1451,16 +1455,24 @@ BOOL AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, // prepare the target context NSGraphicsContext* pOrigNSCtx = [NSGraphicsContext currentContext]; + [pOrigNSCtx retain]; + + // create new context NSGraphicsContext* pDrawNSCtx = [NSGraphicsContext graphicsContextWithGraphicsPort: mrContext flipped: IsFlipped()]; + // set it, setCurrentContext also releases the prviously set one [NSGraphicsContext setCurrentContext: pDrawNSCtx]; + // draw the EPS const NSRect aDstRect = {{nX,nY},{nWidth,nHeight}}; const BOOL bOK = [xEpsImage drawInRect: aDstRect]; + + // restore the NSGraphicsContext + [NSGraphicsContext setCurrentContext: pOrigNSCtx]; + [pOrigNSCtx release]; // restore the original retain count + CGContextRestoreGState( mrContext ); // mark the destination rectangle as updated RefreshRect( aDstRect ); - // restore the NSGraphicsContext, TODO: do we need this? - [NSGraphicsContext setCurrentContext: pOrigNSCtx]; return bOK; } @@ -1545,8 +1557,10 @@ void AquaSalGraphics::SetTextColor( SalColor nSalColor ) // ----------------------------------------------------------------------- -void AquaSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) +void AquaSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { + (void)nFallbackLevel; // glyph-fallback on ATSU is done differently -> no fallback level + // get the ATSU font metrics (in point units) // of the font that has eventually been size-limited @@ -1980,7 +1994,7 @@ USHORT AquaSalGraphics::SetFont( ImplFontSelectData* pReqFont, int nFallbackLeve // ----------------------------------------------------------------------- -ImplFontCharMap* AquaSalGraphics::GetImplFontCharMap() const +const ImplFontCharMap* AquaSalGraphics::GetImplFontCharMap() const { if( !mpMacFontData ) return ImplFontCharMap::GetDefaultMap(); @@ -2342,8 +2356,10 @@ void AquaSalGraphics::GetGlyphWidths( const ImplFontData* pFontData, bool bVerti const ImplFontCharMap* pMap = mpMacFontData->GetImplFontCharMap(); DBG_ASSERT( pMap && pMap->GetCharCount(), "no charmap" ); + pMap->AddReference(); // TODO: add and use RAII object instead // get unicode<->glyph encoding + // TODO? avoid sft mapping by using the pMap itself int nCharCount = pMap->GetCharCount(); sal_uInt32 nChar = pMap->GetFirstChar(); for(; --nCharCount >= 0; nChar = pMap->GetNextChar( nChar ) ) @@ -2355,6 +2371,8 @@ void AquaSalGraphics::GetGlyphWidths( const ImplFontData* pFontData, bool bVerti if( nGlyph > 0 ) rUnicodeEnc[ nUcsChar ] = nGlyph; } + + pMap->DeReference(); // TODO: add and use RAII object instead } ::CloseTTFont( pSftFont ); diff --git a/vcl/aqua/source/gdi/salnativewidgets.cxx b/vcl/aqua/source/gdi/salnativewidgets.cxx index 5eccf88dc523..9ce2b8a5a518 100644 --- a/vcl/aqua/source/gdi/salnativewidgets.cxx +++ b/vcl/aqua/source/gdi/salnativewidgets.cxx @@ -379,13 +379,13 @@ BOOL AquaSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart n * aPos was or was not inside the native widget specified by the * nType/nPart combination. */ -BOOL AquaSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL AquaSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& rPos, BOOL& rIsInside ) { if ( nType == CTRL_SCROLLBAR ) { Rectangle aRect; - bool bValid = AquaGetScrollRect( /* TODO: m_nScreen */ nPart, rControlRegion.GetBoundRect(), aRect ); + bool bValid = AquaGetScrollRect( /* TODO: m_nScreen */ nPart, rControlRegion, aRect ); rIsInside = bValid ? aRect.IsInside( rPos ) : FALSE; if( GetSalData()->mbIsScrollbarDoubleMax ) { @@ -472,7 +472,7 @@ UInt32 AquaSalGraphics::getTrackState( ControlState nState ) */ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ) @@ -484,7 +484,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, CGContextSaveGState( mrContext ); - Rectangle buttonRect = rControlRegion.GetBoundRect(); + Rectangle buttonRect = rControlRegion; HIRect rc = ImplGetHIRectFromRectangle(buttonRect); /** Scrollbar parts code equivalent ** @@ -621,7 +621,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, // no animation aPushInfo.animation.time.start = 0; aPushInfo.animation.time.current = 0; - PushButtonValue* pPBVal = (PushButtonValue*)aValue.getOptionalVal(); + PushButtonValue* pPBVal = aValue.getType() == CTRL_PUSHBUTTON ? (PushButtonValue*)&aValue : NULL; int nPaintHeight = static_cast<int>(rc.size.height); if( pPBVal && pPBVal->mbBevelButton ) @@ -790,7 +790,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, case CTRL_SLIDER: { - SliderValue* pSLVal = (SliderValue*)aValue.getOptionalVal(); + SliderValue* pSLVal = (SliderValue*)&aValue; HIThemeTrackDrawInfo aTrackDraw; aTrackDraw.kind = kThemeSliderMedium; @@ -820,7 +820,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, case CTRL_SCROLLBAR: { - ScrollbarValue* pScrollbarVal = (ScrollbarValue *)(aValue.getOptionalVal()); + ScrollbarValue* pScrollbarVal = (ScrollbarValue *)&aValue; if( nPart == PART_DRAW_BACKGROUND_VERT || nPart == PART_DRAW_BACKGROUND_HORZ ) @@ -962,17 +962,19 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, //first, last or middle tab aTabItemDrawInfo.position=kHIThemeTabPositionMiddle; - TabitemValue *aTabValue=(TabitemValue *) aValue.getOptionalVal(); - unsigned int nAlignement=aTabValue->mnAlignment; + TabitemValue* pTabValue = (TabitemValue *) &aValue; + unsigned int nAlignment = pTabValue->mnAlignment; //TABITEM_LEFTALIGNED (and TABITEM_RIGHTALIGNED) for the leftmost (or rightmost) tab //when there are several lines of tabs because there is only one first tab and one //last tab and TABITEM_FIRST_IN_GROUP (and TABITEM_LAST_IN_GROUP) because when the //line width is different from window width, there may not be TABITEM_RIGHTALIGNED - if((nAlignement & TABITEM_LEFTALIGNED)&&(nAlignement & TABITEM_RIGHTALIGNED)) //tab alone + if( ( (nAlignment & TABITEM_LEFTALIGNED)&&(nAlignment & TABITEM_RIGHTALIGNED) ) || + ( (nAlignment & TABITEM_FIRST_IN_GROUP)&&(nAlignment & TABITEM_LAST_IN_GROUP) ) + ) //tab alone aTabItemDrawInfo.position=kHIThemeTabPositionOnly; - else if((nAlignement & TABITEM_LEFTALIGNED)||(nAlignement & TABITEM_FIRST_IN_GROUP)) + else if((nAlignment & TABITEM_LEFTALIGNED)||(nAlignment & TABITEM_FIRST_IN_GROUP)) aTabItemDrawInfo.position=kHIThemeTabPositionFirst; - else if((nAlignement & TABITEM_RIGHTALIGNED)||(nAlignement & TABITEM_LAST_IN_GROUP)) + else if((nAlignment & TABITEM_RIGHTALIGNED)||(nAlignment & TABITEM_LAST_IN_GROUP)) aTabItemDrawInfo.position=kHIThemeTabPositionLast; //support for RTL @@ -1087,7 +1089,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal); //buttons: - SpinbuttonValue* pSpinButtonVal = (SpinbuttonValue *)(aValue.getOptionalVal()); + SpinbuttonValue* pSpinButtonVal = (SpinbuttonValue *)&aValue; ControlState nUpperState = CTRL_STATE_ENABLED;//state of the upper button ControlState nLowerState = CTRL_STATE_ENABLED;//and of the lower button if(pSpinButtonVal) {//pSpinButtonVal is sometimes null @@ -1226,7 +1228,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, * aValue: An optional value (tristate/numerical/string) * aCaption: A caption or title string (like button text etc) */ -BOOL AquaSalGraphics::drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL AquaSalGraphics::drawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ) { @@ -1247,14 +1249,14 @@ BOOL AquaSalGraphics::drawNativeControlText( ControlType nType, ControlPart nPar * aValue: An optional value (tristate/numerical/string) * aCaption: A caption or title string (like button text etc) */ -BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, +BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ) { BOOL toReturn = FALSE; - Rectangle aCtrlBoundRect( rControlRegion.GetBoundRect() ); + Rectangle aCtrlBoundRect( rControlRegion ); short x = aCtrlBoundRect.Left(); short y = aCtrlBoundRect.Top(); short w, h; @@ -1269,14 +1271,14 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa { w = 19; // taken from HIG h = aCtrlBoundRect.GetHeight(); - rNativeBoundingRegion = rNativeContentRegion = Region( Rectangle( Point( x, y ), Size( w, h ) ) ); + rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); toReturn = true; } else if( nPart == PART_THUMB_VERT ) { w = aCtrlBoundRect.GetWidth(); h = 18; // taken from HIG - rNativeBoundingRegion = rNativeContentRegion = Region( Rectangle( Point( x, y ), Size( w, h ) ) ); + rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) ); toReturn = true; } } @@ -1364,10 +1366,12 @@ BOOL AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPa w = aCtrlBoundRect.GetWidth(); if( w < 3+2*FOCUS_RING_WIDTH ) w = 3+2*FOCUS_RING_WIDTH; - h = TEXT_EDIT_HEIGHT_NORMAL; + h = TEXT_EDIT_HEIGHT_NORMAL+2*FOCUS_RING_WIDTH; + if( h < aCtrlBoundRect.GetHeight() ) + h = aCtrlBoundRect.GetHeight(); - rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*FOCUS_RING_WIDTH-2, h-2 ) ); - rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) ); + rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*(FOCUS_RING_WIDTH+1), h-2*(FOCUS_RING_WIDTH+1) ) ); + rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) ); toReturn = TRUE; } diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index 1c0401f769b5..c79add81d791 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -445,7 +445,7 @@ ULONG AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup* i_pSetupData, USH case PRINTER_CAPABILITIES_COPIES: return 0xffff; case PRINTER_CAPABILITIES_COLLATECOPIES: - return 0; + return 0xffff; case PRINTER_CAPABILITIES_SETORIENTATION: return 1; case PRINTER_CAPABILITIES_SETDUPLEX: @@ -460,6 +460,8 @@ ULONG AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup* i_pSetupData, USH return getUseNativeDialog() ? 1 : 0; case PRINTER_CAPABILITIES_PDF: return 1; + case PRINTER_CAPABILITIES_USEPULLMODEL: + return 1; default: break; }; return 0; @@ -634,6 +636,8 @@ BOOL AquaSalInfoPrinter::StartJob( const String* i_pFileName, } [pPrintDict setObject: [[NSNumber numberWithInt: nCopies] autorelease] forKey: NSPrintCopies]; + if( nCopies > 1 ) + [pPrintDict setObject: [[NSNumber numberWithBool: pPrinter->IsCollateCopy()] autorelease] forKey: NSPrintMustCollate]; [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 diff --git a/vcl/aqua/source/gdi/salvd.cxx b/vcl/aqua/source/gdi/salvd.cxx index eb09a44f5edd..f633dbbdcdce 100644 --- a/vcl/aqua/source/gdi/salvd.cxx +++ b/vcl/aqua/source/gdi/salvd.cxx @@ -33,6 +33,7 @@ #include "salgdi.h" #include "saldata.hxx" #include "salframe.h" +#include <vcl/svapp.hxx> #include "vcl/sysdata.hxx" @@ -197,9 +198,27 @@ BOOL AquaSalVirtualDevice::SetSize( long nDX, long nDY ) pSalFrame = *GetSalData()->maFrames.begin(); if( pSalFrame ) { - NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pSalFrame->getWindow()]; - if( pNSContext ) - xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]); + // #i91990# + NSWindow* pWindow = pSalFrame->getWindow(); + if ( pWindow ) + { + NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pWindow]; + if( pNSContext ) + xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]); + } + else + { + // fall back to a bitmap context + mnBitmapDepth = 32; + const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace; + const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst; + const int nBytesPerRow = (mnBitmapDepth * nDX) / 8; + + void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY ); + mxBitmapContext = ::CGBitmapContextCreate( pRawData, nDX, nDY, + 8, nBytesPerRow, aCGColorSpace, aCGBmpInfo ); + xCGContext = mxBitmapContext; + } } } diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx index b14354e1b4bd..17e034bd6e3d 100644 --- a/vcl/aqua/source/window/salframe.cxx +++ b/vcl/aqua/source/window/salframe.cxx @@ -191,8 +191,17 @@ void AquaSalFrame::initWindowAndView() mnStyleMask |= NSTitledWindowMask; } + // #i91990# support GUI-less (daemon) execution + @try + { mpWindow = [[SalFrameWindow alloc] initWithSalFrame: this]; mpView = [[SalFrameView alloc] initWithSalFrame: this]; + } + @catch ( id exception ) + { + return; + } + if( (mnStyle & SAL_FRAME_STYLE_TOOLTIP) ) [mpWindow setIgnoresMouseEvents: YES]; else @@ -207,8 +216,6 @@ void AquaSalFrame::initWindowAndView() UpdateFrameGeometry(); - // setContentView causes a display; in multithreaded use this can deadlock - //YieldMutexReleaser aRel; [mpWindow setContentView: mpView]; } @@ -293,6 +300,12 @@ BOOL AquaSalFrame::PostEvent( void *pData ) // ----------------------------------------------------------------------- void AquaSalFrame::SetTitle(const XubString& rTitle) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + NSString* pTitle = CreateNSString( rTitle ); [mpWindow setTitle: pTitle]; @@ -331,6 +344,9 @@ void AquaSalFrame::SetIcon( USHORT ) void AquaSalFrame::SetRepresentedURL( const rtl::OUString& i_rDocURL ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( i_rDocURL.indexOfAsciiL( "file:", 5 ) == 0 ) { rtl::OUString aSysPath; @@ -356,12 +372,12 @@ void AquaSalFrame::initShow() if( mpParent ) // center relative to parent { // center on parent - long nNewX = mpParent->maGeometry.nX + (mpParent->maGeometry.nWidth - maGeometry.nWidth)/2; + long nNewX = mpParent->maGeometry.nX + ((long)mpParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2; if( nNewX < aScreenRect.Left() ) nNewX = aScreenRect.Left(); if( long(nNewX + maGeometry.nWidth) > aScreenRect.Right() ) nNewX = aScreenRect.Right() - maGeometry.nWidth-1; - long nNewY = mpParent->maGeometry.nY + (mpParent->maGeometry.nHeight - maGeometry.nHeight)/2; + long nNewY = mpParent->maGeometry.nY + ((long)mpParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2; if( nNewY < aScreenRect.Top() ) nNewY = aScreenRect.Top(); if( nNewY > aScreenRect.Bottom() ) @@ -401,6 +417,12 @@ void AquaSalFrame::SendPaintEvent( const Rectangle* pRect ) void AquaSalFrame::Show(BOOL bVisible, BOOL bNoActivate) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + mbShown = bVisible; if(bVisible) { @@ -411,8 +433,6 @@ void AquaSalFrame::Show(BOOL bVisible, BOOL bNoActivate) // trigger filling our backbuffer SendPaintEvent(); - //YieldMutexReleaser aRel; - if( bNoActivate || [mpWindow canBecomeKeyWindow] == NO ) [mpWindow orderFront: NSApp]; else @@ -443,8 +463,6 @@ void AquaSalFrame::Show(BOOL bVisible, BOOL bNoActivate) if( mpMenu && mpMenu->mbMenuBar && AquaSalMenu::pCurrentMenuBar == mpMenu ) AquaSalMenu::setDefaultMenu(); - //YieldMutexReleaser aRel; - // #i90440# #i94443# work around the focus going back to some other window // if a child gets hidden for a parent window if( mpParent && mpParent->mbShown && [mpWindow isKeyWindow] ) @@ -468,6 +486,9 @@ void AquaSalFrame::Enable( BOOL bEnable ) void AquaSalFrame::SetMinClientSize( long nWidth, long nHeight ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + mnMinWidth = nWidth; mnMinHeight = nHeight; @@ -490,6 +511,9 @@ void AquaSalFrame::SetMinClientSize( long nWidth, long nHeight ) void AquaSalFrame::SetMaxClientSize( long nWidth, long nHeight ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + mnMaxWidth = nWidth; mnMaxHeight = nHeight; @@ -516,6 +540,9 @@ void AquaSalFrame::SetMaxClientSize( long nWidth, long nHeight ) void AquaSalFrame::SetClientSize( long nWidth, long nHeight ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( mpWindow ) { NSSize aSize = { nWidth, nHeight }; @@ -548,6 +575,11 @@ void AquaSalFrame::GetClientSize( long& rWidth, long& rHeight ) void AquaSalFrame::SetWindowState( const SalFrameState* pState ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + + if ( mpWindow ) + { // set normal state NSRect aStateRect = [mpWindow frame]; aStateRect = [NSWindow contentRectForFrameRect: aStateRect styleMask: mnStyleMask]; @@ -563,13 +595,28 @@ void AquaSalFrame::SetWindowState( const SalFrameState* pState ) VCLToCocoa( aStateRect ); aStateRect = [NSWindow frameRectForContentRect: aStateRect styleMask: mnStyleMask]; - // relase and acquire mutex again since this call can block waiting for an internal lock + [mpWindow setFrame: aStateRect display: NO]; + if( pState->mnState == SAL_FRAMESTATE_MINIMIZED ) + [mpWindow miniaturize: NSApp]; + else if( [mpWindow isMiniaturized] ) + [mpWindow deminiaturize: NSApp]; + + + /* ZOOMED is not really maximized (actually it toggles between a user set size and + the program specified one), but comes closest since the default behavior is + "maximized" if the user did not intervene + */ + if( pState->mnState == SAL_FRAMESTATE_MAXIMIZED ) { - //YieldMutexReleaser aRel; - [mpWindow setFrame: aStateRect display: NO]; + if(! [mpWindow isZoomed]) + [mpWindow zoom: NSApp]; + } + else + { + if( [mpWindow isZoomed] ) + [mpWindow zoom: NSApp]; + } } - - // FIXME: HTH maximized state ? // get new geometry UpdateFrameGeometry(); @@ -590,14 +637,12 @@ void AquaSalFrame::SetWindowState( const SalFrameState* pState ) if( nEvent ) CallCallback( nEvent, NULL ); - if( mbShown ) + if( mbShown && mpWindow ) { // trigger filling our backbuffer SendPaintEvent(); // tell the system the views need to be updated - //YieldMutexReleaser aRel; - [mpWindow display]; } } @@ -606,6 +651,12 @@ void AquaSalFrame::SetWindowState( const SalFrameState* pState ) BOOL AquaSalFrame::GetWindowState( SalFrameState* pState ) { + if ( !mpWindow ) + return FALSE; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + pState->mnMask = SAL_FRAMESTATE_MASK_X | SAL_FRAMESTATE_MASK_Y | SAL_FRAMESTATE_MASK_WIDTH | @@ -626,8 +677,6 @@ BOOL AquaSalFrame::GetWindowState( SalFrameState* pState ) pState->mnWidth = long(aStateRect.size.width); pState->mnHeight = long(aStateRect.size.height); - // FIXME: HTH maximized state ? - if( [mpWindow isMiniaturized] ) pState->mnState = SAL_FRAMESTATE_MINIMIZED; else if( ! [mpWindow isZoomed] ) @@ -642,6 +691,12 @@ BOOL AquaSalFrame::GetWindowState( SalFrameState* pState ) void AquaSalFrame::SetScreenNumber(unsigned int nScreen) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + NSArray* pScreens = [NSScreen screens]; Rectangle aRet; NSScreen* pScreen = nil; @@ -673,6 +728,12 @@ void AquaSalFrame::SetScreenNumber(unsigned int nScreen) void AquaSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay ) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( mbFullScreen == bFullScreen ) return; @@ -731,7 +792,6 @@ void AquaSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay ) maFullScreenRect = [mpWindow frame]; { - //YieldMutexReleaser aRel; [mpWindow setFrame: [NSWindow frameRectForContentRect: aNewContentRect styleMask: mnStyleMask] display: mbShown ? YES : NO]; } @@ -743,7 +803,6 @@ void AquaSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nDisplay ) else { { - //YieldMutexReleaser aRel; [mpWindow setFrame: maFullScreenRect display: mbShown ? YES : NO]; } UpdateFrameGeometry(); @@ -782,6 +841,12 @@ public: void AquaSalFrame::StartPresentation( BOOL bStart ) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( bStart ) { mpActivityTimer.reset( new PreventSleepTimer() ); @@ -806,6 +871,15 @@ void AquaSalFrame::SetAlwaysOnTop( BOOL bOnTop ) void AquaSalFrame::ToTop(USHORT nFlags) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( ! (nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN) ) { if( ! [mpWindow isVisible] || [mpWindow isMiniaturized] ) @@ -859,6 +933,12 @@ NSCursor* AquaSalFrame::getCurrentCursor() const void AquaSalFrame::SetPointer( PointerStyle ePointerStyle ) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( ePointerStyle >= POINTER_COUNT || ePointerStyle == mePointerStyle ) return; mePointerStyle = ePointerStyle; @@ -885,6 +965,10 @@ void AquaSalFrame::Flush( void ) if( !(mbGraphics && mpGraphics && mpView && mbShown) ) return; + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + + [mpView setNeedsDisplay: YES]; // outside of the application's event loop (e.g. IntroWindow) @@ -903,6 +987,9 @@ void AquaSalFrame::Flush( const Rectangle& rRect ) if( !(mbGraphics && mpGraphics && mpView && mbShown) ) return; + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + NSRect aNSRect = { {rRect.Left(), rRect.Top()}, { rRect.GetWidth(), rRect.GetHeight() } }; VCLToCocoa( aNSRect, false ); [mpView setNeedsDisplayInRect: aNSRect]; @@ -922,7 +1009,8 @@ void AquaSalFrame::Sync() { if( mbGraphics && mpGraphics && mpView && mbShown ) { - //YieldMutexReleaser aRel; + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); [mpView setNeedsDisplay: YES]; [mpView display]; @@ -1146,6 +1234,12 @@ void AquaSalFrame::getResolution( long& o_rDPIX, long& o_rDPIY ) // doesn't make the anything cleaner for now void AquaSalFrame::UpdateSettings( AllSettings& rSettings ) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + [mpView lockFocus]; StyleSettings aStyleSettings = rSettings.GetStyleSettings(); @@ -1257,6 +1351,12 @@ void AquaSalFrame::Beep( SoundType eSoundType ) void AquaSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, USHORT nFlags) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + USHORT nEvent = 0; if( [mpWindow isMiniaturized] ) @@ -1321,7 +1421,6 @@ void AquaSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, USHOR // do not display yet, we need to update our backbuffer { - //YieldMutexReleaser aRel; [mpWindow setFrame: [NSWindow frameRectForContentRect: aContentRect styleMask: mnStyleMask] display: NO]; } @@ -1336,13 +1435,18 @@ void AquaSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, USHOR SendPaintEvent(); // now inform the system that the views need to be drawn - //YieldMutexReleaser aRel; [mpWindow display]; } } void AquaSalFrame::GetWorkArea( Rectangle& rRect ) { + if ( !mpWindow ) + return; + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + NSScreen* pScreen = [mpWindow screen]; if( pScreen == nil ) pScreen = [NSScreen mainScreen]; @@ -1356,6 +1460,9 @@ void AquaSalFrame::GetWorkArea( Rectangle& rRect ) SalPointerState AquaSalFrame::GetPointerState() { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + SalPointerState state; state.mnState = 0; @@ -1463,6 +1570,9 @@ void AquaSalFrame::DrawMenuBar() void AquaSalFrame::SetMenu( SalMenu* pSalMenu ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + AquaSalMenu* pMenu = static_cast<AquaSalMenu*>(pSalMenu); DBG_ASSERT( ! pMenu || pMenu->mbMenuBar, "setting non menubar on frame" ); mpMenu = pMenu; @@ -1472,8 +1582,15 @@ void AquaSalFrame::SetMenu( SalMenu* pSalMenu ) void AquaSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) { + if ( mpWindow ) + { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( (mnExtStyle & SAL_FRAME_EXT_STYLE_DOCMODIFIED) != (nStyle & SAL_FRAME_EXT_STYLE_DOCMODIFIED) ) [mpWindow setDocumentEdited: (nStyle & SAL_FRAME_EXT_STYLE_DOCMODIFIED) ? YES : NO]; + } + mnExtStyle = nStyle; } @@ -1504,6 +1621,11 @@ void AquaSalFrame::SetParent( SalFrame* pNewParent ) void AquaSalFrame::UpdateFrameGeometry() { + if ( !mpWindow ) + { + return; + } + // keep in mind that view and window coordinates are lower left // whereas vcl's are upper left @@ -1576,6 +1698,14 @@ void AquaSalFrame::CaptureMouse( BOOL bCapture ) void AquaSalFrame::ResetClipRegion() { + if ( !mpWindow ) + { + return; + } + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + // release old path and indicate no clipping CGPathRelease( mrClippingPath ); mrClippingPath = NULL; @@ -1591,6 +1721,14 @@ void AquaSalFrame::ResetClipRegion() void AquaSalFrame::BeginSetClipRegion( ULONG nRects ) { + if ( !mpWindow ) + { + return; + } + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + // release old path if( mrClippingPath ) { @@ -1609,6 +1747,9 @@ void AquaSalFrame::BeginSetClipRegion( ULONG nRects ) void AquaSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) { + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( nWidth && nHeight ) { NSRect aRect = { { nX, nY }, { nWidth, nHeight } }; @@ -1619,6 +1760,14 @@ void AquaSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight void AquaSalFrame::EndSetClipRegion() { + if ( !mpWindow ) + { + return; + } + + // #i113170# may not be the main thread if called from UNO API + SalData::ensureThreadAutoreleasePool(); + if( ! maClippingRects.empty() ) { mrClippingPath = CGPathCreateMutable(); diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm index 0dfa0fa356aa..bc87ea444710 100755 --- a/vcl/aqua/source/window/salframeview.mm +++ b/vcl/aqua/source/window/salframeview.mm @@ -154,7 +154,9 @@ static AquaSalFrame* getMouseContainerFrame() NSRect aRect = { { pFrame->maGeometry.nX, pFrame->maGeometry.nY }, { pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight } }; pFrame->VCLToCocoa( aRect ); - return [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ]; + NSWindow* pNSWindow = [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ]; + [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver + return pNSWindow; } -(AquaSalFrame*)getSalFrame @@ -162,6 +164,20 @@ static AquaSalFrame* getMouseContainerFrame() return mpFrame; } +-(void)displayIfNeeded +{ + if( GetSalData() && GetSalData()->mpFirstInstance ) + { + vos::IMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex(); + if( pMutex ) + { + pMutex->acquire(); + [super displayIfNeeded]; + pMutex->release(); + } + } +} + -(MacOSBOOL)containsMouse { // is this event actually inside that NSWindow ? @@ -378,6 +394,7 @@ static AquaSalFrame* getMouseContainerFrame() mpLastSuperEvent = nil; } + mfLastMagnifyTime = 0.0; return self; } @@ -572,8 +589,11 @@ private: -(void)mouseEntered: (NSEvent*)pEvent { s_pMouseFrame = mpFrame; - - [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE]; + + // #i107215# the only mouse events we get when inactive are enter/exit + // actually we would like to have all of them, but better none than some + if( [NSApp isActive] ) + [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE]; } -(void)mouseExited: (NSEvent*)pEvent @@ -581,7 +601,10 @@ private: if( s_pMouseFrame == mpFrame ) s_pMouseFrame = NULL; - [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE]; + // #i107215# the only mouse events we get when inactive are enter/exit + // actually we would like to have all of them, but better none than some + if( [NSApp isActive] ) + [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE]; } -(void)rightMouseDown: (NSEvent*)pEvent @@ -637,21 +660,40 @@ private: // TODO: ?? -(float)magnification; if( AquaSalFrame::isAlive( mpFrame ) ) - { - mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 ); + { + const NSTimeInterval fMagnifyTime = [pEvent timestamp]; + mpFrame->mnLastEventTime = static_cast<ULONG>( fMagnifyTime * 1000.0 ); mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; - - float dZ = 0.0; - for(;;) + + // check if this is a new series of magnify events + static const NSTimeInterval fMaxDiffTime = 0.3; + const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime); + + if( bNewSeries ) + mfMagnifyDeltaSum = 0.0; + mfMagnifyDeltaSum += [pEvent deltaZ]; + + mfLastMagnifyTime = [pEvent timestamp]; + // TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control + static const float fMagnifyFactor = 0.25; + static const float fMinMagnifyStep = 15.0 / fMagnifyFactor; + if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep ) + return; + + // adapt NSEvent-sensitivity to application expectations + // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter + const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor; + int nDeltaZ = FRound( fDeltaZ ); + if( !nDeltaZ ) { - dZ += [pEvent deltaZ]; - NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask - untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; - if( !pNextEvent ) - break; - pEvent = pNextEvent; + // handle new series immediately + if( !bNewSeries ) + return; + nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1; } - + // eventually give credit for delta sum + mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor; + NSPoint aPt = [NSEvent mouseLocation]; mpFrame->CocoaToVCL( aPt ); @@ -667,18 +709,15 @@ private: if( Application::GetSettings().GetLayoutRTL() ) aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; - if( dZ != 0.0 ) - { - aEvent.mnDelta = static_cast<long>(floor(dZ)); - aEvent.mnNotchDelta = dZ < 0 ? -1 : 1; - if( aEvent.mnDelta == 0 ) - aEvent.mnDelta = aEvent.mnNotchDelta; - aEvent.mbHorz = FALSE; - aEvent.mnScrollLines = dZ > 0 ? dZ/WHEEL_EVENT_FACTOR : -dZ/WHEEL_EVENT_FACTOR; - if( aEvent.mnScrollLines == 0 ) - aEvent.mnScrollLines = 1; - mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); - } + aEvent.mnDelta = nDeltaZ; + aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; + aEvent.mbHorz = FALSE; + aEvent.mnScrollLines = nDeltaZ; + if( aEvent.mnScrollLines == 0 ) + aEvent.mnScrollLines = 1; + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); } } @@ -1510,6 +1549,11 @@ private: mbKeyHandled = true; } +-(void)clearLastEvent +{ + mpLastEvent = nil; +} + - (NSRect)firstRectForCharacterRange:(NSRange)theRange { SalExtTextInputPosEvent aPosEvent; diff --git a/vcl/aqua/source/window/salmenu.cxx b/vcl/aqua/source/window/salmenu.cxx index f39d7c675bc4..82102f2e7095 100644 --- a/vcl/aqua/source/window/salmenu.cxx +++ b/vcl/aqua/source/window/salmenu.cxx @@ -79,10 +79,14 @@ const AquaSalMenu* AquaSalMenu::pCurrentMenuBar = NULL; -(void)showPreferences: (id) sender { + YIELD_GUARD; + [self showDialog: SHOWDIALOG_ID_PREFERENCES]; } -(void)showAbout: (id) sender { + YIELD_GUARD; + [self showDialog: SHOWDIALOG_ID_ABOUT]; } @end @@ -203,11 +207,12 @@ static void initAppMenu() // ======================================================================= -SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar ) +SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar, Menu* pVCLMenu ) { initAppMenu(); AquaSalMenu *pAquaSalMenu = new AquaSalMenu( bMenuBar ); + pAquaSalMenu->mpVCLMenu = pVCLMenu; return pAquaSalMenu; } @@ -370,6 +375,10 @@ bool AquaSalMenu::ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rR displayPopupFrame.origin.y = pWin->ImplGetFrame()->maGeometry.nY - pParentAquaSalFrame->maGeometry.nY + offset; pParentAquaSalFrame->VCLToCocoa(displayPopupFrame, false); + // #i111992# if this menu was opened due to a key event, prevent dispatching that yet again + if( [pParentNSView respondsToSelector: @selector(clearLastEvent)] ) + [pParentNSView performSelector:@selector(clearLastEvent)]; + // open popup menu NSPopUpButtonCell * pPopUpButtonCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]; [pPopUpButtonCell setMenu: pCopyMenu]; diff --git a/vcl/aqua/source/window/salobj.cxx b/vcl/aqua/source/window/salobj.cxx index 07d337dcc81a..f300929f04fe 100644 --- a/vcl/aqua/source/window/salobj.cxx +++ b/vcl/aqua/source/window/salobj.cxx @@ -237,3 +237,9 @@ const SystemEnvData* AquaSalObject::GetSystemData() const return &maSysData; } +// ----------------------------------------------------------------------- + +void AquaSalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/inc/cupsmgr.hxx b/vcl/inc/cupsmgr.hxx index b413184f477f..0250cece817e 100644 --- a/vcl/inc/cupsmgr.hxx +++ b/vcl/inc/cupsmgr.hxx @@ -70,7 +70,7 @@ class CUPSManager : public PrinterInfoManager virtual void initialize(); - void getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOptions, void** rOptions ) const; + void getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner, int& rNumOptions, void** rOptions ) const; void runDests(); public: // public for stub @@ -84,7 +84,7 @@ public: const char* authenticateUser( const char* ); virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand ); - virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ); + virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ); virtual void setupJobContextData( JobData& rData ); // changes the info about a named printer diff --git a/vcl/inc/vcl/abstdlg.hxx b/vcl/inc/vcl/abstdlg.hxx index 1d4e08991bda..2fa134af5078 100644 --- a/vcl/inc/vcl/abstdlg.hxx +++ b/vcl/inc/vcl/abstdlg.hxx @@ -66,6 +66,16 @@ public: virtual void Sync() = 0; }; +class VCL_DLLPUBLIC AbstractPasswordToOpenModifyDialog : public VclAbstractDialog +{ +public: + virtual String GetPasswordToOpen() const = 0; + virtual String GetPasswordToModify() const = 0; + virtual bool IsRecommendToOpenReadonly() const = 0; +}; + +//------------------------------------------------------------- + class VCL_DLLPUBLIC VclAbstractDialogFactory { public: @@ -74,6 +84,9 @@ public: // nDialogId was previously a ResId without ResMgr; the ResourceId is now // an implementation detail of the factory virtual VclAbstractDialog* CreateVclDialog( Window* pParent, sal_uInt32 nResId ) = 0; + + // creates instance of PasswordToOpenModifyDialog from cui + virtual AbstractPasswordToOpenModifyDialog * CreatePasswordToOpenModifyDialog( Window * pParent, sal_uInt16 nMinPasswdLen, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify ) = 0; }; #endif diff --git a/vcl/inc/vcl/arrange.hxx b/vcl/inc/vcl/arrange.hxx index 8846d9bbe948..327494b216e4 100644 --- a/vcl/inc/vcl/arrange.hxx +++ b/vcl/inc/vcl/arrange.hxx @@ -48,7 +48,7 @@ namespace vcl or a child WindowArranger (a node in the hierarchy), but never both */ - class WindowArranger + class VCL_DLLPUBLIC WindowArranger { protected: struct Element @@ -76,11 +76,13 @@ namespace vcl Element( Window* i_pWin, boost::shared_ptr<WindowArranger> const & i_pChild = boost::shared_ptr<WindowArranger>(), - sal_Int32 i_nExpandPriority = 0 + sal_Int32 i_nExpandPriority = 0, + const Size& i_rMinSize = Size() ) : m_pElement( i_pWin ) , m_pChild( i_pChild ) , m_nExpandPriority( i_nExpandPriority ) + , m_aMinSize( i_rMinSize ) , m_bHidden( false ) , m_nLeftBorder( 0 ) , m_nTopBorder( 0 ) @@ -101,12 +103,19 @@ namespace vcl Rectangle m_aManagedArea; long m_nOuterBorder; + rtl::OUString m_aIdentifier; + virtual Element* getElement( size_t i_nIndex ) = 0; const Element* getConstElement( size_t i_nIndex ) const { return const_cast<WindowArranger*>(this)->getElement( i_nIndex ); } public: + static long getDefaultBorder(); + + static long getBorderValue( long nBorder ) + { return nBorder >= 0 ? nBorder : -nBorder * getDefaultBorder(); } + WindowArranger( WindowArranger* i_pParent = NULL ) : m_pParentWindow( i_pParent ? i_pParent->m_pParentWindow : NULL ) , m_pParentArranger( i_pParent ) @@ -141,6 +150,9 @@ namespace vcl virtual bool isVisible() const; // true if any element is visible + virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getProperties() const; + virtual void setProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& ); + sal_Int32 getExpandPriority( size_t i_nIndex ) const { const Element* pEle = getConstElement( i_nIndex ); @@ -173,6 +185,19 @@ namespace vcl } } + void getBorders( size_t i_nIndex, long* i_pLeft = NULL, long* i_pTop = NULL, long* i_pRight = NULL, long* i_pBottom = NULL ) const + { + const Element* pEle = getConstElement( i_nIndex ); + if( pEle ) + { + if( i_pLeft ) *i_pLeft = pEle->m_nLeftBorder; + if( i_pTop ) *i_pTop = pEle->m_nTopBorder; + if( i_pRight ) *i_pRight = pEle->m_nRightBorder; + if( i_pBottom ) *i_pBottom = pEle->m_nBottomBorder; + } + } + + void show( bool i_bShow = true, bool i_bImmediateUpdate = true ); void setManagedArea( const Rectangle& i_rArea ) @@ -187,9 +212,15 @@ namespace vcl m_nOuterBorder = i_nBorder; resize(); } + + const rtl::OUString getIdentifier() const + { return m_aIdentifier; } + + void setIdentifier( const rtl::OUString& i_rId ) + { m_aIdentifier = i_rId; } }; - class RowOrColumn : public WindowArranger + class VCL_DLLPUBLIC RowOrColumn : public WindowArranger { long m_nBorderWidth; bool m_bColumn; @@ -204,7 +235,7 @@ namespace vcl public: RowOrColumn( WindowArranger* i_pParent = NULL, - bool bColumn = true, long i_nBorderWidth = 5 ) + bool bColumn = true, long i_nBorderWidth = -1 ) : WindowArranger( i_pParent ) , m_nBorderWidth( i_nBorderWidth ) , m_bColumn( bColumn ) @@ -218,7 +249,7 @@ namespace vcl // add a managed window at the given index // an index smaller than zero means add the window at the end - size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 ); + size_t addWindow( Window*, sal_Int32 i_nExpandPrio = 0, const Size& i_rMinSize = Size(), size_t i_nIndex = ~0 ); void remove( Window* ); size_t addChild( boost::shared_ptr<WindowArranger> const &, sal_Int32 i_nExpandPrio = 0, size_t i_nIndex = ~0 ); @@ -230,7 +261,7 @@ namespace vcl long getBorderWidth() const { return m_nBorderWidth; } }; - class LabeledElement : public WindowArranger + class VCL_DLLPUBLIC LabeledElement : public WindowArranger { WindowArranger::Element m_aLabel; WindowArranger::Element m_aElement; @@ -248,7 +279,7 @@ namespace vcl } public: - LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = 5 ) + LabeledElement( WindowArranger* i_pParent = NULL, int i_nLabelStyle = 0, long i_nDistance = -1 ) : WindowArranger( i_pParent ) , m_nDistance( i_nDistance ) , m_nLabelColumnWidth( 0 ) @@ -274,11 +305,11 @@ namespace vcl { return m_aElement.getOptimalSize( i_eType ); } }; - class LabelColumn : public RowOrColumn + class VCL_DLLPUBLIC LabelColumn : public RowOrColumn { long getLabelWidth() const; public: - LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = 5 ) + LabelColumn( WindowArranger* i_pParent = NULL, long i_nBorderWidth = -1 ) : RowOrColumn( i_pParent, true, i_nBorderWidth ) {} virtual ~LabelColumn(); @@ -288,10 +319,10 @@ namespace vcl // returns the index of the added label size_t addRow( Window* i_pLabel, boost::shared_ptr<WindowArranger> const& i_rElement, long i_nIndent = 0 ); - size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0 ); + size_t addRow( Window* i_pLabel, Window* i_pElement, long i_nIndent = 0, const Size& i_rElementMinSize = Size() ); }; - class Indenter : public WindowArranger + class VCL_DLLPUBLIC Indenter : public WindowArranger { long m_nIndent; WindowArranger::Element m_aElement; @@ -301,7 +332,7 @@ namespace vcl { return i_nIndex == 0 ? &m_aElement : NULL; } public: - Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 15 ) + Indenter( WindowArranger* i_pParent = NULL, long i_nIndent = 3*getDefaultBorder() ) : WindowArranger( i_pParent ) , m_nIndent( i_nIndent ) {} @@ -325,7 +356,7 @@ namespace vcl { setChild( boost::shared_ptr<WindowArranger>( i_pChild ), i_nExpandPrio ); } }; - class Spacer : public WindowArranger + class VCL_DLLPUBLIC Spacer : public WindowArranger { WindowArranger::Element m_aElement; Size m_aSize; @@ -351,7 +382,7 @@ namespace vcl virtual bool isVisible() const { return true; } }; - class MatrixArranger : public WindowArranger + class VCL_DLLPUBLIC MatrixArranger : public WindowArranger { long m_nBorderX; long m_nBorderY; @@ -370,9 +401,10 @@ namespace vcl MatrixElement( Window* i_pWin, sal_uInt32 i_nX, sal_uInt32 i_nY, boost::shared_ptr<WindowArranger> const & i_pChild = boost::shared_ptr<WindowArranger>(), - sal_Int32 i_nExpandPriority = 0 + sal_Int32 i_nExpandPriority = 0, + const Size& i_rMinSize = Size() ) - : WindowArranger::Element( i_pWin, i_pChild, i_nExpandPriority ) + : WindowArranger::Element( i_pWin, i_pChild, i_nExpandPriority, i_rMinSize ) , m_nX( i_nX ) , m_nY( i_nY ) { @@ -385,15 +417,20 @@ namespace vcl sal_uInt64 getMap( sal_uInt32 i_nX, sal_uInt32 i_nY ) { return static_cast< sal_uInt64 >(i_nX) | (static_cast< sal_uInt64>(i_nY) << 32 ); } - Size getOptimalSize( WindowSizeType, std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights ) const; + static void distributeExtraSize( std::vector<long>& io_rSizes, const std::vector<sal_Int32>& i_rPrios, long i_nExtraWidth ); + + Size getOptimalSize( WindowSizeType, + std::vector<long>& o_rColumnWidths, std::vector<long>& o_rRowHeights, + std::vector<sal_Int32>& o_rColumnPrio, std::vector<sal_Int32>& o_rRowPrio + ) const; protected: virtual Element* getElement( size_t i_nIndex ) { return i_nIndex < m_aElements.size() ? &m_aElements[ i_nIndex ] : 0; } public: MatrixArranger( WindowArranger* i_pParent = NULL, - long i_nBorderX = 5, - long i_nBorderY = 5 ) + long i_nBorderX = -1, + long i_nBorderY = -1 ) : WindowArranger( i_pParent ) , m_nBorderX( i_nBorderX ) , m_nBorderY( i_nBorderY ) @@ -406,7 +443,7 @@ namespace vcl virtual size_t countElements() const { return m_aElements.size(); } // add a managed window at the given matrix position - size_t addWindow( Window*, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 ); + size_t addWindow( Window*, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0, const Size& i_rMinSize = Size() ); void remove( Window* ); size_t addChild( boost::shared_ptr<WindowArranger> const &, sal_uInt32 i_nX, sal_uInt32 i_nY, sal_Int32 i_nExpandPrio = 0 ); diff --git a/vcl/inc/vcl/btndlg.hxx b/vcl/inc/vcl/btndlg.hxx index dbeb8350a0d4..3186ba5f6399 100644 --- a/vcl/inc/vcl/btndlg.hxx +++ b/vcl/inc/vcl/btndlg.hxx @@ -104,8 +104,8 @@ public: XubString GetButtonText( USHORT nId ) const; void SetButtonHelpText( USHORT nId, const XubString& rText ); XubString GetButtonHelpText( USHORT nId ) const; - void SetButtonHelpId( USHORT nId, ULONG nHelpId ); - ULONG GetButtonHelpId( USHORT nId ) const; + void SetButtonHelpId( USHORT nId, const rtl::OString& rHelpId ); + rtl::OString GetButtonHelpId( USHORT nId ) const; void SetFocusButton( USHORT nId = BUTTONDIALOG_BUTTON_NOTFOUND ) { mnFocusButtonId = nId; } USHORT GetFocusButton() const { return mnFocusButtonId; } diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx index 8f4b94bf7b18..ddd023a3aaa4 100644 --- a/vcl/inc/vcl/button.hxx +++ b/vcl/inc/vcl/button.hxx @@ -66,6 +66,8 @@ public: SAL_DLLPRIVATE void ImplSetSymbolAlign( SymbolAlign eAlign ); SAL_DLLPRIVATE SymbolAlign ImplGetSymbolAlign() const; SAL_DLLPRIVATE void ImplSetSmallSymbol( BOOL bSmall = TRUE ); + SAL_DLLPRIVATE const Rectangle& ImplGetSymbolRect() const; + SAL_DLLPRIVATE void ImplSetSymbolRect(const Rectangle&); protected: Button( WindowType nType ); @@ -76,7 +78,6 @@ public: ~Button(); virtual void Click(); - virtual void DataChanged( const DataChangedEvent& rDCEvt ); void SetClickHdl( const Link& rLink ) { maClickHdl = rLink; } const Link& GetClickHdl() const { return maClickHdl; } @@ -130,7 +131,7 @@ protected: SAL_DLLPRIVATE WinBits ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ); SAL_DLLPRIVATE void ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground ); SAL_DLLPRIVATE void ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags, - const Rectangle& rRect, bool bLayout ); + const Rectangle& rRect, bool bLayout, bool bMenuBtnSep ); SAL_DLLPRIVATE void ImplDrawPushButton( bool bLayout = false ); using Button::ImplGetTextStyle; SAL_DLLPRIVATE USHORT ImplGetTextStyle( ULONG nDrawFlags ) const; diff --git a/vcl/inc/vcl/combobox.hxx b/vcl/inc/vcl/combobox.hxx index e35474a84d53..640c70e7116f 100644 --- a/vcl/inc/vcl/combobox.hxx +++ b/vcl/inc/vcl/combobox.hxx @@ -138,6 +138,7 @@ public: USHORT GetEntryPos( const XubString& rStr ) const; USHORT GetEntryPos( const void* pData ) const; + Image GetEntryImage( USHORT nPos ) const; XubString GetEntry( USHORT nPos ) const; USHORT GetEntryCount() const; diff --git a/vcl/source/window/dndevdis.hxx b/vcl/inc/vcl/dndevdis.hxx index 5b91bd0713ec..5b91bd0713ec 100644 --- a/vcl/source/window/dndevdis.hxx +++ b/vcl/inc/vcl/dndevdis.hxx diff --git a/vcl/source/window/dndlcon.hxx b/vcl/inc/vcl/dndlcon.hxx index 5a41a20e4271..5a41a20e4271 100644 --- a/vcl/source/window/dndlcon.hxx +++ b/vcl/inc/vcl/dndlcon.hxx diff --git a/vcl/inc/vcl/edit.hxx b/vcl/inc/vcl/edit.hxx index a40de9503367..9dc427d83943 100644..100755 --- a/vcl/inc/vcl/edit.hxx +++ b/vcl/inc/vcl/edit.hxx @@ -247,6 +247,10 @@ public: virtual XubString GetSurroundingText() const; virtual Selection GetSurroundingTextSelection() const; + + // returns the minimum size a bordered Edit should have given the current + // global style settings (needed by sc's inputwin.cxx) + static Size GetMinimumEditSize(); }; inline ULONG Edit::IsUpdateDataEnabled() const diff --git a/vcl/inc/vcl/field.hxx b/vcl/inc/vcl/field.hxx index e1f39cc78966..6be9fd8d42c5 100644 --- a/vcl/inc/vcl/field.hxx +++ b/vcl/inc/vcl/field.hxx @@ -34,7 +34,7 @@ #include <tools/time.hxx> #include <vcl/spinfld.hxx> #include <vcl/combobox.hxx> -#include <vcl/fldunit.hxx> +#include <tools/fldunit.hxx> namespace com { namespace sun { namespace star { namespace lang { struct Locale; } } } } diff --git a/vcl/inc/vcl/fldunit.hxx b/vcl/inc/vcl/fldunit.hxx deleted file mode 100644 index aa76f34332d6..000000000000 --- a/vcl/inc/vcl/fldunit.hxx +++ /dev/null @@ -1,33 +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 _VCL_FLDUNIT_HXX -#define _VCL_FLDUNIT_HXX - -#include <tools/fldunit.hxx> - -#endif // _VCL_FLDUNIT_HXX diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx index 06f7a0d14a2e..636fc4a979f3 100644 --- a/vcl/inc/vcl/gdimtf.hxx +++ b/vcl/inc/vcl/gdimtf.hxx @@ -158,6 +158,8 @@ public: sal_Bool IsEqual( const GDIMetaFile& rMtf ) const; BOOL Mirror( ULONG nMirrorFlags ); void Move( long nX, long nY ); + // additional Move method getting specifics how to handle MapMode( MAP_PIXEL ) + void Move( long nX, long nY, long nDPIX, long nDPIY ); void Scale( double fScaleX, double fScaleY ); void Scale( const Fraction& rScaleX, const Fraction& rScaleY ); void Rotate( long nAngle10 ); diff --git a/vcl/inc/vcl/gfxlink.hxx b/vcl/inc/vcl/gfxlink.hxx index 3b3938ec848b..dced5a19c461 100644 --- a/vcl/inc/vcl/gfxlink.hxx +++ b/vcl/inc/vcl/gfxlink.hxx @@ -33,9 +33,6 @@ #include <vcl/mapmod.hxx> #include <tools/stream.hxx> -//#if 0 // _SOLAR__PRIVATE -#include <tools/urlobj.hxx> - // ------------- // - ImpBuffer - // ------------- @@ -62,7 +59,7 @@ struct ImpBuffer struct ImpSwap { - INetURLObject maURL; + rtl::OUString maURL; ULONG mnDataSize; ULONG mnRefCount; @@ -71,7 +68,7 @@ struct ImpSwap BYTE* GetData() const; - BOOL IsSwapped() const { return maURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() > 0; } + BOOL IsSwapped() const { return maURL.getLength() > 0; } void WriteTo( SvStream& rOStm ) const; }; diff --git a/vcl/inc/vcl/glyphcache.hxx b/vcl/inc/vcl/glyphcache.hxx index a77c1626dc24..0e77d5dd6bc4 100644 --- a/vcl/inc/vcl/glyphcache.hxx +++ b/vcl/inc/vcl/glyphcache.hxx @@ -48,7 +48,6 @@ class ImplFontOptions; namespace basegfx { class B2DPolyPolygon; } class RawBitmap; -class CmapResult; #include <vcl/outfont.hxx> #include <vcl/impfont.hxx> @@ -190,7 +189,7 @@ public: virtual void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const = 0; virtual ULONG GetKernPairs( ImplKernPairData** ) const { return 0; } virtual int GetGlyphKernValue( int, int ) const { return 0; } - virtual bool GetFontCodeRanges( CmapResult& ) const { return false; } + virtual const ImplFontCharMap* GetImplFontCharMap() const = 0; Point TransformPoint( const Point& ) const; GlyphData& GetGlyphData( int nGlyphIndex ); diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx index 43c2e37a5fb2..ae2ff2962adb 100644 --- a/vcl/inc/vcl/graphite_adaptors.hxx +++ b/vcl/inc/vcl/graphite_adaptors.hxx @@ -55,11 +55,11 @@ #include "vcl/dllapi.h" // Libraries -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include <tools/postextstl.h> +#include <postextstl.h> // Module type definitions and forward declarations. // @@ -86,8 +86,8 @@ namespace grutils // class VCL_DLLPUBLIC GraphiteFontAdaptor : public gr::Font { -typedef std::map<const gr::gid16, std::pair<gr::Rect, gr::Point> > GlyphMetricMap; - + typedef std::map<const gr::gid16, std::pair<gr::Rect, gr::Point> > GlyphMetricMap; + friend class GrFontHasher; public: static bool IsGraphiteEnabledFont(ServerFont &) throw(); diff --git a/vcl/inc/vcl/graphite_cache.hxx b/vcl/inc/vcl/graphite_cache.hxx index 5472b32dd62f..af1392ed4d4b 100644 --- a/vcl/inc/vcl/graphite_cache.hxx +++ b/vcl/inc/vcl/graphite_cache.hxx @@ -105,15 +105,16 @@ typedef std::pair<GraphiteRopeMap::iterator, GraphiteRopeMap::iterator> GrRMEntr */ class GraphiteSegmentCache { +public: enum { // not really sure what good values are here, // bucket size should be >> cache size - SEG_BUCKET_SIZE = 4096, - SEG_CACHE_SIZE = 255 + SEG_BUCKET_FACTOR = 4, + SEG_DEFAULT_CACHE_SIZE = 2047 }; -public: - GraphiteSegmentCache() - : m_segMap(SEG_BUCKET_SIZE), + GraphiteSegmentCache(sal_uInt32 nSegCacheSize) + : m_segMap(nSegCacheSize * SEG_BUCKET_FACTOR), + m_nSegCacheSize(nSegCacheSize), m_oldestKey(NULL) {}; ~GraphiteSegmentCache() { @@ -224,6 +225,7 @@ public: private: GraphiteSegMap m_segMap; GraphiteRopeMap m_ropeMap; + sal_uInt32 m_nSegCacheSize; const xub_Unicode * m_oldestKey; const xub_Unicode * m_prevKey; }; @@ -236,7 +238,24 @@ typedef std::hash_map<int, GraphiteSegmentCache *, std::hash<int> > GraphiteCach class GraphiteCacheHandler { public: - GraphiteCacheHandler() : m_cacheMap(255) {}; + GraphiteCacheHandler() : m_cacheMap(255) + { + const char * pEnvCache = getenv( "SAL_GRAPHITE_CACHE_SIZE" ); + if (pEnvCache != NULL) + { + int envCacheSize = atoi(pEnvCache); + if (envCacheSize <= 0) + m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE; + else + { + m_nSegCacheSize = envCacheSize; + } + } + else + { + m_nSegCacheSize = GraphiteSegmentCache::SEG_DEFAULT_CACHE_SIZE; + } + }; ~GraphiteCacheHandler() { GraphiteCacheMap::iterator i = m_cacheMap.begin(); @@ -257,12 +276,13 @@ public: { return m_cacheMap.find(fontHash)->second; } - GraphiteSegmentCache *pCache = new GraphiteSegmentCache(); + GraphiteSegmentCache *pCache = new GraphiteSegmentCache(m_nSegCacheSize); m_cacheMap[fontHash] = pCache; return pCache; } private: GraphiteCacheMap m_cacheMap; + sal_uInt32 m_nSegCacheSize; }; #endif diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx index 47f4c3a01e7f..47b8f062e299 100644 --- a/vcl/inc/vcl/graphite_features.hxx +++ b/vcl/inc/vcl/graphite_features.hxx @@ -29,11 +29,11 @@ // Parse a string of features specified as ; separated pairs. // e.g. // 1001=1&2002=2&fav1=0 -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrFeature.h> -#include <tools/postextstl.h> +#include <postextstl.h> namespace grutils { diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx index 520f4620cd90..cd22abdcdb26 100644 --- a/vcl/inc/vcl/graphite_layout.hxx +++ b/vcl/inc/vcl/graphite_layout.hxx @@ -40,13 +40,13 @@ #include <vector> #include <utility> // Libraries -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/GrConstants.h> #include <graphite/GrAppData.h> #include <graphite/SegmentAux.h> -#include <tools/postextstl.h> +#include <postextstl.h> // Platform #include <vcl/sallayout.hxx> #include <vcl/dllapi.h> @@ -65,6 +65,19 @@ class GraphiteFontAdaptor; class GrSegRecord; // SAL/VCL types class ServerFont; + +#ifdef WNT +// The GraphiteWinFont is just a wrapper to enable GrFontHasher to be a friend +// so that UniqueCacheInfo can be called. +#include <graphite/WinFont.h> +class GraphiteWinFont : public gr::WinFont +{ + friend class GrFontHasher; +public: + GraphiteWinFont(HDC hdc) : gr::WinFont(hdc) {}; + virtual ~GraphiteWinFont() {}; +}; +#endif // Graphite types namespace gr { class Segment; class GlyphIterator; } namespace grutils { class GrFeatureParser; } @@ -98,7 +111,7 @@ public: iterator_pair_t neighbour_clusters(const_iterator) const; private: std::pair<float,float> appendCluster(gr::Segment & rSeg, ImplLayoutArgs & rArgs, - bool bRtl, int nFirstCharInCluster, int nNextChar, + bool bRtl, float fSegmentAdvance, int nFirstCharInCluster, int nNextChar, int nFirstGlyphInCluster, int nNextGlyph, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset); diff --git a/vcl/inc/vcl/help.hxx b/vcl/inc/vcl/help.hxx index 30308aa8a723..1f4ba36d8f43 100644 --- a/vcl/inc/vcl/help.hxx +++ b/vcl/inc/vcl/help.hxx @@ -52,8 +52,8 @@ class Window; #define QUICKHELP_BIDI_RTL ((USHORT)0x8000) // By changes you must also change: rsc/vclrsc.hxx -#define OOO_HELP_INDEX ((ULONG)0xFFFFFFFF) -#define OOO_HELP_HELPONHELP ((ULONG)0xFFFFFFFE) +#define OOO_HELP_INDEX ".help:index" +#define OOO_HELP_HELPONHELP ".help:helponhelp" // -------- // - Help - @@ -71,10 +71,9 @@ public: void SetHelpFile( const String& rFileName ) { maHelpFile = rFileName; } const String& GetHelpFile() const { return maHelpFile; } - virtual BOOL Start( ULONG nHelpId, const Window* pWindow ); - virtual BOOL Start( const XubString& rKeyWord, const Window* pWindow ); - virtual void OpenHelpAgent( ULONG nHelpId ); - virtual XubString GetHelpText( ULONG nHelpId, const Window* pWindow ); + virtual BOOL Start( const XubString& rHelpId, const Window* pWindow ); + virtual BOOL SearchKeyword( const XubString& rKeyWord ); + virtual void OpenHelpAgent( const rtl::OString& rHelpId ); virtual XubString GetHelpText( const String& aHelpURL, const Window* pWindow ); static void EnableContextHelp(); diff --git a/vcl/inc/vcl/ilstbox.hxx b/vcl/inc/vcl/ilstbox.hxx index 33f60a1e8a2f..6580538f5d10 100644 --- a/vcl/inc/vcl/ilstbox.hxx +++ b/vcl/inc/vcl/ilstbox.hxx @@ -36,6 +36,7 @@ #include <vcl/lstbox.h> #include <vcl/timer.hxx> +#include "vcl/quickselectionengine.hxx" class ScrollBar; class ScrollBarBox; @@ -193,13 +194,11 @@ public: // - ImplListBoxWindow - // --------------------- -class ImplListBoxWindow : public Control +class ImplListBoxWindow : public Control, public ::vcl::ISearchableStringList { private: ImplEntryList* mpEntryList; // EntryListe Rectangle maFocusRect; - String maSearchStr; - Timer maSearchTimeout; Size maUserItemSize; @@ -254,9 +253,10 @@ private: Link maUserDrawHdl; Link maMRUChangedHdl; -protected: - DECL_LINK( SearchStringTimeout, Timer* ); + ::vcl::QuickSelectionEngine + maQuickSelectionEngine; +protected: virtual void KeyInput( const KeyEvent& rKEvt ); virtual void MouseButtonDown( const MouseEvent& rMEvt ); virtual void MouseMove( const MouseEvent& rMEvt ); @@ -379,6 +379,12 @@ public: // pb: #106948# explicit mirroring for calc inline void EnableMirroring() { mbMirroring = TRUE; } inline BOOL IsMirroring() const { return mbMirroring; } + +protected: + // ISearchableStringList + virtual ::vcl::StringEntryIdentifier CurrentEntry( String& _out_entryText ) const; + virtual ::vcl::StringEntryIdentifier NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const; + virtual void SelectEntry( ::vcl::StringEntryIdentifier _entry ); }; // --------------- @@ -396,6 +402,7 @@ private: mbHScroll : 1, // HScroll an oder aus mbAutoHScroll : 1; // AutoHScroll an oder aus Link maScrollHdl; // Weil der vom ImplListBoxWindow selbst benoetigt wird. + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer; protected: virtual void GetFocus(); @@ -500,6 +507,7 @@ public: // pb: #106948# explicit mirroring for calc inline void EnableMirroring() { maLBWindow.EnableMirroring(); } + inline void SetDropTraget(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_xDNDListenerContainer){ mxDNDListenerContainer= i_xDNDListenerContainer; } }; // ----------------------------- diff --git a/vcl/inc/vcl/imgcons.hxx b/vcl/inc/vcl/imgcons.hxx deleted file mode 100644 index 2f582fec15c3..000000000000 --- a/vcl/inc/vcl/imgcons.hxx +++ /dev/null @@ -1,105 +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 _IMGCONS_HXX -#define _IMGCONS_HXX - -#include <vcl/dllapi.h> - -#include <vcl/bitmap.hxx> - -// ----------------- -// - ImageConsumer - -// ----------------- - -class ImageProducer; -class ImplColorMapper; -class BitmapEx; -class Image; - -#define IMAGEERROR 1 -#define SINGLEFRAMEDONE 2 -#define STATICIMAGEDONE 3 -#define IMAGEABORTED 4 - -class VCL_DLLPUBLIC ImageConsumer -{ -private: - - Bitmap maBitmap; - Bitmap maMask; - Rectangle maChangedRect; - Size maSize; - ImplColorMapper* mpMapper; - Color* mpPal; - Link maChgLink; - Link maDoneLink; - sal_uInt32 mnFormat; - sal_uInt32 mnStatus; - BOOL mbTrans; - -protected: - - virtual void DataChanged(); - -public: - - ImageConsumer(); - virtual ~ImageConsumer(); - - BOOL GetData( BitmapEx& rBmpEx ) const; - BOOL GetData( Image& rImage ) const; - const Rectangle& GetChangedRect() const { return maChangedRect; } - sal_uInt32 GetStatus() const; - - void SetDataChangedLink( const Link& rLink ) { maChgLink = rLink; } - const Link& GetDataChangedLink() const { return maChgLink; } - - void SetDoneLink( const Link& rLink ) { maDoneLink = rLink; } - const Link& GetDoneLink() const { return maDoneLink; } - -public: - - virtual void Init( sal_uInt32 nWidth, sal_uInt32 nHeight ); - - virtual void SetColorModel( USHORT nBitCount, - sal_uInt32 nPalEntries, const sal_uInt32* pRGBAPal, - sal_uInt32 nRMask, sal_uInt32 nGMask, sal_uInt32 nBMask, sal_uInt32 nAMask ); - - virtual void SetPixelsByBytes( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const BYTE* pProducerData, sal_uInt32 nOffset, sal_uInt32 nScanSize ); - - virtual void SetPixelsByLongs( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const sal_uInt32* pProducerData, sal_uInt32 nOffset, sal_uInt32 nScanSize ); - - virtual void Completed( sal_uInt32 nStatus ); -// virtual void Completed( sal_uInt32 nStatus, ImageProducer& rProducer ); -}; - -#endif // _IMGCONS_HXX diff --git a/vcl/inc/vcl/impfont.hxx b/vcl/inc/vcl/impfont.hxx index a1104bbf4a86..e38e1dea78d4 100644 --- a/vcl/inc/vcl/impfont.hxx +++ b/vcl/inc/vcl/impfont.hxx @@ -196,8 +196,8 @@ public: int GetIndexFromChar( sal_uInt32 ) const; sal_uInt32 GetCharFromIndex( int ) const; - void AddReference(); - void DeReference(); + void AddReference() const; + void DeReference() const; int GetGlyphIndex( sal_uInt32 ) const; @@ -213,8 +213,8 @@ private: const int* mpStartGlyphs; // range-specific mapper to glyphs const USHORT* mpGlyphIds; // individual glyphid mappings int mnRangeCount; - int mnCharCount; - int mnRefCount; + int mnCharCount; // covered codepoints + mutable int mnRefCount; }; // CmapResult is a normalized version of the many CMAP formats diff --git a/vcl/inc/vcl/javachild.hxx b/vcl/inc/vcl/javachild.hxx index 62b447f26571..c5ec3c678900 100644 --- a/vcl/inc/vcl/javachild.hxx +++ b/vcl/inc/vcl/javachild.hxx @@ -47,8 +47,6 @@ public: private: - SAL_DLLPRIVATE void implTestJavaException( void* pEnv ); - // Copy assignment is forbidden and not implemented. SAL_DLLPRIVATE JavaChildWindow (const JavaChildWindow &); SAL_DLLPRIVATE JavaChildWindow & operator= (const JavaChildWindow &); diff --git a/vcl/inc/vcl/jobdata.hxx b/vcl/inc/vcl/jobdata.hxx index f576b816dab0..18330ae3508d 100644 --- a/vcl/inc/vcl/jobdata.hxx +++ b/vcl/inc/vcl/jobdata.hxx @@ -50,6 +50,7 @@ struct JobData int m_nColorDepth; int m_nPSLevel; // 0: no override, else languaglevel to use int m_nColorDevice; // 0: no override, -1 grey scale, +1 color + int m_nPDFDevice; // 0: PostScript, 1: PDF orientation::type m_eOrientation; ::rtl::OUString m_aPrinterName; const PPDParser* m_pParser; @@ -64,6 +65,7 @@ struct JobData m_nColorDepth( 24 ), m_nPSLevel( 0 ), m_nColorDevice( 0 ), + m_nPDFDevice( 0 ), m_eOrientation( orientation::Portrait ), m_pParser( NULL ) {} @@ -72,6 +74,8 @@ struct JobData JobData( const JobData& rData ) { *this = rData; } void setCollate( bool bCollate ); + bool setPaper( int nWidth, int nHeight ); // dimensions in pt + bool setPaperBin( int nPaperBin ); // dimensions in pt // creates a new buffer using new // it is up to the user to delete it again diff --git a/vcl/inc/vcl/lazydelete.hxx b/vcl/inc/vcl/lazydelete.hxx index 4176d5b4454f..dad10fb62b33 100644 --- a/vcl/inc/vcl/lazydelete.hxx +++ b/vcl/inc/vcl/lazydelete.hxx @@ -39,6 +39,8 @@ #include <stdio.h> #endif +#include <com/sun/star/lang/XComponent.hpp> + namespace vcl { /* Helpers for lazy object deletion @@ -256,6 +258,43 @@ namespace vcl // ownership is transfered ! T* set( T* i_pNew ) { T* pOld = m_pT; m_pT = i_pNew; return pOld; } }; + + /** Similar to DeleteOnDeinit, the DeleteUnoReferenceOnDeinit + template class makes sure that a static UNO object is disposed + and released at the right time. + + Use like + static DeleteUnoReferenceOnDeinit<lang::XMultiServiceFactory> + xStaticFactory (<create factory object>); + Reference<lang::XMultiServiceFactory> xFactory (xStaticFactory.get()); + if (xFactory.is()) + <do something with xFactory> + */ + template <typename I> + class DeleteUnoReferenceOnDeinit : public ::vcl::DeleteOnDeinitBase + { + ::com::sun::star::uno::Reference<I> m_xI; + virtual void doCleanup() { set(NULL); } + public: + DeleteUnoReferenceOnDeinit(const ::com::sun::star::uno::Reference<I>& r_xI ) : m_xI( r_xI ) { + addDeinitContainer( this ); } + virtual ~DeleteUnoReferenceOnDeinit() {} + + ::com::sun::star::uno::Reference<I> get (void) { return m_xI; } + + void set (const ::com::sun::star::uno::Reference<I>& r_xNew ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xComponent (m_xI, ::com::sun::star::uno::UNO_QUERY); + m_xI = r_xNew; + if (xComponent.is()) try + { + xComponent->dispose(); + } + catch( ::com::sun::star::uno::Exception& ) + { + } + } + }; } #endif diff --git a/vcl/inc/vcl/mapmod.hxx b/vcl/inc/vcl/mapmod.hxx index b2ea32958e90..260a5f4f86c2 100644 --- a/vcl/inc/vcl/mapmod.hxx +++ b/vcl/inc/vcl/mapmod.hxx @@ -33,7 +33,7 @@ #include <vcl/sv.h> #include <vcl/dllapi.h> #include <tools/resid.hxx> -#include <vcl/mapunit.hxx> +#include <tools/mapunit.hxx> class SvStream; diff --git a/vcl/inc/vcl/mapunit.hxx b/vcl/inc/vcl/mapunit.hxx deleted file mode 100644 index b4c757c538e6..000000000000 --- a/vcl/inc/vcl/mapunit.hxx +++ /dev/null @@ -1,33 +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 _VCL_MAPUNIT_HXX -#define _VCL_MAPUNIT_HXX - -#include <tools/mapunit.hxx> - -#endif // _VCL_MAPUNIT_HXX diff --git a/vcl/inc/vcl/menu.hxx b/vcl/inc/vcl/menu.hxx index c0cc3b5b51d6..d57fdeb7cfd3 100644 --- a/vcl/inc/vcl/menu.hxx +++ b/vcl/inc/vcl/menu.hxx @@ -41,6 +41,7 @@ struct MenuItemData; class Point; class Size; class Rectangle; +class Menu; class MenuItemList; class HelpEvent; class Image; @@ -102,6 +103,17 @@ typedef USHORT MenuItemBits; // forces images & toggle visibility for toolbar config popup #define MENU_FLAG_SHOWCHECKIMAGES 0x0008 +struct ImplMenuDelData +{ + ImplMenuDelData* mpNext; + const Menu* mpMenu; + + ImplMenuDelData( const Menu* pMenu ); + ~ImplMenuDelData(); + + bool isDeleted() const { return mpMenu == 0; } +}; + // -------- // - Menu - // -------- @@ -120,9 +132,9 @@ class VCL_DLLPUBLIC Menu : public Resource friend class MenuFloatingWindow; friend class PopupMenu; friend class SystemWindow; - + friend struct ImplMenuDelData; private: - void* pMenuData_NotUsedYet; + ImplMenuDelData* mpFirstDel; MenuItemList* pItemList; // Liste mit den MenuItems MenuLogo* pLogo; Menu* pStartedFrom; @@ -186,6 +198,8 @@ protected: // return value is Max( rCheckHeight, rRadioHeight ) SAL_DLLPRIVATE long ImplGetNativeCheckAndRadioSize( Window*, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth ) const; + SAL_DLLPRIVATE void ImplAddDel( ImplMenuDelData &rDel ); + SAL_DLLPRIVATE void ImplRemoveDel( ImplMenuDelData &rDel ); public: SAL_DLLPRIVATE void ImplKillLayoutData() const; SAL_DLLPRIVATE Menu* ImplGetStartedFrom() const; @@ -290,8 +304,8 @@ public: void SetHelpCommand( USHORT nItemId, const XubString& rString ); const XubString& GetHelpCommand( USHORT nItemId ) const; - void SetHelpId( USHORT nItemId, ULONG nHelpId ); - ULONG GetHelpId( USHORT nItemId ) const; + void SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ); + rtl::OString GetHelpId( USHORT nItemId ) const; void SetActivateHdl( const Link& rLink ) { aActivateHdl = rLink; } const Link& GetActivateHdl() const { return aActivateHdl; } diff --git a/vcl/inc/vcl/metric.hxx b/vcl/inc/vcl/metric.hxx index eae6b38c5f9d..6328890c1749 100644 --- a/vcl/inc/vcl/metric.hxx +++ b/vcl/inc/vcl/metric.hxx @@ -95,7 +95,7 @@ public: class VCL_DLLPUBLIC FontCharMap { private: - ImplFontCharMap* mpImpl; + const ImplFontCharMap* mpImpl; public: FontCharMap(); @@ -118,7 +118,7 @@ public: private: friend class OutputDevice; - void Reset( ImplFontCharMap* pNewMap = NULL ); + void Reset( const ImplFontCharMap* pNewMap = NULL ); // prevent assignment and copy construction FontCharMap( const FontCharMap& ); diff --git a/vcl/inc/vcl/mnemonicengine.hxx b/vcl/inc/vcl/mnemonicengine.hxx index d12b3db2417e..fcd303510203 100644 --- a/vcl/inc/vcl/mnemonicengine.hxx +++ b/vcl/inc/vcl/mnemonicengine.hxx @@ -59,7 +59,7 @@ namespace vcl If this value is <NULL/>, searching stops. */ - virtual const void* FirstSearchEntry( String& _rEntryText ) = 0; + virtual const void* FirstSearchEntry( String& _rEntryText ) const = 0; /** returns the next list entry for the mnemonic search @@ -74,7 +74,7 @@ namespace vcl to <member>FirstSearchEntry</member> (i.e. you cycled around), then searching stops, too. */ - virtual const void* NextSearchEntry( const void* _pCurrentSearchEntry, String& _rEntryText ) = 0; + virtual const void* NextSearchEntry( const void* _pCurrentSearchEntry, String& _rEntryText ) const = 0; /** "selects" a given entry. @@ -117,7 +117,7 @@ namespace vcl the entry to select. This is the return value of a previous call to <member>FirstSearchEntry</member> or <member>NextSearchEntry</member>. */ - virtual void ExecuteSearchEntry( const void* _pEntry ) = 0; + virtual void ExecuteSearchEntry( const void* _pEntry ) const = 0; }; //==================================================================== diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 9b748f2b5937..12c4202af144 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -185,6 +185,9 @@ struct KerningPair #define TEXT_DRAW_MULTILINE ((USHORT)0x1000) #define TEXT_DRAW_WORDBREAK ((USHORT)0x2000) #define TEXT_DRAW_NEWSELLIPSIS ((USHORT)0x4000) +// in the long run we should make text style flags longer +// but at the moment we can get away with this 2 bit field for ellipsis style +#define TEXT_DRAW_CENTERELLIPSIS (TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_PATHELLIPSIS) #define TEXT_DRAW_WORDBREAK_HYPHENATION (((USHORT)0x8000) | TEXT_DRAW_WORDBREAK) @@ -1114,7 +1117,7 @@ public: /** Added return value to see if EPS could be painted directly. Theoreticaly, handing over a matrix would be needed to handle - painting rotated EPS files (e.g. contained mn Metafiles). This + painting rotated EPS files (e.g. contained in Metafiles). This would then need to be supported for Mac and PS printers, but that's too much for now, wrote #i107046# for this */ bool DrawEPS( const Point& rPt, const Size& rSz, @@ -1191,14 +1194,14 @@ public: // Query the native control to determine if it was acted upon BOOL HitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); // Request rendering of a particular control and/or part BOOL DrawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ); @@ -1206,7 +1209,7 @@ public: // Request rendering of a caption string for a control BOOL DrawNativeControlText( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ); @@ -1214,12 +1217,12 @@ public: // Query the native control's actual drawing region (including adornment) BOOL GetNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion ); }; diff --git a/vcl/inc/vcl/outfont.hxx b/vcl/inc/vcl/outfont.hxx index 4bbf7176ddb2..7ad233449d93 100644 --- a/vcl/inc/vcl/outfont.hxx +++ b/vcl/inc/vcl/outfont.hxx @@ -39,8 +39,6 @@ #include <hash_map> -#include <com/sun/star/linguistic2/XLinguServiceManager.hpp> - class ImplDevFontListData; class ImplGetDevFontList; class ImplGetDevSizeList; @@ -54,6 +52,8 @@ class ConvertChar; struct FontMatchStatus; class OutputDevice; +namespace com { namespace sun { namespace star { namespace lang { struct Locale; }}}} + // ---------------------- // - ImplFontAttributes - // ---------------------- @@ -140,7 +140,7 @@ public: virtual ImplFontData* Clone() const = 0; protected: - ImplFontData( const ImplDevFontAttributes&, int nMagic ); + explicit ImplFontData( const ImplDevFontAttributes&, int nMagic ); void SetBitmapSize( int nW, int nH ) { mnWidth=nW; mnHeight=nH; } long mnWidth; // Width (in pixels) @@ -199,8 +199,8 @@ private: ImplGlyphFallbackFontSubstitution* mpFallbackHook; // device specific glyh fallback substitution public: - ImplDevFontList(); - ~ImplDevFontList(); + explicit ImplDevFontList(); + virtual ~ImplDevFontList(); // fill the list with device fonts void Add( ImplFontData* ); @@ -226,7 +226,7 @@ public: ImplGetDevSizeList* GetDevSizeList( const String& rFontName ) const; //used by 2-level font fallback - ImplDevFontListData* ImplFindByLocale(com::sun::star::lang::Locale lc) const; + ImplDevFontListData* ImplFindByLocale( com::sun::star::lang::Locale& ) const; protected: void InitMatchData() const; @@ -267,7 +267,7 @@ struct ImplKernPairData class ImplFontMetricData : public ImplFontAttributes { public: - ImplFontMetricData( const ImplFontSelectData& ); + explicit ImplFontMetricData( const ImplFontSelectData& ); void ImplInitTextLineSize( const OutputDevice* pDev ); void ImplInitAboveTextLineSize(); @@ -327,7 +327,7 @@ public: // TODO: hide members behind accessor methods class VCL_DLLPUBLIC ImplFontEntry { public: - ImplFontEntry( const ImplFontSelectData& ); + explicit ImplFontEntry( const ImplFontSelectData& ); virtual ~ImplFontEntry(); public: // TODO: make data members private diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx index 419814e5ce97..52e4b5014120 100644 --- a/vcl/inc/vcl/pdfwriter.hxx +++ b/vcl/inc/vcl/pdfwriter.hxx @@ -38,7 +38,8 @@ #include <vcl/font.hxx> #include <vcl/graphictools.hxx> -#include <com/sun/star/io/XOutputStream.hpp> +#include "com/sun/star/io/XOutputStream.hpp" +#include "com/sun/star/beans/XMaterialHolder.hpp" #include <list> #include <vector> @@ -47,6 +48,7 @@ class Font; class Point; class OutputDevice; +class GDIMetaFile; class MapMode; class Polygon; class LineInfo; @@ -61,15 +63,7 @@ class Wallpaper; namespace vcl { -struct PDFDocInfo -{ - String Title; // document title - String Author; // document author - String Subject; // subject - String Keywords; // keywords - String Creator; // application that created the original document - String Producer; // OpenOffice -}; +class PDFExtOutDevData; struct PDFNote { @@ -468,7 +462,7 @@ public: FitVisible, ActionZoom }; -// These emuns are treated as integer while reading/writing to configuration +// These enums are treated as integer while reading/writing to configuration enum PDFPageLayout { DefaultLayout, @@ -489,20 +483,35 @@ public: /* The following structure describes the permissions used in PDF security */ - struct PDFSecPermissions + struct PDFEncryptionProperties { -//for both 40 and 128 bit security, see 3.5.2 PDF v 1.4 table 3.15, v 1.5 and v 1.6 table 3.20. - bool CanPrintTheDocument; + + bool Security128bit; // true to select 128 bit encryption, false for 40 bit + //for both 40 and 128 bit security, see 3.5.2 PDF v 1.4 table 3.15, v 1.5 and v 1.6 table 3.20. + bool CanPrintTheDocument; bool CanModifyTheContent; bool CanCopyOrExtract; bool CanAddOrModify; -//for revision 3 (bit 128 security) only + //for revision 3 (bit 128 security) only bool CanFillInteractive; bool CanExtractForAccessibility; bool CanAssemble; bool CanPrintFull; -//permission default set for 128 bit, accessibility only - PDFSecPermissions() : + + // encryption will only happen if EncryptionKey is not empty + // EncryptionKey is actually a construct out of OValue, UValue and DocumentIdentifier + // if these do not match, behavior is undefined, most likely an invalid PDF will be produced + // OValue, UValue, EncryptionKey and DocumentIdentifier can be computed from + // PDFDocInfo, Owner password and User password used the InitEncryption method which + // implements the algorithms described in the PDF reference chapter 3.5: Encryption + std::vector<sal_uInt8> OValue; + std::vector<sal_uInt8> UValue; + std::vector<sal_uInt8> EncryptionKey; + std::vector<sal_uInt8> DocumentIdentifier; + + //permission default set for 128 bit, accessibility only + PDFEncryptionProperties() : + Security128bit ( true ), CanPrintTheDocument ( false ), CanModifyTheContent ( false ), CanCopyOrExtract ( false ), @@ -512,6 +521,20 @@ The following structure describes the permissions used in PDF security CanAssemble ( false ), CanPrintFull ( false ) {} + + + bool Encrypt() const + { return ! OValue.empty() && ! UValue.empty() && ! DocumentIdentifier.empty(); } + }; + + struct PDFDocInfo + { + String Title; // document title + String Author; // document author + String Subject; // subject + String Keywords; // keywords + String Creator; // application that created the original document + String Producer; // OpenOffice }; struct PDFWriterContext @@ -570,14 +593,12 @@ The following structure describes the permissions used in PDF security sal_Int32 InitialPage; sal_Int32 OpenBookmarkLevels; // -1 means all levels - struct PDFSecPermissions AccessPermissions; - - bool Encrypt; // main encryption flag, must be true to encript - bool Security128bit; // true to select 128 bit encryption, false for 40 bit - rtl::OUString OwnerPassword; // owner password for PDF, in clear text - rtl::OUString UserPassword; // user password for PDF, in clear text + PDFWriter::PDFEncryptionProperties Encryption; + PDFWriter::PDFDocInfo DocumentInfo; com::sun::star::lang::Locale DocumentLocale; // defines the document default language + sal_uInt32 DPIx, DPIy; // how to handle MapMode( MAP_PIXEL ) + // 0 here specifies a default handling PDFWriterContext() : RelFsys( false ), //i56629, i49415?, i64585? @@ -604,13 +625,13 @@ The following structure describes the permissions used in PDF security FirstPageLeft( false ), InitialPage( 1 ), OpenBookmarkLevels( -1 ), - AccessPermissions( ), - Encrypt( false ), - Security128bit( true ) + Encryption(), + DPIx( 0 ), + DPIy( 0 ) {} }; - PDFWriter( const PDFWriterContext& rContext ); + PDFWriter( const PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); ~PDFWriter(); /** Returns an OutputDevice for formatting @@ -635,17 +656,24 @@ The following structure describes the permissions used in PDF security returns the page id of the new page */ sal_Int32 NewPage( sal_Int32 nPageWidth = 0, sal_Int32 nPageHeight = 0, Orientation eOrientation = Inherit ); + /** Play a metafile like an outputdevice would do + */ + struct PlayMetafileContext + { + int m_nMaxImageResolution; + bool m_bOnlyLosslessCompression; + int m_nJPEGQuality; + bool m_bTransparenciesWereRemoved; + + PlayMetafileContext() + : m_nMaxImageResolution( 0 ) + , m_bOnlyLosslessCompression( false ) + , m_nJPEGQuality( 90 ) + , m_bTransparenciesWereRemoved( false ) + {} - /* - * set document info; due to the use of document information in building the PDF document ID, must be called before - * emitting anything. - */ - void SetDocInfo( const PDFDocInfo& rInfo ); - - /* - * get currently set document info - */ - const PDFDocInfo& GetDocInfo() const; + }; + void PlayMetafile( const GDIMetaFile&, const PlayMetafileContext&, vcl::PDFExtOutDevData* pDevDat = NULL ); /* sets the document locale originally passed with the context to a new value * only affects the output if used before calling <code>Emit/code>. @@ -664,6 +692,12 @@ The following structure describes the permissions used in PDF security PDFVersion GetVersion() const; + static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > + InitEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ); + /* functions for graphics state */ /* flag values: see vcl/outdev.hxx */ void Push( USHORT nFlags = 0xffff ); diff --git a/vcl/inc/vcl/print.hxx b/vcl/inc/vcl/print.hxx index 96822d9bc756..40d88ca373db 100644 --- a/vcl/inc/vcl/print.hxx +++ b/vcl/inc/vcl/print.hxx @@ -208,6 +208,11 @@ public: BOOL IsConvertToGreyscales() const { return mbConvertToGreyscales; } void SetConvertToGreyscales( BOOL bSet ) { mbConvertToGreyscales = bSet; } + + // read printer options from configuration, parameter decides whether the set for + // print "to printer" or "to file" should be read. + // returns true if config was read, false if an error occured + bool ReadFromConfig( bool bFile ); }; // ----------- @@ -313,7 +318,12 @@ public: BOOL Setup( Window* pWindow = NULL ); BOOL SetPrinterProps( const Printer* pPrinter ); - void SetPrinterOptions( const PrinterOptions& rOptions ) { *mpPrinterOptions = rOptions; } + // SetPrinterOptions is used internally only now + // in earlier times it was used only to set the options loaded directly from the configuration + // in SfxPrinter::InitJob, this is now handled internally + // should the need arise to set the printer options outside vcl, also a method would have to be devised + // to not override these again internally + SAL_DLLPRIVATE void SetPrinterOptions( const PrinterOptions& rOptions ); const PrinterOptions& GetPrinterOptions() const { return( *mpPrinterOptions ); } BOOL SetOrientation( Orientation eOrient ); @@ -349,10 +359,6 @@ public: BOOL IsPrinting() const { return mbPrinting; } - void SetPrintFile( const XubString& rFileName ) { maPrintFile = rFileName; } - const XubString& GetPrintFile() const { return maPrintFile; } - void EnablePrintFile( BOOL bEnable ) { mbPrintFile = bEnable; } - BOOL IsPrintFileEnabled() const { return mbPrintFile; } BOOL AbortJob(); const XubString& GetCurJobName() const { return maJobName; } USHORT GetCurPage() const { return mnCurPage; } @@ -400,7 +406,7 @@ protected: PrinterController( const boost::shared_ptr<Printer>& ); public: enum NupOrderType - { LRTB, TBLR }; + { LRTB, TBLR, TBRL, RLTB }; struct MultiPageSetup { // all metrics in 100th mm @@ -478,6 +484,7 @@ public: */ void enableUIOption( const rtl::OUString& rPropName, bool bEnable ); bool isUIOptionEnabled( const rtl::OUString& rPropName ) const; + bool isUIChoiceEnabled( const rtl::OUString& rPropName, sal_Int32 nChoice ) const; /* returns the property name rPropName depends on or an empty string if no dependency exists. */ @@ -513,26 +520,31 @@ public: bool isDirectPrint() const; // implementation details, not usable outside vcl - SAL_DLLPRIVATE int getFilteredPageCount(); + // don't use outside vcl. Some of these ar exported for + // the benefit of vcl's plugins. + // Still: DO NOT USE OUTSIDE VCL + int getFilteredPageCount(); SAL_DLLPRIVATE PageSize getPageFile( int i_inUnfilteredPage, GDIMetaFile& rMtf, bool i_bMayUseCache = false ); - SAL_DLLPRIVATE PageSize getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache = false ); + PageSize getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache = false ); SAL_DLLPRIVATE void printFilteredPage( int i_nPage ); SAL_DLLPRIVATE void setPrinter( const boost::shared_ptr<Printer>& ); SAL_DLLPRIVATE void setOptionChangeHdl( const Link& ); - SAL_DLLPRIVATE void createProgressDialog(); + void createProgressDialog(); + bool isProgressCanceled() const; SAL_DLLPRIVATE void setMultipage( const MultiPageSetup& ); SAL_DLLPRIVATE const MultiPageSetup& getMultipage() const; - SAL_DLLPRIVATE void setLastPage( sal_Bool i_bLastPage ); + void setLastPage( sal_Bool i_bLastPage ); SAL_DLLPRIVATE void setReversePrint( sal_Bool i_bReverse ); SAL_DLLPRIVATE bool getReversePrint() const; SAL_DLLPRIVATE void pushPropertiesToPrinter(); - SAL_DLLPRIVATE void setJobState( com::sun::star::view::PrintableState ); + void setJobState( com::sun::star::view::PrintableState ); SAL_DLLPRIVATE bool setupPrinter( Window* i_pDlgParent ); SAL_DLLPRIVATE int getPageCountProtected() const; SAL_DLLPRIVATE com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getPageParametersProtected( int i_nPage ) const; SAL_DLLPRIVATE ULONG removeTransparencies( GDIMetaFile& i_rIn, GDIMetaFile& o_rOut ); + SAL_DLLPRIVATE void resetPrinterOptions( bool i_bFileOutput ); }; class VCL_DLLPUBLIC PrinterOptionsHelper @@ -615,28 +627,34 @@ class VCL_DLLPUBLIC PrinterOptionsHelper , mbEnabled( i_bEnabled ) {} }; + // note: in the following helper functions HelpIds are expected as an rtl::OUString + // the normal HelpId form is rtl::OString (byte string instead of UTF16 string) + // this is because the whole interface is base on UNO properties; in fact the structures + // are passed over UNO interfaces. UNO does not know a byte string, hence the string is + // transported via UTF16 strings. + // general control static com::sun::star::uno::Any getUIControlOpt( const rtl::OUString& i_rTitle, - const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpText, + const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpId, const rtl::OUString& i_rType, const com::sun::star::beans::PropertyValue* i_pValue = NULL, const UIControlOptions& i_rControlOptions = UIControlOptions() ); // create a group (e.g. a TabPage); following controls will be grouped in it until the next // group begins - static com::sun::star::uno::Any getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpText ); + static com::sun::star::uno::Any getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpId ); // create a subgroup (e.g. a FixedLine); following controls will be grouped in it until the next // subgroup or group begins // setting bJobPage = true will make the subgroup appear on the first page of the print dialog static com::sun::star::uno::Any getSubgroupControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const UIControlOptions& i_rControlOptions = UIControlOptions() ); // create a bool option (usually a checkbox) static com::sun::star::uno::Any getBoolControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, sal_Bool i_bValue, const UIControlOptions& i_rControlOptions = UIControlOptions() @@ -644,18 +662,19 @@ class VCL_DLLPUBLIC PrinterOptionsHelper // create a set of choices (either a radio button group or a list box) static com::sun::star::uno::Any getChoiceControlOpt( const rtl::OUString& i_rTitle, - const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpText, + const com::sun::star::uno::Sequence< rtl::OUString >& i_rHelpId, const rtl::OUString& i_rProperty, const com::sun::star::uno::Sequence< rtl::OUString >& i_rChoices, sal_Int32 i_nValue, const rtl::OUString& i_rType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Radio" ) ), + const com::sun::star::uno::Sequence< sal_Bool >& i_rDisabledChoices = com::sun::star::uno::Sequence< sal_Bool >(), const UIControlOptions& i_rControlOptions = UIControlOptions() ); // create an integer range (e.g. a spin field) // note: max value < min value means do not apply min/max values static com::sun::star::uno::Any getRangeControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, sal_Int32 i_nValue, sal_Int32 i_nMinValue = -1, @@ -666,7 +685,7 @@ class VCL_DLLPUBLIC PrinterOptionsHelper // create a string field // note: max value < min value means do not apply min/max values static com::sun::star::uno::Any getEditControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, const rtl::OUString& i_rValue, const UIControlOptions& i_rControlOptions = UIControlOptions() diff --git a/vcl/inc/vcl/printerinfomanager.hxx b/vcl/inc/vcl/printerinfomanager.hxx index f2e0aad538c8..5e94ed919a4e 100644 --- a/vcl/inc/vcl/printerinfomanager.hxx +++ b/vcl/inc/vcl/printerinfomanager.hxx @@ -157,6 +157,8 @@ public: // there can only be one static PrinterInfoManager& get(); + // only called by SalData destructor, frees the global instance + static void release(); // get PrinterInfoManager type Type getType() const { return m_eType; } @@ -217,8 +219,10 @@ public: // this may either be a regular file or the result of popen() virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand ); // close the FILE* returned by startSpool and does the actual spooling + // set bBanner to "false" will attempt to suppress banner printing + // set bBanner to "true" will rely on the system default // returns a numerical job id - virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ); + virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ); // for spadmin: whether adding or removing a printer is possible virtual bool addOrRemovePossible() const; diff --git a/vcl/inc/vcl/prndlg.hxx b/vcl/inc/vcl/prndlg.hxx index fdaf06c9854e..d21e517d12f7 100644 --- a/vcl/inc/vcl/prndlg.hxx +++ b/vcl/inc/vcl/prndlg.hxx @@ -59,6 +59,9 @@ namespace vcl VirtualDevice maPageVDev; rtl::OUString maReplacementString; rtl::OUString maToolTipString; + bool mbGreyscale; + FixedLine maHorzDim; + FixedLine maVertDim; bool useHCColorReplacement() const; public: @@ -71,7 +74,8 @@ namespace vcl virtual void DataChanged( const DataChangedEvent& ); void setPreview( const GDIMetaFile&, const Size&, const rtl::OUString&, - sal_Int32 i_nDPIX, sal_Int32 i_nDPIY + sal_Int32 i_nDPIX, sal_Int32 i_nDPIY, + bool i_bGreyscale ); }; @@ -126,7 +130,6 @@ namespace vcl // border around each page CheckBox maBorderCB; - vcl::RowOrColumn maLayout; boost::shared_ptr< vcl::RowOrColumn > mxBrochureDep; boost::shared_ptr< vcl::LabeledElement >mxPagesBtnLabel; @@ -142,7 +145,7 @@ namespace vcl void showAdvancedControls( bool ); - virtual void Resize(); + // virtual void Resize(); }; class JobTabPage : public TabPage @@ -174,7 +177,6 @@ namespace vcl long mnCollateUIMode; - vcl::RowOrColumn maLayout; boost::shared_ptr<vcl::RowOrColumn> mxPrintRange; boost::shared_ptr<vcl::WindowArranger> mxDetails; @@ -184,7 +186,7 @@ namespace vcl void readFromSettings(); void storeToSettings(); - virtual void Resize(); + // virtual void Resize(); void setupLayout(); }; @@ -197,7 +199,6 @@ namespace vcl CheckBox maCollateSingleJobsBox; CheckBox maReverseOrderBox; - vcl::RowOrColumn maLayout; boost::shared_ptr<vcl::RowOrColumn> mxOptGroup; OutputOptPage( Window*, const ResId& ); @@ -206,7 +207,7 @@ namespace vcl void readFromSettings(); void storeToSettings(); - virtual void Resize(); + // virtual void Resize(); void setupLayout(); }; @@ -251,7 +252,6 @@ namespace vcl rtl::OUString maPrintText; rtl::OUString maDefPrtText; - vcl::RowOrColumn maLayout; boost::shared_ptr<vcl::RowOrColumn> mxPreviewCtrls; Size maDetailsCollapsedSize; diff --git a/vcl/inc/vcl/prntypes.hxx b/vcl/inc/vcl/prntypes.hxx index 6b2af991f2dd..244154360f3b 100644 --- a/vcl/inc/vcl/prntypes.hxx +++ b/vcl/inc/vcl/prntypes.hxx @@ -91,5 +91,6 @@ enum Orientation { ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE }; #define PRINTER_CAPABILITIES_PDF ((USHORT)9) #define PRINTER_CAPABILITIES_EXTERNALDIALOG ((USHORT)10) #define PRINTER_CAPABILITIES_SETDUPLEX ((USHORT)11) +#define PRINTER_CAPABILITIES_USEPULLMODEL ((USHORT)12) #endif // _SV_PRNTYPES_HXX diff --git a/vcl/inc/vcl/quickselectionengine.hxx b/vcl/inc/vcl/quickselectionengine.hxx new file mode 100644 index 000000000000..f70736428010 --- /dev/null +++ b/vcl/inc/vcl/quickselectionengine.hxx @@ -0,0 +1,95 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* 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 VCL_QUICKSELECTIONENGINE_HXX +#define VCL_QUICKSELECTIONENGINE_HXX + +#include "dllapi.h" + +#include <tools/string.hxx> + +#include <memory> + +class KeyEvent; + +//........................................................................ +namespace vcl +{ +//........................................................................ + + typedef const void* StringEntryIdentifier; + + //==================================================================== + //= ISearchableStringList + //==================================================================== + // TODO: consolidate this with ::vcl::IMnemonicEntryList + class SAL_NO_VTABLE VCL_DLLPUBLIC ISearchableStringList + { + public: + /** returns the current entry in the list of searchable strings. + + Search operations will start with this entry. + */ + virtual StringEntryIdentifier CurrentEntry( String& _out_entryText ) const = 0; + + /** returns the next entry in the list. + + The implementation is expected to wrap around. That is, if the given entry denotes the last + entry in the list, then NextEntry should return the first entry. + */ + virtual StringEntryIdentifier NextEntry( StringEntryIdentifier _currentEntry, String& _out_entryText ) const = 0; + + /** selects a given entry + */ + virtual void SelectEntry( StringEntryIdentifier _entry ) = 0; + }; + + //==================================================================== + //= QuickSelectionEngine + //==================================================================== + struct QuickSelectionEngine_Data; + class VCL_DLLPUBLIC QuickSelectionEngine + { + public: + QuickSelectionEngine( ISearchableStringList& _entryList ); + ~QuickSelectionEngine(); + + bool HandleKeyEvent( const KeyEvent& _rKEvt ); + void Reset(); + + private: + ::std::auto_ptr< QuickSelectionEngine_Data > m_pData; + + private: + QuickSelectionEngine(); // never implemented + QuickSelectionEngine( const QuickSelectionEngine& ); // never implemented + QuickSelectionEngine& operator=( const QuickSelectionEngine& ); // never implemented + }; + +//........................................................................ +} // namespace vcl +//........................................................................ + +#endif // VCL_QUICKSELECTIONENGINE_HXX diff --git a/vcl/inc/vcl/salatype.hxx b/vcl/inc/vcl/salatype.hxx deleted file mode 100644 index d9e25c0cada9..000000000000 --- a/vcl/inc/vcl/salatype.hxx +++ /dev/null @@ -1,47 +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 _SV_SALATYPE_HXX -#define _SV_SALATYPE_HXX - -#include <vcl/sv.h> - -// --------------------- -// - Application-Types - -// --------------------- - -// Derzeit doppelt und in apptypes.hxx auch vorhanden - -#define INPUT_MOUSE 0x0001 -#define INPUT_KEYBOARD 0x0002 -#define INPUT_PAINT 0x0004 -#define INPUT_TIMER 0x0008 -#define INPUT_OTHER 0x0010 -#define INPUT_MOUSEANDKEYBOARD (INPUT_MOUSE | INPUT_KEYBOARD) -#define INPUT_ANY (INPUT_MOUSEANDKEYBOARD | INPUT_PAINT | INPUT_TIMER | INPUT_OTHER) - -#endif // _SV_SALATYPE_HXX diff --git a/vcl/inc/vcl/salctrlhandle.hxx b/vcl/inc/vcl/salctrlhandle.hxx deleted file mode 100644 index 4a0a3a0f5b0a..000000000000 --- a/vcl/inc/vcl/salctrlhandle.hxx +++ /dev/null @@ -1,48 +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 _SV_SALCTRLHANDLE_HXX -#define _SV_SALCTRLHANDLE_HXX - -/* SalControlHandle: - * - * Container for platform-specific handles and data - * about controls. Lives as long as the VCL control - * lives. - */ - -class SalControlHandle -{ - public: - SalControlHandle() {} - virtual ~SalControlHandle(); - - // TODO: derive Sal implementation - //SalControlHandleData maData; -}; - -#endif diff --git a/vcl/inc/vcl/salctype.hxx b/vcl/inc/vcl/salctype.hxx index 1566f02a1299..0cb037ad40e1 100644 --- a/vcl/inc/vcl/salctype.hxx +++ b/vcl/inc/vcl/salctype.hxx @@ -28,6 +28,9 @@ #ifndef _SV_SALCTYPE_HXX #define _SV_SALCTYPE_HXX +#include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/uno/Reference.hxx> + #include <vcl/graph.hxx> // ----------- @@ -77,4 +80,13 @@ typedef ULONG (*SALGRFCVTPROC)( void* pInst, ULONG nInFormat, void* pInBuffer, ULONG nInBufSize, ULONG nOutFormat, void** ppOutBuffer ); +// ------------------- +// - BitmapConverter - +// ------------------- + +namespace vcl +{ +com::sun::star::uno::Reference< com::sun::star::script::XInvocation > createBmpConverter(); +} + #endif // _SV_SALCTYPE_HXX diff --git a/vcl/inc/vcl/saldatabasic.hxx b/vcl/inc/vcl/saldatabasic.hxx index 1df2a701fd1a..a40cd045611c 100644 --- a/vcl/inc/vcl/saldatabasic.hxx +++ b/vcl/inc/vcl/saldatabasic.hxx @@ -32,11 +32,17 @@ #include <vcl/salinst.hxx> #include <osl/module.h> +namespace psp +{ + class PrinterInfoManager; +} + class VCL_DLLPUBLIC SalData { public: - SalInstance* m_pInstance; // pointer to instance - oslModule m_pPlugin; // plugin library handle + SalInstance* m_pInstance; // pointer to instance + oslModule m_pPlugin; // plugin library handle + psp::PrinterInfoManager* m_pPIManager; SalData(); virtual ~SalData(); diff --git a/vcl/inc/vcl/salframe.hxx b/vcl/inc/vcl/salframe.hxx index 08548d7dda40..d82a2099f315 100644 --- a/vcl/inc/vcl/salframe.hxx +++ b/vcl/inc/vcl/salframe.hxx @@ -270,7 +270,6 @@ public: // done setting up the clipregion virtual void EndSetClipRegion() = 0; - // Callbacks (indepent part in vcl/source/window/winproc.cxx) // for default message handling return 0 void SetCallback( Window* pWindow, SALFRAMEPROC pProc ) diff --git a/vcl/inc/vcl/salgdi.hxx b/vcl/inc/vcl/salgdi.hxx index 510e797678b0..b4769c045708 100644 --- a/vcl/inc/vcl/salgdi.hxx +++ b/vcl/inc/vcl/salgdi.hxx @@ -36,7 +36,6 @@ #include "vos/thread.hxx" #include "vcl/outdev.hxx" #include "vcl/salnativewidgets.hxx" -#include "vcl/salctrlhandle.hxx" #include <map> @@ -125,7 +124,7 @@ protected: virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) = 0; virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) = 0; virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) = 0; - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ) = 0; + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ) = 0; virtual sal_Bool drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ) = 0; virtual sal_Bool drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ) = 0; virtual sal_Bool drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry ) = 0; @@ -158,17 +157,17 @@ protected: virtual BOOL drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ) = 0; // native widget rendering methods that require mirroring - virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); - virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, + virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); /** Render bitmap with alpha channel @@ -233,13 +232,13 @@ public: // release the fonts void ReleaseFonts() { SetFont( NULL, 0 ); } // get the current font's metrics - virtual void GetFontMetric( ImplFontMetricData* ) = 0; + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel = 0 ) = 0; // get kernign pairs of the current font // return only PairCount if (pKernPairs == NULL) virtual ULONG GetKernPairs( ULONG nMaxPairCount, ImplKernPairData* ) = 0; // get the repertoire of the current font - virtual ImplFontCharMap* GetImplFontCharMap() const = 0; + virtual const ImplFontCharMap* GetImplFontCharMap() const = 0; // graphics must fill supplied font list virtual void GetDevFontList( ImplDevFontList* ) = 0; // graphics should call ImplAddDevFontSubstitute on supplied @@ -373,7 +372,7 @@ public: PCONSTSALPOINT* pPtAry, const OutputDevice *pOutDev ); bool DrawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency, const OutputDevice* ); - bool DrawPolyLine( const basegfx::B2DPolygon&, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, const OutputDevice* ); + bool DrawPolyLine( const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, const OutputDevice* ); sal_Bool DrawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry, @@ -440,7 +439,7 @@ public: // Query the native control to determine if it was acted upon BOOL HitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside, const OutputDevice *pOutDev ); @@ -448,7 +447,7 @@ public: // Request rendering of a particular control and/or part BOOL DrawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, @@ -457,7 +456,7 @@ public: // Request rendering of a caption string for a control BOOL DrawNativeControlText( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, @@ -466,12 +465,12 @@ public: // Query the native control's actual drawing region (including adornment) BOOL GetNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion, + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion, const OutputDevice *pOutDev ); static void AddDevFontSubstitute( OutputDevice* pOutDev, diff --git a/vcl/inc/vcl/salinst.hxx b/vcl/inc/vcl/salinst.hxx index 9b92bf95e3fe..71b820803473 100644 --- a/vcl/inc/vcl/salinst.hxx +++ b/vcl/inc/vcl/salinst.hxx @@ -60,6 +60,7 @@ struct SalItemParams; class SalSession; struct SystemGraphicsData; struct SystemWindowData; +class Menu; namespace vos { class IMutex; } @@ -133,6 +134,8 @@ public: virtual vos::IMutex* GetYieldMutex() = 0; virtual ULONG ReleaseYieldMutex() = 0; virtual void AcquireYieldMutex( ULONG nCount ) = 0; + // return true, if yield mutex is owned by this thread, else false + virtual bool CheckYieldMutex() = 0; // wait next event and dispatch // must returned by UserEvent (SalFrame::PostEvent) @@ -141,10 +144,10 @@ public: virtual bool AnyInput( USHORT nType ) = 0; // Menues - virtual SalMenu* CreateMenu( BOOL bMenuBar ) = 0; - virtual void DestroyMenu( SalMenu* pMenu) = 0; - virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ) = 0; - virtual void DestroyMenuItem( SalMenuItem* pItem ) = 0; + virtual SalMenu* CreateMenu( BOOL bMenuBar, Menu* pMenu ); + virtual void DestroyMenu( SalMenu* pMenu); + virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); + virtual void DestroyMenuItem( SalMenuItem* pItem ); // may return NULL to disable session management virtual SalSession* CreateSalSession() = 0; diff --git a/vcl/inc/vcl/salnativewidgets.hxx b/vcl/inc/vcl/salnativewidgets.hxx index 8e98791d9f78..621cf0e90c5a 100644..100755 --- a/vcl/inc/vcl/salnativewidgets.hxx +++ b/vcl/inc/vcl/salnativewidgets.hxx @@ -41,6 +41,9 @@ typedef sal_uInt32 ControlType; +// for use in general purpose ImplControlValue +#define CTRL_GENERIC 0 + // Normal PushButton/Command Button #define CTRL_PUSHBUTTON 1 @@ -172,6 +175,7 @@ typedef sal_uInt32 ControlPart; #define PART_MENU_ITEM 250 #define PART_MENU_ITEM_CHECK_MARK 251 #define PART_MENU_ITEM_RADIO_MARK 252 +#define PART_MENU_SEPARATOR 253 /* #i77549# HACK: for scrollbars in case of thumb rect, page up and page down rect we @@ -260,13 +264,50 @@ enum ButtonValue { BUTTONVALUE_MIXED }; -#ifdef __cplusplus +/* ImplControlValue: + * + * Generic value container for all control parts. + */ + +class VCL_DLLPUBLIC ImplControlValue +{ + friend class SalFrame; + + private: + ControlType mType; + ButtonValue mTristate; // Tristate value: on, off, mixed + long mNumber; // numeric value + protected: + ImplControlValue( ControlType i_eType, ButtonValue i_eTriState, long i_nNumber ) + : mType( i_eType ) + , mTristate( i_eTriState ) + , mNumber( i_nNumber ) + {} + + public: + explicit ImplControlValue( ButtonValue nTristate ) + : mType( CTRL_GENERIC ), mTristate(nTristate), mNumber(0) {} + explicit ImplControlValue( long nNumeric ) + : mType( CTRL_GENERIC ), mTristate(BUTTONVALUE_DONTKNOW), mNumber( nNumeric) {} + inline ImplControlValue() + : mType( CTRL_GENERIC ), mTristate(BUTTONVALUE_DONTKNOW), mNumber(0) {} + + virtual ~ImplControlValue(); + + ControlType getType() const { return mType; } + + inline ButtonValue getTristateVal( void ) const { return mTristate; } + inline void setTristateVal( ButtonValue nTristate ) { mTristate = nTristate; } + + inline long getNumericVal( void ) const { return mNumber; } + inline void setNumericVal( long nNumeric ) { mNumber = nNumeric; } +}; /* ScrollbarValue: * * Value container for scrollbars. */ -class VCL_DLLPUBLIC ScrollbarValue + class VCL_DLLPUBLIC ScrollbarValue : public ImplControlValue { public: long mnMin; @@ -283,15 +324,16 @@ class VCL_DLLPUBLIC ScrollbarValue ControlState mnPage2State; inline ScrollbarValue() - { - mnMin = 0; mnMax = 0; mnCur = 0; mnVisibleSize = 0; - mnButton1State = 0; mnButton2State = 0; - mnThumbState = 0; mnPage1State = 0; mnPage2State = 0; - }; - inline ~ScrollbarValue() {}; + : ImplControlValue( CTRL_SCROLLBAR, BUTTONVALUE_DONTKNOW, 0 ) + { + mnMin = 0; mnMax = 0; mnCur = 0; mnVisibleSize = 0; + mnButton1State = 0; mnButton2State = 0; + mnThumbState = 0; mnPage1State = 0; mnPage2State = 0; + }; + virtual ~ScrollbarValue(); }; -class VCL_DLLPUBLIC SliderValue +class VCL_DLLPUBLIC SliderValue : public ImplControlValue { public: long mnMin; @@ -300,9 +342,11 @@ class VCL_DLLPUBLIC SliderValue Rectangle maThumbRect; ControlState mnThumbState; - SliderValue() : mnMin( 0 ), mnMax( 0 ), mnCur( 0 ), mnThumbState( 0 ) + SliderValue() + : ImplControlValue( CTRL_SLIDER, BUTTONVALUE_DONTKNOW, 0 ) + , mnMin( 0 ), mnMax( 0 ), mnCur( 0 ), mnThumbState( 0 ) {} - ~SliderValue() {} + virtual ~SliderValue(); }; /* TabitemValue: @@ -317,23 +361,24 @@ class VCL_DLLPUBLIC SliderValue #define TABITEM_FIRST_IN_GROUP 0x004 // the tabitem is the first in group of tabitems #define TABITEM_LAST_IN_GROUP 0x008 // the tabitem is the last in group of tabitems -class VCL_DLLPUBLIC TabitemValue +class VCL_DLLPUBLIC TabitemValue : public ImplControlValue { public: unsigned int mnAlignment; inline TabitemValue() - { - mnAlignment = 0; - }; - inline ~TabitemValue() {}; - - BOOL isLeftAligned() { return (mnAlignment & TABITEM_LEFTALIGNED) != 0; } - BOOL isRightAligned() { return (mnAlignment & TABITEM_RIGHTALIGNED) != 0; } - BOOL isBothAligned() { return isLeftAligned() && isRightAligned(); } - BOOL isNotAligned() { return (mnAlignment & (TABITEM_LEFTALIGNED | TABITEM_RIGHTALIGNED)) == 0; } - BOOL isFirst() { return (mnAlignment & TABITEM_FIRST_IN_GROUP) != 0; } - BOOL isLast() { return (mnAlignment & TABITEM_LAST_IN_GROUP) != 0; } + : ImplControlValue( CTRL_TAB_ITEM, BUTTONVALUE_DONTKNOW, 0 ) + { + mnAlignment = 0; + }; + virtual ~TabitemValue(); + + BOOL isLeftAligned() const { return (mnAlignment & TABITEM_LEFTALIGNED) != 0; } + BOOL isRightAligned() const { return (mnAlignment & TABITEM_RIGHTALIGNED) != 0; } + BOOL isBothAligned() const { return isLeftAligned() && isRightAligned(); } + BOOL isNotAligned() const { return (mnAlignment & (TABITEM_LEFTALIGNED | TABITEM_RIGHTALIGNED)) == 0; } + BOOL isFirst() const { return (mnAlignment & TABITEM_FIRST_IN_GROUP) != 0; } + BOOL isLast() const { return (mnAlignment & TABITEM_LAST_IN_GROUP) != 0; } }; /* SpinbuttonValue: @@ -342,7 +387,7 @@ class VCL_DLLPUBLIC TabitemValue * Note: the other parameters of DrawNativeControl will have no meaning * all parameters for spinbuttons are carried here */ -class VCL_DLLPUBLIC SpinbuttonValue +class VCL_DLLPUBLIC SpinbuttonValue : public ImplControlValue { public: Rectangle maUpperRect; @@ -353,20 +398,23 @@ class VCL_DLLPUBLIC SpinbuttonValue int mnLowerPart; inline SpinbuttonValue() - { - mnUpperState = mnLowerState = 0; - }; - inline ~SpinbuttonValue() {}; + : ImplControlValue( CTRL_SPINBUTTONS, BUTTONVALUE_DONTKNOW, 0 ) + { + mnUpperState = mnLowerState = 0; + }; + virtual ~SpinbuttonValue(); }; /* Toolbarvalue: * * Value container for toolbars detailing the grip position */ -class ToolbarValue +class ToolbarValue : public ImplControlValue { public: - ToolbarValue() { mbIsTopDockingArea = FALSE; } + ToolbarValue() : ImplControlValue( CTRL_TOOLBAR, BUTTONVALUE_DONTKNOW, 0 ) + { mbIsTopDockingArea = FALSE; } + virtual ~ToolbarValue(); Rectangle maGripRect; BOOL mbIsTopDockingArea; // indicates that this is the top aligned dockingarea // adjacent to the menubar @@ -376,72 +424,49 @@ public: * * Value container for menubars specifying height of adjacent docking area */ -class MenubarValue +class MenubarValue : public ImplControlValue { public: - MenubarValue() { maTopDockingAreaHeight=0; } + MenubarValue() : ImplControlValue( CTRL_MENUBAR, BUTTONVALUE_DONTKNOW, 0 ) + { maTopDockingAreaHeight=0; } + virtual ~MenubarValue(); int maTopDockingAreaHeight; }; -/* PushButtonValue: +/* MenupopupValue: * - * Value container for pushbuttons specifying additional drawing hints + * Value container for menu items; specifies the rectangle for the whole item which + * may be useful when drawing parts with a smaller rectangle. */ -class PushButtonValue +class MenupopupValue : public ImplControlValue { public: -PushButtonValue() : mbBevelButton( false ), mbSingleLine( true ) {} - bool mbBevelButton:1; - bool mbSingleLine:1; + MenupopupValue() : ImplControlValue( CTRL_MENU_POPUP, BUTTONVALUE_DONTKNOW, 0 ) + {} + MenupopupValue( long i_nGutterWidth, const Rectangle& i_rItemRect ) + : ImplControlValue( CTRL_MENU_POPUP, BUTTONVALUE_DONTKNOW, i_nGutterWidth ) + , maItemRect( i_rItemRect ) + {} + virtual ~MenupopupValue(); + Rectangle maItemRect; }; -/* ImplControlValue: +/* PushButtonValue: * - * Generic value container for all control parts. + * Value container for pushbuttons specifying additional drawing hints */ - -class ImplControlValue +class PushButtonValue : public ImplControlValue { - friend class SalFrame; - - private: - ButtonValue mTristate; // Tristate value: on, off, mixed - rtl::OUString mString; // string value - long mNumber; // numeric value - void * mOptionalVal; // optional control-specific value - - public: - inline ImplControlValue( ButtonValue nTristate, rtl::OUString sString, long nNumeric, void * aOptVal ) \ - { mTristate = nTristate; mString = sString; mNumber = nNumeric; mOptionalVal = aOptVal; }; - inline ImplControlValue( ButtonValue nTristate, rtl::OUString sString, long nNumeric ) \ - { mTristate = nTristate; mString = sString; mNumber = nNumeric; mOptionalVal = NULL; }; - explicit ImplControlValue( ButtonValue nTristate ) - : mTristate(nTristate), mNumber(0), mOptionalVal(NULL) {} - explicit ImplControlValue( rtl::OUString& rString ) - : mTristate(BUTTONVALUE_DONTKNOW), mString(rString), mNumber(0), mOptionalVal(NULL) {} - explicit ImplControlValue( long nNumeric ) - : mTristate(BUTTONVALUE_DONTKNOW), mNumber( nNumeric), mOptionalVal(NULL) {} - explicit ImplControlValue( void* aOptVal ) - : mTristate(BUTTONVALUE_DONTKNOW), mNumber(0), mOptionalVal(aOptVal) {} - inline ImplControlValue() - : mTristate(BUTTONVALUE_DONTKNOW), mNumber(0), mOptionalVal(NULL) {} - - inline ~ImplControlValue() { mOptionalVal = NULL; }; - - inline ButtonValue getTristateVal( void ) const { return mTristate; } - inline void setTristateVal( ButtonValue nTristate ) { mTristate = nTristate; } - - inline const rtl::OUString& getStringVal( void ) const { return mString; } - inline void setStringVal( rtl::OUString sString ) { mString = sString; } - - inline long getNumericVal( void ) const { return mNumber; } - inline void setNumericVal( long nNumeric ) { mNumber = nNumeric; } +public: + PushButtonValue() + : ImplControlValue( CTRL_PUSHBUTTON, BUTTONVALUE_DONTKNOW, 0 ) + , mbBevelButton( false ), mbSingleLine( true ) {} + virtual ~PushButtonValue(); - inline void * getOptionalVal( void ) const { return mOptionalVal; } - inline void setOptionalVal( void * aOptVal ) { mOptionalVal = aOptVal; } + bool mbBevelButton:1; + bool mbSingleLine:1; }; -#endif /* __cplusplus */ #endif diff --git a/vcl/inc/vcl/salobj.hxx b/vcl/inc/vcl/salobj.hxx index e453bf5c6f87..adf0e0a3d45d 100644 --- a/vcl/inc/vcl/salobj.hxx +++ b/vcl/inc/vcl/salobj.hxx @@ -73,6 +73,8 @@ public: virtual const SystemEnvData* GetSystemData() const = 0; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ) = 0; + void SetCallback( void* pInst, SALOBJECTPROC pProc ) { m_pInst = pInst; m_pCallback = pProc; } long CallCallback( USHORT nEvent, const void* pEvent ) diff --git a/vcl/inc/vcl/settings.hxx b/vcl/inc/vcl/settings.hxx index 24fd30750501..cc5cbcbc4d0f 100644 --- a/vcl/inc/vcl/settings.hxx +++ b/vcl/inc/vcl/settings.hxx @@ -423,10 +423,6 @@ private: ULONG mnOptions; USHORT mnScreenZoom; USHORT mnScreenFontZoom; - USHORT mnRadioButtonStyle; - USHORT mnCheckBoxStyle; - USHORT mnPushButtonStyle; - USHORT mnTabControlStyle; USHORT mnHighContrast; USHORT mnUseSystemUIFonts; USHORT mnAutoMnemonic; @@ -457,11 +453,6 @@ private: #define STYLE_OPTION_SPINARROW ((ULONG)0x00000080) #define STYLE_OPTION_SPINUPDOWN ((ULONG)0x00000100) #define STYLE_OPTION_NOMNEMONICS ((ULONG)0x00000200) -#define STYLE_OPTION_WINSTYLE ((ULONG)0x00010000) -#define STYLE_OPTION_OS2STYLE ((ULONG)0x00020000) -#define STYLE_OPTION_MACSTYLE ((ULONG)0x00040000) -#define STYLE_OPTION_UNIXSTYLE ((ULONG)0x00080000) -#define STYLE_OPTION_SYSTEMSTYLE ((ULONG)0x000F0000) #define STYLE_OPTION_HIDEDISABLED ((ULONG)0x00100000) #define DRAGFULL_OPTION_WINDOWMOVE ((ULONG)0x00000001) @@ -488,28 +479,8 @@ private: #define DISPLAY_OPTION_AA_DISABLE ((ULONG)0x00000001) -#define STYLE_RADIOBUTTON_WIN ((USHORT)0x0001) -#define STYLE_RADIOBUTTON_OS2 ((USHORT)0x0002) -#define STYLE_RADIOBUTTON_MAC ((USHORT)0x0003) -#define STYLE_RADIOBUTTON_UNIX ((USHORT)0x0004) -#define STYLE_RADIOBUTTON_MONO ((USHORT)0x0005) -#define STYLE_RADIOBUTTON_STYLE ((USHORT)0x000F) - -#define STYLE_CHECKBOX_WIN ((USHORT)0x0001) -#define STYLE_CHECKBOX_OS2 ((USHORT)0x0002) -#define STYLE_CHECKBOX_MAC ((USHORT)0x0003) -#define STYLE_CHECKBOX_UNIX ((USHORT)0x0004) -#define STYLE_CHECKBOX_MONO ((USHORT)0x0005) -#define STYLE_CHECKBOX_STYLE ((USHORT)0x000F) - -#define STYLE_PUSHBUTTON_WIN ((USHORT)0x0001) -#define STYLE_PUSHBUTTON_OS2 ((USHORT)0x0002) -#define STYLE_PUSHBUTTON_MAC ((USHORT)0x0003) -#define STYLE_PUSHBUTTON_UNIX ((USHORT)0x0004) -#define STYLE_PUSHBUTTON_STYLE ((USHORT)0x000F) - -#define STYLE_TABCONTROL_SINGLELINE ((USHORT)0x0001) -#define STYLE_TABCONTROL_COLOR ((USHORT)0x0002) +#define STYLE_RADIOBUTTON_MONO ((USHORT)0x0001) // legacy +#define STYLE_CHECKBOX_MONO ((USHORT)0x0001) // legacy #define STYLE_TOOLBAR_ICONSIZE_UNKNOWN ((ULONG)0) #define STYLE_TOOLBAR_ICONSIZE_SMALL ((ULONG)1) @@ -813,23 +784,6 @@ public: const Font& GetIconFont() const { return mpData->maIconFont; } - void SetRadioButtonStyle( USHORT nStyle ) - { CopyData(); mpData->mnRadioButtonStyle = nStyle; } - USHORT GetRadioButtonStyle() const - { return mpData->mnRadioButtonStyle; } - void SetCheckBoxStyle( USHORT nStyle ) - { CopyData(); mpData->mnCheckBoxStyle = nStyle; } - USHORT GetCheckBoxStyle() const - { return mpData->mnCheckBoxStyle; } - void SetPushButtonStyle( USHORT nStyle ) - { CopyData(); mpData->mnPushButtonStyle = nStyle; } - USHORT GetPushButtonStyle() const - { return mpData->mnPushButtonStyle; } - void SetTabControlStyle( USHORT nStyle ) - { CopyData(); mpData->mnTabControlStyle = nStyle; } - USHORT GetTabControlStyle() const - { return mpData->mnTabControlStyle; } - void SetBorderSize( long nSize ) { CopyData(); mpData->mnBorderSize = nSize; } long GetBorderSize() const @@ -971,10 +925,6 @@ public: { CopyData(); mpData->maWorkspaceGradient = rWall; } void SetStandardStyles(); - void SetStandardWinStyles(); - void SetStandardOS2Styles(); - void SetStandardMacStyles(); - void SetStandardUnixStyles(); const StyleSettings& operator =( const StyleSettings& rSet ); diff --git a/vcl/inc/vcl/smartid.hxx b/vcl/inc/vcl/smartid.hxx deleted file mode 100755 index 2cc5f347b2cb..000000000000 --- a/vcl/inc/vcl/smartid.hxx +++ /dev/null @@ -1,87 +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 _SMARTID_HXX_ -#define _SMARTID_HXX_ - -#include <tools/string.hxx> -#include <vcl/dllapi.h> - -/// SMART_SET_SMART only sets the Ids that are defined in the SmartId -/// the other types set whatever is given. This can also be used to reset an Id -enum SmartIdUpdateMode { SMART_SET_SMART, SMART_SET_NUM, SMART_SET_STR, SMART_SET_ALL }; - -struct ImplSmartIdData; - -/* - -SmartId is a substitute for Numeric HelpIds. They can handle Numeric and String HelpIds and offer commonly needed operators. - -Matching Ids: -if part of an Id is not set (HasNumeric HasString is False) then this part will never match to anything. Not even unset values - -*/ -class VCL_DLLPUBLIC SmartId -{ -private: - ImplSmartIdData* mpData; - SAL_DLLPRIVATE ImplSmartIdData* GetSmartIdData(); - -public: - explicit SmartId( const String& rId ); - explicit SmartId( ULONG nId ); - SmartId( const String& rId, ULONG nId ); - - SmartId(); - - SmartId( const SmartId& rId ); - SmartId& operator = ( const SmartId& rId ); - - ~SmartId(); - - void UpdateId( const SmartId& rId, SmartIdUpdateMode aMode = SMART_SET_SMART ); - - BOOL HasNumeric() const; - BOOL HasString() const; - BOOL HasAny() const; - ULONG GetNum() const; - String GetStr() const; - - String GetText() const; /// return String for UI usage - - BOOL Matches( const String &rId )const; - BOOL Matches( const ULONG nId ) const; -/// In case both Ids have both values set only the StringId is used for Matching - BOOL Matches( const SmartId &rId ) const; - - BOOL Equals( const SmartId &rId ) const; - - BOOL operator == ( const SmartId& rRight ) const; - BOOL operator < ( const SmartId& rRight ) const; -}; - -#endif diff --git a/vcl/inc/vcl/splitwin.hxx b/vcl/inc/vcl/splitwin.hxx index 4aa1ca16785c..f028c6969b16 100644 --- a/vcl/inc/vcl/splitwin.hxx +++ b/vcl/inc/vcl/splitwin.hxx @@ -201,6 +201,18 @@ public: BOOL bPropGreat = FALSE ); void SetItemSize( USHORT nId, long nNewSize ); long GetItemSize( USHORT nId ) const; + /** Set a range that limits the (variable part of the) size with an + upper and a lower bound (both are valid values themselves.) + @param nId + Id of the item for which the size limits are set. + @param aRange + Values of -1 define missing bounds, thus setting a range (-1,-1) + (the default) removes the size limitiation. + */ + void SetItemSizeRange (USHORT nId, const Range aRange); + /** Return the current size limits for the specified item. + */ + Range GetItemSizeRange (USHORT nId) const; long GetItemSize( USHORT nId, SplitWindowItemBits nBits ) const; void SetItemBits( USHORT nId, SplitWindowItemBits nNewBits ); SplitWindowItemBits GetItemBits( USHORT nId ) const; diff --git a/vcl/inc/vcl/status.hxx b/vcl/inc/vcl/status.hxx index 810ecf230960..907d08272cbb 100644 --- a/vcl/inc/vcl/status.hxx +++ b/vcl/inc/vcl/status.hxx @@ -183,8 +183,8 @@ public: using Window::GetQuickHelpText; const XubString& GetQuickHelpText( USHORT nItemId ) const; - void SetHelpId( USHORT nItemId, ULONG nHelpId ); - ULONG GetHelpId( USHORT nItemId ) const; + void SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ); + rtl::OString GetHelpId( USHORT nItemId ) const; void SetBottomBorder( BOOL bBottomBorder = TRUE ); BOOL IsBottomBorder() const { return mbBottomBorder; } @@ -205,9 +205,9 @@ public: const XubString& GetHelpText() const { return Window::GetHelpText(); } - void SetHelpId( ULONG nId ) - { Window::SetHelpId( nId ); } - ULONG GetHelpId() const + void SetHelpId( const rtl::OString& rId ) + { Window::SetHelpId( rId ); } + const rtl::OString& GetHelpId() const { return Window::GetHelpId(); } Size CalcWindowSizePixel() const; diff --git a/vcl/inc/vcl/svdata.hxx b/vcl/inc/vcl/svdata.hxx index 5cc8f32d7ac9..67aa6806be49 100644 --- a/vcl/inc/vcl/svdata.hxx +++ b/vcl/inc/vcl/svdata.hxx @@ -28,20 +28,19 @@ #ifndef _SV_SVDATA_HXX #define _SV_SVDATA_HXX -#ifndef _VOS_THREAD_HXX -#include <vos/thread.hxx> -#endif -#include <tools/string.hxx> -#include <tools/gen.hxx> -#include <tools/shl.hxx> -#include <tools/link.hxx> -#include <vcl/vclevent.hxx> -#include <vcl/sv.h> -#include <tools/color.hxx> -#include <tools/debug.hxx> -#include <vcl/dllapi.h> -#include <com/sun/star/uno/Reference.hxx> -#include <unotools/options.hxx> +#include "vos/thread.hxx" +#include "tools/string.hxx" +#include "tools/gen.hxx" +#include "tools/shl.hxx" +#include "tools/link.hxx" +#include "tools/fldunit.hxx" +#include "vcl/vclevent.hxx" +#include "vcl/sv.h" +#include "tools/color.hxx" +#include "tools/debug.hxx" +#include "vcl/dllapi.h" +#include "com/sun/star/uno/Reference.hxx" +#include "unotools/options.hxx" namespace com { namespace sun { @@ -168,6 +167,8 @@ struct ImplSVAppData BOOL mbDialogCancel; // TRUE: Alle Dialog::Execute()-Aufrufe werden mit return FALSE sofort beendet BOOL mbNoYield; // Application::Yield will not wait for events if the queue is empty // essentially that makes it the same as Application::Reschedule + long mnDefaultLayoutBorder; // default value in pixel for layout distances used + // in window arrangers /** Controls whether showing any IME status window is toggled on or off. @@ -208,7 +209,6 @@ struct ImplSVGDIData BOOL mbFontSubChanged; // TRUE: FontSubstitution wurde zwischen Begin/End geaendert utl::DefaultFontConfiguration* mpDefaultFontConfiguration; utl::FontSubstConfiguration* mpFontSubstConfiguration; - bool mbPrinterPullModel; // true: use pull model instead of normal push model when printing bool mbNativeFontConfig; // true: do not override UI font bool mbNoXORClipping; // true: do not use XOR to achieve clipping effects }; @@ -248,6 +248,8 @@ struct ImplSVWinData // - ImplSVCtrlData - // ------------------ +typedef std::vector< std::pair< String, FieldUnit > > FieldUnitStringList; + struct ImplSVCtrlData { ImageList* mpCheckImgList; // ImageList for CheckBoxes @@ -271,6 +273,8 @@ struct ImplSVCtrlData ULONG mnLastRadioFColor; // Letzte FaceColor fuer RadioImage ULONG mnLastRadioWColor; // Letzte WindowColor fuer RadioImage ULONG mnLastRadioLColor; // Letzte LightColor fuer RadioImage + FieldUnitStringList* mpFieldUnitStrings; // list with field units + FieldUnitStringList* mpCleanUnitStrings; // same list but with some "fluff" like spaces removed }; @@ -318,6 +322,8 @@ struct ImplSVNWFData // window background before drawing the native // checkbox bool mbScrollbarJumpPage; // true for "jump to here" behavior + int mnStatusBarLowerRightOffset; // amount in pixel to avoid in the lower righthand corner + bool mbCanDrawWidgetAnySize; // set to true currently on gtk }; @@ -391,6 +397,10 @@ inline ImplSVData* ImplGetAppSVData() { return ImplGetSVData(); } bool ImplInitAccessBridge( BOOL bAllowCancel, BOOL &rCancelled ); +FieldUnitStringList* ImplGetFieldUnits(); +FieldUnitStringList* ImplGetCleanedFieldUnits(); + + // ----------------------------------------------------------------------- // ----------------- diff --git a/vcl/inc/vcl/svids.hrc b/vcl/inc/vcl/svids.hrc index 059ed1524b7c..432a30c3a748 100644 --- a/vcl/inc/vcl/svids.hrc +++ b/vcl/inc/vcl/svids.hrc @@ -31,11 +31,7 @@ #include "svl/solar.hrc" #define SV_RESID_STDOFFSET 0 -#define SV_RESID_WINOFFSET 1 -#define SV_RESID_OS2OFFSET 2 -#define SV_RESID_MACOFFSET 3 -#define SV_RESID_UNIXOFFSET 4 -#define SV_RESID_MONOOFFSET 5 +#define SV_RESID_MONOOFFSET 1 // Achtung: Diese Id's muessen min. 10 Werte auseinanderliegen, da // je nach Style noch ein Offset aufgerechnet wird @@ -122,8 +118,10 @@ #define SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT 1 #define SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE 2 -#define SV_PRINT_PRT_NUP_ORDER_LRTD 0 -#define SV_PRINT_PRT_NUP_ORDER_TDLR 1 +#define SV_PRINT_PRT_NUP_ORDER_LRTB 0 +#define SV_PRINT_PRT_NUP_ORDER_TBLR 1 +#define SV_PRINT_PRT_NUP_ORDER_TBRL 2 +#define SV_PRINT_PRT_NUP_ORDER_RLTB 3 #define SV_PRINT_TAB_JOB 2 #define SV_PRINT_PRINTERS_FL 1 @@ -212,7 +210,8 @@ #define SV_ACCESSERROR_JAVA_NOT_CONFIGURED 10507 #define SV_ACCESSERROR_JAVA_DISABLED 10508 #define SV_ACCESSERROR_TURNAROUND_MSG 10509 -#define SV_ACCESSERROR_LAST SV_ACCESSERROR_TURNAROUND_MSG +#define SV_ACCESSERROR_NO_FONTS 10510 +#define SV_ACCESSERROR_LAST SV_ACCESSERROR_NO_FONTS #define SV_SHORTCUT_HELP 10600 #define SV_SHORTCUT_CONTEXTHELP 10601 diff --git a/vcl/inc/vcl/symbol.hxx b/vcl/inc/vcl/symbol.hxx index c7a745516856..0f0627fb41e3 100644 --- a/vcl/inc/vcl/symbol.hxx +++ b/vcl/inc/vcl/symbol.hxx @@ -71,9 +71,6 @@ typedef USHORT SymbolType; #define SYMBOL_DOCK ((SymbolType)32) #define SYMBOL_HIDE ((SymbolType)33) #define SYMBOL_HELP ((SymbolType)34) -#define SYMBOL_OS2CLOSE ((SymbolType)35) -#define SYMBOL_OS2FLOAT ((SymbolType)36) -#define SYMBOL_OS2HIDE ((SymbolType)37) #define SYMBOL_MENU SYMBOL_SPIN_DOWN #define SYMBOL_NOSYMBOL (SYMBOL_DONTKNOW) diff --git a/vcl/inc/vcl/syschild.hxx b/vcl/inc/vcl/syschild.hxx index da4ffcd51a22..e914adbdffed 100644 --- a/vcl/inc/vcl/syschild.hxx +++ b/vcl/inc/vcl/syschild.hxx @@ -44,6 +44,7 @@ class VCL_DLLPUBLIC SystemChildWindow : public Window private: using Window::ImplInit; SAL_DLLPRIVATE void ImplInitSysChild( Window* pParent, WinBits nStyle, SystemWindowData *pData, BOOL bShow = FALSE ); + SAL_DLLPRIVATE void ImplTestJavaException( void* pEnv ); // Copy assignment is forbidden and not implemented. SAL_DLLPRIVATE SystemChildWindow (const SystemChildWindow &); @@ -62,6 +63,11 @@ public: // however, this might not always be required void EnableEraseBackground( BOOL bEnable = TRUE ); BOOL IsEraseBackgroundEnabled(); + + // return the platform specific handle/id of this window; + // in case the flag bUseJava is set, a java compatible overlay window + // is created on which other java windows can be created (plugin interface) + sal_IntPtr GetParentWindowHandle( sal_Bool bUseJava = sal_False ); }; #endif // _SV_SYSCHILD_HXX diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx index 4c63b12f15fe..430a99235b52 100644 --- a/vcl/inc/vcl/tabctrl.hxx +++ b/vcl/inc/vcl/tabctrl.hxx @@ -63,14 +63,9 @@ private: long mnMaxPageWidth; USHORT mnActPageId; USHORT mnCurPageId; - USHORT mnFirstPagePos; - USHORT mnLastFirstPagePos; BOOL mbFormat; BOOL mbRestoreHelpId; BOOL mbRestoreUnqId; - BOOL mbSingleLine; - BOOL mbScroll; - BOOL mbRestoreSmartId; BOOL mbSmallInvalidate; BOOL mbExtraSpace; Link maActivateHdl; @@ -79,22 +74,17 @@ private: using Control::ImplInitSettings; SAL_DLLPRIVATE void ImplInitSettings( BOOL bFont, BOOL bForeground, BOOL bBackground ); SAL_DLLPRIVATE ImplTabItem* ImplGetItem( USHORT nId ) const; - SAL_DLLPRIVATE void ImplScrollBtnsColor(); - SAL_DLLPRIVATE void ImplSetScrollBtnsState(); - SAL_DLLPRIVATE void ImplPosScrollBtns(); SAL_DLLPRIVATE Size ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ); SAL_DLLPRIVATE Rectangle ImplGetTabRect( USHORT nPos, long nWidth = -1, long nHeight = -1 ); SAL_DLLPRIVATE void ImplChangeTabPage( USHORT nId, USHORT nOldId ); SAL_DLLPRIVATE BOOL ImplPosCurTabPage(); SAL_DLLPRIVATE void ImplActivateTabPage( BOOL bNext ); - SAL_DLLPRIVATE void ImplSetFirstPagePos( USHORT nPagePos ); SAL_DLLPRIVATE void ImplShowFocus(); SAL_DLLPRIVATE void ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bool bLayout = false, bool bFirstInGroup = false, bool bLastInGroup = false, bool bIsCurrentItem = false ); SAL_DLLPRIVATE void ImplPaint( const Rectangle& rRect, bool bLayout = false ); SAL_DLLPRIVATE void ImplFreeLayoutData(); SAL_DLLPRIVATE long ImplHandleKeyEvent( const KeyEvent& rKeyEvent ); - DECL_DLLPRIVATE_LINK( ImplScrollBtnHdl, PushButton* pBtn ); DECL_DLLPRIVATE_LINK( ImplListBoxSelectHdl, ListBox* ); DECL_DLLPRIVATE_LINK( ImplWindowEventListener, VclSimpleEvent* ); @@ -157,9 +147,6 @@ public: void SetCurPageId( USHORT nPageId ); USHORT GetCurPageId() const; - void SetFirstPageId( USHORT nPageId ); - USHORT GetFirstPageId() const { return GetPageId( mnFirstPagePos ); } - void SelectTabPage( USHORT nPageId ); void SetMaxPageWidth( long nMaxWidth ) { mnMaxPageWidth = nMaxWidth; } @@ -177,8 +164,8 @@ public: void SetHelpText( USHORT nPageId, const XubString& rText ); const XubString& GetHelpText( USHORT nPageId ) const; - void SetHelpId( USHORT nPageId, ULONG nHelpId ); - ULONG GetHelpId( USHORT nPageId ) const; + void SetHelpId( USHORT nPageId, const rtl::OString& rHelpId ); + rtl::OString GetHelpId( USHORT nPageId ) const; void SetPageImage( USHORT nPageId, const Image& rImage ); const Image* GetPageImage( USHORT nPageId ) const; @@ -188,9 +175,9 @@ public: const XubString& GetHelpText() const { return Control::GetHelpText(); } - void SetHelpId( ULONG nId ) - { Control::SetHelpId( nId ); } - ULONG GetHelpId() const + void SetHelpId( const rtl::OString& rId ) + { Control::SetHelpId( rId ); } + const rtl::OString& GetHelpId() const { return Control::GetHelpId(); } void SetActivatePageHdl( const Link& rLink ) { maActivateHdl = rLink; } diff --git a/vcl/inc/vcl/toolbox.h b/vcl/inc/vcl/toolbox.h index 33e4e8d2e013..7cdeb0b17a5a 100644 --- a/vcl/inc/vcl/toolbox.h +++ b/vcl/inc/vcl/toolbox.h @@ -68,7 +68,7 @@ struct ImplToolItem XubString maQuickHelpText; XubString maHelpText; String maCommandStr; - ULONG mnHelpId; + rtl::OString maHelpId; Rectangle maRect; Rectangle maCalcRect; // the overall horizontal item size, including one or more of [image size + textlength + dropdown arrow] diff --git a/vcl/inc/vcl/toolbox.hxx b/vcl/inc/vcl/toolbox.hxx index 5cc102842dc3..aa7ddd886bbb 100644 --- a/vcl/inc/vcl/toolbox.hxx +++ b/vcl/inc/vcl/toolbox.hxx @@ -511,8 +511,8 @@ public: void SetHelpText( USHORT nItemId, const XubString& rText ); const XubString& GetHelpText( USHORT nItemId ) const; - void SetHelpId( USHORT nItemId, ULONG nHelpId ); - ULONG GetHelpId( USHORT nItemId ) const; + void SetHelpId( USHORT nItemId, const rtl::OString& rHelpId ); + rtl::OString GetHelpId( USHORT nItemId ) const; // window size according to current alignment, floating state and number of lines Size CalcWindowSizePixel() const; @@ -569,9 +569,9 @@ public: const XubString& GetHelpText() const { return DockingWindow::GetHelpText(); } - void SetHelpId( ULONG nId ) - { DockingWindow::SetHelpId( nId ); } - ULONG GetHelpId() const + void SetHelpId( const rtl::OString& rId ) + { DockingWindow::SetHelpId( rId ); } + const rtl::OString& GetHelpId() const { return DockingWindow::GetHelpId(); } void SetClickHdl( const Link& rLink ) { maClickHdl = rLink; } diff --git a/vcl/inc/vcl/windata.hxx b/vcl/inc/vcl/windata.hxx deleted file mode 100644 index 9436352e4927..000000000000 --- a/vcl/inc/vcl/windata.hxx +++ /dev/null @@ -1,49 +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 _SV_WINDATA_HXX -#define _SV_WINDATA_HXX - -#include <vcl/sv.h> - -class SalFrame; -class Window; - -// -------------- -// - Prototypes - -// -------------- - -long ImplWindowFrameProc( Window* pInst, SalFrame* pFrame, USHORT nEvent, const void* pEvent ); - -// ----------- -// - HitTest - -// ----------- - -#define WINDOW_HITTEST_INSIDE ((USHORT)0x0001) -#define WINDOW_HITTEST_TRANSPARENT ((USHORT)0x0002) - -#endif // _SV_WINDATA_HXX diff --git a/vcl/inc/vcl/window.h b/vcl/inc/vcl/window.h index 691c3ed18421..c710156422bf 100644 --- a/vcl/inc/vcl/window.h +++ b/vcl/inc/vcl/window.h @@ -38,7 +38,7 @@ #ifndef _SV_POINTR_HXX #include <vcl/pointr.hxx> #endif -#include <vcl/wintypes.hxx> +#include <tools/wintypes.hxx> #include <vcl/vclevent.hxx> #include <com/sun/star/uno/Reference.hxx> #include <cppuhelper/weakref.hxx> @@ -56,7 +56,6 @@ class VirtualDevice; class Cursor; class ImplDevFontList; class ImplFontCache; -class SmartId; class VCLXWindow; class SalFrame; class SalObject; @@ -99,10 +98,24 @@ namespace dnd { class XDropTarget; } } } } } -namespace vcl { struct ControlLayoutData; } +namespace vcl { + struct ControlLayoutData; + struct ExtWindowImpl; +} + + +// -------------- +// - Prototypes - +// -------------- +long ImplWindowFrameProc( Window* pInst, SalFrame* pFrame, USHORT nEvent, const void* pEvent ); +// ----------- +// - HitTest - +// ----------- +#define WINDOW_HITTEST_INSIDE ((USHORT)0x0001) +#define WINDOW_HITTEST_TRANSPARENT ((USHORT)0x0002) // --------------- // - ImplWinData - @@ -120,8 +133,6 @@ struct ImplWinData USHORT mnIsTopWindow; BOOL mbMouseOver; // tracks mouse over for native widget paint effect BOOL mbEnableNativeWidget; // toggle native widget rendering - SmartId* mpSmartHelpId; - SmartId* mpSmartUniqueId; ::std::list< Window* > maTopWindowChildren; }; @@ -239,6 +250,7 @@ public: ImplDelData* mpFirstDel; void* mpUserData; + vcl::ExtWindowImpl* mpExtImpl; Cursor* mpCursor; Pointer maPointer; Fraction maZoom; @@ -254,8 +266,8 @@ public: long mnY; long mnAbsScreenX; Point maPos; - ULONG mnHelpId; - ULONG mnUniqId; + rtl::OString maHelpId; + rtl::OString maUniqId; XubString maHelpText; XubString maQuickHelpText; InputContext maInputContext; @@ -355,7 +367,8 @@ public: mbDisableAccessibleLabelForRelation:1, mbDisableAccessibleLabeledByRelation:1, mbHelpTextDynamic:1, - mbFakeFocusSet:1; + mbFakeFocusSet:1, + mbInterceptChildWindowKeyDown:1; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer; }; diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx index 8264767e59ad..5ba3b615904e 100644..100755 --- a/vcl/inc/vcl/window.hxx +++ b/vcl/inc/vcl/window.hxx @@ -35,7 +35,7 @@ #ifndef _SV_POINTR_HXX #include <vcl/pointr.hxx> #endif -#include <vcl/wintypes.hxx> +#include <tools/wintypes.hxx> #ifndef _SV_APPTYPES_HXX #include <vcl/apptypes.hxx> #endif @@ -50,7 +50,7 @@ #include <rtl/ustring.hxx> #include <cppuhelper/weakref.hxx> #include <com/sun/star/uno/Reference.hxx> -#include <vcl/smartid.hxx> +#include <boost/shared_ptr.hpp> class VirtualDevice; struct ImplDelData; @@ -95,6 +95,13 @@ namespace accessibility { namespace com { namespace sun { namespace star { +namespace beans { + struct PropertyValue; +}}}} + +namespace com { +namespace sun { +namespace star { namespace rendering { class XCanvas; class XSpriteCanvas; @@ -122,7 +129,11 @@ namespace dnd { class XDropTarget; } } } } } -namespace vcl { struct ControlLayoutData; } +namespace vcl { + struct ControlLayoutData; + class WindowArranger; + struct ExtWindowImpl; +} namespace svt { class PopupWindowControllerImpl; } @@ -476,6 +487,10 @@ public: SAL_DLLPRIVATE BOOL ImplUpdatePos(); SAL_DLLPRIVATE void ImplUpdateSysObjPos(); SAL_DLLPRIVATE WindowImpl* ImplGetWindowImpl() const { return mpWindowImpl; } + SAL_DLLPRIVATE void ImplFreeExtWindowImpl(); + // creates ExtWindowImpl on demand, but may return NULL (e.g. if mbInDtor) + SAL_DLLPRIVATE vcl::ExtWindowImpl* ImplGetExtWindowImpl() const; + SAL_DLLPRIVATE void ImplDeleteOwnedChildren(); /** check whether a font is suitable for UI The font to be tested will be checked whether it could display a @@ -541,6 +556,7 @@ public: SAL_DLLPRIVATE BOOL ImplRegisterAccessibleNativeFrame(); SAL_DLLPRIVATE void ImplRevokeAccessibleNativeFrame(); SAL_DLLPRIVATE void ImplCallResize(); + SAL_DLLPRIVATE void ImplExtResize(); SAL_DLLPRIVATE void ImplCallMove(); SAL_DLLPRIVATE Rectangle ImplOutputToUnmirroredAbsoluteScreenPixel( const Rectangle& rRect ) const; SAL_DLLPRIVATE void ImplMirrorFramePos( Point &pt ) const; @@ -599,6 +615,7 @@ public: virtual void KeyUp( const KeyEvent& rKEvt ); virtual void PrePaint(); virtual void Paint( const Rectangle& rRect ); + virtual void PostPaint(); virtual void Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags ); virtual void Move(); virtual void Resize(); @@ -953,16 +970,12 @@ public: void SetQuickHelpText( const XubString& rHelpText ); const XubString& GetQuickHelpText() const; - void SetHelpId( ULONG nHelpId ); /// deprecated - ULONG GetHelpId() const; /// deprecated - void SetSmartHelpId( const SmartId& aId, SmartIdUpdateMode aMode = SMART_SET_SMART ); - SmartId GetSmartHelpId() const; + void SetHelpId( const rtl::OString& ); + const rtl::OString& GetHelpId() const; - void SetUniqueId( ULONG nUniqueId ); /// deprecated - ULONG GetUniqueId() const; /// deprecated - void SetSmartUniqueId( const SmartId& aId, SmartIdUpdateMode aMode = SMART_SET_SMART ); - SmartId GetSmartUniqueId() const; - SmartId GetSmartUniqueOrHelpId() const; + void SetUniqueId( const rtl::OString& ); + const rtl::OString& GetUniqueId() const; + const rtl::OString& GetUniqueOrHelpId() const; Window* FindWindow( const Point& rPos ) const; @@ -1101,8 +1114,61 @@ public: */ void doLazyDelete(); + // let the window intercept the KeyDown messages of the system children + void InterceptChildWindowKeyDown( sal_Bool bIntercept ); + virtual XubString GetSurroundingText() const; virtual Selection GetSurroundingTextSelection() const; + + // ExtImpl + + // layouting + boost::shared_ptr< vcl::WindowArranger > getLayout(); + + /* add a child Window + addWindow will do the following things + - insert the passed window into the child list (equivalent to i_pWin->SetParent( this )) + - mark the window as "owned", meaning that the added Window will be destroyed by + the parent's desctructor. + This means: do not pass in member windows or stack objects here. Do not cause + the destructor of the added window to be called in any way. + + to avoid ownership pass i_bTakeOwnership as "false" + */ + void addWindow( Window* i_pWin, bool i_bTakeOwnership = true ); + + /* remove a child Window + the remove window functions will + - reparent the searched window (equivalent to i_pWin->SetParent( i_pNewParent )) + - return a pointer to the removed window or NULL if i_pWin was not found + caution: ownership passes to the new parent or the caller, if the new parent was NULL + */ + Window* removeWindow( Window* i_pWin, Window* i_pNewParent = NULL ); + + /* return the identifier of this window + */ + const rtl::OUString& getIdentifier() const; + /* set an identifier + identifiers have only loosely defined rules per se + in context of Window they must be unique over the window + hierarchy you'd like to find them again using the findWindow method + */ + void setIdentifier( const rtl::OUString& ); + + /* returns the first found descendant that matches + the passed identifier or NULL + */ + Window* findWindow( const rtl::OUString& ) const; + + /* get/set properties + this will contain window properties (like visible, enabled) + as well as properties of derived classes (e.g. text of Edit fields) + */ + virtual com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > getProperties() const; + /* + */ + virtual void setProperties( const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& ); + }; diff --git a/vcl/inc/vcl/wintypes.hxx b/vcl/inc/vcl/wintypes.hxx deleted file mode 100644 index 6da4e4e3d988..000000000000 --- a/vcl/inc/vcl/wintypes.hxx +++ /dev/null @@ -1,33 +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 _SV_WINTYPES_HXX -#define _SV_WINTYPES_HXX - -#include <tools/wintypes.hxx> - -#endif // _SV_WINTYPES_HXX - diff --git a/vcl/inc/vcl/impbmpconv.hxx b/vcl/inc/vcl/wpropset.hxx index d95da9a4093a..409b629496e6 100644 --- a/vcl/inc/vcl/impbmpconv.hxx +++ b/vcl/inc/vcl/wpropset.hxx @@ -25,15 +25,42 @@ * ************************************************************************/ -#ifndef _VCL_IMPBMPCONV_HXX_ -#define _VCL_IMPBMPCONV_HXX_ +#ifndef VCL_WPROPSET_HXX +#define VCL_WPROPSET_HXX -#include <com/sun/star/script/XInvocation.hpp> -#include <com/sun/star/uno/Reference.hxx> +#include "vcl/dllapi.h" + +#include "tools/link.hxx" +#include "vcl/arrange.hxx" + +#include "com/sun/star/beans/XPropertySet.hpp" + +class VclWindowEvent; namespace vcl { -com::sun::star::uno::Reference< com::sun::star::script::XInvocation > createBmpConverter(); + class WindowPropertySetData; + class WindowPropertySetListener; + + class VCL_DLLPUBLIC WindowPropertySet + { + WindowPropertySetData* mpImpl; + + void addWindowToSet( Window* ); + void addLayoutToSet( const boost::shared_ptr<WindowArranger>& ); + void setupProperties(); + + DECL_LINK( ChildEventListener, VclWindowEvent* ); + + void propertyChange( const com::sun::star::beans::PropertyChangeEvent& ); + friend class vcl::WindowPropertySetListener; + + public: + WindowPropertySet( Window* i_pTopWindow, bool i_bTakeOwnership ); + ~WindowPropertySet(); + + com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet > getPropertySet() const; + }; } #endif diff --git a/vcl/os2/inc/salgdi.h b/vcl/os2/inc/salgdi.h index b8dc4eba0199..94b2b98b4183 100644 --- a/vcl/os2/inc/salgdi.h +++ b/vcl/os2/inc/salgdi.h @@ -74,7 +74,7 @@ public: bool AliasSymbolsHigh() const { return mbAliasSymbolsHigh; } bool AliasSymbolsLow() const { return mbAliasSymbolsLow; } - ImplFontCharMap* GetImplFontCharMap() const; + const ImplFontCharMap* GetImplFontCharMap() const; private: sal_IntPtr mnId; @@ -82,7 +82,7 @@ private: mutable bool mbHasKoreanRange; mutable bool mbHasCJKSupport; - mutable ImplFontCharMap* mpUnicodeMap; + mutable const ImplFontCharMap* mpUnicodeMap; // TODO: get rid of the members below needed to work with the Win9x non-unicode API BYTE* mpFontCharSets; // all Charsets for the current font (used on W98 for kerning) @@ -162,7 +162,7 @@ protected: virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); virtual void drawPolyPolygon( ULONG nPoly, const ULONG* pPoints, PCONSTSALPOINT* pPtAry ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin ); virtual sal_Bool drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolyPolygonBezier( ULONG nPoly, const ULONG* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry ); diff --git a/vcl/os2/inc/salinst.h b/vcl/os2/inc/salinst.h index 0948f605c286..7826a62e1f9b 100644 --- a/vcl/os2/inc/salinst.h +++ b/vcl/os2/inc/salinst.h @@ -85,12 +85,9 @@ public: virtual vos::IMutex* GetYieldMutex(); virtual ULONG ReleaseYieldMutex(); virtual void AcquireYieldMutex( ULONG nCount ); + virtual bool CheckYieldMutex(); virtual void Yield( bool, bool ); virtual bool AnyInput( USHORT nType ); - virtual SalMenu* CreateMenu( BOOL bMenuBar ); - virtual void DestroyMenu( SalMenu* ); - virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); - virtual void DestroyMenuItem( SalMenuItem* ); virtual SalSession* CreateSalSession(); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); virtual void AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType); diff --git a/vcl/os2/inc/salobj.h b/vcl/os2/inc/salobj.h index 5b4ac21ccdd6..04fdef90bf67 100644 --- a/vcl/os2/inc/salobj.h +++ b/vcl/os2/inc/salobj.h @@ -64,6 +64,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/os2/source/app/salinst.cxx b/vcl/os2/source/app/salinst.cxx index b08a9769ccf4..9d74f281d680 100644 --- a/vcl/os2/source/app/salinst.cxx +++ b/vcl/os2/source/app/salinst.cxx @@ -43,7 +43,7 @@ #ifndef _SV_SALIDS_HRC #include <salids.hrc> #endif -#include <vcl/salatype.hxx> +#include <vcl/apptypes.hxx> #include <saldata.hxx> #include <salinst.h> #include <salframe.h> @@ -298,10 +298,9 @@ void ImplSalAcquireYieldMutex( ULONG nCount ) // ----------------------------------------------------------------------- -#ifdef DBG_UTIL - -void ImplDbgTestSolarMutex() +bool Os2SalInstance::CheckYieldMutex() { + bool bRet = true; SalData* pSalData = GetSalData(); ULONG nCurThreadId = GetCurrentThreadId(); if ( pSalData->mnAppThreadId != nCurThreadId ) @@ -311,7 +310,7 @@ void ImplDbgTestSolarMutex() SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; if ( pYieldMutex->mnThreadId != nCurThreadId ) { - DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" ); + bRet = false; } } } @@ -322,14 +321,13 @@ void ImplDbgTestSolarMutex() SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; if ( pYieldMutex->mnThreadId != nCurThreadId ) { - DBG_ERROR( "SolarMutex not locked in the main thread" ); + bRet = false; } } } + return bRet; } -#endif - // ======================================================================= void InitSalData() diff --git a/vcl/os2/source/gdi/salgdi.cxx b/vcl/os2/source/gdi/salgdi.cxx index 5be40355f731..dff1557170fb 100644 --- a/vcl/os2/source/gdi/salgdi.cxx +++ b/vcl/os2/source/gdi/salgdi.cxx @@ -670,6 +670,7 @@ bool Os2SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double / bool Os2SalGraphics::drawPolyLine( const basegfx::B2DPolygon& /*rPolygon*/, + double /*fTransparency*/, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eLineJoin*/) { diff --git a/vcl/os2/source/gdi/salgdi3.cxx b/vcl/os2/source/gdi/salgdi3.cxx index e25e68ee5a4c..0e4cb1d58b0f 100644 --- a/vcl/os2/source/gdi/salgdi3.cxx +++ b/vcl/os2/source/gdi/salgdi3.cxx @@ -434,9 +434,8 @@ bool ImplOs2FontData::IsGSUBstituted( sal_Ucs cChar ) const // ----------------------------------------------------------------------- -ImplFontCharMap* ImplOs2FontData::GetImplFontCharMap() const +const ImplFontCharMap* ImplOs2FontData::GetImplFontCharMap() const { - mpUnicodeMap->AddReference(); return mpUnicodeMap; } @@ -592,6 +591,7 @@ void ImplOs2FontData::ReadCmapTable( HPS hPS ) const aResult.mpPairCodes, aResult.mpStartGlyphs ); else mpUnicodeMap = ImplFontCharMap::GetDefaultMap(); + mpUnicodeMap->AddReference(); } // ======================================================================= @@ -999,10 +999,10 @@ ULONG Os2SalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) // ----------------------------------------------------------------------- -static ImplFontCharMap* pOs2DefaultImplFontCharMap = NULL; +static const ImplFontCharMap* pOs2DefaultImplFontCharMap = NULL; static const sal_uInt32 pOs2DefaultRangeCodes[] = {0x0020,0x00FF}; -ImplFontCharMap* Os2SalGraphics::GetImplFontCharMap() const +const ImplFontCharMap* Os2SalGraphics::GetImplFontCharMap() const { if( !mpOs2FontData[0] ) return ImplFontCharMap::GetDefaultMap(); @@ -1705,7 +1705,7 @@ void Os2SalGraphics::GetGlyphWidths( const ImplFontData* pFont, rUnicodeEnc.clear(); } const ImplOs2FontData* pWinFont = static_cast<const ImplOs2FontData*>(pFont); - ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap(); + const ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap(); DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" ); int nCharCount = pMap->GetCharCount(); diff --git a/vcl/os2/source/window/makefile.mk b/vcl/os2/source/window/makefile.mk index f4a6ad0cb870..560d35880b21 100644 --- a/vcl/os2/source/window/makefile.mk +++ b/vcl/os2/source/window/makefile.mk @@ -40,7 +40,7 @@ CXXFILES__YD= salframe.cxx \ salobj.cxx SLOFILES= $(SLO)$/salframe.obj \ - $(SLO)$/salobj.obj $(SLO)$/salmenu.obj + $(SLO)$/salobj.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/os2/source/window/salframe.cxx b/vcl/os2/source/window/salframe.cxx index f3314c725255..f465dc741a60 100644 --- a/vcl/os2/source/window/salframe.cxx +++ b/vcl/os2/source/window/salframe.cxx @@ -2122,8 +2122,6 @@ void Os2SalFrame::UpdateSettings( AllSettings& rSettings ) // --- Style settings --- StyleSettings aStyleSettings = rSettings.GetStyleSettings(); - BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0; - // General settings LONG nDisplayTime = PrfQueryProfileInt( HINI_PROFILE, (PSZ)aControlPanel, (PSZ)"LogoDisplayTime", -1 ); ULONG nSalDisplayTime; @@ -2145,32 +2143,26 @@ void Os2SalFrame::UpdateSettings( AllSettings& rSettings ) // Size settings aStyleSettings.SetScrollBarSize( WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL ) ); - if ( bCompBorder ) - { - aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) ); - } + aStyleSettings.SetTitleHeight( WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) ); // Color settings - if ( bCompBorder ) - { - aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); - aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); - aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) ); - aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); - aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) ); - aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) ); - aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) ); - aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); - aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) ); - aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) ); - aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) ); - aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) ); - aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) ); - aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) ); - aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) ); - aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); - aStyleSettings.SetMenuBarTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); - } + aStyleSettings.SetFaceColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); + aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); + aStyleSettings.SetLightColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONLIGHT, 0 ) ) ); + aStyleSettings.SetLightBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONMIDDLE, 0 ) ) ); + aStyleSettings.SetShadowColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_BUTTONDARK, 0 ) ) ); + aStyleSettings.SetDarkShadowColor( Color( COL_BLACK ) ); + aStyleSettings.SetDialogColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_DIALOGBACKGROUND, 0 ) ) ); + aStyleSettings.SetButtonTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); + aStyleSettings.SetActiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLE, 0 ) ) ); + aStyleSettings.SetActiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVETITLETEXT, 0 ) ) ); + aStyleSettings.SetActiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_ACTIVEBORDER, 0 ) ) ); + aStyleSettings.SetDeactiveColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLE, 0 ) ) ); + aStyleSettings.SetDeactiveTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVETITLETEXT, 0 ) ) ); + aStyleSettings.SetDeactiveBorderColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_INACTIVEBORDER, 0 ) ) ); + aStyleSettings.SetMenuColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENU, 0 ) ) ); + aStyleSettings.SetMenuTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); + aStyleSettings.SetMenuBarTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUTEXT, 0 ) ) ); aStyleSettings.SetDialogTextColor( aStyleSettings.GetButtonTextColor() ); aStyleSettings.SetRadioCheckTextColor( aStyleSettings.GetButtonTextColor() ); aStyleSettings.SetGroupTextColor( ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_WINDOWSTATICTEXT, 0 ) ) ); @@ -2187,11 +2179,8 @@ void Os2SalFrame::UpdateSettings( AllSettings& rSettings ) Color aMenuHighColor = ImplOS2ColorToSal( WinQuerySysColor( HWND_DESKTOP, SYSCLR_MENUHILITEBGND, 0 ) ); if ( ImplSalIsSameColor( aMenuHighColor, aStyleSettings.GetMenuColor() ) ) { - if ( bCompBorder ) - { - aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) ); - aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) ); - } + aStyleSettings.SetMenuHighlightColor( Color( COL_BLUE ) ); + aStyleSettings.SetMenuHighlightTextColor( Color( COL_WHITE ) ); } else { diff --git a/vcl/os2/source/window/salmenu.cxx b/vcl/os2/source/window/salmenu.cxx deleted file mode 100644 index 339ab5dbfadb..000000000000 --- a/vcl/os2/source/window/salmenu.cxx +++ /dev/null @@ -1,132 +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. - * - ************************************************************************/ - -#define INCL_DOS -#define INCL_PM -#define INCL_WIN -#include <svpm.h> -#include <saldata.hxx> -#include <salinst.h> -#include <salmenu.h> - - -// ======================================================================= - -// Os2SalInst factory methods - -SalMenu* Os2SalInstance::CreateMenu( BOOL bMenuBar ) -{ - return NULL; // no support for native menues -} - -void Os2SalInstance::DestroyMenu( SalMenu* pSalMenu ) -{ - delete pSalMenu; -} - - -SalMenuItem* Os2SalInstance::CreateMenuItem( const SalItemParams* pItemData ) -{ - return NULL; // no support for native menues -} - -void Os2SalInstance::DestroyMenuItem( SalMenuItem* pSalMenuItem ) -{ - delete pSalMenuItem; -} - - -// ======================================================================= - - -/* - * Os2SalMenu - */ - - -Os2SalMenu::~Os2SalMenu() -{ -} - -BOOL Os2SalMenu::VisibleMenuBar() -{ - return FALSE; -} - -void Os2SalMenu::SetFrame( const SalFrame *pFrame ) -{ -} - -void Os2SalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) -{ -} - -void Os2SalMenu::RemoveItem( unsigned nPos ) -{ -} - -void Os2SalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos ) -{ -} - -void Os2SalMenu::CheckItem( unsigned nPos, BOOL bCheck ) -{ -} - -void Os2SalMenu::EnableItem( unsigned nPos, BOOL bEnable ) -{ -} - -void Os2SalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage ) -{ -} - -void Os2SalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const XubString& rText ) -{ -} - -void Os2SalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const XubString& rKeyName ) -{ -} - -void Os2SalMenu::GetSystemMenuData( SystemMenuData* pData ) -{ -} - -// ======================================================================= - -/* - * SalMenuItem - */ - - -Os2SalMenuItem::~Os2SalMenuItem() -{ -} - -// ------------------------------------------------------------------- - diff --git a/vcl/os2/source/window/salobj.cxx b/vcl/os2/source/window/salobj.cxx index 85ed1a606d08..e55ce448f7d0 100644 --- a/vcl/os2/source/window/salobj.cxx +++ b/vcl/os2/source/window/salobj.cxx @@ -566,3 +566,9 @@ void Os2SalObject::SetCallback( void* pInst, SALOBJECTPROC pProc ) } #endif +// ----------------------------------------------------------------------- + +void Os2SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/prj/build.lst b/vcl/prj/build.lst index e6f636522acb..af15ad73e19d 100644 --- a/vcl/prj/build.lst +++ b/vcl/prj/build.lst @@ -1,4 +1,4 @@ -vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools l10ntools icc SO:print_header cpputools shell svl NULL +vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools l10ntools icc SO:print_header cpputools shell svl LIBXSLT:libxslt NULL vc vcl usr1 - all vc_mkout NULL vc vcl\inc nmake - all vc_inc NULL vc vcl\source\glyphs nmake - all vc_glyphs vc_inc NULL @@ -48,3 +48,10 @@ vc vcl\mac\source\src nmake - m vc__srcm vc_inc NULL vc vcl\util nmake - all vc_util vc__plug.u vc__desk.u vc__aquy.u vc__appa.u vc__dtra.u vc__appm.m vc__appu.u vc__dtru.u vc__appw.w vc__appp.p vc__gdia.u vc__gdim.m vc__gdiu.u vc__gdiw.w vc__gdip.p vc__srcm.m vc__srcw.w vc__srcp.p vc__wina.u vc__winm.m vc__winu.u vc__winw.w vc__winp.p vc__gtka.u vc__gtky.u vc__gtkw.u vc__gtkg.u vc__kde.u vc__kde4.u vc__hl.u vc__ftmu.u vc__prgu.u vc__prnu.u vc_app vc_ctrl vc_gdi vc_hlp vc_src vc_win vc_glyphs vc_fts vc_components NULL vc vcl\util\linksvp nmake - u vc_lsvp vc_util NULL vc vcl\workben nmake - all vc_wrkb vc_util vc_salmain NULL + +# memCheck works only within unix +# memCheck is not right yet +# vc vcl\qa\complex\memCheck nmake - u vc_qa_complex vc_util NULL +# GPF +# vc vcl\qa\complex\persistent_window_states nmake - all vc_qa_complex vc_util NULL + diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst index 8345b155ce58..307064f7555d 100644 --- a/vcl/prj/d.lst +++ b/vcl/prj/d.lst @@ -17,12 +17,12 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\alpha.hxx %_DEST%\inc%_EXT%\vcl\alpha.hxx ..\inc\vcl\animate.hxx %_DEST%\inc%_EXT%\vcl\animate.hxx ..\inc\vcl\apptypes.hxx %_DEST%\inc%_EXT%\vcl\apptypes.hxx +..\inc\vcl\arrange.hxx %_DEST%\inc%_EXT%\vcl\arrange.hxx ..\inc\vcl\bitmap.hxx %_DEST%\inc%_EXT%\vcl\bitmap.hxx ..\inc\vcl\bitmapex.hxx %_DEST%\inc%_EXT%\vcl\bitmapex.hxx ..\inc\vcl\bmpacc.hxx %_DEST%\inc%_EXT%\vcl\bmpacc.hxx ..\inc\vcl\btndlg.hxx %_DEST%\inc%_EXT%\vcl\btndlg.hxx ..\inc\vcl\button.hxx %_DEST%\inc%_EXT%\vcl\button.hxx -..\inc\vcl\button.hxx %_DEST%\inc%_EXT%\vcl\imagebtn.hxx ..\inc\vcl\cmdevt.h %_DEST%\inc%_EXT%\vcl\cmdevt.h ..\inc\vcl\cmdevt.hxx %_DEST%\inc%_EXT%\vcl\cmdevt.hxx ..\inc\vcl\combobox.h %_DEST%\inc%_EXT%\vcl\combobox.h @@ -41,7 +41,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\field.hxx %_DEST%\inc%_EXT%\vcl\field.hxx ..\inc\vcl\fixbrd.hxx %_DEST%\inc%_EXT%\vcl\fixbrd.hxx ..\inc\vcl\fixed.hxx %_DEST%\inc%_EXT%\vcl\fixed.hxx -..\inc\vcl\fldunit.hxx %_DEST%\inc%_EXT%\vcl\fldunit.hxx ..\inc\vcl\floatwin.hxx %_DEST%\inc%_EXT%\vcl\floatwin.hxx ..\inc\vcl\fntstyle.hxx %_DEST%\inc%_EXT%\vcl\fntstyle.hxx ..\inc\vcl\font.hxx %_DEST%\inc%_EXT%\vcl\font.hxx @@ -56,7 +55,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\help.hxx %_DEST%\inc%_EXT%\vcl\help.hxx ..\inc\vcl\image.hxx %_DEST%\inc%_EXT%\vcl\image.hxx ..\inc\vcl\imagerepository.hxx %_DEST%\inc%_EXT%\vcl\imagerepository.hxx -..\inc\vcl\imgcons.hxx %_DEST%\inc%_EXT%\vcl\imgcons.hxx ..\inc\vcl\imgctrl.hxx %_DEST%\inc%_EXT%\vcl\imgctrl.hxx ..\inc\vcl\impdel.hxx %_DEST%\inc%_EXT%\vcl\impdel.hxx ..\inc\vcl\inputctx.hxx %_DEST%\inc%_EXT%\vcl\inputctx.hxx @@ -70,7 +68,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\lstbox.h %_DEST%\inc%_EXT%\vcl\lstbox.h ..\inc\vcl\lstbox.hxx %_DEST%\inc%_EXT%\vcl\lstbox.hxx ..\inc\vcl\mapmod.hxx %_DEST%\inc%_EXT%\vcl\mapmod.hxx -..\inc\vcl\mapunit.hxx %_DEST%\inc%_EXT%\vcl\mapunit.hxx ..\inc\vcl\menu.hxx %_DEST%\inc%_EXT%\vcl\menu.hxx ..\inc\vcl\menubtn.hxx %_DEST%\inc%_EXT%\vcl\menubtn.hxx ..\inc\vcl\metaact.hxx %_DEST%\inc%_EXT%\vcl\metaact.hxx @@ -78,6 +75,7 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\metric.hxx %_DEST%\inc%_EXT%\vcl\metric.hxx ..\inc\vcl\mnemonic.hxx %_DEST%\inc%_EXT%\vcl\mnemonic.hxx ..\inc\vcl\mnemonicengine.hxx %_DEST%\inc%_EXT%\vcl\mnemonicengine.hxx +..\inc\vcl\quickselectionengine.hxx %_DEST%\inc%_EXT%\vcl\quickselectionengine.hxx ..\inc\vcl\morebtn.hxx %_DEST%\inc%_EXT%\vcl\morebtn.hxx ..\inc\vcl\msgbox.hxx %_DEST%\inc%_EXT%\vcl\msgbox.hxx ..\inc\vcl\octree.hxx %_DEST%\inc%_EXT%\vcl\octree.hxx @@ -128,7 +126,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\waitobj.hxx %_DEST%\inc%_EXT%\vcl\waitobj.hxx ..\inc\vcl\wall.hxx %_DEST%\inc%_EXT%\vcl\wall.hxx ..\inc\vcl\window.hxx %_DEST%\inc%_EXT%\vcl\window.hxx -..\inc\vcl\wintypes.hxx %_DEST%\inc%_EXT%\vcl\wintypes.hxx ..\inc\vcl\wrkwin.hxx %_DEST%\inc%_EXT%\vcl\wrkwin.hxx ..\inc\vcl\threadex.hxx %_DEST%\inc%_EXT%\vcl\threadex.hxx ..\inc\vcl\evntpost.hxx %_DEST%\inc%_EXT%\vcl\evntpost.hxx @@ -144,7 +141,6 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\pdfextoutdevdata.hxx %_DEST%\inc%_EXT%\vcl\pdfextoutdevdata.hxx ..\inc\vcl\pngread.hxx %_DEST%\inc%_EXT%\vcl\pngread.hxx ..\inc\vcl\pngwrite.hxx %_DEST%\inc%_EXT%\vcl\pngwrite.hxx -..\inc\vcl\smartid.hxx %_DEST%\inc%_EXT%\vcl\smartid.hxx ..\inc\vcl\configsettings.hxx %_DEST%\inc%_EXT%\vcl\configsettings.hxx ..\inc\vcl\ImageListProvider.hxx %_DEST%\inc%_EXT%\vcl\ImageListProvider.hxx ..\inc\vcl\fontmanager.hxx %_DEST%\inc%_EXT%\vcl\fontmanager.hxx @@ -153,4 +149,8 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\ppdparser.hxx %_DEST%\inc%_EXT%\vcl\ppdparser.hxx ..\inc\vcl\helper.hxx %_DEST%\inc%_EXT%\vcl\helper.hxx ..\inc\vcl\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx -..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx
\ No newline at end of file +..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx +..\inc\vcl\arrange.hxx %_DEST%\inc%_EXT%\vcl\arrange.hxx +..\inc\vcl\wpropset.hxx %_DEST%\inc%_EXT%\vcl\wpropset.hxx +..\%__SRC%\misc\vcl.component %_DEST%\xml%_EXT%\vcl.component + diff --git a/vcl/qa/complex/memCheck/CheckMemoryUsage.java b/vcl/qa/complex/memCheck/CheckMemoryUsage.java index 9f8272240403..a089a1c99f54 100644 --- a/vcl/qa/complex/memCheck/CheckMemoryUsage.java +++ b/vcl/qa/complex/memCheck/CheckMemoryUsage.java @@ -32,19 +32,27 @@ import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.uno.UnoRuntime; import com.sun.star.util.XCloseable; -import complexlib.ComplexTestCase; +// import complexlib.ComplexTestCase; import helper.ProcessHandler; import java.io.File; -import java.io.FilePermission; +// import java.io.FilePermission; import java.io.FileWriter; import java.io.FilenameFilter; import java.io.PrintWriter; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; +import lib.*; import util.DesktopTools; -import util.WriterTools; -import util.utils; +// import util.WriterTools; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; /** * Documents are opened and exported with StarOffice. The memory usage of @@ -66,95 +74,141 @@ import util.utils; * All parameters are used for iteration over the test document path. * </ul> */ -public class CheckMemoryUsage extends ComplexTestCase { +class TempDir +{ + + private String m_sTempDir; + + public TempDir(String _sTempDir) + { + m_sTempDir = _sTempDir; + } + + public String getOfficeTempDir() + { + return m_sTempDir; + } + + public String getTempDir() + { + final String sTempDir = FileHelper.getJavaCompatibleFilename(m_sTempDir); + return sTempDir; + } +} + +public class CheckMemoryUsage /* extends ComplexTestCase */ + +{ + private final String sWriterDoc = "sxw,writer_pdf_Export"; private final String sCalcDoc = "sxc,calc_pdf_Export"; private final String sImpressDoc = "sxi,impress_pdf_Export"; - private String sProcessId = "ps -ef | grep $USER | grep soffice | grep -v grep"; - private String sMemoryMonitor = "pmap <processID> | grep total"; - private String sChmod = "chmod 777 "; - private String sProcessIdCommand = null; - private String sOfficeMemoryCommand = null; - private String sTempDir = null; - private String sFS = null; - private String sMemoryMap1 = null; - private String sMemoryMap2 = null; - private String bash = "#!/bin/bash"; - private String sDocumentPath = ""; + // private String sProcessIdCommand = null; + TempDir m_aTempDir; + // private String sFS = null; + // private String sMemoryMap1 = null; + // private String sMemoryMap2 = null; + // private String sDocumentPath = ""; private String[][] sDocTypeExportFilter; private String[][] sDocuments; private int iAllowMemoryIncrease = 10; private int iExportDocCount = 25; + /** + * The test parameters + */ + private static TestParameters param = null; /** * Get all test methods * @return The test methods. - */ - public String[] getTestMethodNames() { - return new String[] {"loadAndSaveDocuments"}; - } - + // */ +// public String[] getTestMethodNames() { +// return new String[] {"loadAndSaveDocuments"}; +// } /** * Collect all documnets to load and all filters used for export. */ - public void before() { + @Before + public void before() + { + + final XMultiServiceFactory xMsf = getMSF(); + + // some Tests need the qadevOOo TestParameters, it is like a Hashmap for Properties. + param = new TestParameters(); + param.put("ServiceFactory", xMsf); // some qadevOOo functions need the ServiceFactory + // test does definitely not run on Windows. - if (param.get("OperatingSystem").equals("wntmsci")) { - log.println("Test can only reasonably be executed with a tool that " - + "displays the memory usage of StarOffice."); - failed("Test does not run on Windows, only on Solaris or Linux."); + if (param.get("OperatingSystem").equals("wntmsci")) + { + System.out.println("Test can only reasonably be executed with a tool that " + + "displays the memory usage of StarOffice."); + System.out.println("Test does not run on Windows, only on Solaris or Linux."); + // in an automatic environment it is better to say, there is no error here. + // it is a limitation, but no error. + System.exit(0); } + // how many times is every document exported. int count = param.getInt("ExportDocCount"); if (count != 0) + { iExportDocCount = count; + } // get the temp dir for creating the command scripts. - sTempDir = System.getProperty("java.io.tmpdir"); - sProcessIdCommand = sTempDir + "getPS"; - sOfficeMemoryCommand = sTempDir + "getPmap"; + // sTempDir = System.getProperty("java.io.tmpdir"); + m_aTempDir = new TempDir(util.utils.getOfficeTemp/*Dir*/(xMsf)); // get the file extension, export filter connection Enumeration keys = param.keys(); - Vector v = new Vector(); - while(keys.hasMoreElements()) { - String key = (String)keys.nextElement(); - if (key.startsWith("FileExportFilter")) { - v.add(param.get(key)); + Vector<String> v = new Vector<String>(); + while (keys.hasMoreElements()) + { + String key = (String) keys.nextElement(); + if (key.startsWith("FileExportFilter")) + { + v.add((String) param.get(key)); } } // if no param given, set defaults. - if (v.size() == 0){ + if (v.size() == 0) + { v.add(sWriterDoc); v.add(sCalcDoc); v.add(sImpressDoc); } // store a file extension sDocTypeExportFilter = new String[v.size()][2]; - for (int i=0; i<v.size(); i++) { + for (int i = 0; i < v.size(); i++) + { // 2do: error routine for wrong given params - StringTokenizer t = new StringTokenizer((String)v.get(i), ","); - sDocTypeExportFilter[i][0] = t.nextToken(); - sDocTypeExportFilter[i][1] = t.nextToken(); + final String sVContent = v.get(i); + StringTokenizer t = new StringTokenizer(sVContent, ","); + final String sExt = t.nextToken(); + final String sName = t.nextToken(); + sDocTypeExportFilter[i][0] = sExt; + sDocTypeExportFilter[i][1] = sName; } // get files to load and export - sDocumentPath = (String)param.get("TestDocumentPath"); - File f = new File(sDocumentPath); - sDocumentPath = f.getAbsolutePath(); - String sFS = System.getProperty("file.separator"); +// sDocumentPath = (String) param.get("TestDocumentPath"); + String sDocumentPath = TestDocument.getUrl(); + File f = new File(FileHelper.getJavaCompatibleFilename(sDocumentPath)); + // sDocumentPath = f.getAbsolutePath(); + // String sFS = System.getProperty("file.separator"); sDocuments = new String[sDocTypeExportFilter.length][]; - for (int j=0; j<sDocTypeExportFilter.length; j++) { + for (int j = 0; j < sDocTypeExportFilter.length; j++) + { FileFilter filter = new FileFilter(sDocTypeExportFilter[j][0]); String[] doc = f.list(filter); sDocuments[j] = new String[doc.length]; - for (int i=0; i<doc.length; i++) { - if (sDocumentPath.endsWith(sFS)) - sDocuments[j][i] = sDocumentPath + doc[i]; - else - sDocuments[j][i] = sDocumentPath + sFS + doc[i]; - sDocuments[j][i] = utils.getFullURL(sDocuments[j][i]); + for (int i = 0; i < doc.length; i++) + { + // final String sDocument = FileHelper.appendPath(sDocumentPath, doc[i]); + // sDocuments[j][i] = utils.getFullURL(sDocuments[j][i]); + sDocuments[j][i] = TestDocument.getUrl(doc[i]); } } } @@ -162,141 +216,323 @@ public class CheckMemoryUsage extends ComplexTestCase { /** * delete all created files on disk */ - public void after() { + @After + public void after() + { // delete the constructed files. - for (int i=0; i<iExportDocCount; i++) { - File f = new File(sTempDir + "DocExport" + i + ".pdf"); - f.delete(); - } - File f = new File(sProcessIdCommand); - f.delete(); - f = new File(sOfficeMemoryCommand); - f.delete(); +// we don't need to delete anything, all is stored in $USER_TREE +// for (int i = 0; i < iExportDocCount; i++) +// { +// final String sDocumentName = "DocExport" + i + ".pdf"; +// final String sFilename = FileHelper.appendPath(m_sTempDir, sDocumentName); +// File f = new File(FileHelper.getJavaCompatibleFilename(sFilename)); +// f.delete(); +// } + // File f = new File(sProcessIdCommand); + // f.delete(); + // f = new File(sOfficeMemoryCommand); + // f.delete(); } /** - * Thet etst function: load documents and save them using the given filters + * The test function: load documents and save them using the given filters * for each given document type. */ - public void loadAndSaveDocuments() { - int storageBefore = getOfficeMemoryUsage(); + @Test + public void loadAndSaveDocuments() + { + int nOk = 0; + int nRunThrough = 0; - XMultiServiceFactory xMSF = (XMultiServiceFactory)param.getMSF(); + // At first: + // we load the document, there will be some post work in office like late initialisations + // we store exact one time the document + // so the memory footprint should be right // iterate over all document types - for (int k=0; k<sDocTypeExportFilter.length; k++) { + for (int k = 0; k < sDocTypeExportFilter.length; k++) + { // iterate over all documents of this type - for (int i=0; i<sDocuments[k].length; i++) { - System.out.println("Document: "+ sDocuments[k][i]); - XComponent xComponent = DesktopTools.loadDoc(xMSF, sDocuments[k][i], null); - XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xComponent); - if (xStorable != null) { - // export each document iExportDocCount times - for (int j=0; j<iExportDocCount; j++) { - String url = utils.getFullURL(sTempDir + "DocExport" + j + ".pdf"); - try { - PropertyValue[] props = new PropertyValue[1]; - props[0] = new PropertyValue(); - props[0].Name = "FilterName"; - // use export filter for this doc type - props[0].Value = sDocTypeExportFilter[k][1]; - xStorable.storeToURL(url, props); - } - catch(com.sun.star.io.IOException e) { - failed("Could not store to '" + url + "'", true); - } - } - // close the doc - XCloseable xCloseable = (XCloseable)UnoRuntime.queryInterface(XCloseable.class, xStorable); - try { - xCloseable.close(true); - } - catch(com.sun.star.util.CloseVetoException e) { - e.printStackTrace((java.io.PrintWriter)log); - failed("Cannot close document: test is futile, Office will surely use more space."); - } - } - else { - log.println("Cannot query for XStorable interface on document '" + sDocuments[i] + "'"); - log.println(" -> Skipping storage."); - } + for (int i = 0; i < sDocuments[k].length; i++) + { + + final String sDocument = sDocuments[k][i]; + final String sExtension = sDocTypeExportFilter[k][1]; + +// OfficeMemchecker aChecker = new OfficeMemchecker(); +// aChecker.setDocumentName(FileHelper.getBasename(sDocument)); +// aChecker.setExtension(sExtension); +// aChecker.start(); + + loadAndSaveNTimesDocument(sDocument, 1, sExtension); + +// nOk += checkMemory(aChecker); +// nRunThrough ++; } + System.out.println(); + System.out.println(); } - // short wait for the office to 'calm down' and free some memory - shortWait(5000); - // wait util memory is not freed anymore. - int storageAfter = getOfficeMemoryUsage(); - int mem = 0; - int count = 0; - while (storageAfter != mem && count < 10) { - count++; - mem = storageAfter; - storageAfter = getOfficeMemoryUsage(); - shortWait(1000); - } - assure("The Office consumes now " + (storageAfter - storageBefore) - + "K more memory than at the start of the test; allowed were " - + iAllowMemoryIncrease * iExportDocCount + "K.", - storageAfter - storageBefore < iAllowMemoryIncrease * iExportDocCount); + shortWait(10000); + + // Now the real test, load document and store 25 times + + // iterate over all document types + for (int k = 0; k < sDocTypeExportFilter.length; k++) + { + // iterate over all documents of this type + for (int i = 0; i < sDocuments[k].length; i++) + { + + final String sDocument = sDocuments[k][i]; + final String sExtension = sDocTypeExportFilter[k][1]; + + OfficeMemchecker aChecker = new OfficeMemchecker(); + aChecker.setDocumentName(FileHelper.getBasename(sDocument)); + aChecker.setExtension(sExtension); + aChecker.start(); + + loadAndSaveNTimesDocument(sDocument, iExportDocCount, sExtension); + + aChecker.stop(); + final int nConsumMore = aChecker.getConsumMore(); + + nOk += checkMemory(nConsumMore); + nRunThrough++; + } + System.out.println(); + System.out.println(); + } + System.out.println("Find the output of used 'pmap' here: " + m_aTempDir.getTempDir() + " if test failed."); + assertTrue("Office consumes too many memory.", nOk == nRunThrough); } /** - * Get the process ID from the Office - * @return the Id as String + * Checks how much memory should consum + * @param storageBefore + * @return 1 if consum is ok, else 0 */ - private String getOfficeProcessID() { - writeExecutableFile(sProcessIdCommand, sProcessId); - ProcessHandler processID = new ProcessHandler(sProcessIdCommand); - processID.executeSynchronously(); - String text = processID.getOutputText(); - if (text == null || text.equals("") || text.indexOf(' ') == -1) - failed("Could not determine Office process ID. Check " + sProcessIdCommand); - StringTokenizer aToken = new StringTokenizer(text); - // this is not nice, but ps gives the same output on every machine - aToken.nextToken(); - String id = aToken.nextToken(); - return id; + private int checkMemory(int nConsumMore) + { + int nAllowed = iAllowMemoryIncrease * iExportDocCount; + System.out.println("The Office consumes now " + nConsumMore + + "K more memory than at the start of the test; allowed were " + + nAllowed + "K."); + if (nConsumMore > nAllowed) + { + System.out.println("ERROR: This is not allowed."); + return 0; + } + System.out.println("OK."); + return 1; } /** - * Get the memory usage of the Office in KByte. - * @return The memory used by the Office. + * load and save exact one document */ - private int getOfficeMemoryUsage() { - String command = sMemoryMonitor.replaceAll("<processID>", getOfficeProcessID()); - writeExecutableFile(sOfficeMemoryCommand, command); - ProcessHandler processID = new ProcessHandler(sOfficeMemoryCommand); - processID.executeSynchronously(); - String text = processID.getOutputText(); - if (text == null || text.equals("") || text.indexOf(' ') == -1) { - failed("Could not determine Office memory usage. Check " + sOfficeMemoryCommand); + private void loadAndSaveNTimesDocument(String _sDocument, int _nCount, String _sStoreExtension) + { + System.out.println("Document: " + _sDocument); + XComponent xComponent = DesktopTools.loadDoc(getMSF(), _sDocument, null); + XStorable xStorable = UnoRuntime.queryInterface(XStorable.class, xComponent); + if (xStorable != null) + { + // export each document iExportDocCount times + for (int j = 0; j < _nCount; j++) + { + final String sDocumentName = FileHelper.getBasename(_sDocument) + "_" + j + ".pdf"; + final String sFilename = FileHelper.appendPath(m_aTempDir.getOfficeTempDir(), sDocumentName); + // String url = utils.getFullURL(sFilename); + String url = sFilename; // graphical.FileHelper.getFileURLFromSystemPath(sFilename); + try + { + PropertyValue[] props = new PropertyValue[1]; + props[0] = new PropertyValue(); + props[0].Name = "FilterName"; + // use export filter for this doc type + props[0].Value = _sStoreExtension; + xStorable.storeToURL(url, props); + } + catch (com.sun.star.io.IOException e) + { + fail("Could not store to '" + url + "'"); + } + } + // close the doc + XCloseable xCloseable = UnoRuntime.queryInterface(XCloseable.class, xStorable); + try + { + xCloseable.close(true); + } + catch (com.sun.star.util.CloseVetoException e) + { + e.printStackTrace(); + fail("Cannot close document: test is futile, Office will surely use more space."); + } + } + else + { + System.out.println("Cannot query for XStorable interface on document '" + _sDocument + "'"); + System.out.println(" -> Skipping storage."); } - StringTokenizer aToken = new StringTokenizer(text); - // this works, because the output of pmap is quite standardized. - aToken.nextToken(); - String mem = aToken.nextToken(); - mem = mem.substring(0, mem.indexOf('K')); - Integer memory = new Integer(mem); - return memory.intValue(); + } - /** - * Write a script file and set its rights to rwxrwxrwx. - * @param fileName The name of the created file - * @param line The commandline that has to be written inside of the file. - */ - private void writeExecutableFile(String fileName, String line) { - try { - PrintWriter fWriter = new PrintWriter(new FileWriter(fileName)); - fWriter.println(bash); - fWriter.println(line); - fWriter.close(); - // change rights to rwxrwxrwx - ProcessHandler processID = new ProcessHandler(sChmod + fileName); +// ----------------------------------------------------------------------------- + private class OfficeMemchecker + { + + /** + * After called start() it contains the memory need at startup + */ + private int m_nMemoryStart; + /** + * After called stop() it contains the memory usage + */ + private int m_nMemoryUsage; + private String m_sDocumentName; + private String m_sExtension; + + public OfficeMemchecker() + { + m_nMemoryStart = 0; + } + + public void setDocumentName(String _sDocName) + { + m_sDocumentName = _sDocName; + } + + public void setExtension(String _sExt) + { + m_sExtension = _sExt; + } + + public void start() + { + m_nMemoryStart = getOfficeMemoryUsage(createModeName("start", 0)); + } + + private String createModeName(String _sSub, int _nCount) + { + StringBuffer aBuf = new StringBuffer(); + aBuf.append(_sSub); + aBuf.append('_').append(m_sDocumentName).append('_').append(m_sExtension); + aBuf.append('_').append(_nCount); + return aBuf.toString(); + } + + public void stop() + { + // short wait for the office to 'calm down' and free some memory + shortWait(20000); + // wait util memory is not freed anymore. + int storageAfter = getOfficeMemoryUsage(createModeName("stop", 0)); + int mem = 0; + int count = 0; + while (storageAfter != mem && count < 10) + { + count++; + mem = storageAfter; + storageAfter = getOfficeMemoryUsage(createModeName("stop", count)); + shortWait(1000); + } + m_nMemoryUsage = (storageAfter - m_nMemoryStart); + } + + public int getConsumMore() + { + return m_nMemoryUsage; + } + + /** + * Get the process ID from the Office + * @return the Id as String + */ + private String getOfficeProcessID() + { + String sProcessIdCommand = FileHelper.appendPath(m_aTempDir.getTempDir(), "getPS"); + final String sofficeArg = org.openoffice.test.Argument.get("soffice"); + final String sPSGrep = "ps -ef | grep $USER | grep <soffice>.bin | grep -v grep"; + final String sProcessId = sPSGrep.replaceAll("<soffice>", FileHelper.getJavaCompatibleFilename(sofficeArg)); + + createExecutableFile(sProcessIdCommand, sProcessId); + ProcessHandler processID = new ProcessHandler(sProcessIdCommand); + processID.noOutput(); + processID.executeSynchronously(); + String text = processID.getOutputText(); + if (text == null || text.equals("") || text.indexOf(' ') == -1) + { + fail("Could not determine Office process ID. Check " + sProcessIdCommand); + } + StringTokenizer aToken = new StringTokenizer(text); + // this is not nice, but ps gives the same output on every machine + aToken.nextToken(); + String id = aToken.nextToken(); + return id; + } + + /** + * Get the memory usage of the Office in KByte. + * @return The memory used by the Office. + */ + private int getOfficeMemoryUsage(String _sMode) + { + final String sMemoryMonitor = "pmap <processID> |tee <pmapoutputfile> | grep total"; + String sOfficeMemoryCommand = null; + sOfficeMemoryCommand = FileHelper.appendPath(m_aTempDir.getTempDir(), "getPmap"); + // sOfficeMemoryCommand = FileHelper.getJavaCompatibleFilename(sOfficeMemoryCommand); + String command = sMemoryMonitor.replaceAll("<processID>", getOfficeProcessID()); + String sPmapOutputFile = FileHelper.appendPath(m_aTempDir.getTempDir(), "pmap_" + _sMode + ".txt"); + command = command.replaceAll("<pmapoutputfile>", sPmapOutputFile); + createExecutableFile(sOfficeMemoryCommand, command); + + ProcessHandler processID = new ProcessHandler(sOfficeMemoryCommand); + processID.noOutput(); processID.executeSynchronously(); + int nError = processID.getExitCode(); + assertTrue("Execute of " + sOfficeMemoryCommand + " failed", nError == 0); + String text = processID.getOutputText(); + if (text == null || text.equals("") || text.indexOf(' ') == -1) + { + fail("Could not determine Office memory usage. Check " + sOfficeMemoryCommand); + } + StringTokenizer aToken = new StringTokenizer(text); + // this works, because the output of pmap is quite standardized. + aToken.nextToken(); + String mem = aToken.nextToken(); + mem = mem.substring(0, mem.indexOf('K')); + Integer memory = new Integer(mem); + return memory.intValue(); } - catch(java.io.IOException e) { + + /** + * Write a script file and set its rights to rwxrwxrwx. + * @param fileName The name of the created file + * @param line The commandline that has to be written inside of the file. + */ + private void createExecutableFile(String fileName, String line) + { + final String sChmod = "chmod a+x "; + final String bash = "#!/bin/bash"; + + try + { + String sFilename = FileHelper.getJavaCompatibleFilename(fileName); + PrintWriter fWriter = new PrintWriter(new FileWriter(sFilename)); + fWriter.println(bash); + fWriter.println(line); + fWriter.close(); + // change rights to rwxrwxrwx + ProcessHandler processID = new ProcessHandler(sChmod + sFilename); + processID.noOutput(); + processID.executeSynchronously(); + int nError = processID.getExitCode(); + assertTrue("chmod failed. ", nError == 0); + } + catch (java.io.IOException e) + { + } } } @@ -304,11 +540,15 @@ public class CheckMemoryUsage extends ComplexTestCase { * Let this thread sleep for some time * @param milliSeconds time to wait in milliseconds. */ - private void shortWait(int milliSeconds) { - try { + public static void shortWait(int milliSeconds) + { + System.out.println("Wait for: " + milliSeconds + "ms"); + try + { Thread.sleep(milliSeconds); } - catch(java.lang.InterruptedException e) { // ignore + catch (java.lang.InterruptedException e) + { // ignore } } @@ -316,15 +556,20 @@ public class CheckMemoryUsage extends ComplexTestCase { * Own file filter, will just return ok for all files that end with a given * suffix */ - private class FileFilter implements FilenameFilter { + private class FileFilter implements FilenameFilter + { + private String suffix = null; + /** * C'tor. * @param suffix The suffix each filename should end with. */ - public FileFilter(String suffix) { + public FileFilter(String suffix) + { this.suffix = suffix; } + /** * Returns true, if the name of the file has the suffix given to the * c'tor. @@ -332,9 +577,32 @@ public class CheckMemoryUsage extends ComplexTestCase { * @param file Not used. * @return True, if name ends with suffix. */ - public boolean accept(File file, String name) { + public boolean accept(File file, String name) + { return name.endsWith(suffix); } - }; + } + + private XMultiServiceFactory getMSF() + { + final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager()); + return xMSF1; + } + // setup and close connections + @BeforeClass + public static void setUpConnection() throws Exception + { + System.out.println("setUpConnection()"); + connection.setUp(); + } + + @AfterClass + public static void tearDownConnection() + throws InterruptedException, com.sun.star.uno.Exception + { + System.out.println("tearDownConnection()"); + connection.tearDown(); + } + private static final OfficeConnection connection = new OfficeConnection(); } diff --git a/vcl/qa/complex/memCheck/FileHelper.java b/vcl/qa/complex/memCheck/FileHelper.java new file mode 100644 index 000000000000..21ce46185b4a --- /dev/null +++ b/vcl/qa/complex/memCheck/FileHelper.java @@ -0,0 +1,90 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +package complex.memCheck; + +import java.io.File; + +/** + * + * @author ll93751 + */ +public class FileHelper +{ + public static String appendPath(String _sPath, String _sRelativePathToAdd) + { + String sNewPath = _sPath; + String fs = System.getProperty("file.separator"); + if (_sPath.startsWith("file:")) + { + fs = "/"; // we use a file URL so only '/' is allowed. + } + if (! (sNewPath.endsWith("/") || sNewPath.endsWith("\\") ) ) + { + sNewPath += fs; + } + sNewPath += _sRelativePathToAdd; + return sNewPath; + } + public static String getJavaCompatibleFilename(String _sFilename) + { + // It is a little bit stupid that office urls not compatible to java file urls + // System.out.println("java.io.File can't access Office file urls."); + if(_sFilename.startsWith("path:")) + { + final String sPath = _sFilename.substring(5); + return sPath; + } + + String sSystemPath = graphical.FileHelper.getSystemPathFromFileURL(_sFilename); + if (sSystemPath == null) + { + sSystemPath = _sFilename; + } + return sSystemPath; + } + +public static String getBasename(String _sFilename) + { + if (_sFilename == null) + { + return ""; + } + // String fs = System.getProperty("file.separator"); + + int nIdx = _sFilename.lastIndexOf("\\"); + if (nIdx == -1) + { + nIdx = _sFilename.lastIndexOf("/"); + } + if (nIdx > 0) + { + return _sFilename.substring(nIdx + 1); + } + return _sFilename; + } +} diff --git a/vcl/qa/complex/memCheck/TestDocument.java b/vcl/qa/complex/memCheck/TestDocument.java new file mode 100644 index 000000000000..8ca9f7b71192 --- /dev/null +++ b/vcl/qa/complex/memCheck/TestDocument.java @@ -0,0 +1,45 @@ +/************************************************************************* +* +* 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. +* +************************************************************************/ + +package complex.memCheck; + +import java.io.File; +import org.openoffice.test.OfficeFileUrl; + +final class TestDocument +{ + final static String sPathname = "testdocuments"; + public static String getUrl(String name) + { + return OfficeFileUrl.getAbsolute(new File(sPathname, name)); + } + public static String getUrl() + { + return OfficeFileUrl.getAbsolute(new File(sPathname)); + } + private TestDocument() {} +} diff --git a/vcl/qa/complex/memCheck/makefile.mk b/vcl/qa/complex/memCheck/makefile.mk index d1d4b5c08c98..4a809e71e50e 100755 --- a/vcl/qa/complex/memCheck/makefile.mk +++ b/vcl/qa/complex/memCheck/makefile.mk @@ -25,65 +25,107 @@ # #************************************************************************* -PRJ = ..$/..$/.. -TARGET = MemoryCheck -PRJNAME = $(TARGET) -PACKAGE = complex$/memCheck - -# --- Settings ----------------------------------------------------- -.INCLUDE: settings.mk - - -#----- compile .java files ----------------------------------------- - -JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar -JAVAFILES = CheckMemoryUsage.java - -#----- make a jar from compiled files ------------------------------ - -MAXLINELENGTH = 100000 - -JARCLASSDIRS = $(PACKAGE) -JARTARGET = $(TARGET).jar -JARCOMPRESS = TRUE +.IF "$(OOO_SUBSEQUENT_TESTS)" == "" +nothing .PHONY: +.ELSE -# --- Parameters for the test -------------------------------------- +PRJ = ../../.. +PRJNAME = vcl +TARGET = qa_complex_memCheck -# start an office if the parameter is set for the makefile -.IF "$(OFFICE)" == "" -CT_APPEXECCOMMAND = -.ELSE -CT_APPEXECCOMMAND = -AppExecutionCommand \ - "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" -.ENDIF +.IF "$(OOO_JUNIT_JAR)" != "" +PACKAGE = complex/memCheck -# test base is java complex -CT_TESTBASE = -TestBase java_complex +# here store only Files which contain a @Test +JAVATESTFILES = \ + CheckMemoryUsage.java -# replace $/ with . in package name -CT_PACKAGE = -o $(PACKAGE:s\$/\.\) +# put here all other files +JAVAFILES = $(JAVATESTFILES) \ + FileHelper.java \ + TestDocument.java -# start the runner application -CT_APP = org.openoffice.Runner -# --- Targets ------------------------------------------------------ +JARFILES = OOoRunner.jar ridl.jar test.jar unoil.jar +EXTRAJARFILES = $(OOO_JUNIT_JAR) -.IF "$(depend)" == "" -$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR -.ELSE -$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR -.ENDIF +# Sample how to debug +# JAVAIFLAGS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=9003,suspend=y -.INCLUDE : target.mk +.END +.INCLUDE: settings.mk +.INCLUDE: target.mk +.INCLUDE: installationtest.mk +ALLTAR : javatest -$(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : CheckMemoryUsage.props - cp $(@:f) $@ - jar uf $(CLASSDIR)$/$(JARTARGET) -C $(CLASSDIR) $(PACKAGE)$/$(@:f) +.END -RUN: run -run: - java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_PACKAGE).CheckMemoryUsage +# +# +# +# PRJ = ..$/..$/.. +# TARGET = MemoryCheck +# PRJNAME = $(TARGET) +# PACKAGE = complex$/memCheck +# +# # --- Settings ----------------------------------------------------- +# .INCLUDE: settings.mk +# +# +# #----- compile .java files ----------------------------------------- +# +# JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar +# JAVAFILES = CheckMemoryUsage.java +# +# #----- make a jar from compiled files ------------------------------ +# +# MAXLINELENGTH = 100000 +# +# JARCLASSDIRS = $(PACKAGE) +# JARTARGET = $(TARGET).jar +# JARCOMPRESS = TRUE +# +# # --- Parameters for the test -------------------------------------- +# +# # start an office if the parameter is set for the makefile +# .IF "$(OFFICE)" == "" +# CT_APPEXECCOMMAND = +# .ELSE +# CT_APPEXECCOMMAND = -AppExecutionCommand \ +# "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" +# .ENDIF +# +# # test base is java complex +# CT_TESTBASE = -TestBase java_complex +# +# # replace $/ with . in package name +# CT_PACKAGE = -o $(PACKAGE:s\$/\.\) +# +# # start the runner application +# CT_APP = org.openoffice.Runner +# +# # --- Targets ------------------------------------------------------ +# +# .IF "$(depend)" == "" +# $(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR +# .ELSE +# $(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : ALLTAR +# .ENDIF +# +# .INCLUDE : target.mk +# +# +# +# $(CLASSDIR)$/$(PACKAGE)$/CheckMemoryUsage.props : CheckMemoryUsage.props +# cp $(@:f) $@ +# jar uf $(CLASSDIR)$/$(JARTARGET) -C $(CLASSDIR) $(PACKAGE)$/$(@:f) +# +# +# RUN: run +# +# run: +# java -cp $(CLASSPATH) $(CT_APP) $(CT_TESTBASE) $(CT_APPEXECCOMMAND) $(CT_PACKAGE).CheckMemoryUsage diff --git a/vcl/qa/testdocuments/CalcDoc.sxc b/vcl/qa/complex/memCheck/testdocuments/CalcDoc.sxc Binary files differindex 4b2b572085dc..4b2b572085dc 100755..100644 --- a/vcl/qa/testdocuments/CalcDoc.sxc +++ b/vcl/qa/complex/memCheck/testdocuments/CalcDoc.sxc diff --git a/vcl/qa/testdocuments/ImpressDoc.sxi b/vcl/qa/complex/memCheck/testdocuments/ImpressDoc.sxi Binary files differindex efcdf9b6a25e..efcdf9b6a25e 100755..100644 --- a/vcl/qa/testdocuments/ImpressDoc.sxi +++ b/vcl/qa/complex/memCheck/testdocuments/ImpressDoc.sxi diff --git a/vcl/qa/testdocuments/WriterDoc.sxw b/vcl/qa/complex/memCheck/testdocuments/WriterDoc.sxw Binary files differindex 1b2c2cb2dab6..1b2c2cb2dab6 100755..100644 --- a/vcl/qa/testdocuments/WriterDoc.sxw +++ b/vcl/qa/complex/memCheck/testdocuments/WriterDoc.sxw diff --git a/vcl/qa/complex/persistent_window_states/DocumentHandle.java b/vcl/qa/complex/persistent_window_states/DocumentHandle.java index 0b32eaaeff51..ea28c41f65f7 100644 --- a/vcl/qa/complex/persistent_window_states/DocumentHandle.java +++ b/vcl/qa/complex/persistent_window_states/DocumentHandle.java @@ -34,13 +34,9 @@ import com.sun.star.lang.XComponent; import com.sun.star.awt.XWindow; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.PropertyState; -import com.sun.star.frame.XController; -import com.sun.star.frame.FrameSearchFlag; -import com.sun.star.text.XTextDocument; import com.sun.star.uno.UnoRuntime; import com.sun.star.frame.XFrame; import com.sun.star.frame.FrameSearchFlag; -import com.sun.star.frame.XFramesSupplier; import helper.WindowListener; /** @@ -59,7 +55,7 @@ public class DocumentHandle { /** * Constructor - * @param xComponentLoader A loader to load a document + * @param xCompLoader A loader to load a document */ public DocumentHandle(XComponentLoader xCompLoader) { this.xCompLoader = xCompLoader; @@ -71,6 +67,7 @@ public class DocumentHandle { * @param docName The name of a document as file URL * @param hidden If true, the document is loaded hidden. * @return The size of the opened/created document. + * @throws Exception */ public Rectangle loadDocument(String docName, boolean hidden) throws Exception{ @@ -91,13 +88,13 @@ public class DocumentHandle { } // get the current active window - XFrame xCurFrame = (XFrame)UnoRuntime.queryInterface(XFrame.class, xCompLoader); + XFrame xCurFrame = UnoRuntime.queryInterface(XFrame.class, xCompLoader); // create a new frame XFrame xFrame = xCurFrame.findFrame("_blank", FrameSearchFlag.CREATE); // load document in this frame - XComponentLoader xFrameLoader = (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, xFrame); + XComponentLoader xFrameLoader = UnoRuntime.queryInterface(XComponentLoader.class, xFrame); xComp = xFrameLoader.loadComponentFromURL( docName, "_self", 0, szArgs); // wait for the document to load. diff --git a/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java index edceeeafd883..898324504b4e 100644 --- a/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java +++ b/vcl/qa/complex/persistent_window_states/PersistentWindowTest.java @@ -26,31 +26,27 @@ ************************************************************************/ package complex.persistent_window_states; - -import com.sun.star.lang.XServiceInfo; -import com.sun.star.lang.XInitialization; -import com.sun.star.uno.Type; import com.sun.star.uno.Any; -import com.sun.star.lang.XTypeProvider; -import com.sun.star.lang.XSingleServiceFactory; import com.sun.star.lang.XMultiServiceFactory; -import com.sun.star.lang.XComponent; -import com.sun.star.frame.XDesktop; import com.sun.star.frame.XFramesSupplier; import com.sun.star.frame.XFrames; -import com.sun.star.registry.XRegistryKey; -import com.sun.star.comp.loader.FactoryHelper; import com.sun.star.container.XIndexAccess; -import com.sun.star.beans.XPropertySet; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.AnyConverter; import com.sun.star.frame.XComponentLoader; import com.sun.star.awt.Rectangle; import com.sun.star.util.XCloseable; import helper.ConfigurationRead; -import complexlib.ComplexTestCase; -import helper.OfficeProvider; -import complex.persistent_window_states.DocumentHandle; + + + +// import org.junit.After; +import org.junit.AfterClass; +// import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openoffice.test.OfficeConnection; +import static org.junit.Assert.*; /** * Parameters: @@ -58,10 +54,11 @@ import complex.persistent_window_states.DocumentHandle; * <li>NoOffice=yes - StarOffice is not started initially.</li> * </ul> */ -public class PersistentWindowTest extends ComplexTestCase { +public class PersistentWindowTest +{ - private XMultiServiceFactory xMSF; - private OfficeProvider oProvider; + // private XMultiServiceFactory xMSF; +// private OfficeProvider oProvider; private int iOfficeCloseTime = 0; /** @@ -69,9 +66,18 @@ public class PersistentWindowTest extends ComplexTestCase { * Right now, it's only 'checkPersistentWindowState'. * @return All test methods. */ - public String[] getTestMethodNames() { - return new String[]{"checkPersistentWindowState"}; - } +// public String[] getTestMethodNames() +// { +// return new String[] +// { +// "checkPersistentWindowState" +// }; +// } + + /** + * The test parameters + */ + // private static TestParameters param = null; /** * Test if all available document types change the @@ -94,42 +100,32 @@ public class PersistentWindowTest extends ComplexTestCase { * - close office * - Test finished */ - public void checkPersistentWindowState() + @Test public void checkPersistentWindowState() { - try { - - log.println("Connect the first time."); - log.println("AppExecCommand: " + (String)param.get("AppExecutionCommand")); - log.println("ConnString: " + (String)param.get("ConnectionString")); - oProvider = new OfficeProvider(); - iOfficeCloseTime = param.getInt("OfficeCloseTime"); - if ( iOfficeCloseTime == 0 ) { - iOfficeCloseTime = 1000; - } + // final XMultiServiceFactory xMsf = getMSF(); - if (!connect()) return; + // some Tests need the qadevOOo TestParameters, it is like a Hashmap for Properties. +// param = new TestParameters(); +// param.put("ServiceFactory", xMsf); // some qadevOOo functions need the ServiceFactory - // create the configuration provider - Object o = null; - try { - o = xMSF.createInstance( - "com.sun.star.configuration.ConfigurationProvider"); - } - catch(com.sun.star.uno.Exception e) { - failed("Cannot create \"com.sun.star.configuration."+ - "ConfigurationProvider\""); - return; - } + try + { - // fetch the multi service factory for setup - XMultiServiceFactory xCP = (XMultiServiceFactory) - UnoRuntime.queryInterface(XMultiServiceFactory.class, o); + // At first we are already connected + // if (!connect()) + // { + // return; + // } - // create the configuration reader - ConfigurationRead cfgRead = new ConfigurationRead(xCP); + // fetch the multi service factory for setup + // XMultiServiceFactory xCP = getMSF(); + + // create the configuration reader + // ConfigurationRead cfgRead = new ConfigurationRead(xCP); - // just test the wrong ones, not all. - String [] els = new String[]{ + // just test the wrong ones, not all. + String[] els = new String[] + { "Office/Factories/com.sun.star.drawing.DrawingDocument", "Office/Factories/com.sun.star.formula.FormulaProperties", //"Office/Factories/com.sun.star.presentation.PresentationDocument", @@ -138,92 +134,98 @@ public class PersistentWindowTest extends ComplexTestCase { "Office/Factories/com.sun.star.text.TextDocument", "Office/Factories/com.sun.star.text.WebDocument", }; - // uncomment the following line for all doc types -// String [] els = cfgRead.getSubNodeNames("Office/Factories"); - - log.println("Found "+ els.length + " document types to test.\n"); - if (!disconnect()) return; - - // for all types - for(int i=0; i<els.length; i++) { - log.println("\tStart test for document type " + i + ": " + els[i]); - // exclude chart documents: cannot be created this way. - if ( els[i].indexOf("ChartDocument") != -1) { - log.println("Skipping chart document: cannot be create like this."); - continue; - } + // uncomment the following line for all doc types + // String [] els = cfgRead.getSubNodeNames("Office/Factories"); + + System.out.println("Found " + els.length + " document types to test.\n"); + disconnect(); + + // for all types + for (int i = 0; i < els.length; i++) + { + System.out.println("\tStart test for document type " + i + ": " + els[i]); + // exclude chart documents: cannot be created this way. + if (els[i].indexOf("ChartDocument") != -1) + { + System.out.println("Skipping chart document: cannot be create like this."); + continue; + } - // start an office - if (!connect()) return; + // start an office + connect(); - // get configuration - String[] settings = getConfigurationAndLoader(xMSF, els[i]); - if (settings == null) { - log.println("Skipping document type " + els[i]); - disconnect(); - continue; - } - String cfg = settings[1]; + // get configuration + String[] settings = getConfigurationAndLoader(getMSF(), els[i]); + if (settings == null) + { + System.out.println("Skipping document type " + els[i]); + disconnect(); + continue; + } + String cfg = settings[1]; - // load a document - DocumentHandle handle = loadDocument(xMSF, settings[0]); + // load a document + DocumentHandle handle = loadDocument(getMSF(), settings[0]); - // first size - Rectangle rect1 = handle.getDocumentPosSize(); + // first size + Rectangle rect1 = handle.getDocumentPosSize(); - // resize - handle.resizeDocument(); - // after resize - Rectangle rect2 = handle.getDocumentPosSize(); + // resize + handle.resizeDocument(); + // after resize + Rectangle rect2 = handle.getDocumentPosSize(); - // disposeManager and start a new office - if (!disconnect()) return; + // disposeManager and start a new office + disconnect(); - if (!connect()) return; + connect(); - // get configuration - settings = getConfigurationAndLoader(xMSF, els[i]); + // get configuration + settings = getConfigurationAndLoader(getMSF(), els[i]); - String newCfg = settings[1]; + String newCfg = settings[1]; - // load a document - handle = loadDocument(xMSF, settings[0]); + // load a document + handle = loadDocument(getMSF(), settings[0]); - Rectangle newRect = handle.getDocumentPosSize(); + Rectangle newRect = handle.getDocumentPosSize(); - // print the settings and window sizes - log.println("----------------------------"); - log.println("Initial Config String : " + cfg); - log.println("Config String after restart: " + newCfg); + // print the settings and window sizes + System.out.println("----------------------------"); + System.out.println("Initial Config String : " + cfg); + System.out.println("Config String after restart: " + newCfg); - log.println("----------------------------"); - log.println("Initial window (X,Y,Width,Height): " - +rect1.X+";"+rect1.Y+";"+ rect1.Width+";"+rect1.Height); - log.println("Window after resize (X,Y,Width,Height): " - +rect2.X+";"+rect2.Y+";"+ rect2.Width+";"+rect2.Height); - log.println("Window after restart (X,Y,Width,Height): " - +newRect.X+";"+newRect.Y+";"+newRect.Width+";" - +newRect.Height); + System.out.println("----------------------------"); + System.out.println("Initial window (X,Y,Width,Height): " + + rect1.X + ";" + rect1.Y + ";" + rect1.Width + ";" + rect1.Height); + System.out.println("Window after resize (X,Y,Width,Height): " + + rect2.X + ";" + rect2.Y + ";" + rect2.Width + ";" + rect2.Height); + System.out.println("Window after restart (X,Y,Width,Height): " + + newRect.X + ";" + newRect.Y + ";" + newRect.Width + ";" + + newRect.Height); - // compare to see if resize worked - log.println("----------------------------"); - assure("Resize values for "+ els[i] + - " are equal.", !compareRectangles(rect1, rect2), true); - // compare settings and sizes - assure("Config settings for "+ els[i] + - " were not changed.", !cfg.equals(newCfg), true); - assure("Resized and restarted window for "+ els[i] + - " are not equal.", compareRectangles(rect2, newRect), true); - log.println("----------------------------"); + // compare to see if resize worked + System.out.println("----------------------------"); + if (els[i].indexOf("SpreadsheetDocument") == -1 && + els[i].indexOf("DrawingDocument") == -1) + { + // leave out Spreadsheet- and DrawingDocumnt + assertTrue("Resize values for " + els[i] + " are equal.", !compareRectangles(rect1, rect2)); + } + // compare settings and sizes + assertTrue("Config settings for " + els[i] + " were not changed.", !cfg.equals(newCfg)); + assertTrue("Resized and restarted window for " + els[i] + " are not equal.", compareRectangles(rect2, newRect)); + System.out.println("----------------------------"); - // disposeManager - if (!disconnect()) return; + // disposeManager + disconnect(); - log.println("\tFinish test for document type " + i + ": " + els[i]); + System.out.println("\tFinish test for document type " + i + ": " + els[i]); + } } - } - catch(Exception e) { + catch (Exception e) + { e.printStackTrace(); } } @@ -235,16 +237,17 @@ public class PersistentWindowTest extends ComplexTestCase { * @return Settings and Loader */ private static String[] getConfigurationAndLoader(XMultiServiceFactory xMSF, - String cfgString) { + String cfgString) + { String[] conf = new String[2]; - try { + try + { Object o = xMSF.createInstance( - "com.sun.star.configuration.ConfigurationProvider"); + "com.sun.star.configuration.ConfigurationProvider"); // fetch the multi service factory for setup - XMultiServiceFactory xCP = (XMultiServiceFactory) - UnoRuntime.queryInterface(XMultiServiceFactory.class, o); + XMultiServiceFactory xCP = UnoRuntime.queryInterface(XMultiServiceFactory.class, o); // create the configuration reader ConfigurationRead cfgRead = new ConfigurationRead(xCP); @@ -253,22 +256,28 @@ public class PersistentWindowTest extends ComplexTestCase { String loader = getStringFromObject( cfgRead.getByHierarchicalName(cfgString + "/ooSetupFactoryEmptyDocumentURL")); - if (loader == null) return null; - log.println("\tLoader: " + loader); + if (loader == null) + { + return null; + } + System.out.println("\tLoader: " + loader); // read attributes String hierchName = cfgString + "/ooSetupFactoryWindowAttributes"; String setupSettings = getStringFromObject(cfgRead.getByHierarchicalName(hierchName)); // remove slots: just plain document types have to start - if ( loader.indexOf("?slot") != -1 ) { + if (loader.indexOf("?slot") != -1) + { loader = loader.substring(0, loader.indexOf("?slot")); - System.out.println("Loader: "+loader); + System.out.println("Loader: " + loader); } conf[0] = loader; conf[1] = setupSettings; } - catch(com.sun.star.uno.Exception e) {} + catch (com.sun.star.uno.Exception e) + { + } return conf; } @@ -279,97 +288,105 @@ public class PersistentWindowTest extends ComplexTestCase { * @return A handle to the document */ private DocumentHandle loadDocument(XMultiServiceFactory xMSF, - String docLoader) { + String docLoader) + { DocumentHandle docHandle = null; - try { + try + { // create component loaader - XComponentLoader xCompLoader = (XComponentLoader) - UnoRuntime.queryInterface( - XComponentLoader.class, xMSF.createInstance( - "com.sun.star.frame.Desktop")); - XFramesSupplier xFrameSupp = (XFramesSupplier)UnoRuntime.queryInterface(XFramesSupplier.class, xCompLoader); + XComponentLoader xCompLoader = UnoRuntime.queryInterface(XComponentLoader.class, xMSF.createInstance("com.sun.star.frame.Desktop")); + XFramesSupplier xFrameSupp = UnoRuntime.queryInterface(XFramesSupplier.class, xCompLoader); // close all existing frames XFrames xFrames = xFrameSupp.getFrames(); - XIndexAccess xAcc = (XIndexAccess)UnoRuntime.queryInterface(XIndexAccess.class, xFrames); - for ( int i=0; i<xAcc.getCount(); i++ ) { - XCloseable xClose = (XCloseable)UnoRuntime.queryInterface(XCloseable.class, xAcc.getByIndex(i)); - try { - if ( xClose != null ) { + XIndexAccess xAcc = UnoRuntime.queryInterface(XIndexAccess.class, xFrames); + for (int i = 0; i < xAcc.getCount(); i++) + { + XCloseable xClose = UnoRuntime.queryInterface(XCloseable.class, xAcc.getByIndex(i)); + try + { + if (xClose != null) + { xClose.close(false); } - else { - failed("Could not query frame for XCloseable!"); + else + { + fail("Could not query frame for XCloseable!"); } } - catch( com.sun.star.uno.Exception e ) { - e.printStackTrace((java.io.PrintWriter)log); - failed("Could not query frame for XCloseable!"); + catch (com.sun.star.uno.Exception e) + { + e.printStackTrace(); + fail("Could not query frame for XCloseable!"); } } docHandle = new DocumentHandle(xCompLoader); docHandle.loadDocument(docLoader, false); } - catch(com.sun.star.uno.Exception e) { + catch (com.sun.star.uno.Exception e) + { e.printStackTrace(); } - catch(java.lang.Exception e) { + catch (java.lang.Exception e) + { e.printStackTrace(); } return docHandle; } - private boolean connect() { - try { - xMSF = (XMultiServiceFactory)oProvider.getManager(param); - try { - Thread.sleep(10000); - } - catch(java.lang.InterruptedException e) {} + private boolean connect() + { + try + { + connection.setUp(); + } + catch (java.lang.InterruptedException e) + { + fail("can't connect."); } - catch (java.lang.Exception e) { - log.println(e.getClass().getName()); - log.println("Message: " + e.getMessage()); - failed("Cannot connect the Office."); - return false; + catch (Exception e) + { + fail("can't connect."); } return true; } - private boolean disconnect() { - try { - XDesktop desk = null; - desk = (XDesktop) UnoRuntime.queryInterface( - XDesktop.class, xMSF.createInstance( - "com.sun.star.frame.Desktop")); - xMSF = null; - desk.terminate(); - log.println("Waiting " + iOfficeCloseTime + " milliseconds for the Office to close down"); - try { - Thread.sleep(iOfficeCloseTime); - } - catch(java.lang.InterruptedException e) {} + private boolean disconnect() + { + try + { + connection.tearDown(); } - catch (java.lang.Exception e) { - e.printStackTrace(); - failed("Cannot dispose the Office."); - return false; + catch (java.lang.InterruptedException e) + { + fail("can't disconnect."); + } + catch (Exception e) + { + fail("can't disconnect."); } return true; } - private static String getStringFromObject(Object oName) { + private static String getStringFromObject(Object oName) + { if (oName instanceof String) - return (String)oName; + { + return (String) oName; + } String value = null; - if (oName instanceof Any) { - try { + if (oName instanceof Any) + { + try + { value = AnyConverter.toString(oName); - if (value == null) { - log.println("Got a void css.uno.Any as loading string."); + if (value == null) + { + System.out.println("Got a void css.uno.Any as loading string."); } } - catch(Exception e) { - log.println("This document type cannot be opened directly."); + catch (Exception e) + { + System.out.println("This document type cannot be opened directly."); } } return value; @@ -382,12 +399,37 @@ public class PersistentWindowTest extends ComplexTestCase { * @param rect2 Second Rectangle. * @return True, if the rectangles are equal. */ - private boolean compareRectangles(Rectangle rect1, Rectangle rect2) { + private boolean compareRectangles(Rectangle rect1, Rectangle rect2) + { boolean result = true; - result &= (rect1.X==rect2.X); - result &= (rect1.Y==rect2.Y); - result &= (rect1.Width==rect2.Width); - result &= (rect1.Height==rect2.Height); + result &= (rect1.X == rect2.X); + result &= (rect1.Y == rect2.Y); + result &= (rect1.Width == rect2.Width); + result &= (rect1.Height == rect2.Height); return result; } + + + + private XMultiServiceFactory getMSF() + { + final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager()); + return xMSF1; + } + + // setup and close connections + @BeforeClass public static void setUpConnection() throws Exception { + System.out.println("setUpConnection()"); + connection.setUp(); + } + + @AfterClass public static void tearDownConnection() + throws InterruptedException, com.sun.star.uno.Exception + { + System.out.println("tearDownConnection()"); + connection.tearDown(); + } + + private static final OfficeConnection connection = new OfficeConnection(); + } diff --git a/vcl/qa/complex/persistent_window_states/makefile.mk b/vcl/qa/complex/persistent_window_states/makefile.mk index 4c61d8969b8d..e4d9f6b514a0 100644 --- a/vcl/qa/complex/persistent_window_states/makefile.mk +++ b/vcl/qa/complex/persistent_window_states/makefile.mk @@ -24,58 +24,44 @@ # for a copy of the LGPLv3 License. # #************************************************************************* +.IF "$(OOO_SUBSEQUENT_TESTS)" == "" +nothing .PHONY: +.ELSE -PRJ = ..$/..$/.. -TARGET = PersistentWindowTest -PRJNAME = $(TARGET) -PACKAGE = complex$/persistent_window_states - -# --- Settings ----------------------------------------------------- -.INCLUDE: settings.mk +PRJ = ../../.. +PRJNAME = vcl +TARGET = qa_complex_persistent_window_states -#----- compile .java files ----------------------------------------- +.IF "$(OOO_JUNIT_JAR)" != "" +PACKAGE = complex/persistent_window_states -JARFILES = ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar -JAVAFILES = PersistentWindowTest.java DocumentHandle.java +# here store only Files which contain a @Test +JAVATESTFILES = \ + PersistentWindowTest.java -#----- make a jar from compiled files ------------------------------ +# put here all other files +JAVAFILES = $(JAVATESTFILES) \ +DocumentHandle.java -MAXLINELENGTH = 100000 -JARCLASSDIRS = $(PACKAGE) -JARTARGET = $(TARGET).jar -JARCOMPRESS = TRUE +JARFILES = OOoRunner.jar ridl.jar test.jar unoil.jar +EXTRAJARFILES = $(OOO_JUNIT_JAR) -# --- Parameters for the test -------------------------------------- +# Sample how to debug +# JAVAIFLAGS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=9003,suspend=y -# test base is java complex -CT_TESTBASE = -TestBase java_complex +.END -# test looks something like the.full.package.TestName -CT_TEST = -o $(PACKAGE:s\$/\.\).$(TARGET) +.INCLUDE: settings.mk +.INCLUDE: target.mk +.INCLUDE: installationtest.mk -# start the runner application -CT_APP = org.openoffice.Runner +ALLTAR : javatest -# --- Targets ------------------------------------------------------ +.END -$(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props : ALLTAR -.INCLUDE : target.mk -$(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props : $(TARGET).props - cp $(TARGET).props $@ - jar uf $(CLASSDIR)$/$(JARTARGET) -C $(CLASSDIR) $(PACKAGE)$/$(TARGET).props -RUN: run -# start an office if the parameter is set for the makefile -.IF "$(OFFICE)" == "" -run: - @echo "Execute this test with 'dmake run OFFICE=/system/path/to/office/program'." - @echo "The office will be started by the test with a socket connection on port 8100" -.ELSE -run: $(CLASSDIR)$/$(PACKAGE)$/$(TARGET).props - java -cp $(CLASSPATH) $(CT_APP) -AppExecutionCommand "$(OFFICE)$/soffice -accept=socket,host=localhost,port=8100;urp;" $(CT_TESTBASE) $(CT_TEST) -.ENDIF diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx index dd9a5b4a15ee..b48db1d6ee97 100644 --- a/vcl/source/app/dbggui.cxx +++ b/vcl/source/app/dbggui.cxx @@ -37,32 +37,33 @@ #include <cmath> #include <limits.h> -#include <vcl/svdata.hxx> -#include <svsys.h> +#include "vcl/svdata.hxx" +#include "svsys.h" #ifdef WNT #undef min #endif -#include <tools/debug.hxx> -#include <vcl/svdata.hxx> -#include <vcl/svapp.hxx> -#include <vcl/event.hxx> -#include <vcl/lstbox.hxx> -#include <vcl/button.hxx> -#include <vcl/edit.hxx> -#include <vcl/fixed.hxx> -#include <vcl/group.hxx> -#include <vcl/field.hxx> -#include <vcl/msgbox.hxx> -#include <vcl/wrkwin.hxx> -#include <vcl/sound.hxx> -#include <vcl/threadex.hxx> -#include <vcl/dbggui.hxx> -#include <com/sun/star/i18n/XCharacterClassification.hpp> - -#include <vcl/unohelp.hxx> -#include <vcl/unohelp2.hxx> -#include <vos/mutex.hxx> +#include "tools/debug.hxx" +#include "vcl/svdata.hxx" +#include "vcl/svapp.hxx" +#include "vcl/event.hxx" +#include "vcl/lstbox.hxx" +#include "vcl/button.hxx" +#include "vcl/edit.hxx" +#include "vcl/fixed.hxx" +#include "vcl/group.hxx" +#include "vcl/field.hxx" +#include "vcl/msgbox.hxx" +#include "vcl/wrkwin.hxx" +#include "vcl/sound.hxx" +#include "vcl/threadex.hxx" +#include "vcl/dbggui.hxx" +#include "com/sun/star/i18n/XCharacterClassification.hpp" + +#include "vcl/unohelp.hxx" +#include "vcl/unohelp2.hxx" +#include "vos/mutex.hxx" +#include "vcl/salinst.hxx" #include <map> #include <algorithm> @@ -1963,9 +1964,11 @@ void DbgPrintWindow( const char* pLine ) // ======================================================================= -#ifdef WNT -void ImplDbgTestSolarMutex(); -#endif +void ImplDbgTestSolarMutex() +{ + bool bCheck = ImplGetSVData()->mpDefInst->CheckYieldMutex(); + OSL_ENSURE( bCheck, "SolarMutex not locked" ); +} // ======================================================================= @@ -1973,9 +1976,7 @@ void DbgGUIInit() { DbgSetPrintMsgBox( DbgPrintMsgBox ); DbgSetPrintWindow( DbgPrintWindow ); -#ifdef WNT DbgSetTestSolarMutex( ImplDbgTestSolarMutex ); -#endif } // ----------------------------------------------------------------------- @@ -1984,9 +1985,7 @@ void DbgGUIDeInit() { DbgSetPrintMsgBox( NULL ); DbgSetPrintWindow( NULL ); -#ifdef WNT DbgSetTestSolarMutex( NULL ); -#endif DbgWindow* pDbgWindow = ImplGetSVData()->maWinData.mpDbgWin; if ( pDbgWindow ) diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx index ac1da931ba06..2c7ad2fa9c3e 100644 --- a/vcl/source/app/help.cxx +++ b/vcl/source/app/help.cxx @@ -62,12 +62,7 @@ Help::~Help() // ----------------------------------------------------------------------- -BOOL Help::Start( ULONG, const Window* ) -{ - return FALSE; -} - -void Help::OpenHelpAgent( ULONG ) +void Help::OpenHelpAgent( const rtl::OString& ) { } @@ -78,11 +73,9 @@ BOOL Help::Start( const XubString&, const Window* ) return FALSE; } -// ----------------------------------------------------------------------- - -XubString Help::GetHelpText( ULONG, const Window* ) +BOOL Help::SearchKeyword( const XubString& ) { - return ImplGetSVEmptyStr(); + return FALSE; } // ----------------------------------------------------------------------- @@ -444,7 +437,7 @@ void HelpTextWindow::Paint( const Rectangle& ) if ( IsNativeControlSupported( CTRL_TOOLTIP, PART_ENTIRE_CONTROL ) ) { // #i46472# workaround gcc3.3 temporary problem - Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( Point( 0, 0 ), GetOutputSizePixel() ); ImplControlValue aControlValue; bNativeOK = DrawNativeControl( CTRL_TOOLTIP, PART_ENTIRE_CONTROL, aCtrlRegion, 0, aControlValue, rtl::OUString() ); diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 9a2404d36740..73eaa8f965d2 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -38,7 +38,6 @@ #include <vcl/salbmp.hxx> #include <vcl/salobj.hxx> #include <vcl/salmenu.hxx> -#include <vcl/salctrlhandle.hxx> // this file contains the virtual destructors of the sal interface // compilers ususally put their vtables where the destructor is @@ -74,6 +73,29 @@ void SalInstance::FillFontPathList( std::list< rtl::OString >& ) // do nothing } +SalMenu* SalInstance::CreateMenu( BOOL, Menu* ) +{ + // default: no native menus + return NULL; +} + +void SalInstance::DestroyMenu( SalMenu* pMenu ) +{ + (void)pMenu; + OSL_ENSURE( pMenu == 0, "DestroyMenu called with non-native menus" ); +} + +SalMenuItem* SalInstance::CreateMenuItem( const SalItemParams* ) +{ + return NULL; +} + +void SalInstance::DestroyMenuItem( SalMenuItem* pItem ) +{ + (void)pItem; + OSL_ENSURE( pItem == 0, "DestroyMenu called with non-native menus" ); +} + SalTimer::~SalTimer() { } @@ -138,7 +160,4 @@ Rectangle SalMenu::GetMenuBarButtonRectPixel( USHORT, SalFrame* ) SalMenuItem::~SalMenuItem() { } -SalControlHandle::~SalControlHandle() -{ -} diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index 980e0f1c5b58..dbc792039f80 100755..100644 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -419,12 +419,11 @@ ImplStyleData::ImplStyleData() mnCursorBlinkTime = STYLE_CURSOR_NOBLINKTIME; mnScreenZoom = 100; mnScreenFontZoom = 100; - mnRadioButtonStyle = 0; - mnCheckBoxStyle = 0; - mnPushButtonStyle = 0; - mnTabControlStyle = 0; mnLogoDisplayTime = LOGO_DISPLAYTIME_STARTTIME; - mnDragFullOptions = 0; + mnDragFullOptions = DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE | + DRAGFULL_OPTION_OBJECTMOVE | DRAGFULL_OPTION_OBJECTSIZE | + DRAGFULL_OPTION_DOCKING | DRAGFULL_OPTION_SPLIT | + DRAGFULL_OPTION_SCROLL; mnAnimationOptions = 0; mnSelectionOptions = 0; mnDisplayOptions = 0; @@ -520,10 +519,6 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : mnCursorBlinkTime = rData.mnCursorBlinkTime; mnScreenZoom = rData.mnScreenZoom; mnScreenFontZoom = rData.mnScreenFontZoom; - mnRadioButtonStyle = rData.mnRadioButtonStyle; - mnCheckBoxStyle = rData.mnCheckBoxStyle; - mnPushButtonStyle = rData.mnPushButtonStyle; - mnTabControlStyle = rData.mnTabControlStyle; mnLogoDisplayTime = rData.mnLogoDisplayTime; mnDragFullOptions = rData.mnDragFullOptions; mnAnimationOptions = rData.mnAnimationOptions; @@ -614,12 +609,6 @@ void ImplStyleData::SetStandardStyles() maHighlightLinkColor = Color( COL_LIGHTBLUE ); maFontColor = Color( COL_BLACK ); - mnRadioButtonStyle &= ~STYLE_RADIOBUTTON_STYLE; - mnCheckBoxStyle &= ~STYLE_CHECKBOX_STYLE; - mnPushButtonStyle &= ~STYLE_PUSHBUTTON_STYLE; - mnTabControlStyle = 0; - - mnOptions &= ~(STYLE_OPTION_SYSTEMSTYLE | STDSYS_STYLE); mnBorderSize = 1; mnTitleHeight = 18; mnFloatTitleHeight = 13; @@ -871,34 +860,6 @@ void StyleSettings::SetStandardStyles() // ----------------------------------------------------------------------- -void StyleSettings::SetStandardWinStyles() -{ - return; // no more style changes since NWF -} - -// ----------------------------------------------------------------------- - -void StyleSettings::SetStandardOS2Styles() -{ - return; // no more style changes since NWF -} - -// ----------------------------------------------------------------------- - -void StyleSettings::SetStandardMacStyles() -{ - return; // no more style changes since NWF -} - -// ----------------------------------------------------------------------- - -void StyleSettings::SetStandardUnixStyles() -{ - return; // no more style changes since NWF -} - -// ----------------------------------------------------------------------- - Color StyleSettings::GetFaceGradientColor() const { // compute a brighter face color that can be used in gradients @@ -1033,14 +994,12 @@ BOOL StyleSettings::operator ==( const StyleSettings& rSet ) const (mpData->mnAntialiasedMin == rSet.mpData->mnAntialiasedMin) && (mpData->mnScreenZoom == rSet.mpData->mnScreenZoom) && (mpData->mnScreenFontZoom == rSet.mpData->mnScreenFontZoom) && - (mpData->mnRadioButtonStyle == rSet.mpData->mnRadioButtonStyle) && - (mpData->mnCheckBoxStyle == rSet.mpData->mnCheckBoxStyle) && - (mpData->mnPushButtonStyle == rSet.mpData->mnPushButtonStyle) && - (mpData->mnTabControlStyle == rSet.mpData->mnTabControlStyle) && (mpData->mnHighContrast == rSet.mpData->mnHighContrast) && (mpData->mnUseSystemUIFonts == rSet.mpData->mnUseSystemUIFonts) && (mpData->mnUseFlatBorders == rSet.mpData->mnUseFlatBorders) && (mpData->mnUseFlatMenues == rSet.mpData->mnUseFlatMenues) && + (mpData->mnSymbolsStyle == rSet.mpData->mnSymbolsStyle) && + (mpData->mnPreferredSymbolsStyle == rSet.mpData->mnPreferredSymbolsStyle) && (mpData->maFaceColor == rSet.mpData->maFaceColor) && (mpData->maCheckedColor == rSet.mpData->maCheckedColor) && (mpData->maLightColor == rSet.mpData->maLightColor) && diff --git a/vcl/source/app/sound.cxx b/vcl/source/app/sound.cxx index bac9d50dc5da..d180f2647135 100644 --- a/vcl/source/app/sound.cxx +++ b/vcl/source/app/sound.cxx @@ -38,6 +38,7 @@ #include <vcl/salframe.hxx> #include <tools/debug.hxx> #include <vcl/svdata.hxx> +#include <vcl/svapp.hxx> #include <vcl/window.hxx> #include <vcl/salbtype.hxx> #include <vcl/sound.hxx> @@ -45,6 +46,10 @@ void Sound::Beep( SoundType eType, Window* pWindow ) { + // #i91990# + if ( Application::IsHeadlessModeEnabled() ) + return; + if( !pWindow ) { Window* pDefWindow = ImplGetDefaultWindow(); diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index e503172eb2c6..dd1ea7c0469e 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -45,7 +45,6 @@ #include "vcl/event.hxx" #include "vcl/vclevent.hxx" #include "vcl/virdev.hxx" -#include "vcl/windata.hxx" #include "vcl/window.h" #include "vcl/wrkwin.hxx" #include "vcl/idlemgr.hxx" diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index f8b0d1d3379f..935d2c1894ea 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -27,47 +27,49 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" + #include <string.h> -#ifndef _SV_SVSYS_HXX -#include <svsys.h> -#endif -#include <vcl/salinst.hxx> -#include <vcl/salframe.hxx> - -#ifndef _VOS_MUTEX_HXX -#include <vos/mutex.hxx> -#endif - -#include <osl/process.h> -#include <osl/file.hxx> -#include <uno/current_context.hxx> -#include <cppuhelper/implbase1.hxx> -#include <tools/debug.hxx> -#include <unotools/fontcfg.hxx> -#include <vcl/configsettings.hxx> -#include <vcl/svdata.hxx> -#include <vcl/window.h> -#include <vcl/svapp.hxx> -#include <vcl/wrkwin.hxx> -#include <vcl/msgbox.hxx> -#include <vcl/unohelp.hxx> -#include <vcl/button.hxx> // for Button::GetStandardText -#include <vcl/dockwin.hxx> // for DockingManager -#include <vcl/salimestatus.hxx> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/awt/XExtendedToolkit.hpp> -#include <com/sun/star/java/JavaNotConfiguredException.hpp> -#include <com/sun/star/java/JavaVMCreationFailureException.hpp> -#include <com/sun/star/java/MissingJavaRuntimeException.hpp> -#include <com/sun/star/java/JavaDisabledException.hpp> - -#include <com/sun/star/lang/XComponent.hpp> +#include "rtl/instance.hxx" +#include "osl/process.h" +#include "osl/file.hxx" + +#include "svsys.h" + +#include "tools/debug.hxx" +#include "tools/resary.hxx" + +#include "vcl/salinst.hxx" +#include "vcl/salframe.hxx" +#include "vcl/configsettings.hxx" +#include "vcl/svdata.hxx" +#include "vcl/window.h" +#include "vcl/svapp.hxx" +#include "vcl/wrkwin.hxx" +#include "vcl/msgbox.hxx" +#include "vcl/unohelp.hxx" +#include "vcl/button.hxx" // for Button::GetStandardText +#include "vcl/dockwin.hxx" // for DockingManager +#include "vcl/salimestatus.hxx" +#include "vcl/salsys.hxx" +#include "vcl/svids.hrc" + +#include "unotools/fontcfg.hxx" + +#include "vos/mutex.hxx" + +#include "cppuhelper/implbase1.hxx" +#include "uno/current_context.hxx" + +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/lang/XComponent.hpp" +#include "com/sun/star/awt/XExtendedToolkit.hpp" +#include "com/sun/star/java/JavaNotConfiguredException.hpp" +#include "com/sun/star/java/JavaVMCreationFailureException.hpp" +#include "com/sun/star/java/MissingJavaRuntimeException.hpp" +#include "com/sun/star/java/JavaDisabledException.hpp" #include <stdio.h> -#include <vcl/salsys.hxx> -#include <vcl/svids.hrc> -#include <rtl/instance.hxx> using namespace com::sun::star::uno; using namespace com::sun::star::lang; @@ -112,7 +114,6 @@ void ImplInitSVData() // init global instance data memset( pImplSVData, 0, sizeof( ImplSVData ) ); pImplSVData->maHelpData.mbAutoHelpId = sal_True; - pImplSVData->maHelpData.mbAutoHelpId = sal_True; pImplSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT ); // find out whether we are running in the testtool @@ -128,6 +129,9 @@ void ImplInitSVData() break; } } + + // mark default layout border as unitialized + pImplSVData->maAppData.mnDefaultLayoutBorder = -1; } // ----------------------------------------------------------------------- @@ -163,6 +167,11 @@ void ImplDeInitSVData() delete pSVData->maAppData.mpMSFTempFileName; pSVData->maAppData.mpMSFTempFileName = NULL; } + + if( pSVData->maCtrlData.mpFieldUnitStrings ) + delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL; + if( pSVData->maCtrlData.mpCleanUnitStrings ) + delete pSVData->maCtrlData.mpCleanUnitStrings, pSVData->maCtrlData.mpCleanUnitStrings = NULL; } // ----------------------------------------------------------------------- @@ -240,6 +249,52 @@ ResId VclResId( sal_Int32 nId ) return ResId( nId, *pMgr ); } +FieldUnitStringList* ImplGetFieldUnits() +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->maCtrlData.mpFieldUnitStrings ) + { + ResMgr* pResMgr = ImplGetResMgr(); + if( pResMgr ) + { + ResStringArray aUnits( ResId (SV_FUNIT_STRINGS, *pResMgr) ); + sal_uInt32 nUnits = aUnits.Count(); + pSVData->maCtrlData.mpFieldUnitStrings = new FieldUnitStringList(); + pSVData->maCtrlData.mpFieldUnitStrings->reserve( nUnits ); + for( sal_uInt32 i = 0; i < nUnits; i++ ) + { + std::pair< String, FieldUnit > aElement( aUnits.GetString(i), static_cast<FieldUnit>(aUnits.GetValue(i)) ); + pSVData->maCtrlData.mpFieldUnitStrings->push_back( aElement ); + } + } + } + return pSVData->maCtrlData.mpFieldUnitStrings; +} + +FieldUnitStringList* ImplGetCleanedFieldUnits() +{ + ImplSVData* pSVData = ImplGetSVData(); + if( ! pSVData->maCtrlData.mpCleanUnitStrings ) + { + FieldUnitStringList* pUnits = ImplGetFieldUnits(); + if( pUnits ) + { + size_t nUnits = pUnits->size(); + pSVData->maCtrlData.mpCleanUnitStrings = new FieldUnitStringList(); + pSVData->maCtrlData.mpCleanUnitStrings->reserve( nUnits ); + for( size_t i = 0; i < nUnits; i++ ) + { + String aUnit( (*pUnits)[i].first ); + aUnit.EraseAllChars( sal_Unicode( ' ' ) ); + aUnit.ToLowerAscii(); + std::pair< String, FieldUnit > aElement( aUnit, (*pUnits)[i].second ); + pSVData->maCtrlData.mpCleanUnitStrings->push_back( aElement ); + } + } + } + return pSVData->maCtrlData.mpCleanUnitStrings; +} + DockingManager* ImplGetDockingManager() { ImplSVData* pSVData = ImplGetSVData(); diff --git a/vcl/source/components/factory.cxx b/vcl/source/components/factory.cxx index 6bed493cacde..7cfdecbfdb00 100644 --- a/vcl/source/components/factory.cxx +++ b/vcl/source/components/factory.cxx @@ -62,6 +62,10 @@ extern Sequence< OUString > SAL_CALL FontIdentificator_getSupportedServiceNames( extern OUString SAL_CALL FontIdentificator_getImplementationName(); extern Reference< XInterface > SAL_CALL FontIdentificator_createInstance( const Reference< XMultiServiceFactory > & ); +extern Sequence< OUString > SAL_CALL StringMirror_getSupportedServiceNames(); +extern OUString SAL_CALL StringMirror_getImplementationName(); +extern Reference< XInterface > SAL_CALL StringMirror_createInstance( const Reference< XMultiServiceFactory > & ); + extern Sequence< OUString > SAL_CALL Clipboard_getSupportedServiceNames(); extern OUString SAL_CALL Clipboard_getImplementationName(); extern Reference< XSingleServiceFactory > SAL_CALL Clipboard_createFactory( const Reference< XMultiServiceFactory > & ); @@ -84,62 +88,6 @@ extern "C" { *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; } - VCL_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pXUnoKey ) - { - if( pXUnoKey ) - { - try - { - Reference< ::com::sun::star::registry::XRegistryKey > xKey( reinterpret_cast< ::com::sun::star::registry::XRegistryKey* >( pXUnoKey ) ); - - OUStringBuffer aImplName(64); - aImplName.appendAscii( "/" ); - aImplName.append( vcl_session_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl_session_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - - aImplName.appendAscii( "/" ); - aImplName.append( vcl::DisplayAccess_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl::DisplayAccess_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - - aImplName.appendAscii( "/" ); - aImplName.append( vcl::FontIdentificator_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl::FontIdentificator_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - - #if defined UNX - aImplName.appendAscii( "/" ); - aImplName.append( vcl::Clipboard_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl::Clipboard_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - - aImplName.appendAscii( "/" ); - aImplName.append( vcl::DragSource_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl::DragSource_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - - aImplName.appendAscii( "/" ); - aImplName.append( vcl::DropTarget_getImplementationName() ); - aImplName.appendAscii( "/UNO/SERVICES/" ); - aImplName.append( vcl::DropTarget_getSupportedServiceNames()[0] ); - xKey->createKey( aImplName.makeStringAndClear() ); - #endif - - return sal_True; - } - catch( ::com::sun::star::registry::InvalidRegistryException& ) - { - } - } - return sal_False; - } - VCL_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* pImplementationName, void* pXUnoSMgr, @@ -172,6 +120,12 @@ extern "C" { xMgr, vcl::FontIdentificator_getImplementationName(), vcl::FontIdentificator_createInstance, vcl::FontIdentificator_getSupportedServiceNames() ); } + else if( vcl::StringMirror_getImplementationName().equalsAscii( pImplementationName ) ) + { + xFactory = ::cppu::createSingleFactory( + xMgr, vcl::StringMirror_getImplementationName(), vcl::StringMirror_createInstance, + vcl::StringMirror_getSupportedServiceNames() ); + } else if( vcl::Clipboard_getImplementationName().equalsAscii( pImplementationName ) ) { xFactory = vcl::Clipboard_createFactory( xMgr ); diff --git a/vcl/source/components/makefile.mk b/vcl/source/components/makefile.mk index e30975dbc099..982687104c01 100644 --- a/vcl/source/components/makefile.mk +++ b/vcl/source/components/makefile.mk @@ -39,9 +39,10 @@ ENABLE_EXCEPTIONS=TRUE # --- Files -------------------------------------------------------- -SLOFILES= $(SLO)$/display.obj \ - $(SLO)$/dtranscomp.obj \ - $(SLO)$/fontident.obj \ +SLOFILES= $(SLO)$/display.obj \ + $(SLO)$/dtranscomp.obj \ + $(SLO)$/fontident.obj \ + $(SLO)$/stringmirror.obj \ $(SLO)$/factory.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/components/stringmirror.cxx b/vcl/source/components/stringmirror.cxx new file mode 100644 index 000000000000..78806914a7c4 --- /dev/null +++ b/vcl/source/components/stringmirror.cxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/util/XStringMapping.hpp" + +#include "cppuhelper/implbase2.hxx" +#include "rtl/ustrbuf.hxx" +#include "vcl/svapp.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; + +// ----------------------------------------------------------------------- + +namespace vcl +{ + +class StringMirror : public ::cppu::WeakAggImplHelper2< XStringMapping, XServiceInfo > +{ +public: + StringMirror() + {} + + virtual ~StringMirror() + {} + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const OUString& ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + // XStringMapping + virtual sal_Bool SAL_CALL mapStrings( Sequence< OUString >& io_rStrings ) throw (RuntimeException) + { + sal_Int32 nItems = io_rStrings.getLength(); + for( sal_Int32 n = 0; n < nItems; n++ ) + { + rtl::OUString& rStr( io_rStrings.getArray()[n] ); + + sal_Int32 nLen = rStr.getLength(); + rtl::OUStringBuffer aMirror( nLen ); + for(sal_Int32 i = nLen - 1; i >= 0; i--) + { + sal_Unicode cChar = rStr[ i ]; + aMirror.append(sal_Unicode(GetMirroredChar(cChar))); + } + rStr = aMirror.makeStringAndClear(); + } + return sal_True; + } +}; + +Sequence< OUString > StringMirror_getSupportedServiceNames() +{ + static OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.StringMirror" ) ); + static Sequence< OUString > aServiceNames( &aServiceName, 1 ); + return aServiceNames; +} + +OUString StringMirror_getImplementationName() +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "vcl::StringMirror" ) ); +} + +Reference< XInterface > SAL_CALL StringMirror_createInstance( const Reference< XMultiServiceFactory >& ) +{ + return static_cast< ::cppu::OWeakObject * >( new StringMirror ); +} + + +// XServiceInfo +OUString SAL_CALL StringMirror::getImplementationName() throw (RuntimeException) +{ + return StringMirror_getImplementationName(); +} + +sal_Bool SAL_CALL StringMirror::supportsService( const OUString& i_rServiceName ) throw (RuntimeException) +{ + Sequence< OUString > aSN( StringMirror_getSupportedServiceNames() ); + for( sal_Int32 nService = 0; nService < aSN.getLength(); nService++ ) + { + if( aSN[nService] == i_rServiceName ) + return sal_True; + } + return sal_False; +} + +Sequence< OUString > SAL_CALL StringMirror::getSupportedServiceNames() throw (RuntimeException) +{ + return StringMirror_getSupportedServiceNames(); +} + +} // namespace vcl diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index 08759f37d7a6..82bec2214dff 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -83,6 +83,7 @@ class ImplCommonButtonData { public: Rectangle maFocusRect; + Rectangle maSymbolRect; USHORT mnButtonState; BOOL mbSmallSymbol; @@ -334,6 +335,18 @@ const Rectangle& Button::GetFocusRect() const // ----------------------------------------------------------------------- +const Rectangle& Button::ImplGetSymbolRect() const +{ + return mpButtonData->maSymbolRect; +} + +void Button::ImplSetSymbolRect( const Rectangle& i_rRect ) +{ + mpButtonData->maSymbolRect = i_rRect; +} + +// ----------------------------------------------------------------------- + USHORT Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle, ULONG nDrawFlags ) { @@ -756,47 +769,6 @@ BOOL Button::IsTextDisplayEnabled() } // ----------------------------------------------------------------------- -void Button::DataChanged( const DataChangedEvent& rDCEvt ) -{ - Control::DataChanged( rDCEvt ); - - // The flag SETTINGS_IN_UPDATE_SETTINGS is set when the settings changed due to a - // Application::SettingsChanged event. In this scenario we want to keep the style settings - // of our radio buttons and our check boxes. - if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && - ( rDCEvt.GetFlags() & SETTINGS_IN_UPDATE_SETTINGS ) ) - - { - const AllSettings* pOldSettings = rDCEvt.GetOldSettings(); - if ( pOldSettings ) - { - BOOL bResetStyleSettings = FALSE; - AllSettings aAllSettings = GetSettings(); - StyleSettings aStyleSetting = aAllSettings.GetStyleSettings(); - - USHORT nCheckBoxStyle = aStyleSetting.GetCheckBoxStyle(); - if ( nCheckBoxStyle != pOldSettings->GetStyleSettings().GetCheckBoxStyle() ) - { - aStyleSetting.SetCheckBoxStyle( pOldSettings->GetStyleSettings().GetCheckBoxStyle() ); - bResetStyleSettings = TRUE; - } - - USHORT nRadioButtonStyle = aStyleSetting.GetRadioButtonStyle(); - if ( nRadioButtonStyle != pOldSettings->GetStyleSettings().GetRadioButtonStyle() ) - { - aStyleSetting.SetRadioButtonStyle( pOldSettings->GetStyleSettings().GetRadioButtonStyle() ); - bResetStyleSettings = TRUE; - } - - if ( bResetStyleSettings ) - { - aAllSettings.SetStyleSettings( pOldSettings->GetStyleSettings() ); - SetSettings( aAllSettings ); - } - } - } -} - void Button::SetSmallSymbol (bool small) { ImplSetSmallSymbol (small); @@ -883,7 +855,8 @@ void PushButton::ImplInitSettings( BOOL bFont, // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled() // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP // for radio and checkbox this is ok as they shoud appear transparent in documents - if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) ) + if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) || + (GetStyle() & WB_FLATBUTTON) != 0 ) { EnableChildTransparentMode( TRUE ); SetParentClipMode( PARENTCLIPMODE_NOCLIP ); @@ -911,125 +884,6 @@ void PushButton::ImplDrawPushButtonFrame( Window* pDev, StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings(); if ( pDev->IsControlBackground() ) aStyleSettings.Set3DColors( pDev->GetControlBackground() ); - - USHORT nPushButtonSysStyle = aStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE; - if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC ) - { - pDev->SetLineColor(); - pDev->SetFillColor( aStyleSettings.GetFaceColor() ); - pDev->DrawRect( rRect ); - - if ( (aStyleSettings.GetOptions() & STYLE_OPTION_MONO) || - (pDev->GetOutDevType() == OUTDEV_PRINTER) ) - nStyle |= BUTTON_DRAW_MONO; - - if ( nStyle & BUTTON_DRAW_DEFAULT ) - { - if ( nStyle & BUTTON_DRAW_MONO ) - pDev->SetLineColor( Color( COL_BLACK ) ); - else - pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() ); - - pDev->DrawLine( Point( rRect.Left()+3, rRect.Top() ), - Point( rRect.Right()-3, rRect.Top() ) ); - pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom() ), - Point( rRect.Right()-3, rRect.Bottom() ) ); - pDev->DrawLine( Point( rRect.Left(), rRect.Top()+3 ), - Point( rRect.Left(), rRect.Bottom()-3 ) ); - pDev->DrawLine( Point( rRect.Right(), rRect.Top()+3 ), - Point( rRect.Right(), rRect.Bottom()-3 ) ); - pDev->DrawPixel( Point( rRect.Left()+2, rRect.Top()+1 ) ); - pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+2 ) ); - pDev->DrawPixel( Point( rRect.Right()-2, rRect.Top()+1 ) ); - pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+2 ) ); - pDev->DrawPixel( Point( rRect.Left()+2, rRect.Bottom()-1 ) ); - pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-1 ) ); - pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-2 ) ); - - if ( nStyle & BUTTON_DRAW_MONO ) - pDev->SetLineColor( Color( COL_BLACK ) ); - else - pDev->SetLineColor( aStyleSettings.GetShadowColor() ); - pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom()-1 ), - Point( rRect.Right()-3, rRect.Bottom()-1 ) ); - pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+3 ), - Point( rRect.Right()-1, rRect.Bottom()-3 ) ); - pDev->DrawPixel( Point( rRect.Right()-3, rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-3 ) ); - } - - rRect.Left() += 2; - rRect.Top() += 2; - rRect.Right() -= 2; - rRect.Bottom() -= 2; - - if ( nStyle & BUTTON_DRAW_MONO ) - pDev->SetLineColor( Color( COL_BLACK ) ); - else - pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() ); - - pDev->DrawLine( Point( rRect.Left()+2, rRect.Top() ), - Point( rRect.Right()-2, rRect.Top() ) ); - pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom() ), - Point( rRect.Right()-2, rRect.Bottom() ) ); - pDev->DrawLine( Point( rRect.Left(), rRect.Top()+2 ), - Point( rRect.Left(), rRect.Bottom()-2 ) ); - pDev->DrawLine( Point( rRect.Right(), rRect.Top()+2 ), - Point( rRect.Right(), rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+1 ) ); - pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+1 ) ); - pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-1 ) ); - pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-1 ) ); - - pDev->SetLineColor(); - if ( nStyle & BUTTON_DRAW_CHECKED ) - pDev->SetFillColor( aStyleSettings.GetCheckedColor() ); - else - pDev->SetFillColor( aStyleSettings.GetFaceColor() ); - pDev->DrawRect( Rectangle( rRect.Left()+2, rRect.Top()+2, rRect.Right()-2, rRect.Bottom()-2 ) ); - - if ( !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) ) - { - if ( nStyle & BUTTON_DRAW_MONO ) - pDev->SetLineColor( Color( COL_BLACK ) ); - else - pDev->SetLineColor( aStyleSettings.GetShadowColor() ); - pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom()-1 ), - Point( rRect.Right()-2, rRect.Bottom()-1 ) ); - pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+2 ), - Point( rRect.Right()-1, rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) ); - pDev->SetLineColor( aStyleSettings.GetLightColor() ); - } - else - pDev->SetLineColor( aStyleSettings.GetShadowColor() ); - - if ( !(nStyle & BUTTON_DRAW_MONO) ) - { - pDev->DrawLine( Point( rRect.Left()+2, rRect.Top()+1 ), - Point( rRect.Right()-2, rRect.Top()+1 ) ); - pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()+2 ), - Point( rRect.Left()+1, rRect.Bottom()-2 ) ); - pDev->DrawPixel( Point( rRect.Top()+2, rRect.Right()+2 ) ); - } - - rRect.Left() += 2; - rRect.Top() += 2; - rRect.Right() -= 2; - rRect.Bottom() -= 2; - - if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) ) - { - rRect.Left()++; - rRect.Top()++; - rRect.Right()++; - rRect.Bottom()++; - } - - return; - } } DecorationView aDecoView( pDev ); @@ -1056,20 +910,6 @@ BOOL PushButton::ImplHitTestPushButton( Window* pDev, Point aTempPoint; Rectangle aTestRect( aTempPoint, pDev->GetOutputSizePixel() ); - if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) ) - { - const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings(); - - USHORT nPushButtonSysStyle = rStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE; - if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC ) - { - aTestRect.Left() += 2; - aTestRect.Top() += 2; - aTestRect.Right() -= 2; - aTestRect.Bottom() -= 2; - } - } - return aTestRect.IsInside( rPos ); } @@ -1142,7 +982,9 @@ static void ImplDrawBtnDropDownArrow( OutputDevice* pDev, void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags, const Rectangle& rRect, - bool bLayout ) + bool bLayout, + bool bMenuBtnSep + ) { const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); Rectangle aInRect = rRect; @@ -1176,6 +1018,9 @@ void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags Size aSize = rRect.GetSize(); Point aPos = rRect.TopLeft(); + ULONG nImageSep = 1 + (pDev->GetTextHeight()-10)/2; + if( nImageSep < 1 ) + nImageSep = 1; if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON ) { if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) @@ -1186,33 +1031,41 @@ void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags aInRect.Left() = aInRect.Right() - nSymbolSize; aSize.Width() -= ( 5 + nSymbolSize ); - ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, - 1, nDrawFlags, nTextStyle ); + ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, + nDrawFlags, nTextStyle, NULL, true ); } else ImplCalcSymbolRect( aInRect ); if( ! bLayout ) { + long nDistance = (aInRect.GetHeight() > 10) ? 2 : 1; DecorationView aDecoView( pDev ); + if( bMenuBtnSep ) + { + long nX = aInRect.Left() - 2*nDistance;; + Point aStartPt( nX, aInRect.Top()+nDistance ); + Point aEndPt( nX, aInRect.Bottom()-nDistance ); + aDecoView.DrawSeparator( aStartPt, aEndPt ); + } aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle ); + aInRect.Left() -= 2*nDistance; + ImplSetSymbolRect( aInRect ); } } else { Rectangle aSymbolRect; - ULONG nImageSep = 1 + (pDev->GetTextHeight()-10)/2; - if( nImageSep < 1 ) - nImageSep = 1; // FIXME: (GetStyle() & WB_FLATBUTTON) != 0 is preliminary // in the next major this should be replaced by "true" ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, nDrawFlags, - nTextStyle, IsSymbol() ? &aSymbolRect : NULL, (GetStyle() & WB_FLATBUTTON) != 0 ); + nTextStyle, IsSymbol() ? &aSymbolRect : NULL, true ); if ( IsSymbol() && ! bLayout ) { DecorationView aDecoView( pDev ); aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle ); + ImplSetSymbolRect( aSymbolRect ); } if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout ) @@ -1314,7 +1167,6 @@ void PushButton::ImplDrawPushButton( bool bLayout ) // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN ImplControlValue aControlValue; - Region aCtrlRegion( aInRect ); ControlState nState = 0; if ( mbPressed ) nState |= CTRL_STATE_PRESSED; @@ -1326,7 +1178,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) ) nState |= CTRL_STATE_ROLLOVER; - bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aCtrlRegion, nState, + bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState, aControlValue, rtl::OUString() ); } } @@ -1336,12 +1188,16 @@ void PushButton::ImplDrawPushButton( bool bLayout ) return; bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() )); + bool bDrawMenuSep = true; + if( (GetStyle() & WB_FLATBUTTON) ) + { + if( ! bRollOver && ! HasFocus() ) + bDrawMenuSep = false; + } if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE ) { - PushButtonValue aPBVal; - ImplControlValue aControlValue; - aControlValue.setOptionalVal( &aPBVal ); - Region aCtrlRegion( aInRect ); + PushButtonValue aControlValue; + Rectangle aCtrlRegion( aInRect ); ControlState nState = 0; if ( mbPressed || IsChecked() ) nState |= CTRL_STATE_PRESSED; @@ -1354,7 +1210,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) nState |= CTRL_STATE_ROLLOVER; if( GetStyle() & WB_BEVELBUTTON ) - aPBVal.mbBevelButton = true; + aControlValue.mbBevelButton = true; // draw frame into invisible window to have aInRect modified correctly // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED) @@ -1373,7 +1229,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() ); aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) ); Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); - aPBVal.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); + aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) ) { @@ -1388,7 +1244,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) // draw content using the same aInRect as non-native VCL would do ImplDrawPushButtonContent( this, (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0, - aInRect, bLayout ); + aInRect, bLayout, bDrawMenuSep ); if ( HasFocus() ) ShowFocus( ImplGetFocusRect() ); @@ -1414,7 +1270,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) } // draw content - ImplDrawPushButtonContent( this, 0, aInRect, bLayout ); + ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep ); if( ! bLayout && HasFocus() ) { @@ -1434,22 +1290,19 @@ void PushButton::ImplSetDefButton( BOOL bSet ) if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE ) { - Region aBoundingRgn, aContentRgn; + Rectangle aBound, aCont; Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating // will not work if the theme has dynamic adornment sizes ImplControlValue aControlValue; - Region aCtrlRegion( aCtrlRect ); + Rectangle aCtrlRegion( aCtrlRect ); ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; // get native size of a 'default' button // and adjust the VCL button if more space for adornment is required if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, aControlValue, rtl::OUString(), - aBoundingRgn, aContentRgn ) ) + aBound, aCont ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - Rectangle aBound(aBoundingRgn.GetBoundRect()); - dLeft = aCont.Left() - aBound.Left(); dTop = aCont.Top() - aBound.Top(); dRight = aBound.Right() - aCont.Right(); @@ -1738,7 +1591,7 @@ void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, nButtonStyle |= BUTTON_DRAW_CHECKED; aRect = aDecoView.DrawButton( aRect, nButtonStyle ); - ImplDrawPushButtonContent( pDev, nFlags, aRect, false ); + ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true ); pDev->Pop(); } @@ -2004,6 +1857,8 @@ Size PushButton::CalcMinimumSize( long nMaxWidth ) const aSize = Size( 16, 12 ); else aSize = Size( 26, 24 ); + if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON ) + aSize.Width() += 4; } else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) aSize = GetModeImage().GetSizePixel(); @@ -2334,9 +2189,8 @@ void RadioButton::ImplDrawRadioButtonState() // no native drawing for image radio buttons if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == TRUE ) { - ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 ); + ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); Rectangle aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() ); - Region aCtrlRegion( aCtrlRect ); ControlState nState = 0; if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; @@ -2347,7 +2201,7 @@ void RadioButton::ImplDrawRadioButtonState() if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) ) nState |= CTRL_STATE_ROLLOVER; - bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, + bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState, aControlValue,rtl::OUString() ); } @@ -3198,17 +3052,16 @@ Size RadioButton::ImplGetRadioImageSize() const { ImplControlValue aControlValue; // #i45896# workaround gcc3.3 temporary problem - Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); + Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; - Region aBoundingRgn, aContentRgn; + Rectangle aBoundingRgn, aContentRgn; // get native size of a radio button if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - aSize = aCont.GetSize(); + aSize = aContentRgn.GetSize(); bDefaultSize = false; } } @@ -3247,7 +3100,7 @@ Image RadioButton::GetRadioImage( const AllSettings& rSettings, USHORT nFlags ) { ImplSVData* pSVData = ImplGetSVData(); const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); - USHORT nStyle = rStyleSettings.GetRadioButtonStyle() & STYLE_RADIOBUTTON_STYLE; + USHORT nStyle = 0; if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) nStyle = STYLE_RADIOBUTTON_MONO; @@ -3323,16 +3176,15 @@ void RadioButton::ImplSetMinimumNWFSize() ImplControlValue aControlValue; Size aCurSize( GetSizePixel() ); - Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) ); - Region aBoundingRgn, aContentRgn; + Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); + Rectangle aBoundingRgn, aContentRgn; // get native size of a radiobutton if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - Size aSize = aCont.GetSize(); + Size aSize = aContentRgn.GetSize(); if( aSize.Height() > aCurSize.Height() ) { @@ -3509,8 +3361,8 @@ void CheckBox::ImplDrawCheckBoxState() if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == TRUE ) { - ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 ); - Region aCtrlRegion( maStateRect ); + ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); + Rectangle aCtrlRegion( maStateRect ); ControlState nState = 0; if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; @@ -3688,11 +3540,14 @@ void CheckBox::ImplCheck() else eNewState = STATE_NOCHECK; meState = eNewState; - ImplInvalidateOrDrawCheckBoxState(); ImplDelData aDelData; ImplAddDel( &aDelData ); - Toggle(); + if( (GetStyle() & WB_EARLYTOGGLE) ) + Toggle(); + ImplInvalidateOrDrawCheckBoxState(); + if( ! (GetStyle() & WB_EARLYTOGGLE) ) + Toggle(); if ( aDelData.IsDelete() ) return; ImplRemoveDel( &aDelData ); @@ -4141,17 +3996,16 @@ Size CheckBox::ImplGetCheckImageSize() const { ImplControlValue aControlValue; // #i45896# workaround gcc3.3 temporary problem - Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); + Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; - Region aBoundingRgn, aContentRgn; + Rectangle aBoundingRgn, aContentRgn; // get native size of a check box if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - aSize = aCont.GetSize(); + aSize = aContentRgn.GetSize(); bDefaultSize = false; } } @@ -4164,7 +4018,7 @@ Image CheckBox::GetCheckImage( const AllSettings& rSettings, USHORT nFlags ) { ImplSVData* pSVData = ImplGetSVData(); const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); - USHORT nStyle = rStyleSettings.GetCheckBoxStyle() & STYLE_CHECKBOX_STYLE; + USHORT nStyle = 0; if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) nStyle = STYLE_CHECKBOX_MONO; @@ -4231,16 +4085,15 @@ void CheckBox::ImplSetMinimumNWFSize() ImplControlValue aControlValue; Size aCurSize( GetSizePixel() ); - Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) ); - Region aBoundingRgn, aContentRgn; + Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); + Rectangle aBoundingRgn, aContentRgn; // get native size of a radiobutton if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - Size aSize = aCont.GetSize(); + Size aSize = aContentRgn.GetSize(); if( aSize.Height() > aCurSize.Height() ) { @@ -4441,8 +4294,8 @@ void DisclosureButton::ImplDrawCheckBoxState() Rectangle aStateRect( GetStateRect() ); - ImplControlValue aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 ); - Region aCtrlRegion( aStateRect ); + ImplControlValue aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); + Rectangle aCtrlRegion( aStateRect ); ControlState nState = 0; if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx index f5c04b7c3cfa..5b2e8755e5c8 100644 --- a/vcl/source/control/combobox.cxx +++ b/vcl/source/control/combobox.cxx @@ -139,8 +139,8 @@ void ComboBox::ImplCalcEditHeight() if ( !IsDropDownBox() ) mnDDHeight += 4; - Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 10, 10 ) ) ); - Region aBoundRegion, aContentRegion; + Rectangle aCtrlRegion( Point( 0, 0 ), Size( 10, 10 ) ); + Rectangle aBoundRegion, aContentRegion; ImplControlValue aControlValue; ControlType aType = IsDropDownBox() ? CTRL_COMBOBOX : CTRL_EDITBOX; if( GetNativeControlRegion( aType, PART_ENTIRE_CONTROL, @@ -149,7 +149,7 @@ void ComboBox::ImplCalcEditHeight() aControlValue, rtl::OUString(), aBoundRegion, aContentRegion ) ) { - const long nNCHeight = aBoundRegion.GetBoundRect().GetHeight(); + const long nNCHeight = aBoundRegion.GetHeight(); if( mnDDHeight < nNCHeight ) mnDDHeight = sal::static_int_cast<USHORT>( nNCHeight ); } @@ -629,10 +629,10 @@ void ComboBox::Resize() Window *pBorder = GetWindow( WINDOW_BORDER ); ImplControlValue aControlValue; Point aPoint; - Region aContent, aBound; + Rectangle aContent, aBound; // use the full extent of the control - Region aArea( Rectangle(aPoint, pBorder->GetOutputSizePixel()) ); + Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); if ( GetNativeControlRegion(CTRL_COMBOBOX, PART_BUTTON_DOWN, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) @@ -641,7 +641,7 @@ void ComboBox::Resize() aPoint = pBorder->ScreenToOutputPixel( OutputToScreenPixel( aPoint ) ); aContent.Move(-aPoint.X(), -aPoint.Y()); - mpBtn->SetPosSizePixel( aContent.GetBoundRect().Left(), nTop, aContent.GetBoundRect().getWidth(), (nBottom-nTop) ); + mpBtn->SetPosSizePixel( aContent.Left(), nTop, aContent.getWidth(), (nBottom-nTop) ); // adjust the size of the edit field if ( GetNativeControlRegion(CTRL_COMBOBOX, PART_SUB_EDIT, @@ -651,13 +651,12 @@ void ComboBox::Resize() aContent.Move(-aPoint.X(), -aPoint.Y()); // use the themes drop down size - Rectangle aContentRect = aContent.GetBoundRect(); - mpSubEdit->SetPosSizePixel( aContentRect.TopLeft(), aContentRect.GetSize() ); + mpSubEdit->SetPosSizePixel( aContent.TopLeft(), aContent.GetSize() ); } else { // use the themes drop down size for the button - aOutSz.Width() -= aContent.GetBoundRect().getWidth(); + aOutSz.Width() -= aContent.getWidth(); mpSubEdit->SetSizePixel( aOutSz ); } } @@ -1011,6 +1010,14 @@ void ComboBox::Clear() mpImplLB->Clear(); CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED, (void*) sal_IntPtr(-1) ); } +// ----------------------------------------------------------------------- + +Image ComboBox::GetEntryImage( USHORT nPos ) const +{ + if ( mpImplLB->GetEntryList()->HasEntryImage( nPos ) ) + return mpImplLB->GetEntryList()->GetEntryImage( nPos ); + return Image(); +} // ----------------------------------------------------------------------- diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx index 0a29a627b8e3..5091a4722845 100644..100755 --- a/vcl/source/control/edit.cxx +++ b/vcl/source/control/edit.cxx @@ -122,6 +122,7 @@ struct DDInfo BOOL bStarterOfDD; BOOL bDroppedInMe; BOOL bVisCursor; + BOOL bIsStringSupported; DDInfo() { @@ -130,6 +131,7 @@ struct DDInfo bStarterOfDD = FALSE; bDroppedInMe = FALSE; bVisCursor = FALSE; + bIsStringSupported = FALSE; } }; @@ -1799,6 +1801,9 @@ BOOL Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt ) } break; + /* #i101255# disable autocomplete tab forward/backward + users expect tab/shif-tab to move the focus to other controls + not suddenly to cycle the autocompletion case KEY_TAB: { if ( !mbReadOnly && maAutocompleteHdl.IsSet() && @@ -1820,6 +1825,7 @@ BOOL Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt ) } } break; + */ default: { @@ -2842,7 +2848,7 @@ Size Edit::CalcMinimumSize() const Size aMinSize ( CalcSize( 3 ) ); if( aSize.Width() < aMinSize.Width() ) aSize.Width() = aMinSize.Width(); - // add some space between text entry an border + // add some space between text entry and border aSize.Height() += 4; aSize = CalcWindowSize( aSize ); @@ -2850,18 +2856,25 @@ Size Edit::CalcMinimumSize() const // ask NWF what if it has an opinion, too ImplControlValue aControlValue; Rectangle aRect( Point( 0, 0 ), aSize ); - Region aContent, aBound; + Rectangle aContent, aBound; if( const_cast<Edit*>(this)->GetNativeControlRegion( CTRL_EDITBOX, PART_ENTIRE_CONTROL, aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { - Rectangle aBoundRect( aContent.GetBoundRect() ); - if( aBoundRect.GetHeight() > aSize.Height() ) - aSize.Height() = aBoundRect.GetHeight(); + if( aBound.GetHeight() > aSize.Height() ) + aSize.Height() = aBound.GetHeight(); } return aSize; } +Size Edit::GetMinimumEditSize() +{ + Window* pDefWin = ImplGetDefaultWindow(); + Edit aEdit( pDefWin, WB_BORDER ); + Size aSize( aEdit.CalcMinimumSize() ); + return aSize; +} + // ----------------------------------------------------------------------- Size Edit::GetOptimalSize(WindowSizeType eType) const @@ -3055,17 +3068,26 @@ void Edit::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent& rDTDE.Context->dropComplete( bChanges ); } -void Edit::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& ) throw (::com::sun::star::uno::RuntimeException) +void Edit::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent& rDTDE ) throw (::com::sun::star::uno::RuntimeException) { if ( !mpDDInfo ) { mpDDInfo = new DDInfo; } -// sal_Bool bTextContent = mbReadOnly ? sal_False : sal_True; // quiery from rDTDEE.SupportedDataFlavors() -// if ( bTextContent ) -// rDTDEE.Context->acceptDrop(datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE); -// else -// rDTDEE.Context->rejectDrop(); + // search for string data type + const Sequence< com::sun::star::datatransfer::DataFlavor >& rFlavors( rDTDE.SupportedDataFlavors ); + sal_Int32 nEle = rFlavors.getLength(); + mpDDInfo->bIsStringSupported = FALSE; + for( sal_Int32 i = 0; i < nEle; i++ ) + { + sal_Int32 nIndex = 0; + rtl::OUString aMimetype = rFlavors[i].MimeType.getToken( 0, ';', nIndex ); + if( aMimetype.equalsAscii( "text/plain" ) ) + { + mpDDInfo->bIsStringSupported = TRUE; + break; + } + } } void Edit::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent& ) throw (::com::sun::star::uno::RuntimeException) @@ -3097,7 +3119,7 @@ void Edit::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEv aSel.Justify(); // Don't accept drop in selection or read-only field... - if ( IsReadOnly() || aSel.IsInside( mpDDInfo->nDropPos ) ) + if ( IsReadOnly() || aSel.IsInside( mpDDInfo->nDropPos ) || ! mpDDInfo->bIsStringSupported ) { ImplHideDDCursor(); rDTDE.Context->rejectDrag(); diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx index 090aa2a84163..4c4e3c870429 100644 --- a/vcl/source/control/field.cxx +++ b/vcl/source/control/field.cxx @@ -52,8 +52,6 @@ using namespace ::com::sun::star; -static ResStringArray *strAllUnits = NULL; - // ----------------------------------------------------------------------- #define FORMAT_NUMERIC 1 @@ -224,6 +222,42 @@ static BOOL ImplNumericGetValue( const XubString& rStr, double& rValue, return TRUE; } +static void ImplUpdateSeparatorString( String& io_rText, + const String& rOldDecSep, const String& rNewDecSep, + const String& rOldThSep, const String& rNewThSep ) +{ + rtl::OUStringBuffer aBuf( io_rText.Len() ); + xub_StrLen nIndexDec = 0, nIndexTh = 0, nIndex = 0; + + const sal_Unicode* pBuffer = io_rText.GetBuffer(); + while( nIndex != STRING_NOTFOUND ) + { + nIndexDec = io_rText.Search( rOldDecSep, nIndex ); + nIndexTh = io_rText.Search( rOldThSep, nIndex ); + if( (nIndexTh != STRING_NOTFOUND && nIndexDec != STRING_NOTFOUND && nIndexTh < nIndexDec ) + || (nIndexTh != STRING_NOTFOUND && nIndexDec == STRING_NOTFOUND) + ) + { + aBuf.append( pBuffer + nIndex, nIndexTh - nIndex ); + aBuf.append( rNewThSep ); + nIndex = nIndexTh + rOldThSep.Len(); + } + else if( nIndexDec != STRING_NOTFOUND ) + { + aBuf.append( pBuffer + nIndex, nIndexDec - nIndex ); + aBuf.append( rNewDecSep ); + nIndex = nIndexDec + rOldDecSep.Len(); + } + else + { + aBuf.append( pBuffer + nIndex ); + nIndex = STRING_NOTFOUND; + } + } + + io_rText = aBuf.makeStringAndClear(); +} + static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDecSep, const String& rOldThSep, const String& rNewThSep, Edit* pEdit ) @@ -236,10 +270,7 @@ static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDe BOOL bUpdateMode = pEdit->IsUpdateMode(); pEdit->SetUpdateMode( FALSE ); String aText = pEdit->GetText(); - if( bChangeDec ) - aText.SearchAndReplaceAll( rNewDecSep, rOldDecSep ); - if( bChangeTh ) - aText.SearchAndReplaceAll( rNewThSep, rOldThSep ); + ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep ); pEdit->SetText( aText ); ComboBox* pCombo = dynamic_cast<ComboBox*>(pEdit); @@ -250,12 +281,11 @@ static void ImplUpdateSeparators( const String& rOldDecSep, const String& rNewDe for ( USHORT i=0; i < nEntryCount; i++ ) { aText = pCombo->GetEntry( i ); - if( bChangeDec ) - aText.SearchAndReplaceAll( rNewDecSep, rOldDecSep ); - if( bChangeTh ) - aText.SearchAndReplaceAll( rNewThSep, rOldThSep ); + void* pEntryData = pCombo->GetEntryData( i ); + ImplUpdateSeparatorString( aText, rOldDecSep, rNewDecSep, rOldThSep, rNewThSep ); pCombo->RemoveEntry( i ); pCombo->InsertEntry( aText, i ); + pCombo->SetEntryData( i, pEntryData ); } } if( bUpdateMode ) @@ -1099,34 +1129,37 @@ static XubString ImplMetricGetUnitText( const XubString& rStr ) // #104355# support localized mesaurements -static String ImplMetricToString( FieldUnit rUnit ) +static const String& ImplMetricToString( FieldUnit rUnit ) { - if( !strAllUnits ) + FieldUnitStringList* pList = ImplGetFieldUnits(); + if( pList ) { - ResMgr* pResMgr = ImplGetResMgr(); - strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) ); + // return unit's default string (ie, the first one ) + for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) + { + if ( it->second == rUnit ) + return it->first; + } } - // return unit's default string (ie, the first one ) - for( USHORT i=0; i < strAllUnits->Count(); i++ ) - if( (FieldUnit) strAllUnits->GetValue( i ) == rUnit ) - return strAllUnits->GetString( i ); - return String(); + return String::EmptyString(); } static FieldUnit ImplStringToMetric( const String &rMetricString ) { - if( !strAllUnits ) + FieldUnitStringList* pList = ImplGetCleanedFieldUnits(); + if( pList ) { - ResMgr* pResMgr = ImplGetResMgr(); - strAllUnits = new ResStringArray( ResId (SV_FUNIT_STRINGS, *pResMgr) ); + // return FieldUnit + String aStr( rMetricString ); + aStr.ToLowerAscii(); + aStr.EraseAllChars( sal_Unicode( ' ' ) ); + for( FieldUnitStringList::const_iterator it = pList->begin(); it != pList->end(); ++it ) + { + if ( it->first.Equals( aStr ) ) + return it->second; + } } - // return FieldUnit - String aStr( rMetricString ); - aStr.ToLowerAscii(); - for( USHORT i=0; i < strAllUnits->Count(); i++ ) - if ( strAllUnits->GetString( i ).Equals( aStr ) ) - return (FieldUnit) strAllUnits->GetValue( i ); return FUNIT_NONE; } diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx index 37406293d7cf..f73cf008a5e5 100644 --- a/vcl/source/control/fixed.cxx +++ b/vcl/source/control/fixed.cxx @@ -27,13 +27,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <vcl/decoview.hxx> -#include <vcl/event.hxx> -#include <vcl/fixed.hxx> -#include <vcl/controldata.hxx> -#include <vcl/window.h> +#include "vcl/decoview.hxx" +#include "vcl/event.hxx" +#include "vcl/fixed.hxx" +#include "vcl/controldata.hxx" +#include "vcl/window.h" -#include <tools/rc.h> +#include "tools/rc.h" // ======================================================================= @@ -501,7 +501,7 @@ void FixedLine::ImplDraw( bool bLayout ) String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; DecorationView aDecoView( this ); - if ( !aText.Len() || (nWinStyle & WB_VERT) ) + if ( !aText.Len() ) { if( !pVector ) { @@ -520,11 +520,34 @@ void FixedLine::ImplDraw( bool bLayout ) } } } + else if( (nWinStyle & WB_VERT) ) + { + long nWidth = GetTextWidth( aText ); + Push( PUSH_FONT ); + Font aFont( GetFont() ); + aFont.SetOrientation( 900 ); + SetFont( aFont ); + Point aStartPt( aOutSize.Width()/2, aOutSize.Height()-1 ); + if( (nWinStyle & WB_VCENTER) ) + aStartPt.Y() -= (aOutSize.Height() - nWidth)/2; + Point aTextPt( aStartPt ); + aTextPt.X() -= GetTextHeight()/2; + DrawText( aTextPt, aText, 0, STRING_LEN, pVector, pDisplayText ); + Pop(); + if( aOutSize.Height() - aStartPt.Y() > FIXEDLINE_TEXT_BORDER ) + aDecoView.DrawSeparator( Point( aStartPt.X(), aOutSize.Height()-1 ), + Point( aStartPt.X(), aStartPt.Y() + FIXEDLINE_TEXT_BORDER ) ); + if( aStartPt.Y() - nWidth - FIXEDLINE_TEXT_BORDER > 0 ) + aDecoView.DrawSeparator( Point( aStartPt.X(), aStartPt.Y() - nWidth - FIXEDLINE_TEXT_BORDER ), + Point( aStartPt.X(), 0 ) ); + } else { USHORT nStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS; Rectangle aRect( 0, 0, aOutSize.Width(), aOutSize.Height() ); const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + if( (nWinStyle & WB_CENTER) ) + nStyle |= TEXT_DRAW_CENTER; if ( !IsEnabled() ) nStyle |= TEXT_DRAW_DISABLE; @@ -539,6 +562,8 @@ void FixedLine::ImplDraw( bool bLayout ) { long nTop = aRect.Top() + ((aRect.GetHeight()-1)/2); aDecoView.DrawSeparator( Point( aRect.Right()+FIXEDLINE_TEXT_BORDER, nTop ), Point( aOutSize.Width()-1, nTop ), false ); + if( aRect.Left() > FIXEDLINE_TEXT_BORDER ) + aDecoView.DrawSeparator( Point( 0, nTop ), Point( aRect.Left()-FIXEDLINE_TEXT_BORDER, nTop ), false ); } } } diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx index ebccfdc1e6bb..bd0179ffe454 100644 --- a/vcl/source/control/ilstbox.cxx +++ b/vcl/source/control/ilstbox.cxx @@ -529,7 +529,8 @@ USHORT ImplEntryList::FindFirstSelectable( USHORT nPos, bool bForward /* = true // ======================================================================= ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) : - Control( pParent, 0 ) + Control( pParent, 0 ), + maQuickSelectionEngine( *this ) { mpEntryList = new ImplEntryList( this ); @@ -568,9 +569,6 @@ ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) : SetTextFillColor(); SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); - maSearchTimeout.SetTimeout( 2500 ); - maSearchTimeout.SetTimeoutHdl( LINK( this, ImplListBoxWindow, SearchStringTimeout ) ); - ImplInitSettings( TRUE, TRUE, TRUE ); ImplCalcMetrics(); } @@ -579,7 +577,6 @@ ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) : ImplListBoxWindow::~ImplListBoxWindow() { - maSearchTimeout.Stop(); delete mpEntryList; } @@ -624,14 +621,6 @@ void ImplListBoxWindow::ImplCalcMetrics() // ----------------------------------------------------------------------- -IMPL_LINK( ImplListBoxWindow, SearchStringTimeout, Timer*, EMPTYARG ) -{ - maSearchStr.Erase(); - return 1; -} - -// ----------------------------------------------------------------------- - void ImplListBoxWindow::Clear() { mpEntryList->Clear(); @@ -648,6 +637,7 @@ void ImplListBoxWindow::Clear() ImplClearLayoutData(); mnCurrentPos = LISTBOX_ENTRY_NOTFOUND; + maQuickSelectionEngine.Reset(); Invalidate(); } @@ -918,7 +908,7 @@ USHORT ImplListBoxWindow::GetLastVisibleEntry() const void ImplListBoxWindow::MouseButtonDown( const MouseEvent& rMEvt ) { mbMouseMoveSelect = FALSE; // Nur bis zum ersten MouseButtonDown - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); if ( !IsReadOnly() ) { @@ -1465,7 +1455,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1492,7 +1482,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1523,7 +1513,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) } bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1557,7 +1547,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) } bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1578,7 +1568,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) bDone = TRUE; } } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1604,7 +1594,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) } bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1615,7 +1605,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) ScrollHorz( -HORZ_SCROLL ); bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1626,7 +1616,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) ScrollHorz( HORZ_SCROLL ); bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1638,7 +1628,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) ImplCallSelect(); bDone = FALSE; // RETURN nicht abfangen. } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1653,7 +1643,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) } bDone = TRUE; } - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); } break; @@ -1673,7 +1663,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) SetUpdateMode( bUpdates ); Invalidate(); - maSearchStr.Erase(); + maQuickSelectionEngine.Reset(); bDone = TRUE; break; @@ -1682,43 +1672,12 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) // fall through intentional default: { - xub_Unicode c = rKEvt.GetCharCode(); - - if ( !IsReadOnly() && (c >= 32) && (c != 127) && !rKEvt.GetKeyCode().IsMod2() ) + if ( !IsReadOnly() ) { - maSearchStr += c; - XubString aTmpSearch( maSearchStr ); - - nSelect = mpEntryList->FindMatchingEntry( aTmpSearch, mnCurrentPos ); - if ( (nSelect == LISTBOX_ENTRY_NOTFOUND) && (aTmpSearch.Len() > 1) ) - { - // Wenn alles die gleichen Buchstaben, dann anderer Such-Modus - BOOL bAllEqual = TRUE; - for ( USHORT n = aTmpSearch.Len(); n && bAllEqual; ) - bAllEqual = aTmpSearch.GetChar( --n ) == c; - if ( bAllEqual ) - { - aTmpSearch = c; - nSelect = mpEntryList->FindMatchingEntry( aTmpSearch, mnCurrentPos+1 ); - } - } - if ( nSelect == LISTBOX_ENTRY_NOTFOUND ) - nSelect = mpEntryList->FindMatchingEntry( aTmpSearch, 0 ); - - if ( nSelect != LISTBOX_ENTRY_NOTFOUND ) - { - ShowProminentEntry( nSelect ); - - if ( mpEntryList->IsEntryPosSelected( nSelect ) ) - nSelect = LISTBOX_ENTRY_NOTFOUND; - - maSearchTimeout.Start(); - } - else - maSearchStr.Erase(); - bDone = TRUE; + bDone = maQuickSelectionEngine.HandleKeyEvent( rKEvt ); } - } + } + break; } if ( ( nSelect != LISTBOX_ENTRY_NOTFOUND ) @@ -1744,6 +1703,72 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt ) } // ----------------------------------------------------------------------- +namespace +{ + static ::vcl::StringEntryIdentifier lcl_getEntry( const ImplEntryList& _rList, USHORT _nPos, String& _out_entryText ) + { + OSL_PRECOND( ( _nPos != LISTBOX_ENTRY_NOTFOUND ), "lcl_getEntry: invalid position!" ); + USHORT nEntryCount( _rList.GetEntryCount() ); + if ( _nPos >= nEntryCount ) + _nPos = 0; + _out_entryText = _rList.GetEntryText( _nPos ); + + // ::vcl::StringEntryIdentifier does not allow for 0 values, but our position is 0-based + // => normalize + return reinterpret_cast< ::vcl::StringEntryIdentifier >( _nPos + 1 ); + } + + static USHORT lcl_getEntryPos( ::vcl::StringEntryIdentifier _entry ) + { + // our pos is 0-based, but StringEntryIdentifier does not allow for a NULL + return static_cast< USHORT >( reinterpret_cast< sal_Int64 >( _entry ) ) - 1; + } +} + +// ----------------------------------------------------------------------- +::vcl::StringEntryIdentifier ImplListBoxWindow::CurrentEntry( String& _out_entryText ) const +{ + return lcl_getEntry( *GetEntryList(), ( mnCurrentPos == LISTBOX_ENTRY_NOTFOUND ) ? 0 : mnCurrentPos + 1, _out_entryText ); +} + +// ----------------------------------------------------------------------- +::vcl::StringEntryIdentifier ImplListBoxWindow::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const +{ + USHORT nNextPos = lcl_getEntryPos( _currentEntry ) + 1; + return lcl_getEntry( *GetEntryList(), nNextPos, _out_entryText ); +} + +// ----------------------------------------------------------------------- +void ImplListBoxWindow::SelectEntry( ::vcl::StringEntryIdentifier _entry ) +{ + USHORT nSelect = lcl_getEntryPos( _entry ); + if ( mpEntryList->IsEntryPosSelected( nSelect ) ) + { + // ignore that. This method is a callback from the QuickSelectionEngine, which means the user attempted + // to select the given entry by typing its starting letters. No need to act. + return; + } + + // normalize + OSL_ENSURE( nSelect < mpEntryList->GetEntryCount(), "ImplListBoxWindow::SelectEntry: how that?" ); + if( nSelect >= mpEntryList->GetEntryCount() ) + nSelect = mpEntryList->GetEntryCount()-1; + + // make visible + ShowProminentEntry( nSelect ); + + // actually select + mnCurrentPos = nSelect; + if ( SelectEntries( nSelect, LET_KEYMOVE, FALSE, FALSE ) ) + { + mbTravelSelect = TRUE; + mnSelectModifier = 0; + ImplCallSelect(); + mbTravelSelect = FALSE; + } +} + +// ----------------------------------------------------------------------- void ImplListBoxWindow::ImplPaint( USHORT nPos, BOOL bErase, bool bLayout ) { @@ -2356,7 +2381,11 @@ IMPL_LINK( ImplListBox, MRUChanged, void*, EMPTYARG ) IMPL_LINK( ImplListBox, LBWindowScrolled, void*, EMPTYARG ) { + long nSet = GetTopEntry(); + if( nSet > mpVScrollBar->GetRangeMax() ) + mpVScrollBar->SetRangeMax( GetEntryList()->GetEntryCount() ); mpVScrollBar->SetThumbPos( GetTopEntry() ); + mpHScrollBar->SetThumbPos( GetLeftIndent() ); maScrollHdl.Call( this ); @@ -2395,7 +2424,11 @@ void ImplListBox::ImplCheckScrollBars() mbVScroll = TRUE; // Ueberpruefung des rausgescrollten Bereichs - SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... + if( GetEntryList()->GetSelectEntryCount() == 1 && + GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND ) + ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) ); + else + SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... } else { @@ -2428,7 +2461,11 @@ void ImplListBox::ImplCheckScrollBars() mbVScroll = TRUE; // Ueberpruefung des rausgescrollten Bereichs - SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... + if( GetEntryList()->GetSelectEntryCount() == 1 && + GetEntryList()->GetSelectEntryPos( 0 ) != LISTBOX_ENTRY_NOTFOUND ) + ShowProminentEntry( GetEntryList()->GetSelectEntryPos( 0 ) ); + else + SetTopEntry( GetTopEntry() ); // MaxTop wird geprueft... } } @@ -2819,7 +2856,7 @@ void ImplWin::ImplDraw( bool bLayout ) sal_Int32 nLeft, nTop, nRight, nBottom; pWin->GetBorder( nLeft, nTop, nRight, nBottom ); Point aPoint( -nLeft, -nTop ); - Region aCtrlRegion( Rectangle( aPoint - GetPosPixel(), pWin->GetSizePixel() ) ); + Rectangle aCtrlRegion( aPoint - GetPosPixel(), pWin->GetSizePixel() ); BOOL bMouseOver = FALSE; if( GetParent() ) @@ -2838,8 +2875,7 @@ void ImplWin::ImplDraw( bool bLayout ) if( ! (nParentStyle & WB_BORDER) || (nParentStyle & WB_NOBORDER) ) { Rectangle aParentRect( Point( 0, 0 ), pWin->GetSizePixel() ); - Region aParentReg( aParentRect ); - pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentReg, + pWin->DrawNativeControl( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aParentRect, nState, aControlValue, rtl::OUString() ); } diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx index 6c7df5b106bf..03527bf083a7 100644 --- a/vcl/source/control/lstbox.cxx +++ b/vcl/source/control/lstbox.cxx @@ -44,9 +44,10 @@ #include "tools/debug.hxx" +#include <vcl/dndevdis.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> - -// ======================================================================= +// ======================================================================= ListBox::ListBox( WindowType nType ) : Control( nType ) { @@ -119,6 +120,8 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle ) Control::ImplInit( pParent, nStyle, NULL ); SetBackground(); + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener> xDrop = new DNDEventDispatcher(this); + if( nStyle & WB_DROPDOWN ) { sal_Int32 nLeft, nTop, nRight, nBottom; @@ -129,14 +132,14 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle ) IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) { ImplControlValue aControlValue; - Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 20, mnDDHeight ) ) ); - Region aBoundingRgn( aCtrlRegion ); - Region aContentRgn( aCtrlRegion ); + Rectangle aCtrlRegion( Point( 0, 0 ), Size( 20, mnDDHeight ) ); + Rectangle aBoundingRgn( aCtrlRegion ); + Rectangle aContentRgn( aCtrlRegion ); if( GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - sal_Int32 nHeight = aBoundingRgn.GetBoundRect().GetHeight(); + sal_Int32 nHeight = aBoundingRgn.GetHeight(); if( nHeight > mnDDHeight ) mnDDHeight = static_cast<USHORT>(nHeight); } @@ -145,16 +148,19 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle ) mpFloatWin = new ImplListBoxFloatingWindow( this ); mpFloatWin->SetAutoWidth( TRUE ); mpFloatWin->SetPopupModeEndHdl( LINK( this, ListBox, ImplPopupModeEndHdl ) ); + mpFloatWin->GetDropTarget()->addDropTargetListener(xDrop); mpImplWin = new ImplWin( this, (nStyle & (WB_LEFT|WB_RIGHT|WB_CENTER))|WB_NOBORDER ); mpImplWin->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) ); mpImplWin->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) ); mpImplWin->Show(); + mpImplWin->GetDropTarget()->addDropTargetListener(xDrop); mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE ); ImplInitDropDownButton( mpBtn ); mpBtn->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) ); mpBtn->Show(); + mpBtn->GetDropTarget()->addDropTargetListener(xDrop); } @@ -170,6 +176,9 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle ) mpImplLB->SetPosPixel( Point() ); mpImplLB->Show(); + mpImplLB->GetDropTarget()->addDropTargetListener(xDrop); + mpImplLB->SetDropTraget(xDrop); + if ( mpFloatWin ) { mpFloatWin->SetImplListBox( mpImplLB ); @@ -652,10 +661,10 @@ void ListBox::Resize() Window *pBorder = GetWindow( WINDOW_BORDER ); ImplControlValue aControlValue; Point aPoint; - Region aContent, aBound; + Rectangle aContent, aBound; // use the full extent of the control - Region aArea( Rectangle(aPoint, pBorder->GetOutputSizePixel()) ); + Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); if ( GetNativeControlRegion( CTRL_LISTBOX, PART_BUTTON_DOWN, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) @@ -665,8 +674,8 @@ void ListBox::Resize() aContent.Move( -aPoint.X(), -aPoint.Y() ); // use the themes drop down size for the button - aOutSz.Width() = aContent.GetBoundRect().Left(); - mpBtn->SetPosSizePixel( aContent.GetBoundRect().Left(), nTop, aContent.GetBoundRect().Right(), (nBottom-nTop) ); + aOutSz.Width() = aContent.Left(); + mpBtn->SetPosSizePixel( aContent.Left(), nTop, aContent.Right(), (nBottom-nTop) ); // adjust the size of the edit field if ( GetNativeControlRegion( CTRL_LISTBOX, PART_SUB_EDIT, @@ -676,7 +685,6 @@ void ListBox::Resize() aContent.Move( -aPoint.X(), -aPoint.Y() ); // use the themes drop down size - Rectangle aContentRect = aContent.GetBoundRect(); if( ! (GetStyle() & WB_BORDER) && ImplGetSVData()->maNWFData.mbNoFocusRects ) { // no border but focus ring behavior -> we have a problem; the @@ -684,11 +692,11 @@ void ListBox::Resize() // let's do the best we can and center vertically, so it doesn't look // completely wrong. Size aSz( GetOutputSizePixel() ); - long nDiff = aContentRect.Top() - (aSz.Height() - aContentRect.GetHeight())/2; - aContentRect.Top() -= nDiff; - aContentRect.Bottom() -= nDiff; + long nDiff = aContent.Top() - (aSz.Height() - aContent.GetHeight())/2; + aContent.Top() -= nDiff; + aContent.Bottom() -= nDiff; } - mpImplWin->SetPosSizePixel( aContentRect.TopLeft(), aContentRect.GetSize() ); + mpImplWin->SetPosSizePixel( aContent.TopLeft(), aContent.GetSize() ); } else mpImplWin->SetSizePixel( aOutSz ); @@ -1327,15 +1335,14 @@ Size ListBox::CalcMinimumSize() const // see how large the edit area inside is to estimate what is needed for the dropdown ImplControlValue aControlValue; Point aPoint; - Region aContent, aBound; + Rectangle aContent, aBound; Size aTestSize( 100, 20 ); - Region aArea( Rectangle( aPoint, aTestSize ) ); + Rectangle aArea( aPoint, aTestSize ); if( const_cast<ListBox*>(this)->GetNativeControlRegion( CTRL_LISTBOX, PART_SUB_EDIT, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { // use the themes drop down size - Rectangle aContentRect = aContent.GetBoundRect(); - aSz.Width() += aTestSize.Width() - aContentRect.GetWidth(); + aSz.Width() += aTestSize.Width() - aContent.GetWidth(); } else aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); @@ -1347,13 +1354,12 @@ Size ListBox::CalcMinimumSize() const { ImplControlValue aControlValue; Rectangle aRect( Point( 0, 0 ), aSz ); - Region aContent, aBound; + Rectangle aContent, aBound; if( const_cast<ListBox*>(this)->GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) ) { - Rectangle aBoundRect( aBound.GetBoundRect() ); - if( aBoundRect.GetHeight() > aSz.Height() ) - aSz.Height() = aBoundRect.GetHeight(); + if( aBound.GetHeight() > aSz.Height() ) + aSz.Height() = aBound.GetHeight(); } } @@ -1615,7 +1621,6 @@ const Wallpaper& ListBox::GetDisplayBackground() const } // ======================================================================= - MultiListBox::MultiListBox( Window* pParent, WinBits nStyle ) : ListBox( WINDOW_MULTILISTBOX ) { diff --git a/vcl/source/control/makefile.mk b/vcl/source/control/makefile.mk index a2553333246d..b1644e58ccd9 100644 --- a/vcl/source/control/makefile.mk +++ b/vcl/source/control/makefile.mk @@ -62,7 +62,8 @@ SLOFILES= $(SLO)$/button.obj \ $(SLO)$/slider.obj \ $(SLO)$/spinfld.obj \ $(SLO)$/spinbtn.obj \ - $(SLO)$/tabctrl.obj + $(SLO)$/tabctrl.obj \ + $(SLO)$/quickselectionengine.obj EXCEPTIONSFILES= \ $(SLO)$/button.obj \ diff --git a/vcl/source/control/menubtn.cxx b/vcl/source/control/menubtn.cxx index 94f61818ac92..c264d01916fc 100644 --- a/vcl/source/control/menubtn.cxx +++ b/vcl/source/control/menubtn.cxx @@ -78,15 +78,6 @@ void MenuButton::ImplExecuteMenu() Point aPos( 0, 1 ); Size aSize = GetSizePixel(); Rectangle aRect( aPos, aSize ); - const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); - if ( !((GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) || - !(rStyleSettings.GetOptions() & STYLE_OPTION_MACSTYLE)) ) - { - aRect.Left() += 2; - aRect.Top() += 2; - aRect.Right() -= 2; - aRect.Bottom() -= 2; - } SetPressed( TRUE ); EndSelection(); mnCurItemId = mpMenu->Execute( this, aRect, POPUPMENU_EXECUTE_DOWN ); @@ -169,20 +160,27 @@ IMPL_LINK( MenuButton, ImplMenuTimeoutHdl, Timer*, EMPTYARG ) void MenuButton::MouseButtonDown( const MouseEvent& rMEvt ) { + bool bExecute = true; if ( mnMenuMode & MENUBUTTON_MENUMODE_TIMED ) { - if ( !mpMenuTimer ) + // if the separated dropdown symbol is hit, + // execute the popup immediately + if( ! ImplGetSymbolRect().IsInside( rMEvt.GetPosPixel() ) ) { - mpMenuTimer = new Timer; - mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) ); - } + if ( !mpMenuTimer ) + { + mpMenuTimer = new Timer; + mpMenuTimer->SetTimeoutHdl( LINK( this, MenuButton, ImplMenuTimeoutHdl ) ); + } - mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() ); - mpMenuTimer->Start(); + mpMenuTimer->SetTimeout( GetSettings().GetMouseSettings().GetActionDelay() ); + mpMenuTimer->Start(); - PushButton::MouseButtonDown( rMEvt ); + PushButton::MouseButtonDown( rMEvt ); + bExecute = false; + } } - else + if( bExecute ) { if ( PushButton::ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) ) { diff --git a/vcl/source/control/quickselectionengine.cxx b/vcl/source/control/quickselectionengine.cxx new file mode 100644 index 000000000000..2d32393bf79a --- /dev/null +++ b/vcl/source/control/quickselectionengine.cxx @@ -0,0 +1,183 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2009 by Sun Microsystems, Inc. +* +* 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. +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "vcl/quickselectionengine.hxx" +#include "vcl/event.hxx" +#include "vcl/timer.hxx" +#include "vcl/i18nhelp.hxx" +#include "vcl/svapp.hxx" + +#include <boost/optional.hpp> + +//........................................................................ +namespace vcl +{ +//........................................................................ + + //==================================================================== + //= QuickSelectionEngine_Data + //==================================================================== + struct QuickSelectionEngine_Data + { + ISearchableStringList& rEntryList; + String sCurrentSearchString; + ::boost::optional< sal_Unicode > aSingleSearchChar; + Timer aSearchTimeout; + + QuickSelectionEngine_Data( ISearchableStringList& _entryList ) + :rEntryList( _entryList ) + ,sCurrentSearchString() + ,aSingleSearchChar() + ,aSearchTimeout() + { + aSearchTimeout.SetTimeout( 2500 ); + aSearchTimeout.SetTimeoutHdl( LINK( this, QuickSelectionEngine_Data, SearchStringTimeout ) ); + } + + ~QuickSelectionEngine_Data() + { + aSearchTimeout.Stop(); + } + + DECL_LINK( SearchStringTimeout, Timer* ); + }; + + //-------------------------------------------------------------------- + namespace + { + static void lcl_reset( QuickSelectionEngine_Data& _data ) + { + _data.sCurrentSearchString.Erase(); + _data.aSingleSearchChar.reset(); + _data.aSearchTimeout.Stop(); + } + } + + //-------------------------------------------------------------------- + IMPL_LINK( QuickSelectionEngine_Data, SearchStringTimeout, Timer*, /*EMPTYARG*/ ) + { + lcl_reset( *this ); + return 1; + } + + //-------------------------------------------------------------------- + static StringEntryIdentifier findMatchingEntry( const String& _searchString, QuickSelectionEngine_Data& _engineData ) + { + const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetLocaleI18nHelper(); + // TODO: do we really need the Window's settings here? The original code used it ... + + String sEntryText; + // get the "current + 1" entry + StringEntryIdentifier pSearchEntry = _engineData.rEntryList.CurrentEntry( sEntryText ); + if ( pSearchEntry ) + pSearchEntry = _engineData.rEntryList.NextEntry( pSearchEntry, sEntryText ); + // loop 'til we find another matching entry + StringEntryIdentifier pStartedWith = pSearchEntry; + while ( pSearchEntry ) + { + if ( rI18nHelper.MatchString( _searchString, sEntryText ) != 0 ) + break; + + pSearchEntry = _engineData.rEntryList.NextEntry( pSearchEntry, sEntryText ); + if ( pSearchEntry == pStartedWith ) + pSearchEntry = NULL; + } + + return pSearchEntry; + } + + //==================================================================== + //= QuickSelectionEngine + //==================================================================== + //-------------------------------------------------------------------- + QuickSelectionEngine::QuickSelectionEngine( ISearchableStringList& _entryList ) + :m_pData( new QuickSelectionEngine_Data( _entryList ) ) + { + } + + //-------------------------------------------------------------------- + QuickSelectionEngine::~QuickSelectionEngine() + { + } + + //-------------------------------------------------------------------- + bool QuickSelectionEngine::HandleKeyEvent( const KeyEvent& _keyEvent ) + { + xub_Unicode c = _keyEvent.GetCharCode(); + + if ( ( c >= 32 ) && ( c != 127 ) && !_keyEvent.GetKeyCode().IsMod2() ) + { + m_pData->sCurrentSearchString += c; + OSL_TRACE( "QuickSelectionEngine::HandleKeyEvent: searching for %s", ByteString( m_pData->sCurrentSearchString, RTL_TEXTENCODING_UTF8 ).GetBuffer() ); + + if ( m_pData->sCurrentSearchString.Len() == 1 ) + { // first character in the search -> remmeber + m_pData->aSingleSearchChar.reset( c ); + } + else if ( m_pData->sCurrentSearchString.Len() > 1 ) + { + if ( !!m_pData->aSingleSearchChar && ( *m_pData->aSingleSearchChar != c ) ) + // we already have a "single char", but the current one is different -> reset + m_pData->aSingleSearchChar.reset(); + } + + XubString aSearchTemp( m_pData->sCurrentSearchString ); + + StringEntryIdentifier pMatchingEntry = findMatchingEntry( aSearchTemp, *m_pData ); + OSL_TRACE( "QuickSelectionEngine::HandleKeyEvent: found %p", pMatchingEntry ); + if ( !pMatchingEntry && ( aSearchTemp.Len() > 1 ) && !!m_pData->aSingleSearchChar ) + { + // if there's only one letter in the search string, use a different search mode + aSearchTemp = *m_pData->aSingleSearchChar; + pMatchingEntry = findMatchingEntry( aSearchTemp, *m_pData ); + } + + if ( pMatchingEntry ) + { + m_pData->rEntryList.SelectEntry( pMatchingEntry ); + m_pData->aSearchTimeout.Start(); + } + else + { + lcl_reset( *m_pData ); + } + + return true; + } + return false; + } + + //-------------------------------------------------------------------- + void QuickSelectionEngine::Reset() + { + lcl_reset( *m_pData ); + } + +//........................................................................ +} // namespace vcl +//........................................................................ diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx index 54a1e0a97eab..4261965995fa 100644 --- a/vcl/source/control/scrbar.cxx +++ b/vcl/source/control/scrbar.cxx @@ -342,8 +342,8 @@ void ScrollBar::ImplCalc( BOOL bUpdate ) Rectangle& maTrackRect = mpData->maTrackRect; // TODO: remove when maTrackRect is no longer in mpData if ( mbCalcSize ) { - const Region aControlRegion( Rectangle( (const Point&)Point(0,0), aSize ) ); - Region aBtn1Region, aBtn2Region, aTrackRegion, aBoundingRegion; + const Rectangle aControlRegion( Point(0,0), aSize ); + Rectangle aBtn1Region, aBtn2Region, aTrackRegion, aBoundingRegion; if ( GetStyle() & WB_HORZ ) { @@ -352,8 +352,8 @@ void ScrollBar::ImplCalc( BOOL bUpdate ) GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_RIGHT, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn2Region ) ) { - maBtn1Rect = aBtn1Region.GetBoundRect(); - maBtn2Rect = aBtn2Region.GetBoundRect(); + maBtn1Rect = aBtn1Region; + maBtn2Rect = aBtn2Region; } else { @@ -366,7 +366,7 @@ void ScrollBar::ImplCalc( BOOL bUpdate ) if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_TRACK_HORZ_AREA, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aTrackRegion ) ) - maTrackRect = aTrackRegion.GetBoundRect(); + maTrackRect = aTrackRegion; else maTrackRect = Rectangle( maBtn1Rect.TopRight(), maBtn2Rect.BottomLeft() ); @@ -393,8 +393,8 @@ void ScrollBar::ImplCalc( BOOL bUpdate ) GetNativeControlRegion( CTRL_SCROLLBAR, PART_BUTTON_DOWN, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aBtn2Region ) ) { - maBtn1Rect = aBtn1Region.GetBoundRect(); - maBtn2Rect = aBtn2Region.GetBoundRect(); + maBtn1Rect = aBtn1Region; + maBtn2Rect = aBtn2Region; } else { @@ -407,7 +407,7 @@ void ScrollBar::ImplCalc( BOOL bUpdate ) if ( GetNativeControlRegion( CTRL_SCROLLBAR, PART_TRACK_VERT_AREA, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aBoundingRegion, aTrackRegion ) ) - maTrackRect = aTrackRegion.GetBoundRect(); + maTrackRect = aTrackRegion; else maTrackRect = Rectangle( maBtn1Rect.BottomLeft()+Point(0,1), maBtn2Rect.TopRight() ); @@ -524,7 +524,7 @@ void ScrollBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) { - ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); + ScrollbarValue scrValue; BOOL bNativeOK = IsNativeControlSupported(CTRL_SCROLLBAR, PART_ENTIRE_CONTROL); if( bNativeOK ) @@ -535,7 +535,6 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) if( IsNativeControlSupported(CTRL_SCROLLBAR, bHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT) ) { ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 ); - ScrollbarValue scrValue; scrValue.mnMin = mnMinRange; scrValue.mnMax = mnMaxRange; @@ -570,20 +569,14 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) } } - aControlValue.setOptionalVal( (void *)(&scrValue) ); - -#if 1 - Region aCtrlRegion; + Rectangle aCtrlRegion; aCtrlRegion.Union( maBtn1Rect ); aCtrlRegion.Union( maBtn2Rect ); aCtrlRegion.Union( maPage1Rect ); aCtrlRegion.Union( maPage2Rect ); aCtrlRegion.Union( maThumbRect ); -#else - const Region aCtrlRegion( Rectangle( Point(0,0), GetOutputSizePixel() ) ); -#endif bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, (bHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT), - aCtrlRegion, nState, aControlValue, rtl::OUString() ); + aCtrlRegion, nState, scrValue, rtl::OUString() ); } else { @@ -591,8 +584,8 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) { sal_uInt32 part1 = bHorz ? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER; sal_uInt32 part2 = bHorz ? PART_TRACK_HORZ_RIGHT : PART_TRACK_VERT_LOWER; - Region aCtrlRegion1( maPage1Rect ); - Region aCtrlRegion2( maPage2Rect ); + Rectangle aCtrlRegion1( maPage1Rect ); + Rectangle aCtrlRegion2( maPage2Rect ); ControlState nState1 = (IsEnabled() ? CTRL_STATE_ENABLED : 0) | (HasFocus() ? CTRL_STATE_FOCUSED : 0); ControlState nState2 = nState1; @@ -613,18 +606,18 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) if ( nDrawFlags & SCRBAR_DRAW_PAGE1 ) bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part1, aCtrlRegion1, nState1, - aControlValue, rtl::OUString() ); + scrValue, rtl::OUString() ); if ( nDrawFlags & SCRBAR_DRAW_PAGE2 ) bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part2, aCtrlRegion2, nState2, - aControlValue, rtl::OUString() ); + scrValue, rtl::OUString() ); } if ( (nDrawFlags & SCRBAR_DRAW_BTN1) || (nDrawFlags & SCRBAR_DRAW_BTN2) ) { sal_uInt32 part1 = bHorz ? PART_BUTTON_LEFT : PART_BUTTON_UP; sal_uInt32 part2 = bHorz ? PART_BUTTON_RIGHT : PART_BUTTON_DOWN; - Region aCtrlRegion1( maBtn1Rect ); - Region aCtrlRegion2( maBtn2Rect ); + Rectangle aCtrlRegion1( maBtn1Rect ); + Rectangle aCtrlRegion2( maBtn2Rect ); ControlState nState1 = HasFocus() ? CTRL_STATE_FOCUSED : 0; ControlState nState2 = nState1; @@ -655,16 +648,16 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) if ( nDrawFlags & SCRBAR_DRAW_BTN1 ) bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part1, aCtrlRegion1, nState1, - aControlValue, rtl::OUString() ); + scrValue, rtl::OUString() ); if ( nDrawFlags & SCRBAR_DRAW_BTN2 ) bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, part2, aCtrlRegion2, nState2, - aControlValue, rtl::OUString() ); + scrValue, rtl::OUString() ); } if ( (nDrawFlags & SCRBAR_DRAW_THUMB) && !maThumbRect.IsEmpty() ) { ControlState nState = IsEnabled() ? CTRL_STATE_ENABLED : 0; - Region aCtrlRegion( maThumbRect ); + Rectangle aCtrlRegion( maThumbRect ); if ( mnStateFlags & SCRBAR_STATE_THUMB_DOWN ) nState |= CTRL_STATE_PRESSED; @@ -683,7 +676,7 @@ BOOL ScrollBar::ImplDrawNative( USHORT nDrawFlags ) } bNativeOK = DrawNativeControl( CTRL_SCROLLBAR, (bHorz ? PART_THUMB_HORZ : PART_THUMB_VERT), - aCtrlRegion, nState, aControlValue, rtl::OUString() ); + aCtrlRegion, nState, scrValue, rtl::OUString() ); } } } @@ -777,64 +770,7 @@ void ScrollBar::ImplDraw( USHORT nDrawFlags, OutputDevice* pOutDev ) if ( bEnabled ) { nStyle = BUTTON_DRAW_NOLIGHTBORDER; - // pressed thumbs only in OS2 style - if ( rStyleSettings.GetOptions() & STYLE_OPTION_OS2STYLE ) - if ( mnStateFlags & SCRBAR_STATE_THUMB_DOWN ) - nStyle |= BUTTON_DRAW_PRESSED; aTempRect = aDecoView.DrawButton( maThumbRect, nStyle ); - // OS2 style requires pattern on the thumb - if ( rStyleSettings.GetOptions() & STYLE_OPTION_OS2STYLE ) - { - if ( GetStyle() & WB_HORZ ) - { - if ( aTempRect.GetWidth() > 6 ) - { - long nX = aTempRect.Center().X(); - nX -= 6; - if ( nX < aTempRect.Left() ) - nX = aTempRect.Left(); - for ( int i = 0; i < 6; i++ ) - { - if ( nX > aTempRect.Right()-1 ) - break; - - pOutDev->SetLineColor( rStyleSettings.GetButtonTextColor() ); - pOutDev->DrawLine( Point( nX, aTempRect.Top()+1 ), - Point( nX, aTempRect.Bottom()-1 ) ); - nX++; - pOutDev->SetLineColor( rStyleSettings.GetLightColor() ); - pOutDev->DrawLine( Point( nX, aTempRect.Top()+1 ), - Point( nX, aTempRect.Bottom()-1 ) ); - nX++; - } - } - } - else - { - if ( aTempRect.GetHeight() > 6 ) - { - long nY = aTempRect.Center().Y(); - nY -= 6; - if ( nY < aTempRect.Top() ) - nY = aTempRect.Top(); - for ( int i = 0; i < 6; i++ ) - { - if ( nY > aTempRect.Bottom()-1 ) - break; - - pOutDev->SetLineColor( rStyleSettings.GetButtonTextColor() ); - pOutDev->DrawLine( Point( aTempRect.Left()+1, nY ), - Point( aTempRect.Right()-1, nY ) ); - nY++; - pOutDev->SetLineColor( rStyleSettings.GetLightColor() ); - pOutDev->DrawLine( Point( aTempRect.Left()+1, nY ), - Point( aTempRect.Right()-1, nY ) ); - nY++; - } - } - } - pOutDev->SetLineColor(); - } } else { @@ -920,7 +856,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, BOOL bCallAction ) BOOL bIsInside = FALSE; Point aPoint( 0, 0 ); - Region aControlRegion( Rectangle( aPoint, GetOutputSizePixel() ) ); + Rectangle aControlRegion( aPoint, GetOutputSizePixel() ); switch ( meScrollType ) { @@ -953,7 +889,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, BOOL bCallAction ) case SCROLL_PAGEUP: // HitTestNativeControl, see remark at top of file if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_LEFT: PART_TRACK_VERT_UPPER, - Region( maPage1Rect ), rMousePos, bIsInside )? + maPage1Rect, rMousePos, bIsInside )? bIsInside: maPage1Rect.IsInside( rMousePos ) ) { @@ -967,7 +903,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, BOOL bCallAction ) case SCROLL_PAGEDOWN: // HitTestNativeControl, see remark at top of file if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_RIGHT: PART_TRACK_VERT_LOWER, - Region( maPage2Rect ), rMousePos, bIsInside )? + maPage2Rect, rMousePos, bIsInside )? bIsInside: maPage2Rect.IsInside( rMousePos ) ) { @@ -1030,7 +966,7 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt ) BOOL bDragToMouse = FALSE; Point aPoint( 0, 0 ); - Region aControlRegion( Rectangle( aPoint, GetOutputSizePixel() ) ); + Rectangle aControlRegion( aPoint, GetOutputSizePixel() ); if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_LEFT: PART_BUTTON_UP, aControlRegion, rMousePos, bIsInside )? @@ -1063,7 +999,7 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt ) else { bool bThumbHit = HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_THUMB_HORZ : PART_THUMB_VERT, - Region( maThumbRect ), rMousePos, bIsInside ) + maThumbRect, rMousePos, bIsInside ) ? bIsInside : maThumbRect.IsInside( rMousePos ); bool bDragHandling = rMEvt.IsMiddle() || bThumbHit || ImplGetSVData()->maNWFData.mbScrollbarJumpPage; if( bDragHandling ) @@ -1112,7 +1048,7 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt ) // HitTestNativeControl, see remark at top of file if ( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER, - Region( maPage1Rect ), rMousePos, bIsInside )? + maPage1Rect, rMousePos, bIsInside )? bIsInside: maPage1Rect.IsInside( rMousePos ) ) { @@ -1387,7 +1323,7 @@ Rectangle* ScrollBar::ImplFindPartRect( const Point& rPt ) BOOL bIsInside = FALSE; Point aPoint( 0, 0 ); - Region aControlRegion( Rectangle( aPoint, GetOutputSizePixel() ) ); + Rectangle aControlRegion( aPoint, GetOutputSizePixel() ); if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal? PART_BUTTON_LEFT: PART_BUTTON_UP, aControlRegion, rPt, bIsInside )? @@ -1401,19 +1337,19 @@ Rectangle* ScrollBar::ImplFindPartRect( const Point& rPt ) return &maBtn2Rect; // HitTestNativeControl, see remark at top of file else if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal ? PART_TRACK_HORZ_LEFT : PART_TRACK_VERT_UPPER, - Region( maPage1Rect ), rPt, bIsInside)? + maPage1Rect, rPt, bIsInside)? bIsInside: maPage1Rect.IsInside( rPt ) ) return &maPage1Rect; // HitTestNativeControl, see remark at top of file else if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal ? PART_TRACK_HORZ_RIGHT : PART_TRACK_VERT_LOWER, - Region( maPage2Rect ), rPt, bIsInside)? + maPage2Rect, rPt, bIsInside)? bIsInside: maPage2Rect.IsInside( rPt ) ) return &maPage2Rect; // HitTestNativeControl, see remark at top of file else if( HitTestNativeControl( CTRL_SCROLLBAR, bHorizontal ? PART_THUMB_HORZ : PART_THUMB_VERT, - Region( maThumbRect ), rPt, bIsInside)? + maThumbRect, rPt, bIsInside)? bIsInside: maThumbRect.IsInside( rPt ) ) return &maThumbRect; diff --git a/vcl/source/control/slider.cxx b/vcl/source/control/slider.cxx index 2390a8e3e9a6..26a4c1cfd205 100644 --- a/vcl/source/control/slider.cxx +++ b/vcl/source/control/slider.cxx @@ -195,15 +195,14 @@ void Slider::ImplUpdateRects( BOOL bUpdate ) else maChannel2Rect.SetEmpty(); - const Region aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE, 10 ) ) ); - Region aThumbBounds, aThumbContent; + const Rectangle aControlRegion( Rectangle( Point(0,0), Size( SLIDER_THUMB_SIZE, 10 ) ) ); + Rectangle aThumbBounds, aThumbContent; if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_HORZ, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aThumbBounds, aThumbContent ) ) { - Rectangle aRect( aThumbBounds.GetBoundRect() ); - maThumbRect.Left() = mnThumbPixPos - aRect.GetWidth()/2; - maThumbRect.Right() = maThumbRect.Left() + aRect.GetWidth() - 1; + maThumbRect.Left() = mnThumbPixPos - aThumbBounds.GetWidth()/2; + maThumbRect.Right() = maThumbRect.Left() + aThumbBounds.GetWidth() - 1; bInvalidateAll = true; } } @@ -230,15 +229,14 @@ void Slider::ImplUpdateRects( BOOL bUpdate ) else maChannel2Rect.SetEmpty(); - const Region aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE ) ) ); - Region aThumbBounds, aThumbContent; + const Rectangle aControlRegion( Rectangle( Point(0,0), Size( 10, SLIDER_THUMB_SIZE ) ) ); + Rectangle aThumbBounds, aThumbContent; if ( GetNativeControlRegion( CTRL_SLIDER, PART_THUMB_VERT, aControlRegion, 0, ImplControlValue(), rtl::OUString(), aThumbBounds, aThumbContent ) ) { - Rectangle aRect( aThumbBounds.GetBoundRect() ); - maThumbRect.Top() = mnThumbPixPos - aRect.GetHeight()/2; - maThumbRect.Bottom() = maThumbRect.Top() + aRect.GetHeight() - 1; + maThumbRect.Top() = mnThumbPixPos - aThumbBounds.GetHeight()/2; + maThumbRect.Bottom() = maThumbRect.Top() + aThumbBounds.GetHeight() - 1; bInvalidateAll = true; } } @@ -388,7 +386,6 @@ void Slider::ImplDraw( USHORT nDrawFlags ) ImplCalc( FALSE ); ControlPart nPart = (GetStyle() & WB_HORZ) ? PART_TRACK_HORZ_AREA : PART_TRACK_VERT_AREA; - ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); ControlState nState = ( IsEnabled() ? CTRL_STATE_ENABLED : 0 ) | ( HasFocus() ? CTRL_STATE_FOCUSED : 0 ); SliderValue sldValue; @@ -402,11 +399,10 @@ void Slider::ImplDraw( USHORT nDrawFlags ) if( maThumbRect.IsInside( GetPointerPosPixel() ) ) sldValue.mnThumbState |= CTRL_STATE_ROLLOVER; } - aControlValue.setOptionalVal( (void *)(&sldValue) ); - const Region aCtrlRegion( Rectangle( Point(0,0), GetOutputSizePixel() ) ); + const Rectangle aCtrlRegion( Point(0,0), GetOutputSizePixel() ); bool bNativeOK = DrawNativeControl( CTRL_SLIDER, nPart, - aCtrlRegion, nState, aControlValue, rtl::OUString() ); + aCtrlRegion, nState, sldValue, rtl::OUString() ); if( bNativeOK ) return; @@ -717,13 +713,6 @@ void Slider::MouseButtonDown( const MouseEvent& rMEvt ) mnMouseOff = rMousePos.X()-aCenterPos.X(); else mnMouseOff = rMousePos.Y()-aCenterPos.Y(); - - // Im OS2-Look geben wir den Thumb gedrueckt aus - if ( GetSettings().GetStyleSettings().GetOptions() & STYLE_OPTION_OS2STYLE ) - { - mnStateFlags |= SLIDER_STATE_THUMB_DOWN; - ImplDraw( SLIDER_DRAW_THUMB ); - } } else if ( ImplIsPageUp( rMousePos ) ) { diff --git a/vcl/source/control/spinfld.cxx b/vcl/source/control/spinfld.cxx index d18a412e31cc..c51ac834f1b4 100644 --- a/vcl/source/control/spinfld.cxx +++ b/vcl/source/control/spinfld.cxx @@ -88,15 +88,12 @@ BOOL ImplDrawNativeSpinfield( Window *pWin, const SpinbuttonValue& rSpinbuttonVa // there is just no useful native support for spinfields with dropdown !(pWin->GetStyle() & WB_DROPDOWN) ) { - ImplControlValue aControlValue; - aControlValue.setOptionalVal( (void*) &rSpinbuttonValue ); - if( pWin->IsNativeControlSupported(CTRL_SPINBOX, rSpinbuttonValue.mnUpperPart) && pWin->IsNativeControlSupported(CTRL_SPINBOX, rSpinbuttonValue.mnLowerPart) ) { // only paint the embedded spin buttons, all buttons are painted at once - bNativeOK = pWin->DrawNativeControl( CTRL_SPINBOX, PART_ALL_BUTTONS, Region(), CTRL_STATE_ENABLED, - aControlValue, rtl::OUString() ); + bNativeOK = pWin->DrawNativeControl( CTRL_SPINBOX, PART_ALL_BUTTONS, Rectangle(), CTRL_STATE_ENABLED, + rSpinbuttonValue, rtl::OUString() ); } else { @@ -115,17 +112,18 @@ BOOL ImplDrawNativeSpinfield( Window *pWin, const SpinbuttonValue& rSpinbuttonVa Point aPt; Size aSize( pBorder->GetOutputSizePixel() ); // the size of the border window, i.e., the whole control - Region aBound, aContent; - Region aNatRgn( Rectangle( aPt, aSize ) ); - if( pBorder->GetNativeControlRegion(CTRL_SPINBOX, PART_ENTIRE_CONTROL, - aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) + Rectangle aBound, aContent; + Rectangle aNatRgn( aPt, aSize ); + if( ! ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize && + pBorder->GetNativeControlRegion( CTRL_SPINBOX, PART_ENTIRE_CONTROL, + aNatRgn, 0, rSpinbuttonValue, rtl::OUString(), aBound, aContent) ) { - aSize = aContent.GetBoundRect().GetSize(); + aSize = aContent.GetSize(); } - Region aRgn( Rectangle( aPt, aSize ) ); + Rectangle aRgn( aPt, aSize ); bNativeOK = pBorder->DrawNativeControl( CTRL_SPINBOX, PART_ENTIRE_CONTROL, aRgn, CTRL_STATE_ENABLED, - aControlValue, rtl::OUString() ); + rSpinbuttonValue, rtl::OUString() ); pBorder->SetClipRegion( oldRgn ); } @@ -139,12 +137,9 @@ BOOL ImplDrawNativeSpinbuttons( Window *pWin, const SpinbuttonValue& rSpinbutton if( pWin->IsNativeControlSupported(CTRL_SPINBUTTONS, PART_ENTIRE_CONTROL) ) { - ImplControlValue aControlValue; - aControlValue.setOptionalVal( (void*) &rSpinbuttonValue ); - // only paint the standalone spin buttons, all buttons are painted at once - bNativeOK = pWin->DrawNativeControl( CTRL_SPINBUTTONS, PART_ALL_BUTTONS, Region(), CTRL_STATE_ENABLED, - aControlValue, rtl::OUString() ); + bNativeOK = pWin->DrawNativeControl( CTRL_SPINBUTTONS, PART_ALL_BUTTONS, Rectangle(), CTRL_STATE_ENABLED, + rSpinbuttonValue, rtl::OUString() ); } return bNativeOK; } @@ -705,7 +700,7 @@ void SpinField::ImplCalcButtonAreas( OutputDevice* pDev, const Size& rOutSz, Rec nBottom1--; BOOL bNativeRegionOK = FALSE; - Region aContentUp, aContentDown; + Rectangle aContentUp, aContentDown; if ( (pDev->GetOutDevType() == OUTDEV_WINDOW) && // there is just no useful native support for spinfields with dropdown @@ -717,11 +712,11 @@ void SpinField::ImplCalcButtonAreas( OutputDevice* pDev, const Size& rOutSz, Rec // get the system's spin button size ImplControlValue aControlValue; - Region aBound; + Rectangle aBound; Point aPoint; // use the full extent of the control - Region aArea( Rectangle( aPoint, pBorder->GetOutputSizePixel() ) ); + Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); bNativeRegionOK = pWin->GetNativeControlRegion(CTRL_SPINBOX, PART_BUTTON_UP, @@ -740,8 +735,8 @@ void SpinField::ImplCalcButtonAreas( OutputDevice* pDev, const Size& rOutSz, Rec if( bNativeRegionOK ) { - rSpinUpArea = aContentUp.GetBoundRect(); - rSpinDownArea = aContentDown.GetBoundRect(); + rSpinUpArea = aContentUp; + rSpinDownArea = aContentDown; } else { @@ -774,11 +769,11 @@ void SpinField::Resize() ImplControlValue aControlValue; Point aPoint; - Region aContent, aBound; + Rectangle aContent, aBound; // use the full extent of the control Window *pBorder = GetWindow( WINDOW_BORDER ); - Region aArea( Rectangle(aPoint, pBorder->GetOutputSizePixel()) ); + Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); // adjust position and size of the edit field if ( GetNativeControlRegion(CTRL_SPINBOX, PART_SUB_EDIT, @@ -789,10 +784,9 @@ void SpinField::Resize() aContent.Move(-aPoint.X(), -aPoint.Y()); // use the themes drop down size - Rectangle aContentRect = aContent.GetBoundRect(); - mpEdit->SetPosPixel( aContentRect.TopLeft() ); + mpEdit->SetPosPixel( aContent.TopLeft() ); bSubEditPositioned = true; - aSize = aContentRect.GetSize(); + aSize = aContent.GetSize(); } else { diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx index 95f84626b582..2c81b6af241b 100644 --- a/vcl/source/control/tabctrl.cxx +++ b/vcl/source/control/tabctrl.cxx @@ -42,7 +42,6 @@ #include "vcl/controldata.hxx" #include "vcl/sound.hxx" #include "vcl/lstbox.hxx" -#include "vcl/smartid.hxx" #include "vcl/window.h" @@ -59,7 +58,7 @@ struct ImplTabItem String maText; String maFormatText; String maHelpText; - ULONG mnHelpId; + rtl::OString maHelpId; Rectangle maRect; USHORT mnLine; bool mbFullVisible; @@ -67,7 +66,7 @@ struct ImplTabItem Image maTabImage; ImplTabItem() - : mnId( 0 ), mnTabPageResId( 0 ), mpTabPage( NULL ), mnHelpId( 0 ), + : mnId( 0 ), mnTabPageResId( 0 ), mpTabPage( NULL ), mnLine( 0 ), mbFullVisible( FALSE ), mbEnabled( true ) {} }; @@ -76,8 +75,6 @@ struct ImplTabItem struct ImplTabCtrlData { - PushButton* mpLeftBtn; - PushButton* mpRightBtn; std::hash_map< int, int > maLayoutPageIdToLine; std::hash_map< int, int > maLayoutLineToPageId; std::vector< Rectangle > maTabRectangles; @@ -89,27 +86,6 @@ struct ImplTabCtrlData // ----------------------------------------------------------------------- -#if 0 -// not used -#define TABCOLORCOUNT 10 - -static ColorData aImplTabColorAry[TABCOLORCOUNT] = -{ - RGB_COLORDATA( 80, 216, 248 ), - RGB_COLORDATA( 128, 216, 168 ), - RGB_COLORDATA( 128, 144, 248 ), - RGB_COLORDATA( 208, 180, 168 ), - RGB_COLORDATA( 248, 252, 168 ), - RGB_COLORDATA( 168, 144, 168 ), - RGB_COLORDATA( 248, 144, 80 ), - RGB_COLORDATA( 248, 216, 80 ), - RGB_COLORDATA( 248, 180, 168 ), - RGB_COLORDATA( 248, 216, 168 ) -}; -#endif - -// ----------------------------------------------------------------------- - #define TAB_OFFSET 3 #define TAB_TABOFFSET_X 3 #define TAB_TABOFFSET_Y 3 @@ -133,9 +109,6 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle ) if ( !(nStyle & WB_NODIALOGCONTROL) ) nStyle |= WB_DIALOGCONTROL; - // no single line tabs since NWF - nStyle &= ~WB_SINGLELINE; - Control::ImplInit( pParent, nStyle, NULL ); mnLastWidth = 0; @@ -144,19 +117,12 @@ void TabControl::ImplInit( Window* pParent, WinBits nStyle ) mnMaxPageWidth = 0; mnActPageId = 0; mnCurPageId = 0; - mnFirstPagePos = 0; - mnLastFirstPagePos = 0; mbFormat = TRUE; mbRestoreHelpId = FALSE; mbRestoreUnqId = FALSE; - mbSingleLine = FALSE; - mbScroll = FALSE; - mbRestoreSmartId = FALSE; mbSmallInvalidate = FALSE; mbExtraSpace = FALSE; mpTabCtrlData = new ImplTabCtrlData; - mpTabCtrlData->mpLeftBtn = NULL; - mpTabCtrlData->mpRightBtn = NULL; mpTabCtrlData->mpListBox = NULL; @@ -228,8 +194,6 @@ void TabControl::ImplInitSettings( BOOL bFont, SetBackground( pParent->GetBackground() ); } } - - ImplScrollBtnsColor(); } // ----------------------------------------------------------------------- @@ -301,10 +265,6 @@ TabControl::~TabControl() { if( mpTabCtrlData->mpListBox ) delete mpTabCtrlData->mpListBox; - if ( mpTabCtrlData->mpLeftBtn ) - delete mpTabCtrlData->mpLeftBtn; - if ( mpTabCtrlData->mpRightBtn ) - delete mpTabCtrlData->mpRightBtn; delete mpTabCtrlData; } } @@ -325,74 +285,6 @@ ImplTabItem* TabControl::ImplGetItem( USHORT nId ) const // ----------------------------------------------------------------------- -void TabControl::ImplScrollBtnsColor() -{ - if ( mpTabCtrlData && mpTabCtrlData->mpLeftBtn ) - { - mpTabCtrlData->mpLeftBtn->SetControlForeground(); - mpTabCtrlData->mpRightBtn->SetControlForeground(); - } -} - -// ----------------------------------------------------------------------- - -void TabControl::ImplSetScrollBtnsState() -{ - if ( mbScroll ) - { - mpTabCtrlData->mpLeftBtn->Enable( mnFirstPagePos != 0 ); - mpTabCtrlData->mpRightBtn->Enable( mnFirstPagePos < mnLastFirstPagePos ); - } -} - -// ----------------------------------------------------------------------- - -void TabControl::ImplPosScrollBtns() -{ - if ( mbScroll ) - { - if ( !mpTabCtrlData->mpLeftBtn ) - { - mpTabCtrlData->mpLeftBtn = new PushButton( this, WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOPOINTERFOCUS | WB_REPEAT ); - mpTabCtrlData->mpLeftBtn->SetSymbol( SYMBOL_PREV ); - mpTabCtrlData->mpLeftBtn->SetClickHdl( LINK( this, TabControl, ImplScrollBtnHdl ) ); - } - if ( !mpTabCtrlData->mpRightBtn ) - { - mpTabCtrlData->mpRightBtn = new PushButton( this, WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOPOINTERFOCUS | WB_REPEAT ); - mpTabCtrlData->mpRightBtn->SetSymbol( SYMBOL_NEXT ); - mpTabCtrlData->mpRightBtn->SetClickHdl( LINK( this, TabControl, ImplScrollBtnHdl ) ); - } - - Rectangle aRect = ImplGetTabRect( TAB_PAGERECT ); - aRect.Left() -= TAB_OFFSET; - aRect.Top() -= TAB_OFFSET; - aRect.Right() += TAB_OFFSET; - aRect.Bottom() += TAB_OFFSET; - long nX = aRect.Right()-mnBtnSize+1; - long nY = aRect.Top()-mnBtnSize; - mpTabCtrlData->mpRightBtn->SetPosSizePixel( nX, nY, mnBtnSize, mnBtnSize ); - nX -= mnBtnSize; - mpTabCtrlData->mpLeftBtn->SetPosSizePixel( nX, nY, mnBtnSize, mnBtnSize ); - ImplScrollBtnsColor(); - ImplSetScrollBtnsState(); - mpTabCtrlData->mpLeftBtn->Show(); - mpTabCtrlData->mpRightBtn->Show(); - } - else - { - if ( mpTabCtrlData ) - { - if ( mpTabCtrlData->mpLeftBtn ) - mpTabCtrlData->mpLeftBtn->Hide(); - if ( mpTabCtrlData->mpRightBtn ) - mpTabCtrlData->mpRightBtn->Hide(); - } - } -} - -// ----------------------------------------------------------------------- - Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) { pItem->maFormatText = pItem->maText; @@ -411,15 +303,14 @@ Size TabControl::ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth ) aSize.Width() += TAB_TABOFFSET_X*2; aSize.Height() += TAB_TABOFFSET_Y*2; - Region aCtrlRegion( Rectangle( (const Point&)Point( 0, 0 ), aSize ) ); - Region aBoundingRgn, aContentRgn; - const ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); + Rectangle aCtrlRegion( Point( 0, 0 ), aSize ); + Rectangle aBoundingRgn, aContentRgn; + const ImplControlValue aControlValue; if(GetNativeControlRegion( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, aCtrlRegion, CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn ) ) { - Rectangle aCont(aContentRgn.GetBoundRect()); - return aCont.GetSize(); + return aContentRgn.GetSize(); } // For systems without synthetic bold support @@ -527,8 +418,6 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight nMaxWidth = mnMaxPageWidth; nMaxWidth -= GetItemsOffset().X(); - mbScroll = FALSE; - USHORT nLines = 0; USHORT nCurLine = 0; long nLineWidthAry[100]; @@ -653,8 +542,6 @@ Rectangle TabControl::ImplGetTabRect( USHORT nItemPos, long nWidth, long nHeight mnLastWidth = nWidth; mnLastHeight = nHeight; mbFormat = FALSE; - - ImplPosScrollBtns(); } return size_t(nItemPos) < mpTabCtrlData->maItemList.size() ? mpTabCtrlData->maItemList[nItemPos].maRect : Rectangle(); @@ -706,11 +593,9 @@ void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId ) if ( pOldPage ) { if ( mbRestoreHelpId ) - pCtrlParent->SetHelpId( 0 ); + pCtrlParent->SetHelpId( rtl::OString() ); if ( mbRestoreUnqId ) - pCtrlParent->SetUniqueId( 0 ); - if( mbRestoreSmartId ) - pCtrlParent->SetSmartHelpId( SmartId() ); + pCtrlParent->SetUniqueId( rtl::OString() ); pOldPage->DeactivatePage(); } @@ -720,21 +605,16 @@ void TabControl::ImplChangeTabPage( USHORT nId, USHORT nOldId ) // activate page here so the conbtrols can be switched // also set the help id of the parent window to that of the tab page - if ( !GetHelpId() ) + if ( !GetHelpId().getLength() ) { mbRestoreHelpId = TRUE; pCtrlParent->SetHelpId( pPage->GetHelpId() ); } - if ( !pCtrlParent->GetUniqueId() ) + if ( !pCtrlParent->GetUniqueId().getLength() ) { mbRestoreUnqId = TRUE; pCtrlParent->SetUniqueId( pPage->GetUniqueId() ); } - if( ! GetSmartHelpId().HasAny() ) - { - mbRestoreSmartId = TRUE; - pCtrlParent->SetSmartHelpId( pPage->GetSmartHelpId() ); - } pPage->ActivatePage(); @@ -805,13 +685,6 @@ void TabControl::ImplActivateTabPage( BOOL bNext ) // ----------------------------------------------------------------------- -void TabControl::ImplSetFirstPagePos( USHORT ) -{ - return; // was only required for single line -} - -// ----------------------------------------------------------------------- - void TabControl::ImplShowFocus() { if ( !GetPageCount() || mpTabCtrlData->mpListBox ) @@ -938,8 +811,7 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo if( !bLayout && (bNativeOK = IsNativeControlSupported(CTRL_TAB_ITEM, PART_ENTIRE_CONTROL)) == TRUE ) { - ImplControlValue aControlValue; - Region aCtrlRegion( pItem->maRect ); + Rectangle aCtrlRegion( pItem->maRect ); ControlState nState = 0; if( pItem->mnId == mnCurPageId ) @@ -974,10 +846,9 @@ void TabControl::ImplDrawItem( ImplTabItem* pItem, const Rectangle& rCurRect, bo tiValue.mnAlignment |= TABITEM_FIRST_IN_GROUP; if ( bLastInGroup ) tiValue.mnAlignment |= TABITEM_LAST_IN_GROUP; - aControlValue.setOptionalVal( (void *)(&tiValue) ); bNativeOK = DrawNativeControl( CTRL_TAB_ITEM, PART_ENTIRE_CONTROL, aCtrlRegion, nState, - aControlValue, rtl::OUString() ); + tiValue, rtl::OUString() ); } if( ! bLayout && !bNativeOK ) @@ -1113,14 +984,6 @@ long TabControl::ImplHandleKeyEvent( const KeyEvent& rKeyEvent ) // ----------------------------------------------------------------------- -IMPL_LINK( TabControl, ImplScrollBtnHdl, PushButton*, EMPTYARG ) -{ - ImplSetScrollBtnsState(); - return 0; -} - -// ----------------------------------------------------------------------- - IMPL_LINK( TabControl, ImplListBoxSelectHdl, ListBox*, EMPTYARG ) { SelectTabPage( GetPageId( mpTabCtrlData->mpListBox->GetSelectEntryPos() ) ); @@ -1236,7 +1099,7 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout ) BOOL bNativeOK = FALSE; if( ! bLayout && (bNativeOK = IsNativeControlSupported( CTRL_TAB_PANE, PART_ENTIRE_CONTROL) ) == TRUE ) { - const ImplControlValue aControlValue( BUTTONVALUE_DONTKNOW, rtl::OUString(), 0 ); + const ImplControlValue aControlValue; ControlState nState = CTRL_STATE_ENABLED; int part = PART_ENTIRE_CONTROL; @@ -1250,10 +1113,8 @@ void TabControl::ImplPaint( const Rectangle& rRect, bool bLayout ) if( !rRect.IsEmpty() ) aClipRgn.Intersect( rRect ); - Region aCtrlRegion( aRect ); - Rectangle aClipRect( aClipRgn.GetBoundRect() ); - if( !aClipRgn.IsEmpty() ) //&& aClipRect.getHeight() && aClipRect.getWidth() ) - bNativeOK = DrawNativeControl( CTRL_TAB_PANE, part, aCtrlRegion, nState, + if( !aClipRgn.IsEmpty() ) + bNativeOK = DrawNativeControl( CTRL_TAB_PANE, part, aRect, nState, aControlValue, rtl::OUString() ); } else @@ -1401,19 +1262,14 @@ void TabControl::Resize() // Feststellen, was invalidiert werden muss Size aNewSize = Control::GetOutputSizePixel(); long nNewWidth = aNewSize.Width(); - if ( mbScroll ) - mbSmallInvalidate = FALSE; - else + for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); + it != mpTabCtrlData->maItemList.end(); ++it ) { - for( std::vector< ImplTabItem >::iterator it = mpTabCtrlData->maItemList.begin(); - it != mpTabCtrlData->maItemList.end(); ++it ) + if ( !it->mbFullVisible || + (it->maRect.Right()-2 >= nNewWidth) ) { - if ( !it->mbFullVisible || - (it->maRect.Right()-2 >= nNewWidth) ) - { - mbSmallInvalidate = FALSE; - break; - } + mbSmallInvalidate = FALSE; + break; } } @@ -1491,13 +1347,13 @@ void TabControl::RequestHelp( const HelpEvent& rHEvt ) } else if ( rHEvt.GetMode() & HELPMODE_EXTENDED ) { - ULONG nHelpId = GetHelpId( nItemId ); - if ( nHelpId ) + rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) ); + if ( aHelpId.getLength() ) { // Wenn eine Hilfe existiert, dann ausloesen Help* pHelp = Application::GetHelp(); if ( pHelp ) - pHelp->Start( nHelpId, this ); + pHelp->Start( aHelpId, this ); return; } } @@ -1579,7 +1435,7 @@ void TabControl::Command( const CommandEvent& rCEvt ) aMenu.InsertItem( it->mnId, it->maText, MIB_CHECKABLE | MIB_RADIOCHECK ); if ( it->mnId == mnCurPageId ) aMenu.CheckItem( it->mnId ); - aMenu.SetHelpId( it->mnId, it->mnHelpId ); + aMenu.SetHelpId( it->mnId, it->maHelpId ); } USHORT nId = aMenu.Execute( this, aMenuPos ); @@ -1831,7 +1687,6 @@ void TabControl::InsertPage( USHORT nPageId, const XubString& rText, pItem->mnId = nPageId; pItem->mpTabPage = NULL; pItem->mnTabPageResId = 0; - pItem->mnHelpId = 0; pItem->maText = rText; pItem->mbFullVisible = FALSE; @@ -2028,13 +1883,6 @@ USHORT TabControl::GetCurPageId() const // ----------------------------------------------------------------------- -void TabControl::SetFirstPageId( USHORT ) -{ - return; // was only required for single line -} - -// ----------------------------------------------------------------------- - void TabControl::SelectTabPage( USHORT nPageId ) { if ( nPageId && (nPageId != mnCurPageId) ) @@ -2159,11 +2007,11 @@ const XubString& TabControl::GetHelpText( USHORT nPageId ) const if ( pItem ) { - if ( !pItem->maHelpText.Len() && pItem->mnHelpId ) + if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() ) { Help* pHelp = Application::GetHelp(); if ( pHelp ) - pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this ); + pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this ); } return pItem->maHelpText; @@ -2174,24 +2022,25 @@ const XubString& TabControl::GetHelpText( USHORT nPageId ) const // ----------------------------------------------------------------------- -void TabControl::SetHelpId( USHORT nPageId, ULONG nHelpId ) +void TabControl::SetHelpId( USHORT nPageId, const rtl::OString& rHelpId ) { ImplTabItem* pItem = ImplGetItem( nPageId ); if ( pItem ) - pItem->mnHelpId = nHelpId; + pItem->maHelpId = rHelpId; } // ----------------------------------------------------------------------- -ULONG TabControl::GetHelpId( USHORT nPageId ) const +rtl::OString TabControl::GetHelpId( USHORT nPageId ) const { + rtl::OString aRet; ImplTabItem* pItem = ImplGetItem( nPageId ); if ( pItem ) - return pItem->mnHelpId; - else - return 0; + aRet = pItem->maHelpId; + + return aRet; } // ----------------------------------------------------------------------- diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 468d4be36b0a..43f24e5026ea 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -1397,6 +1397,7 @@ static void FindCmap(TrueTypeFont *ttf) sal_uInt32 table_size = getTableSize(ttf, O_cmap); sal_uInt16 ncmaps = GetUInt16(table, 2, 1); unsigned int i; + sal_uInt32 AppleUni = 0; // Apple Unicode sal_uInt32 ThreeZero = 0; /* MS Symbol */ sal_uInt32 ThreeOne = 0; /* MS UCS-2 */ sal_uInt32 ThreeTwo = 0; /* MS ShiftJIS */ @@ -1423,7 +1424,7 @@ static void FindCmap(TrueTypeFont *ttf) /* Unicode tables in Apple fonts */ if (pID == 0) { - ThreeOne = offset; break; + AppleUni = offset; } if (pID == 3) { @@ -1440,6 +1441,10 @@ static void FindCmap(TrueTypeFont *ttf) } } + // fall back to AppleUnicode if there are no ThreeOne/Threezero tables + if( AppleUni && !ThreeZero && !ThreeOne) + ThreeOne = AppleUni; + if (ThreeOne) { ttf->cmapType = CMAP_MS_Unicode; ttf->cmap = table + ThreeOne; diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx index 9e2a21b43e37..ec476157fbeb 100644 --- a/vcl/source/gdi/bitmap3.cxx +++ b/vcl/source/gdi/bitmap3.cxx @@ -961,8 +961,8 @@ BOOL Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) const long nScanlineSize = pWriteAcc->GetScanlineSize(); const long nNewWidth1 = nNewWidth - 1L; const long nNewHeight1 = nNewHeight - 1L; - const long nWidth1 = pReadAcc->Width() - 1L; - const long nHeight1 = pReadAcc->Height() - 1L; + const long nWidth = pReadAcc->Width(); + const long nHeight = pReadAcc->Height(); long* pLutX = new long[ nNewWidth ]; long* pLutY = new long[ nNewHeight ]; long nX, nY, nMapY, nActY = 0L; @@ -970,10 +970,10 @@ BOOL Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) if( nNewWidth1 && nNewHeight1 ) { for( nX = 0L; nX < nNewWidth; nX++ ) - pLutX[ nX ] = nX * nWidth1 / nNewWidth1; + pLutX[ nX ] = nX * nWidth / nNewWidth; for( nY = 0L; nY < nNewHeight; nY++ ) - pLutY[ nY ] = nY * nHeight1 / nNewHeight1; + pLutY[ nY ] = nY * nHeight / nNewHeight; while( nActY < nNewHeight ) { diff --git a/vcl/source/gdi/bmpconv.cxx b/vcl/source/gdi/bmpconv.cxx index d949f519d197..188b4e49f0c5 100644 --- a/vcl/source/gdi/bmpconv.cxx +++ b/vcl/source/gdi/bmpconv.cxx @@ -28,14 +28,14 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <vcl/bitmap.hxx> -#include <vcl/impbmpconv.hxx> -#include <vcl/svapp.hxx> -#include <vos/mutex.hxx> -#include <tools/stream.hxx> -#include <com/sun/star/script/XInvocation.hpp> -#include <com/sun/star/awt/XBitmap.hpp> -#include <cppuhelper/compbase1.hxx> +#include "vcl/bitmap.hxx" +#include "vcl/svapp.hxx" +#include "vcl/salctype.hxx" +#include "vos/mutex.hxx" +#include "tools/stream.hxx" +#include "com/sun/star/script/XInvocation.hpp" +#include "com/sun/star/awt/XBitmap.hpp" +#include "cppuhelper/compbase1.hxx" using namespace com::sun::star::uno; diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 01b34286a086..d36a18a1afba 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -841,6 +841,49 @@ void GDIMetaFile::Move( long nX, long nY ) } } +void GDIMetaFile::Move( long nX, long nY, long nDPIX, long nDPIY ) +{ + const Size aBaseOffset( nX, nY ); + Size aOffset( aBaseOffset ); + VirtualDevice aMapVDev; + + aMapVDev.EnableOutput( FALSE ); + aMapVDev.SetReferenceDevice( nDPIX, nDPIY ); + aMapVDev.SetMapMode( GetPrefMapMode() ); + + for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) + { + const long nType = pAct->GetType(); + MetaAction* pModAct; + + if( pAct->GetRefCount() > 1 ) + { + Replace( pModAct = pAct->Clone(), GetCurPos() ); + pAct->Delete(); + } + else + pModAct = pAct; + + if( ( META_MAPMODE_ACTION == nType ) || + ( META_PUSH_ACTION == nType ) || + ( META_POP_ACTION == nType ) ) + { + pModAct->Execute( &aMapVDev ); + if( aMapVDev.GetMapMode().GetMapUnit() == MAP_PIXEL ) + { + aOffset = aMapVDev.LogicToPixel( aBaseOffset, GetPrefMapMode() ); + MapMode aMap( aMapVDev.GetMapMode() ); + aOffset.Width() = static_cast<long>(aOffset.Width() * (double)aMap.GetScaleX()); + aOffset.Height() = static_cast<long>(aOffset.Height() * (double)aMap.GetScaleY()); + } + else + aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() ); + } + + pModAct->Move( aOffset.Width(), aOffset.Height() ); + } +} + // ------------------------------------------------------------------------ void GDIMetaFile::Scale( double fScaleX, double fScaleY ) diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx index 4d32990f9335..60ad94a63273 100644 --- a/vcl/source/gdi/gfxlink.cxx +++ b/vcl/source/gdi/gfxlink.cxx @@ -28,6 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" +#include <osl/file.h> #include <tools/vcompat.hxx> #include <tools/urlobj.hxx> #include <tools/debug.hxx> @@ -398,12 +399,10 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : { ::utl::TempFile aTempFile; - maURL = INetURLObject(aTempFile.GetURL()); - - if( maURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() ) + maURL = aTempFile.GetURL(); + if( maURL.getLength() ) { - SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); - + SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); if( pOStm ) { pOStm->Write( pData, mnDataSize ); @@ -412,28 +411,8 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : if( bError ) { - try - { - ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ), - ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); - - aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), - ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); - } - catch( const ::com::sun::star::ucb::ContentCreationException& ) - { - } - catch( const ::com::sun::star::uno::RuntimeException& ) - { - } - catch( const ::com::sun::star::ucb::CommandAbortedException& ) - { - } - catch( const ::com::sun::star::uno::Exception& ) - { - } - - maURL = INetURLObject(); + osl_removeFile( maURL.pData ); + maURL = String(); } } } @@ -445,28 +424,7 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : ImpSwap::~ImpSwap() { if( IsSwapped() ) - { - try - { - ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ), - ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); - - aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), - ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); - } - catch( const ::com::sun::star::ucb::ContentCreationException& ) - { - } - catch( const ::com::sun::star::uno::RuntimeException& ) - { - } - catch( const ::com::sun::star::ucb::CommandAbortedException& ) - { - } - catch( const ::com::sun::star::uno::Exception& ) - { - } - } + osl_removeFile( maURL.pData ); } // ------------------------------------------------------------------------ @@ -477,8 +435,7 @@ BYTE* ImpSwap::GetData() const if( IsSwapped() ) { - SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE ); - + SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE ); if( pIStm ) { pData = new BYTE[ mnDataSize ]; diff --git a/vcl/source/gdi/imgcons.cxx b/vcl/source/gdi/imgcons.cxx deleted file mode 100644 index 0826c5f2310b..000000000000 --- a/vcl/source/gdi/imgcons.cxx +++ /dev/null @@ -1,574 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#include <tools/stream.hxx> -#include <vcl/bmpacc.hxx> -#include <vcl/bitmapex.hxx> -#include <vcl/image.hxx> -#include <vcl/imgcons.hxx> - -// ------------------- -// - ImplColorMapper - -// ------------------- - -class ImplColorMapper -{ - Color maCol; - ULONG mnR; - ULONG mnG; - ULONG mnB; - ULONG mnT; - ULONG mnRShift; - ULONG mnGShift; - ULONG mnBShift; - ULONG mnTShift; - - ULONG ImplCalcMaskShift( ULONG nVal ); - -public: - - ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ); - ~ImplColorMapper(); - - const Color& ImplGetColor( ULONG nColor ) - { - maCol.SetRed( (UINT8) ( ( nColor & mnR ) >> mnRShift ) ); - maCol.SetGreen( (UINT8) ( ( nColor & mnG ) >> mnGShift ) ); - maCol.SetBlue( (UINT8) ( ( nColor & mnB ) >> mnBShift ) ); - maCol.SetTransparency( (UINT8) ( ( nColor & mnT ) >> mnTShift ) ); - return maCol; - } -}; - -// ----------------------------------------------------------------------------- - -ImplColorMapper::ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ) : - mnR( nRMask ), - mnG( nGMask ), - mnB( nBMask ), - mnT( nTMask ) -{ - mnRShift = ImplCalcMaskShift( mnR ); - mnGShift = ImplCalcMaskShift( mnG ); - mnBShift = ImplCalcMaskShift( mnB ); - mnTShift = ImplCalcMaskShift( mnT ); -} - -// ----------------------------------------------------------------------------- - -ImplColorMapper::~ImplColorMapper() -{ -} - -// ----------------------------------------------------------------------------- - -ULONG ImplColorMapper::ImplCalcMaskShift( ULONG nVal ) -{ - DBG_ASSERT( nVal > 0, "Mask has no value!" ); - - ULONG nRet = 0UL; - - for( ULONG i = 0UL; i < 32; i++ ) - { - if( nVal & ( 1UL << i ) ) - { - nRet = i; - break; - } - } - - return nRet; -} - -// ----------------- -// - ImageConsumer - -// ----------------- - -ImageConsumer::ImageConsumer() : - mpMapper( NULL ), - mpPal ( NULL ), - mnStatus( 0UL ), - mbTrans ( FALSE ) -{ -} - -// ----------------------------------------------------------------------------- - -ImageConsumer::~ImageConsumer() -{ - delete[] mpPal; - delete mpMapper; -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::Init( sal_uInt32 nWidth, sal_uInt32 nHeight ) -{ - maSize = Size( nWidth, nHeight ); - maBitmap = maMask = Bitmap(); - mnStatus = 0UL; - mbTrans = FALSE; -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetColorModel( USHORT nBitCount, - sal_uInt32 nPalEntries, const sal_uInt32* pRGBAPal, - sal_uInt32 nRMask, sal_uInt32 nGMask, sal_uInt32 nBMask, sal_uInt32 nAMask ) -{ - DBG_ASSERT( maSize.Width() && maSize.Height(), "Missing call to ImageConsumer::Init(...)!" ); - - BitmapPalette aPal( Min( (USHORT) nPalEntries, (USHORT) 256 ) ); - - if( nPalEntries ) - { - BitmapColor aCol; - const sal_Int32* pTmp = (sal_Int32*) pRGBAPal; - - delete mpMapper; - mpMapper = NULL; - - delete[] mpPal; - mpPal = new Color[ nPalEntries ]; - - for( ULONG i = 0; i < nPalEntries; i++, pTmp++ ) - { - Color& rCol = mpPal[ i ]; - BYTE cVal; - - cVal = (BYTE) ( ( *pTmp & 0xff000000UL ) >> 24L ); - rCol.SetRed( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetRed( cVal ); - - cVal = (BYTE) ( ( *pTmp & 0x00ff0000UL ) >> 16L ); - rCol.SetGreen( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetGreen( cVal ); - - cVal = (BYTE) ( ( *pTmp & 0x0000ff00UL ) >> 8L ); - rCol.SetBlue( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetBlue( cVal ); - - rCol.SetTransparency( (BYTE) ( ( *pTmp & 0x000000ffL ) ) ); - } - - if( nBitCount <= 1 ) - nBitCount = 1; - else if( nBitCount <= 4 ) - nBitCount = 4; - else if( nBitCount <= 8 ) - nBitCount = 8; - else - nBitCount = 24; - } - else - { - delete mpMapper; - mpMapper = new ImplColorMapper( nRMask, nGMask, nBMask, nAMask ); - - delete[] mpPal; - mpPal = NULL; - - nBitCount = 24; - } - - if( !maBitmap ) - { - - maBitmap = Bitmap( maSize, nBitCount, &aPal ); - maMask = Bitmap( maSize, 1 ); - maMask.Erase( COL_BLACK ); - mbTrans = FALSE; - } -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetPixelsByBytes( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const BYTE* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize ) -{ - DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" ); - - BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess(); - BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess(); - sal_Bool bDataChanged = sal_False; - - if( pBmpAcc && pMskAcc ) - { - const long nWidth = pBmpAcc->Width(); - const long nHeight = pBmpAcc->Height(); - - maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) ); - maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) ); - - if( !maChangedRect.IsEmpty() ) - { - const long nStartX = maChangedRect.Left(); - const long nEndX = maChangedRect.Right(); - const long nStartY = maChangedRect.Top(); - const long nEndY = maChangedRect.Bottom(); - - if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const Color& rCol = mpMapper->ImplGetColor( *pTmp++ ); - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) ) - { - BitmapColor aIndex( (BYTE) 0 ); - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const BYTE cIndex = *pTmp++; - const Color& rCol = mpPal[ cIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aIndex.SetIndex( cIndex ); - pBmpAcc->SetPixel( nY, nX, aIndex ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const BYTE cIndex = *pTmp++; - const Color& rCol = mpPal[ cIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else - { - DBG_ERROR( "Producer format error!" ); - maChangedRect.SetEmpty(); - } - } - } - else - maChangedRect.SetEmpty(); - - maBitmap.ReleaseAccess( pBmpAcc ); - maMask.ReleaseAccess( pMskAcc ); - - if( bDataChanged ) - DataChanged(); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetPixelsByLongs( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const sal_uInt32* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize ) -{ - DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" ); - - BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess(); - BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess(); - sal_Bool bDataChanged = sal_False; - - if( pBmpAcc && pMskAcc ) - { - const long nWidth = pBmpAcc->Width(); - const long nHeight = pBmpAcc->Height(); - - maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) ); - maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) ); - - if( !maChangedRect.IsEmpty() ) - { - const long nStartX = maChangedRect.Left(); - const long nEndX = maChangedRect.Right(); - const long nStartY = maChangedRect.Top(); - const long nEndY = maChangedRect.Bottom(); - - if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const Color& rCol = mpMapper->ImplGetColor( *pTmp++ ); - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) ) - { - BitmapColor aIndex( (BYTE) 0 ); - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const sal_Int32 nIndex = *pTmp++; - const Color& rCol = mpPal[ nIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aIndex.SetIndex( (BYTE) nIndex ); - pBmpAcc->SetPixel( nY, nX, aIndex ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const sal_Int32 nIndex = *pTmp++; - const Color& rCol = mpPal[ nIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else - { - DBG_ERROR( "Producer format error!" ); - maChangedRect.SetEmpty(); - } - } - } - else - maChangedRect.SetEmpty(); - - maBitmap.ReleaseAccess( pBmpAcc ); - maMask.ReleaseAccess( pMskAcc ); - - if( bDataChanged ) - DataChanged(); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::Completed( sal_uInt32 nStatus /*, ImageProducer& rProducer */ ) -{ - delete mpMapper; - mpMapper = NULL; - delete[] mpPal; - mpPal = NULL; - maSize = Size(); - mnStatus = nStatus; - - switch( nStatus ) - { - case( SINGLEFRAMEDONE ): - case( STATICIMAGEDONE ): - { - if( !mbTrans ) - maMask = Bitmap(); - } - break; - - case( IMAGEERROR ): - case( IMAGEABORTED ): - maBitmap = maMask = Bitmap(); - break; - - default: - break; - } - -// rProducer.RemoveConsumer( *this ); - - if( maDoneLink.IsSet() ) - maDoneLink.Call( this ); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::DataChanged() -{ - if( maChgLink.IsSet() ) - maChgLink.Call( this ); -} - -// ----------------------------------------------------------------------------- - -sal_uInt32 ImageConsumer::GetStatus() const -{ - return mnStatus; -} - -// ----------------------------------------------------------------------------- - -BOOL ImageConsumer::GetData( BitmapEx& rBmpEx ) const -{ - const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus ); - - if( bRet ) - { - if( !!maMask ) - rBmpEx = BitmapEx( maBitmap, maMask ); - else - rBmpEx = BitmapEx( maBitmap ); - } - - return bRet; -} - -// ----------------------------------------------------------------------------- - -BOOL ImageConsumer::GetData( Image& rImage ) const -{ - const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus ); - - if( bRet ) - { - if( !!maMask ) - rImage = Image( maBitmap, maMask ); - else - rImage = Image( maBitmap ); - } - - return bRet; -} diff --git a/vcl/source/gdi/impimage.cxx b/vcl/source/gdi/impimage.cxx index 476ac3ca44a9..3105850c4fbf 100644 --- a/vcl/source/gdi/impimage.cxx +++ b/vcl/source/gdi/impimage.cxx @@ -553,14 +553,14 @@ void ImplImageBmp::Draw( USHORT nPos, OutputDevice* pOutDev, // ----------------------------------------------------------------------- void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice* -#if defined WIN || defined WNT +#if defined WNT pOutDev #endif ) { if( !mpDisplayBmp && !maBmpEx.IsEmpty() ) { -#if defined WIN || defined WNT +#if defined WNT if( maBmpEx.IsAlpha() ) mpDisplayBmp = new BitmapEx( maBmpEx ); else diff --git a/vcl/source/gdi/impprn.cxx b/vcl/source/gdi/impprn.cxx deleted file mode 100644 index 5224286cdad1..000000000000 --- a/vcl/source/gdi/impprn.cxx +++ /dev/null @@ -1,584 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#define _SPOOLPRINTER_EXT -#include "tools/queue.hxx" -#include "vcl/svapp.hxx" -#include "vcl/metaact.hxx" -#include "vcl/gdimtf.hxx" -#include "vcl/timer.hxx" -#include "vcl/impprn.hxx" -#include "vcl/jobset.h" - -#include "vcl/svdata.hxx" -#include "vcl/salprn.hxx" - -// ----------- -// - Defines - -// ----------- - -#define OPTIMAL_BMP_RESOLUTION 300 -#define NORMAL_BMP_RESOLUTION 200 - -// ======================================================================= - -struct QueuePage -{ - GDIMetaFile* mpMtf; - JobSetup* mpSetup; - USHORT mnPage; - BOOL mbEndJob; - - QueuePage() { mpMtf = NULL; mpSetup = NULL; } - ~QueuePage() { delete mpMtf; if ( mpSetup ) delete mpSetup; } -}; - -// ======================================================================= - -ImplQPrinter::ImplQPrinter( Printer* pParent ) : - Printer( pParent->GetName() ), - mpParent( pParent ), - mbAborted( false ), - mbUserCopy( false ), - mbDestroyAllowed( true ), - mbDestroyed( false ), - mnMaxBmpDPIX( mnDPIX ), - mnMaxBmpDPIY( mnDPIY ), - mnCurCopyCount( 0 ) -{ - SetSelfAsQueuePrinter( TRUE ); - SetPrinterProps( pParent ); - SetPageQueueSize( 0 ); - mnCopyCount = pParent->mnCopyCount; - mbCollateCopy = pParent->mbCollateCopy; -} - -// ----------------------------------------------------------------------- - -ImplQPrinter::~ImplQPrinter() -{ - for( std::vector< QueuePage* >::iterator it = maQueue.begin(); - it != maQueue.end(); ++it ) - delete (*it); -} - -// ----------------------------------------------------------------------------- - -void ImplQPrinter::Destroy() -{ - if( mbDestroyAllowed ) - delete this; - else - mbDestroyed = TRUE; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::ImplPrintMtf( GDIMetaFile& rPrtMtf, long nMaxBmpDPIX, long nMaxBmpDPIY ) -{ - for( MetaAction* pAct = rPrtMtf.FirstAction(); pAct && !mbAborted; pAct = rPrtMtf.NextAction() ) - { - const ULONG nType = pAct->GetType(); - sal_Bool bExecuted = sal_False; - - if( nType == META_COMMENT_ACTION ) - { - // search for special comments ( ..._BEGIN/..._END ) - MetaCommentAction* pComment = (MetaCommentAction*) pAct; - - if( pComment->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) - { - pAct = rPrtMtf.NextAction(); - - // if next action is a GradientEx action, execute this and - // skip actions until a XGRAD_SEQ_END comment is found - if( pAct && ( pAct->GetType() == META_GRADIENTEX_ACTION ) ) - { - MetaGradientExAction* pGradientExAction = (MetaGradientExAction*) pAct; - DrawGradientEx( this, pGradientExAction->GetPolyPolygon(), pGradientExAction->GetGradient() ); - - // seek to end of this comment - do - { - pAct = rPrtMtf.NextAction(); - } - while( pAct && - ( ( pAct->GetType() != META_COMMENT_ACTION ) || - ( ( (MetaCommentAction*) pAct )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) != COMPARE_EQUAL ) ) ); - - bExecuted = sal_True; - } - } - else if( pComment->GetComment().CompareIgnoreCaseToAscii( "PRNSPOOL_TRANSPARENTBITMAP_BEGIN" ) == COMPARE_EQUAL ) - { - pAct = rPrtMtf.NextAction(); - - if( pAct && ( pAct->GetType() == META_BMPSCALE_ACTION ) ) - { - // execute action here to avoid DPI processing of bitmap; - pAct->Execute( this ); - -#ifdef VERBOSE_DEBUG - Push(); - SetLineColor(COL_RED); - SetFillColor(); - DrawRect( Rectangle( - static_cast<MetaBmpScaleAction*>(pAct)->GetPoint(), - static_cast<MetaBmpScaleAction*>(pAct)->GetSize()) ); - Pop(); -#endif - - // seek to end of this comment - do - { - pAct = rPrtMtf.NextAction(); - } - while( pAct && - ( ( pAct->GetType() != META_COMMENT_ACTION ) || - ( ( (MetaCommentAction*) pAct )->GetComment().CompareIgnoreCaseToAscii( "PRNSPOOL_TRANSPARENTBITMAP_END" ) != COMPARE_EQUAL ) ) ); - - bExecuted = sal_True; - } - } - } - else if( nType == META_GRADIENT_ACTION ) - { - MetaGradientAction* pGradientAction = (MetaGradientAction*) pAct; - DrawGradientEx( this, pGradientAction->GetRect(), pGradientAction->GetGradient() ); - bExecuted = sal_True; - } - else if( nType == META_BMPSCALE_ACTION ) - { - MetaBmpScaleAction* pBmpScaleAction = (MetaBmpScaleAction*) pAct; - const Bitmap& rBmp = pBmpScaleAction->GetBitmap(); - - DrawBitmap( pBmpScaleAction->GetPoint(), pBmpScaleAction->GetSize(), - GetDownsampledBitmap( pBmpScaleAction->GetSize(), - Point(), rBmp.GetSizePixel(), - rBmp, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPSCALEPART_ACTION ) - { - MetaBmpScalePartAction* pBmpScalePartAction = (MetaBmpScalePartAction*) pAct; - const Bitmap& rBmp = pBmpScalePartAction->GetBitmap(); - - DrawBitmap( pBmpScalePartAction->GetDestPoint(), pBmpScalePartAction->GetDestSize(), - GetDownsampledBitmap( pBmpScalePartAction->GetDestSize(), - pBmpScalePartAction->GetSrcPoint(), pBmpScalePartAction->GetSrcSize(), - rBmp, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPEXSCALE_ACTION ) - { - MetaBmpExScaleAction* pBmpExScaleAction = (MetaBmpExScaleAction*) pAct; - const BitmapEx& rBmpEx = pBmpExScaleAction->GetBitmapEx(); - - DrawBitmapEx( pBmpExScaleAction->GetPoint(), pBmpExScaleAction->GetSize(), - GetDownsampledBitmapEx( pBmpExScaleAction->GetSize(), - Point(), rBmpEx.GetSizePixel(), - rBmpEx, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPEXSCALEPART_ACTION ) - { - MetaBmpExScalePartAction* pBmpExScalePartAction = (MetaBmpExScalePartAction*) pAct; - const BitmapEx& rBmpEx = pBmpExScalePartAction->GetBitmapEx(); - - DrawBitmapEx( pBmpExScalePartAction->GetDestPoint(), pBmpExScalePartAction->GetDestSize(), - GetDownsampledBitmapEx( pBmpExScalePartAction->GetDestSize(), - pBmpExScalePartAction->GetSrcPoint(), pBmpExScalePartAction->GetSrcSize(), - rBmpEx, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_TRANSPARENT_ACTION ) - { - MetaTransparentAction* pTransAct = static_cast<MetaTransparentAction*>(pAct); - USHORT nTransparency( pTransAct->GetTransparence() ); - - // #i10613# Respect transparency for draw color - if( nTransparency ) - { - Push( PUSH_LINECOLOR|PUSH_FILLCOLOR ); - - // assume white background for alpha blending - Color aLineColor( GetLineColor() ); - aLineColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetRed()) / 100L ) ); - aLineColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetGreen()) / 100L ) ); - aLineColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetBlue()) / 100L ) ); - SetLineColor( aLineColor ); - - Color aFillColor( GetFillColor() ); - aFillColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetRed()) / 100L ) ); - aFillColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetGreen()) / 100L ) ); - aFillColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetBlue()) / 100L ) ); - SetFillColor( aFillColor ); - } - - DrawPolyPolygon( pTransAct->GetPolyPolygon() ); - - if( nTransparency ) - Pop(); - - bExecuted = sal_True; - } - else if( nType == META_FLOATTRANSPARENT_ACTION ) - { - MetaFloatTransparentAction* pFloatAction = (MetaFloatTransparentAction*) pAct; - GDIMetaFile& rMtf = (GDIMetaFile&) pFloatAction->GetGDIMetaFile(); - MapMode aDrawMap( rMtf.GetPrefMapMode() ); - Point aDestPoint( LogicToPixel( pFloatAction->GetPoint() ) ); - Size aDestSize( LogicToPixel( pFloatAction->GetSize() ) ); - - if( aDestSize.Width() && aDestSize.Height() ) - { - Size aTmpPrefSize( LogicToPixel( rMtf.GetPrefSize(), aDrawMap ) ); - - if( !aTmpPrefSize.Width() ) - aTmpPrefSize.Width() = aDestSize.Width(); - - if( !aTmpPrefSize.Height() ) - aTmpPrefSize.Height() = aDestSize.Height(); - - Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() ); - Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() ); - - aDrawMap.SetScaleX( aScaleX *= aDrawMap.GetScaleX() ); - aDrawMap.SetScaleY( aScaleY *= aDrawMap.GetScaleY() ); - aDrawMap.SetOrigin( PixelToLogic( aDestPoint, aDrawMap ) ); - - Push(); - SetMapMode( aDrawMap ); - ImplPrintMtf( rMtf, nMaxBmpDPIX, nMaxBmpDPIY ); - Pop(); - } - - bExecuted = sal_True; - } - - if( !bExecuted && pAct ) - pAct->Execute( this ); - - if( ! ImplGetSVData()->maGDIData.mbPrinterPullModel ) - Application::Reschedule(); - } -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::PrePrintPage( QueuePage* pPage ) -{ - mnRestoreDrawMode = GetDrawMode(); - mnMaxBmpDPIX = mnDPIX; - mnMaxBmpDPIY = mnDPIY; - - const PrinterOptions& rPrinterOptions = GetPrinterOptions(); - - if( rPrinterOptions.IsReduceBitmaps() ) - { - // calculate maximum resolution for bitmap graphics - if( PRINTER_BITMAP_OPTIMAL == rPrinterOptions.GetReducedBitmapMode() ) - { - mnMaxBmpDPIX = Min( (long) OPTIMAL_BMP_RESOLUTION, mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) OPTIMAL_BMP_RESOLUTION, mnMaxBmpDPIY ); - } - else if( PRINTER_BITMAP_NORMAL == rPrinterOptions.GetReducedBitmapMode() ) - { - mnMaxBmpDPIX = Min( (long) NORMAL_BMP_RESOLUTION, mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) NORMAL_BMP_RESOLUTION, mnMaxBmpDPIY ); - } - else - { - mnMaxBmpDPIX = Min( (long) rPrinterOptions.GetReducedBitmapResolution(), mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) rPrinterOptions.GetReducedBitmapResolution(), mnMaxBmpDPIY ); - } - } - - // convert to greysacles - if( rPrinterOptions.IsConvertToGreyscales() ) - { - SetDrawMode( GetDrawMode() | ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | - DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); - } - - // disable transparency output - if( rPrinterOptions.IsReduceTransparency() && ( PRINTER_TRANSPARENCY_NONE == rPrinterOptions.GetReducedTransparencyMode() ) ) - { - SetDrawMode( GetDrawMode() | DRAWMODE_NOTRANSPARENCY ); - } - - maCurPageMetaFile = GDIMetaFile(); - RemoveTransparenciesFromMetaFile( *pPage->mpMtf, maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY, - rPrinterOptions.IsReduceTransparency(), - rPrinterOptions.GetReducedTransparencyMode() == PRINTER_TRANSPARENCY_AUTO, - rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency() - ); -} - -void ImplQPrinter::PostPrintPage() -{ - SetDrawMode( mnRestoreDrawMode ); -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::PrintPage( unsigned int nPage ) -{ - if( nPage >= maQueue.size() ) - return; - mnCurCopyCount = (mbUserCopy && !mbCollateCopy) ? mnCopyCount : 1; - QueuePage* pActPage = maQueue[nPage]; - PrePrintPage( pActPage ); - if ( pActPage->mpSetup ) - SetJobSetup( *pActPage->mpSetup ); - - StartPage(); - ImplPrintMtf( maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY ); - EndPage(); - - mnCurCopyCount--; - if( mnCurCopyCount == 0 ) - PostPrintPage(); -} - -// ----------------------------------------------------------------------- - -ImplJobSetup* ImplQPrinter::GetPageSetup( unsigned int nPage ) const -{ - return nPage >= maQueue.size() ? NULL : - ( maQueue[nPage]->mpSetup ? maQueue[nPage]->mpSetup->ImplGetData() : NULL ); -} - -// ----------------------------------------------------------------------- -ULONG ImplQPrinter::GetPrintPageCount() const -{ - ULONG nPageCount = maQueue.size() * ((mbUserCopy && !mbCollateCopy) ? mnCopyCount : 1); - return nPageCount; -} - -// ----------------------------------------------------------------------- - -IMPL_LINK( ImplQPrinter, ImplPrintHdl, Timer*, EMPTYARG ) -{ - // Ist Drucken abgebrochen wurden? - if( !IsPrinting() || ( mpParent->IsJobActive() && ( maQueue.size() < (ULONG)mpParent->GetPageQueueSize() ) ) ) - return 0; - - // Druck-Job zuende? - QueuePage* pActPage = maQueue.front(); - maQueue.erase( maQueue.begin() ); - - - vcl::DeletionListener aDel( this ); - if ( pActPage->mbEndJob ) - { - maTimer.Stop(); - delete pActPage; - if( ! EndJob() ) - mpParent->Error(); - if( ! aDel.isDeleted() ) - mpParent->ImplEndPrint(); - } - else - { - mbDestroyAllowed = FALSE; - - PrePrintPage( pActPage ); - - USHORT nCopyCount = 1; - if( mbUserCopy && !mbCollateCopy ) - nCopyCount = mnCopyCount; - - for ( USHORT i = 0; i < nCopyCount; i++ ) - { - if ( pActPage->mpSetup ) - { - SetJobSetup( *pActPage->mpSetup ); - if ( mbAborted ) - break; - } - - StartPage(); - - if ( mbAborted ) - break; - - ImplPrintMtf( maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY ); - - if( !mbAborted ) - EndPage(); - else - break; - } - - PostPrintPage(); - - delete pActPage; - mbDestroyAllowed = TRUE; - - if( mbDestroyed ) - Destroy(); - } - - return 0; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::StartQueuePrint() -{ - if( ! ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - maTimer.SetTimeout( 50 ); - maTimer.SetTimeoutHdl( LINK( this, ImplQPrinter, ImplPrintHdl ) ); - maTimer.Start(); - } -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::EndQueuePrint() -{ - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - DBG_ASSERT( mpPrinter, "no SalPrinter in ImplQPrinter" ); - if( mpPrinter ) - { - #if 0 - mpPrinter->StartJob( mbPrintFile ? &maPrintFile : NULL, - Application::GetDisplayName(), - maJobSetup.ImplGetConstData(), - this ); - #endif - EndJob(); - mpParent->ImplEndPrint(); - } - } - else - { - QueuePage* pQueuePage = new QueuePage; - pQueuePage->mbEndJob = TRUE; - maQueue.push_back( pQueuePage ); - } -} - -// ----------------------------------------------------------------------- - -bool ImplQPrinter::GetPaperRanges( std::vector< ULONG >& o_rRanges, bool i_bIncludeOrientationChanges ) const -{ - bool bRet = false; - - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - bRet = true; - o_rRanges.clear(); - - if( ! maQueue.empty() ) - { - ULONG nCurPage = 0; - - // get first job data - const ImplJobSetup* pLastFormat = NULL; - if( maQueue.front()->mpSetup ) - pLastFormat = maQueue.front()->mpSetup->ImplGetConstData(); - - // begin first range - o_rRanges.push_back( 0 ); - for( std::vector< QueuePage* >::const_iterator it = maQueue.begin(); - it != maQueue.end(); ++it, ++nCurPage ) - { - const ImplJobSetup* pNewSetup = (*it)->mpSetup ? (*it)->mpSetup->ImplGetConstData() : NULL; - if( pNewSetup && pNewSetup != pLastFormat ) - { - bool bChange = false; - if( pLastFormat == NULL ) - { - bChange = true; - } - else if( ! i_bIncludeOrientationChanges && - pNewSetup->meOrientation != pLastFormat->meOrientation ) - { - bChange = true; - } - else if( pNewSetup->mePaperFormat != pLastFormat->mePaperFormat || - ( pNewSetup->mePaperFormat == PAPER_USER && - ( pNewSetup->mnPaperWidth != pLastFormat->mnPaperWidth || - pNewSetup->mnPaperHeight != pLastFormat->mnPaperHeight ) ) ) - { - bChange = true; - } - else if( pNewSetup->mnPaperBin != pLastFormat->mnPaperBin ) - { - bChange = true; - } - if( bChange ) - { - o_rRanges.push_back( nCurPage ); - pLastFormat = pNewSetup; - } - } - } - - o_rRanges.push_back( nCurPage ); - } - } - - return bRet; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::AbortQueuePrint() -{ - maTimer.Stop(); - mbAborted = TRUE; - AbortJob(); -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::AddQueuePage( GDIMetaFile* pPage, USHORT nPage, BOOL bNewJobSetup ) -{ - QueuePage* pQueuePage = new QueuePage; - pQueuePage->mpMtf = pPage; - pQueuePage->mnPage = nPage; - pQueuePage->mbEndJob = FALSE; - // ensure that the first page has a valid setup, this is needed - // in GetPaperRanges (used in pullmodel) - // caution: this depends on mnCurPage in Printer being - // 0: not printing 1: after StartJob, 2 after first EndPage, 3+ at following EndPage calls - if ( bNewJobSetup || (nPage == 2 && ImplGetSVData()->maGDIData.mbPrinterPullModel) ) - pQueuePage->mpSetup = new JobSetup( mpParent->GetJobSetup() ); - maQueue.push_back( pQueuePage ); -} diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index f069828f25f9..ac2e586a41cb 100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -50,6 +50,7 @@ CDEFS+=-DENABLE_GRAPHITE EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/outdev.obj \ $(SLO)$/outdev3.obj \ + $(SLO)$/outdevnative.obj \ $(SLO)$/gfxlink.obj \ $(SLO)$/print.obj \ $(SLO)$/print2.obj \ @@ -62,6 +63,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/impgraph.obj \ $(SLO)$/metric.obj \ $(SLO)$/pdfwriter_impl.obj \ + $(SLO)$/pdfwriter_impl2.obj \ $(SLO)$/pdffontcache.obj\ $(SLO)$/bmpconv.obj \ $(SLO)$/pdfextoutdevdata.obj \ @@ -84,7 +86,6 @@ SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/bitmap4.obj \ $(SLO)$/alpha.obj \ $(SLO)$/bitmapex.obj \ - $(SLO)$/imgcons.obj \ $(SLO)$/bmpacc.obj \ $(SLO)$/bmpacc2.obj \ $(SLO)$/bmpacc3.obj \ @@ -106,7 +107,6 @@ SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/outdev4.obj \ $(SLO)$/outdev5.obj \ $(SLO)$/outdev6.obj \ - $(SLO)$/outdevnative.obj \ $(SLO)$/regband.obj \ $(SLO)$/region.obj \ $(SLO)$/wall.obj \ diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 752a4222bcb2..f398888a33b6 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -1441,19 +1441,35 @@ void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData ) rIStm >> mnLen; rIStm >> nAryLen; + if ( mnIndex + mnLen > maStr.Len() ) + { + mnIndex = 0; + mpDXAry = 0; + return; + } + if( nAryLen ) { // #i9762#, #106172# Ensure that DX array is at least mnLen entries long - const ULONG nIntAryLen( Max(nAryLen, static_cast<sal_uInt32>(mnLen)) ); - mpDXAry = new sal_Int32[ nIntAryLen ]; - - ULONG i; - for( i = 0UL; i < nAryLen; i++ ) - rIStm >> mpDXAry[ i ]; + if ( mnLen >= nAryLen ) + { + mpDXAry = new (std::nothrow)sal_Int32[ mnLen ]; + if ( mpDXAry ) + { + ULONG i; + for( i = 0UL; i < nAryLen; i++ ) + rIStm >> mpDXAry[ i ]; - // #106172# setup remainder - for( ; i < nIntAryLen; i++ ) - mpDXAry[ i ] = 0; + // #106172# setup remainder + for( ; i < mnLen; i++ ) + mpDXAry[ i ] = 0; + } + } + else + { + mpDXAry = NULL; + return; + } } else mpDXAry = NULL; @@ -1465,6 +1481,12 @@ void MetaTextArrayAction::Read( SvStream& rIStm, ImplMetaReadData* pData ) sal_Unicode* pBuffer = maStr.AllocBuffer( nLen ); while ( nLen-- ) rIStm >> *pBuffer++; + + if ( mnIndex + mnLen > maStr.Len() ) + { + mnIndex = 0; + delete[] mpDXAry, mpDXAry = NULL; + } } } @@ -3793,7 +3815,6 @@ MetaAction* MetaFloatTransparentAction::Clone() void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove ) { maPoint.Move( nHorzMove, nVertMove ); - maMtf.Move(nHorzMove, nVertMove); } // ------------------------------------------------------------------------ @@ -3804,7 +3825,6 @@ void MetaFloatTransparentAction::Scale( double fScaleX, double fScaleY ) ImplScaleRect( aRectangle, fScaleX, fScaleY ); maPoint = aRectangle.TopLeft(); maSize = aRectangle.GetSize(); - maMtf.Scale(fScaleX, fScaleY); } // ------------------------------------------------------------------------ @@ -4078,7 +4098,7 @@ void MetaCommentAction::Move( long nXMove, long nYMove ) aMemStm >> aFill; PolyPolygon aPath; aFill.getPath( aPath ); - aPath.Scale( nXMove, nYMove ); + aPath.Move( nXMove, nYMove ); aFill.setPath( aPath ); aDest << aFill; } diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx index 325146b6be8a..6d225ad7e0dc 100644 --- a/vcl/source/gdi/metric.cxx +++ b/vcl/source/gdi/metric.cxx @@ -34,6 +34,8 @@ #include <vector> #include <set> +#include <cstdio> + // ======================================================================= ImplFontMetric::ImplFontMetric() @@ -51,6 +53,7 @@ ImplFontMetric::ImplFontMetric() inline void ImplFontMetric::AddReference() { + // TODO: disable refcounting on the default maps? ++mnRefCount; } @@ -58,6 +61,7 @@ inline void ImplFontMetric::AddReference() inline void ImplFontMetric::DeReference() { + // TODO: disable refcounting on the default maps? if( --mnRefCount <= 0 ) delete this; } @@ -252,7 +256,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR ) , mpGlyphIds( rCR.mpGlyphIds ) , mnRangeCount( rCR.mnRangeCount ) , mnCharCount( 0 ) -, mnRefCount( 1 ) +, mnRefCount( 0 ) { const sal_uInt32* pRangePtr = mpRangeCodes; for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 ) @@ -263,7 +267,8 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR ) } } -static ImplFontCharMap* pDefaultImplFontCharMap = NULL; +static ImplFontCharMap* pDefaultUnicodeImplFontCharMap = NULL; +static ImplFontCharMap* pDefaultSymbolImplFontCharMap = NULL; static const sal_uInt32 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0}; static const sal_uInt32 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100}; @@ -284,44 +289,60 @@ ImplFontCharMap::~ImplFontCharMap() delete[] mpRangeCodes; delete[] mpStartGlyphs; delete[] mpGlyphIds; -} + } // ----------------------------------------------------------------------- -ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols) +namespace { - if( pDefaultImplFontCharMap ) - pDefaultImplFontCharMap->AddReference(); - else + ImplFontCharMap *GetDefaultUnicodeMap() { - const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges; - int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes); - if( bSymbols ) + if( !pDefaultUnicodeImplFontCharMap ) { - pRangeCodes = aDefaultSymbolRanges; - nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes); + const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges; + int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes); + CmapResult aDefaultCR( false, pRangeCodes, nCodesCount/2 ); + pDefaultUnicodeImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + pDefaultUnicodeImplFontCharMap->AddReference(); } - CmapResult aDefaultCR( bSymbols, pRangeCodes, nCodesCount/2 ); - pDefaultImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + return pDefaultUnicodeImplFontCharMap; } - return pDefaultImplFontCharMap; + ImplFontCharMap *GetDefaultSymbolMap() + { + if( !pDefaultSymbolImplFontCharMap ) + { + const sal_uInt32* pRangeCodes = aDefaultSymbolRanges; + int nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes); + CmapResult aDefaultCR( true, pRangeCodes, nCodesCount/2 ); + pDefaultSymbolImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + pDefaultSymbolImplFontCharMap->AddReference(); + } + + return pDefaultSymbolImplFontCharMap; + } +} + +ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols) +{ + return bSymbols ? GetDefaultSymbolMap() : GetDefaultUnicodeMap(); } // ----------------------------------------------------------------------- -void ImplFontCharMap::AddReference() +void ImplFontCharMap::AddReference( void ) const { + // TODO: disable refcounting on the default maps? ++mnRefCount; } // ----------------------------------------------------------------------- -void ImplFontCharMap::DeReference() +void ImplFontCharMap::DeReference( void ) const { if( --mnRefCount <= 0 ) - if( this != pDefaultImplFontCharMap ) + if( (this != pDefaultUnicodeImplFontCharMap) && (this != pDefaultSymbolImplFontCharMap) ) delete this; } @@ -815,7 +836,9 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult ) FontCharMap::FontCharMap() : mpImpl( ImplFontCharMap::GetDefaultMap() ) -{} +{ + mpImpl->AddReference(); +} // ----------------------------------------------------------------------- @@ -841,19 +864,14 @@ int FontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const // ----------------------------------------------------------------------- -void FontCharMap::Reset( ImplFontCharMap* pNewMap ) +void FontCharMap::Reset( const ImplFontCharMap* pNewMap ) { + mpImpl->DeReference(); if( pNewMap == NULL ) - { - mpImpl->DeReference(); mpImpl = ImplFontCharMap::GetDefaultMap(); - } else if( pNewMap != mpImpl ) - { - mpImpl->DeReference(); mpImpl = pNewMap; - mpImpl->AddReference(); - } + mpImpl->AddReference(); } // ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx index bb5e4e3ba36d..847a8d7a299a 100644 --- a/vcl/source/gdi/outdev.cxx +++ b/vcl/source/gdi/outdev.cxx @@ -2311,7 +2311,7 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) { return; } @@ -2416,7 +2416,7 @@ void OutputDevice::impPaintLineGeometryWithEvtlExpand( if(bTryAA) { - bDone = mpGraphics->DrawPolyLine(aCandidate, basegfx::B2DVector(1.0, 1.0), basegfx::B2DLINEJOIN_NONE, this); + bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, this); } if(!bDone) @@ -2495,6 +2495,9 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt, const bool bDashUsed(LINE_DASH == aInfo.GetStyle()); const bool bLineWidthUsed(aInfo.GetWidth() > 1); + if ( mbInitLineColor ) + ImplInitLineColor(); + if(bDashUsed || bLineWidthUsed) { basegfx::B2DPolygon aLinePolygon; @@ -2505,9 +2508,6 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt, } else { - if ( mbInitLineColor ) - ImplInitLineColor(); - mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); } @@ -2605,7 +2605,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly ) aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) { return; } @@ -2653,7 +2653,7 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && LINE_SOLID == rLineInfo.GetStyle()) { - DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin()); + DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin()); return; } @@ -2785,7 +2785,7 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly ) aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); } - bSuccess = mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + bSuccess = mpGraphics->DrawPolyLine( aB2DPolygon, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); } if(bSuccess) @@ -2877,7 +2877,7 @@ void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly ) for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++) { - bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + bSuccess = mpGraphics->DrawPolyLine( aB2DPolyPolygon.getB2DPolygon(a), 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); } } @@ -3000,7 +3000,7 @@ void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPo for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++) { - bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + bSuccess = mpGraphics->DrawPolyLine( aB2DPolyPolygon.getB2DPolygon(a), 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); } } @@ -3047,7 +3047,7 @@ bool OutputDevice::ImpTryDrawPolyLineDirect( } // draw the polyline - return mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, eLineJoin, this); + return mpGraphics->DrawPolyLine( aB2DPolygon, 0.0, aB2DLineWidth, eLineJoin, this); } void OutputDevice::DrawPolyLine( diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx index 3826a3dbc7b0..06dcd73cc3d4 100644 --- a/vcl/source/gdi/outdev2.cxx +++ b/vcl/source/gdi/outdev2.cxx @@ -1614,6 +1614,18 @@ void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor ) // ------------------------------------------------------------------------ +namespace +{ + BYTE lcl_calcColor( const BYTE nSourceColor, const BYTE nSourceOpaq, const BYTE nDestColor ) + { + int c = ( (int)nDestColor * ( 255 - nSourceOpaq ) ) + + (int)nSourceOpaq * (int)nSourceColor; + return BYTE( c / 255 ); + } +} + +// ------------------------------------------------------------------------ + Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, BitmapReadAccess* pP, BitmapReadAccess* pA, @@ -1626,7 +1638,6 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, const long* pMapY ) { BitmapColor aDstCol,aSrcCol; - BYTE nSrcAlpha, nDstAlpha; Bitmap res; int nX, nOutX, nY, nOutY; @@ -1660,36 +1671,23 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, aSrcCol = pP->GetColor( nMapY, nMapX ); aDstCol = pB->GetColor( nY, nX ); - nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); - nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); + const BYTE nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); + const BYTE nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); - if( nSrcAlpha + nDstAlpha == 0 ) - { - // #i70653# zero alpha -> zero color values - aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] ) ); - } - else - { - aDstCol.SetRed( (BYTE)(((int)(aSrcCol.GetRed())*nSrcAlpha + (int)(aDstCol.GetRed())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetGreen( (BYTE)(((int)(aSrcCol.GetGreen())*nSrcAlpha + (int)(aDstCol.GetGreen())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetBlue( (BYTE)(((int)(aSrcCol.GetBlue())*nSrcAlpha + (int)(aDstCol.GetBlue())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - - aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); - } + aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) ); + aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) ); + + aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + + nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + + nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); pW->SetPixel( nY, nX, aIndex ); // Have to perform the compositing 'algebra' in // the inverse alpha space (with 255 meaning // opaque), otherwise, transitivity is not // achieved. - nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstAlpha, nSrcAlpha ); + const BYTE nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstOpaq, nSrcOpaq ); aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] + nVCLGLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] + @@ -1718,25 +1716,12 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, aSrcCol = pP->GetColor( nMapY, nMapX ); aDstCol = pB->GetColor( nY, nX ); - nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); - nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); + const BYTE nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); + const BYTE nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); - if( nSrcAlpha + nDstAlpha == 0 ) - { - // #i70653# zero alpha -> zero color values - aDstCol.SetRed(0); - aDstCol.SetGreen(0); - aDstCol.SetBlue(0); - } - else - { - aDstCol.SetRed( (BYTE)(((int)(aSrcCol.GetRed())*nSrcAlpha + (int)(aDstCol.GetRed())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetGreen( (BYTE)(((int)(aSrcCol.GetGreen())*nSrcAlpha + (int)(aDstCol.GetGreen())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetBlue( (BYTE)(((int)(aSrcCol.GetBlue())*nSrcAlpha + (int)(aDstCol.GetBlue())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - } + aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) ); + aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) ); pB->SetPixel( nY, nX, aDstCol ); @@ -1744,7 +1729,7 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, // the inverse alpha space (with 255 meaning // opaque), otherwise, transitivity is not // achieved. - nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstAlpha, nSrcAlpha ); + const BYTE nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstOpaq, nSrcOpaq ); pAlphaW->SetPixel( nY, nX, Color(nSrcAlpha, nSrcAlpha, nSrcAlpha) ); } @@ -2003,7 +1988,15 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight(); const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight(); const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height(); - const long nOffX = aDstRect.Left() - aOutPt.X(), nOffY = aDstRect.Top() - aOutPt.Y(); + // calculate offset in original bitmap + // in RTL case this is a little more complicated since the contents of the + // bitmap is not mirrored (it never is), however the paint region and bmp region + // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these + // is content wise somewhere else and needs to take mirroring into account + const long nOffX = IsRTLEnabled() + ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X()) + : aDstRect.Left() - aOutPt.X(), + nOffY = aDstRect.Top() - aOutPt.Y(); long nX, nOutX, nY, nOutY; long nMirrOffX = 0; long nMirrOffY = 0; @@ -2017,7 +2010,6 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) { pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth; - if( bHMirr ) pMapX[ nX ] = nMirrOffX - pMapX[ nX ]; } diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 949d3df5275f..ca50e4bf6c82 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -27,62 +27,57 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <cstring> -#include <i18npool/mslangid.hxx> -#ifndef _SV_SVSYS_HXX -#include <svsys.h> -#endif -#include <vcl/salgdi.hxx> -#include <vcl/sallayout.hxx> -#include <rtl/tencinfo.h> -#include <tools/debug.hxx> -#include <vcl/svdata.hxx> -#include <vcl/metric.hxx> -#include <vcl/impfont.hxx> -#include <vcl/metaact.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/outdata.hxx> -#include <vcl/outfont.hxx> -#include <basegfx/polygon/b2dpolygon.hxx> -#include <basegfx/polygon/b2dpolypolygon.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <tools/poly.hxx> -#include <vcl/outdev.h> -#include <vcl/virdev.hxx> -#include <vcl/print.hxx> -#include <vcl/event.hxx> -#include <vcl/window.h> -#include <vcl/window.hxx> -#include <vcl/svapp.hxx> -#include <vcl/bmpacc.hxx> -#include <unotools/fontcvt.hxx> -#include <vcl/outdev.hxx> -#include <vcl/edit.hxx> -#include <unotools/fontcfg.hxx> -#include <vcl/sysdata.hxx> -#include <vcl/textlayout.hxx> -#ifndef _OSL_FILE_H -#include <osl/file.h> -#endif +#include "i18npool/mslangid.hxx" + +#include "svsys.h" +#include "vcl/salgdi.hxx" +#include "vcl/sallayout.hxx" +#include "rtl/tencinfo.h" +#include "tools/debug.hxx" +#include "vcl/svdata.hxx" +#include "vcl/metric.hxx" +#include "vcl/impfont.hxx" +#include "vcl/metaact.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/outdata.hxx" +#include "vcl/outfont.hxx" +#include "basegfx/polygon/b2dpolygon.hxx" +#include "basegfx/polygon/b2dpolypolygon.hxx" +#include "basegfx/matrix/b2dhommatrix.hxx" +#include "tools/poly.hxx" +#include "vcl/outdev.h" +#include "vcl/virdev.hxx" +#include "vcl/print.hxx" +#include "vcl/event.hxx" +#include "vcl/window.h" +#include "vcl/window.hxx" +#include "vcl/svapp.hxx" +#include "vcl/bmpacc.hxx" +#include "unotools/fontcvt.hxx" +#include "vcl/outdev.hxx" +#include "vcl/edit.hxx" +#include "unotools/fontcfg.hxx" +#include "vcl/sysdata.hxx" +#include "vcl/textlayout.hxx" +#include "vcl/svids.hrc" +#include "osl/file.h" #ifdef ENABLE_GRAPHITE -#include <vcl/graphite_features.hxx> +#include "vcl/graphite_features.hxx" #endif #ifdef USE_BUILTIN_RASTERIZER -#include <vcl/glyphcache.hxx> +#include "vcl/glyphcache.hxx" #endif -#include <vcl/unohelp.hxx> -#include <pdfwriter_impl.hxx> -#include <vcl/controllayout.hxx> -#include <rtl/logfile.hxx> +#include "vcl/unohelp.hxx" +#include "pdfwriter_impl.hxx" +#include "vcl/controllayout.hxx" +#include "rtl/logfile.hxx" -#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HDL_ -#include <com/sun/star/beans/PropertyValues.hdl> -#endif -#include <com/sun/star/i18n/XBreakIterator.hpp> -#include <com/sun/star/i18n/WordType.hpp> -#include <com/sun/star/linguistic2/XLinguServiceManager.hpp> +#include "com/sun/star/beans/PropertyValues.hpp" +#include "com/sun/star/i18n/XBreakIterator.hpp" +#include "com/sun/star/i18n/WordType.hpp" +#include "com/sun/star/linguistic2/XLinguServiceManager.hpp" #if defined UNX #define GLYPH_FONT_HEIGHT 128 @@ -92,7 +87,7 @@ #define GLYPH_FONT_HEIGHT 256 #endif -#include <sal/alloca.h> +#include "sal/alloca.h" #include <cmath> #include <cstring> @@ -1327,11 +1322,11 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const "msmincho", "fzmingti", "fzheiti", "ipamincho", "sazanamimincho", "kochimincho", "", "sunbatang", "sundotum", "baekmukdotum", "gulim", "batang", "dotum", "", "hgmincholightj", "msunglightsc", "msunglighttc", "hymyeongjolightk", "", - "tahoma", "dejavusans", "timesnewroman", "lucidatypewriter", "lucidasans", "nimbussansl", "", + "tahoma", "dejavusans", "timesnewroman", "liberationsans", "", "shree", "mangal", "", "raavi", "shruti", "tunga", "", "latha", "gautami", "kartika", "vrinda", "", - "shayyalmt", "naskmt", "", + "shayyalmt", "naskmt", "scheherazade", "", "david", "nachlieli", "lucidagrande", "", "norasi", "angsanaupc", "", "khmerossystem", "", @@ -1381,6 +1376,7 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const } } +#ifdef SAL_FONTENUM_STABLE_ON_PLATFORM // #i113472# // sort the list of fonts for glyph fallback by quality (highest first) // #i33947# keep the EUDC font at the front of the list // an insertion sort is good enough for this short list @@ -1396,6 +1392,7 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const break; pFallbackList[ j+1 ] = pTestFont; } +#endif #if defined(HDU_DEBUG) for( int i = 0; i < nMaxLevel; ++i ) @@ -1529,7 +1526,7 @@ void ImplDevFontList::Add( ImplFontData* pNewData ) // add font alias if available // a font alias should never win against an original font with similar quality - if( aMapNames.Len() >= nMapNameIndex ) + if( aMapNames.Len() <= nMapNameIndex ) break; if( bKeepNewData ) // try to recycle obsoleted object pNewData = pNewData->CreateAlias(); @@ -1645,10 +1642,25 @@ ImplDevFontListData* ImplDevFontList::ImplFindBySubstFontAttr( const utl::FontNa pFoundData = ImplFindBySearchName( aSearchName ); if( pFoundData ) - break; + return pFoundData; } - return pFoundData; + // use known attributes from the configuration to find a matching substitute + const ULONG nSearchType = rFontAttr.Type; + if( nSearchType != 0 ) + { + const FontWeight eSearchWeight = rFontAttr.Weight; + const FontWidth eSearchWidth = rFontAttr.Width; + const FontItalic eSearchSlant = ITALIC_DONTKNOW; + const FontFamily eSearchFamily = FAMILY_DONTKNOW; + const String aSearchName; + pFoundData = ImplFindByAttributes( nSearchType, + eSearchWeight, eSearchWidth, eSearchFamily, eSearchSlant, aSearchName ); + if( pFoundData ) + return pFoundData; + } + + return NULL; } // ----------------------------------------------------------------------- @@ -1674,15 +1686,15 @@ void ImplDevFontList::InitMatchData() const } //---------------------------------------------------------------------------- -ImplDevFontListData* ImplDevFontList::ImplFindByLocale(com::sun::star::lang::Locale lc) const +ImplDevFontListData* ImplDevFontList::ImplFindByLocale( com::sun::star::lang::Locale& rLocale ) const { // get the default font for a specified locale const DefaultFontConfiguration& rDefaults = *DefaultFontConfiguration::get(); - String aDefault = rDefaults.getUserInterfaceFont( lc ); + const String aDefault = rDefaults.getUserInterfaceFont( rLocale ); ImplDevFontListData* pFontData = ImplFindByTokenNames( aDefault ); if( pFontData ) return pFontData; - return 0; + return NULL; } // ----------------------------------------------------------------------- @@ -1889,10 +1901,11 @@ ImplDevFontListData* ImplDevFontList::ImplFindByAttributes( ULONG nSearchType, nTestMatch -= 1000000; // test font name substrings - if( (rSearchFamilyName.Len() && pData->maMatchFamilyName.Len()) + // TODO: calculate name matching score using e.g. Levenstein distance + if( (rSearchFamilyName.Len() >= 4) && (pData->maMatchFamilyName.Len() >= 4) && ((rSearchFamilyName.Search( pData->maMatchFamilyName ) != STRING_NOTFOUND) || (pData->maMatchFamilyName.Search( rSearchFamilyName ) != STRING_NOTFOUND)) ) - nTestMatch += 100000*2; + nTestMatch += 5000; // test SERIF attribute if( nSearchType & IMPL_FONT_ATTR_SERIF ) @@ -2909,6 +2922,18 @@ void OutputDevice::ImplInitFontList() const mpGraphics->GetDevFontList( mpFontList ); } } + if( meOutDevType == OUTDEV_WINDOW && ! mpFontList->Count() ) + { + String aError( RTL_CONSTASCII_USTRINGPARAM( "Application error: no fonts and no vcl resource found on your system" ) ); + ResMgr* pMgr = ImplGetResMgr(); + if( pMgr ) + { + String aResStr( ResId( SV_ACCESSERROR_NO_FONTS, *pMgr ) ); + if( aResStr.Len() ) + aError = aResStr; + } + Application::Abort( aError ); + } } // ======================================================================= @@ -3130,17 +3155,17 @@ long OutputDevice::ImplGetTextWidth( const SalLayout& rSalLayout ) const // ----------------------------------------------------------------------- void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, long nHeight ) + long nDistX, long nDistY, long nWidth, long nHeight ) { + long nX = nDistX; + long nY = nDistY; + short nOrientation = mpFontEntry->mnOrientation; if ( nOrientation ) { // Rotate rect without rounding problems for 90 degree rotations if ( !(nOrientation % 900) ) { - nX -= nBaseX; - nY -= nBaseY; - if ( nOrientation == 900 ) { long nTemp = nX; @@ -3168,12 +3193,11 @@ void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, nHeight = nTemp; nX -= nWidth; } - - nX += nBaseX; - nY += nBaseY; } else { + nX += nBaseX; + nY += nBaseY; // inflate because polygons are drawn smaller Rectangle aRect( Point( nX, nY ), Size( nWidth+1, nHeight+1 ) ); Polygon aPoly( aRect ); @@ -3183,6 +3207,8 @@ void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, } } + nX += nBaseX; + nY += nBaseY; mpGraphics->DrawRect( nX, nY, nWidth, nHeight, this ); } @@ -3203,7 +3229,7 @@ void OutputDevice::ImplDrawTextBackground( const SalLayout& rSalLayout ) mpGraphics->SetFillColor( ImplColorToSal( GetTextFillColor() ) ); mbInitFillColor = TRUE; - ImplDrawTextRect( nX, nY, nX, nY-mpFontEntry->maMetric.mnAscent-mnEmphasisAscent, + ImplDrawTextRect( nX, nY, 0, -(mpFontEntry->maMetric.mnAscent + mnEmphasisAscent), nWidth, mpFontEntry->mnLineHeight+mnEmphasisAscent+mnEmphasisDescent ); } @@ -3488,7 +3514,7 @@ static void ImplDrawWavePixel( long nOriginX, long nOriginY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, - long nStartX, long nStartY, + long nDistX, long nDistY, long nWidth, long nHeight, long nLineWidth, short nOrientation, const Color& rColor ) @@ -3496,6 +3522,9 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, if ( !nHeight ) return; + long nStartX = nBaseX + nDistX; + long nStartY = nBaseY + nDistY; + // Bei Hoehe von 1 Pixel reicht es, eine Linie auszugeben if ( (nLineWidth == 1) && (nHeight == 1) ) { @@ -3510,7 +3539,6 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, ImplRotatePos( nBaseX, nBaseY, nEndX, nEndY, nOrientation ); } mpGraphics->DrawLine( nStartX, nStartY, nEndX, nEndY, this ); - } else { @@ -3610,7 +3638,7 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontUnderline eTextLine, Color aColor, BOOL bIsAbove ) @@ -3636,7 +3664,7 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, nLineWidth = 1; if ( eTextLine == UNDERLINE_BOLDWAVE ) nLineWidth *= 2; - nLinePos += nY - (nLineHeight / 2); + nLinePos += nDistY - (nLineHeight / 2); long nLineWidthHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY; if ( eTextLine == UNDERLINE_DOUBLEWAVE ) { @@ -3657,16 +3685,16 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, nLineDY2 = 1; nLinePos -= nLineWidthHeight-nLineDY2; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); nLinePos += nLineWidthHeight+nLineDY; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); } else { nLinePos -= nLineWidthHeight/2; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); } } @@ -3674,7 +3702,7 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontUnderline eTextLine, Color aColor, BOOL bIsAbove ) @@ -3684,6 +3712,8 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, long nLinePos = 0; long nLinePos2 = 0; + const long nY = nDistY; + if ( eTextLine > UNDERLINE_LAST ) eTextLine = UNDERLINE_SINGLE; @@ -3751,7 +3781,7 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, mpGraphics->SetFillColor( ImplColorToSal( aColor ) ); mbInitFillColor = TRUE; - long nLeft = nX; + long nLeft = nDistX; switch ( eTextLine ) { @@ -3904,7 +3934,7 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontStrikeout eStrikeout, Color aColor ) { @@ -3913,6 +3943,8 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, long nLinePos = 0; long nLinePos2 = 0; + long nY = nDistY; + if ( eStrikeout > STRIKEOUT_LAST ) eStrikeout = STRIKEOUT_SINGLE; @@ -3945,7 +3977,7 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, mpGraphics->SetFillColor( ImplColorToSal( aColor ) ); mbInitFillColor = TRUE; - long nLeft = nX; + const long& nLeft = nDistX; switch ( eStrikeout ) { @@ -3966,7 +3998,7 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontStrikeout eStrikeout, Color aColor ) { @@ -4000,12 +4032,12 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, // calculate acceptable strikeout length // allow the strikeout to be one pixel larger than the text it strikes out - long nMaxWidth = nStrikeoutWidth / 2; + long nMaxWidth = nStrikeoutWidth * 3 / 4; if ( nMaxWidth < 2 ) nMaxWidth = 2; nMaxWidth += nWidth + 1; - int nStrikeStrLen = (nMaxWidth + nStrikeoutWidth - 1) / nStrikeoutWidth; + int nStrikeStrLen = (nMaxWidth - 1) / nStrikeoutWidth; // if the text width is smaller than the strikeout text, then do not // strike out at all. This case requires user interaction, e.g. adding // a space to the text @@ -4020,7 +4052,9 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, const String aStrikeoutText( aChars, xub_StrLen(nStrikeStrLen) ); if( mpFontEntry->mnOrientation ) - ImplRotatePos( nBaseX, nBaseY, nX, nY, mpFontEntry->mnOrientation ); + ImplRotatePos( 0, 0, nDistX, nDistY, mpFontEntry->mnOrientation ); + nBaseX += nDistX; + nBaseY += nDistY; // strikeout text has to be left aligned ULONG nOrigTLM = mnTextLayoutMode; @@ -4036,7 +4070,7 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, SetTextColor( aColor ); ImplInitTextColor(); - pLayout->DrawBase() = Point( nX+mnTextOffX, nY+mnTextOffY ); + pLayout->DrawBase() = Point( nBaseX+mnTextOffX, nBaseY+mnTextOffY ); pLayout->DrawText( *mpGraphics ); pLayout->Release(); @@ -4046,8 +4080,8 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- -void OutputDevice::ImplDrawTextLine( long nBaseX, - long nX, long nY, long nWidth, +void OutputDevice::ImplDrawTextLine( long nX, long nY, + long nDistX, long nWidth, FontStrikeout eStrikeout, FontUnderline eUnderline, FontUnderline eOverline, @@ -4063,10 +4097,14 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, BOOL bUnderlineDone = FALSE; BOOL bOverlineDone = FALSE; - // TODO: fix rotated text if ( IsRTLEnabled() ) + { // --- RTL --- mirror at basex - nX = nBaseX - nWidth - (nX - nBaseX - 1); + long nXAdd = nWidth - nDistX; + if( mpFontEntry->mnOrientation ) + nXAdd = FRound( nXAdd * cos( mpFontEntry->mnOrientation * F_PI1800 ) ); + nX += nXAdd - 1; + } if ( !IsTextLineColor() ) aUnderlineColor = GetTextColor(); @@ -4079,7 +4117,7 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, (eUnderline == UNDERLINE_DOUBLEWAVE) || (eUnderline == UNDERLINE_BOLDWAVE) ) { - ImplDrawWaveTextLine( nBaseX, nY, nX, nY, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); + ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); bUnderlineDone = TRUE; } if ( (eOverline == UNDERLINE_SMALLWAVE) || @@ -4087,25 +4125,25 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, (eOverline == UNDERLINE_DOUBLEWAVE) || (eOverline == UNDERLINE_BOLDWAVE) ) { - ImplDrawWaveTextLine( nBaseX, nY, nX, nY, nWidth, eOverline, aOverlineColor, TRUE ); + ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, TRUE ); bOverlineDone = TRUE; } if ( (eStrikeout == STRIKEOUT_SLASH) || (eStrikeout == STRIKEOUT_X) ) { - ImplDrawStrikeoutChar( nBaseX, nY, nX, nY, nWidth, eStrikeout, aStrikeoutColor ); + ImplDrawStrikeoutChar( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor ); bStrikeoutDone = TRUE; } if ( !bUnderlineDone ) - ImplDrawStraightTextLine( nBaseX, nY, nX, nY, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); + ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); if ( !bOverlineDone ) - ImplDrawStraightTextLine( nBaseX, nY, nX, nY, nWidth, eOverline, aOverlineColor, TRUE ); + ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, TRUE ); if ( !bStrikeoutDone ) - ImplDrawStrikeoutLine( nBaseX, nY, nX, nY, nWidth, eStrikeout, aStrikeoutColor ); + ImplDrawStrikeoutLine( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor ); } // ----------------------------------------------------------------------- @@ -4115,34 +4153,49 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, { if( bWordLine ) { - Point aPos, aStartPt; - sal_Int32 nWidth = 0, nAdvance=0; + // draw everything relative to the layout base point + const Point aStartPt = rSalLayout.DrawBase(); + // calculate distance of each word from the base point + Point aPos; + sal_Int32 nDist = 0, nWidth = 0, nAdvance=0; for( int nStart = 0;;) { + // iterate through the layouted glyphs sal_GlyphId nGlyphIndex; if( !rSalLayout.GetNextGlyphs( 1, &nGlyphIndex, aPos, nStart, &nAdvance ) ) break; + // calculate the boundaries of each word if( !rSalLayout.IsSpacingGlyph( nGlyphIndex ) ) { if( !nWidth ) { - aStartPt = aPos;//rSalLayout.DrawBase() - (aPos - rSalLayout.DrawOffset()); + // get the distance to the base point (as projected to baseline) + nDist = aPos.X() - aStartPt.X(); + if( mpFontEntry->mnOrientation ) + { + const long nDY = aPos.Y() - aStartPt.Y(); + const double fRad = mpFontEntry->mnOrientation * F_PI1800; + nDist = FRound( nDist*cos(fRad) - nDY*sin(fRad) ); + } } + // update the length of the textline nWidth += nAdvance; } else if( nWidth > 0 ) { - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + // draw the textline for each word + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); nWidth = 0; } } + // draw textline for the last word if( nWidth > 0 ) { - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); } } @@ -4150,7 +4203,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, { Point aStartPt = rSalLayout.GetDrawPosition(); int nWidth = rSalLayout.GetTextWidth() / rSalLayout.GetUnitsPerPixel(); - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), 0, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); } } @@ -4169,7 +4222,7 @@ void OutputDevice::ImplDrawMnemonicLine( long nX, long nY, long nWidth ) nX = nBaseX - nWidth - (nX - nBaseX - 1); } - ImplDrawTextLine( nBaseX, nX, nY, nWidth, STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, FALSE ); + ImplDrawTextLine( nX, nY, 0, nWidth, STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, FALSE ); } // ----------------------------------------------------------------------- @@ -5417,7 +5470,7 @@ void OutputDevice::DrawTextLine( const Point& rPos, long nWidth, Point aPos = ImplLogicToDevicePixel( rPos ); nWidth = ImplLogicWidthToDevicePixel( nWidth ); aPos += Point( mnTextOffX, mnTextOffY ); - ImplDrawTextLine( aPos.X(), aPos.X(), aPos.Y(), nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); + ImplDrawTextLine( aPos.X(), aPos.X(), 0, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); if( mpAlphaVDev ) mpAlphaVDev->DrawTextLine( rPos, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); @@ -5494,7 +5547,7 @@ void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos, if( nWaveHeight > pFontEntry->maMetric.mnWUnderlineSize ) nWaveHeight = pFontEntry->maMetric.mnWUnderlineSize; - ImplDrawWaveLine( nStartX, nStartY, nStartX, nStartY, + ImplDrawWaveLine( nStartX, nStartY, 0, 0, nEndX-nStartX, nWaveHeight, 1, nOrientation, GetLineColor() ); if( mpAlphaVDev ) @@ -6057,6 +6110,11 @@ SalLayout* OutputDevice::ImplGlyphFallbackLayout( SalLayout* pSalLayout, ImplLay rtl::OUString aMissingCodes = aMissingCodeBuf.makeStringAndClear(); ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData; + + ImplFontMetricData aOrigMetric( aFontSelData ); + // TODO: use cached metric in fontentry + mpGraphics->GetFontMetric( &aOrigMetric ); + // when device specific font substitution may have been performed for // the originally selected font then make sure that a fallback to that // font is performed first @@ -6101,7 +6159,27 @@ SalLayout* OutputDevice::ImplGlyphFallbackLayout( SalLayout* pSalLayout, ImplLay } #endif + // TODO: try to get the metric data from the GFB's mpFontEntry + ImplFontMetricData aSubstituteMetric( aFontSelData ); pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); + mpGraphics->GetFontMetric( &aSubstituteMetric, nFallbackLevel ); + + const long nOriginalHeight = aOrigMetric.mnAscent + aOrigMetric.mnDescent; + const long nSubstituteHeight = aSubstituteMetric.mnAscent + aSubstituteMetric.mnDescent; + // Too tall, shrink it a bit. Need a better calculation to include extra + // factors and any extra wriggle room we might have available? + // TODO: should we scale by max-ascent/max-descent instead of design height? + if( nSubstituteHeight > nOriginalHeight ) + { + const float fScale = nOriginalHeight / (float)nSubstituteHeight; + const float fOrigHeight = aFontSelData.mfExactHeight; + const int nOrigHeight = aFontSelData.mnHeight; + aFontSelData.mfExactHeight *= fScale; + aFontSelData.mnHeight = static_cast<int>(aFontSelData.mfExactHeight); + pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); + aFontSelData.mnHeight = nOrigHeight; + aFontSelData.mfExactHeight = fOrigHeight; + } // create and add glyph fallback layout to multilayout rLayoutArgs.ResetPos(); @@ -6763,7 +6841,20 @@ String OutputDevice::ImplGetEllipsisString( const OutputDevice& rTargetDevice, c if ( nIndex != STRING_LEN ) { - if ( nStyle & TEXT_DRAW_ENDELLIPSIS ) + if( (nStyle & TEXT_DRAW_CENTERELLIPSIS) == TEXT_DRAW_CENTERELLIPSIS ) + { + String aTmpStr( aStr ); + xub_StrLen nEraseChars = 4; + while( nEraseChars < aStr.Len() && _rLayout.GetTextWidth( aTmpStr, 0, aTmpStr.Len() ) > nMaxWidth ) + { + aTmpStr = aStr; + xub_StrLen i = (aTmpStr.Len() - nEraseChars)/2; + aTmpStr.Erase( i, nEraseChars++ ); + aTmpStr.InsertAscii( "...", i ); + } + aStr = aTmpStr; + } + else if ( nStyle & TEXT_DRAW_ENDELLIPSIS ) { aStr.Erase( nIndex ); if ( nIndex > 1 ) @@ -7946,7 +8037,7 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const if( !mpFontEntry ) return FALSE; - // a little font charmap cache helps considerably +#ifdef ENABLE_IFC_CACHE // a little font charmap cache helps considerably static const int NMAXITEMS = 16; static int nUsedItems = 0, nCurItem = 0; @@ -7964,10 +8055,12 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const rFontCharMap.Reset( aCache[i].maCharMap.mpImpl ); } else // need to cache +#endif // ENABLE_IFC_CACHE { - ImplFontCharMap* pNewMap = mpGraphics->GetImplFontCharMap(); + const ImplFontCharMap* pNewMap = mpGraphics->GetImplFontCharMap(); rFontCharMap.Reset( pNewMap ); +#ifdef ENABLE_IFC_CACHE // manage cache round-robin and insert data CharMapCacheItem& rItem = aCache[ nCurItem ]; rItem.mpFontData = pFontData; @@ -7978,6 +8071,7 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const if( ++nUsedItems >= NMAXITEMS ) nUsedItems = NMAXITEMS; +#endif // ENABLE_IFC_CACHE } if( rFontCharMap.IsDefaultMap() ) diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index bef37284adbd..5b8d228bb141 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -184,18 +184,31 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) - && ROP_OVERPAINT == GetRasterOp() - && IsFillColor()) + && ROP_OVERPAINT == GetRasterOp() ) { // b2dpolygon support not implemented yet on non-UNX platforms const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); - // transform the polygon and ensure closed - aB2DPolyPolygon.transform(aTransform); - aB2DPolyPolygon.setClosed(true); + // transform the polygon into device space and ensure it is closed + aB2DPolyPolygon.transform( aTransform ); + aB2DPolyPolygon.setClosed( true ); + + bool bDrawnOk = true; + if( IsFillColor() ) + bDrawnOk = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this ); + if( bDrawnOk && IsLineColor() ) + { + const basegfx::B2DVector aHairlineWidth(1,1); + const int nPolyCount = aB2DPolyPolygon.count(); + for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) + { + const ::basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx ); + mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, ::basegfx::B2DLINEJOIN_NONE, this ); + } + } - if(mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, fTransparency, this)) + if( bDrawnOk ) { #if 0 // MetaB2DPolyPolygonAction is not implemented yet: @@ -287,14 +300,17 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, // get the polygon in device coordinates basegfx::B2DPolyPolygon aB2DPolyPolygon( rPolyPoly.getB2DPolyPolygon() ); - aB2DPolyPolygon.setClosed( true ); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); aB2DPolyPolygon.transform( aTransform ); - // draw the transparent polygon - bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, nTransparencePercent*0.01, this ); + const double fTransparency = 0.01 * nTransparencePercent; + if( mbFillColor ) + { + // draw the transparent polygon + // NOTE: filled polygons are assumed to be drawn as if they were always closed + bDrawn = mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, fTransparency, this ); + } - // DrawTransparent() assumes that the border is NOT to be drawn transparently??? if( mbLineColor ) { // disable the fill color for now @@ -305,7 +321,7 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) { const ::basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx ); - mpGraphics->DrawPolyLine( rPolygon, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, this ); + bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, ::basegfx::B2DLINEJOIN_NONE, this ); } // prepare to restore the fill color mbInitFillColor = mbFillColor; @@ -329,6 +345,12 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, if( OUTDEV_PRINTER == meOutDevType ) { + if(100 <= nTransparencePercent) + { + // #i112959# 100% transparent, draw nothing + return; + } + Rectangle aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() ); const Size aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) ); const long nBaseExtent = Max( FRound( aDPISize.Width() / 300. ), 1L ); @@ -343,30 +365,40 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, case( 25 ): nMove = nBaseExtent * 3; break; case( 50 ): nMove = nBaseExtent * 4; break; case( 75 ): nMove = nBaseExtent * 6; break; - // TODO What is the correct VALUE??? + + // #i112959# very transparent (88 < nTransparencePercent <= 99) + case( 100 ): nMove = nBaseExtent * 8; break; + + // #i112959# not transparent (nTransparencePercent < 13) default: nMove = 0; break; } Push( PUSH_CLIPREGION | PUSH_LINECOLOR ); IntersectClipRegion( rPolyPoly ); SetLineColor( GetFillColor() ); - - Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) ); - const BOOL bOldMap = mbMap; EnableMapMode( FALSE ); - while( aRect.Top() <= aPolyRect.Bottom() ) + if(nMove) { - DrawRect( aRect ); - aRect.Move( 0, nMove ); - } + Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) ); + while( aRect.Top() <= aPolyRect.Bottom() ) + { + DrawRect( aRect ); + aRect.Move( 0, nMove ); + } - aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) ); - while( aRect.Left() <= aPolyRect.Right() ) + aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) ); + while( aRect.Left() <= aPolyRect.Right() ) + { + DrawRect( aRect ); + aRect.Move( nMove, 0 ); + } + } + else { - DrawRect( aRect ); - aRect.Move( nMove, 0 ); + // #i112959# if not transparent, draw full rectangle in clip region + DrawRect( aPolyRect ); } EnableMapMode( bOldMap ); @@ -1119,7 +1151,7 @@ void OutputDevice::Erase() { ImplControlValue aControlValue; Point aGcc3WorkaroundTemporary; - Region aCtrlRegion( Rectangle( aGcc3WorkaroundTemporary, GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() ); ControlState nState = 0; if( pWindow->IsEnabled() ) nState |= CTRL_STATE_ENABLED; diff --git a/vcl/source/gdi/outdevnative.cxx b/vcl/source/gdi/outdevnative.cxx index fed41ec4de85..b5b745b708fa 100644..100755 --- a/vcl/source/gdi/outdevnative.cxx +++ b/vcl/source/gdi/outdevnative.cxx @@ -59,6 +59,42 @@ static bool lcl_enableNativeWidget( const OutputDevice& i_rDevice ) } } +ImplControlValue::~ImplControlValue() +{ +} + +ScrollbarValue::~ScrollbarValue() +{ +} + +SliderValue::~SliderValue() +{ +} + +TabitemValue::~TabitemValue() +{ +} + +SpinbuttonValue::~SpinbuttonValue() +{ +} + +ToolbarValue::~ToolbarValue() +{ +} + +MenubarValue::~MenubarValue() +{ +} + +MenupopupValue::~MenupopupValue() +{ +} + +PushButtonValue::~PushButtonValue() +{ +} + // ----------------------------------------------------------------------- // These functions are mainly passthrough functions that allow access to // the SalFrame behind a Window object for native widget rendering purposes. @@ -83,7 +119,7 @@ BOOL OutputDevice::IsNativeControlSupported( ControlType nType, ControlPart nPar BOOL OutputDevice::HitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ) { @@ -95,7 +131,7 @@ BOOL OutputDevice::HitTestNativeControl( ControlType nType, return FALSE; Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); + Rectangle screenRegion( rControlRegion ); screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ), @@ -104,47 +140,88 @@ BOOL OutputDevice::HitTestNativeControl( ControlType nType, // ----------------------------------------------------------------------- -static void lcl_moveControlValue( ControlType nType, const ImplControlValue& aValue, const Point& rDelta ) +static boost::shared_ptr< ImplControlValue > lcl_transformControlValue( const ImplControlValue& rVal, OutputDevice& rDev ) { - if( aValue.getOptionalVal() ) + boost::shared_ptr< ImplControlValue > aResult; + switch( rVal.getType() ) { - switch( nType ) + case CTRL_SLIDER: { - case CTRL_SLIDER: - { - SliderValue* pSlVal = reinterpret_cast<SliderValue*>(aValue.getOptionalVal()); - pSlVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_SCROLLBAR: - { - ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(aValue.getOptionalVal()); - pScVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); - pScVal->maButton1Rect.Move( rDelta.X(), rDelta.Y() ); - pScVal->maButton2Rect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_SPINBOX: - case CTRL_SPINBUTTONS: - { - SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(aValue.getOptionalVal()); - pSpVal->maUpperRect.Move( rDelta.X(), rDelta.Y() ); - pSpVal->maLowerRect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_TOOLBAR: - { - ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(aValue.getOptionalVal()); - pTVal->maGripRect.Move( rDelta.X(), rDelta.Y() ); - } + const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal); + SliderValue* pNew = new SliderValue( *pSlVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect ); + } + break; + case CTRL_SCROLLBAR: + { + const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal); + ScrollbarValue* pNew = new ScrollbarValue( *pScVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect ); + pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect ); + pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect ); + } + break; + case CTRL_SPINBUTTONS: + { + const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal); + SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal ); + aResult.reset( pNew ); + pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect ); + pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect ); + } + break; + case CTRL_TOOLBAR: + { + const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal); + ToolbarValue* pNew = new ToolbarValue( *pTVal ); + aResult.reset( pNew ); + pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect ); + } + break; + case CTRL_TAB_ITEM: + { + const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal); + TabitemValue* pNew = new TabitemValue( *pTIVal ); + aResult.reset( pNew ); + } + break; + case CTRL_MENUBAR: + { + const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal); + MenubarValue* pNew = new MenubarValue( *pMVal ); + aResult.reset( pNew ); + } + break; + case CTRL_PUSHBUTTON: + { + const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal); + PushButtonValue* pNew = new PushButtonValue( *pBVal ); + aResult.reset( pNew ); + } + break; + case CTRL_GENERIC: + aResult.reset( new ImplControlValue( rVal ) ); break; + case CTRL_MENU_POPUP: + { + const MenupopupValue* pMVal = static_cast<const MenupopupValue*>(&rVal); + MenupopupValue* pNew = new MenupopupValue( *pMVal ); + pNew->maItemRect = rDev.ImplLogicToDevicePixel( pMVal->maItemRect ); + aResult.reset( pNew ); } + break; + default: + OSL_ENSURE( 0, "unknown ImplControlValue type !" ); + break; } + return aResult; } BOOL OutputDevice::DrawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ) @@ -152,20 +229,6 @@ BOOL OutputDevice::DrawNativeControl( ControlType nType, if( !lcl_enableNativeWidget( *this ) ) return FALSE; - /* - if( !IsInPaint() && IsPaintTransparent() ) - { - // only required if called directly (ie, we're not in Paint() ): - // force redraw (Paint()) for transparent controls - // to trigger a repaint of the background - Region aClipRgn( GetClipRegion() ); - if( !rControlRegion.IsEmpty() ) - aClipRgn.Intersect( rControlRegion ); - Invalidate( aClipRgn, INVALIDATE_UPDATE ); - return TRUE; - } - */ - // make sure the current clip region is initialized correctly if ( !mpGraphics ) if ( !ImplGetGraphics() ) @@ -183,22 +246,15 @@ BOOL OutputDevice::DrawNativeControl( ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - - // do so for ImplControlValue members, also - lcl_moveControlValue( nType, aValue, aWinOffs ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); Region aTestRegion( GetActiveClipRegion() ); aTestRegion.Intersect( rControlRegion ); if( aTestRegion == rControlRegion ) nState |= CTRL_CACHING_ALLOWED; // control is not clipped, caching allowed - BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, aValue, aCaption, this ); - - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); + BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this ); return bRet; } @@ -208,7 +264,7 @@ BOOL OutputDevice::DrawNativeControl( ControlType nType, BOOL OutputDevice::DrawNativeControlText(ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ) @@ -233,15 +289,10 @@ BOOL OutputDevice::DrawNativeControlText(ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - lcl_moveControlValue( nType, aValue, aWinOffs ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); - BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, aValue, aCaption, this ); - - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); + BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this ); return bRet; } @@ -251,12 +302,12 @@ BOOL OutputDevice::DrawNativeControlText(ControlType nType, BOOL OutputDevice::GetNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion ) { if( !lcl_enableNativeWidget( *this ) ) return FALSE; @@ -267,22 +318,18 @@ BOOL OutputDevice::GetNativeControlRegion( ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - lcl_moveControlValue( nType, aValue, aWinOffs ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); - BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, aValue, + BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, rNativeBoundingRegion, rNativeContentRegion, this ); if( bRet ) { // transform back native regions - rNativeBoundingRegion.Move( -aWinOffs.X(), -aWinOffs.Y() ); - rNativeContentRegion.Move( -aWinOffs.X(), -aWinOffs.Y() ); + rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion ); + rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion ); } - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); return bRet; } diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 5dcce25a0315..23ce1dfa6169 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -38,9 +38,9 @@ PDFWriter::AnyWidget::~AnyWidget() { } -PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext ) +PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& xEnc ) : - pImplementation( new PDFWriterImpl( rContext ) ) + pImplementation( new PDFWriterImpl( rContext, xEnc, *this ) ) { } @@ -69,16 +69,6 @@ PDFWriter::PDFVersion PDFWriter::GetVersion() const return ((PDFWriterImpl*)pImplementation)->getVersion(); } -void PDFWriter::SetDocInfo( const PDFDocInfo& rInfo ) -{ - ((PDFWriterImpl*)pImplementation)->setDocInfo( rInfo ); -} - -const PDFDocInfo& PDFWriter::GetDocInfo() const -{ - return ((PDFWriterImpl*)pImplementation)->getDocInfo(); -} - void PDFWriter::SetDocumentLocale( const com::sun::star::lang::Locale& rLoc ) { ((PDFWriterImpl*)pImplementation)->setDocumentLocale( rLoc ); @@ -569,3 +559,18 @@ std::set< PDFWriter::ErrorCode > PDFWriter::GetErrors() { return ((PDFWriterImpl*)pImplementation)->getErrors(); } + +com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > +PDFWriter::InitEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ) +{ + return PDFWriterImpl::initEncryption( i_rOwnerPassword, i_rUserPassword, b128Bit ); +} + +void PDFWriter::PlayMetafile( const GDIMetaFile& i_rMTF, const vcl::PDFWriter::PlayMetafileContext& i_rPlayContext, PDFExtOutDevData* i_pData ) +{ + ((PDFWriterImpl*)pImplementation)->playMetafile( i_rMTF, i_pData, i_rPlayContext, NULL); +} + diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 77f7f74fc10e..325ccef1c3a6 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -32,6 +32,7 @@ #include <math.h> #include <algorithm> +#include <tools/urlobj.hxx> #include <pdfwriter_impl.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> @@ -66,6 +67,7 @@ #include "cppuhelper/implbase1.hxx" #include <icc/sRGB-IEC61966-2.1.hxx> #include <vcl/lineinfo.hxx> +#include "vcl/strhelper.hxx" using namespace vcl; using namespace rtl; @@ -111,12 +113,10 @@ void doTestCode() aContext.Version = PDFWriter::PDF_1_4; aContext.Tagged = true; aContext.InitialPage = 2; + aContext.DocumentInfo.Title = OUString( RTL_CONSTASCII_USTRINGPARAM( "PDF export test document" ) ); + aContext.DocumentInfo.Producer = OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL" ) ); PDFWriter aWriter( aContext ); - PDFDocInfo aDocInfo; - aDocInfo.Title = OUString( RTL_CONSTASCII_USTRINGPARAM( "PDF export test document" ) ); - aDocInfo.Producer = OUString( RTL_CONSTASCII_USTRINGPARAM( "VCL" ) ); - aWriter.SetDocInfo( aDocInfo ); aWriter.NewPage( 595, 842 ); aWriter.BeginStructureElement( PDFWriter::Document ); // set duration of 3 sec for first page @@ -494,6 +494,12 @@ static inline double pixelToPoint( sal_Int32 px ) { return double(px)/fDivisor; static inline double pixelToPoint( double px ) { return px/fDivisor; } static inline sal_Int32 pointToPixel( double pt ) { return sal_Int32(pt*fDivisor); } +const sal_uInt8 PDFWriterImpl::s_nPadString[32] = +{ + 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, + 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A +}; + static void appendHex( sal_Int8 nInt, OStringBuffer& rBuffer ) { static const sal_Char pHexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', @@ -1691,7 +1697,9 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal * class PDFWriterImpl */ -PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) + PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, + const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& xEnc, + PDFWriter& i_rOuterFace) : m_pReferenceDevice( NULL ), m_aMapMode( MAP_POINT, Point(), Fraction( 1L, pointToPixel(1) ), Fraction( 1L, pointToPixel(1) ) ), @@ -1712,12 +1720,10 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_aCipher( (rtlCipher)NULL ), m_aDigest( NULL ), m_bEncryptThisStream( false ), - m_aDocID( 32 ), - m_aCreationDateString( 64 ), - m_aCreationMetaDateString( 64 ), m_pEncryptionBuffer( NULL ), m_nEncryptionBufferSize( 0 ), - m_bIsPDF_A1( false ) + m_bIsPDF_A1( false ), + m_rOuterFace( i_rOuterFace ) { #ifdef DO_TEST_PDF static bool bOnce = true; @@ -1756,14 +1762,37 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_bOpen = true; -/* prepare the cypher engine, can be done in CTOR, free in DTOR */ + // setup DocInfo + setupDocInfo(); + /* prepare the cypher engine, can be done in CTOR, free in DTOR */ m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); m_aDigest = rtl_digest_createMD5(); -/* the size of the Codec default maximum */ + /* the size of the Codec default maximum */ checkEncryptionBufferSize( 0x4000 ); + if( xEnc.is() ) + prepareEncryption( xEnc ); + + if( m_aContext.Encryption.Encrypt() ) + { + // sanity check + if( m_aContext.Encryption.OValue.size() != ENCRYPTED_PWD_SIZE || + m_aContext.Encryption.UValue.size() != ENCRYPTED_PWD_SIZE || + m_aContext.Encryption.EncryptionKey.size() != MAXIMUM_RC4_KEY_LENGTH + ) + { + // the field lengths are invalid ? This was not setup by initEncryption. + // do not encrypt after all + m_aContext.Encryption.OValue.clear(); + m_aContext.Encryption.UValue.clear(); + OSL_ENSURE( 0, "encryption data failed sanity check, encryption disabled" ); + } + else // setup key lengths + m_nAccessPermissions = computeAccessPermissions( m_aContext.Encryption, m_nKeyLength, m_nRC4KeyLength ); + } + // write header OStringBuffer aBuffer( 20 ); aBuffer.append( "%PDF-" ); @@ -1809,139 +1838,138 @@ PDFWriterImpl::~PDFWriterImpl() rtl_freeMemory( m_pEncryptionBuffer ); } -void PDFWriterImpl::setDocInfo( const PDFDocInfo& rInfo ) +void PDFWriterImpl::setupDocInfo() { - m_aDocInfo.Title = rInfo.Title; - m_aDocInfo.Author = rInfo.Author; - m_aDocInfo.Subject = rInfo.Subject; - m_aDocInfo.Keywords = rInfo.Keywords; - m_aDocInfo.Creator = rInfo.Creator; - m_aDocInfo.Producer = rInfo.Producer; + std::vector< sal_uInt8 > aId; + computeDocumentIdentifier( aId, m_aContext.DocumentInfo, m_aCreationDateString, m_aCreationMetaDateString ); + if( m_aContext.Encryption.DocumentIdentifier.empty() ) + m_aContext.Encryption.DocumentIdentifier = aId; +} -//build the document id +void PDFWriterImpl::computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo, + rtl::OString& o_rCString1, + rtl::OString& o_rCString2 + ) +{ + o_rIdentifier.clear(); + + //build the document id rtl::OString aInfoValuesOut; OStringBuffer aID( 1024 ); - if( m_aDocInfo.Title.Len() ) - appendUnicodeTextString( m_aDocInfo.Title, aID ); - if( m_aDocInfo.Author.Len() ) - appendUnicodeTextString( m_aDocInfo.Author, aID ); - if( m_aDocInfo.Subject.Len() ) - appendUnicodeTextString( m_aDocInfo.Subject, aID ); - if( m_aDocInfo.Keywords.Len() ) - appendUnicodeTextString( m_aDocInfo.Keywords, aID ); - if( m_aDocInfo.Creator.Len() ) - appendUnicodeTextString( m_aDocInfo.Creator, aID ); - if( m_aDocInfo.Producer.Len() ) - appendUnicodeTextString( m_aDocInfo.Producer, aID ); + if( i_rDocInfo.Title.Len() ) + appendUnicodeTextString( i_rDocInfo.Title, aID ); + if( i_rDocInfo.Author.Len() ) + appendUnicodeTextString( i_rDocInfo.Author, aID ); + if( i_rDocInfo.Subject.Len() ) + appendUnicodeTextString( i_rDocInfo.Subject, aID ); + if( i_rDocInfo.Keywords.Len() ) + appendUnicodeTextString( i_rDocInfo.Keywords, aID ); + if( i_rDocInfo.Creator.Len() ) + appendUnicodeTextString( i_rDocInfo.Creator, aID ); + if( i_rDocInfo.Producer.Len() ) + appendUnicodeTextString( i_rDocInfo.Producer, aID ); TimeValue aTVal, aGMT; oslDateTime aDT; osl_getSystemTime( &aGMT ); osl_getLocalTimeFromSystemTime( &aGMT, &aTVal ); osl_getDateTimeFromTimeValue( &aTVal, &aDT ); - m_aCreationDateString.append( "D:" ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); -//--> i59651, we fill the Metadata date string as well, if PDF/A is requested - if( m_bIsPDF_A1 ) - { -// according to ISO 19005-1:2005 6.7.3 the date is corrected for -// local time zone offset UTC only, whereas Acrobat 8 seems -// to use the localtime notation only -// according to a raccomandation in XMP Specification (Jan 2004, page 75) -// the Acrobat way seems the right approach - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); - m_aCreationMetaDateString.append( "-" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); - m_aCreationMetaDateString.append( "-" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); - m_aCreationMetaDateString.append( "T" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); - } + rtl::OStringBuffer aCreationDateString(64), aCreationMetaDateString(64); + aCreationDateString.append( "D:" ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); + + //--> i59651, we fill the Metadata date string as well, if PDF/A is requested + // according to ISO 19005-1:2005 6.7.3 the date is corrected for + // local time zone offset UTC only, whereas Acrobat 8 seems + // to use the localtime notation only + // according to a raccomandation in XMP Specification (Jan 2004, page 75) + // the Acrobat way seems the right approach + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/1000)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/100)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Year)%10)) ); + aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Month)%10)) ); + aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Day)%10)) ); + aCreationMetaDateString.append( "T" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Hours)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Minutes)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds/10)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((aDT.Seconds)%10)) ); + sal_uInt32 nDelta = 0; if( aGMT.Seconds > aTVal.Seconds ) { - m_aCreationDateString.append( "-" ); + aCreationDateString.append( "-" ); nDelta = aGMT.Seconds-aTVal.Seconds; - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "-" ); + aCreationMetaDateString.append( "-" ); } else if( aGMT.Seconds < aTVal.Seconds ) { - m_aCreationDateString.append( "+" ); + aCreationDateString.append( "+" ); nDelta = aTVal.Seconds-aGMT.Seconds; - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "+" ); + aCreationMetaDateString.append( "+" ); } else { - m_aCreationDateString.append( "Z" ); - if( m_bIsPDF_A1 ) - m_aCreationMetaDateString.append( "Z" ); + aCreationDateString.append( "Z" ); + aCreationMetaDateString.append( "Z" ); } if( nDelta ) { - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); - m_aCreationDateString.append( "'" ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); - m_aCreationDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); - if( m_bIsPDF_A1 ) - { - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); - m_aCreationMetaDateString.append( ":" ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); - m_aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); - } + aCreationDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); + aCreationDateString.append( "'" ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); + aCreationDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); + + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/36000)%10)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/3600)%10)) ); + aCreationMetaDateString.append( ":" ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/600)%6)) ); + aCreationMetaDateString.append( (sal_Char)('0' + ((nDelta/60)%10)) ); } - m_aCreationDateString.append( "'" ); - aID.append( m_aCreationDateString.getStr(), m_aCreationDateString.getLength() ); + aCreationDateString.append( "'" ); + aID.append( aCreationDateString.getStr(), aCreationDateString.getLength() ); aInfoValuesOut = aID.makeStringAndClear(); + o_rCString1 = aCreationDateString.makeStringAndClear(); + o_rCString2 = aCreationMetaDateString.makeStringAndClear(); - DBG_ASSERT( m_aDigest != NULL, "PDFWrite_Impl::setDocInfo: cannot obtain a digest object !" ); - - m_aDocID.setLength( 0 ); - if( m_aDigest ) + rtlDigest aDigest = rtl_digest_createMD5(); + OSL_ENSURE( aDigest != NULL, "PDFWriterImpl::computeDocumentIdentifier: cannot obtain a digest object !" ); + if( aDigest ) { - osl_getSystemTime( &aGMT ); - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, &aGMT, sizeof( aGMT ) ); + rtlDigestError nError = rtl_digest_updateMD5( aDigest, &aGMT, sizeof( aGMT ) ); if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_aContext.URL.getStr(), m_aContext.URL.getLength()*sizeof(sal_Unicode) ); - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, aInfoValuesOut.getStr(), aInfoValuesOut.getLength() ); + nError = rtl_digest_updateMD5( aDigest, aInfoValuesOut.getStr(), aInfoValuesOut.getLength() ); if( nError == rtl_Digest_E_None ) { -//the binary form of the doc id is needed for encryption stuff - rtl_digest_getMD5( m_aDigest, m_nDocID, 16 ); - for( unsigned int i = 0; i < 16; i++ ) - appendHex( m_nDocID[i], m_aDocID ); + o_rIdentifier = std::vector< sal_uInt8 >( 16, 0 ); + //the binary form of the doc id is needed for encryption stuff + rtl_digest_getMD5( aDigest, &o_rIdentifier[0], 16 ); } } } @@ -1954,7 +1982,7 @@ append the string as unicode hex, encrypted if needed inline void PDFWriterImpl::appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, OStringBuffer& rOutBuffer ) { rOutBuffer.append( "<" ); - if( m_aContext.Encrypt ) + if( m_aContext.Encryption.Encrypt() ) { const sal_Unicode* pStr = rInString.getStr(); sal_Int32 nLen = rInString.getLength(); @@ -1991,7 +2019,7 @@ inline void PDFWriterImpl::appendLiteralStringEncrypt( rtl::OStringBuffer& rInSt rOutBuffer.append( "(" ); sal_Int32 nChars = rInString.getLength(); //check for encryption, if ok, encrypt the string, then convert with appndLiteralString - if( m_aContext.Encrypt && checkEncryptionBufferSize( nChars ) ) + if( m_aContext.Encryption.Encrypt() && checkEncryptionBufferSize( nChars ) ) { //encrypt the string in a buffer, then append it enableStringEncryption( nInObjectNumber ); @@ -2136,7 +2164,10 @@ OutputDevice* PDFWriterImpl::getReferenceDevice() m_pReferenceDevice = pVDev; - pVDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_PDF1 ); + if( m_aContext.DPIx == 0 || m_aContext.DPIy == 0 ) + pVDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_PDF1 ); + else + pVDev->SetReferenceDevice( m_aContext.DPIx, m_aContext.DPIy ); pVDev->SetOutputSizePixel( Size( 640, 480 ) ); pVDev->SetMapMode( MAP_MM ); @@ -2378,9 +2409,6 @@ SalLayout* PDFWriterImpl::GetTextLayout( ImplLayoutArgs& rArgs, ImplFontSelectDa sal_Int32 PDFWriterImpl::newPage( sal_Int32 nPageWidth, sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation ) { - if( m_aContext.Encrypt && m_aPages.empty() ) - initEncryption(); - endPage(); m_nCurrentPage = m_aPages.size(); m_aPages.push_back( PDFPage(this, nPageWidth, nPageHeight, eOrientation ) ); @@ -4081,15 +4109,15 @@ bool PDFWriterImpl::emitFonts() } else if( (aSubsetInfo.m_nFontType & FontSubsetInfo::TYPE1_PFB) != 0 ) // TODO: also support PFA? { - unsigned char* pBuffer = new unsigned char[ (int)nLength1 ]; + boost::shared_array<unsigned char> pBuffer( new unsigned char[ nLength1 ] ); sal_uInt64 nBytesRead = 0; - CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, pBuffer, nLength1, &nBytesRead ) ) ); + CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, pBuffer.get(), nLength1, &nBytesRead ) ) ); DBG_ASSERT( nBytesRead==nLength1, "PDF-FontSubset read incomplete!" ); CHECK_RETURN( (osl_File_E_None == osl_setFilePos( aFontFile, osl_Pos_Absolut, 0 ) ) ); // get the PFB-segment lengths ThreeInts aSegmentLengths = {0,0,0}; - getPfbSegmentLengths( pBuffer, (int)nBytesRead, aSegmentLengths ); + getPfbSegmentLengths( pBuffer.get(), (int)nBytesRead, aSegmentLengths ); // the lengths below are mandatory for PDF-exported Type1 fonts // because the PFB segment headers get stripped! WhyOhWhy. aLine.append( (sal_Int32)aSegmentLengths[0] ); @@ -4106,11 +4134,9 @@ bool PDFWriterImpl::emitFonts() // emit PFB-sections without section headers beginCompression(); checkAndEnableStreamEncryption( nFontStream ); - CHECK_RETURN( writeBuffer( pBuffer+ 6, aSegmentLengths[0] ) ); - CHECK_RETURN( writeBuffer( pBuffer+12 + aSegmentLengths[0], aSegmentLengths[1] ) ); - CHECK_RETURN( writeBuffer( pBuffer+18 + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) ); - - delete[] pBuffer; + CHECK_RETURN( writeBuffer( &pBuffer[6], aSegmentLengths[0] ) ); + CHECK_RETURN( writeBuffer( &pBuffer[12] + aSegmentLengths[0], aSegmentLengths[1] ) ); + CHECK_RETURN( writeBuffer( &pBuffer[18] + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) ); } else { @@ -5877,7 +5903,7 @@ bool PDFWriterImpl::emitCatalog() } // viewer preferences, if we had some, then emit if( m_aContext.HideViewerToolbar || - ( m_aContext.Version > PDFWriter::PDF_1_3 && m_aDocInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) || + ( m_aContext.Version > PDFWriter::PDF_1_3 && m_aContext.DocumentInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) || m_aContext.HideViewerMenubar || m_aContext.HideViewerWindowControls || m_aContext.FitWindow || m_aContext.CenterWindow || (m_aContext.FirstPageLeft && m_aContext.PageLayout == PDFWriter::ContinuousFacing ) || @@ -5894,7 +5920,7 @@ bool PDFWriterImpl::emitCatalog() aLine.append( "/FitWindow true\n" ); if( m_aContext.CenterWindow ) aLine.append( "/CenterWindow true\n" ); - if( m_aContext.Version > PDFWriter::PDF_1_3 && m_aDocInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) + if( m_aContext.Version > PDFWriter::PDF_1_3 && m_aContext.DocumentInfo.Title.Len() && m_aContext.DisplayPDFDocumentTitle ) aLine.append( "/DisplayDocTitle true\n" ); if( m_aContext.FirstPageLeft && m_aContext.PageLayout == PDFWriter::ContinuousFacing ) aLine.append( "/Direction/R2L\n" ); @@ -5998,40 +6024,40 @@ sal_Int32 PDFWriterImpl::emitInfoDict( ) aLine.append( nObject ); aLine.append( " 0 obj\n" "<<" ); - if( m_aDocInfo.Title.Len() ) + if( m_aContext.DocumentInfo.Title.Len() ) { aLine.append( "/Title" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Title, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Title, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Author.Len() ) + if( m_aContext.DocumentInfo.Author.Len() ) { aLine.append( "/Author" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Author, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Author, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Subject.Len() ) { aLine.append( "/Subject" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Subject, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Subject, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Keywords.Len() ) { aLine.append( "/Keywords" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Keywords, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Keywords, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Creator.Len() ) + if( m_aContext.DocumentInfo.Creator.Len() ) { aLine.append( "/Creator" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Creator, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Creator, nObject, aLine ); aLine.append( "\n" ); } - if( m_aDocInfo.Producer.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() ) { aLine.append( "/Producer" ); - appendUnicodeTextStringEncrypt( m_aDocInfo.Producer, nObject, aLine ); + appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Producer, nObject, aLine ); aLine.append( "\n" ); } @@ -6277,45 +6303,45 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " <pdfaid:conformance>A</pdfaid:conformance>\n" ); aMetadataStream.append( " </rdf:Description>\n" ); //... Dublin Core properties go here - if( m_aDocInfo.Title.Len() || - m_aDocInfo.Author.Len() || - m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Title.Len() || + m_aContext.DocumentInfo.Author.Len() || + m_aContext.DocumentInfo.Subject.Len() ) { aMetadataStream.append( " <rdf:Description rdf:about=\"\"\n" ); aMetadataStream.append( " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n" ); - if( m_aDocInfo.Title.Len() ) + if( m_aContext.DocumentInfo.Title.Len() ) { // this is according to PDF/A-1, technical corrigendum 1 (2007-04-01) aMetadataStream.append( " <dc:title>\n" ); aMetadataStream.append( " <rdf:Alt>\n" ); aMetadataStream.append( " <rdf:li xml:lang=\"x-default\">" ); rtl::OUString aTitle; - escapeStringXML( m_aDocInfo.Title, aTitle ); + escapeStringXML( m_aContext.DocumentInfo.Title, aTitle ); aMetadataStream.append( OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Alt>\n" ); aMetadataStream.append( " </dc:title>\n" ); } - if( m_aDocInfo.Author.Len() ) + if( m_aContext.DocumentInfo.Author.Len() ) { aMetadataStream.append( " <dc:creator>\n" ); aMetadataStream.append( " <rdf:Seq>\n" ); aMetadataStream.append( " <rdf:li>" ); rtl::OUString aAuthor; - escapeStringXML( m_aDocInfo.Author, aAuthor ); + escapeStringXML( m_aContext.DocumentInfo.Author, aAuthor ); aMetadataStream.append( OUStringToOString( aAuthor , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Seq>\n" ); aMetadataStream.append( " </dc:creator>\n" ); } - if( m_aDocInfo.Subject.Len() ) + if( m_aContext.DocumentInfo.Subject.Len() ) { // this is according to PDF/A-1, technical corrigendum 1 (2007-04-01) aMetadataStream.append( " <dc:description>\n" ); aMetadataStream.append( " <rdf:Alt>\n" ); aMetadataStream.append( " <rdf:li xml:lang=\"x-default\">" ); rtl::OUString aSubject; - escapeStringXML( m_aDocInfo.Subject, aSubject ); + escapeStringXML( m_aContext.DocumentInfo.Subject, aSubject ); aMetadataStream.append( OUStringToOString( aSubject , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</rdf:li>\n" ); aMetadataStream.append( " </rdf:Alt>\n" ); @@ -6325,24 +6351,24 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() } //... PDF properties go here - if( m_aDocInfo.Producer.Len() || - m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() || + m_aContext.DocumentInfo.Keywords.Len() ) { aMetadataStream.append( " <rdf:Description rdf:about=\"\"\n" ); aMetadataStream.append( " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n" ); - if( m_aDocInfo.Producer.Len() ) + if( m_aContext.DocumentInfo.Producer.Len() ) { aMetadataStream.append( " <pdf:Producer>" ); rtl::OUString aProducer; - escapeStringXML( m_aDocInfo.Producer, aProducer ); + escapeStringXML( m_aContext.DocumentInfo.Producer, aProducer ); aMetadataStream.append( OUStringToOString( aProducer , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</pdf:Producer>\n" ); } - if( m_aDocInfo.Keywords.Len() ) + if( m_aContext.DocumentInfo.Keywords.Len() ) { aMetadataStream.append( " <pdf:Keywords>" ); rtl::OUString aKeywords; - escapeStringXML( m_aDocInfo.Keywords, aKeywords ); + escapeStringXML( m_aContext.DocumentInfo.Keywords, aKeywords ); aMetadataStream.append( OUStringToOString( aKeywords , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</pdf:Keywords>\n" ); } @@ -6351,11 +6377,11 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadataStream.append( " <rdf:Description rdf:about=\"\"\n" ); aMetadataStream.append( " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\">\n" ); - if( m_aDocInfo.Creator.Len() ) + if( m_aContext.DocumentInfo.Creator.Len() ) { aMetadataStream.append( " <xmp:CreatorTool>" ); rtl::OUString aCreator; - escapeStringXML( m_aDocInfo.Creator, aCreator ); + escapeStringXML( m_aContext.DocumentInfo.Creator, aCreator ); aMetadataStream.append( OUStringToOString( aCreator , RTL_TEXTENCODING_UTF8 ) ); aMetadataStream.append( "</xmp:CreatorTool>\n" ); } @@ -6411,7 +6437,7 @@ bool PDFWriterImpl::emitTrailer() sal_Int32 nSecObject = 0; - if( m_aContext.Encrypt == true ) + if( m_aContext.Encryption.Encrypt() ) { //emit the security information //must be emitted as indirect dictionary object, since @@ -6425,16 +6451,16 @@ bool PDFWriterImpl::emitTrailer() aLineS.append( " 0 obj\n" "<</Filter/Standard/V " ); // check the version - if( m_aContext.Security128bit == true ) + if( m_aContext.Encryption.Security128bit ) aLineS.append( "2/Length 128/R 3" ); else aLineS.append( "1/R 2" ); // emit the owner password, must not be encrypted aLineS.append( "/O(" ); - appendLiteralString( (const sal_Char*)m_nEncryptedOwnerPassword, 32, aLineS ); + appendLiteralString( (const sal_Char*)&m_aContext.Encryption.OValue[0], sal_Int32(m_aContext.Encryption.OValue.size()), aLineS ); aLineS.append( ")/U(" ); - appendLiteralString( (const sal_Char*)m_nEncryptedUserPassword, 32, aLineS ); + appendLiteralString( (const sal_Char*)&m_aContext.Encryption.UValue[0], sal_Int32(m_aContext.Encryption.UValue.size()), aLineS ); aLineS.append( ")/P " );// the permission set aLineS.append( m_nAccessPermissions ); aLineS.append( ">>\nendobj\n\n" ); @@ -6500,13 +6526,21 @@ bool PDFWriterImpl::emitTrailer() aLine.append( nDocInfoObject ); aLine.append( " 0 R\n" ); } - if( m_aDocID.getLength() ) + if( ! m_aContext.Encryption.DocumentIdentifier.empty() ) { aLine.append( "/ID [ <" ); - aLine.append( m_aDocID.getStr(), m_aDocID.getLength() ); + for( std::vector< sal_uInt8 >::const_iterator it = m_aContext.Encryption.DocumentIdentifier.begin(); + it != m_aContext.Encryption.DocumentIdentifier.end(); ++it ) + { + appendHex( sal_Int8(*it), aLine ); + } aLine.append( ">\n" "<" ); - aLine.append( m_aDocID.getStr(), m_aDocID.getLength() ); + for( std::vector< sal_uInt8 >::const_iterator it = m_aContext.Encryption.DocumentIdentifier.begin(); + it != m_aContext.Encryption.DocumentIdentifier.end(); ++it ) + { + appendHex( sal_Int8(*it), aLine ); + } aLine.append( "> ]\n" ); } if( aDocChecksum.getLength() ) @@ -7399,7 +7433,14 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT // try to handle ligatures and such if( i < nGlyphs-1 ) { - pUnicodesPerGlyph[i] = nChars = pCharPosAry[i+1] - pCharPosAry[i]; + nChars = pCharPosAry[i+1] - pCharPosAry[i]; + // #i115618# fix for simple RTL+CTL cases + // TODO: sanitize for RTL ligatures, more complex CTL, etc. + if( nChars < 0 ) + nChars = -nChars; + else if( nChars == 0 ) + nChars = 1; + pUnicodesPerGlyph[i] = nChars; for( int n = 1; n < nChars; n++ ) aUnicodes.push_back( rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]+n) ) ); } @@ -8500,6 +8541,7 @@ void PDFWriterImpl::beginRedirect( SvStream* pStream, const Rectangle& rTargetRe { push( PUSH_ALL ); + // force reemitting clip region clearClipRegion(); updateGraphicsState(); @@ -8543,7 +8585,10 @@ SvStream* PDFWriterImpl::endRedirect() } pop(); - // force reemitting colors + // force reemitting colors and clip region + clearClipRegion(); + m_aCurrentPDFState.m_bClipRegion = m_aGraphicsStack.front().m_bClipRegion; + m_aCurrentPDFState.m_aClipRegion = m_aGraphicsStack.front().m_aClipRegion; m_aCurrentPDFState.m_aLineColor = Color( COL_TRANSPARENT ); m_aCurrentPDFState.m_aFillColor = Color( COL_TRANSPARENT ); @@ -9653,7 +9698,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask ) aLine.append( "[ /Indexed/DeviceRGB " ); aLine.append( (sal_Int32)(pAccess->GetPaletteEntryCount()-1) ); aLine.append( "\n<" ); - if( m_aContext.Encrypt ) + if( m_aContext.Encryption.Encrypt() ) { enableStringEncryption( rObject.m_nObject ); //check encryption buffer size @@ -10840,7 +10885,7 @@ sal_Int32 PDFWriterImpl::setOutlineItemText( sal_Int32 nItem, const OUString& rT if( nItem < 1 || nItem >= (sal_Int32)m_aOutline.size() ) return -1; - m_aOutline[ nItem ].m_aTitle = rText; + m_aOutline[ nItem ].m_aTitle = psp::WhitespaceToSpace( rText ); return 0; } @@ -12039,268 +12084,5 @@ void PDFWriterImpl::addStream( const String& rMimeType, PDFOutputStream* pStream } } -/************************************************************* -begin i12626 methods - -Implements Algorithm 3.2, step 1 only -*/ -void PDFWriterImpl::padPassword( rtl::OUString aPassword, sal_uInt8 *paPasswordTarget ) -{ -// get ansi-1252 version of the password string CHECKIT ! i12626 - rtl::OString aString = rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_MS_1252 ); - -//copy the string to the target - sal_Int32 nToCopy = ( aString.getLength() < 32 ) ? aString.getLength() : 32; - sal_Int32 nCurrentChar; - - for( nCurrentChar = 0; nCurrentChar < nToCopy; nCurrentChar++ ) - paPasswordTarget[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); - -//pad it - if( nCurrentChar < 32 ) - {//fill with standard byte string - sal_Int32 i,y; - for( i = nCurrentChar, y = 0 ; i < 32; i++, y++ ) - paPasswordTarget[i] = m_nPadString[y]; - } -} - -/********************************** -Algorithm 3.2 Compute the encryption key used - -step 1 should already be done before calling, the paThePaddedPassword parameter should contain -the padded password and must be 32 byte long, the encryption key is returned into the paEncryptionKey parameter, -it will be 16 byte long for 128 bit security; for 40 bit security only the first 5 bytes are used - -TODO: in pdf ver 1.5 and 1.6 the step 6 is different, should be implemented. See spec. - -*/ -void PDFWriterImpl::computeEncryptionKey(sal_uInt8 *paThePaddedPassword, sal_uInt8 *paEncryptionKey ) -{ -//step 2 - if( m_aDigest ) - { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, paThePaddedPassword, ENCRYPTED_PWD_SIZE ); -//step 3 - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nEncryptedOwnerPassword , sizeof( m_nEncryptedOwnerPassword ) ); -//Step 4 - sal_uInt8 nPerm[4]; - - nPerm[0] = (sal_uInt8)m_nAccessPermissions; - nPerm[1] = (sal_uInt8)( m_nAccessPermissions >> 8 ); - nPerm[2] = (sal_uInt8)( m_nAccessPermissions >> 16 ); - nPerm[3] = (sal_uInt8)( m_nAccessPermissions >> 24 ); - - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, nPerm , sizeof( nPerm ) ); - -//step 5, get the document ID, binary form - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nDocID , sizeof( m_nDocID ) ); -//get the digest - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - if( nError == rtl_Digest_E_None ) - { - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - -//step 6, only if 128 bit - if( m_aContext.Security128bit ) - { - for( sal_Int32 i = 0; i < 50; i++ ) - { - nError = rtl_digest_updateMD5( m_aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); - if( nError != rtl_Digest_E_None ) - break; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - } - } - } -//Step 7 - for( sal_Int32 i = 0; i < MD5_DIGEST_SIZE; i++ ) - paEncryptionKey[i] = nMD5Sum[i]; - } -} - -/********************************** -Algorithm 3.3 Compute the encryption dictionary /O value, save into the class data member -the step numbers down here correspond to the ones in PDF v.1.4 specfication -*/ -void PDFWriterImpl::computeODictionaryValue() -{ -//step 1 already done, data is in m_nPaddedOwnerPassword -//step 2 - if( m_aDigest ) - { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, &m_nPaddedOwnerPassword, sizeof( m_nPaddedOwnerPassword ) ); - if( nError == rtl_Digest_E_None ) - { - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof(nMD5Sum) ); -//step 3, only if 128 bit - if( m_aContext.Security128bit ) - { - sal_Int32 i; - for( i = 0; i < 50; i++ ) - { - nError = rtl_digest_updateMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - if( nError != rtl_Digest_E_None ) - break; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof( nMD5Sum ) ); - } - } -//Step 4, the key is in nMD5Sum -//step 5 already done, data is in m_nPaddedUserPassword -//step 6 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - nMD5Sum, m_nKeyLength , NULL, 0 ); -// encrypt the user password using the key set above - rtl_cipher_encodeARCFOUR( m_aCipher, m_nPaddedUserPassword, sizeof( m_nPaddedUserPassword ), // the data to be encrypted - m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ) ); //encrypted data, stored in class data member -//Step 7, only if 128 bit - if( m_aContext.Security128bit ) - { - sal_uInt32 i, y; - sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key - for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 - { - for( y = 0; y < sizeof( nLocalKey ); y++ ) - nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i ); - - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - nLocalKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( m_aCipher, m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ), // the data to be encrypted - m_nEncryptedOwnerPassword, sizeof( m_nEncryptedOwnerPassword ) ); // encrypted data, can be the same as the input, encrypt "in place" -//step 8, store in class data member - } - } - } - } -} - -/********************************** -Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into the class data member, revision 2 (40 bit) or 3 (128 bit) -*/ -void PDFWriterImpl::computeUDictionaryValue() -{ -//step 1, common to both 3.4 and 3.5 - computeEncryptionKey( m_nPaddedUserPassword , m_nEncryptionKey ); - - if( m_aContext.Security128bit == false ) - { -//3.4 -//step 2 and 3 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - m_nEncryptionKey, 5 , // key and key length - NULL, 0 ); //destination data area -// encrypt the user password using the key set above, save for later use - rtl_cipher_encodeARCFOUR( m_aCipher, m_nPadString, sizeof( m_nPadString ), // the data to be encrypted - m_nEncryptedUserPassword, sizeof( m_nEncryptedUserPassword ) ); //encrypted data, stored in class data member - } - else - { -//or 3.5, for 128 bit security -//step6, initilize the last 16 bytes of the encrypted user password to 0 - for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sizeof( m_nEncryptedUserPassword ); i++) - m_nEncryptedUserPassword[i] = 0; -//step 2 - if( m_aDigest ) - { - rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, m_nPadString, sizeof( m_nPadString ) ); -//step 3 - if( nError == rtl_Digest_E_None ) - nError = rtl_digest_updateMD5( m_aDigest, m_nDocID , sizeof(m_nDocID) ); - - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - rtl_digest_getMD5( m_aDigest, nMD5Sum, sizeof(nMD5Sum) ); -//Step 4 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - m_nEncryptionKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area - rtl_cipher_encodeARCFOUR( m_aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted - m_nEncryptedUserPassword, sizeof( nMD5Sum ) ); //encrypted data, stored in class data member -//step 5 - sal_uInt32 i, y; - sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; - - for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 - { - for( y = 0; y < sizeof( nLocalKey ) ; y++ ) - nLocalKey[y] = (sal_uInt8)( m_nEncryptionKey[y] ^ i ); - - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, - nLocalKey, SECUR_128BIT_KEY, // key and key length - NULL, 0 ); //destination data area, on init can be NULL - rtl_cipher_encodeARCFOUR( m_aCipher, m_nEncryptedUserPassword, SECUR_128BIT_KEY, // the data to be encrypted - m_nEncryptedUserPassword, SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" - } - } - } -} - -/* init the encryption engine -1. init the document id, used both for building the document id and for building the encryption key(s) -2. build the encryption key following algorithms described in the PDF specification - */ -void PDFWriterImpl::initEncryption() -{ - m_aOwnerPassword = m_aContext.OwnerPassword; - m_aUserPassword = m_aContext.UserPassword; -/* password stuff computing, before sending out anything */ - DBG_ASSERT( m_aCipher != NULL, "PDFWriterImpl::initEncryption: a cipher (ARCFOUR) object is not available !" ); - DBG_ASSERT( m_aDigest != NULL, "PDFWriterImpl::initEncryption: a digest (MD5) object is not available !" ); - - if( m_aCipher && m_aDigest ) - { -//if there is no owner password, force it to the user password - if( m_aOwnerPassword.getLength() == 0 ) - m_aOwnerPassword = m_aUserPassword; - - initPadString(); -/* -1) pad passwords -*/ - padPassword( m_aOwnerPassword, m_nPaddedOwnerPassword ); - padPassword( m_aUserPassword, m_nPaddedUserPassword ); -/* -2) compute the access permissions, in numerical form - -the default value depends on the revision 2 (40 bit) or 3 (128 bit security): -- for 40 bit security the unused bit must be set to 1, since they are not used -- for 128 bit security the same bit must be preset to 0 and set later if needed -according to the table 3.15, pdf v 1.4 */ - m_nAccessPermissions = ( m_aContext.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; - -/* check permissions for 40 bit security case */ - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanPrintTheDocument ) ? 1 << 2 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanModifyTheContent ) ? 1 << 3 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanCopyOrExtract ) ? 1 << 4 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanAddOrModify ) ? 1 << 5 : 0; - m_nKeyLength = SECUR_40BIT_KEY; - m_nRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 - - if( m_aContext.Security128bit ) - { - m_nKeyLength = SECUR_128BIT_KEY; - m_nRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum - // permitted value is 16 - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanFillInteractive ) ? 1 << 8 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanExtractForAccessibility ) ? 1 << 9 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanAssemble ) ? 1 << 10 : 0; - m_nAccessPermissions |= ( m_aContext.AccessPermissions.CanPrintFull ) ? 1 << 11 : 0; - } - computeODictionaryValue(); - computeUDictionaryValue(); - -//clear out exceding key values, prepares for generation number default to 0 as well -// see checkAndEnableStreamEncryption in pdfwriter_impl.hxx - sal_Int32 i, y; - for( i = m_nKeyLength, y = 0; y < 5 ; y++ ) - m_nEncryptionKey[i++] = 0; - } - else //either no cipher or no digest or both, something is wrong with memory or something else - m_aContext.Encrypt = false; //then turn the encryption off -} -/* end i12626 methods */ diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 2eacdc215dd8..5702bee23ea5 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -58,6 +58,7 @@ class ImplFontSelectData; class ImplFontMetricData; class FontSubsetInfo; class ZCodec; +class EncHashTransporter; // the maximum password length #define ENCRYPTED_PWD_SIZE 32 @@ -595,7 +596,6 @@ private: MapMode m_aMapMode; // PDFWriterImpl scaled units std::vector< PDFPage > m_aPages; - PDFDocInfo m_aDocInfo; /* maps object numbers to file offsets (needed for xref) */ std::vector< sal_uInt64 > m_aObjects; /* contains Bitmaps until they are written to the @@ -796,116 +796,37 @@ i12626 /* used to cipher the stream data and for password management */ rtlCipher m_aCipher; rtlDigest m_aDigest; -/* pad string used for password in Standard security handler */ - sal_uInt8 m_nPadString[ENCRYPTED_PWD_SIZE]; -/* the owner password, in clear text */ - rtl::OUString m_aOwnerPassword; -/* the padded owner password */ - sal_uInt8 m_nPaddedOwnerPassword[ENCRYPTED_PWD_SIZE]; -/* the encryption dictionary owner password, according to algorithm 3.3 */ - sal_uInt8 m_nEncryptedOwnerPassword[ENCRYPTED_PWD_SIZE]; -/* the user password, in clear text */ - rtl::OUString m_aUserPassword; -/* the padded user password */ - sal_uInt8 m_nPaddedUserPassword[ENCRYPTED_PWD_SIZE]; -/* the encryption dictionary user password, according to algorithm 3.4 or 3.5 depending on the - security handler revision */ - sal_uInt8 m_nEncryptedUserPassword[ENCRYPTED_PWD_SIZE]; - -/* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2 - for 128 bit security */ - sal_uInt8 m_nEncryptionKey[MAXIMUM_RC4_KEY_LENGTH]; + /* pad string used for password in Standard security handler */ + static const sal_uInt8 s_nPadString[ENCRYPTED_PWD_SIZE]; + + /* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2 + for 128 bit security */ sal_Int32 m_nKeyLength; // key length, 16 or 5 sal_Int32 m_nRC4KeyLength; // key length, 16 or 10, to be input to the algorith 3.1 -/* set to true if the following stream must be encrypted, used inside writeBuffer() */ + /* set to true if the following stream must be encrypted, used inside writeBuffer() */ sal_Bool m_bEncryptThisStream; -/* the numerical value of the access permissions, according to PDF spec, must be signed */ + /* the numerical value of the access permissions, according to PDF spec, must be signed */ sal_Int32 m_nAccessPermissions; -/* the document ID, the raw MD5 hash */ - sal_uInt8 m_nDocID[MD5_DIGEST_SIZE]; -/* string buffer to hold document ID, this is the output string */ - rtl::OStringBuffer m_aDocID; -/* string to hold the PDF creation date */ - rtl::OStringBuffer m_aCreationDateString; -/* string to hold the PDF creation date, for PDF/A metadata */ - rtl::OStringBuffer m_aCreationMetaDateString; -/* the buffer where the data are encrypted, dynamically allocated */ + /* string to hold the PDF creation date */ + rtl::OString m_aCreationDateString; + /* string to hold the PDF creation date, for PDF/A metadata */ + rtl::OString m_aCreationMetaDateString; + /* the buffer where the data are encrypted, dynamically allocated */ sal_uInt8 *m_pEncryptionBuffer; -/* size of the buffer */ + /* size of the buffer */ sal_Int32 m_nEncryptionBufferSize; -/* check and reallocate the buffer for encryption */ - sal_Bool checkEncryptionBufferSize( register sal_Int32 newSize ) - { - if( m_nEncryptionBufferSize < newSize ) - { -/* reallocate the buffer, the used function allocate as rtl_allocateMemory - if the pointer parameter is NULL */ - m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); - if( m_pEncryptionBuffer ) - m_nEncryptionBufferSize = newSize; - else - m_nEncryptionBufferSize = 0; - } - return ( m_nEncryptionBufferSize != 0 ); - } -/* init the internal pad string */ - void initPadString() - { - static const sal_uInt8 nPadString[32] = - { - 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, - 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A - }; - - for(sal_uInt32 i = 0; i < sizeof( nPadString ); i++ ) - m_nPadString[i] = nPadString[i]; - - }; -/* initialize the encryption engine */ - void initEncryption(); - -/* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */ - void checkAndEnableStreamEncryption( register sal_Int32 nObject ) - { - if( m_aContext.Encrypt ) - { - m_bEncryptThisStream = true; - register sal_Int32 i = m_nKeyLength; - m_nEncryptionKey[i++] = (sal_uInt8)nObject; - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); -//the other location of m_nEncryptionKey are already set to 0, our fixed generation number -// do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) ); -// initialize the RC4 with the key -// key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - } - }; + /* check and reallocate the buffer for encryption */ + sal_Bool checkEncryptionBufferSize( register sal_Int32 newSize ); + /* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */ + void checkAndEnableStreamEncryption( register sal_Int32 nObject ); void disableStreamEncryption() { m_bEncryptThisStream = false; }; -/* */ - void enableStringEncryption( register sal_Int32 nObject ) - { - register sal_Int32 i = m_nKeyLength; - m_nEncryptionKey[i++] = (sal_uInt8)nObject; - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); - m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); -//the other location of m_nEncryptionKey are already set to 0, our fixed generation number -// do the MD5 hash - sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; - // the i+2 to take into account the generation number, always zero - rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) ); -// initialize the RC4 with the key -// key legth: see algoritm 3.1, step 4: (N+5) max 16 - rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); - }; + /* */ + void enableStringEncryption( register sal_Int32 nObject ); // test if the encryption is active, if yes than encrypt the unicode string and add to the OStringBuffer parameter void appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer ); @@ -1095,24 +1016,56 @@ i12626 /* true if PDF/A-1a or PDF/A-1b is output */ sal_Bool m_bIsPDF_A1; - -/* -i12626 -methods for PDF security - - pad a password according algorithm 3.2, step 1 */ - void padPassword( const rtl::OUString aPassword, sal_uInt8 *paPasswordTarget ); -/* algorithm 3.2: compute an encryption key */ - void computeEncryptionKey( sal_uInt8 *paThePaddedPassword, sal_uInt8 *paEncryptionKey ); -/* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ - void computeODictionaryValue(); -/* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ - void computeUDictionaryValue(); + PDFWriter& m_rOuterFace; + + /* + i12626 + methods for PDF security + + pad a password according algorithm 3.2, step 1 */ + static void padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ); + /* algorithm 3.2: compute an encryption key */ + static bool computeEncryptionKey( EncHashTransporter*, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nAccessPermissions + ); + /* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ + static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, + std::vector< sal_uInt8 >& io_rOValue, + sal_Int32 i_nKeyLength + ); + /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ + static bool computeUDictionaryValue( EncHashTransporter* i_pTransporter, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, + sal_Int32 i_nAccessPermissions + ); + + static void computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier, + const vcl::PDFWriter::PDFDocInfo& i_rDocInfo, + rtl::OString& o_rCString1, + rtl::OString& o_rCString2 + ); + static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, + sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ); + void setupDocInfo(); + bool prepareEncryption( const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); + + // helper for playMetafile + void implWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient, + VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); + void implWriteBitmapEx( const Point& rPoint, const Size& rSize, const BitmapEx& rBitmapEx, + VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); public: - PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ); + PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >&, PDFWriter& ); ~PDFWriterImpl(); + static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > + initEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit ); + /* for OutputDevice so the reference device can have a list * that contains only suitable fonts (subsettable or builtin) * produces a new font list @@ -1134,6 +1087,7 @@ public: bool emit(); std::set< PDFWriter::ErrorCode > getErrors(); void insertError( PDFWriter::ErrorCode eErr ) { m_aErrors.insert( eErr ); } + void playMetafile( const GDIMetaFile&, vcl::PDFExtOutDevData*, const vcl::PDFWriter::PlayMetafileContext&, VirtualDevice* pDummyDev = NULL ); Size getCurPageSize() const { @@ -1144,8 +1098,6 @@ public: } PDFWriter::PDFVersion getVersion() const { return m_aContext.Version; } - void setDocInfo( const PDFDocInfo& rInfo ); - const PDFDocInfo& getDocInfo() const { return m_aDocInfo; } void setDocumentLocale( const com::sun::star::lang::Locale& rLoc ) { m_aContext.DocumentLocale = rLoc; } diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx new file mode 100644 index 000000000000..ee1fe1cc6bc5 --- /dev/null +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -0,0 +1,1540 @@ +/************************************************************************* + * + * 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 "pdfwriter_impl.hxx" + +#include "vcl/pdfextoutdevdata.hxx" +#include "vcl/virdev.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/metaact.hxx" +#include "vcl/graph.hxx" +#include "vcl/svdata.hxx" +#include "unotools/streamwrap.hxx" +#include "unotools/processfactory.hxx" +#include "comphelper/processfactory.hxx" + +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/io/XSeekable.hpp" +#include "com/sun/star/graphic/XGraphicProvider.hpp" + +#include "cppuhelper/implbase1.hxx" + +#include <rtl/digest.h> + +using namespace vcl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::implWriteGradient( const PolyPolygon& i_rPolyPoly, const Gradient& i_rGradient, + VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext ) +{ + GDIMetaFile aTmpMtf; + + i_pDummyVDev->AddGradientActions( i_rPolyPoly.GetBoundRect(), i_rGradient, aTmpMtf ); + + m_rOuterFace.Push(); + m_rOuterFace.IntersectClipRegion( i_rPolyPoly.getB2DPolyPolygon() ); + playMetafile( aTmpMtf, NULL, i_rContext, i_pDummyVDev ); + m_rOuterFace.Pop(); +} + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSize, const BitmapEx& i_rBitmapEx, + VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext ) +{ + if ( !i_rBitmapEx.IsEmpty() && i_rSize.Width() && i_rSize.Height() ) + { + BitmapEx aBitmapEx( i_rBitmapEx ); + Point aPoint( i_rPoint ); + Size aSize( i_rSize ); + + // #i19065# Negative sizes have mirror semantics on + // OutputDevice. BitmapEx and co. have no idea about that, so + // perform that _before_ doing anything with aBitmapEx. + ULONG nMirrorFlags(BMP_MIRROR_NONE); + if( aSize.Width() < 0 ) + { + aSize.Width() *= -1; + aPoint.X() -= aSize.Width(); + nMirrorFlags |= BMP_MIRROR_HORZ; + } + if( aSize.Height() < 0 ) + { + aSize.Height() *= -1; + aPoint.Y() -= aSize.Height(); + nMirrorFlags |= BMP_MIRROR_VERT; + } + + if( nMirrorFlags != BMP_MIRROR_NONE ) + { + aBitmapEx.Mirror( nMirrorFlags ); + } + if( i_rContext.m_nMaxImageResolution > 50 ) + { + // do downsampling if neccessary + const Size aDstSizeTwip( i_pDummyVDev->PixelToLogic( i_pDummyVDev->LogicToPixel( aSize ), MAP_TWIP ) ); + const Size aBmpSize( aBitmapEx.GetSizePixel() ); + const double fBmpPixelX = aBmpSize.Width(); + const double fBmpPixelY = aBmpSize.Height(); + const double fMaxPixelX = aDstSizeTwip.Width() * i_rContext.m_nMaxImageResolution / 1440.0; + const double fMaxPixelY = aDstSizeTwip.Height() * i_rContext.m_nMaxImageResolution / 1440.0; + + // check, if the bitmap DPI exceeds the maximum DPI (allow 4 pixel rounding tolerance) + if( ( ( fBmpPixelX > ( fMaxPixelX + 4 ) ) || + ( fBmpPixelY > ( fMaxPixelY + 4 ) ) ) && + ( fBmpPixelY > 0.0 ) && ( fMaxPixelY > 0.0 ) ) + { + // do scaling + Size aNewBmpSize; + const double fBmpWH = fBmpPixelX / fBmpPixelY; + const double fMaxWH = fMaxPixelX / fMaxPixelY; + + if( fBmpWH < fMaxWH ) + { + aNewBmpSize.Width() = FRound( fMaxPixelY * fBmpWH ); + aNewBmpSize.Height() = FRound( fMaxPixelY ); + } + else if( fBmpWH > 0.0 ) + { + aNewBmpSize.Width() = FRound( fMaxPixelX ); + aNewBmpSize.Height() = FRound( fMaxPixelX / fBmpWH); + } + if( aNewBmpSize.Width() && aNewBmpSize.Height() ) + aBitmapEx.Scale( aNewBmpSize ); + else + aBitmapEx.SetEmpty(); + } + } + + const Size aSizePixel( aBitmapEx.GetSizePixel() ); + if ( aSizePixel.Width() && aSizePixel.Height() ) + { + sal_Bool bUseJPGCompression = !i_rContext.m_bOnlyLosslessCompression; + if ( ( aSizePixel.Width() < 32 ) || ( aSizePixel.Height() < 32 ) ) + bUseJPGCompression = sal_False; + + SvMemoryStream aStrm; + Bitmap aMask; + + bool bTrueColorJPG = true; + if ( bUseJPGCompression ) + { + sal_uInt32 nZippedFileSize; // sj: we will calculate the filesize of a zipped bitmap + { // to determine if jpeg compression is usefull + SvMemoryStream aTemp; + aTemp.SetCompressMode( aTemp.GetCompressMode() | COMPRESSMODE_ZBITMAP ); + aTemp.SetVersion( SOFFICE_FILEFORMAT_40 ); // sj: up from version 40 our bitmap stream operator + aTemp << aBitmapEx; // is capable of zlib stream compression + aTemp.Seek( STREAM_SEEK_TO_END ); + nZippedFileSize = aTemp.Tell(); + } + if ( aBitmapEx.IsTransparent() ) + { + if ( aBitmapEx.IsAlpha() ) + aMask = aBitmapEx.GetAlpha().GetBitmap(); + else + aMask = aBitmapEx.GetMask(); + } + Graphic aGraphic( aBitmapEx.GetBitmap() ); + sal_Int32 nColorMode = 0; + + Sequence< PropertyValue > aFilterData( 2 ); + aFilterData[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ); + aFilterData[ 0 ].Value <<= sal_Int32(i_rContext.m_nJPEGQuality); + aFilterData[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) ); + aFilterData[ 1 ].Value <<= nColorMode; + + try + { + uno::Reference < io::XStream > xStream = new utl::OStreamWrapper( aStrm ); + Reference< io::XSeekable > xSeekable( xStream, UNO_QUERY_THROW ); + Reference< graphic::XGraphicProvider > xGraphicProvider( ImplGetSVData()->maAppData.mxMSF->createInstance( + OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ); + if ( xGraphicProvider.is() ) + { + Reference< graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() ); + Reference < io::XOutputStream > xOut( xStream->getOutputStream() ); + rtl::OUString aMimeType( ::rtl::OUString::createFromAscii( "image/jpeg" ) ); + uno::Sequence< beans::PropertyValue > aOutMediaProperties( 3 ); + aOutMediaProperties[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" ); + aOutMediaProperties[0].Value <<= xOut; + aOutMediaProperties[1].Name = ::rtl::OUString::createFromAscii( "MimeType" ); + aOutMediaProperties[1].Value <<= aMimeType; + aOutMediaProperties[2].Name = ::rtl::OUString::createFromAscii( "FilterData" ); + aOutMediaProperties[2].Value <<= aFilterData; + xGraphicProvider->storeGraphic( xGraphic, aOutMediaProperties ); + xOut->flush(); + if ( xSeekable->getLength() > nZippedFileSize ) + { + bUseJPGCompression = sal_False; + } + else + { + aStrm.Seek( STREAM_SEEK_TO_END ); + + xSeekable->seek( 0 ); + Sequence< PropertyValue > aArgs( 1 ); + aArgs[ 0 ].Name = ::rtl::OUString::createFromAscii( "InputStream" ); + aArgs[ 0 ].Value <<= xStream; + Reference< XPropertySet > xPropSet( xGraphicProvider->queryGraphicDescriptor( aArgs ) ); + if ( xPropSet.is() ) + { + sal_Int16 nBitsPerPixel = 24; + if ( xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "BitsPerPixel" ) ) >>= nBitsPerPixel ) + { + bTrueColorJPG = nBitsPerPixel != 8; + } + } + } + } + else + bUseJPGCompression = sal_False; + } + catch( uno::Exception& ) + { + bUseJPGCompression = sal_False; + } + } + if ( bUseJPGCompression ) + m_rOuterFace.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, Rectangle( aPoint, aSize ), aMask ); + else if ( aBitmapEx.IsTransparent() ) + m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx ); + else + m_rOuterFace.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap() ); + } + } +} + + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::playMetafile( const GDIMetaFile& i_rMtf, vcl::PDFExtOutDevData* i_pOutDevData, const vcl::PDFWriter::PlayMetafileContext& i_rContext, VirtualDevice* pDummyVDev ) +{ + bool bAssertionFired( false ); + + VirtualDevice* pPrivateDevice = NULL; + if( ! pDummyVDev ) + { + pPrivateDevice = pDummyVDev = new VirtualDevice(); + pDummyVDev->EnableOutput( sal_False ); + pDummyVDev->SetMapMode( i_rMtf.GetPrefMapMode() ); + } + GDIMetaFile aMtf( i_rMtf ); + + for( sal_uInt32 i = 0, nCount = aMtf.GetActionCount(); i < nCount; ) + { + if ( !i_pOutDevData || !i_pOutDevData->PlaySyncPageAct( m_rOuterFace, i ) ) + { + const MetaAction* pAction = aMtf.GetAction( i ); + const USHORT nType = pAction->GetType(); + + switch( nType ) + { + case( META_PIXEL_ACTION ): + { + const MetaPixelAction* pA = (const MetaPixelAction*) pAction; + m_rOuterFace.DrawPixel( pA->GetPoint(), pA->GetColor() ); + } + break; + + case( META_POINT_ACTION ): + { + const MetaPointAction* pA = (const MetaPointAction*) pAction; + m_rOuterFace.DrawPixel( pA->GetPoint() ); + } + break; + + case( META_LINE_ACTION ): + { + const MetaLineAction* pA = (const MetaLineAction*) pAction; + if ( pA->GetLineInfo().IsDefault() ) + m_rOuterFace.DrawLine( pA->GetStartPoint(), pA->GetEndPoint() ); + else + m_rOuterFace.DrawLine( pA->GetStartPoint(), pA->GetEndPoint(), pA->GetLineInfo() ); + } + break; + + case( META_RECT_ACTION ): + { + const MetaRectAction* pA = (const MetaRectAction*) pAction; + m_rOuterFace.DrawRect( pA->GetRect() ); + } + break; + + case( META_ROUNDRECT_ACTION ): + { + const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction; + m_rOuterFace.DrawRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() ); + } + break; + + case( META_ELLIPSE_ACTION ): + { + const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction; + m_rOuterFace.DrawEllipse( pA->GetRect() ); + } + break; + + case( META_ARC_ACTION ): + { + const MetaArcAction* pA = (const MetaArcAction*) pAction; + m_rOuterFace.DrawArc( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_PIE_ACTION ): + { + const MetaArcAction* pA = (const MetaArcAction*) pAction; + m_rOuterFace.DrawPie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_CHORD_ACTION ): + { + const MetaChordAction* pA = (const MetaChordAction*) pAction; + m_rOuterFace.DrawChord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_POLYGON_ACTION ): + { + const MetaPolygonAction* pA = (const MetaPolygonAction*) pAction; + m_rOuterFace.DrawPolygon( pA->GetPolygon() ); + } + break; + + case( META_POLYLINE_ACTION ): + { + const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction; + if ( pA->GetLineInfo().IsDefault() ) + m_rOuterFace.DrawPolyLine( pA->GetPolygon() ); + else + m_rOuterFace.DrawPolyLine( pA->GetPolygon(), pA->GetLineInfo() ); + } + break; + + case( META_POLYPOLYGON_ACTION ): + { + const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pAction; + m_rOuterFace.DrawPolyPolygon( pA->GetPolyPolygon() ); + } + break; + + case( META_GRADIENT_ACTION ): + { + const MetaGradientAction* pA = (const MetaGradientAction*) pAction; + const PolyPolygon aPolyPoly( pA->GetRect() ); + + implWriteGradient( aPolyPoly, pA->GetGradient(), pDummyVDev, i_rContext ); + } + break; + + case( META_GRADIENTEX_ACTION ): + { + const MetaGradientExAction* pA = (const MetaGradientExAction*) pAction; + implWriteGradient( pA->GetPolyPolygon(), pA->GetGradient(), pDummyVDev, i_rContext ); + } + break; + + case META_HATCH_ACTION: + { + const MetaHatchAction* pA = (const MetaHatchAction*) pAction; + m_rOuterFace.DrawHatch( pA->GetPolyPolygon(), pA->GetHatch() ); + } + break; + + case( META_TRANSPARENT_ACTION ): + { + const MetaTransparentAction* pA = (const MetaTransparentAction*) pAction; + m_rOuterFace.DrawTransparent( pA->GetPolyPolygon(), pA->GetTransparence() ); + } + break; + + case( META_FLOATTRANSPARENT_ACTION ): + { + const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction; + + GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() ); + const Point& rPos = pA->GetPoint(); + const Size& rSize= pA->GetSize(); + const Gradient& rTransparenceGradient = pA->GetGradient(); + + // special case constant alpha value + if( rTransparenceGradient.GetStartColor() == rTransparenceGradient.GetEndColor() ) + { + const Color aTransCol( rTransparenceGradient.GetStartColor() ); + const USHORT nTransPercent = aTransCol.GetLuminance() * 100 / 255; + m_rOuterFace.BeginTransparencyGroup(); + playMetafile( aTmpMtf, NULL, i_rContext, pDummyVDev ); + m_rOuterFace.EndTransparencyGroup( Rectangle( rPos, rSize ), nTransPercent ); + } + else + { + const Size aDstSizeTwip( pDummyVDev->PixelToLogic( pDummyVDev->LogicToPixel( rSize ), MAP_TWIP ) ); + sal_Int32 nMaxBmpDPI = i_rContext.m_bOnlyLosslessCompression ? 300 : 72; + if( i_rContext.m_nMaxImageResolution > 50 ) + { + if ( nMaxBmpDPI > i_rContext.m_nMaxImageResolution ) + nMaxBmpDPI = i_rContext.m_nMaxImageResolution; + } + const sal_Int32 nPixelX = (sal_Int32)((double)aDstSizeTwip.Width() * (double)nMaxBmpDPI / 1440.0); + const sal_Int32 nPixelY = (sal_Int32)((double)aDstSizeTwip.Height() * (double)nMaxBmpDPI / 1440.0); + if ( nPixelX && nPixelY ) + { + Size aDstSizePixel( nPixelX, nPixelY ); + VirtualDevice* pVDev = new VirtualDevice; + if( pVDev->SetOutputSizePixel( aDstSizePixel ) ) + { + Bitmap aPaint, aMask; + AlphaMask aAlpha; + Point aPoint; + + MapMode aMapMode( pDummyVDev->GetMapMode() ); + aMapMode.SetOrigin( aPoint ); + pVDev->SetMapMode( aMapMode ); + Size aDstSize( pVDev->PixelToLogic( aDstSizePixel ) ); + + Point aMtfOrigin( aTmpMtf.GetPrefMapMode().GetOrigin() ); + if ( aMtfOrigin.X() || aMtfOrigin.Y() ) + aTmpMtf.Move( -aMtfOrigin.X(), -aMtfOrigin.Y() ); + double fScaleX = (double)aDstSize.Width() / (double)aTmpMtf.GetPrefSize().Width(); + double fScaleY = (double)aDstSize.Height() / (double)aTmpMtf.GetPrefSize().Height(); + if( fScaleX != 1.0 || fScaleY != 1.0 ) + aTmpMtf.Scale( fScaleX, fScaleY ); + aTmpMtf.SetPrefMapMode( aMapMode ); + + // create paint bitmap + aTmpMtf.WindStart(); + aTmpMtf.Play( pVDev, aPoint, aDstSize ); + aTmpMtf.WindStart(); + + pVDev->EnableMapMode( FALSE ); + aPaint = pVDev->GetBitmap( aPoint, aDstSizePixel ); + pVDev->EnableMapMode( TRUE ); + + // create mask bitmap + pVDev->SetLineColor( COL_BLACK ); + pVDev->SetFillColor( COL_BLACK ); + pVDev->DrawRect( Rectangle( aPoint, aDstSize ) ); + pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT | + DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT ); + aTmpMtf.WindStart(); + aTmpMtf.Play( pVDev, aPoint, aDstSize ); + aTmpMtf.WindStart(); + pVDev->EnableMapMode( FALSE ); + aMask = pVDev->GetBitmap( aPoint, aDstSizePixel ); + pVDev->EnableMapMode( TRUE ); + + // create alpha mask from gradient + pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT ); + pVDev->DrawGradient( Rectangle( aPoint, aDstSize ), rTransparenceGradient ); + pVDev->SetDrawMode( DRAWMODE_DEFAULT ); + pVDev->EnableMapMode( FALSE ); + pVDev->DrawMask( aPoint, aDstSizePixel, aMask, Color( COL_WHITE ) ); + aAlpha = pVDev->GetBitmap( aPoint, aDstSizePixel ); + implWriteBitmapEx( rPos, rSize, BitmapEx( aPaint, aAlpha ), pDummyVDev, i_rContext ); + } + delete pVDev; + } + } + } + break; + + case( META_EPS_ACTION ): + { + const MetaEPSAction* pA = (const MetaEPSAction*) pAction; + const GDIMetaFile aSubstitute( pA->GetSubstitute() ); + + m_rOuterFace.Push(); + pDummyVDev->Push(); + + MapMode aMapMode( aSubstitute.GetPrefMapMode() ); + Size aOutSize( pDummyVDev->LogicToLogic( pA->GetSize(), pDummyVDev->GetMapMode(), aMapMode ) ); + aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) ); + aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) ); + aMapMode.SetOrigin( pDummyVDev->LogicToLogic( pA->GetPoint(), pDummyVDev->GetMapMode(), aMapMode ) ); + + m_rOuterFace.SetMapMode( aMapMode ); + pDummyVDev->SetMapMode( aMapMode ); + playMetafile( aSubstitute, NULL, i_rContext, pDummyVDev ); + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + } + break; + + case( META_COMMENT_ACTION ): + if( ! i_rContext.m_bTransparenciesWereRemoved ) + { + const MetaCommentAction* pA = (const MetaCommentAction*) pAction; + String aSkipComment; + + if( pA->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) + { + const MetaGradientExAction* pGradAction = NULL; + sal_Bool bDone = sal_False; + + while( !bDone && ( ++i < nCount ) ) + { + pAction = aMtf.GetAction( i ); + + if( pAction->GetType() == META_GRADIENTEX_ACTION ) + pGradAction = (const MetaGradientExAction*) pAction; + else if( ( pAction->GetType() == META_COMMENT_ACTION ) && + ( ( (const MetaCommentAction*) pAction )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL ) ) + { + bDone = sal_True; + } + } + + if( pGradAction ) + implWriteGradient( pGradAction->GetPolyPolygon(), pGradAction->GetGradient(), pDummyVDev, i_rContext ); + } + else + { + const BYTE* pData = pA->GetData(); + if ( pData ) + { + SvMemoryStream aMemStm( (void*)pData, pA->GetDataSize(), STREAM_READ ); + sal_Bool bSkipSequence = sal_False; + ByteString sSeqEnd; + + if( pA->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) ) + { + sSeqEnd = ByteString( "XPATHSTROKE_SEQ_END" ); + SvtGraphicStroke aStroke; + aMemStm >> aStroke; + + Polygon aPath; + aStroke.getPath( aPath ); + + PolyPolygon aStartArrow; + PolyPolygon aEndArrow; + double fTransparency( aStroke.getTransparency() ); + double fStrokeWidth( aStroke.getStrokeWidth() ); + SvtGraphicStroke::DashArray aDashArray; + + aStroke.getStartArrow( aStartArrow ); + aStroke.getEndArrow( aEndArrow ); + aStroke.getDashArray( aDashArray ); + + bSkipSequence = sal_True; + if ( aStartArrow.Count() || aEndArrow.Count() ) + bSkipSequence = sal_False; + if ( aDashArray.size() && ( fStrokeWidth != 0.0 ) && ( fTransparency == 0.0 ) ) + bSkipSequence = sal_False; + if ( bSkipSequence ) + { + PDFWriter::ExtLineInfo aInfo; + aInfo.m_fLineWidth = fStrokeWidth; + aInfo.m_fTransparency = fTransparency; + aInfo.m_fMiterLimit = aStroke.getMiterLimit(); + switch( aStroke.getCapType() ) + { + default: + case SvtGraphicStroke::capButt: aInfo.m_eCap = PDFWriter::capButt;break; + case SvtGraphicStroke::capRound: aInfo.m_eCap = PDFWriter::capRound;break; + case SvtGraphicStroke::capSquare: aInfo.m_eCap = PDFWriter::capSquare;break; + } + switch( aStroke.getJoinType() ) + { + default: + case SvtGraphicStroke::joinMiter: aInfo.m_eJoin = PDFWriter::joinMiter;break; + case SvtGraphicStroke::joinRound: aInfo.m_eJoin = PDFWriter::joinRound;break; + case SvtGraphicStroke::joinBevel: aInfo.m_eJoin = PDFWriter::joinBevel;break; + case SvtGraphicStroke::joinNone: + aInfo.m_eJoin = PDFWriter::joinMiter; + aInfo.m_fMiterLimit = 0.0; + break; + } + aInfo.m_aDashArray = aDashArray; + + if(SvtGraphicStroke::joinNone == aStroke.getJoinType() + && fStrokeWidth > 0.0) + { + // emulate no edge rounding by handling single edges + const sal_uInt16 nPoints(aPath.GetSize()); + const bool bCurve(aPath.HasFlags()); + + for(sal_uInt16 a(0); a + 1 < nPoints; a++) + { + if(bCurve + && POLY_NORMAL != aPath.GetFlags(a + 1) + && a + 2 < nPoints + && POLY_NORMAL != aPath.GetFlags(a + 2) + && a + 3 < nPoints) + { + const Polygon aSnippet(4, + aPath.GetConstPointAry() + a, + aPath.GetConstFlagAry() + a); + m_rOuterFace.DrawPolyLine( aSnippet, aInfo ); + a += 2; + } + else + { + const Polygon aSnippet(2, + aPath.GetConstPointAry() + a); + m_rOuterFace.DrawPolyLine( aSnippet, aInfo ); + } + } + } + else + { + m_rOuterFace.DrawPolyLine( aPath, aInfo ); + } + } + } + else if ( pA->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) ) + { + sSeqEnd = ByteString( "XPATHFILL_SEQ_END" ); + SvtGraphicFill aFill; + aMemStm >> aFill; + + if ( ( aFill.getFillType() == SvtGraphicFill::fillSolid ) && ( aFill.getFillRule() == SvtGraphicFill::fillEvenOdd ) ) + { + double fTransparency = aFill.getTransparency(); + if ( fTransparency == 0.0 ) + { + PolyPolygon aPath; + aFill.getPath( aPath ); + + bSkipSequence = sal_True; + m_rOuterFace.DrawPolyPolygon( aPath ); + } + else if ( fTransparency == 1.0 ) + bSkipSequence = sal_True; + } +/* #i81548# removing optimization for fill textures, because most of the texture settings are not + exported properly. In OpenOffice 3.1 the drawing layer will support graphic primitives, then it + will not be a problem to optimize the filltexture export. But for wysiwyg is more important than + filesize. + else if( aFill.getFillType() == SvtGraphicFill::fillTexture && aFill.isTiling() ) + { + sal_Int32 nPattern = mnCachePatternId; + Graphic aPatternGraphic; + aFill.getGraphic( aPatternGraphic ); + bool bUseCache = false; + SvtGraphicFill::Transform aPatTransform; + aFill.getTransform( aPatTransform ); + + if( mnCachePatternId >= 0 ) + { + SvtGraphicFill::Transform aCacheTransform; + maCacheFill.getTransform( aCacheTransform ); + if( aCacheTransform.matrix[0] == aPatTransform.matrix[0] && + aCacheTransform.matrix[1] == aPatTransform.matrix[1] && + aCacheTransform.matrix[2] == aPatTransform.matrix[2] && + aCacheTransform.matrix[3] == aPatTransform.matrix[3] && + aCacheTransform.matrix[4] == aPatTransform.matrix[4] && + aCacheTransform.matrix[5] == aPatTransform.matrix[5] + ) + { + Graphic aCacheGraphic; + maCacheFill.getGraphic( aCacheGraphic ); + if( aCacheGraphic == aPatternGraphic ) + bUseCache = true; + } + } + + if( ! bUseCache ) + { + + // paint graphic to metafile + GDIMetaFile aPattern; + pDummyVDev->SetConnectMetaFile( &aPattern ); + pDummyVDev->Push(); + pDummyVDev->SetMapMode( aPatternGraphic.GetPrefMapMode() ); + + aPatternGraphic.Draw( &rDummyVDev, Point( 0, 0 ) ); + pDummyVDev->Pop(); + pDummyVDev->SetConnectMetaFile( NULL ); + aPattern.WindStart(); + + MapMode aPatternMapMode( aPatternGraphic.GetPrefMapMode() ); + // prepare pattern from metafile + Size aPrefSize( aPatternGraphic.GetPrefSize() ); + // FIXME: this magic -1 shouldn't be necessary + aPrefSize.Width() -= 1; + aPrefSize.Height() -= 1; + aPrefSize = m_rOuterFace.GetReferenceDevice()-> + LogicToLogic( aPrefSize, + &aPatternMapMode, + &m_rOuterFace.GetReferenceDevice()->GetMapMode() ); + // build bounding rectangle of pattern + Rectangle aBound( Point( 0, 0 ), aPrefSize ); + m_rOuterFace.BeginPattern( aBound ); + m_rOuterFace.Push(); + pDummyVDev->Push(); + m_rOuterFace.SetMapMode( aPatternMapMode ); + pDummyVDev->SetMapMode( aPatternMapMode ); + ImplWriteActions( m_rOuterFace, NULL, aPattern, rDummyVDev ); + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + + nPattern = m_rOuterFace.EndPattern( aPatTransform ); + + // try some caching and reuse pattern + mnCachePatternId = nPattern; + maCacheFill = aFill; + } + + // draw polypolygon with pattern fill + PolyPolygon aPath; + aFill.getPath( aPath ); + m_rOuterFace.DrawPolyPolygon( aPath, nPattern, aFill.getFillRule() == SvtGraphicFill::fillEvenOdd ); + + bSkipSequence = sal_True; + } +*/ + } + if ( bSkipSequence ) + { + while( ++i < nCount ) + { + pAction = aMtf.GetAction( i ); + if ( pAction->GetType() == META_COMMENT_ACTION ) + { + ByteString sComment( ((MetaCommentAction*)pAction)->GetComment() ); + if ( sComment.Equals( sSeqEnd ) ) + break; + } + // #i44496# + // the replacement action for stroke is a filled rectangle + // the set fillcolor of the replacement is part of the graphics + // state and must not be skipped + else if( pAction->GetType() == META_FILLCOLOR_ACTION ) + { + const MetaFillColorAction* pMA = (const MetaFillColorAction*) pAction; + if( pMA->IsSetting() ) + m_rOuterFace.SetFillColor( pMA->GetColor() ); + else + m_rOuterFace.SetFillColor(); + } + } + } + } + } + } + break; + + case( META_BMP_ACTION ): + { + const MetaBmpAction* pA = (const MetaBmpAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmap() ); + Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), + aBitmapEx.GetPrefMapMode(), pDummyVDev->GetMapMode() ) ); + if( ! ( aSize.Width() && aSize.Height() ) ) + aSize = pDummyVDev->PixelToLogic( aBitmapEx.GetSizePixel() ); + implWriteBitmapEx( pA->GetPoint(), aSize, aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPSCALE_ACTION ): + { + const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction; + implWriteBitmapEx( pA->GetPoint(), pA->GetSize(), BitmapEx( pA->GetBitmap() ), pDummyVDev, i_rContext ); + } + break; + + case( META_BMPSCALEPART_ACTION ): + { + const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmap() ); + aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); + implWriteBitmapEx( pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEX_ACTION ): + { + const MetaBmpExAction* pA = (const MetaBmpExAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmapEx() ); + Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), + aBitmapEx.GetPrefMapMode(), pDummyVDev->GetMapMode() ) ); + implWriteBitmapEx( pA->GetPoint(), aSize, aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEXSCALE_ACTION ): + { + const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction; + implWriteBitmapEx( pA->GetPoint(), pA->GetSize(), pA->GetBitmapEx(), pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEXSCALEPART_ACTION ): + { + const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmapEx() ); + aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); + implWriteBitmapEx( pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_MASK_ACTION ): + case( META_MASKSCALE_ACTION ): + case( META_MASKSCALEPART_ACTION ): + { + DBG_ERROR( "MetaMask...Action not supported yet" ); + } + break; + + case( META_TEXT_ACTION ): + { + const MetaTextAction* pA = (const MetaTextAction*) pAction; + m_rOuterFace.DrawText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ) ); + } + break; + + case( META_TEXTRECT_ACTION ): + { + const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction; + m_rOuterFace.DrawText( pA->GetRect(), String( pA->GetText() ), pA->GetStyle() ); + } + break; + + case( META_TEXTARRAY_ACTION ): + { + const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction; + m_rOuterFace.DrawTextArray( pA->GetPoint(), pA->GetText(), pA->GetDXArray(), pA->GetIndex(), pA->GetLen() ); + } + break; + + case( META_STRETCHTEXT_ACTION ): + { + const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction; + m_rOuterFace.DrawStretchText( pA->GetPoint(), pA->GetWidth(), pA->GetText(), pA->GetIndex(), pA->GetLen() ); + } + break; + + + case( META_TEXTLINE_ACTION ): + { + const MetaTextLineAction* pA = (const MetaTextLineAction*) pAction; + m_rOuterFace.DrawTextLine( pA->GetStartPoint(), pA->GetWidth(), pA->GetStrikeout(), pA->GetUnderline(), pA->GetOverline() ); + + } + break; + + case( META_CLIPREGION_ACTION ): + { + const MetaClipRegionAction* pA = (const MetaClipRegionAction*) pAction; + + if( pA->IsClipping() ) + { + if( pA->GetRegion().IsEmpty() ) + m_rOuterFace.SetClipRegion( basegfx::B2DPolyPolygon() ); + else + { + Region aReg( pA->GetRegion() ); + m_rOuterFace.SetClipRegion( aReg.ConvertToB2DPolyPolygon() ); + } + } + else + m_rOuterFace.SetClipRegion(); + } + break; + + case( META_ISECTRECTCLIPREGION_ACTION ): + { + const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pAction; + m_rOuterFace.IntersectClipRegion( pA->GetRect() ); + } + break; + + case( META_ISECTREGIONCLIPREGION_ACTION ): + { + const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*) pAction; + Region aReg( pA->GetRegion() ); + m_rOuterFace.IntersectClipRegion( aReg.ConvertToB2DPolyPolygon() ); + } + break; + + case( META_MOVECLIPREGION_ACTION ): + { + const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pAction; + m_rOuterFace.MoveClipRegion( pA->GetHorzMove(), pA->GetVertMove() ); + } + break; + + case( META_MAPMODE_ACTION ): + { + const_cast< MetaAction* >( pAction )->Execute( pDummyVDev ); + m_rOuterFace.SetMapMode( pDummyVDev->GetMapMode() ); + } + break; + + case( META_LINECOLOR_ACTION ): + { + const MetaLineColorAction* pA = (const MetaLineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetLineColor( pA->GetColor() ); + else + m_rOuterFace.SetLineColor(); + } + break; + + case( META_FILLCOLOR_ACTION ): + { + const MetaFillColorAction* pA = (const MetaFillColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetFillColor( pA->GetColor() ); + else + m_rOuterFace.SetFillColor(); + } + break; + + case( META_TEXTLINECOLOR_ACTION ): + { + const MetaTextLineColorAction* pA = (const MetaTextLineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetTextLineColor( pA->GetColor() ); + else + m_rOuterFace.SetTextLineColor(); + } + break; + + case( META_OVERLINECOLOR_ACTION ): + { + const MetaOverlineColorAction* pA = (const MetaOverlineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetOverlineColor( pA->GetColor() ); + else + m_rOuterFace.SetOverlineColor(); + } + break; + + case( META_TEXTFILLCOLOR_ACTION ): + { + const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetTextFillColor( pA->GetColor() ); + else + m_rOuterFace.SetTextFillColor(); + } + break; + + case( META_TEXTCOLOR_ACTION ): + { + const MetaTextColorAction* pA = (const MetaTextColorAction*) pAction; + m_rOuterFace.SetTextColor( pA->GetColor() ); + } + break; + + case( META_TEXTALIGN_ACTION ): + { + const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pAction; + m_rOuterFace.SetTextAlign( pA->GetTextAlign() ); + } + break; + + case( META_FONT_ACTION ): + { + const MetaFontAction* pA = (const MetaFontAction*) pAction; + m_rOuterFace.SetFont( pA->GetFont() ); + } + break; + + case( META_PUSH_ACTION ): + { + const MetaPushAction* pA = (const MetaPushAction*) pAction; + + pDummyVDev->Push( pA->GetFlags() ); + m_rOuterFace.Push( pA->GetFlags() ); + } + break; + + case( META_POP_ACTION ): + { + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + } + break; + + case( META_LAYOUTMODE_ACTION ): + { + const MetaLayoutModeAction* pA = (const MetaLayoutModeAction*) pAction; + m_rOuterFace.SetLayoutMode( pA->GetLayoutMode() ); + } + break; + + case META_TEXTLANGUAGE_ACTION: + { + const MetaTextLanguageAction* pA = (const MetaTextLanguageAction*) pAction; + m_rOuterFace.SetDigitLanguage( pA->GetTextLanguage() ); + } + break; + + case( META_WALLPAPER_ACTION ): + { + const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pAction; + m_rOuterFace.DrawWallpaper( pA->GetRect(), pA->GetWallpaper() ); + } + break; + + case( META_RASTEROP_ACTION ): + { + // !!! >>> we don't want to support this actions + } + break; + + case( META_REFPOINT_ACTION ): + { + // !!! >>> we don't want to support this actions + } + break; + + default: + // #i24604# Made assertion fire only once per + // metafile. The asserted actions here are all + // deprecated + if( !bAssertionFired ) + { + bAssertionFired = true; + DBG_ERROR( "PDFExport::ImplWriteActions: deprecated and unsupported MetaAction encountered" ); + } + break; + } + i++; + } + } + + delete pPrivateDevice; +} + +// Encryption methods + +/* a crutch to transport an rtlDigest safely though UNO API + this is needed for the PDF export dialog, which otherwise would have to pass + clear text passwords down till they can be used in PDFWriter. Unfortunately + the MD5 sum of the password (which is needed to create the PDF encryption key) + is not sufficient, since an rtl MD5 digest cannot be created in an arbitrary state + which would be needed in PDFWriterImpl::computeEncryptionKey. +*/ +class EncHashTransporter : public cppu::WeakImplHelper1 < com::sun::star::beans::XMaterialHolder > +{ + rtlDigest maUDigest; + sal_IntPtr maID; + std::vector< sal_uInt8 > maOValue; + + static std::map< sal_IntPtr, EncHashTransporter* > sTransporters; +public: + EncHashTransporter() + : maUDigest( rtl_digest_createMD5() ) + { + maID = reinterpret_cast< sal_IntPtr >(this); + while( sTransporters.find( maID ) != sTransporters.end() ) // paranoia mode + maID++; + sTransporters[ maID ] = this; + } + + virtual ~EncHashTransporter() + { + sTransporters.erase( maID ); + if( maUDigest ) + rtl_digest_destroyMD5( maUDigest ); + OSL_TRACE( "EncHashTransporter freed\n" ); + } + + rtlDigest getUDigest() const { return maUDigest; }; + std::vector< sal_uInt8 >& getOValue() { return maOValue; } + void invalidate() + { + if( maUDigest ) + { + rtl_digest_destroyMD5( maUDigest ); + maUDigest = NULL; + } + } + + // XMaterialHolder + virtual uno::Any SAL_CALL getMaterial() throw() + { + return uno::makeAny( sal_Int64(maID) ); + } + + static EncHashTransporter* getEncHashTransporter( const uno::Reference< beans::XMaterialHolder >& ); + +}; + +std::map< sal_IntPtr, EncHashTransporter* > EncHashTransporter::sTransporters; + +EncHashTransporter* EncHashTransporter::getEncHashTransporter( const uno::Reference< beans::XMaterialHolder >& xRef ) +{ + EncHashTransporter* pResult = NULL; + if( xRef.is() ) + { + uno::Any aMat( xRef->getMaterial() ); + sal_Int64 nMat = 0; + if( aMat >>= nMat ) + { + std::map< sal_IntPtr, EncHashTransporter* >::iterator it = sTransporters.find( static_cast<sal_IntPtr>(nMat) ); + if( it != sTransporters.end() ) + pResult = it->second; + } + } + return pResult; +} + +sal_Bool PDFWriterImpl::checkEncryptionBufferSize( register sal_Int32 newSize ) +{ + if( m_nEncryptionBufferSize < newSize ) + { + /* reallocate the buffer, the used function allocate as rtl_allocateMemory + if the pointer parameter is NULL */ + m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize ); + if( m_pEncryptionBuffer ) + m_nEncryptionBufferSize = newSize; + else + m_nEncryptionBufferSize = 0; + } + return ( m_nEncryptionBufferSize != 0 ); +} + +void PDFWriterImpl::checkAndEnableStreamEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + m_bEncryptThisStream = true; + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +void PDFWriterImpl::enableStringEncryption( register sal_Int32 nObject ) +{ + if( m_aContext.Encryption.Encrypt() ) + { + sal_Int32 i = m_nKeyLength; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)nObject; + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 8 ); + m_aContext.Encryption.EncryptionKey[i++] = (sal_uInt8)( nObject >> 16 ); + //the other location of m_nEncryptionKey are already set to 0, our fixed generation number + // do the MD5 hash + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + // the i+2 to take into account the generation number, always zero + rtl_digest_MD5( &m_aContext.Encryption.EncryptionKey[0], i+2, nMD5Sum, sizeof(nMD5Sum) ); + // initialize the RC4 with the key + // key legth: see algoritm 3.1, step 4: (N+5) max 16 + rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 ); + } +} + +/* init the encryption engine +1. init the document id, used both for building the document id and for building the encryption key(s) +2. build the encryption key following algorithms described in the PDF specification + */ +uno::Reference< beans::XMaterialHolder > PDFWriterImpl::initEncryption( const rtl::OUString& i_rOwnerPassword, + const rtl::OUString& i_rUserPassword, + bool b128Bit + ) +{ + uno::Reference< beans::XMaterialHolder > xResult; + if( i_rOwnerPassword.getLength() || i_rUserPassword.getLength() ) + { + EncHashTransporter* pTransporter = new EncHashTransporter; + xResult = pTransporter; + + // get padded passwords + sal_uInt8 aPadUPW[ENCRYPTED_PWD_SIZE], aPadOPW[ENCRYPTED_PWD_SIZE]; + padPassword( i_rOwnerPassword.getLength() ? i_rOwnerPassword : i_rUserPassword, aPadOPW ); + padPassword( i_rUserPassword, aPadUPW ); + sal_Int32 nKeyLength = SECUR_40BIT_KEY; + if( b128Bit ) + nKeyLength = SECUR_128BIT_KEY; + + if( computeODictionaryValue( aPadOPW, aPadUPW, pTransporter->getOValue(), nKeyLength ) ) + { + rtlDigest aDig = pTransporter->getUDigest(); + if( rtl_digest_updateMD5( aDig, aPadUPW, ENCRYPTED_PWD_SIZE ) != rtl_Digest_E_None ) + xResult.clear(); + } + else + xResult.clear(); + + // trash temporary padded cleartext PWDs + rtl_zeroMemory( aPadOPW, sizeof(aPadOPW) ); + rtl_zeroMemory( aPadUPW, sizeof(aPadUPW) ); + + } + return xResult; +} + +bool PDFWriterImpl::prepareEncryption( const uno::Reference< beans::XMaterialHolder >& xEnc ) +{ + bool bSuccess = false; + EncHashTransporter* pTransporter = EncHashTransporter::getEncHashTransporter( xEnc ); + if( pTransporter ) + { + sal_Int32 nKeyLength = 0, nRC4KeyLength = 0; + sal_Int32 nAccessPermissions = computeAccessPermissions( m_aContext.Encryption, nKeyLength, nRC4KeyLength ); + m_aContext.Encryption.OValue = pTransporter->getOValue(); + bSuccess = computeUDictionaryValue( pTransporter, m_aContext.Encryption, nKeyLength, nAccessPermissions ); + } + if( ! bSuccess ) + { + m_aContext.Encryption.OValue.clear(); + m_aContext.Encryption.UValue.clear(); + m_aContext.Encryption.EncryptionKey.clear(); + } + return bSuccess; +} + +sal_Int32 PDFWriterImpl::computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, + sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ) +{ + /* + 2) compute the access permissions, in numerical form + + the default value depends on the revision 2 (40 bit) or 3 (128 bit security): + - for 40 bit security the unused bit must be set to 1, since they are not used + - for 128 bit security the same bit must be preset to 0 and set later if needed + according to the table 3.15, pdf v 1.4 */ + sal_Int32 nAccessPermissions = ( i_rProperties.Security128bit ) ? 0xfffff0c0 : 0xffffffc0 ; + + /* check permissions for 40 bit security case */ + nAccessPermissions |= ( i_rProperties.CanPrintTheDocument ) ? 1 << 2 : 0; + nAccessPermissions |= ( i_rProperties.CanModifyTheContent ) ? 1 << 3 : 0; + nAccessPermissions |= ( i_rProperties.CanCopyOrExtract ) ? 1 << 4 : 0; + nAccessPermissions |= ( i_rProperties.CanAddOrModify ) ? 1 << 5 : 0; + o_rKeyLength = SECUR_40BIT_KEY; + o_rRC4KeyLength = SECUR_40BIT_KEY+5; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 5 + + if( i_rProperties.Security128bit ) + { + o_rKeyLength = SECUR_128BIT_KEY; + o_rRC4KeyLength = 16; // for this value see PDF spec v 1.4, algorithm 3.1 step 4, where n is 16, thus maximum + // permitted value is 16 + nAccessPermissions |= ( i_rProperties.CanFillInteractive ) ? 1 << 8 : 0; + nAccessPermissions |= ( i_rProperties.CanExtractForAccessibility ) ? 1 << 9 : 0; + nAccessPermissions |= ( i_rProperties.CanAssemble ) ? 1 << 10 : 0; + nAccessPermissions |= ( i_rProperties.CanPrintFull ) ? 1 << 11 : 0; + } + return nAccessPermissions; +} + +/************************************************************* +begin i12626 methods + +Implements Algorithm 3.2, step 1 only +*/ +void PDFWriterImpl::padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ) +{ + // get ansi-1252 version of the password string CHECKIT ! i12626 + rtl::OString aString( rtl::OUStringToOString( i_rPassword, RTL_TEXTENCODING_MS_1252 ) ); + + //copy the string to the target + sal_Int32 nToCopy = ( aString.getLength() < ENCRYPTED_PWD_SIZE ) ? aString.getLength() : ENCRYPTED_PWD_SIZE; + sal_Int32 nCurrentChar; + + for( nCurrentChar = 0; nCurrentChar < nToCopy; nCurrentChar++ ) + o_pPaddedPW[nCurrentChar] = (sal_uInt8)( aString.getStr()[nCurrentChar] ); + + //pad it with standard byte string + sal_Int32 i,y; + for( i = nCurrentChar, y = 0 ; i < ENCRYPTED_PWD_SIZE; i++, y++ ) + o_pPaddedPW[i] = s_nPadString[y]; + + // trash memory of temporary clear text password + rtl_zeroMemory( (sal_Char*)aString.getStr(), aString.getLength() ); +} + +/********************************** +Algorithm 3.2 Compute the encryption key used + +step 1 should already be done before calling, the paThePaddedPassword parameter should contain +the padded password and must be 32 byte long, the encryption key is returned into the paEncryptionKey parameter, +it will be 16 byte long for 128 bit security; for 40 bit security only the first 5 bytes are used + +TODO: in pdf ver 1.5 and 1.6 the step 6 is different, should be implemented. See spec. + +*/ +bool PDFWriterImpl::computeEncryptionKey( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ) +{ + bool bSuccess = true; + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + + // transporter contains an MD5 digest with the padded user password already + rtlDigest aDigest = i_pTransporter->getUDigest(); + rtlDigestError nError = rtl_Digest_E_None; + if( aDigest ) + { + //step 3 + if( ! io_rProperties.OValue.empty() ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.OValue[0] , sal_Int32(io_rProperties.OValue.size()) ); + else + bSuccess = false; + //Step 4 + sal_uInt8 nPerm[4]; + + nPerm[0] = (sal_uInt8)i_nAccessPermissions; + nPerm[1] = (sal_uInt8)( i_nAccessPermissions >> 8 ); + nPerm[2] = (sal_uInt8)( i_nAccessPermissions >> 16 ); + nPerm[3] = (sal_uInt8)( i_nAccessPermissions >> 24 ); + + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, nPerm , sizeof( nPerm ) ); + + //step 5, get the document ID, binary form + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + //get the digest + if( nError == rtl_Digest_E_None ) + { + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + + //step 6, only if 128 bit + if( io_rProperties.Security128bit ) + { + for( sal_Int32 i = 0; i < 50; i++ ) + { + nError = rtl_digest_updateMD5( aDigest, &nMD5Sum, sizeof( nMD5Sum ) ); + if( nError != rtl_Digest_E_None ) + { + bSuccess = false; + break; + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + } + } + } + else + bSuccess = false; + + i_pTransporter->invalidate(); + + //Step 7 + if( bSuccess ) + { + io_rProperties.EncryptionKey.resize( MAXIMUM_RC4_KEY_LENGTH ); + for( sal_Int32 i = 0; i < MD5_DIGEST_SIZE; i++ ) + io_rProperties.EncryptionKey[i] = nMD5Sum[i]; + } + else + io_rProperties.EncryptionKey.clear(); + + return bSuccess; +} + +/********************************** +Algorithm 3.3 Compute the encryption dictionary /O value, save into the class data member +the step numbers down here correspond to the ones in PDF v.1.4 specfication +*/ +bool PDFWriterImpl::computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, + const sal_uInt8* i_pPaddedUserPassword, + std::vector< sal_uInt8 >& io_rOValue, + sal_Int32 i_nKeyLength + ) +{ + bool bSuccess = true; + + io_rOValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher) + { + //step 1 already done, data is in i_pPaddedOwnerPassword + //step 2 + + rtlDigestError nError = rtl_digest_updateMD5( aDigest, i_pPaddedOwnerPassword, ENCRYPTED_PWD_SIZE ); + if( nError == rtl_Digest_E_None ) + { + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); +//step 3, only if 128 bit + if( i_nKeyLength == SECUR_128BIT_KEY ) + { + sal_Int32 i; + for( i = 0; i < 50; i++ ) + { + nError = rtl_digest_updateMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + if( nError != rtl_Digest_E_None ) + { + bSuccess = false; + break; + } + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof( nMD5Sum ) ); + } + } + //Step 4, the key is in nMD5Sum + //step 5 already done, data is in i_pPaddedUserPassword + //step 6 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nMD5Sum, i_nKeyLength , NULL, 0 ); + // encrypt the user password using the key set above + rtl_cipher_encodeARCFOUR( aCipher, i_pPaddedUserPassword, ENCRYPTED_PWD_SIZE, // the data to be encrypted + &io_rOValue[0], sal_Int32(io_rOValue.size()) ); //encrypted data + //Step 7, only if 128 bit + if( i_nKeyLength == SECUR_128BIT_KEY ) + { + sal_uInt32 i, y; + sal_uInt8 nLocalKey[ SECUR_128BIT_KEY ]; // 16 = 128 bit key + + for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + { + for( y = 0; y < sizeof( nLocalKey ); y++ ) + nLocalKey[y] = (sal_uInt8)( nMD5Sum[y] ^ i ); + + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nLocalKey, SECUR_128BIT_KEY, NULL, 0 ); //destination data area, on init can be NULL + rtl_cipher_encodeARCFOUR( aCipher, &io_rOValue[0], sal_Int32(io_rOValue.size()), // the data to be encrypted + &io_rOValue[0], sal_Int32(io_rOValue.size()) ); // encrypted data, can be the same as the input, encrypt "in place" + //step 8, store in class data member + } + } + } + else + bSuccess = false; + } + else + bSuccess = false; + + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); + + if( ! bSuccess ) + io_rOValue.clear(); + return bSuccess; +} + +/********************************** +Algorithms 3.4 and 3.5 Compute the encryption dictionary /U value, save into the class data member, revision 2 (40 bit) or 3 (128 bit) +*/ +bool PDFWriterImpl::computeUDictionaryValue( EncHashTransporter* i_pTransporter, + vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, + sal_Int32 i_nKeyLength, + sal_Int32 i_nAccessPermissions + ) +{ + bool bSuccess = true; + + io_rProperties.UValue.resize( ENCRYPTED_PWD_SIZE ); + + rtlDigest aDigest = rtl_digest_createMD5(); + rtlCipher aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); + if( aDigest && aCipher ) + { + //step 1, common to both 3.4 and 3.5 + if( computeEncryptionKey( i_pTransporter, io_rProperties, i_nAccessPermissions ) ) + { + // prepare encryption key for object + for( sal_Int32 i = i_nKeyLength, y = 0; y < 5 ; y++ ) + io_rProperties.EncryptionKey[i++] = 0; + + if( io_rProperties.Security128bit == false ) + { + //3.4 + //step 2 and 3 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], 5 , // key and key length + NULL, 0 ); //destination data area + // encrypt the user password using the key set above, save for later use + rtl_cipher_encodeARCFOUR( aCipher, s_nPadString, sizeof( s_nPadString ), // the data to be encrypted + &io_rProperties.UValue[0], sal_Int32(io_rProperties.UValue.size()) ); //encrypted data, stored in class data member + } + else + { + //or 3.5, for 128 bit security + //step6, initilize the last 16 bytes of the encrypted user password to 0 + for(sal_uInt32 i = MD5_DIGEST_SIZE; i < sal_uInt32(io_rProperties.UValue.size()); i++) + io_rProperties.UValue[i] = 0; + //step 2 + rtlDigestError nError = rtl_digest_updateMD5( aDigest, s_nPadString, sizeof( s_nPadString ) ); + //step 3 + if( nError == rtl_Digest_E_None ) + nError = rtl_digest_updateMD5( aDigest, &io_rProperties.DocumentIdentifier[0], sal_Int32(io_rProperties.DocumentIdentifier.size()) ); + else + bSuccess = false; + + sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ]; + rtl_digest_getMD5( aDigest, nMD5Sum, sizeof(nMD5Sum) ); + //Step 4 + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + &io_rProperties.EncryptionKey[0], SECUR_128BIT_KEY, NULL, 0 ); //destination data area + rtl_cipher_encodeARCFOUR( aCipher, nMD5Sum, sizeof( nMD5Sum ), // the data to be encrypted + &io_rProperties.UValue[0], sizeof( nMD5Sum ) ); //encrypted data, stored in class data member + //step 5 + sal_uInt32 i, y; + sal_uInt8 nLocalKey[SECUR_128BIT_KEY]; + + for( i = 1; i <= 19; i++ ) // do it 19 times, start with 1 + { + for( y = 0; y < sizeof( nLocalKey ) ; y++ ) + nLocalKey[y] = (sal_uInt8)( io_rProperties.EncryptionKey[y] ^ i ); + + rtl_cipher_initARCFOUR( aCipher, rtl_Cipher_DirectionEncode, + nLocalKey, SECUR_128BIT_KEY, // key and key length + NULL, 0 ); //destination data area, on init can be NULL + rtl_cipher_encodeARCFOUR( aCipher, &io_rProperties.UValue[0], SECUR_128BIT_KEY, // the data to be encrypted + &io_rProperties.UValue[0], SECUR_128BIT_KEY ); // encrypted data, can be the same as the input, encrypt "in place" + } + } + } + else + bSuccess = false; + } + else + bSuccess = false; + + if( aDigest ) + rtl_digest_destroyMD5( aDigest ); + if( aCipher ) + rtl_cipher_destroyARCFOUR( aCipher ); + + if( ! bSuccess ) + io_rProperties.UValue.clear(); + return bSuccess; +} + +/* end i12626 methods */ + diff --git a/vcl/source/gdi/pngread.cxx b/vcl/source/gdi/pngread.cxx index 11971db34378..df67c4974d47 100644 --- a/vcl/source/gdi/pngread.cxx +++ b/vcl/source/gdi/pngread.cxx @@ -411,7 +411,9 @@ BitmapEx PNGReaderImpl::GetBitmapEx( const Size& rPreviewSizeHint ) case PNGCHUNK_IDAT : { - if ( !mbIDAT ) // the gfx is finished, but there may be left a zlibCRC of about 4Bytes + if ( !mpInflateInBuf ) // taking care that the header has properly been read + mbStatus = FALSE; + else if ( !mbIDAT ) // the gfx is finished, but there may be left a zlibCRC of about 4Bytes ImplReadIDAT(); } break; @@ -527,7 +529,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) mbIDAT = mbAlphaChannel = mbTransparent = FALSE; mbGrayScale = mbRGBTriple = FALSE; mnTargetDepth = mnPngDepth; - mnScansize = ( ( maOrigSize.Width() * mnPngDepth ) + 7 ) >> 3; + sal_uInt64 nScansize64 = ( ( static_cast< sal_uInt64 >( maOrigSize.Width() ) * mnPngDepth ) + 7 ) >> 3; // valid color types are 0,2,3,4 & 6 switch ( mnColorType ) @@ -557,7 +559,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 2 : // each pixel is an RGB triple { mbRGBTriple = TRUE; - mnScansize *= 3; + nScansize64 *= 3; switch ( mnPngDepth ) { case 16 : // we have to reduce the bitmap @@ -590,7 +592,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 4 : // each pixel is a grayscale sample followed by an alpha sample { - mnScansize *= 2; + nScansize64 *= 2; mbAlphaChannel = TRUE; switch ( mnPngDepth ) { @@ -608,7 +610,7 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) case 6 : // each pixel is an RGB triple followed by an alpha sample { mbRGBTriple = TRUE; - mnScansize *= 4; + nScansize64 *= 4; mbAlphaChannel = TRUE; switch (mnPngDepth ) { @@ -626,16 +628,24 @@ BOOL PNGReaderImpl::ImplReadHeader( const Size& rPreviewSizeHint ) return FALSE; } - mnBPP = mnScansize / maOrigSize.Width(); + mnBPP = static_cast< sal_uInt32 >( nScansize64 / maOrigSize.Width() ); if ( !mnBPP ) mnBPP = 1; - mnScansize++; // each scanline includes one filterbyte + nScansize64++; // each scanline includes one filterbyte + + if ( nScansize64 > SAL_MAX_UINT32 ) + return FALSE; + + mnScansize = static_cast< sal_uInt32 >( nScansize64 ); // TODO: switch between both scanlines instead of copying - mpInflateInBuf = new BYTE[ mnScansize ]; + mpInflateInBuf = new (std::nothrow) BYTE[ mnScansize ]; mpScanCurrent = mpInflateInBuf; - mpScanPrior = new BYTE[ mnScansize ]; + mpScanPrior = new (std::nothrow) BYTE[ mnScansize ]; + + if ( !mpInflateInBuf || !mpScanPrior ) + return FALSE; // calculate target size from original size and the preview hint if( rPreviewSizeHint.Width() || rPreviewSizeHint.Height() ) diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 2ea9bfcc4c11..78456992340f 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -57,8 +57,14 @@ #include <comphelper/processfactory.hxx> +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/container/XNameAccess.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" + using namespace com::sun::star::uno; using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; int nImplSysDialog = 0; @@ -130,6 +136,105 @@ PrinterOptions::~PrinterOptions() { } +#define PROPERTYNAME_REDUCETRANSPARENCY rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceTransparency")) +#define PROPERTYNAME_REDUCEDTRANSPARENCYMODE rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedTransparencyMode")) +#define PROPERTYNAME_REDUCEGRADIENTS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceGradients")) +#define PROPERTYNAME_REDUCEDGRADIENTMODE rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientMode")) +#define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedGradientStepCount")) +#define PROPERTYNAME_REDUCEBITMAPS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReduceBitmaps")) +#define PROPERTYNAME_REDUCEDBITMAPMODE rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapMode")) +#define PROPERTYNAME_REDUCEDBITMAPRESOLUTION rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapResolution")) +#define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedBitmapIncludesTransparency")) +#define PROPERTYNAME_CONVERTTOGREYSCALES rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ConvertToGreyscales")) + +bool PrinterOptions::ReadFromConfig( bool i_bFile ) +{ + bool bSuccess = false; + // save old state in case something goes wrong + PrinterOptions aOldValues( *this ); + + // get the configuration service + Reference< XMultiServiceFactory > xConfigProvider; + Reference< XNameAccess > xConfigAccess; + try + { + // get service provider + Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); + // create configuration hierachical access name + if( xSMgr.is() ) + { + try + { + xConfigProvider = Reference< XMultiServiceFactory >( + xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.configuration.ConfigurationProvider" ))), + UNO_QUERY ); + if( xConfigProvider.is() ) + { + Sequence< Any > aArgs(1); + PropertyValue aVal; + aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); + if( i_bFile ) + aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Print/Option/File" ) ); + else + aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Print/Option/Printer" ) ); + aArgs.getArray()[0] <<= aVal; + xConfigAccess = Reference< XNameAccess >( + xConfigProvider->createInstanceWithArguments( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )), aArgs ), + UNO_QUERY ); + if( xConfigAccess.is() ) + { + Reference< XPropertySet > xSet( xConfigAccess, UNO_QUERY ); + if( xSet.is() ) + { + sal_Int32 nValue = 0; + sal_Bool bValue = 0; + if( xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bValue ) + SetReduceTransparency( bValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nValue ) + SetReducedTransparencyMode( (PrinterTransparencyMode)nValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bValue ) + SetReduceGradients( bValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nValue ) + SetReducedGradientMode( (PrinterGradientMode)nValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nValue ) + SetReducedGradientStepCount( (USHORT)nValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bValue ) + SetReduceBitmaps( bValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nValue ) + SetReducedBitmapMode( (PrinterBitmapMode)nValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nValue ) + SetReducedBitmapResolution( (USHORT)nValue ); + if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bValue ) + SetReducedBitmapIncludesTransparency( bValue ); + if( xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bValue ) + SetConvertToGreyscales( bValue ); + + bSuccess = true; + } + } + } + } + catch( Exception& ) + { + } + } + } + catch( WrappedTargetException& ) + { + } + + if( ! bSuccess ) + *this = aOldValues; + return bSuccess; +} + +void Printer::SetPrinterOptions( const PrinterOptions& i_rOptions ) +{ + *mpPrinterOptions = i_rOptions; +} + // ------------- // - QueueInfo - // ------------- diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx index d560b0b6e7cc..5c2a742a10ba 100644 --- a/vcl/source/gdi/print2.cxx +++ b/vcl/source/gdi/print2.cxx @@ -404,9 +404,21 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic break; case META_LINE_ACTION: - aActionBounds = Rectangle( static_cast<const MetaLineAction&>(rAct).GetStartPoint(), - static_cast<const MetaLineAction&>(rAct).GetEndPoint() ); + { + const MetaLineAction& rMetaLineAction = static_cast<const MetaLineAction&>(rAct); + aActionBounds = Rectangle( rMetaLineAction.GetStartPoint(), rMetaLineAction.GetEndPoint() ); + aActionBounds.Justify(); + const long nLineWidth(rMetaLineAction.GetLineInfo().GetWidth()); + if(nLineWidth) + { + const long nHalfLineWidth((nLineWidth + 1) / 2); + aActionBounds.Left() -= nHalfLineWidth; + aActionBounds.Top() -= nHalfLineWidth; + aActionBounds.Right() += nHalfLineWidth; + aActionBounds.Bottom() += nHalfLineWidth; + } break; + } case META_RECT_ACTION: aActionBounds = static_cast<const MetaRectAction&>(rAct).GetRect(); @@ -446,8 +458,20 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic break; case META_POLYLINE_ACTION: - aActionBounds = static_cast<const MetaPolyLineAction&>(rAct).GetPolygon().GetBoundRect(); + { + const MetaPolyLineAction& rMetaPolyLineAction = static_cast<const MetaPolyLineAction&>(rAct); + aActionBounds = rMetaPolyLineAction.GetPolygon().GetBoundRect(); + const long nLineWidth(rMetaPolyLineAction.GetLineInfo().GetWidth()); + if(nLineWidth) + { + const long nHalfLineWidth((nLineWidth + 1) / 2); + aActionBounds.Left() -= nHalfLineWidth; + aActionBounds.Top() -= nHalfLineWidth; + aActionBounds.Right() += nHalfLineWidth; + aActionBounds.Bottom() += nHalfLineWidth; + } break; + } case META_POLYGON_ACTION: aActionBounds = static_cast<const MetaPolygonAction&>(rAct).GetPolygon().GetBoundRect(); diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index 191f8f26dc75..8207282add99 100644..100755 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -150,6 +150,7 @@ public: typedef std::hash_map< rtl::OUString, size_t, rtl::OUStringHash > PropertyToIndexMap; typedef std::hash_map< rtl::OUString, ControlDependency, rtl::OUStringHash > ControlDependencyMap; + typedef std::hash_map< rtl::OUString, Sequence< sal_Bool >, rtl::OUStringHash > ChoiceDisableMap; boost::shared_ptr<Printer> mpPrinter; Sequence< PropertyValue > maUIOptions; @@ -158,6 +159,7 @@ public: PropertyToIndexMap maPropertyToIndex; Link maOptionChangeHdl; ControlDependencyMap maControlDependencies; + ChoiceDisableMap maChoiceDisableMap; sal_Bool mbFirstPage; sal_Bool mbLastPage; sal_Bool mbReversePageOrder; @@ -173,6 +175,7 @@ public: // if set, pages are centered and trimmed onto the fixed page Size maFixedPageSize; sal_Int32 mnDefaultPaperBin; + sal_Int32 mnFixedPaperBin; ImplPrinterControllerData() : mbFirstPage( sal_True ), @@ -180,21 +183,22 @@ public: mbReversePageOrder( sal_False ), meJobState( view::PrintableState_JOB_STARTED ), mpProgress( NULL ), - mnDefaultPaperBin( -1 ) + mnDefaultPaperBin( -1 ), + mnFixedPaperBin( -1 ) {} ~ImplPrinterControllerData() { delete mpProgress; } - Size getRealPaperSize( const Size& i_rPageSize ) const + Size getRealPaperSize( const Size& i_rPageSize, bool bNoNUP ) const { if( maFixedPageSize.Width() > 0 && maFixedPageSize.Height() > 0 ) return maFixedPageSize; - if( maMultiPage.nRows * maMultiPage.nColumns > 1 ) + if( maMultiPage.nRows * maMultiPage.nColumns > 1 && ! bNoNUP ) return maMultiPage.aPaperSize; return i_rPageSize; } bool isFixedPageSize() const { return maFixedPageSize.Width() != 0 && maFixedPageSize.Height() != 0; } - PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps ); + PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP ); }; PrinterController::PrinterController() @@ -444,8 +448,7 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr if( ! aDlg.Execute() ) { GDIMetaFile aPageFile; - i_pController->setLastPage( sal_True ); - i_pController->getFilteredPageFile( 0, aPageFile ); + i_pController->abortJob(); return; } if( aDlg.isPrintToFile() ) @@ -453,9 +456,7 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr rtl::OUString aFile = queryFile( pController->getPrinter().get() ); if( ! aFile.getLength() ) { - GDIMetaFile aPageFile; - i_pController->setLastPage( sal_True ); - i_pController->getFilteredPageFile( 0, aPageFile ); + i_pController->abortJob(); return; } pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ), @@ -532,10 +533,6 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: pSingleValue->Value >>= bSinglePrintJobs; } - // remark: currently it is still possible to use EnablePrintFile and - // SetPrintFileName to redirect printout into file - // it can be argued that those methods should be removed in favor - // of only using the LocalFileName property beans::PropertyValue* pFileValue = i_pController->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ) ); if( pFileValue ) { @@ -552,12 +549,13 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: XubString* pPrintFile = NULL; if ( mbPrintFile ) pPrintFile = &maPrintFile; + mpPrinterOptions->ReadFromConfig( mbPrintFile ); maJobName = i_rJobName; mnCurPage = 1; mnCurPrintPage = 1; mbPrinting = TRUE; - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) + if( GetCapabilities( PRINTER_CAPABILITIES_USEPULLMODEL ) ) { mbJobActive = TRUE; // sallayer does all necessary page printing @@ -594,17 +592,25 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: i_pController->jobStarted(); int nJobs = 1; - int nRepeatCount = bUserCopy ? mnCopyCount : 1; + int nOuterRepeatCount = 1; + int nInnerRepeatCount = 1; + if( bUserCopy ) + { + if( mbCollateCopy ) + nOuterRepeatCount = mnCopyCount; + else + nInnerRepeatCount = mnCopyCount; + } if( bSinglePrintJobs ) { nJobs = mnCopyCount; nCopies = 1; - nRepeatCount = 1; + nOuterRepeatCount = nInnerRepeatCount = 1; } for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ ) { - bool bError = false; + bool bError = false, bAborted = false; if( mpPrinter->StartJob( pPrintFile, i_rJobName, Application::GetDisplayName(), @@ -616,13 +622,26 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: mbJobActive = TRUE; i_pController->createProgressDialog(); int nPages = i_pController->getFilteredPageCount(); - for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) + for( int nOuterIteration = 0; nOuterIteration < nOuterRepeatCount && ! bAborted; nOuterIteration++ ) { - for( int nPage = 0; nPage < nPages; nPage++ ) + for( int nPage = 0; nPage < nPages && ! bAborted; nPage++ ) { - if( nPage == nPages-1 && nIteration == nRepeatCount-1 && nJobIteration == nJobs-1 ) - i_pController->setLastPage( sal_True ); - i_pController->printFilteredPage( nPage ); + for( int nInnerIteration = 0; nInnerIteration < nInnerRepeatCount && ! bAborted; nInnerIteration++ ) + { + if( nPage == nPages-1 && + nOuterIteration == nOuterRepeatCount-1 && + nInnerIteration == nInnerRepeatCount-1 && + nJobIteration == nJobs-1 ) + { + i_pController->setLastPage( sal_True ); + } + i_pController->printFilteredPage( nPage ); + if( i_pController->isProgressCanceled() ) + { + i_pController->abortJob(); + bAborted = true; + } + } } // FIXME: duplex ? } @@ -708,6 +727,14 @@ void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ), makeAny( rtl::OUString( i_rPrinter->GetName() ) ) ); mpImplData->mnDefaultPaperBin = mpImplData->mpPrinter->GetPaperBin(); + mpImplData->mnFixedPaperBin = -1; +} + +void PrinterController:: resetPrinterOptions( bool i_bFileOutput ) +{ + PrinterOptions aOpt; + aOpt.ReadFromConfig( i_bFileOutput ); + mpImplData->mpPrinter->SetPrinterOptions( aOpt ); } bool PrinterController::setupPrinter( Window* i_pParent ) @@ -715,15 +742,20 @@ bool PrinterController::setupPrinter( Window* i_pParent ) bool bRet = false; if( mpImplData->mpPrinter.get() ) { + // get old data Size aPaperSize( mpImplData->mpPrinter->PixelToLogic( mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); + USHORT nPaperBin = mpImplData->mpPrinter->GetPaperBin(); + + // call driver setup bRet = mpImplData->mpPrinter->Setup( i_pParent ); if( bRet ) { - // was the papersize overridden ? if so we need to take action + // was papersize or bin overridden ? if so we need to take action Size aNewPaperSize( mpImplData->mpPrinter->PixelToLogic( mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); - if( aNewPaperSize != aPaperSize ) + USHORT nNewPaperBin = mpImplData->mpPrinter->GetPaperBin(); + if( aNewPaperSize != aPaperSize || nNewPaperBin != nPaperBin ) { mpImplData->maFixedPageSize = aNewPaperSize; mpImplData->maPageCache.invalidate(); @@ -732,13 +764,14 @@ bool PrinterController::setupPrinter( Window* i_pParent ) aOverrideSize.Height = aNewPaperSize.Height(); setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OverridePageSize" ) ), makeAny( aOverrideSize ) ); + mpImplData->mnFixedPaperBin = nNewPaperBin; } } } return bRet; } -PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps ) +PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP ) { PrinterController::PageSize aPageSize; aPageSize.aSize = mpPrinter->GetPaperSize(); @@ -773,7 +806,7 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons if( aSetSize.Width && aSetSize.Height ) { Size aSetPaperSize( aSetSize.Width, aSetSize.Height ); - Size aRealPaperSize( getRealPaperSize( aSetPaperSize ) ); + Size aRealPaperSize( getRealPaperSize( aSetPaperSize, bNoNUP ) ); if( aRealPaperSize != aCurSize ) aIsSize = aSetSize; } @@ -783,7 +816,7 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons aPageSize.aSize.Width() = aIsSize.Width; aPageSize.aSize.Height() = aIsSize.Height; - Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); + Size aRealPaperSize( getRealPaperSize( aPageSize.aSize, bNoNUP ) ); if( aRealPaperSize != aCurSize ) mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); } @@ -849,7 +882,7 @@ PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPag mpImplData->mpPrinter->SetMapMode( aMapMode ); // modify job setup if necessary - PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm ); + PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm, true ); o_rMtf.SetPrefSize( aPageSize.aSize ); o_rMtf.SetPrefMapMode( aMapMode ); @@ -931,7 +964,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 ) { PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache ); - Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize ); + Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true ); mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() ); if( aPaperSize != aPageSize.aSize ) @@ -940,7 +973,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte o_rMtf.WindStart(); long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2; long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2; - o_rMtf.Move( nDX, nDY ); + o_rMtf.Move( nDX, nDY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); o_rMtf.WindStart(); o_rMtf.SetPrefSize( aPaperSize ); aPageSize.aSize = aPaperSize; @@ -953,7 +986,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte sal_Bool bIsLastPage = mpImplData->mbLastPage; mpImplData->mbLastPage = sal_False; - Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize ) ); + Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize, false ) ); // multi page area: page size minus margins + one time spacing right and down // the added spacing is so each subpage can be calculated including its spacing @@ -1002,6 +1035,14 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte nCellX = (nSubPage / rMPS.nRows); nCellY = (nSubPage % rMPS.nRows); break; + case PrinterController::RLTB: + nCellX = rMPS.nColumns - 1 - (nSubPage % rMPS.nColumns); + nCellY = (nSubPage / rMPS.nColumns); + break; + case PrinterController::TBRL: + nCellX = rMPS.nColumns - 1 - (nSubPage / rMPS.nRows); + nCellY = (nSubPage % rMPS.nRows); + break; } // scale the metafile down to a sub page size double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width()); @@ -1015,7 +1056,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte long nOffY = (aSubPageSize.Height() - long(double(aPageSize.aSize.Height()) * fScale)) / 2; long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX; long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY; - aPageFile.Move( nX, nY ); + aPageFile.Move( nX, nY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); aPageFile.WindStart(); // calculate border rectangle Rectangle aSubPageRect( Point( nX, nY ), @@ -1129,13 +1170,18 @@ void PrinterController::printFilteredPage( int i_nPage ) mpImplData->mpPrinter->SetMapMode( MAP_100TH_MM ); // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile() mpImplData->mpPrinter->SetPaperSizeUser( aPageSize.aSize, ! mpImplData->isFixedPageSize() ); + if( mpImplData->mnFixedPaperBin != -1 && + mpImplData->mpPrinter->GetPaperBin() != mpImplData->mnFixedPaperBin ) + { + mpImplData->mpPrinter->SetPaperBin( mpImplData->mnFixedPaperBin ); + } - // if full paper are is meant, move the output to accomodate for pageoffset + // if full paper is meant to be used, move the output to accomodate for pageoffset if( aPageSize.bFullPaper ) { Point aPageOffset( mpImplData->mpPrinter->GetPageOffset() ); aPageFile.WindStart(); - aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y() ); + aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y(), mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); } GDIMetaFile aCleanedFile; @@ -1167,6 +1213,13 @@ void PrinterController::jobFinished( view::PrintableState ) void PrinterController::abortJob() { setJobState( view::PrintableState_JOB_ABORTED ); + // applications (well, sw) depend on a page request with "IsLastPage" = true + // to free resources, else they (well, sw) will crash eventually + setLastPage( sal_True ); + delete mpImplData->mpProgress; + mpImplData->mpProgress = NULL; + GDIMetaFile aMtf; + getPageFile( 0, aMtf, false ); } void PrinterController::setLastPage( sal_Bool i_bLastPage ) @@ -1299,6 +1352,7 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ bool bHaveProperty = false; rtl::OUString aPropName; vcl::ImplPrinterControllerData::ControlDependency aDep; + Sequence< sal_Bool > aChoicesDisabled; for( int n = 0; n < aOptProp.getLength(); n++ ) { const beans::PropertyValue& rEntry( aOptProp[ n ] ); @@ -1326,6 +1380,10 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ { rEntry.Value >>= aDep.mnDependsOnEntry; } + else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) + { + rEntry.Value >>= aChoicesDisabled; + } } if( bHaveProperty ) { @@ -1338,6 +1396,8 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ } if( aDep.maDependsOnName.getLength() > 0 ) mpImplData->maControlDependencies[ aPropName ] = aDep; + if( aChoicesDisabled.getLength() > 0 ) + mpImplData->maChoiceDisableMap[ aPropName ] = aChoicesDisabled; } } } @@ -1413,6 +1473,20 @@ bool PrinterController::isUIOptionEnabled( const rtl::OUString& i_rProperty ) co return bEnabled; } +bool PrinterController::isUIChoiceEnabled( const rtl::OUString& i_rProperty, sal_Int32 i_nValue ) const +{ + bool bEnabled = true; + ImplPrinterControllerData::ChoiceDisableMap::const_iterator it = + mpImplData->maChoiceDisableMap.find( i_rProperty ); + if(it != mpImplData->maChoiceDisableMap.end() ) + { + const Sequence< sal_Bool >& rDisabled( it->second ); + if( i_nValue >= 0 && i_nValue < rDisabled.getLength() ) + bEnabled = ! rDisabled[i_nValue]; + } + return bEnabled; +} + rtl::OUString PrinterController::getDependency( const rtl::OUString& i_rProperty ) const { rtl::OUString aDependency; @@ -1499,6 +1573,11 @@ void PrinterController::createProgressDialog() mpImplData->mpProgress->reset(); } +bool PrinterController::isProgressCanceled() const +{ + return mpImplData->mpProgress && mpImplData->mpProgress->isCanceled(); +} + void PrinterController::setMultipage( const MultiPageSetup& i_rMPS ) { mpImplData->maMultiPage = i_rMPS; @@ -1654,7 +1733,7 @@ void PrinterOptionsHelper::appendPrintUIOptions( uno::Sequence< beans::PropertyV } Any PrinterOptionsHelper::getUIControlOpt( const rtl::OUString& i_rTitle, - const Sequence< rtl::OUString >& i_rHelpTexts, + const Sequence< rtl::OUString >& i_rHelpIds, const rtl::OUString& i_rType, const PropertyValue* i_pVal, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions @@ -1663,7 +1742,7 @@ Any PrinterOptionsHelper::getUIControlOpt( const rtl::OUString& i_rTitle, sal_Int32 nElements = 1 // ControlType + (i_rTitle.getLength() ? 1 : 0) // Text - + (i_rHelpTexts.getLength() ? 1 : 0) // HelpText + + (i_rHelpIds.getLength() ? 1 : 0) // HelpId + (i_pVal ? 1 : 0) // Property + i_rControlOptions.maAddProps.getLength() // additional props + (i_rControlOptions.maGroupHint.getLength() ? 1 : 0) // grouping @@ -1686,10 +1765,10 @@ Any PrinterOptionsHelper::getUIControlOpt( const rtl::OUString& i_rTitle, aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" ) ); aCtrl[nUsed++].Value = makeAny( i_rTitle ); } - if( i_rHelpTexts.getLength() ) + if( i_rHelpIds.getLength() ) { - aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) ); - aCtrl[nUsed++].Value = makeAny( i_rHelpTexts ); + aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpId" ) ); + aCtrl[nUsed++].Value = makeAny( i_rHelpIds ); } aCtrl[nUsed ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlType" ) ); aCtrl[nUsed++].Value = makeAny( i_rType ); @@ -1738,74 +1817,80 @@ Any PrinterOptionsHelper::getUIControlOpt( const rtl::OUString& i_rTitle, return makeAny( aCtrl ); } -Any PrinterOptionsHelper::getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpText ) +Any PrinterOptionsHelper::getGroupControlOpt( const rtl::OUString& i_rTitle, const rtl::OUString& i_rHelpId ) { - Sequence< rtl::OUString > aHelpText; - if( i_rHelpText.getLength() > 0 ) + Sequence< rtl::OUString > aHelpId; + if( i_rHelpId.getLength() > 0 ) { - aHelpText.realloc( 1 ); - *aHelpText.getArray() = i_rHelpText; + aHelpId.realloc( 1 ); + *aHelpId.getArray() = i_rHelpId; } - return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) ); + return getUIControlOpt( i_rTitle, aHelpId, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Group" ) ) ); } Any PrinterOptionsHelper::getSubgroupControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions ) { - Sequence< rtl::OUString > aHelpText; - if( i_rHelpText.getLength() > 0 ) + Sequence< rtl::OUString > aHelpId; + if( i_rHelpId.getLength() > 0 ) { - aHelpText.realloc( 1 ); - *aHelpText.getArray() = i_rHelpText; + aHelpId.realloc( 1 ); + *aHelpId.getArray() = i_rHelpId; } - return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Subgroup" ) ), + return getUIControlOpt( i_rTitle, aHelpId, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Subgroup" ) ), NULL, i_rControlOptions ); } Any PrinterOptionsHelper::getBoolControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, sal_Bool i_bValue, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions ) { - Sequence< rtl::OUString > aHelpText; - if( i_rHelpText.getLength() > 0 ) + Sequence< rtl::OUString > aHelpId; + if( i_rHelpId.getLength() > 0 ) { - aHelpText.realloc( 1 ); - *aHelpText.getArray() = i_rHelpText; + aHelpId.realloc( 1 ); + *aHelpId.getArray() = i_rHelpId; } PropertyValue aVal; aVal.Name = i_rProperty; aVal.Value = makeAny( i_bValue ); - return getUIControlOpt( i_rTitle, aHelpText, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bool" ) ), &aVal, i_rControlOptions ); + return getUIControlOpt( i_rTitle, aHelpId, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Bool" ) ), &aVal, i_rControlOptions ); } Any PrinterOptionsHelper::getChoiceControlOpt( const rtl::OUString& i_rTitle, - const Sequence< rtl::OUString >& i_rHelpText, + const Sequence< rtl::OUString >& i_rHelpId, const rtl::OUString& i_rProperty, const Sequence< rtl::OUString >& i_rChoices, sal_Int32 i_nValue, const rtl::OUString& i_rType, + const Sequence< sal_Bool >& i_rDisabledChoices, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions ) { UIControlOptions aOpt( i_rControlOptions ); sal_Int32 nUsed = aOpt.maAddProps.getLength(); - aOpt.maAddProps.realloc( nUsed + 1 ); + aOpt.maAddProps.realloc( nUsed + 1 + (i_rDisabledChoices.getLength() ? 1 : 0) ); aOpt.maAddProps[nUsed].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Choices" ) ); aOpt.maAddProps[nUsed].Value = makeAny( i_rChoices ); + if( i_rDisabledChoices.getLength() ) + { + aOpt.maAddProps[nUsed+1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChoicesDisabled" ) ); + aOpt.maAddProps[nUsed+1].Value = makeAny( i_rDisabledChoices ); + } PropertyValue aVal; aVal.Name = i_rProperty; aVal.Value = makeAny( i_nValue ); - return getUIControlOpt( i_rTitle, i_rHelpText, i_rType, &aVal, aOpt ); + return getUIControlOpt( i_rTitle, i_rHelpId, i_rType, &aVal, aOpt ); } Any PrinterOptionsHelper::getRangeControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, sal_Int32 i_nValue, sal_Int32 i_nMinValue, @@ -1824,17 +1909,17 @@ Any PrinterOptionsHelper::getRangeControlOpt( const rtl::OUString& i_rTitle, aOpt.maAddProps[nUsed++].Value = makeAny( i_nMaxValue ); } - Sequence< rtl::OUString > aHelpText; - if( i_rHelpText.getLength() > 0 ) + Sequence< rtl::OUString > aHelpId; + if( i_rHelpId.getLength() > 0 ) { - aHelpText.realloc( 1 ); - *aHelpText.getArray() = i_rHelpText; + aHelpId.realloc( 1 ); + *aHelpId.getArray() = i_rHelpId; } PropertyValue aVal; aVal.Name = i_rProperty; aVal.Value = makeAny( i_nValue ); return getUIControlOpt( i_rTitle, - aHelpText, + aHelpId, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Range" ) ), &aVal, aOpt @@ -1842,23 +1927,23 @@ Any PrinterOptionsHelper::getRangeControlOpt( const rtl::OUString& i_rTitle, } Any PrinterOptionsHelper::getEditControlOpt( const rtl::OUString& i_rTitle, - const rtl::OUString& i_rHelpText, + const rtl::OUString& i_rHelpId, const rtl::OUString& i_rProperty, const rtl::OUString& i_rValue, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions ) { - Sequence< rtl::OUString > aHelpText; - if( i_rHelpText.getLength() > 0 ) + Sequence< rtl::OUString > aHelpId; + if( i_rHelpId.getLength() > 0 ) { - aHelpText.realloc( 1 ); - *aHelpText.getArray() = i_rHelpText; + aHelpId.realloc( 1 ); + *aHelpId.getArray() = i_rHelpId; } PropertyValue aVal; aVal.Name = i_rProperty; aVal.Value = makeAny( i_rValue ); return getUIControlOpt( i_rTitle, - aHelpText, + aHelpId, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Edit" ) ), &aVal, i_rControlOptions diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 84e45979d679..97e11c5a6aa4 100644..100755 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -405,6 +405,7 @@ void SalGraphics::DrawRect( long nX, long nY, long nWidth, long nHeight, cons } bool SalGraphics::drawPolyLine( const basegfx::B2DPolygon& /*rPolyPolygon*/, + double /*fTransparency*/, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eLineJoin*/) { @@ -536,7 +537,7 @@ sal_Bool SalGraphics::DrawPolyPolygonBezier( sal_uInt32 i_nPoly, const sal_uInt3 return bRet; } -bool SalGraphics::DrawPolyLine( const ::basegfx::B2DPolygon& i_rPolygon, +bool SalGraphics::DrawPolyLine( const ::basegfx::B2DPolygon& i_rPolygon, double fTransparency, const ::basegfx::B2DVector& i_rLineWidth, basegfx::B2DLineJoin i_eLineJoin, const OutputDevice* i_pOutDev ) { @@ -544,10 +545,10 @@ bool SalGraphics::DrawPolyLine( const ::basegfx::B2DPolygon& i_rPolygon, if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) ) { basegfx::B2DPolygon aMirror( mirror( i_rPolygon, i_pOutDev ) ); - bRet = drawPolyLine( aMirror, i_rLineWidth, i_eLineJoin ); + bRet = drawPolyLine( aMirror, fTransparency, i_rLineWidth, i_eLineJoin ); } else - bRet = drawPolyLine( i_rPolygon, i_rLineWidth, i_eLineJoin ); + bRet = drawPolyLine( i_rPolygon, fTransparency, i_rLineWidth, i_eLineJoin ); return bRet; } @@ -668,13 +669,13 @@ BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* return drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize ); } -BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { Point pt( aPos ); - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( pt.X(), pOutDev ); mirror( rgn, pOutDev ); return hitTestNativeControl( nType, nPart, rgn, pt, rIsInside ); @@ -683,51 +684,48 @@ BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, co return hitTestNativeControl( nType, nPart, rControlRegion, aPos, rIsInside ); } -void SalGraphics::mirror( ControlType nType, const ImplControlValue& rVal, const OutputDevice* pOutDev, bool bBack ) const +void SalGraphics::mirror( ControlType , const ImplControlValue& rVal, const OutputDevice* pOutDev, bool bBack ) const { - if( rVal.getOptionalVal() ) + switch( rVal.getType() ) { - switch( nType ) + case CTRL_SLIDER: { - case CTRL_SLIDER: - { - SliderValue* pSlVal = reinterpret_cast<SliderValue*>(rVal.getOptionalVal()); - mirror(pSlVal->maThumbRect,pOutDev,bBack); - } - break; - case CTRL_SCROLLBAR: - { - ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(rVal.getOptionalVal()); - mirror(pScVal->maThumbRect,pOutDev,bBack); - mirror(pScVal->maButton1Rect,pOutDev,bBack); - mirror(pScVal->maButton2Rect,pOutDev,bBack); - } - break; - case CTRL_SPINBOX: - case CTRL_SPINBUTTONS: - { - SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(rVal.getOptionalVal()); - mirror(pSpVal->maUpperRect,pOutDev,bBack); - mirror(pSpVal->maLowerRect,pOutDev,bBack); - } - break; - case CTRL_TOOLBAR: - { - ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(rVal.getOptionalVal()); - mirror(pTVal->maGripRect,pOutDev,bBack); - } - break; + SliderValue* pSlVal = static_cast<SliderValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pSlVal->maThumbRect,pOutDev,bBack); + } + break; + case CTRL_SCROLLBAR: + { + ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pScVal->maThumbRect,pOutDev,bBack); + mirror(pScVal->maButton1Rect,pOutDev,bBack); + mirror(pScVal->maButton2Rect,pOutDev,bBack); + } + break; + case CTRL_SPINBOX: + case CTRL_SPINBUTTONS: + { + SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pSpVal->maUpperRect,pOutDev,bBack); + mirror(pSpVal->maLowerRect,pOutDev,bBack); + } + break; + case CTRL_TOOLBAR: + { + ToolbarValue* pTVal = static_cast<ToolbarValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pTVal->maGripRect,pOutDev,bBack); } + break; } } -BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); BOOL bRet = drawNativeControl( nType, nPart, rgn, nState, aValue, aCaption ); @@ -738,13 +736,13 @@ BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const return drawNativeControl( nType, nPart, rControlRegion, nState, aValue, aCaption ); } -BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); BOOL bRet = drawNativeControlText( nType, nPart, rgn, nState, aValue, aCaption ); @@ -755,13 +753,13 @@ BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, c return drawNativeControlText( nType, nPart, rControlRegion, nState, aValue, aCaption ); } -BOOL SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, +BOOL SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion, const OutputDevice *pOutDev ) + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); if( getNativeControlRegion( nType, nPart, rgn, nState, aValue, aCaption, diff --git a/vcl/source/gdi/salnativewidgets-none.cxx b/vcl/source/gdi/salnativewidgets-none.cxx index 7faf12d062fe..8aa0e47f1a35 100644 --- a/vcl/source/gdi/salnativewidgets-none.cxx +++ b/vcl/source/gdi/salnativewidgets-none.cxx @@ -58,7 +58,7 @@ BOOL SalGraphics::IsNativeControlSupported( ControlType, ControlPart ) */ BOOL SalGraphics::hitTestNativeControl( ControlType, ControlPart, - const Region&, + const Rectangle&, const Point&, BOOL& ) { @@ -77,7 +77,7 @@ BOOL SalGraphics::hitTestNativeControl( ControlType, */ BOOL SalGraphics::drawNativeControl( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -98,7 +98,7 @@ BOOL SalGraphics::drawNativeControl( ControlType, */ BOOL SalGraphics::drawNativeControlText( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -122,12 +122,12 @@ BOOL SalGraphics::drawNativeControlText( ControlType, */ BOOL SalGraphics::getNativeControlRegion( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString&, - Region &, - Region & ) + Rectangle &, + Rectangle & ) { return( FALSE ); } diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx index ebdd59f517af..601e46411cd8 100644 --- a/vcl/source/glyphs/gcach_ftyp.cxx +++ b/vcl/source/glyphs/gcach_ftyp.cxx @@ -301,6 +301,7 @@ FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes, mnSynthetic( nSynthetic ), mnFontId( nFontId ), maDevFontAttributes( rDevFontAttributes ), + mpFontCharMap( NULL ), mpChar2Glyph( NULL ), mpGlyph2Char( NULL ), mpExtraKernInfo( pExtraKernInfo ) @@ -318,6 +319,8 @@ FtFontInfo::FtFontInfo( const ImplDevFontAttributes& rDevFontAttributes, FtFontInfo::~FtFontInfo() { + if( mpFontCharMap ) + mpFontCharMap->DeReference(); delete mpExtraKernInfo; delete mpChar2Glyph; delete mpGlyph2Char; @@ -520,10 +523,25 @@ void* FreetypeServerFont::GetFtFace() const FreetypeManager::~FreetypeManager() { -// This crashes on Solaris 10 -// TODO: check which versions have this problem -// -// FT_Error rcFT = FT_Done_FreeType( aLibFT ); + // an application about to exit can omit garbage collecting the heap + // since it makes things slower and introduces risks if the heap was not perfect + // for debugging, for memory grinding or leak checking the env allows to force GC + const char* pEnv = getenv( "SAL_FORCE_GC_ON_EXIT" ); + if( pEnv && (*pEnv != '0') ) + { + // cleanup container of fontinfos + for( FontList::const_iterator it = maFontList.begin(); it != maFontList.end(); ++it ) + { + FtFontInfo* pInfo = (*it).second; + delete pInfo; + } + maFontList.clear(); + +#if 0 // FT_Done_FreeType crashes on Solaris 10 + // TODO: check which versions have this problem + FT_Error rcFT = FT_Done_FreeType( aLibFT ); +#endif + } } // ----------------------------------------------------------------------- @@ -895,6 +913,9 @@ void FreetypeServerFont::SetFontOptions( const ImplFontOptions& rFontOptions) } } #endif + + if( mnPrioEmbedded <= 0 ) + mnLoadFlags |= FT_LOAD_NO_BITMAP; } // ----------------------------------------------------------------------- @@ -1730,16 +1751,39 @@ bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap // determine unicode ranges in font // ----------------------------------------------------------------------- -// TODO: replace with GetFontCharMap() -bool FreetypeServerFont::GetFontCodeRanges( CmapResult& rResult ) const +const ImplFontCharMap* FreetypeServerFont::GetImplFontCharMap( void ) const +{ + const ImplFontCharMap* pIFCMap = mpFontInfo->GetImplFontCharMap(); + return pIFCMap; +} + +const ImplFontCharMap* FtFontInfo::GetImplFontCharMap( void ) +{ + // check if the charmap is already cached + if( mpFontCharMap ) + return mpFontCharMap; + + // get the charmap and cache it + CmapResult aCmapResult; + bool bOK = GetFontCodeRanges( aCmapResult ); + if( bOK ) + mpFontCharMap = new ImplFontCharMap( aCmapResult ); + else + mpFontCharMap = ImplFontCharMap::GetDefaultMap(); + mpFontCharMap->AddReference(); + return mpFontCharMap; +} + +// TODO: merge into method GetFontCharMap() +bool FtFontInfo::GetFontCodeRanges( CmapResult& rResult ) const { - rResult.mbSymbolic = mpFontInfo->IsSymbolFont(); + rResult.mbSymbolic = IsSymbolFont(); // TODO: is the full CmapResult needed on platforms calling this? if( FT_IS_SFNT( maFaceFT ) ) { ULONG nLength = 0; - const unsigned char* pCmap = mpFontInfo->GetTable( "cmap", &nLength ); + const unsigned char* pCmap = GetTable( "cmap", &nLength ); if( pCmap && (nLength > 0) ) if( ParseCMAP( pCmap, nLength, rResult ) ) return true; diff --git a/vcl/source/glyphs/gcach_ftyp.hxx b/vcl/source/glyphs/gcach_ftyp.hxx index 5ebe70bcbdf9..d760ce1d1fed 100644 --- a/vcl/source/glyphs/gcach_ftyp.hxx +++ b/vcl/source/glyphs/gcach_ftyp.hxx @@ -94,6 +94,9 @@ public: int GetGlyphIndex( sal_UCS4 cChar ) const; void CacheGlyphIndex( sal_UCS4 cChar, int nGI ) const; + bool GetFontCodeRanges( CmapResult& ) const; + const ImplFontCharMap* GetImplFontCharMap( void ); + bool HasExtraKerning() const; int GetExtraKernPairs( ImplKernPairData** ) const; int GetExtraGlyphKernValue( int nLeftGlyph, int nRightGlyph ) const; @@ -108,6 +111,8 @@ private: sal_IntPtr mnFontId; ImplDevFontAttributes maDevFontAttributes; + const ImplFontCharMap* mpFontCharMap; + // cache unicode->glyphid mapping because looking it up is expensive // TODO: change to hash_multimap when a use case requires a m:n mapping typedef ::std::hash_map<int,int> Int2IntMap; @@ -181,6 +186,7 @@ public: virtual bool NeedsArtificialItalic() const { return mbArtItalic; } virtual void FetchFontMetric( ImplFontMetricData&, long& rFactor ) const; + virtual const ImplFontCharMap* GetImplFontCharMap( void ) const; virtual int GetGlyphIndex( sal_UCS4 ) const; int GetRawGlyphIndex( sal_UCS4 ) const; @@ -203,7 +209,6 @@ protected: int ApplyGlyphTransform( int nGlyphFlags, FT_GlyphRec_*, bool ) const; virtual void InitGlyphData( int nGlyphIndex, GlyphData& ) const; - virtual bool GetFontCodeRanges( CmapResult& ) const; bool ApplyGSUB( const ImplFontSelectData& ); virtual ServerFontLayoutEngine* GetLayoutEngine(); diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx index 1953ecf553c4..7181db56dd4d 100644 --- a/vcl/source/glyphs/glyphcache.cxx +++ b/vcl/source/glyphs/glyphcache.cxx @@ -78,12 +78,18 @@ GlyphCache::~GlyphCache() void GlyphCache::InvalidateAllGlyphs() { -#if 0 // TODO: implement uncaching of all glyph shapes and metrics - for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it ) - delete const_cast<ServerFont*>( it->second ); - maFontList.clear(); - mpCurrentGCFont = NULL; -#endif + // an application about to exit can omit garbage collecting the heap + // since it makes things slower and introduces risks if the heap was not perfect + // for debugging, for memory grinding or leak checking the env allows to force GC + const char* pEnv = getenv( "SAL_FORCE_GC_ON_EXIT" ); + if( pEnv && (*pEnv != '0') ) + { + // uncache of all glyph shapes and metrics + for( FontList::iterator it = maFontList.begin(); it != maFontList.end(); ++it ) + delete const_cast<ServerFont*>( it->second ); + maFontList.clear(); + mpCurrentGCFont = NULL; + } } // ----------------------------------------------------------------------- diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx index f66f5b48e39e..f82e3afe39c8 100644 --- a/vcl/source/glyphs/graphite_adaptors.cxx +++ b/vcl/source/glyphs/graphite_adaptors.cxx @@ -99,12 +99,18 @@ FontProperties::FontProperties(const FreetypeServerFont &font) throw() fItalic = false; } - // Get the font name. + // Get the font name, but prefix with file name hash in case + // there are 2 fonts on the system with the same face name + sal_Int32 nHashCode = font.GetFontFileName()->hashCode(); + ::rtl::OUStringBuffer nHashFaceName; + nHashFaceName.append(nHashCode, 16); const sal_Unicode * name = font.GetFontSelData().maName.GetBuffer(); - const size_t name_sz = std::min(sizeof szFaceName/sizeof(wchar_t)-1, - size_t(font.GetFontSelData().maName.Len())); + nHashFaceName.append(name); - std::copy(name, name + name_sz, szFaceName); + const size_t name_sz = std::min(sizeof szFaceName/sizeof(wchar_t)-1, + static_cast<size_t>(nHashFaceName.getLength())); + + std::copy(nHashFaceName.getStr(), nHashFaceName.getStr() + name_sz, szFaceName); szFaceName[name_sz] = '\0'; } @@ -120,13 +126,13 @@ GraphiteFontAdaptor::GraphiteFontAdaptor(ServerFont & sfont, const sal_Int32 dpi mfEmUnits(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().y_ppem), mpFeatures(NULL) { - //std::wstring face_name(maFontProperties.szFaceName); const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( sfont.GetFontSelData().meLanguage ); -#ifdef DEBUG - printf("GraphiteFontAdaptor %lx\n", (long)this); -#endif rtl::OString name = rtl::OUStringToOString( sfont.GetFontSelData().maTargetName, RTL_TEXTENCODING_UTF8 ); +#ifdef DEBUG + printf("GraphiteFontAdaptor %lx %s italic=%u bold=%u\n", (long)this, name.getStr(), + maFontProperties.fItalic, maFontProperties.fBold); +#endif sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1; if (nFeat > 0) { @@ -259,21 +265,24 @@ const void * GraphiteFontAdaptor::getTable(gr::fontTableId32 table_id, size_t * // Return the glyph's metrics in pixels. void GraphiteFontAdaptor::getGlyphMetrics(gr::gid16 nGlyphId, gr::Rect & aBounding, gr::Point & advances) { - // Graphite gets really confused if the glyphs have been transformed, so - // if orientation has been set we can't use the font's glyph cache - // unfortunately the font selection data, doesn't always have the orientation - // set, even if it was when the glyphs were cached, so we use our own cache. - -// const GlyphMetric & metric = mrFont.GetGlyphMetric(nGlyphId); -// -// aBounding.right = aBounding.left = metric.GetOffset().X(); -// aBounding.bottom = aBounding.top = -metric.GetOffset().Y(); -// aBounding.right += metric.GetSize().Width(); -// aBounding.bottom -= metric.GetSize().Height(); -// -// advances.x = metric.GetDelta().X(); -// advances.y = -metric.GetDelta().Y(); - + // There used to be problems when orientation was set however, this no + // longer seems to be the case and the Glyph Metric cache in + // FreetypeServerFont is more efficient since it lasts between calls to VCL +#if 1 + const GlyphMetric & metric = mrFont.GetGlyphMetric(nGlyphId); + + aBounding.right = aBounding.left = metric.GetOffset().X(); + aBounding.bottom = aBounding.top = -metric.GetOffset().Y(); + aBounding.right += metric.GetSize().Width(); + aBounding.bottom -= metric.GetSize().Height(); + + advances.x = metric.GetDelta().X(); + advances.y = -metric.GetDelta().Y(); + +#else + // The problem with the code below is that the cache only lasts + // as long as the life time of the GraphiteFontAdaptor, which + // is created once per call to X11SalGraphics::GetTextLayout GlyphMetricMap::const_iterator gm_itr = maGlyphMetricMap.find(nGlyphId); if (gm_itr != maGlyphMetricMap.end()) { @@ -321,6 +330,7 @@ void GraphiteFontAdaptor::getGlyphMetrics(gr::gid16 nGlyphId, gr::Rect & aBoundi // Now add an entry to our metrics map. maGlyphMetricMap[nGlyphId] = std::make_pair(aBounding, advances); } +#endif } #endif diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx index 64bbb0a38d60..7682cdb6c8ba 100644 --- a/vcl/source/glyphs/graphite_cache.cxx +++ b/vcl/source/glyphs/graphite_cache.cxx @@ -36,10 +36,10 @@ #include <tools/debug.hxx> #include <vcl/sallayout.hxx> -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Segment.h> -#include <tools/postextstl.h> +#include <postextstl.h> #include <rtl/ustring.hxx> #include <vcl/graphite_layout.hxx> @@ -105,7 +105,7 @@ GrSegRecord * GraphiteSegmentCache::cacheSegment(TextSourceAdaptor * adapter, gr // when the next key is added, the record for the prevKey's m_nextKey field // is updated to the newest key so that m_oldestKey can be updated to the // next oldest key when the record for m_oldestKey is deleted - if (m_segMap.size() > SEG_CACHE_SIZE) + if (m_segMap.size() > m_nSegCacheSize) { GraphiteSegMap::iterator oldestPair = m_segMap.find(reinterpret_cast<long>(m_oldestKey)); // oldest record may no longer exist if a buffer was changed diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx index ff2fd8f306b1..8a011606ab41 100644 --- a/vcl/source/glyphs/graphite_layout.cxx +++ b/vcl/source/glyphs/graphite_layout.cxx @@ -56,6 +56,10 @@ #include <svsys.h> #endif +#ifdef UNX +#include <vcl/graphite_adaptors.hxx> +#endif + #include <vcl/salgdi.hxx> #include <unicode/uchar.h> @@ -63,13 +67,13 @@ #include <unicode/uscript.h> // Graphite Libraries (must be after vcl headers on windows) -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> #include <graphite/Segment.h> #include <graphite/SegmentPainter.h> -#include <tools/postextstl.h> +#include <postextstl.h> #include <vcl/graphite_layout.hxx> #include <vcl/graphite_features.hxx> @@ -175,7 +179,8 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, glyph_range_t iGlyphs = rSegment.glyphs(); int nGlyphs = iGlyphs.second - iGlyphs.first; gr::GlyphIterator prevBase = iGlyphs.second; - float fMinX = rSegment.advanceWidth(); + float fSegmentAdvance = rSegment.advanceWidth(); + float fMinX = fSegmentAdvance; float fMaxX = 0.0f; rGlyph2Char.assign(nGlyphs, -1); long nDxOffset = 0; @@ -222,7 +227,8 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, nFirstGlyphInCluster != nGlyphIndex) { std::pair <float,float> aBounds = - appendCluster(rSegment, rArgs, bRtl, nFirstCharInCluster, + appendCluster(rSegment, rArgs, bRtl, + fSegmentAdvance, nFirstCharInCluster, nNextChar, nFirstGlyphInCluster, nGlyphIndex, fScaling, rChar2Base, rGlyph2Char, rCharDxs, nDxOffset); fMinX = std::min(aBounds.first, fMinX); @@ -285,7 +291,8 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, nFirstGlyphInCluster != nGlyphIndex) { std::pair <float,float> aBounds = - appendCluster(rSegment, rArgs, bRtl, nFirstCharInCluster, nNextChar, + appendCluster(rSegment, rArgs, bRtl, fSegmentAdvance, + nFirstCharInCluster, nNextChar, nFirstGlyphInCluster, nGlyphIndex, fScaling, rChar2Base, rGlyph2Char, rCharDxs, nDxOffset); fMinX = std::min(aBounds.first, fMinX); @@ -334,11 +341,11 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, } } -std::pair<float,float> GraphiteLayout::Glyphs::appendCluster(gr::Segment & rSeg, - ImplLayoutArgs & rArgs, bool bRtl, int nFirstCharInCluster, int nNextChar, - int nFirstGlyphInCluster, int nNextGlyph, float fScaling, - std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, - std::vector<int> & rCharDxs, long & rDXOffset) +std::pair<float,float> GraphiteLayout::Glyphs::appendCluster(gr::Segment& rSeg, + ImplLayoutArgs & rArgs, bool bRtl,float fSegmentAdvance, + int nFirstCharInCluster, int nNextChar, int nFirstGlyphInCluster, + int nNextGlyph, float fScaling, std::vector<int> & rChar2Base, + std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset) { glyph_range_t iGlyphs = rSeg.glyphs(); int nGlyphs = iGlyphs.second - iGlyphs.first; @@ -402,9 +409,9 @@ std::pair<float,float> GraphiteLayout::Glyphs::appendCluster(gr::Segment & rSeg, gr::GlyphInfo aGlyph = *(iGlyphs.first + j); if (j + nDelta >= nGlyphs || j + nDelta < 0) // at rhs ltr,rtl { - fNextOrigin = rSeg.advanceWidth(); - nNextOrigin = round(rSeg.advanceWidth() * fScaling + rDXOffset); - aBounds.second = std::max(rSeg.advanceWidth(), aBounds.second); + fNextOrigin = fSegmentAdvance; + nNextOrigin = round(fSegmentAdvance * fScaling + rDXOffset); + aBounds.second = std::max(fSegmentAdvance, aBounds.second); } else { @@ -546,7 +553,7 @@ GraphiteLayout::GraphiteLayout(const gr::Font & font, const grutils::GrFeaturePa // If true, it can cause end of line spaces to be hidden e.g. Doulos SIL maLayout.setStartOfLine(false); maLayout.setEndOfLine(false); -// maLayout.setDumbFallback(false); + maLayout.setDumbFallback(true); // trailing ws doesn't seem to always take affect if end of line is true maLayout.setTrailingWs(gr::ktwshAll); #ifdef GRLAYOUT_DEBUG @@ -587,19 +594,39 @@ bool GraphiteLayout::LayoutText(ImplLayoutArgs & rArgs) { #ifdef GRCACHE GrSegRecord * pSegRecord = NULL; - gr::Segment * pSegment = CreateSegment(rArgs, &pSegRecord); - if (!pSegment) - return false; - + gr::Segment * pSegment = NULL; + // Graphite can in rare cases crash with a zero length + if (rArgs.mnMinCharPos < rArgs.mnEndCharPos) + { + pSegment = CreateSegment(rArgs, &pSegRecord); + if (!pSegment) + return false; + } + else + { + clear(); + return true; + } // layout the glyphs as required by OpenOffice bool success = LayoutGlyphs(rArgs, pSegment, pSegRecord); if (pSegRecord) pSegRecord->unlock(); else delete pSegment; #else - gr::Segment * pSegment = CreateSegment(rArgs); - bool success = LayoutGlyphs(rArgs, pSegment); - delete pSegment; + gr::Segment * pSegment = NULL; + bool success = true; + if (rArgs.mnMinCharPos < rArgs.mnEndCharPos) + { + pSegment = CreateSegment(rArgs); + if (!pSegment) + return false; + success = LayoutGlyphs(rArgs, pSegment); + if (pSegment) delete pSegment; + } + else + { + clear(); + } #endif return success; } @@ -649,7 +676,19 @@ public: #endif return hash; }; - +protected: + virtual void UniqueCacheInfo( ext_std::wstring& stuFace, bool& fBold, bool& fItalic ) + { +#ifdef WIN32 + dynamic_cast<GraphiteWinFont&>(mrRealFont).UniqueCacheInfo(stuFace, fBold, fItalic); +#else +#ifdef UNX + dynamic_cast<GraphiteFontAdaptor&>(mrRealFont).UniqueCacheInfo(stuFace, fBold, fItalic); +#else +#error Unknown base type for gr::Font::UniqueCacheInfo +#endif +#endif + } private: gr::Font & mrRealFont; }; @@ -701,7 +740,7 @@ gr::Segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs) (GraphiteCacheHandler::instance).getCache(aFontHash); if (pCache) { - *pSegRecord = pCache->getSegment(rArgs, bRtl, nSegCharLimit); + *pSegRecord = pCache->getSegment(rArgs, bRtl, limit); if (*pSegRecord) { pSegment = (*pSegRecord)->getSegment(); @@ -715,7 +754,34 @@ gr::Segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs) (*pSegRecord)->clearVectors(); } mpTextSrc->switchLayoutArgs(rArgs); - return pSegment; + if (limit > rArgs.mnMinCharPos && limit == rArgs.mnEndCharPos + && pSegment->stopCharacter() != limit) + { + // check that the last character is not part of a ligature + glyph_set_range_t aGlyphSet = pSegment->charToGlyphs(limit - 1); + if (aGlyphSet.first == aGlyphSet.second) + { + // no glyphs associated with this glyph - occurs mid ligature + pSegment = NULL; + *pSegRecord = NULL; + } + else + { + while (aGlyphSet.first != aGlyphSet.second) + { + int lastChar = static_cast<int>((*aGlyphSet.first).lastChar()); + if (lastChar >= limit) + { + pSegment = NULL; + *pSegRecord = NULL; + break; + } + aGlyphSet.first++; + } + } + } + if (pSegment) + return pSegment; } } #endif @@ -738,6 +804,14 @@ gr::Segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs) } else { +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(), "Gr::LayoutText failed: "); + for (int i = mnMinCharPos; i < limit; i++) + { + fprintf(grLog(), "%04x ", rArgs.mpStr[i]); + } + fprintf(grLog(), "\n"); +#endif clear(); return NULL; } @@ -897,7 +971,7 @@ long GraphiteLayout::FillDXArray( sal_Int32* pDXArray ) const if (i > 0) pDXArray[i] -= mvCharDxs[i-1]; } #ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%d,%ld ", (int)i, (int)mvCharDxs[i], pDXArray[i]); + fprintf(grLog(),"%d,%d,%d ", (int)i, (int)mvCharDxs[i], pDXArray[i]); #endif } //std::adjacent_difference(mvCharDxs.begin(), mvCharDxs.end(), pDXArray); @@ -974,13 +1048,13 @@ void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs) { if (mvGlyphs[i].IsClusterStart()) { - nOffset = fExtraPerCluster * nCluster; + nOffset = FRound( fExtraPerCluster * nCluster ); size_t nCharIndex = mvGlyph2Char[i]; mvCharDxs[nCharIndex] += nOffset; // adjust char dxs for rest of characters in cluster while (++nCharIndex < mvGlyph2Char.size()) { - int nChar2Base = (mvChar2BaseGlyph[nCharIndex] == -1)? -1 : mvChar2BaseGlyph[nCharIndex] & GLYPH_INDEX_MASK; + int nChar2Base = (mvChar2BaseGlyph[nCharIndex] == -1)? -1 : (int)(mvChar2BaseGlyph[nCharIndex] & GLYPH_INDEX_MASK); if (nChar2Base == -1 || nChar2Base == static_cast<int>(i)) mvCharDxs[nCharIndex] += nOffset; } @@ -1003,14 +1077,15 @@ void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs) Glyphs::iterator iGlyph = mvGlyphs.begin(); while (iGlyph != iLastGlyph) { - iGlyph->maLinearPos.X() = static_cast<float>(iGlyph->maLinearPos.X()) * fXFactor; + iGlyph->maLinearPos.X() = FRound( fXFactor * iGlyph->maLinearPos.X() ); ++iGlyph; } for (size_t i = 0; i < mvCharDxs.size(); i++) { - mvCharDxs[i] = fXFactor * static_cast<float>(mvCharDxs[i]); + mvCharDxs[i] = FRound( fXFactor * mvCharDxs[i] ); } } + mnWidth = rArgs.mnLayoutWidth; } void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDeltaWidth) @@ -1020,7 +1095,7 @@ void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDelt #ifdef GRLAYOUT_DEBUG for (size_t iDx = 0; iDx < mvCharDxs.size(); iDx++) - fprintf(grLog(),"%d,%d,%ld ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]); + fprintf(grLog(),"%d,%d,%d ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]); fprintf(grLog(),"ApplyDx\n"); #endif bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL; @@ -1029,11 +1104,11 @@ void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDelt { nXOffset = args.mpDXArray[nChars - 1] - mvCharDxs[nChars - 1]; } - int nPrevClusterGlyph = (bRtl)? mvGlyphs.size() : -1; + int nPrevClusterGlyph = (bRtl)? (signed)mvGlyphs.size() : -1; int nPrevClusterLastChar = -1; for (size_t i = 0; i < nChars; i++) { - int nChar2Base = (mvChar2BaseGlyph[i] == -1)? -1 : mvChar2BaseGlyph[i] & GLYPH_INDEX_MASK; + int nChar2Base = (mvChar2BaseGlyph[i] == -1)? -1 : (int)(mvChar2BaseGlyph[i] & GLYPH_INDEX_MASK); if ((nChar2Base > -1) && (nChar2Base != nPrevClusterGlyph)) { assert((nChar2Base > -1) && (nChar2Base < (signed)mvGlyphs.size())); @@ -1047,11 +1122,11 @@ void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDelt int nLastGlyph = nChar2Base; for (; j < nChars; j++) { - int nChar2BaseJ = (mvChar2BaseGlyph[j] == -1)? -1 : mvChar2BaseGlyph[j] & GLYPH_INDEX_MASK; + int nChar2BaseJ = (mvChar2BaseGlyph[j] == -1)? -1 : (int)(mvChar2BaseGlyph[j] & GLYPH_INDEX_MASK); assert((nChar2BaseJ >= -1) && (nChar2BaseJ < (signed)mvGlyphs.size())); if (nChar2BaseJ != -1 && mvGlyphs[nChar2BaseJ].IsClusterStart()) { - nLastGlyph = nChar2BaseJ + ((bRtl)? 1 : -1); + nLastGlyph = nChar2BaseJ + ((bRtl)? +1 : -1); nLastChar = j - 1; break; } @@ -1090,7 +1165,7 @@ void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDelt } long nDWidth = nNewClusterWidth - nOrigClusterWidth; #ifdef GRLAYOUT_DEBUG - fprintf(grLog(), "c%d last glyph %d/%d\n", i, nLastGlyph, mvGlyphs.size()); + fprintf(grLog(), "c%lu last glyph %d/%lu\n", i, nLastGlyph, mvGlyphs.size()); #endif assert((nLastGlyph > -1) && (nLastGlyph < (signed)mvGlyphs.size())); mvGlyphs[nLastGlyph].mnNewWidth += nDWidth; @@ -1128,7 +1203,7 @@ void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDelt std::copy(args.mpDXArray, args.mpDXArray + nChars, mvCharDxs.begin() + (args.mnMinCharPos - mnMinCharPos)); #ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"ApplyDx %ld(%ld)\n", args.mpDXArray[nChars - 1], mnWidth); + fprintf(grLog(),"ApplyDx %d(%ld)\n", args.mpDXArray[nChars - 1], mnWidth); #endif mnWidth = args.mpDXArray[nChars - 1]; } @@ -1170,7 +1245,7 @@ void GraphiteLayout::kashidaJustify(std::vector<int>& rDeltaWidths, sal_GlyphId } nKashidaCount = 1 + (nGapWidth / nKashidaWidth); #ifdef GRLAYOUT_DEBUG - printf("inserting %d kashidas at %ld\n", nKashidaCount, (*i).mnGlyphIndex); + printf("inserting %d kashidas at %u\n", nKashidaCount, (*i).mnGlyphIndex); #endif GlyphItem glyphItem = *i; Point aPos(0, 0); @@ -1309,7 +1384,7 @@ void GraphiteLayout::GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray pCaretXArray[i] = pCaretXArray[i+1] = 0; } #ifdef GRLAYOUT_DEBUG - fprintf(grLog(),"%d,%ld-%ld\t", nCharSlot, pCaretXArray[i], pCaretXArray[i+1]); + fprintf(grLog(),"%d,%d-%d\t", nCharSlot, pCaretXArray[i], pCaretXArray[i+1]); #endif } #ifdef GRLAYOUT_DEBUG diff --git a/vcl/source/glyphs/graphite_textsrc.hxx b/vcl/source/glyphs/graphite_textsrc.hxx index 2b9c705a5ea7..388f8a631b49 100644 --- a/vcl/source/glyphs/graphite_textsrc.hxx +++ b/vcl/source/glyphs/graphite_textsrc.hxx @@ -59,11 +59,11 @@ #include "vcl/dllapi.h" // Libraries -#include <tools/preextstl.h> +#include <preextstl.h> #include <graphite/GrClient.h> #include <graphite/Font.h> #include <graphite/ITextSource.h> -#include <tools/postextstl.h> +#include <postextstl.h> // Module type definitions and forward declarations. // @@ -93,6 +93,7 @@ public: virtual ext_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); virtual size_t getFontFeatures(gr::toffset ich, gr::FeatureSetting * prgfset); virtual bool sameSegment(gr::toffset ich1, gr::toffset ich2); + virtual bool featureVariations() { return false; } operator ImplLayoutArgs & () throw(); void setFeatures(const grutils::GrFeatureParser * pFeatures); diff --git a/vcl/source/helper/makefile.mk b/vcl/source/helper/makefile.mk index e708bdec9eaa..1a417417dbe4 100644 --- a/vcl/source/helper/makefile.mk +++ b/vcl/source/helper/makefile.mk @@ -46,7 +46,6 @@ SLOFILES=\ $(SLO)$/canvastools.obj \ $(SLO)$/xconnection.obj \ $(SLO)$/threadex.obj \ - $(SLO)$/smartid.obj \ $(SLO)$/lazydelete.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/helper/smartid.cxx b/vcl/source/helper/smartid.cxx deleted file mode 100755 index c367aeb2bce5..000000000000 --- a/vcl/source/helper/smartid.cxx +++ /dev/null @@ -1,264 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" -#include <vcl/smartid.hxx> - -struct ImplSmartIdData -{ - String aUId; - ULONG nUId; - BOOL bHasStringId; - BOOL bHasNumericId; -}; - - -ImplSmartIdData* SmartId::GetSmartIdData() -{ - if ( !mpData ) - { - mpData = new ImplSmartIdData; -// mpData->aUId = ""; - mpData->nUId = 0; - mpData->bHasStringId = FALSE; - mpData->bHasNumericId = FALSE; - } - return mpData; -} - - -SmartId::SmartId( const String& rId ) -: mpData( NULL ) -{ - GetSmartIdData()->aUId = rId; - GetSmartIdData()->bHasStringId = TRUE; -} - -SmartId::SmartId( ULONG nId ) -: mpData( NULL ) -{ - GetSmartIdData()->nUId = nId; - GetSmartIdData()->bHasNumericId = TRUE; -} - -SmartId::SmartId( const String& rId, ULONG nId ) -: mpData( NULL ) -{ - GetSmartIdData()->aUId = rId; - GetSmartIdData()->bHasStringId = TRUE; - GetSmartIdData()->nUId = nId; - GetSmartIdData()->bHasNumericId = TRUE; -} - -SmartId::SmartId() -: mpData( NULL ) -{} - -SmartId::SmartId( const SmartId& rId ) -: mpData( NULL ) -{ - if ( rId.mpData ) - { - GetSmartIdData(); - mpData->aUId = rId.mpData->aUId; - mpData->bHasStringId = rId.mpData->bHasStringId; - mpData->nUId = rId.mpData->nUId; - mpData->bHasNumericId = rId.mpData->bHasNumericId; - } -} - -SmartId& SmartId::operator = ( const SmartId& rId ) -{ - if ( rId.mpData ) - GetSmartIdData(); - else - { - delete mpData; - mpData = NULL; - } - if ( mpData && rId.mpData ) - { - mpData->aUId = rId.mpData->aUId; - mpData->bHasStringId = rId.mpData->bHasStringId; - mpData->nUId = rId.mpData->nUId; - mpData->bHasNumericId = rId.mpData->bHasNumericId; - } - return *this; -} - -SmartId::~SmartId() -{ - if ( mpData ) - delete mpData; -#ifdef DBG_UTIL - if ( mpData ) - mpData = (ImplSmartIdData*)0xDeadBeef; -#endif -} - -void SmartId::UpdateId( const SmartId& rId, SmartIdUpdateMode aMode ) -{ - // Check if ImplData is needed - if ( aMode != SMART_SET_SMART || ( rId.HasString() || rId.HasNumeric() ) ) - GetSmartIdData(); - - if ( aMode == SMART_SET_STR || aMode == SMART_SET_ALL || ( aMode == SMART_SET_SMART && rId.HasString() ) ) - { - GetSmartIdData()->aUId = rId.GetStr(); - GetSmartIdData()->bHasStringId = rId.HasString(); - } - if ( aMode == SMART_SET_NUM || aMode == SMART_SET_ALL || ( aMode == SMART_SET_SMART && rId.HasNumeric() ) ) - { - GetSmartIdData()->nUId = rId.GetNum(); - GetSmartIdData()->bHasNumericId = rId.HasNumeric(); - } - - // remove ImplData when no IDs are set. This is Important because Implementation of Equals() Matches and HasAny relies on it - if ( mpData && !mpData->bHasStringId && !mpData->bHasNumericId ) - { - delete mpData; - mpData = NULL; - } -} - -BOOL SmartId::HasNumeric() const -{ - if ( !mpData ) - return FALSE; - else - return mpData->bHasNumericId; -} - -BOOL SmartId::HasString() const -{ - if ( !mpData ) - return FALSE; - else - return mpData->bHasStringId; -} - -BOOL SmartId::HasAny() const -{ - return mpData != NULL; -} - -ULONG SmartId::GetNum() const -{ - if ( !mpData ) - return 0; - else - return mpData->nUId; -} - -String SmartId::GetStr() const -{ - if ( !mpData ) - return String(); - else - return mpData->aUId; -} - - -String SmartId::GetText() const // return String for UI usage -{ - String aRes; - if ( HasNumeric() ) - aRes = String::CreateFromInt64( GetNum() ); - if ( HasString() ) - { - if ( HasNumeric() ) - aRes.AppendAscii( "/" ); - aRes.Append( GetStr() ); - } - return aRes; -} - -BOOL SmartId::Matches( const String &rId )const -{ - if ( HasString() ) - return GetStr().EqualsIgnoreCaseAscii( rId ); - else - return FALSE; -} - -BOOL SmartId::Matches( const ULONG nId ) const -{ - if ( HasNumeric() ) - return GetNum() == nId; - else - return FALSE; -} - -/****************************************************************************** -If Both Ids have nither Strings nor Numbers they don't match -If both Ids have Strings the result of Matching these is returned. -Numbers are then Ignored. -Else Matching Numbers is attempted. -******************************************************************************/ -BOOL SmartId::Matches( const SmartId &rId ) const -{ - if ( !mpData || !rId.mpData ) - return FALSE; - else if ( HasString() && rId.HasString() ) - return Matches( rId.GetStr() ); - else - return rId.HasNumeric() && Matches( rId.GetNum() ); -} - -BOOL SmartId::Equals( const SmartId &rId ) const -{ - if ( mpData && rId.mpData ) - return mpData->aUId.EqualsIgnoreCaseAscii( rId.mpData->aUId ) - && mpData->bHasStringId == rId.mpData->bHasStringId - && mpData->nUId == rId.mpData->nUId - && mpData->bHasNumericId == rId.mpData->bHasNumericId; - else if ( !mpData && !rId.mpData ) - return TRUE; - else - return FALSE; -} - -BOOL SmartId::operator == ( const SmartId& rRight ) const -{ - return Equals( rRight ); -} - -BOOL SmartId::operator < ( const SmartId& rRight ) const -{ - if ( HasString() && rRight.HasString() && GetStr() != rRight.GetStr() ) - return GetStr() < rRight.GetStr(); - else if ( HasNumeric() && rRight.HasNumeric() && GetNum() != rRight.GetNum() ) - return GetNum() < rRight.GetNum(); - else - { // Sort Strings to Front - if ( HasString() ) - return rRight.HasString() && rRight.HasNumeric(); - else - return rRight.HasString() || (!HasNumeric() && rRight.HasNumeric()); - } -} diff --git a/vcl/source/helper/strhelper.cxx b/vcl/source/helper/strhelper.cxx index db622073cea9..67f50b69a182 100644 --- a/vcl/source/helper/strhelper.cxx +++ b/vcl/source/helper/strhelper.cxx @@ -365,8 +365,8 @@ String WhitespaceToSpace( const String& rLine, BOOL bProtect ) else { *pLeap = *pRun; - *pLeap++; - *pRun++; + ++pLeap; + ++pRun; } } } @@ -422,8 +422,8 @@ ByteString WhitespaceToSpace( const ByteString& rLine, BOOL bProtect ) else { *pLeap = *pRun; - *pLeap++; - *pRun++; + ++pLeap; + ++pRun; } } } diff --git a/vcl/source/src/btntext.src b/vcl/source/src/btntext.src index 6d2360dae6cb..b786184fa2f3 100644 --- a/vcl/source/src/btntext.src +++ b/vcl/source/src/btntext.src @@ -81,67 +81,3 @@ String SV_BUTTONTEXT_ABORT Text [ en-US ] = "~Abort"; }; -/* HelpTexte, die wir derzeit nicht mehr verwenden: -SV_BUTTONHELPTEXT_OK -{ - Text = "Schliet dieses Dialogfeld und speichert alle vorgenommenen nderungen." ; -}; - -SV_BUTTONHELPTEXT_CANCEL -{ - Text = "Schliet dieses Dialogfeld, ohne Ihre nderungen zu speichern." ; -}; - -SV_BUTTONHELPTEXT_HELP -{ - Text = "Zeigt Hilfe zu diesem Fenster an." ; -}; - -SV_BUTTONHELPTEXT_MORE -{ - Text = "Zeigt weitere Einstellmglichkeiten an oder versteckt diese wieder." ; -}; - -Finnische-Texte: -OK OK -CANCEL Peruuta -HELP ~Ohje -MORE ~Enemmn -YES ~Kyll -NO ~Ei -RETRY ~Yrituudelleen -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vcl/source/src/images.src b/vcl/source/src/images.src index fdb1e755c86a..000d7215d80d 100644 --- a/vcl/source/src/images.src +++ b/vcl/source/src/images.src @@ -38,25 +38,6 @@ Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_STDOFFSET) File = "check.bmp"; }; -Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_WINOFFSET) -{ - File = "checkwin.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_OS2OFFSET) -{ - File = "checkos2.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_MACOFFSET) -{ - File = "checkmac.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_UNIXOFFSET) -{ - File = "checkunx.bmp"; -}; Bitmap (SV_RESID_BITMAP_CHECK + SV_RESID_MONOOFFSET) { @@ -80,26 +61,6 @@ Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_STDOFFSET) File = "radio.bmp"; }; -Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_WINOFFSET) -{ - File = "radiowin.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_OS2OFFSET) -{ - File = "radioos2.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_MACOFFSET) -{ - File = "radiomac.bmp"; -}; - -Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_UNIXOFFSET) -{ - File = "radiounx.bmp"; -}; - Bitmap (SV_RESID_BITMAP_RADIO + SV_RESID_MONOOFFSET) { File = "radiomono.bmp"; diff --git a/vcl/source/src/print.src b/vcl/source/src/print.src index 58f0a477c848..04ab77f09288 100644 --- a/vcl/source/src/print.src +++ b/vcl/source/src/print.src @@ -29,6 +29,7 @@ ModalDialog SV_DLG_PRINT { + HelpID = ".HelpID:vcl:PrintDialog:Dialog"; Text [en-US] = "Print"; Closeable = TRUE; Sizeable = TRUE; @@ -44,16 +45,19 @@ ModalDialog SV_DLG_PRINT Pos = MAP_APPFONT( 240, 195 ); Size = MAP_APPFONT( 50, 15 ); Text [en-US] = "~Print"; + HelpID = ".HelpID:vcl:PrintDialog:OK"; }; CancelButton SV_PRINT_CANCEL { Pos = MAP_APPFONT( 295, 195 ); Size = MAP_APPFONT( 50, 15 ); + HelpID = ".HelpID:vcl:PrintDialog:Cancel"; }; HelpButton SV_PRINT_HELP { Pos = MAP_APPFONT( 5, 5 ); Size = MAP_APPFONT( 50, 15 ); + HelpID = ".HelpID:vcl:PrintDialog:Help"; }; Window SV_PRINT_PAGE_PREVIEW @@ -61,6 +65,7 @@ ModalDialog SV_DLG_PRINT Pos = MAP_APPFONT( 5, 5 ); Size = MAP_APPFONT( 130, 130 ); Border = FALSE; + HelpID = ".HelpID:vcl:PrintDialog:Preview"; }; NumericField SV_PRINT_PAGE_EDIT { @@ -69,7 +74,7 @@ ModalDialog SV_DLG_PRINT SVLook = TRUE; Spin = FALSE; Border = TRUE; - HelpText [en-US] = "Select page to display in preview."; + HelpID = ".HelpID:vcl:PrintDialog:PageEdit"; }; FixedText SV_PRINT_PAGE_TXT { @@ -77,23 +82,25 @@ ModalDialog SV_DLG_PRINT Size = MAP_APPFONT( 30, 12 ); Text [ en-US ] = "/ %n"; VCenter = TRUE; + HelpID = ".HelpID:vcl:PrintDialog:NumPagesText"; }; PushButton SV_PRINT_PAGE_FORWARD { Pos = MAP_APPFONT( 95, 140 ); Size = MAP_APPFONT( 15, 12 ); - HelpText [en-US] = "Scroll one page forward."; + HelpID = ".HelpID:vcl:PrintDialog:ForwardBtn"; }; PushButton SV_PRINT_PAGE_BACKWARD { Pos = MAP_APPFONT( 80, 140 ); Size = MAP_APPFONT( 15, 12 ); - HelpText [en-US] = "Scroll one page backward."; + HelpID = ".HelpID:vcl:PrintDialog:BackwardBtn"; }; TabControl SV_PRINT_TABCTRL { Pos = MAP_APPFONT( 140, 5 ); Size = MAP_APPFONT( 205, 175 ); + HelpID = ".HelpID:vcl:PrintDialog:TabPages"; }; FixedLine SV_PRINT_BUTTONLINE { @@ -123,6 +130,7 @@ ModalDialog SV_DLG_PRINT TabPage SV_PRINT_TAB_NUP { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage"; Text [en-US] = "Page Layout"; Hide = TRUE; @@ -132,34 +140,28 @@ ModalDialog SV_DLG_PRINT Size = MAP_APPFONT( 150, 10 ); Text [en-US] = "Layout"; }; - RadioButton SV_PRINT_PRT_NUP_DEFAULT_BTN - { - Pos = MAP_APPFONT( 0, 0 ); - Size = MAP_APPFONT( 10, 10 ); - Text [en-US] = "~Default"; - HelpText [en-US] = "Print one page per sheet of paper."; - }; RadioButton SV_PRINT_PRT_NUP_BROCHURE_BTN { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:Brochure"; Pos = MAP_APPFONT( 0, 0 ); Size = MAP_APPFONT( 10, 10 ); Text = ""; }; RadioButton SV_PRINT_PRT_NUP_PAGES_BTN { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:PagesPerSheet"; Pos = MAP_APPFONT( 0, 0 ); Size = MAP_APPFONT( 10, 10 ); Text [en-US] = "Pa~ges per sheet"; - HelpText [en-US] = "Print multiple pages per sheet of paper."; }; ListBox SV_PRINT_PRT_NUP_PAGES_BOX { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:PagesPerSheetBox"; Pos = MAP_APPFONT( 0, 0 ); Size = MAP_APPFONT( 10, 80 ); Border = TRUE; DropDown = TRUE; CurPos = 0; - HelpText [en-US] = "Select how many pages to print per sheet of paper."; StringList [en-US] = { < "1"; 1; >; @@ -180,6 +182,7 @@ ModalDialog SV_DLG_PRINT }; NumericField SV_PRINT_PRT_NUP_COLS_EDT { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:ColumnsBox"; Pos = MAP_APPFONT( 55, 20 ); Size = MAP_APPFONT( 40, 12 ); Border = TRUE; @@ -187,7 +190,6 @@ ModalDialog SV_DLG_PRINT Minimum = 1; Maximum = 32; Value = 1; - HelpText [en-US] = "Select number of columns."; }; FixedText SV_PRINT_PRT_NUP_TIMES_TXT { @@ -198,6 +200,7 @@ ModalDialog SV_DLG_PRINT }; NumericField SV_PRINT_PRT_NUP_ROWS_EDT { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:RowsBox"; Pos = MAP_APPFONT( 55, 35 ); Size = MAP_APPFONT( 40, 12 ); Border = TRUE; @@ -205,7 +208,6 @@ ModalDialog SV_DLG_PRINT Minimum = 1; Maximum = 32; Value = 1; - HelpText [en-US] = "Select number of rows."; }; FixedText SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT { @@ -215,13 +217,13 @@ ModalDialog SV_DLG_PRINT }; MetricField SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:PageMarginBox"; Pos = MAP_APPFONT( 55, 95 ); Size = MAP_APPFONT( 40, 12 ); Spin = TRUE; Border = TRUE; Value = 0; Unit = FUNIT_MM; - HelpText [en-US] = "Select margin between individual pages on each sheet of paper."; }; FixedText SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT { @@ -237,13 +239,13 @@ ModalDialog SV_DLG_PRINT }; MetricField SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:SheetMarginBox"; Pos = MAP_APPFONT( 155, 95 ); Size = MAP_APPFONT( 40, 12 ); Spin = TRUE; Border = TRUE; Value = 0; Unit = FUNIT_MM; - HelpText [en-US] = "Select margin between the printed pages and paper edge."; }; FixedText SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT { @@ -259,6 +261,7 @@ ModalDialog SV_DLG_PRINT }; ListBox SV_PRINT_PRT_NUP_ORIENTATION_BOX { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:OrientationBox"; Pos = MAP_APPFONT( 0, 0 ); Size = MAP_APPFONT( 10, 40 ); Border = TRUE; @@ -270,7 +273,6 @@ ModalDialog SV_DLG_PRINT < "Portrait"; SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT; >; < "Landscape"; SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE; >; }; - HelpText [en-US] = "Select the orientation of the paper."; }; FixedText SV_PRINT_PRT_NUP_ORDER_TXT { @@ -280,29 +282,32 @@ ModalDialog SV_DLG_PRINT }; ListBox SV_PRINT_PRT_NUP_ORDER_BOX { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:OrderBox"; Pos = MAP_APPFONT( 0, 0 ); - Size = MAP_APPFONT( 10, 20 ); + Size = MAP_APPFONT( 10, 50 ); DropDown = TRUE; Border = TRUE; CurPos = 0; StringList [en-US] = { - < "left to right, then down"; SV_PRINT_PRT_NUP_ORDER_LRTD; >; - < "top to bottom, then right"; SV_PRINT_PRT_NUP_ORDER_TDLR; >; + < "left to right, then down"; SV_PRINT_PRT_NUP_ORDER_LRTB; >; + < "top to bottom, then right"; SV_PRINT_PRT_NUP_ORDER_TBLR; >; + < "top to bottom, then left"; SV_PRINT_PRT_NUP_ORDER_TBRL; >; + < "right to left, then down"; SV_PRINT_PRT_NUP_ORDER_RLTB; >; }; - HelpText [en-US] = "Select order in which pages are to be printed."; }; CheckBox SV_PRINT_PRT_NUP_BORDER_CB { + HelpID = ".HelpID:vcl:PrintDialog:NUpPage:BorderBox"; Pos = MAP_APPFONT( 10, 65 ); Size = MAP_APPFONT( 150, 12 ); Text [en-US] = "Draw a border around each page"; - HelpText [en-US] = "Check to draw a border around each page."; }; }; TabPage SV_PRINT_TAB_JOB { + HelpID = ".HelpID:vcl:PrintDialog:JobPage"; Text [en-US] = "General"; Hide = TRUE; @@ -314,18 +319,18 @@ ModalDialog SV_DLG_PRINT }; ListBox SV_PRINT_PRINTERS { + HelpID = ".HelpID:vcl:PrintDialog:JobPage:PrinterList"; Pos = MAP_APPFONT( 5, 5 ); Size = MAP_APPFONT( 100, 80 ); Border = TRUE; Sort = TRUE; - HelpText [en-US] = "Select the printer to print on."; }; CheckBox SV_PRINT_DETAILS_BTN { + HelpID = ".HelpID:vcl:PrintDialog:JobPage:DetailsBtn"; Pos = MAP_APPFONT( 5, 5 ); Size = MAP_APPFONT( 5, 5 ); Text [en-US] = "Details"; - HelpText [en-US] = "Show/Hide detailed information of the selected printer."; }; FixedText SV_PRINT_STATUS_TXT { @@ -347,10 +352,10 @@ ModalDialog SV_DLG_PRINT }; PushButton SV_PRINT_PRT_SETUP { + HelpID = ".HelpID:vcl:PrintDialog:JobPage:Properties"; Pos = MAP_APPFONT( 115, 5 ); Size = MAP_APPFONT( 50, 15 ); Text [en-US] = "Properties..."; - HelpText [en-US] = "Call the setup dialog of the selected printer."; }; FixedLine SV_PRINT_COPIES { @@ -366,6 +371,7 @@ ModalDialog SV_DLG_PRINT }; NumericField SV_PRINT_COPYCOUNT_FIELD { + HelpID = ".HelpID:vcl:PrintDialog:JobPage:Copies"; Pos = MAP_APPFONT( 10, 56 ); Size = MAP_APPFONT( 40, 12 ); Border = TRUE; @@ -373,7 +379,6 @@ ModalDialog SV_DLG_PRINT Minimum = 1; Maximum = 16384; Value = 1; - HelpText [en-US] = "Select the number of copies to be produced."; }; FixedImage SV_PRINT_COLLATE_IMAGE { @@ -382,10 +387,10 @@ ModalDialog SV_DLG_PRINT }; CheckBox SV_PRINT_COLLATE { + HelpID = ".HelpID:vcl:PrintDialog:JobPage:Collate"; Pos = MAP_APPFONT( 95, 45 ); Size = MAP_APPFONT( 70, 10 ); Text [en-US] = "Collate"; - HelpText [en-US] = "Select whether copies should be collated or not."; }; Image SV_PRINT_COLLATE_IMG @@ -413,6 +418,7 @@ ModalDialog SV_DLG_PRINT { Text [en-US] = "Options"; Hide = TRUE; + HelpID = ".HelpID:vcl:PrintDialog:OptPage"; FixedLine SV_PRINT_OPT_PRINT_FL { @@ -422,30 +428,31 @@ ModalDialog SV_DLG_PRINT }; CheckBox SV_PRINT_OPT_TOFILE { + HelpID = ".HelpID:vcl:PrintDialog:OptPage:ToFile"; Pos = MAP_APPFONT( 10, 20 ); Size = MAP_APPFONT( 200, 12 ); Text [en-US] = "Print to ~file"; - HelpText [en-US] = "Check to send output to a file instead of the actual printer."; }; CheckBox SV_PRINT_OPT_SINGLEJOBS { + HelpID = ".HelpID:vcl:PrintDialog:OptPage:SingleJobs"; Pos = MAP_APPFONT( 10, 35 ); Size = MAP_APPFONT( 200, 12 ); Text [en-US] = "~Create single print jobs for collated output"; - HelpText [en-US] = "Check to not rely on the printer to create collated copies but create a print job for each copy instead."; }; CheckBox SV_PRINT_OPT_REVERSE { + HelpID = ".HelpID:vcl:PrintDialog:OptPage:ToReverse"; Pos = MAP_APPFONT( 10, 50 ); Size = MAP_APPFONT( 200, 12 ); Text [en-US] = "Print in ~reverse page order"; - HelpText [en-US] = "Check to print pages in reverse order."; }; }; }; ModelessDialog SV_DLG_PRINT_PROGRESS { + HelpID = "vcl:ModelessDialog:SV_DLG_PRINT_PROGRESS"; Text [en-US] = "Printing"; Closeable = FALSE; Sizeable = FALSE; @@ -488,5 +495,6 @@ StringArray SV_PRINT_NATIVE_STRINGS < "Page number"; >; < "Number of pages"; >; < "More"; >; + < "Print selection only"; >; }; }; diff --git a/vcl/source/src/stdtext.src b/vcl/source/src/stdtext.src index 2c6574220a5f..1b95f7bb1d72 100644 --- a/vcl/source/src/stdtext.src +++ b/vcl/source/src/stdtext.src @@ -101,6 +101,11 @@ String SV_ACCESSERROR_TURNAROUND_MSG Text [ en-US ] = "The Java Access Bridge could not be started."; }; +String SV_ACCESSERROR_NO_FONTS +{ + Text [ en-US ] = "No fonts could be found on the system."; +}; + String SV_STDTEXT_ABOUT { Text [ en-US ] = "About %PRODUCTNAME"; 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/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/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; +} diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx index 13492f3d4a5c..076e36291ae6 100644 --- a/vcl/unx/gtk/a11y/atkutil.cxx +++ b/vcl/unx/gtk/a11y/atkutil.cxx @@ -77,11 +77,10 @@ atk_wrapper_focus_idle_handler (gpointer data) uno::Reference< accessibility::XAccessible > xAccessible = xNextFocusObject; if( xAccessible.get() == reinterpret_cast < accessibility::XAccessible * > (data) ) { + AtkObject *atk_obj = xAccessible.is() ? atk_object_wrapper_ref( xAccessible ) : NULL; // Gail does not notify focus changes to NULL, so do we .. - if( xAccessible.is() ) + if( atk_obj ) { - AtkObject *atk_obj = atk_object_wrapper_ref( xAccessible ); - #ifdef ENABLE_TRACING fprintf(stderr, "notifying focus event for %p\n", atk_obj); #endif @@ -92,7 +91,7 @@ atk_wrapper_focus_idle_handler (gpointer data) // also emit state-changed:focused event under the same condition. { AtkObjectWrapper* wrapper_obj = ATK_OBJECT_WRAPPER (atk_obj); - if( !wrapper_obj->mpText && wrapper_obj->mpContext ) + if( wrapper_obj && !wrapper_obj->mpText && wrapper_obj->mpContext ) { uno::Any any = wrapper_obj->mpContext->queryInterface( accessibility::XAccessibleText::static_type(NULL) ); if ( typelib_TypeClass_INTERFACE == any.pType->eTypeClass && diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index 2679f4a29c02..f308822df147 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -217,11 +217,12 @@ void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) { gint nMonitors = gdk_screen_get_n_monitors(pScreen); m_aXineramaScreens = std::vector<Rectangle>(); + m_aXineramaScreenIndexMap = std::vector<int>(nMonitors); for (gint i = 0; i < nMonitors; ++i) { GdkRectangle dest; gdk_screen_get_monitor_geometry(pScreen, i, &dest); - addXineramaScreenUnique( dest.x, dest.y, dest.width, dest.height ); + m_aXineramaScreenIndexMap[i] = addXineramaScreenUnique( dest.x, dest.y, dest.width, dest.height ); } m_bXinerama = m_aXineramaScreens.size() > 1; if( ! m_aFrames.empty() ) @@ -235,6 +236,26 @@ void GtkSalDisplay::monitorsChanged( GdkScreen* pScreen ) } } +extern "C" +{ + typedef gint(* screen_get_primary_monitor)(GdkScreen *screen); +} + +int GtkSalDisplay::GetDefaultMonitorNumber() const +{ + int n = 0; + GdkScreen* pScreen = gdk_display_get_screen( m_pGdkDisplay, m_nDefaultScreen ); +#if GTK_CHECK_VERSION(2,20,0) + n = m_aXineramaScreenIndexMap[gdk_screen_get_primary_monitor(pScreen)]; +#else + static screen_get_primary_monitor sym_gdk_screen_get_primary_monitor = + (screen_get_primary_monitor)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_primary_monitor" ); + if (sym_gdk_screen_get_primary_monitor) + n = m_aXineramaScreenIndexMap[sym_gdk_screen_get_primary_monitor( pScreen )]; +#endif + return n; +} + void GtkSalDisplay::initScreen( int nScreen ) const { if( nScreen < 0 || nScreen >= static_cast<int>(m_aScreens.size()) ) @@ -489,6 +510,7 @@ class GtkXLib : public SalXLib GSource *m_pUserEvent; oslMutex m_aDispatchMutex; oslCondition m_aDispatchCondition; + XIOErrorHandler m_aOrigGTKXIOErrorHandler; public: static gboolean timeoutFn(gpointer data); @@ -522,6 +544,7 @@ GtkXLib::GtkXLib() m_pUserEvent = NULL; m_aDispatchCondition = osl_createCondition(); m_aDispatchMutex = osl_createMutex(); + m_aOrigGTKXIOErrorHandler = NULL; } GtkXLib::~GtkXLib() @@ -535,6 +558,9 @@ GtkXLib::~GtkXLib() osl_setCondition( m_aDispatchCondition ); osl_destroyCondition( m_aDispatchCondition ); osl_destroyMutex( m_aDispatchMutex ); + + PopXErrorLevel(); + XSetIOErrorHandler (m_aOrigGTKXIOErrorHandler); } void GtkXLib::Init() @@ -596,6 +622,10 @@ void GtkXLib::Init() // init gtk/gdk gtk_init_check( &nParams, &pCmdLineAry ); + //gtk_init_check sets XError/XIOError handlers, we want our own one + m_aOrigGTKXIOErrorHandler = XSetIOErrorHandler ( (XIOErrorHandler)X11SalData::XIOErrorHdl ); + PushXErrorLevel( !!getenv( "SAL_IGNOREXERRORS" ) ); + for (i = 0; i < nParams; i++ ) g_free( pCmdLineAry[i] ); delete [] pCmdLineAry; @@ -630,9 +660,10 @@ void GtkXLib::Init() * the clipboard build another connection * to the xserver using $DISPLAY */ - char *pPutEnvIsBroken = g_strdup_printf( "DISPLAY=%s", - gdk_display_get_name( pGdkDisp ) ); - putenv( pPutEnvIsBroken ); + rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("DISPLAY")); + const gchar *name = gdk_display_get_name( pGdkDisp ); + rtl::OUString envValue(name, strlen(name), aEnc); + osl_setEnvironment(envVar.pData, envValue.pData); Display *pDisp = gdk_x11_display_get_xdisplay( pGdkDisp ); diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx index 68617c8c16be..2cb92ecd8292 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -39,6 +39,8 @@ #include <rtl/strbuf.hxx> +#include <rtl/uri.hxx> + #if OSL_DEBUG_LEVEL > 1 #include <stdio.h> #endif @@ -76,7 +78,7 @@ void GtkHookedYieldMutex::ThreadsLeave() #if OSL_DEBUG_LEVEL > 1 if( mnThreadId && - mnThreadId != NAMESPACE_VOS(OThread)::getCurrentIdentifier()) + mnThreadId != vos::OThread::getCurrentIdentifier()) fprintf( stderr, "\n\n--- A different thread owns the mutex ...---\n\n\n"); #endif @@ -216,9 +218,25 @@ extern "C" void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const rtl::OUString& rMimeType) { + rtl::OString sGtkURL; + rtl_TextEncoding aSystemEnc = osl_getThreadTextEncoding(); + if ((aSystemEnc == RTL_TEXTENCODING_UTF8) || (rFileUrl.compareToAscii( "file://", 7 ) != 0)) + sGtkURL = rtl::OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8); + else + { + //Non-utf8 locales are a bad idea if trying to work with non-ascii filenames + //Decode %XX components + rtl::OUString sDecodedUri = Uri::decode(rFileUrl.copy(7), rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8); + //Convert back to system locale encoding + rtl::OString sSystemUrl = rtl::OUStringToOString(sDecodedUri, aSystemEnc); + //Encode to an escaped ASCII-encoded URI + gchar *g_uri = g_filename_to_uri(sSystemUrl.getStr(), NULL, NULL); + sGtkURL = rtl::OString(g_uri); + g_free(g_uri); + } #if GTK_CHECK_VERSION(2,10,0) GtkRecentManager *manager = gtk_recent_manager_get_default (); - gtk_recent_manager_add_item (manager, rtl::OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8).getStr()); + gtk_recent_manager_add_item (manager, sGtkURL); (void)rMimeType; #else static getDefaultFnc sym_gtk_recent_manager_get_default = @@ -227,10 +245,7 @@ void GtkInstance::AddToRecentDocumentList(const rtl::OUString& rFileUrl, const r static addItemFnc sym_gtk_recent_manager_add_item = (addItemFnc)osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_recent_manager_add_item"); if (sym_gtk_recent_manager_get_default && sym_gtk_recent_manager_add_item) - { - sym_gtk_recent_manager_add_item(sym_gtk_recent_manager_get_default(), - rtl::OUStringToOString(rFileUrl, RTL_TEXTENCODING_UTF8).getStr()); - } + sym_gtk_recent_manager_add_item(sym_gtk_recent_manager_get_default(), sGtkURL); else X11SalInstance::AddToRecentDocumentList(rFileUrl, rMimeType); #endif diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index cdc72485ae6c..ff615f5ede74 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -411,6 +411,9 @@ void GtkData::initNWF( void ) // open first menu on F10 pSVData->maNWFData.mbOpenMenuOnF10 = true; + // omit GetNativeControl while painting (see brdwin.cxx) + pSVData->maNWFData.mbCanDrawWidgetAnySize = true; + int nScreens = GetX11SalData()->GetDisplay()->GetScreenCount(); gWidgetData = std::vector<NWFWidgetData>( nScreens ); for( int i = 0; i < nScreens; i++ ) @@ -617,7 +620,7 @@ BOOL GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP */ BOOL GtkSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ) { @@ -654,8 +657,8 @@ BOOL GtkSalGraphics::hitTestNativeControl( ControlType nType, else if ( nPart == PART_BUTTON_RIGHT ) nCounterPart = PART_BUTTON_LEFT; - aBackward = NWGetScrollButtonRect( m_nScreen, nPart, rControlRegion.GetBoundRect() ); - aForward = NWGetScrollButtonRect( m_nScreen, nCounterPart, rControlRegion.GetBoundRect() ); + aBackward = NWGetScrollButtonRect( m_nScreen, nPart, rControlRegion ); + aForward = NWGetScrollButtonRect( m_nScreen, nCounterPart, rControlRegion ); if ( has_backward && has_forward2 ) { @@ -727,20 +730,14 @@ BOOL GtkSalGraphics::hitTestNativeControl( ControlType nType, */ BOOL GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& rCaption ) { - if( (nType==CTRL_CHECKBOX) && (nPart==PART_ENTIRE_CONTROL) && - aValue.getTristateVal() == BUTTONVALUE_MIXED ) - { - return drawNativeMixedStateCheck( nType, nPart, rControlRegion, nState, aValue, rCaption ); - } - BOOL returnVal = FALSE; // get a GC with current clipping region set - SelectFont(); + GetFontGC(); // theme changed ? @@ -753,7 +750,7 @@ BOOL GtkSalGraphics::drawNativeControl( ControlType nType, GtkSalGraphics::bThemeChanged = FALSE; } - Rectangle aCtrlRect = rControlRegion.GetBoundRect(); + Rectangle aCtrlRect( rControlRegion ); Region aClipRegion( m_aClipRegion ); if( aClipRegion.IsNull() ) aClipRegion = aCtrlRect; @@ -895,55 +892,6 @@ BOOL GtkSalGraphics::drawNativeControl( ControlType nType, return( returnVal ); } -BOOL GtkSalGraphics::drawNativeMixedStateCheck( ControlType nType, - ControlPart nPart, - const Region& rControlRegion, - ControlState nState, - const ImplControlValue& aValue, - const OUString& rCaption ) -{ - // need to emulate something for mixed state - - // do this via pixmap since some themes don't care for regions - bool bOldNeedPixmapPaint = bNeedPixmapPaint; - bNeedPixmapPaint = true; - - Rectangle aCtrlRect = rControlRegion.GetBoundRect(); - BOOL returnVal = FALSE; - SelectFont(); - - // draw upper half in off state - const_cast<ImplControlValue&>(aValue).setTristateVal( BUTTONVALUE_OFF ); - XLIB_Region aRegion = XCreateRegion(); - XRectangle aXRect = { aCtrlRect.Left(), aCtrlRect.Top(), aCtrlRect.GetWidth(), aCtrlRect.GetHeight() }; - const unsigned short nH = aXRect.height/2; - aXRect.height -= nH; - XUnionRectWithRegion( &aXRect, aRegion, aRegion ); - SetClipRegion( pFontGC_, aRegion ); - XDestroyRegion( aRegion ); - - returnVal = drawNativeControl( nType, nPart, rControlRegion, nState, aValue, rCaption ); - - if( returnVal ) - { - // draw lower half in on state - const_cast<ImplControlValue&>(aValue).setTristateVal( BUTTONVALUE_ON ); - aXRect.y += nH; - aRegion = XCreateRegion(); - XUnionRectWithRegion( &aXRect, aRegion, aRegion ); - SetClipRegion( pFontGC_, aRegion ); - XDestroyRegion( aRegion ); - returnVal = drawNativeControl( nType, nPart, rControlRegion, nState, aValue, rCaption ); - } - - // clean up - bNeedPixmapPaint = bOldNeedPixmapPaint; - const_cast<ImplControlValue&>(aValue).setTristateVal( BUTTONVALUE_MIXED ); - SetClipRegion( pFontGC_ ); - return returnVal; -} - - /* * DrawNativeControlText() * @@ -956,7 +904,7 @@ BOOL GtkSalGraphics::drawNativeMixedStateCheck( ControlType nType, */ BOOL GtkSalGraphics::drawNativeControlText( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -980,20 +928,20 @@ BOOL GtkSalGraphics::drawNativeControlText( ControlType, */ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& rCaption, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion ) { BOOL returnVal = FALSE; if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL) - && (rControlRegion.GetBoundRect().GetWidth() > 16) - && (rControlRegion.GetBoundRect().GetHeight() > 16) ) + && (rControlRegion.GetWidth() > 16) + && (rControlRegion.GetHeight() > 16) ) { - rNativeBoundingRegion = NWGetButtonArea( m_nScreen, nType, nPart, rControlRegion.GetBoundRect(), + rNativeBoundingRegion = NWGetButtonArea( m_nScreen, nType, nPart, rControlRegion, nState, aValue, rCaption ); rNativeContentRegion = rControlRegion; @@ -1001,7 +949,7 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, } if ( (nType==CTRL_COMBOBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) ) { - rNativeBoundingRegion = NWGetComboBoxButtonRect( m_nScreen, nType, nPart, rControlRegion.GetBoundRect(), nState, + rNativeBoundingRegion = NWGetComboBoxButtonRect( m_nScreen, nType, nPart, rControlRegion, nState, aValue, rCaption ); rNativeContentRegion = rNativeBoundingRegion; @@ -1010,7 +958,7 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, if ( (nType==CTRL_SPINBOX) && ((nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) ) { - rNativeBoundingRegion = NWGetSpinButtonRect( m_nScreen, nType, nPart, rControlRegion.GetBoundRect(), nState, + rNativeBoundingRegion = NWGetSpinButtonRect( m_nScreen, nType, nPart, rControlRegion, nState, aValue, rCaption ); rNativeContentRegion = rNativeBoundingRegion; @@ -1018,7 +966,7 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, } if ( (nType==CTRL_LISTBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) ) { - rNativeBoundingRegion = NWGetListBoxButtonRect( m_nScreen, nType, nPart, rControlRegion.GetBoundRect(), nState, + rNativeBoundingRegion = NWGetListBoxButtonRect( m_nScreen, nType, nPart, rControlRegion, nState, aValue, rCaption ); rNativeContentRegion = rNativeBoundingRegion; @@ -1032,14 +980,14 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, (nPart==PART_BUTTON) )) { - rNativeBoundingRegion = NWGetToolbarRect( m_nScreen, nType, nPart, rControlRegion.GetBoundRect(), nState, aValue, rCaption ); + rNativeBoundingRegion = NWGetToolbarRect( m_nScreen, nType, nPart, rControlRegion, nState, aValue, rCaption ); rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; } if ( (nType==CTRL_SCROLLBAR) && ((nPart==PART_BUTTON_LEFT) || (nPart==PART_BUTTON_RIGHT) || (nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN) ) ) { - rNativeBoundingRegion = NWGetScrollButtonRect( m_nScreen, nPart, rControlRegion.GetBoundRect() ); + rNativeBoundingRegion = NWGetScrollButtonRect( m_nScreen, nPart, rControlRegion ); rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; @@ -1049,10 +997,10 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, NWEnsureGTKMenubar( m_nScreen ); GtkRequisition aReq; gtk_widget_size_request( gWidgetData[m_nScreen].gMenubarWidget, &aReq ); - Rectangle aMenuBarRect = rControlRegion.GetBoundRect(); + Rectangle aMenuBarRect = rControlRegion; aMenuBarRect = Rectangle( aMenuBarRect.TopLeft(), Size( aMenuBarRect.GetWidth(), aReq.height+1 ) ); - rNativeBoundingRegion = Region( aMenuBarRect ); + rNativeBoundingRegion = aMenuBarRect; rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; } @@ -1071,9 +1019,9 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, (char *)NULL ); rNativeBoundingRegion = rControlRegion; Rectangle aIndicatorRect( Point( 0, - (rControlRegion.GetBoundRect().GetHeight()-indicator_size)/2), + (rControlRegion.GetHeight()-indicator_size)/2), Size( indicator_size, indicator_size ) ); - rNativeContentRegion = Region( aIndicatorRect ); + rNativeContentRegion = aIndicatorRect; returnVal = TRUE; } } @@ -1090,9 +1038,9 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, indicator_size += 2*indicator_spacing; // guess overpaint of theme rNativeBoundingRegion = rControlRegion; Rectangle aIndicatorRect( Point( 0, - (rControlRegion.GetBoundRect().GetHeight()-indicator_size)/2), + (rControlRegion.GetHeight()-indicator_size)/2), Size( indicator_size, indicator_size ) ); - rNativeContentRegion = Region( aIndicatorRect ); + rNativeContentRegion = aIndicatorRect; returnVal = TRUE; } if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX) && nPart == PART_ENTIRE_CONTROL ) @@ -1101,10 +1049,11 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, GtkWidget* widget = gWidgetData[m_nScreen].gEditBoxWidget; GtkRequisition aReq; gtk_widget_size_request( widget, &aReq ); - Rectangle aEditRect = rControlRegion.GetBoundRect(); + Rectangle aEditRect = rControlRegion; + long nHeight = (aEditRect.GetHeight() > aReq.height+1) ? aEditRect.GetHeight() : aReq.height+1; aEditRect = Rectangle( aEditRect.TopLeft(), - Size( aEditRect.GetWidth(), aReq.height+1 ) ); - rNativeBoundingRegion = Region( aEditRect ); + Size( aEditRect.GetWidth(), nHeight ) ); + rNativeBoundingRegion = aEditRect; rNativeContentRegion = rNativeBoundingRegion; returnVal = TRUE; } @@ -1118,7 +1067,7 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, "slider-width", &slider_width, "slider-length", &slider_length, (char *)NULL); - Rectangle aRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( rControlRegion ); if( nPart == PART_THUMB_HORZ ) { aRect.Right() = aRect.Left() + slider_length - 1; @@ -1129,7 +1078,7 @@ BOOL GtkSalGraphics::getNativeControlRegion( ControlType nType, aRect.Bottom() = aRect.Top() + slider_length - 1; aRect.Right() = aRect.Left() + slider_width - 1; } - rNativeBoundingRegion = rNativeContentRegion = Region( aRect ); + rNativeBoundingRegion = rNativeContentRegion = aRect; returnVal = TRUE; } @@ -1378,7 +1327,8 @@ BOOL GtkSalGraphics::NWPaintGTKCheck( GdkDrawable* gdkDrawable, { GtkStateType stateType; GtkShadowType shadowType; - BOOL isChecked = (aValue.getTristateVal()==BUTTONVALUE_ON) ? TRUE : FALSE; + bool isChecked = (aValue.getTristateVal() == BUTTONVALUE_ON); + bool isInconsistent = (aValue.getTristateVal() == BUTTONVALUE_MIXED); GdkRectangle clipRect; gint x,y; @@ -1393,7 +1343,7 @@ BOOL GtkSalGraphics::NWPaintGTKCheck( GdkDrawable* gdkDrawable, y = rControlRectangle.Top() + (rControlRectangle.GetHeight()-indicator_size)/2; // Set the shadow based on if checked or not so we get a checkmark. - shadowType = isChecked ? GTK_SHADOW_IN : GTK_SHADOW_OUT; + shadowType = isChecked ? GTK_SHADOW_IN : isInconsistent ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_OUT; NWSetWidgetState( gWidgetData[m_nScreen].gCheckWidget, nState, stateType ); GTK_TOGGLE_BUTTON(gWidgetData[m_nScreen].gCheckWidget)->active = isChecked; @@ -1432,7 +1382,8 @@ BOOL GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart, const ImplControlValue& aValue, const OUString& ) { - ScrollbarValue* pScrollbarVal = (ScrollbarValue *)(aValue.getOptionalVal()); + OSL_ASSERT( aValue.getType() == CTRL_SCROLLBAR ); + const ScrollbarValue* pScrollbarVal = static_cast<const ScrollbarValue *>(&aValue); GdkPixmap* pixmap = NULL; Rectangle pixmapRect, scrollbarRect; GtkStateType stateType; @@ -1979,7 +1930,7 @@ BOOL GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart, Rectangle pixmapRect; GtkStateType stateType; GtkShadowType shadowType; - SpinbuttonValue * pSpinVal = (SpinbuttonValue *)(aValue.getOptionalVal()); + const SpinbuttonValue * pSpinVal = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue *>(&aValue) : NULL; Rectangle upBtnRect; ControlPart upBtnPart = PART_BUTTON_UP; ControlState upBtnState = CTRL_STATE_ENABLED; @@ -2290,10 +2241,10 @@ BOOL GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, const ImplControlValue& aValue, const OUString& ) { + OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM ); GdkPixmap * pixmap; Rectangle pixmapRect; Rectangle tabRect; - TabitemValue * pTabitemValue = (TabitemValue *)(aValue.getOptionalVal()); GtkStateType stateType; GtkShadowType shadowType; if( ! gWidgetData[ m_nScreen ].gCacheTabItems ) @@ -2309,9 +2260,8 @@ BOOL GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, if( !aCachePage.GetSize() ) aCachePage.SetSize( 1 ); - if ( !pTabitemValue && (nType==CTRL_TAB_ITEM) ) + if ( (nType == CTRL_TAB_ITEM) && (aValue.getType() != CTRL_TAB_ITEM) ) { - std::fprintf( stderr, "NWPaintGTKTabItem() received a NULL TabitemValue. Cannot draw native tab\n" ); return( false ); } @@ -2324,6 +2274,7 @@ BOOL GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart, pixmapRect = rControlRectangle; if ( nType == CTRL_TAB_ITEM ) { + const TabitemValue * pTabitemValue = static_cast<const TabitemValue *>(&aValue); if ( !pTabitemValue->isFirst() ) { // GTK+ tabs overlap on the right edge (the top tab obscures the @@ -2532,7 +2483,6 @@ BOOL GtkSalGraphics::NWPaintGTKToolbar( gint g_x=0, g_y=0, g_w=10, g_h=10; bool bPaintButton = true; GtkWidget* pButtonWidget = gWidgetData[m_nScreen].gToolbarButtonWidget; - const gchar* pButtonDetail = "button"; GdkRectangle clipRect; NWEnsureGTKToolbar( m_nScreen ); @@ -2571,9 +2521,9 @@ BOOL GtkSalGraphics::NWPaintGTKToolbar( gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(gWidgetData[m_nScreen].gHandleBoxWidget), shadowType ); // evaluate grip rect - ToolbarValue* pVal = (ToolbarValue*)aValue.getOptionalVal(); - if( pVal ) + if( aValue.getType() == CTRL_TOOLBAR ) { + const ToolbarValue* pVal = static_cast<const ToolbarValue*>(&aValue); g_x = pVal->maGripRect.Left(); g_y = pVal->maGripRect.Top(); g_w = pVal->maGripRect.GetWidth(); @@ -2591,13 +2541,18 @@ BOOL GtkSalGraphics::NWPaintGTKToolbar( { pButtonWidget = gWidgetData[m_nScreen].gToolbarToggleWidget; shadowType = GTK_SHADOW_IN; + stateType = GTK_STATE_ACTIVE; // special case stateType value for depressed toggle buttons // cf. gtk+/gtk/gtktogglebutton.c (gtk_toggle_button_update_state) - if( ! (nState & (CTRL_STATE_PRESSED|CTRL_STATE_ROLLOVER)) ) - stateType = GTK_STATE_ACTIVE; - pButtonDetail = "togglebutton"; + if( (nState & (CTRL_STATE_ROLLOVER|CTRL_STATE_PRESSED)) ) + { + stateType = GTK_STATE_PRELIGHT; + shadowType = GTK_SHADOW_OUT; + } bPaintButton = true; } + else + stateType = GTK_STATE_PRELIGHT; // only for bPaintButton = true, in which case always rollver is meant NWSetWidgetState( pButtonWidget, nState, stateType ); gtk_widget_ensure_style( pButtonWidget ); @@ -2655,7 +2610,7 @@ BOOL GtkSalGraphics::NWPaintGTKToolbar( stateType, shadowType, &clipRect, - pButtonWidget, pButtonDetail, x, y, w, h ); + pButtonWidget, "button", x, y, w, h ); } } } @@ -3044,20 +2999,19 @@ BOOL GtkSalGraphics::NWPaintGTKSlider( ControlState nState, const ImplControlValue& rValue, const OUString& ) { + OSL_ASSERT( rValue.getType() == CTRL_SLIDER ); NWEnsureGTKSlider( m_nScreen ); gint w, h; w = rControlRectangle.GetWidth(); h = rControlRectangle.GetHeight(); - SliderValue* pVal = (SliderValue*)rValue.getOptionalVal(); + const SliderValue* pVal = static_cast<const SliderValue*>(&rValue); GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle ); if( ! pixmap ) return FALSE; - (void)pVal; - GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap ); GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA) ? GTK_WIDGET(gWidgetData[m_nScreen].gHScale) @@ -3733,7 +3687,8 @@ GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect ) BOOL GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect ) { // The GC can't be null, otherwise we'd have no clip region - if( SelectFont() == NULL ) + GC aFontGC = GetFontGC(); + if( aFontGC == NULL ) { std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" ); return( FALSE ); @@ -3748,7 +3703,7 @@ BOOL GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRe gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ), gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ), GetDrawable(), m_nScreen, GetVisual().GetDepth(), - SelectFont(), + aFontGC, 0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() ); return( TRUE ); diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 11d567c85098..9181ee3fd40d 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -1353,11 +1353,7 @@ void GtkSalFrame::Show( BOOL bVisible, BOOL bNoActivate ) // // i.e. having a time < that of the toplevel frame means that the toplevel frame gets unfocused. // awesome. - bool bHack = - getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") || - getDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("compiz") - ; - if( nUserTime == 0 && bHack ) + if( nUserTime == 0 ) { /* #i99360# ugly workaround an X11 library bug */ nUserTime= getDisplay()->GetLastUserEventTime( true ); @@ -1365,7 +1361,7 @@ void GtkSalFrame::Show( BOOL bVisible, BOOL bNoActivate ) } lcl_set_user_time( GTK_WIDGET(m_pWindow)->window, nUserTime ); - if( bHack && ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) + if( ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) m_bSetFocusOnMap = true; gtk_widget_show( m_pWindow ); @@ -1452,7 +1448,7 @@ void GtkSalFrame::setMinMaxSize() aHints |= GDK_HINT_MAX_SIZE; } } - if( m_bFullscreen ) + if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) { aGeo.max_width = m_aMaxSize.Width(); aGeo.max_height = m_aMaxSize.Height(); @@ -1832,7 +1828,11 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) // workaround different legacy version window managers have different opinions about // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); + } if( bVisible ) Show( TRUE ); } @@ -1863,11 +1863,8 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) { if( bFullScreen ) { - if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) - { - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); - } + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); gtk_window_fullscreen( GTK_WINDOW(m_pWindow) ); moveToScreen( nScreen ); Size aScreenSize = pDisp->GetScreenSize( m_nScreen ); @@ -1879,11 +1876,8 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) else { gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); - if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) - { - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); - } + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); moveToScreen( nScreen ); } } @@ -2849,12 +2843,52 @@ gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer f return FALSE; } +IMPL_LINK( GtkSalFrame, ImplDelayedFullScreenHdl, void*, EMPTYARG ) +{ + Atom nStateAtom = getDisplay()->getWMAdaptor()->getAtom(vcl_sal::WMAdaptor::NET_WM_STATE); + Atom nFSAtom = getDisplay()->getWMAdaptor()->getAtom(vcl_sal::WMAdaptor::NET_WM_STATE_FULLSCREEN ); + if( nStateAtom && nFSAtom ) + { + /* #i110881# workaround a gtk issue (see https://bugzilla.redhat.com/show_bug.cgi?id=623191#c8) + gtk_window_fullscreen can fail due to a race condition, request an additional status change + to fullscreen to be safe + */ + XEvent aEvent; + aEvent.type = ClientMessage; + aEvent.xclient.display = getDisplay()->GetDisplay(); + aEvent.xclient.window = GDK_WINDOW_XWINDOW(m_pWindow->window); + aEvent.xclient.message_type = nStateAtom; + aEvent.xclient.format = 32; + aEvent.xclient.data.l[0] = 1; + aEvent.xclient.data.l[1] = nFSAtom; + aEvent.xclient.data.l[2] = 0; + aEvent.xclient.data.l[3] = 0; + aEvent.xclient.data.l[4] = 0; + XSendEvent( getDisplay()->GetDisplay(), + getDisplay()->GetRootWindow( m_nScreen ), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &aEvent + ); + } + + return 0; +} + gboolean GtkSalFrame::signalMap( GtkWidget*, GdkEvent*, gpointer frame ) { GtkSalFrame* pThis = (GtkSalFrame*)frame; GTK_YIELD_GRAB(); + if( pThis->m_bFullscreen ) + { + /* #i110881# workaorund a gtk issue (see https://bugzilla.redhat.com/show_bug.cgi?id=623191#c8) + gtk_window_fullscreen can run into a race condition with the window's showstate + */ + Application::PostUserEvent( LINK( pThis, GtkSalFrame, ImplDelayedFullScreenHdl ) ); + } + bool bSetFocus = pThis->m_bSetFocusOnMap; pThis->m_bSetFocusOnMap = false; if( ImplGetSVData()->mbIsTestTool ) @@ -3305,7 +3339,9 @@ void GtkSalFrame::IMHandler::updateIMSpotLocation() aArea.y = aPosEvent.mnY; aArea.width = aPosEvent.mnWidth; aArea.height = aPosEvent.mnHeight; + m_pFrame->getDisplay()->GetXLib()->PushXErrorLevel( true ); gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); + m_pFrame->getDisplay()->GetXLib()->PopXErrorLevel(); } void GtkSalFrame::IMHandler::setInputContext( SalInputContext* ) @@ -3757,8 +3793,21 @@ gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint if (xText.is()) { sal_uInt32 nPosition = xText->getCaretPosition(); - xText->deleteText(nPosition + offset, nPosition + offset + nchars); - return TRUE; + // --> OD 2010-06-04 #i111768# - apply patch from kstribley: + // range checking +// xText->deleteText(nPosition + offset, nPosition + offset + nchars); + sal_Int32 nDeletePos = nPosition + offset; + sal_Int32 nDeleteEnd = nDeletePos + nchars; + if (nDeletePos < 0) + nDeletePos = 0; + if (nDeleteEnd < 0) + nDeleteEnd = 0; + if (nDeleteEnd > xText->getCharacterCount()) + nDeleteEnd = xText->getCharacterCount(); + + xText->deleteText(nDeletePos, nDeleteEnd); + // <-- + return TRUE; } return FALSE; diff --git a/vcl/unx/gtk/window/gtkobject.cxx b/vcl/unx/gtk/window/gtkobject.cxx index 2a2bbe78078a..c5f5a168f653 100644 --- a/vcl/unx/gtk/window/gtkobject.cxx +++ b/vcl/unx/gtk/window/gtkobject.cxx @@ -209,3 +209,8 @@ void GtkSalObject::signalDestroy( GtkObject* pObj, gpointer object ) pThis->m_pSocket = NULL; } } + +void GtkSalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/unx/headless/svpdummies.cxx b/vcl/unx/headless/svpdummies.cxx index 5983ff18c34f..0a67b147804a 100644 --- a/vcl/unx/headless/svpdummies.cxx +++ b/vcl/unx/headless/svpdummies.cxx @@ -61,6 +61,7 @@ void SvpSalObject::GrabFocus() {} void SvpSalObject::SetBackground() {} void SvpSalObject::SetBackground( SalColor ) {} const SystemEnvData* SvpSalObject::GetSystemData() const { return &m_aSystemChildData; } +void SvpSalObject::InterceptChildWindowKeyDown( sal_Bool ) {} // SalI18NImeStatus SvpImeStatus::~SvpImeStatus() {} diff --git a/vcl/unx/headless/svpdummies.hxx b/vcl/unx/headless/svpdummies.hxx index febf7eef6bbe..ea7667ce51ca 100644 --- a/vcl/unx/headless/svpdummies.hxx +++ b/vcl/unx/headless/svpdummies.hxx @@ -58,6 +58,8 @@ public: virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; class SvpImeStatus : public SalI18NImeStatus diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx index e65c9faf1432..68d8be7cb4eb 100644 --- a/vcl/unx/headless/svpgdi.cxx +++ b/vcl/unx/headless/svpgdi.cxx @@ -382,7 +382,7 @@ void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, dbgOut( m_aDevice ); } -bool SvpSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/ ) +bool SvpSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon&, double /*fTransparency*/, const ::basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/ ) { // TODO: implement and advertise OutDevSupport_B2DDraw support return false; diff --git a/vcl/unx/headless/svpgdi.hxx b/vcl/unx/headless/svpgdi.hxx index 132dafaa9adf..93ec080d0136 100644 --- a/vcl/unx/headless/svpgdi.hxx +++ b/vcl/unx/headless/svpgdi.hxx @@ -86,9 +86,9 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); @@ -121,7 +121,7 @@ public: virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ); virtual void drawRect( long nX, long nY, long nWidth, long nHeight ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ); virtual void drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ); virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); virtual void drawPolyPolygon( sal_uInt32 nPoly, diff --git a/vcl/unx/headless/svpinst.cxx b/vcl/unx/headless/svpinst.cxx index 466b56868900..09e359ca3f71 100644 --- a/vcl/unx/headless/svpinst.cxx +++ b/vcl/unx/headless/svpinst.cxx @@ -38,7 +38,7 @@ #include <vcl/salframe.hxx> #include <vcl/svdata.hxx> -#include <vcl/salatype.hxx> +#include <vcl/apptypes.hxx> #include <vcl/saldatabasic.hxx> #include <sal/types.h> @@ -302,7 +302,7 @@ vos::IMutex* SvpSalInstance::GetYieldMutex() ULONG SvpSalInstance::ReleaseYieldMutex() { if ( m_aYieldMutex.GetThreadId() == - NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + vos::OThread::getCurrentIdentifier() ) { ULONG nCount = m_aYieldMutex.GetAcquireCount(); ULONG n = nCount; @@ -327,6 +327,19 @@ void SvpSalInstance::AcquireYieldMutex( ULONG nCount ) } } +bool SvpSalInstance::CheckYieldMutex() +{ + bool bRet = true; + + if ( m_aYieldMutex.GetThreadId() != + vos::OThread::getCurrentIdentifier() ) + { + bRet = false; + } + + return bRet; +} + void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { // first, check for already queued events. @@ -419,24 +432,6 @@ bool SvpSalInstance::AnyInput( USHORT nType ) return false; } -SalMenu* SvpSalInstance::CreateMenu( BOOL ) -{ - return NULL; -} - -void SvpSalInstance::DestroyMenu( SalMenu* ) -{ -} - -SalMenuItem* SvpSalInstance::CreateMenuItem( const SalItemParams* ) -{ - return NULL; -} - -void SvpSalInstance::DestroyMenuItem( SalMenuItem* ) -{ -} - SalSession* SvpSalInstance::CreateSalSession() { return NULL; @@ -464,13 +459,13 @@ SvpSalYieldMutex::SvpSalYieldMutex() void SvpSalYieldMutex::acquire() { OMutex::acquire(); - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; } void SvpSalYieldMutex::release() { - if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + if ( mnThreadId == vos::OThread::getCurrentIdentifier() ) { if ( mnCount == 1 ) mnThreadId = 0; @@ -483,7 +478,7 @@ sal_Bool SvpSalYieldMutex::tryToAcquire() { if ( OMutex::tryToAcquire() ) { - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; return sal_True; } diff --git a/vcl/unx/headless/svpinst.hxx b/vcl/unx/headless/svpinst.hxx index 284a2d11cd82..02d5e3fa9494 100644 --- a/vcl/unx/headless/svpinst.hxx +++ b/vcl/unx/headless/svpinst.hxx @@ -46,11 +46,11 @@ // SalYieldMutex // ------------------------------------------------------------------------- -class SvpSalYieldMutex : public NAMESPACE_VOS(OMutex) +class SvpSalYieldMutex : public vos::OMutex { protected: ULONG mnCount; - NAMESPACE_VOS(OThread)::TThreadIdentifier mnThreadId; + vos::OThread::TThreadIdentifier mnThreadId; public: SvpSalYieldMutex(); @@ -60,7 +60,7 @@ public: virtual sal_Bool tryToAcquire(); ULONG GetAcquireCount() const { return mnCount; } - NAMESPACE_VOS(OThread)::TThreadIdentifier GetThreadId() const { return mnThreadId; } + vos::OThread::TThreadIdentifier GetThreadId() const { return mnThreadId; } }; // --------------- @@ -176,6 +176,7 @@ public: virtual vos::IMutex* GetYieldMutex(); virtual ULONG ReleaseYieldMutex(); virtual void AcquireYieldMutex( ULONG nCount ); + virtual bool CheckYieldMutex(); // wait next event and dispatch // must returned by UserEvent (SalFrame::PostEvent) @@ -183,12 +184,6 @@ public: virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); virtual bool AnyInput( USHORT nType ); - // Menues - virtual SalMenu* CreateMenu( BOOL bMenuBar ); - virtual void DestroyMenu( SalMenu* pMenu); - virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); - virtual void DestroyMenuItem( SalMenuItem* pItem ); - // may return NULL to disable session management virtual SalSession* CreateSalSession(); diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx index 7f551051c1a7..c7b1f4f41fca 100644 --- a/vcl/unx/headless/svppspgraphics.cxx +++ b/vcl/unx/headless/svppspgraphics.cxx @@ -323,7 +323,7 @@ void PspGraphics::drawPolyPolygon( sal_uInt32 nPoly, m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, (const Point**)pPtAry); } -bool PspGraphics::drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/ ) +bool PspGraphics::drawPolyLine( const ::basegfx::B2DPolygon&, double /*fTransparency*/, const ::basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/ ) { // TODO: implement and advertise OutDevSupport_B2DDraw support return false; @@ -683,16 +683,13 @@ void PspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) DrawPrinterLayout( rLayout, *m_pPrinterGfx, true ); } -ImplFontCharMap* PspGraphics::GetImplFontCharMap() const +const ImplFontCharMap* PspGraphics::GetImplFontCharMap() const { - // TODO: get ImplFontCharMap directly from fonts if( !m_pServerFont[0] ) return NULL; - CmapResult aCmapResult; - if( !m_pServerFont[0]->GetFontCodeRanges( aCmapResult ) ) - return NULL; - return new ImplFontCharMap( aCmapResult ); + const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap(); + return pIFCMap; } USHORT PspGraphics::SetFont( ImplFontSelectData *pEntry, int nFallbackLevel ) @@ -792,7 +789,7 @@ void PspGraphics::GetDevFontSubstList( OutputDevice* pOutDev ) } } -void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric ) +void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int ) { const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); psp::PrintFontInfo aInfo; diff --git a/vcl/unx/headless/svppspgraphics.hxx b/vcl/unx/headless/svppspgraphics.hxx index 82ba613615cb..138198239621 100644 --- a/vcl/unx/headless/svppspgraphics.hxx +++ b/vcl/unx/headless/svppspgraphics.hxx @@ -105,9 +105,9 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); @@ -142,7 +142,7 @@ public: virtual void drawPolyLine( ULONG nPoints, const SalPoint* pPtAry ); virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin ); virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ); diff --git a/vcl/unx/headless/svptext.cxx b/vcl/unx/headless/svptext.cxx index ecb8b11b7e04..dff1fd4d6ca7 100644 --- a/vcl/unx/headless/svptext.cxx +++ b/vcl/unx/headless/svptext.cxx @@ -240,12 +240,15 @@ USHORT SvpSalGraphics::SetFont( ImplFontSelectData* pIFSD, int nFallbackLevel ) // --------------------------------------------------------------------------- -void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) +void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { - if( m_pServerFont[0] != NULL ) + if( nFallbackLevel >= MAX_FALLBACK ) + return; + + if( m_pServerFont[nFallbackLevel] != NULL ) { long rDummyFactor; - m_pServerFont[0]->FetchFontMetric( *pMetric, rDummyFactor ); + m_pServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor ); } } @@ -269,15 +272,13 @@ ULONG SvpSalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) // --------------------------------------------------------------------------- -ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const +const ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const { if( !m_pServerFont[0] ) return NULL; - CmapResult aCmapResult; - if( !m_pServerFont[0]->GetFontCodeRanges( aCmapResult ) ) - return NULL; - return new ImplFontCharMap( aCmapResult ); + const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap(); + return pIFCMap; } // --------------------------------------------------------------------------- diff --git a/vcl/unx/inc/i18n_im.hxx b/vcl/unx/inc/i18n_im.hxx index 297bc8edec17..a22a57b976c8 100644 --- a/vcl/unx/inc/i18n_im.hxx +++ b/vcl/unx/inc/i18n_im.hxx @@ -56,10 +56,6 @@ public: Bool FilterEvent( XEvent *pEvent, XLIB_Window window ); Bool AddConnectionWatch (Display *pDisplay, void *pConnectionHandler); - #ifdef _USE_PRINT_EXTENSION_ - void Invalidate() { mbUseable = False; } - #endif - SalI18N_InputMethod(); ~SalI18N_InputMethod(); }; diff --git a/vcl/unx/inc/plugins/gtk/gtkdata.hxx b/vcl/unx/inc/plugins/gtk/gtkdata.hxx index d4dec957a6b3..b650cffbae8b 100644 --- a/vcl/unx/inc/plugins/gtk/gtkdata.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkdata.hxx @@ -59,6 +59,8 @@ class GtkSalDisplay : public SalDisplay GdkDisplay* m_pGdkDisplay; GdkCursor *m_aCursors[ POINTER_COUNT ]; bool m_bStartupCompleted; + std::vector< int > m_aXineramaScreenIndexMap; + GdkCursor* getFromXPM( const char *pBitmap, const char *pMask, int nWidth, int nHeight, int nXHot, int nYHot ); public: @@ -73,6 +75,8 @@ public: virtual long Dispatch( XEvent *pEvent ); virtual void initScreen( int nScreen ) const; + virtual int GetDefaultMonitorNumber() const; + static GdkFilterReturn filterGdkEvent( GdkXEvent* sys_event, GdkEvent* event, gpointer data ); diff --git a/vcl/unx/inc/plugins/gtk/gtkframe.hxx b/vcl/unx/inc/plugins/gtk/gtkframe.hxx index 18dd476fc2c4..d47e5fb50fca 100644 --- a/vcl/unx/inc/plugins/gtk/gtkframe.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkframe.hxx @@ -38,6 +38,8 @@ #include <vcl/salframe.hxx> #include <vcl/sysdata.hxx> +#include "tools/link.hxx" + #include <list> #include <vector> @@ -265,6 +267,8 @@ class GtkSalFrame : public SalFrame void setMinMaxSize(); void createNewWindow( XLIB_Window aParent, bool bXEmbed, int nScreen ); void askForXEmbedFocus( sal_Int32 nTimecode ); + + DECL_LINK( ImplDelayedFullScreenHdl, void* ); public: GtkSalFrame( SalFrame* pParent, ULONG nStyle ); GtkSalFrame( SystemParentData* pSysData ); diff --git a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx index 065b5435eeb0..38c79b3e11df 100644 --- a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx @@ -63,17 +63,17 @@ public: // native widget methods virtual BOOL IsNativeControlSupported( ControlType nType, ControlPart nPart ); - virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); - virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& rCaption ); - virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& rCaption ); - virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, + virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& rCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); //helper methods for frame's UpdateSettings void updateSettings( AllSettings& rSettings ); @@ -178,10 +178,6 @@ protected: const clipList& rClipList, ControlState nState, const ImplControlValue& aValue, const OUString& rCaption ); - - BOOL drawNativeMixedStateCheck( ControlType nType, ControlPart nPart, const Region& rControlRegion, - ControlState nState, const ImplControlValue& aValue, - const rtl::OUString& rCaption ); }; #endif // _VCL_GTKGDI_HXX diff --git a/vcl/unx/inc/plugins/gtk/gtkobject.hxx b/vcl/unx/inc/plugins/gtk/gtkobject.hxx index ea740249f1c6..9d3f235b8894 100644 --- a/vcl/unx/inc/plugins/gtk/gtkobject.hxx +++ b/vcl/unx/inc/plugins/gtk/gtkobject.hxx @@ -64,6 +64,7 @@ public: virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/unx/inc/pspgraphics.h b/vcl/unx/inc/pspgraphics.h index 2eae73cdaa86..d4f5a9f156e0 100644 --- a/vcl/unx/inc/pspgraphics.h +++ b/vcl/unx/inc/pspgraphics.h @@ -102,9 +102,9 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); virtual ULONG GetKernPairs( ULONG nMaxPairs, ImplKernPairData* ); - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); @@ -142,7 +142,7 @@ public: const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const basegfx::B2DPolygon&, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin); + virtual bool drawPolyLine( const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin); virtual sal_Bool drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); diff --git a/vcl/unx/inc/saldata.hxx b/vcl/unx/inc/saldata.hxx index 7e38e0a89bf2..939437060750 100644 --- a/vcl/unx/inc/saldata.hxx +++ b/vcl/unx/inc/saldata.hxx @@ -63,6 +63,7 @@ protected: SalDisplay *m_pSalDisplay; pthread_t hMainThread_; rtl::OUString maLocalHostName; + rtl::OUString maUnicodeAccumulator; public: X11SalData(); @@ -90,6 +91,7 @@ public: const rtl::OUString& GetLocalHostName() const { return maLocalHostName; } + rtl::OUString& GetUnicodeAccumulator() { return maUnicodeAccumulator; } static int XErrorHdl( Display*, XErrorEvent* ); static int XIOErrorHdl( Display* ); diff --git a/vcl/unx/inc/saldisp.hxx b/vcl/unx/inc/saldisp.hxx index 3734cbec6ef7..89efad3cde4d 100644 --- a/vcl/unx/inc/saldisp.hxx +++ b/vcl/unx/inc/saldisp.hxx @@ -269,15 +269,10 @@ public: class SalI18N_InputMethod; class SalI18N_KeyboardExtension; -class XlfdStorage; -class ExtendedFontStruct; -class ExtendedXlfd; class AttributeProvider; class SalUnicodeConverter; class SalConverterCache; -DECLARE_LIST( SalFontCache, ExtendedFontStruct* ) - extern "C" { struct SnDisplay; struct SnLauncheeContext; @@ -349,8 +344,6 @@ protected: SalI18N_KeyboardExtension *mpKbdExtension; AttributeProvider *mpFactory; - XlfdStorage *mpFontList; - const ExtendedXlfd *mpFallbackFactory; Display *pDisp_; // X Display int m_nDefaultScreen; // XDefaultScreen @@ -374,8 +367,6 @@ protected: XLIB_Cursor aPointerCache_[POINTER_COUNT]; SalFrame* m_pCapture; - mutable SalFontCache* m_pFontCache; - // Keyboard BOOL bNumLockFromXS_; // Num Lock handled by X Server int nNumLockIndex_; // modifier index in modmap @@ -397,7 +388,6 @@ protected: mutable XLIB_Time m_nLastUserEventTime; // mutable because changed on first access - void DestroyFontCache(); virtual long Dispatch( XEvent *pEvent ) = 0; void InitXinerama(); void InitRandR( XLIB_Window aRoot ) const; @@ -405,7 +395,7 @@ protected: int processRandREvent( XEvent* ); void doDestruct(); - void addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ); + int addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ); public: static SalDisplay *GetSalDisplay( Display* display ); static BOOL BestVisual( Display *pDisp, @@ -434,14 +424,6 @@ public: void PrintEvent( const ByteString &rComment, XEvent *pEvent ) const; - XlfdStorage* GetXlfdList() const; - ExtendedFontStruct* - GetFont( const ExtendedXlfd *pFont, - const Size& rPixelSize, sal_Bool bVertical ) const; - const ExtendedXlfd* - GetFallbackFactory() - { return mpFallbackFactory; } - void Beep() const; void ModifierMapping(); @@ -475,6 +457,7 @@ public: XLIB_Window GetDrawable( int nScreen ) const { return getDataForScreen( nScreen ).m_aRefWindow; } Display *GetDisplay() const { return pDisp_; } int GetDefaultScreenNumber() const { return m_nDefaultScreen; } + virtual int GetDefaultMonitorNumber() const { return 0; } const Size& GetScreenSize( int nScreen ) const { return getDataForScreen( nScreen ).m_aSize; } srv_vendor_t GetServerVendor() const { return meServerVendor; } void SetServerVendor() { meServerVendor = sal_GetServerVendor(pDisp_); } diff --git a/vcl/unx/inc/salframe.h b/vcl/unx/inc/salframe.h index 6f962c9a13b3..9786bac76f35 100644 --- a/vcl/unx/inc/salframe.h +++ b/vcl/unx/inc/salframe.h @@ -108,6 +108,8 @@ class VCL_DLLPUBLIC X11SalFrame : public SalFrame bool m_bXEmbed; int nVisibility_; int m_nWorkArea; + bool m_bSetFocusOnMap; + int nScreenSaversTimeout_; Rectangle maPaintRegion; @@ -206,6 +208,10 @@ public: bool isMapped() const { return bMapped_; } bool hasFocus() const { return mbInputFocus; } + void beginUnicodeSequence(); + bool appendUnicodeSequence( sal_Unicode ); + bool endUnicodeSequence(); + virtual SalGraphics* GetGraphics(); virtual void ReleaseGraphics( SalGraphics* pGraphics ); diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h index 6ccea2c4a00c..8af62a5c6607 100644 --- a/vcl/unx/inc/salgdi.h +++ b/vcl/unx/inc/salgdi.h @@ -28,18 +28,15 @@ #ifndef _SV_SALGDI_H #define _SV_SALGDI_H - -// -=-= exports -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -class SalFontCacheItem; - // -=-= includes -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "salstd.hxx" #include "vcl/salgdi.hxx" #include "vcl/salgtype.hxx" #include "tools/fract.hxx" #include "vcl/dllapi.h" +#include <vcl/vclenum.hxx> +#include <vcl/sallayout.hxx> #include <deque> -#include "xfont.hxx" // -=-= forwards -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= struct ImplFontMetricData; @@ -100,7 +97,6 @@ protected: Pixel nPenPixel_; GC pFontGC_; // Font attributes - ExtendedFontStructRef mXFont[ MAX_FALLBACK ]; ServerFont* mpServerFont[ MAX_FALLBACK ]; SalColor nTextColor_; @@ -185,7 +181,7 @@ protected: const SalBitmap &rTransparentBitmap, SalColor nTransparentColor ); - GC SelectFont(); + GC GetFontGC(); bool setFont( const ImplFontSelectData* pEntry, int nFallbackLevel ); void drawMaskedBitmap( const SalTwoRect* pPosAry, @@ -193,9 +189,6 @@ protected: const SalBitmap& rTransparentBitmap ); protected: - void DrawStringUCS2MB( ExtendedFontStruct& rFont, const Point&, - const sal_Unicode* pStr, int nLength ); - void DrawPrinterString( const SalLayout& ); void DrawServerFontString( const ServerFontLayout& ); @@ -253,9 +246,9 @@ public: virtual void SetTextColor( SalColor nSalColor ); virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); virtual ULONG GetKernPairs( ULONG nMaxPairs, ImplKernPairData* ); - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; virtual void GetDevFontList( ImplDevFontList* ); virtual void GetDevFontSubstList( OutputDevice* ); virtual bool AddTempDevFont( ImplDevFontList*, const String& rFileURL, const String& rFontName ); @@ -294,7 +287,7 @@ public: const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin ); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin ); virtual bool drawFilledTrapezoids( const ::basegfx::B2DTrapezoid*, int nTrapCount, double fTransparency ); #if 1 // TODO: remove these obselete methods @@ -386,19 +379,8 @@ inline Pixel X11SalGraphics::GetPixel( SalColor nSalColor ) const #ifdef DBG_UTIL #define stderr0( s ) fprintf( stderr, s ) -#define stderr1( s, a ) fprintf( stderr, s, a ) -#define stderr2( s, a, b ) fprintf( stderr, s, a, b ) -#define stderr3( s, a, b, c ) fprintf( stderr, s, a, b, c ) -#define stdass0( b ) (void)( !(b) \ - ? fprintf( stderr, "\"%s\" (%s line %d)\n", \ - #b, __FILE__, __LINE__ ) \ - : 0 ) #else #define stderr0( s ) ; -#define stderr1( s, a ) ; -#define stderr2( s, a, b ) ; -#define stderr3( s, a, b, c ) ; -#define stdass0( b ) ; #endif #endif // _SV_SALGDI_H diff --git a/vcl/unx/inc/salinst.h b/vcl/unx/inc/salinst.h index d73d67f81425..133f0bf6037f 100644 --- a/vcl/unx/inc/salinst.h +++ b/vcl/unx/inc/salinst.h @@ -39,11 +39,11 @@ #include <vcl/dllapi.h> #include <vcl/salinst.hxx> -class VCL_DLLPUBLIC SalYieldMutex : public NAMESPACE_VOS(OMutex) +class VCL_DLLPUBLIC SalYieldMutex : public vos::OMutex { protected: ULONG mnCount; - NAMESPACE_VOS(OThread)::TThreadIdentifier mnThreadId; + vos::OThread::TThreadIdentifier mnThreadId; public: SalYieldMutex(); @@ -53,7 +53,7 @@ public: virtual sal_Bool tryToAcquire(); ULONG GetAcquireCount() const { return mnCount; } - NAMESPACE_VOS(OThread)::TThreadIdentifier GetThreadId() const { return mnThreadId; } + vos::OThread::TThreadIdentifier GetThreadId() const { return mnThreadId; } }; // -=-= SalInstanceData =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -102,13 +102,10 @@ public: virtual vos::IMutex* GetYieldMutex(); virtual ULONG ReleaseYieldMutex(); virtual void AcquireYieldMutex( ULONG nCount ); + virtual bool CheckYieldMutex(); virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); virtual bool AnyInput( USHORT nType ); - virtual SalMenu* CreateMenu( BOOL bMenuBar ); - virtual void DestroyMenu( SalMenu* pMenu); - virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); - virtual void DestroyMenuItem( SalMenuItem* pItem ); virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ); void FillFontPathList( std::list< rtl::OString >& o_rFontPaths ); diff --git a/vcl/unx/inc/salobj.h b/vcl/unx/inc/salobj.h index fa9f1309c8ca..d7d9334f281b 100644 --- a/vcl/unx/inc/salobj.h +++ b/vcl/unx/inc/salobj.h @@ -98,6 +98,7 @@ public: virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/unx/inc/salprn.h b/vcl/unx/inc/salprn.h index fa68f1b38e73..6e6ca0a2f1cc 100644 --- a/vcl/unx/inc/salprn.h +++ b/vcl/unx/inc/salprn.h @@ -71,6 +71,7 @@ public: bool m_bFax:1; bool m_bPdf:1; bool m_bSwallowFaxNo:1; + bool m_bIsPDFWriterJob:1; PspGraphics* m_pGraphics; psp::PrinterJob m_aPrintJob; psp::JobData m_aJobData; @@ -91,6 +92,11 @@ public: bool bCollate, bool bDirect, ImplJobSetup* pSetupData ); + virtual BOOL StartJob( const String*, + const String&, + const String&, + ImplJobSetup*, + vcl::PrinterController& i_rController ); virtual BOOL EndJob(); virtual BOOL AbortJob(); virtual SalGraphics* StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData ); diff --git a/vcl/unx/inc/wmadaptor.hxx b/vcl/unx/inc/wmadaptor.hxx index cbedede2cc99..e8620db29c6f 100644 --- a/vcl/unx/inc/wmadaptor.hxx +++ b/vcl/unx/inc/wmadaptor.hxx @@ -165,6 +165,8 @@ protected: bool m_bLegacyPartialFullscreen; int m_nWinGravity; int m_nInitWinGravity; + bool m_bWMshouldSwitchWorkspace; + bool m_bWMshouldSwitchWorkspaceInit; WMAdaptor( SalDisplay * ) ; @@ -177,6 +179,7 @@ protected: */ virtual bool isValid() const; + bool getWMshouldSwitchWorkspace() const; public: virtual ~WMAdaptor(); @@ -214,8 +217,9 @@ public: /* * attemp to switch the desktop to a certain workarea + * if bConsiderWM is true, then on some WMs the call will not result in any action */ - void switchToWorkArea( int nWorkArea ) const; + void switchToWorkArea( int nWorkArea, bool bConsiderWM = true ) const; /* * sets window title diff --git a/vcl/unx/inc/xfont.hxx b/vcl/unx/inc/xfont.hxx deleted file mode 100644 index 4041ed7ce67d..000000000000 --- a/vcl/unx/inc/xfont.hxx +++ /dev/null @@ -1,162 +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 EXTENDED_FONTSTRUCT_HXX -#define EXTENDED_FONTSTRUCT_HXX - -#ifndef _XLIB_H_ -#include <tools/prex.h> -#include <X11/Xlib.h> -#include <tools/postx.h> -#endif -#include <tools/ref.hxx> -#include <rtl/tencinfo.h> -#include <vcl/vclenum.hxx> -#include <vcl/sallayout.hxx> - -typedef unsigned short sal_MultiByte; - -class ImplFontMetricData; -class ExtendedXlfd; - -struct VerticalTextItem -{ - BOOL mbFixed; - XFontStruct* mpXFontStruct; - const sal_Unicode* mpString; - int mnLength; - int mnTransX; - int mnTransY; - int mnFixedAdvance; - int* mpAdvanceAry; - - VerticalTextItem( XFontStruct* pXFontStruct, - const sal_Unicode* pString, - int nLength, - int nTransX, - int nTransY, - int nFixedAdvance ) - : mbFixed( TRUE ), - mpXFontStruct( pXFontStruct ), - mpString( pString ), - mnLength( nLength ), - mnTransX( nTransX ), - mnTransY( nTransY ), - mnFixedAdvance( nFixedAdvance ) - {} - - VerticalTextItem( XFontStruct* pXFontStruct, - const sal_Unicode* pString, - int nLength, - int nTransX, - int nTransY, - int* pAdvanceAry ) - : mbFixed( FALSE ), - mpXFontStruct( pXFontStruct ), - mpString( pString ), - mnLength( nLength ), - mnTransX( nTransX ), - mnTransY( nTransY ), - mpAdvanceAry( pAdvanceAry ) - {} - - ~VerticalTextItem() - { - if (!mbFixed) - { - delete( mpAdvanceAry ); - } - } -}; - -class ExtendedFontStruct : public SvRefBase -{ - private: - Display* mpDisplay; - Size maPixelSize; - float mfXScale; - float mfYScale; - sal_Size mnDefaultWidth; - sal_Bool mbVertical; - rtl_TextEncoding mnCachedEncoding; - rtl_TextEncoding mnAsciiEncoding; - - ExtendedXlfd* mpXlfd; - XFontStruct** mpXFontStruct; - - // unicode range cache - mutable sal_uInt32* mpRangeCodes; - mutable int mnRangeCount; - - int LoadEncoding( rtl_TextEncoding nEncoding ); - FontPitch GetSpacing( rtl_TextEncoding nEncoding ); - bool GetFontBoundingBox( XCharStruct *pCharStruct, - int *pAscent, int *pDescent ) ; - - sal_Size GetDefaultWidth(); - sal_Size GetCharWidth8( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32 *pWidthArray, - rtl_TextEncoding nEncoding ); - sal_Size GetCharWidthUTF16( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32 *pWidthArray ); - sal_Size GetCharWidth16( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32 *pWidthArray, ExtendedFontStruct *pFallback ); - public: - ExtendedFontStruct( Display* pDisplay, - const Size& rPixelSize, sal_Bool bVertical, - ExtendedXlfd* pXlfd ); - ~ExtendedFontStruct(); - bool Match( const ExtendedXlfd *pXlfd, - const Size& rPixelSize, sal_Bool bVertical ) const; - XFontStruct* GetFontStruct( rtl_TextEncoding nEncoding ); - XFontStruct* GetFontStruct( sal_Unicode nChar, - rtl_TextEncoding *pEncoding ); - bool ToImplFontMetricData( ImplFontMetricData *pMetric ); - rtl_TextEncoding GetAsciiEncoding( int *pAsciiRange = NULL ) const; - sal_Size GetCharWidth( sal_Unicode, - sal_Int32* pPhysWidth, sal_Int32* pLogWidth ); - int GetFontCodeRanges( sal_uInt32* pCodePairs ) const; - bool HasUnicodeChar( sal_Unicode ) const; -}; - -// Declaration and Implementation for ExtendedFontStructRef: Add RefCounting -// to ExtendedFontStruct (it's not possible to separate decl and impl into -// a separate source file: all ref member functions are inline -SV_DECL_IMPL_REF( ExtendedFontStruct ); - -class X11FontLayout : public GenericSalLayout -{ -public: - X11FontLayout( ExtendedFontStruct& ); - virtual bool LayoutText( ImplLayoutArgs& ); - virtual void AdjustLayout( ImplLayoutArgs& ); - virtual void DrawText( SalGraphics& ) const; - -private: - ExtendedFontStruct& mrFont; -}; - -#endif /* EXTENDED_FONTSTRUCT_HXX */ diff --git a/vcl/unx/kde/salnativewidgets-kde.cxx b/vcl/unx/kde/salnativewidgets-kde.cxx index 3adc9f5c679a..29d79f88ffb3 100644 --- a/vcl/unx/kde/salnativewidgets-kde.cxx +++ b/vcl/unx/kde/salnativewidgets-kde.cxx @@ -255,19 +255,19 @@ class WidgetPainter @return valid push button. */ - QPushButton *pushButton( const Region& rControlRegion, BOOL bDefault ); + QPushButton *pushButton( const Rectangle& rControlRegion, BOOL bDefault ); /** 'Get' method for radio button. @see pushButton() */ - QRadioButton *radioButton( const Region& rControlRegion ); + QRadioButton *radioButton( const Rectangle& rControlRegion ); /** 'Get' method for check box. @see pushButton() */ - QCheckBox *checkBox( const Region& rControlRegion ); + QCheckBox *checkBox( const Rectangle& rControlRegion ); /** 'Get' method for combo box. @@ -276,74 +276,74 @@ class WidgetPainter @see pushButton(), m_pEditableComboBox */ - QComboBox *comboBox( const Region& rControlRegion, BOOL bEditable ); + QComboBox *comboBox( const Rectangle& rControlRegion, BOOL bEditable ); /** 'Get' method for line edit box. @see pushButton() */ - QLineEdit *lineEdit( const Region& rControlRegion ); + QLineEdit *lineEdit( const Rectangle& rControlRegion ); /** 'Get' method for spin box. @see pushButton() */ - QSpinWidget *spinWidget( const Region& rControlRegion ); + QSpinWidget *spinWidget( const Rectangle& rControlRegion ); /** 'Get' method for tab bar. @see pushButton() */ - QTabBar *tabBar( const Region& rControlRegion ); + QTabBar *tabBar( const Rectangle& rControlRegion ); /** 'Get' method for tab widget. @see pushButton() */ - QTabWidget *tabWidget( const Region& rControlRegion ); + QTabWidget *tabWidget( const Rectangle& rControlRegion ); /** 'Get' method for list view. @see pushButton() */ - QListView *listView( const Region& rControlRegion ); + QListView *listView( const Rectangle& rControlRegion ); /** 'Get' method for scroll bar. @see pushButton() */ - QScrollBar *scrollBar( const Region& rControlRegion, + QScrollBar *scrollBar( const Rectangle& rControlRegion, BOOL bHorizontal, const ImplControlValue& aValue ); /** 'Get' method for tool bar. @see pushButton() */ - QToolBar *toolBar( const Region& rControlRegion, BOOL bHorizontal ); + QToolBar *toolBar( const Rectangle& rControlRegion, BOOL bHorizontal ); /** 'Get' method for tool button. @see pushButton() */ - QToolButton *toolButton( const Region& rControlRegion ); + QToolButton *toolButton( const Rectangle& rControlRegion ); /** 'Get' method for menu bar. @see pushButton() */ - QMenuBar *menuBar( const Region& rControlRegion ); + QMenuBar *menuBar( const Rectangle& rControlRegion ); /** 'Get' method for popup menu. @see pushButton() */ - QPopupMenu *popupMenu( const Region& rControlRegion ); + QPopupMenu *popupMenu( const Rectangle& rControlRegion ); /** 'Get' method for progress bar @see pushButton() */ - QProgressBar *progressBar( const Region& rControlRegion ); + QProgressBar *progressBar( const Rectangle& rControlRegion ); // TODO other widgets @@ -363,7 +363,7 @@ class WidgetPainter QStyle::SFlags vclStateValue2SFlags( ControlState nState, const ImplControlValue& aValue ); public: - /** Convert VCL Region to QRect. + /** Convert VCL Rectangle to QRect. @param rControlRegion The region to convert. @@ -371,7 +371,7 @@ class WidgetPainter @return The bounding box of the region. */ - static QRect region2QRect( const Region& rControlRegion ); + static QRect region2QRect( const Rectangle& rControlRegion ); }; WidgetPainter::WidgetPainter( void ) @@ -525,7 +525,7 @@ BOOL WidgetPainter::drawStyledWidget( QWidget *pWidget, } else if ( strcmp( "QSpinWidget", pClassName ) == 0 ) { - SpinbuttonValue *pValue = static_cast<SpinbuttonValue *> ( aValue.getOptionalVal() ); + const SpinbuttonValue *pValue = static_cast<const SpinbuttonValue *> ( &aValue ); // Is any of the buttons pressed? QStyle::SCFlags eActive = QStyle::SC_None; @@ -576,7 +576,7 @@ BOOL WidgetPainter::drawStyledWidget( QWidget *pWidget, } else if ( strcmp( "QTabBar", pClassName ) == 0 ) { - TabitemValue *pValue = static_cast<TabitemValue *> ( aValue.getOptionalVal() ); + const TabitemValue *pValue = static_cast<const TabitemValue *> ( &aValue ); QTab *pTab = NULL; if ( pValue ) @@ -614,7 +614,7 @@ BOOL WidgetPainter::drawStyledWidget( QWidget *pWidget, } else if ( strcmp( "QScrollBar", pClassName ) == 0 ) { - ScrollbarValue *pValue = static_cast<ScrollbarValue *> ( aValue.getOptionalVal() ); + const ScrollbarValue *pValue = static_cast<const ScrollbarValue *> ( &aValue ); QStyle::SCFlags eActive = QStyle::SC_None; if ( pValue ) @@ -695,7 +695,7 @@ BOOL WidgetPainter::drawStyledWidget( QWidget *pWidget, if ( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT ) { - ToolbarValue *pValue = static_cast< ToolbarValue * >( aValue.getOptionalVal() ); + const ToolbarValue *pValue = static_cast< const ToolbarValue * >( &aValue ); QRect qThumbRect = region2QRect( pValue->maGripRect ); qThumbRect.moveBy( -qWidgetPos.x(), -qWidgetPos.y() ); @@ -795,7 +795,7 @@ BOOL WidgetPainter::drawStyledWidget( QWidget *pWidget, return TRUE; } -QPushButton *WidgetPainter::pushButton( const Region& rControlRegion, +QPushButton *WidgetPainter::pushButton( const Rectangle& rControlRegion, BOOL bDefault ) { if ( !m_pPushButton ) @@ -832,7 +832,7 @@ QPushButton *WidgetPainter::pushButton( const Region& rControlRegion, return m_pPushButton; } -QRadioButton *WidgetPainter::radioButton( const Region& rControlRegion ) +QRadioButton *WidgetPainter::radioButton( const Rectangle& rControlRegion ) { if ( !m_pRadioButton ) m_pRadioButton = new QRadioButton( NULL, "radio_button" ); @@ -861,7 +861,7 @@ QRadioButton *WidgetPainter::radioButton( const Region& rControlRegion ) return m_pRadioButton; } -QCheckBox *WidgetPainter::checkBox( const Region& rControlRegion ) +QCheckBox *WidgetPainter::checkBox( const Rectangle& rControlRegion ) { if ( !m_pCheckBox ) m_pCheckBox = new QCheckBox( NULL, "check_box" ); @@ -890,7 +890,7 @@ QCheckBox *WidgetPainter::checkBox( const Region& rControlRegion ) return m_pCheckBox; } -QComboBox *WidgetPainter::comboBox( const Region& rControlRegion, +QComboBox *WidgetPainter::comboBox( const Rectangle& rControlRegion, BOOL bEditable ) { QComboBox *pComboBox = NULL; @@ -915,7 +915,7 @@ QComboBox *WidgetPainter::comboBox( const Region& rControlRegion, return pComboBox; } -QLineEdit *WidgetPainter::lineEdit( const Region& rControlRegion ) +QLineEdit *WidgetPainter::lineEdit( const Rectangle& rControlRegion ) { if ( !m_pLineEdit ) m_pLineEdit = new QLineEdit( NULL, "line_edit" ); @@ -928,7 +928,7 @@ QLineEdit *WidgetPainter::lineEdit( const Region& rControlRegion ) return m_pLineEdit; } -QSpinWidget *WidgetPainter::spinWidget( const Region& rControlRegion ) +QSpinWidget *WidgetPainter::spinWidget( const Rectangle& rControlRegion ) { if ( !m_pSpinWidget ) { @@ -947,7 +947,7 @@ QSpinWidget *WidgetPainter::spinWidget( const Region& rControlRegion ) return m_pSpinWidget; } -QTabBar *WidgetPainter::tabBar( const Region& rControlRegion ) +QTabBar *WidgetPainter::tabBar( const Rectangle& rControlRegion ) { if ( !m_pTabBar ) { @@ -976,7 +976,7 @@ QTabBar *WidgetPainter::tabBar( const Region& rControlRegion ) return m_pTabBar; } -QTabWidget *WidgetPainter::tabWidget( const Region& rControlRegion ) +QTabWidget *WidgetPainter::tabWidget( const Rectangle& rControlRegion ) { if ( !m_pTabWidget ) m_pTabWidget = new QTabWidget( NULL, "tab_widget" ); @@ -990,7 +990,7 @@ QTabWidget *WidgetPainter::tabWidget( const Region& rControlRegion ) return m_pTabWidget; } -QListView *WidgetPainter::listView( const Region& rControlRegion ) +QListView *WidgetPainter::listView( const Rectangle& rControlRegion ) { if ( !m_pListView ) m_pListView = new QListView( NULL, "list_view" ); @@ -1003,7 +1003,7 @@ QListView *WidgetPainter::listView( const Region& rControlRegion ) return m_pListView; } -QScrollBar *WidgetPainter::scrollBar( const Region& rControlRegion, +QScrollBar *WidgetPainter::scrollBar( const Rectangle& rControlRegion, BOOL bHorizontal, const ImplControlValue& aValue ) { if ( !m_pScrollBar ) @@ -1019,7 +1019,7 @@ QScrollBar *WidgetPainter::scrollBar( const Region& rControlRegion, m_pScrollBar->resize( qRect.size() ); m_pScrollBar->setOrientation( bHorizontal? Qt::Horizontal: Qt::Vertical ); - ScrollbarValue *pValue = static_cast<ScrollbarValue *> ( aValue.getOptionalVal() ); + const ScrollbarValue *pValue = static_cast<const ScrollbarValue *> ( &aValue ); if ( pValue ) { m_pScrollBar->setMinValue( pValue->mnMin ); @@ -1031,7 +1031,7 @@ QScrollBar *WidgetPainter::scrollBar( const Region& rControlRegion, return m_pScrollBar; } -QToolBar *WidgetPainter::toolBar( const Region& rControlRegion, BOOL bHorizontal ) +QToolBar *WidgetPainter::toolBar( const Rectangle& rControlRegion, BOOL bHorizontal ) { if ( !m_pMainWindow ) m_pMainWindow = new QMainWindow( NULL, "main_window" ); @@ -1064,7 +1064,7 @@ QToolBar *WidgetPainter::toolBar( const Region& rControlRegion, BOOL bHorizontal return pToolBar; } -QToolButton *WidgetPainter::toolButton( const Region& rControlRegion) +QToolButton *WidgetPainter::toolButton( const Rectangle& rControlRegion) { if ( !m_pToolButton ) m_pToolButton = new QToolButton( NULL, "tool_button" ); @@ -1077,7 +1077,7 @@ QToolButton *WidgetPainter::toolButton( const Region& rControlRegion) return m_pToolButton; } -QMenuBar *WidgetPainter::menuBar( const Region& rControlRegion) +QMenuBar *WidgetPainter::menuBar( const Rectangle& rControlRegion) { if ( !m_pMenuBar ) { @@ -1098,7 +1098,7 @@ QMenuBar *WidgetPainter::menuBar( const Region& rControlRegion) return m_pMenuBar; } -QPopupMenu *WidgetPainter::popupMenu( const Region& rControlRegion) +QPopupMenu *WidgetPainter::popupMenu( const Rectangle& rControlRegion) { if ( !m_pPopupMenu ) { @@ -1119,7 +1119,7 @@ QPopupMenu *WidgetPainter::popupMenu( const Region& rControlRegion) return m_pPopupMenu; } -QProgressBar *WidgetPainter::progressBar( const Region& rControlRegion ) +QProgressBar *WidgetPainter::progressBar( const Rectangle& rControlRegion ) { if ( !m_pProgressBar ) m_pProgressBar = new QProgressBar( NULL, "progress_bar" ); @@ -1155,12 +1155,10 @@ QStyle::SFlags WidgetPainter::vclStateValue2SFlags( ControlState nState, return nStyle; } -QRect WidgetPainter::region2QRect( const Region& rControlRegion ) +QRect WidgetPainter::region2QRect( const Rectangle& rControlRegion ) { - Rectangle aRect = rControlRegion.GetBoundRect(); - - return QRect( QPoint( aRect.Left(), aRect.Top() ), - QPoint( aRect.Right(), aRect.Bottom() ) ); + return QRect( QPoint( rControlRegion.Left(), rControlRegion.Top() ), + QPoint( rControlRegion.Right(), rControlRegion.Bottom() ) ); } /** Instance of WidgetPainter. @@ -1176,21 +1174,21 @@ class KDESalGraphics : public X11SalGraphics virtual ~KDESalGraphics() {} virtual BOOL IsNativeControlSupported( ControlType nType, ControlPart nPart ); virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, const Point& aPos, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, ControlState nState, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption ); virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, - const Region& rControlRegion, ControlState nState, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption ); virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, ControlState nState, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); }; /** What widgets can be drawn the native way. @@ -1241,13 +1239,13 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP nType/nPart combination. */ BOOL KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, const Point& rPos, + const Rectangle& rControlRegion, const Point& rPos, BOOL& rIsInside ) { if ( nType == CTRL_SCROLLBAR ) { // make position relative to rControlRegion - Point aPos = rPos - rControlRegion.GetBoundRect().TopLeft(); + Point aPos = rPos - rControlRegion.TopLeft(); rIsInside = FALSE; BOOL bHorizontal = ( nPart == PART_BUTTON_LEFT || nPart == PART_BUTTON_RIGHT ); @@ -1348,7 +1346,7 @@ BOOL KDESalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, A caption or title string (like button text etc.) */ BOOL KDESalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, ControlState nState, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& ) { @@ -1490,7 +1488,7 @@ BOOL KDESalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, A caption or title string (like button text etc.) */ BOOL KDESalGraphics::drawNativeControlText( ControlType, ControlPart, - const Region&, ControlState, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) { @@ -1515,10 +1513,10 @@ BOOL KDESalGraphics::drawNativeControlText( ControlType, ControlPart, A caption or title string (like button text etc.) */ BOOL KDESalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, ControlState nState, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue&, const OUString&, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ) { BOOL bReturn = FALSE; QRect qBoundingRect = WidgetPainter::region2QRect( rControlRegion ); @@ -1697,12 +1695,12 @@ BOOL KDESalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPar // Bounding region Point aBPoint( qBoundingRect.x(), qBoundingRect.y() ); Size aBSize( qBoundingRect.width(), qBoundingRect.height() ); - rNativeBoundingRegion = Region( Rectangle( aBPoint, aBSize ) ); + rNativeBoundingRegion = Rectangle( aBPoint, aBSize ); // Region of the content Point aPoint( qRect.x(), qRect.y() ); Size aSize( qRect.width(), qRect.height() ); - rNativeContentRegion = Region( Rectangle( aPoint, aSize ) ); + rNativeContentRegion = Rectangle( aPoint, aSize ); } return bReturn; diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx index 5f8b5d2ae59e..5a5cd11c52d9 100644 --- a/vcl/unx/kde4/KDESalGraphics.cxx +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -80,15 +80,13 @@ QStyle::State vclStateValue2StateFlag( ControlState nControlState, } /** - Convert VCL Region to QRect. - @param rControlRegion The region to convert. - @return The bounding box of the region. + Convert VCL Rectangle to QRect. + @param rControlRegion The Rectangle to convert. + @return The matching QRect */ -QRect region2QRect( const Region& rControlRegion ) +QRect region2QRect( const Rectangle& rControlRegion ) { - Rectangle aRect = rControlRegion.GetBoundRect(); - - return QRect(aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()); + return QRect(rControlRegion.Left(), rControlRegion.Top(), rControlRegion.GetWidth(), rControlRegion.GetHeight()); } KDESalGraphics::KDESalGraphics() : @@ -157,7 +155,7 @@ BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart par } BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, - const Region&, const Point&, + const Rectangle&, const Point&, BOOL& ) { return FALSE; @@ -195,6 +193,22 @@ namespace kapp->style()->drawComplexControl(element, option, &painter); } + int getFrameWidth() + { + static int s_nFrameWidth = -1; + if( s_nFrameWidth < 0 ) + { + // fill in a default + s_nFrameWidth = 2; + QFrame aFrame( NULL ); + aFrame.setFrameRect( QRect(0, 0, 100, 30) ); + aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + aFrame.ensurePolished(); + s_nFrameWidth = aFrame.frameWidth(); + } + return s_nFrameWidth; + } + void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state) { #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) @@ -219,7 +233,7 @@ namespace } BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, - const Region& rControlRegion, ControlState nControlState, + const Rectangle& rControlRegion, ControlState nControlState, const ImplControlValue& value, const OUString& ) { @@ -236,7 +250,8 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, type = CTRL_SPINBUTTONS; if( type == CTRL_SPINBUTTONS ) { - SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); + OSL_ASSERT( value.getType() != CTRL_SPINBUTTONS ); + const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value); Rectangle aButtonRect( pSpinVal->maUpperRect); aButtonRect.Union( pSpinVal->maLowerRect );; widgetRect = QRect( aButtonRect.Left(), aButtonRect.Top(), @@ -409,7 +424,8 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ)) { QStyleOptionSlider option; - ScrollbarValue* sbVal = static_cast<ScrollbarValue *> ( value.getOptionalVal() ); + OSL_ASSERT( value.getType() == CTRL_SCROLLBAR ); + const ScrollbarValue* sbVal = static_cast<const ScrollbarValue *>(&value); //if the scroll bar is active (aka not degenrate...allow for hover events if (sbVal->mnVisibleSize < sbVal->mnMax) @@ -445,9 +461,9 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, QStyleOptionSpinBox option; // determine active control - SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); - if( pSpinVal ) + if( value.getType() == CTRL_SPINBUTTONS ) { + const SpinbuttonValue* pSpinVal = static_cast<const SpinbuttonValue *>(&value); if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) ) option.activeSubControls |= QStyle::SC_SpinBoxUp; if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) ) @@ -480,18 +496,25 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, lcl_drawFrame( QStyle::PE_Frame, m_image, vclStateValue2StateFlag(nControlState, value) ); - int size = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin); + // draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945 + int nFrameWidth = getFrameWidth(); pTempClipRegion = XCreateRegion(); XRectangle xRect = { widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height() }; XUnionRectWithRegion( &xRect, pTempClipRegion, pTempClipRegion ); - XLIB_Region pSubtract = XCreateRegion(); - xRect.x += size; - xRect.y += size; - xRect.width -= 2* size; - xRect.height -= 2*size; - XUnionRectWithRegion( &xRect, pSubtract, pSubtract ); - XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion ); - XDestroyRegion( pSubtract ); + xRect.x += nFrameWidth; + xRect.y += nFrameWidth; + + // do not crash for too small widgets, see http://qa.openoffice.org/issues/show_bug.cgi?id=112102 + if( xRect.width > 2*nFrameWidth && xRect.height > 2*nFrameWidth ) + { + xRect.width -= 2*nFrameWidth; + xRect.height -= 2*nFrameWidth; + + XLIB_Region pSubtract = XCreateRegion(); + XUnionRectWithRegion( &xRect, pSubtract, pSubtract ); + XSubtractRegion( pTempClipRegion, pSubtract, pTempClipRegion ); + XDestroyRegion( pSubtract ); + } } else if (type == CTRL_FIXEDBORDER) { @@ -513,7 +536,8 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else if (type == CTRL_SLIDER && (part == PART_TRACK_HORZ_AREA || part == PART_TRACK_VERT_AREA)) { - SliderValue* slVal = static_cast<SliderValue *> ( value.getOptionalVal() ); + OSL_ASSERT( value.getType() == CTRL_SLIDER ); + const SliderValue* slVal = static_cast<const SliderValue *>(&value); QStyleOptionSlider option; option.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); @@ -532,7 +556,7 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, if (returnVal) { - GC gc = SelectFont(); + GC gc = GetFontGC(); if( gc ) { @@ -566,10 +590,10 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, - const Region& controlRegion, ControlState controlState, + const Rectangle& controlRegion, ControlState controlState, const ImplControlValue& val, const OUString&, - Region &nativeBoundingRegion, Region &nativeContentRegion ) + Rectangle &nativeBoundingRegion, Rectangle &nativeContentRegion ) { bool retVal = false; @@ -744,14 +768,14 @@ BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, { if( part == PART_BORDER ) { - int size = kapp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + int nFrameWidth = getFrameWidth(); USHORT nStyle = val.getNumericVal(); if( nStyle & FRAME_DRAW_NODRAW ) { // in this case the question is: how thick would a frame be // see brdwin.cxx, decoview.cxx // most probably the behavior in decoview.cxx is wrong. - contentRect.adjust(size, size, -size, -size); + contentRect.adjust(nFrameWidth, nFrameWidth, -nFrameWidth, -nFrameWidth); } retVal = true; } @@ -869,12 +893,12 @@ BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, // Bounding region Point aBPoint( boundingRect.x(), boundingRect.y() ); Size aBSize( boundingRect.width(), boundingRect.height() ); - nativeBoundingRegion = Region( Rectangle( aBPoint, aBSize ) ); + nativeBoundingRegion = Rectangle( aBPoint, aBSize ); // Region of the content Point aPoint( contentRect.x(), contentRect.y() ); Size aSize( contentRect.width(), contentRect.height() ); - nativeContentRegion = Region( Rectangle( aPoint, aSize ) ); + nativeContentRegion = Rectangle( aPoint, aSize ); } return retVal; diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx index 5661d743e0cd..0bce1700f1fc 100644 --- a/vcl/unx/kde4/KDESalGraphics.hxx +++ b/vcl/unx/kde4/KDESalGraphics.hxx @@ -58,12 +58,12 @@ class KDESalGraphics : public X11SalGraphics type/part combination. */ virtual BOOL hitTestNativeControl( ControlType type, ControlPart part, - const Region& rControlRegion, const Point& aPos, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); /** Draw the requested control described by part/nControlState. @param rControlRegion - The bounding region of the complete control in VCL frame coordinates. + The bounding Rectangle of the complete control in VCL frame coordinates. @param aValue An optional value (tristate/numerical/string). @@ -72,7 +72,7 @@ class KDESalGraphics : public X11SalGraphics A caption or title string (like button text etc.) */ virtual BOOL drawNativeControl( ControlType type, ControlPart part, - const Region& rControlRegion, ControlState nControlState, + const Rectangle& rControlRegion, ControlState nControlState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); @@ -85,7 +85,7 @@ class KDESalGraphics : public X11SalGraphics @param aCaption A caption or title string (like button text etc.) */ virtual BOOL drawNativeControlText( ControlType, ControlPart, - const Region&, ControlState, + const Rectangle&, ControlState, const ImplControlValue&, const rtl::OUString& ) { return false; } /** Check if the bounding regions match. @@ -106,8 +106,8 @@ class KDESalGraphics : public X11SalGraphics A caption or title string (like button text etc.) */ virtual BOOL getNativeControlRegion( ControlType type, ControlPart part, - const Region& rControlRegion, ControlState nControlState, + const Rectangle& rControlRegion, ControlState nControlState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); };
\ No newline at end of file diff --git a/vcl/unx/source/app/i18n_im.cxx b/vcl/unx/source/app/i18n_im.cxx index 9f1ffee3d1c4..c797da34e76c 100644 --- a/vcl/unx/source/app/i18n_im.cxx +++ b/vcl/unx/source/app/i18n_im.cxx @@ -36,10 +36,6 @@ # endif #endif #include <poll.h> -#ifdef SOLARIS -// for SetSystemEnvironment() -#include <sal/alloca.h> -#endif #include <tools/prex.h> #include <X11/Xlocale.h> @@ -53,6 +49,7 @@ #include <i18n_status.hxx> #include <osl/thread.h> +#include <osl/process.h> using namespace vcl; #include "i18n_cb.hxx" @@ -179,21 +176,13 @@ SetSystemLocale( const char* p_inlocale ) #ifdef SOLARIS static void -SetSystemEnvironment( const char* p_locale ) +SetSystemEnvironment( const rtl::OUString& rLocale ) { - const char *lc_all = "LC_ALL=%s"; - const char *lang = "LANG=%s"; - - char *p_buffer; + rtl::OUString LC_ALL_Var(RTL_CONSTASCII_USTRINGPARAM("LC_ALL")); + osl_setEnvironment(LC_ALL_Var.pData, rLocale.pData); - if (p_locale != NULL) - { - p_buffer = (char*)alloca(10 + strlen(p_locale)); - sprintf(p_buffer, lc_all, p_locale); - putenv(strdup(p_buffer)); - sprintf(p_buffer, lang, p_locale); - putenv(strdup(p_buffer)); - } + rtl::OUString LANG_Var(RTL_CONSTASCII_USTRINGPARAM("LANG")); + osl_setEnvironment(LANG_Var.pData, rLocale.pData); } #endif @@ -249,13 +238,13 @@ SalI18N_InputMethod::SetLocale( const char* pLocale ) osl_setThreadTextEncoding (RTL_TEXTENCODING_ISO_8859_1); locale = SetSystemLocale( "en_US" ); #ifdef SOLARIS - SetSystemEnvironment( "en_US" ); + SetSystemEnvironment( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en_US")) ); #endif if (! IsXWindowCompatibleLocale(locale)) { locale = SetSystemLocale( "C" ); #ifdef SOLARIS - SetSystemEnvironment( "C" ); + SetSystemEnvironment( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("C")) ); #endif if (! IsXWindowCompatibleLocale(locale)) mbUseable = False; @@ -440,7 +429,8 @@ SalI18N_InputMethod::CreateMethod ( Display *pDisplay ) if ((maMethod == (XIM)NULL) && (getenv("XMODIFIERS") != NULL)) { - putenv (strdup("XMODIFIERS")); + rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("XMODIFIERS")); + osl_clearEnvironment(envVar.pData); XSetLocaleModifiers(""); maMethod = XOpenIM(pDisplay, NULL, NULL, NULL); mbMultiLingual = False; diff --git a/vcl/unx/source/app/keysymnames.cxx b/vcl/unx/source/app/keysymnames.cxx index cf7f7e082e69..c9515f016433 100644 --- a/vcl/unx/source/app/keysymnames.cxx +++ b/vcl/unx/source/app/keysymnames.cxx @@ -637,6 +637,7 @@ const char* SalDisplay::GetKeyboardName( BOOL bRefresh ) } } } + close(kbd); } } #else diff --git a/vcl/unx/source/app/saldata.cxx b/vcl/unx/source/app/saldata.cxx index 50ef71df8619..beb7b60a551c 100644 --- a/vcl/unx/source/app/saldata.cxx +++ b/vcl/unx/source/app/saldata.cxx @@ -425,10 +425,8 @@ void SalXLib::Init() * the clipboard build another connection * to the xserver using $DISPLAY */ - const char envpre[] = "DISPLAY="; - char *envstr = new char[sizeof(envpre)+aDisplay.getLength()]; - snprintf(envstr, sizeof(envpre)+aDisplay.getLength(), "DISPLAY=%s", aDisplay.getStr()); - putenv(envstr); + rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("DISPLAY")); + osl_setEnvironment(envVar.pData, aParam.pData); } break; } diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index aa2afab93657..92d5f75f7315 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -59,9 +59,7 @@ #ifdef USE_XINERAMA #ifdef USE_XINERAMA_XORG -#if defined(X86) || defined(X86_64) #include <X11/extensions/Xinerama.h> -#endif #elif defined USE_XINERAMA_XSUN #if defined(SOLARIS) && defined(INTEL) // missing extension header in standard installation #define MAXFRAMEBUFFERS 16 @@ -377,11 +375,6 @@ sal_GetServerVendor( Display *p_display ) { vendor_none, NULL, 0 }, }; -#ifdef _USE_PRINT_EXTENSION_ - if ( ! XSalIsDisplay( p_display ) ) - return vendor_xprinter; -#endif - // handle regular server vendors char *p_name = ServerVendor( p_display ); vendor_t *p_vendor; @@ -510,7 +503,6 @@ BOOL SalDisplay::BestVisual( Display *pDisplay, SalDisplay::SalDisplay( Display *display ) : mpInputMethod( NULL ), - mpFallbackFactory ( NULL ), pDisp_( display ), m_pWMAdaptor( NULL ), m_pDtIntegrator( NULL ), @@ -559,7 +551,6 @@ void SalDisplay::doDestruct() m_pDtIntegrator = NULL; X11SalBitmap::ImplDestroyCache(); X11SalGraphics::releaseGlyphPeer(); - DestroyFontCache(); if( IsDisplay() ) { @@ -816,8 +807,6 @@ void SalDisplay::Init() eWindowManager_ = otherwm; nProperties_ = PROPERTY_DEFAULT; hEventGuard_ = NULL; - m_pFontCache = NULL; - mpFontList = (XlfdStorage*)NULL; mpFactory = (AttributeProvider*)NULL; m_pCapture = NULL; m_bXinerama = false; @@ -2257,7 +2246,7 @@ void SalX11Display::Yield() XEvent aEvent; DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() == - NAMESPACE_VOS(OThread)::getCurrentIdentifier(), + vos::OThread::getCurrentIdentifier(), "will crash soon since solar mutex not locked in SalDisplay::Yield" ); XNextEvent( pDisp_, &aEvent ); @@ -2577,6 +2566,7 @@ void SalDisplay::PrintInfo() const fprintf( stderr, "\tProperties \t0x%lX\n", GetProperties() ); if( eWindowManager_ != otherwm ) fprintf( stderr, "\tWindowmanager \t%d\n", eWindowManager_ ); + fprintf( stderr, "\tWMName \t%s\n", rtl::OUStringToOString( getWMAdaptor()->getWindowManagerName(), osl_getThreadTextEncoding() ).getStr() ); } fprintf( stderr, "Screen\n" ); fprintf( stderr, "\tResolution/Size \t%ld*%ld %ld*%ld %.1lf\"\n", @@ -2594,7 +2584,7 @@ void SalDisplay::PrintInfo() const sal::static_int_cast< unsigned int >(GetVisual(m_nDefaultScreen).GetVisualId()) ); } -void SalDisplay::addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ) +int SalDisplay::addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, long i_nHeight ) { // see if any frame buffers are at the same coordinates // this can happen with weird configuration e.g. on @@ -2610,10 +2600,11 @@ void SalDisplay::addXineramaScreenUnique( long i_nX, long i_nY, long i_nWidth, l { m_aXineramaScreens[n].SetSize( Size( i_nWidth, i_nHeight ) ); } - return; + return (int)n; } } m_aXineramaScreens.push_back( Rectangle( Point( i_nX, i_nY ), Size( i_nWidth, i_nHeight ) ) ); + return (int)m_aXineramaScreens.size()-1; } void SalDisplay::InitXinerama() @@ -2638,7 +2629,7 @@ void SalDisplay::InitXinerama() if( result > 0 && nFramebuffers > 1 ) { m_bXinerama = true; - m_aXineramaScreens = std::vector<Rectangle>( nFramebuffers ); + m_aXineramaScreens = std::vector<Rectangle>(); for( int i = 0; i < nFramebuffers; i++ ) addXineramaScreenUnique( pFramebuffers[i].x, pFramebuffers[i].y, @@ -2647,7 +2638,6 @@ void SalDisplay::InitXinerama() } } #elif defined(USE_XINERAMA_XORG) -#if defined( X86 ) || defined( X86_64 ) if( XineramaIsActive( pDisp_ ) ) { int nFramebuffers = 1; @@ -2670,7 +2660,6 @@ if( XineramaIsActive( pDisp_ ) ) } } #endif -#endif #if OSL_DEBUG_LEVEL > 1 if( m_bXinerama ) { diff --git a/vcl/unx/source/app/salinst.cxx b/vcl/unx/source/app/salinst.cxx index 8a8db44cefcd..f125d5f98fa6 100644 --- a/vcl/unx/source/app/salinst.cxx +++ b/vcl/unx/source/app/salinst.cxx @@ -45,7 +45,7 @@ #include "sm.hxx" #include "vcl/salwtype.hxx" -#include "vcl/salatype.hxx" +#include "vcl/apptypes.hxx" #include "vcl/helper.hxx" #include <tools/solarmutex.hxx> #include "vos/mutex.hxx" @@ -66,13 +66,13 @@ SalYieldMutex::SalYieldMutex() void SalYieldMutex::acquire() { OMutex::acquire(); - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; } void SalYieldMutex::release() { - if ( mnThreadId == NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + if ( mnThreadId == vos::OThread::getCurrentIdentifier() ) { if ( mnCount == 1 ) mnThreadId = 0; @@ -85,7 +85,7 @@ sal_Bool SalYieldMutex::tryToAcquire() { if ( OMutex::tryToAcquire() ) { - mnThreadId = NAMESPACE_VOS(OThread)::getCurrentIdentifier(); + mnThreadId = vos::OThread::getCurrentIdentifier(); mnCount++; return True; } @@ -231,7 +231,7 @@ ULONG X11SalInstance::ReleaseYieldMutex() { SalYieldMutex* pYieldMutex = mpSalYieldMutex; if ( pYieldMutex->GetThreadId() == - NAMESPACE_VOS(OThread)::getCurrentIdentifier() ) + vos::OThread::getCurrentIdentifier() ) { ULONG nCount = pYieldMutex->GetAcquireCount(); ULONG n = nCount; @@ -259,6 +259,24 @@ void X11SalInstance::AcquireYieldMutex( ULONG nCount ) } } +// ----------------------------------------------------------------------- + +bool X11SalInstance::CheckYieldMutex() +{ + bool bRet = true; + + SalYieldMutex* pYieldMutex = mpSalYieldMutex; + if ( pYieldMutex->GetThreadId() != + vos::OThread::getCurrentIdentifier() ) + { + bRet = false; + } + + return bRet; +} + +// ----------------------------------------------------------------------- + void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) { GetX11SalData()->GetLib()->Yield( bWait, bHandleAllCurrentEvents ); } diff --git a/vcl/unx/source/app/salsys.cxx b/vcl/unx/source/app/salsys.cxx index 1ccb214df4ed..84c9dba32e40 100644 --- a/vcl/unx/source/app/salsys.cxx +++ b/vcl/unx/source/app/salsys.cxx @@ -71,7 +71,7 @@ bool X11SalSystem::IsMultiDisplay() unsigned int X11SalSystem::GetDefaultDisplayNumber() { SalDisplay* pSalDisp = GetX11SalData()->GetDisplay(); - return pSalDisp->GetDefaultScreenNumber(); + return pSalDisp->IsXinerama() ? pSalDisp->GetDefaultMonitorNumber() : pSalDisp->GetDefaultScreenNumber(); } Rectangle X11SalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen ) diff --git a/vcl/unx/source/app/sm.cxx b/vcl/unx/source/app/sm.cxx index dbaa278a780b..959d6af5912d 100644 --- a/vcl/unx/source/app/sm.cxx +++ b/vcl/unx/source/app/sm.cxx @@ -159,6 +159,10 @@ class ICEConnectionObserver static int nWakeupFiles[2]; static oslMutex ICEMutex; static oslThread ICEThread; +#ifdef USE_SM_EXTENSION + static IceIOErrorHandler origIOErrorHandler; + static IceErrorHandler origErrorHandler; +#endif public: static void activate(); @@ -179,6 +183,19 @@ oslMutex ICEConnectionObserver::ICEMutex = NULL; oslThread ICEConnectionObserver::ICEThread = NULL; int ICEConnectionObserver::nWakeupFiles[2] = { 0, 0 }; +#ifdef USE_SM_EXTENSION +IceIOErrorHandler ICEConnectionObserver::origIOErrorHandler = NULL; +IceErrorHandler ICEConnectionObserver::origErrorHandler = NULL; + +static void IgnoreIceErrors(IceConn, Bool, int, unsigned long, int, int, IcePointer) +{ +} + +static void IgnoreIceIOErrors(IceConn) +{ +} +#endif + // HACK bool SessionManagerClient::bDocSaveDone = false; @@ -591,6 +608,12 @@ void ICEConnectionObserver::activate() ICEMutex = osl_createMutex(); bIsWatching = TRUE; #ifdef USE_SM_EXTENSION + /* + * Default handlers call exit, we don't care that strongly if something + * happens to fail + */ + origIOErrorHandler = IceSetIOErrorHandler( IgnoreIceIOErrors ); + origErrorHandler = IceSetErrorHandler( IgnoreIceErrors ); IceAddConnectionWatch( ICEWatchProc, NULL ); #endif } @@ -604,6 +627,8 @@ void ICEConnectionObserver::deactivate() bIsWatching = FALSE; #ifdef USE_SM_EXTENSION IceRemoveConnectionWatch( ICEWatchProc, NULL ); + IceSetErrorHandler( origErrorHandler ); + IceSetIOErrorHandler( origIOErrorHandler ); #endif nConnections = 0; if( ICEThread ) diff --git a/vcl/unx/source/app/wmadaptor.cxx b/vcl/unx/source/app/wmadaptor.cxx index fb2317e19573..f816c5d1426e 100644 --- a/vcl/unx/source/app/wmadaptor.cxx +++ b/vcl/unx/source/app/wmadaptor.cxx @@ -31,21 +31,22 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> -#include <sal/alloca.h> -#include <wmadaptor.hxx> -#include <saldisp.hxx> -#include <saldata.hxx> -#include <salframe.h> -#include <vcl/salgdi.hxx> -#include <osl/thread.h> -#include <rtl/locale.h> -#include <osl/process.h> - -#include <tools/prex.h> +#include "sal/alloca.h" +#include "wmadaptor.hxx" +#include "saldisp.hxx" +#include "saldata.hxx" +#include "salframe.h" +#include "vcl/salgdi.hxx" +#include "osl/thread.h" +#include "rtl/locale.h" +#include "osl/process.h" +#include "vcl/configsettings.hxx" + +#include "tools/prex.h" #include <X11/X.h> #include <X11/Xatom.h> #include <X11/Xresource.h> -#include <tools/postx.h> +#include "tools/postx.h" #if OSL_DEBUG_LEVEL > 1 #include <stdio.h> @@ -238,7 +239,9 @@ WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) : m_bEnableAlwaysOnTopWorks( false ), m_bLegacyPartialFullscreen( false ), m_nWinGravity( StaticGravity ), - m_nInitWinGravity( StaticGravity ) + m_nInitWinGravity( StaticGravity ), + m_bWMshouldSwitchWorkspace( true ), + m_bWMshouldSwitchWorkspaceInit( false ) { Atom aRealType = None; int nFormat = 8; @@ -965,6 +968,30 @@ bool WMAdaptor::getNetWmName() return bNetWM; } +bool WMAdaptor::getWMshouldSwitchWorkspace() const +{ + if( ! m_bWMshouldSwitchWorkspaceInit ) + { + WMAdaptor * pWMA = const_cast<WMAdaptor*>(this); + + pWMA->m_bWMshouldSwitchWorkspace = true; + vcl::SettingsConfigItem* pItem = vcl::SettingsConfigItem::get(); + rtl::OUString aSetting( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WM" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ShouldSwitchWorkspace" ) ) ) ); + if( aSetting.getLength() == 0 ) + { + if( m_aWMName.EqualsAscii( "awesome" ) ) + { + pWMA->m_bWMshouldSwitchWorkspace = false; + } + } + else + pWMA->m_bWMshouldSwitchWorkspace = aSetting.toBoolean(); + pWMA->m_bWMshouldSwitchWorkspaceInit = true; + } + return m_bWMshouldSwitchWorkspace; +} + /* * WMAdaptor::isValid() */ @@ -1407,56 +1434,59 @@ void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eTy pFrame->meWindowType = eType; pFrame->mnDecorationFlags = nDecorationFlags; - // set mwm hints - struct _mwmhints { - unsigned long flags, func, deco; - long input_mode; - unsigned long status; - } aHint; - - aHint.flags = 15; /* flags for functions, decoration, input mode and status */ - aHint.deco = 0; - aHint.func = 1L << 2; - aHint.status = 0; - aHint.input_mode = 0; - - // evaluate decoration flags - if( nDecorationFlags & decoration_All ) - aHint.deco = 1, aHint.func = 1; - else - { - if( nDecorationFlags & decoration_Title ) - aHint.deco |= 1L << 3; - if( nDecorationFlags & decoration_Border ) - aHint.deco |= 1L << 1; - if( nDecorationFlags & decoration_Resize ) - aHint.deco |= 1L << 2, aHint.func |= 1L << 1; - if( nDecorationFlags & decoration_MinimizeBtn ) - aHint.deco |= 1L << 5, aHint.func |= 1L << 3; - if( nDecorationFlags & decoration_MaximizeBtn ) - aHint.deco |= 1L << 6, aHint.func |= 1L << 4; - if( nDecorationFlags & decoration_CloseBtn ) - aHint.deco |= 1L << 4, aHint.func |= 1L << 5; - } - // evaluate window type - switch( eType ) + if( ! pFrame->mbFullScreen ) { - case windowType_ModalDialogue: - aHint.input_mode = 1; - break; - default: - break; - } + // set mwm hints + struct _mwmhints { + unsigned long flags, func, deco; + long input_mode; + unsigned long status; + } aHint; + + aHint.flags = 15; /* flags for functions, decoration, input mode and status */ + aHint.deco = 0; + aHint.func = 1L << 2; + aHint.status = 0; + aHint.input_mode = 0; + + // evaluate decoration flags + if( nDecorationFlags & decoration_All ) + aHint.deco = 1, aHint.func = 1; + else + { + if( nDecorationFlags & decoration_Title ) + aHint.deco |= 1L << 3; + if( nDecorationFlags & decoration_Border ) + aHint.deco |= 1L << 1; + if( nDecorationFlags & decoration_Resize ) + aHint.deco |= 1L << 2, aHint.func |= 1L << 1; + if( nDecorationFlags & decoration_MinimizeBtn ) + aHint.deco |= 1L << 5, aHint.func |= 1L << 3; + if( nDecorationFlags & decoration_MaximizeBtn ) + aHint.deco |= 1L << 6, aHint.func |= 1L << 4; + if( nDecorationFlags & decoration_CloseBtn ) + aHint.deco |= 1L << 4, aHint.func |= 1L << 5; + } + // evaluate window type + switch( eType ) + { + case windowType_ModalDialogue: + aHint.input_mode = 1; + break; + default: + break; + } - // set the hint - XChangeProperty( m_pDisplay, - pFrame->GetShellWindow(), - m_aWMAtoms[ MOTIF_WM_HINTS ], - m_aWMAtoms[ MOTIF_WM_HINTS ], - 32, - PropModeReplace, - (unsigned char*)&aHint, - 5 ); + // set the hint + XChangeProperty( m_pDisplay, + pFrame->GetShellWindow(), + m_aWMAtoms[ MOTIF_WM_HINTS ], + m_aWMAtoms[ MOTIF_WM_HINTS ], + 32, + PropModeReplace, + (unsigned char*)&aHint, + 5 ); + } // set transientFor hint /* #91030# dtwm will not map a dialogue if the transient @@ -2177,6 +2207,15 @@ void NetWMAdaptor::showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const if( m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] ) { pFrame->mbFullScreen = bFullScreen; + if( bFullScreen ) + { + if( m_aWMAtoms[ MOTIF_WM_HINTS ] ) + { + XDeleteProperty( m_pDisplay, + pFrame->GetShellWindow(), + m_aWMAtoms[ MOTIF_WM_HINTS ] ); + } + } if( pFrame->bMapped_ ) { // window already mapped, send WM a message @@ -2326,8 +2365,11 @@ int WMAdaptor::getWindowWorkArea( XLIB_Window aWindow ) const * WMAdaptor::getCurrentWorkArea */ // fixme: multi screen case -void WMAdaptor::switchToWorkArea( int nWorkArea ) const +void WMAdaptor::switchToWorkArea( int nWorkArea, bool bConsiderWM ) const { + if( bConsiderWM && ! getWMshouldSwitchWorkspace() ) + return; + if( m_aWMAtoms[ NET_CURRENT_DESKTOP ] ) { XEvent aEvent; diff --git a/vcl/unx/source/dtrans/X11_selection.cxx b/vcl/unx/source/dtrans/X11_selection.cxx index 7f205407b21b..403ee9707a94 100644 --- a/vcl/unx/source/dtrans/X11_selection.cxx +++ b/vcl/unx/source/dtrans/X11_selection.cxx @@ -28,15 +28,17 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" +#include "saldisp.hxx" +#include "saldata.hxx" + #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/time.h> + #include "tools/prex.h" #include <X11/Xatom.h> #include <X11/keysym.h> -#include <X11/Xlib.h> -#include <X11/X.h> #include <X11/Xutil.h> #include "tools/postx.h" #if defined(LINUX) || defined(NETBSD) || defined (FREEBSD) @@ -3259,6 +3261,8 @@ void SelectionManager::startDrag( return; } + SalFrame* pCaptureFrame = NULL; + { ClearableMutexGuard aGuard(m_aMutex); @@ -3327,6 +3331,32 @@ void SelectionManager::startDrag( None, None, CurrentTime ); + /* if we could not grab the pointer here, there is a chance + that the pointer is grabbed by the other vcl display (the main loop) + so let's break that grab an reset it later + + remark: this whole code should really be molten into normal vcl so only + one display is used .... + */ + if( nPointerGrabSuccess != GrabSuccess ) + { + vos::IMutex& rSolarMutex( Application::GetSolarMutex() ); + if( rSolarMutex.tryToAcquire() ) + { + pCaptureFrame = GetX11SalData()->GetDisplay()->GetCaptureFrame(); + if( pCaptureFrame ) + { + GetX11SalData()->GetDisplay()->CaptureMouse( NULL ); + nPointerGrabSuccess = + XGrabPointer( m_pDisplay, it->second.m_aRootWindow, True, + DRAG_EVENT_MASK, + GrabModeAsync, GrabModeAsync, + None, + None, + CurrentTime ); + } + } + } #if OSL_DEBUG_LEVEL > 1 fprintf( stderr, "%d\n", nPointerGrabSuccess ); #endif @@ -3349,6 +3379,16 @@ void SelectionManager::startDrag( aGuard.clear(); if( listener.is() ) listener->dragDropEnd( aDragFailedEvent ); + if( pCaptureFrame ) + { + vos::IMutex& rSolarMutex( Application::GetSolarMutex() ); + if( rSolarMutex.tryToAcquire() ) + GetX11SalData()->GetDisplay()->CaptureMouse( pCaptureFrame ); +#if OSL_DEBUG_LEVEL > 0 + else + OSL_ENSURE( 0, "failed to acquire SolarMutex to reset capture frame" ); +#endif + } return; } @@ -3428,6 +3468,17 @@ void SelectionManager::startDrag( XUngrabKeyboard( m_pDisplay, CurrentTime ); XFlush( m_pDisplay ); + if( pCaptureFrame ) + { + vos::IMutex& rSolarMutex( Application::GetSolarMutex() ); + if( rSolarMutex.tryToAcquire() ) + GetX11SalData()->GetDisplay()->CaptureMouse( pCaptureFrame ); +#if OSL_DEBUG_LEVEL > 0 + else + OSL_ENSURE( 0, "failed to acquire SolarMutex to reset capture frame" ); +#endif + } + m_aDragRunning.reset(); if( listener.is() ) @@ -3915,6 +3966,18 @@ void SelectionManager::deregisterHandler( Atom selection ) // ------------------------------------------------------------------------ +static bool bWasError = false; + +extern "C" +{ + int local_xerror_handler(Display* , XErrorEvent*) + { + bWasError = true; + return 0; + } + typedef int(*xerror_hdl_t)(Display*,XErrorEvent*); +} + void SelectionManager::registerDropTarget( XLIB_Window aWindow, DropTarget* pTarget ) { MutexGuard aGuard(m_aMutex); @@ -3926,18 +3989,31 @@ void SelectionManager::registerDropTarget( XLIB_Window aWindow, DropTarget* pTar OSL_ASSERT( "attempt to register window as drop target twice" ); else if( aWindow && m_pDisplay ) { - XSelectInput( m_pDisplay, aWindow, PropertyChangeMask ); - - // set XdndAware - XChangeProperty( m_pDisplay, aWindow, m_nXdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&nXdndProtocolRevision, 1 ); - DropTargetEntry aEntry( pTarget ); - // get root window of window (in 99.999% of all cases this will be - // DefaultRootWindow( m_pDisplay ) - int x, y; - unsigned int w, h, bw, d; - XGetGeometry( m_pDisplay, aWindow, &aEntry.m_aRootWindow, - &x, &y, &w, &h, &bw, &d ); + bWasError=false; + /* #i100000# ugly workaround: gtk sets its own XErrorHandler which is not suitable for us + unfortunately XErrorHandler is not per display, so this is just and ugly hack + Need to remove separate display and integrate clipboard/dnd into vcl's unx code ASAP + */ + xerror_hdl_t pOldHandler = XSetErrorHandler( local_xerror_handler ); + XSelectInput( m_pDisplay, aWindow, PropertyChangeMask ); + if( ! bWasError ) + { + // set XdndAware + XChangeProperty( m_pDisplay, aWindow, m_nXdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&nXdndProtocolRevision, 1 ); + if( ! bWasError ) + { + // get root window of window (in 99.999% of all cases this will be + // DefaultRootWindow( m_pDisplay ) + int x, y; + unsigned int w, h, bw, d; + XGetGeometry( m_pDisplay, aWindow, &aEntry.m_aRootWindow, + &x, &y, &w, &h, &bw, &d ); + } + } + XSetErrorHandler( pOldHandler ); + if(bWasError) + return; m_aDropTargets[ aWindow ] = aEntry; } else diff --git a/vcl/unx/source/fontmanager/fontcache.cxx b/vcl/unx/source/fontmanager/fontcache.cxx index db4a7d05e5fc..0c43373bfa8e 100644 --- a/vcl/unx/source/fontmanager/fontcache.cxx +++ b/vcl/unx/source/fontmanager/fontcache.cxx @@ -373,9 +373,9 @@ void FontCache::read() xub_StrLen nLastIndex = nIndex+1; for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ ) ; - if( nIndex - nLastIndex > 1 ) + if( nIndex - nLastIndex ) { - OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex-1, RTL_TEXTENCODING_UTF8 ); + OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 ); pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, sal_True ) ); } } diff --git a/vcl/unx/source/fontmanager/fontconfig.cxx b/vcl/unx/source/fontmanager/fontconfig.cxx index 816c8fb0b4c4..434263db352e 100644 --- a/vcl/unx/source/fontmanager/fontconfig.cxx +++ b/vcl/unx/source/fontmanager/fontconfig.cxx @@ -121,16 +121,20 @@ class FontCfgWrapper FcResult (*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*); void (*m_pFcDefaultSubstitute)(FcPattern *); FcPattern* (*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*); + FcPattern* (*m_pFcFontMatch)(FcConfig*,FcPattern*,FcResult*); FcBool (*m_pFcConfigAppFontAddFile)(FcConfig*, const FcChar8*); FcBool (*m_pFcConfigAppFontAddDir)(FcConfig*, const FcChar8*); FcBool (*m_pFcConfigParseAndLoad)(FcConfig*,const FcChar8*,FcBool); - FcBool (*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind); + + FcPattern* (*m_pFcPatternDuplicate)(const FcPattern*); FcBool (*m_pFcPatternAddInteger)(FcPattern*,const char*,int); FcBool (*m_pFcPatternAddDouble)(FcPattern*,const char*,double); FcBool (*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool); FcBool (*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*); FcBool (*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*); + FcBool (*m_pFcPatternDel)(FcPattern*,const char*); + FT_UInt (*m_pFcFreeTypeCharIndex)(FT_Face,FcChar32); oslGenericFunction loadSymbol( const char* ); @@ -230,8 +234,13 @@ public: { m_pFcDefaultSubstitute( pPattern ); } FcPattern* FcFontSetMatch( FcConfig* pConfig, FcFontSet **ppFontSet, int nset, FcPattern* pPattern, FcResult* pResult ) { return m_pFcFontSetMatch ? m_pFcFontSetMatch( pConfig, ppFontSet, nset, pPattern, pResult ) : 0; } + FcPattern* FcFontMatch( FcConfig* pConfig, FcPattern* pPattern, FcResult* pResult ) + { return m_pFcFontMatch( pConfig, pPattern, pResult ); } FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind ) { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); } + + FcPattern* FcPatternDuplicate( const FcPattern* pPattern ) const + { return m_pFcPatternDuplicate( pPattern ); } FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue ) { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); } FcBool FcPatternAddDouble( FcPattern* pPattern, const char* pObject, double nValue ) @@ -242,6 +251,8 @@ public: { return m_pFcPatternAddBool( pPattern, pObject, nValue ); } FcBool FcPatternAddCharSet(FcPattern* pPattern,const char* pObject,const FcCharSet*pCharSet) { return m_pFcPatternAddCharSet(pPattern,pObject,pCharSet); } + FcBool FcPatternDel(FcPattern* pPattern, const char* object) + { return m_pFcPatternDel( pPattern, object); } FT_UInt FcFreeTypeCharIndex( FT_Face face, FcChar32 ucs4 ) { return m_pFcFreeTypeCharIndex ? m_pFcFreeTypeCharIndex( face, ucs4 ) : 0; } @@ -337,8 +348,13 @@ FontCfgWrapper::FontCfgWrapper() loadSymbol( "FcDefaultSubstitute" ); m_pFcFontSetMatch = (FcPattern*(*)(FcConfig*,FcFontSet**,int,FcPattern*,FcResult*)) loadSymbol( "FcFontSetMatch" ); + m_pFcFontMatch = (FcPattern*(*)(FcConfig*,FcPattern*,FcResult*)) + loadSymbol( "FcFontMatch" ); m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind)) loadSymbol( "FcConfigSubstitute" ); + + m_pFcPatternDuplicate = (FcPattern*(*)(const FcPattern*)) + loadSymbol( "FcPatternDuplicate" ); m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int)) loadSymbol( "FcPatternAddInteger" ); m_pFcPatternAddDouble = (FcBool(*)(FcPattern*,const char*,double)) @@ -349,6 +365,9 @@ FontCfgWrapper::FontCfgWrapper() loadSymbol( "FcPatternAddCharSet" ); m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*)) loadSymbol( "FcPatternAddString" ); + m_pFcPatternDel = (FcBool(*)(FcPattern*,const char*)) + loadSymbol( "FcPatternDel" ); + m_pFcFreeTypeCharIndex = (FT_UInt(*)(FT_Face,FcChar32)) loadSymbol( "FcFreeTypeCharIndex" ); @@ -391,13 +410,16 @@ FontCfgWrapper::FontCfgWrapper() m_pFcConfigAppFontAddFile && m_pFcConfigAppFontAddDir && m_pFcConfigParseAndLoad && + m_pFcFontMatch && m_pFcDefaultSubstitute && m_pFcConfigSubstitute && + m_pFcPatternDuplicate && m_pFcPatternAddInteger && m_pFcPatternAddDouble && m_pFcPatternAddCharSet && m_pFcPatternAddBool && - m_pFcPatternAddString + m_pFcPatternAddString && + m_pFcPatternDel ) ) { osl_unloadModule( (oslModule)m_pLib ); @@ -428,18 +450,44 @@ void FontCfgWrapper::addFontSet( FcSetName eSetName ) if( !pOrig ) return; + // filter the font sets to remove obsolete or duplicate faces for( int i = 0; i < pOrig->nfont; ++i ) { - FcBool outline = false; - FcPattern *pOutlinePattern = pOrig->fonts[i]; - FcResult eOutRes = - FcPatternGetBool( pOutlinePattern, FC_OUTLINE, 0, &outline ); - if( (eOutRes != FcResultMatch) || (outline != FcTrue) ) + FcPattern* pOrigPattern = pOrig->fonts[i]; + // #i115131# ignore non-outline fonts + FcBool bOutline = FcFalse; + FcResult eOutRes = FcPatternGetBool( pOrigPattern, FC_OUTLINE, 0, &bOutline ); + if( (eOutRes != FcResultMatch) || (bOutline == FcFalse) ) continue; - FcPatternReference(pOutlinePattern); - FcFontSetAdd(m_pOutlineSet, pOutlinePattern); + // create a pattern to find eventually better alternatives + FcPattern* pBetterPattern = pOrigPattern; + if( m_nFcVersion > 20400 ) // #i115204# avoid trouble with old FC versions + { + FcPattern* pTestPattern = FcPatternDuplicate( pOrigPattern ); + FcPatternAddBool( pTestPattern, FC_OUTLINE, FcTrue ); + // TODO: ignore all attributes that are not interesting for finding dupes + // e.g. by using pattern->ImplFontAttr->pattern conversion + FcPatternDel( pTestPattern, FC_FONTVERSION ); + FcPatternDel( pTestPattern, FC_CHARSET ); + FcPatternDel( pTestPattern, FC_FILE ); + // find the font face for the dupe-search pattern + FcResult eFcResult = FcResultMatch; + pBetterPattern = FcFontMatch( FcConfigGetCurrent(), pTestPattern, &eFcResult ); + FcPatternDestroy( pTestPattern ); + if( eFcResult != FcResultMatch ) + continue; + // #i115131# double check results and eventually ignore them + eOutRes = FcPatternGetBool( pBetterPattern, FC_OUTLINE, 0, &bOutline ); + if( (eOutRes != FcResultMatch) || (bOutline == FcFalse) ) + continue; + } + // insert best found pattern for the dupe-search pattern + // TODO: skip inserting patterns that are already known in the target fontset + FcPatternReference( pBetterPattern ); + FcFontSetAdd( m_pOutlineSet, pBetterPattern ); } - // TODO: FcFontSetDestroy( pOrig ); + + // TODO?: FcFontSetDestroy( pOrig ); #else (void)eSetName; // prevent compiler warning about unused parameter #endif @@ -509,22 +557,29 @@ namespace std::vector<lang_and_family>::const_iterator aEnd = families.end(); bool alreadyclosematch = false; - for (std::vector<lang_and_family>::const_iterator aIter = families.begin(); aIter != aEnd; ++aIter) + for( std::vector<lang_and_family>::const_iterator aIter = families.begin(); aIter != aEnd; ++aIter ) { const char *pLang = (const char*)aIter->first; - //perfect - if( rtl_str_compare(pLang,sFullMatch.getStr() ) == 0) + if( rtl_str_compare( pLang, sFullMatch.getStr() ) == 0) { + // both language and country match candidate = aIter->second; break; } - else if( (rtl_str_compare(pLang,sLangMatch.getStr()) == 0) && (!alreadyclosematch)) + else if( alreadyclosematch ) + continue; + else if( rtl_str_compare( pLang, sLangMatch.getStr()) == 0) { + // just the language matches candidate = aIter->second; alreadyclosematch = true; } + else if( rtl_str_compare( pLang, "en") == 0) + { + // fallback to the english family name + candidate = aIter->second; + } } - return candidate; } } @@ -701,7 +756,7 @@ int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl ); #endif - OSL_ASSERT(eOutRes != FcResultMatch || outline); +// OSL_ASSERT(eOutRes != FcResultMatch || outline); // only outline fonts are usable to psprint anyway if( eOutRes == FcResultMatch && ! outline ) @@ -731,7 +786,10 @@ int PrintFontManager::countFontconfigFonts( std::hash_map<rtl::OString, int, rtl #endif } if( aFonts.empty() ) + { + // TODO: remove fonts unusable to psprint from fontset continue; + } int nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, OStringToOUString( OString( (sal_Char*)family ), RTL_TEXTENCODING_UTF8 ), sal_True ); PrintFont* pUpdate = aFonts.front(); @@ -851,22 +909,25 @@ bool PrintFontManager::addFontconfigDir( const rtl::OString& rDirName ) bool bDirOk = (rWrapper.FcConfigAppFontAddDir( rWrapper.FcConfigGetCurrent(), (FcChar8*)pDirName ) == FcTrue); #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "FcConfigAppFontAddDir( \"%s\") => %d\n", pDirName, bRet ); + fprintf( stderr, "FcConfigAppFontAddDir( \"%s\") => %d\n", pDirName, bDirOk ); #endif - if( bDirOk ) + if( !bDirOk ) + return false; + + // load dir-specific fc-config file too if available + const rtl::OString aConfFileName = rDirName + "/fc_local.conf"; + FILE* pCfgFile = fopen( aConfFileName.getStr(), "rb" ); + if( pCfgFile ) { - const rtl::OString aConfFileName = rDirName + "/fc_local.conf"; + fclose( pCfgFile); bool bCfgOk = rWrapper.FcConfigParseAndLoad( rWrapper.FcConfigGetCurrent(), - (FcChar8*)aConfFileName.getStr(), FcTrue ); - (void)bCfgOk; // silence compiler warning - -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "FcConfigParseAndLoad( \"%s\") => %d\n", aConfFileName.getStr(), bCfgOk ); -#endif + (FcChar8*)aConfFileName.getStr(), FcTrue ); + if( !bCfgOk ) + fprintf( stderr, "FcConfigParseAndLoad( \"%s\") => %d\n", aConfFileName.getStr(), bCfgOk ); } - return bDirOk; + return true; } static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, @@ -1058,6 +1119,7 @@ bool PrintFontManager::getFontOptions( ImplFontOptions& rOptions) const { #ifndef ENABLE_FONTCONFIG + (void)rInfo;(void)nSize;(void)subcallback;(void)rOptions; return false; #else // ENABLE_FONTCONFIG FontCfgWrapper& rWrapper = FontCfgWrapper::get(); diff --git a/vcl/unx/source/gdi/makefile.mk b/vcl/unx/source/gdi/makefile.mk index 536aadcac015..123fcbcf9131 100644 --- a/vcl/unx/source/gdi/makefile.mk +++ b/vcl/unx/source/gdi/makefile.mk @@ -53,29 +53,19 @@ SLOFILES= \ $(SLO)$/salvd.obj \ $(SLO)$/dtint.obj \ $(SLO)$/salcvt.obj \ - $(SLO)$/xfont.obj \ - $(SLO)$/xlfd_attr.obj \ - $(SLO)$/xlfd_extd.obj \ - $(SLO)$/xlfd_smpl.obj \ $(SLO)$/salgdi3.obj \ $(SLO)$/gcach_xpeer.obj \ $(SLO)$/xrender_peer.obj \ $(SLO)$/pspgraphics.obj EXCEPTIONSFILES=\ - $(SLO)$/xlfd_extd.obj \ $(SLO)$/salgdi.obj \ $(SLO)$/salbmp.obj \ $(SLO)$/salgdi3.obj \ $(SLO)$/salcvt.obj -.IF "$(USE_XPRINT)" == "TRUE" -CFLAGS+=-D_USE_PRINT_EXTENSION_=1 -SLOFILES+=$(SLO)$/xprintext.obj -.ELSE SLOFILES+=$(SLO)$/salprnpsp.obj EXCEPTIONSFILES+=$(SLO)$/salprnpsp.obj -.ENDIF .IF "$(OS)"=="SOLARIS" SLOFILES+=$(SLO)$/cdeint.obj diff --git a/vcl/unx/source/gdi/pspgraphics.cxx b/vcl/unx/source/gdi/pspgraphics.cxx index d599e09e71f2..bab78b0cb2df 100644 --- a/vcl/unx/source/gdi/pspgraphics.cxx +++ b/vcl/unx/source/gdi/pspgraphics.cxx @@ -403,7 +403,7 @@ bool PspGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fT return false; } -bool PspGraphics::drawPolyLine( const basegfx::B2DPolygon&, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/) +bool PspGraphics::drawPolyLine( const basegfx::B2DPolygon&, double /*fTranspareny*/, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/) { // TODO: a PS printer can draw B2DPolyLines almost directly return false; @@ -694,7 +694,7 @@ void PspServerFontLayout::InitFont() const static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx, bool bIsPspServerFontLayout ) { const int nMaxGlyphs = 200; - sal_GlyphId aGlyphAry[ nMaxGlyphs ]; + sal_uInt32 aGlyphAry[ nMaxGlyphs ]; // TODO: use sal_GlyphId sal_Int32 aWidthAry[ nMaxGlyphs ]; sal_Int32 aIdxAry [ nMaxGlyphs ]; sal_Unicode aUnicodes[ nMaxGlyphs ]; @@ -720,15 +720,20 @@ static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx #ifdef ENABLE_GRAPHITE else if (pGrLayout) { + #if 0 // HACK: disabled for now due to #i114460#, see #desc12 there + // TODO: get rid of glyph->string mapping altogether for printing + // TODO: fix GraphiteServerFontLayout's returned aCharPosAry + // TODO: fix PrinterGfx's caching? pText = pGrLayout->getTextPtr(); nMinCharPos = pGrLayout->getMinCharPos(); nMaxCharPos = pGrLayout->getMaxCharPos(); + #endif } #endif } for( int nStart = 0;; ) { - int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, bIsPspServerFontLayout ? aCharPosAry : NULL ); + int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, pText ? aCharPosAry : NULL ); if( !nGlyphCount ) break; @@ -738,7 +743,7 @@ static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx nXOffset += aWidthAry[ i ]; aIdxAry[ i ] = nXOffset / nUnitsPerPixel; sal_Int32 nGlyphIdx = aGlyphAry[i] & (GF_IDXMASK | GF_ROTMASK); - if( bIsPspServerFontLayout ) + if( pText ) aUnicodes[i] = (aCharPosAry[i] >= nMinCharPos && aCharPosAry[i] <= nMaxCharPos) ? pText[ aCharPosAry[i] ] : 0; else aUnicodes[i] = (aGlyphAry[i] & GF_ISCHAR) ? nGlyphIdx : 0; @@ -770,16 +775,13 @@ void PspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) DrawPrinterLayout( rLayout, *m_pPrinterGfx, true ); } -ImplFontCharMap* PspGraphics::GetImplFontCharMap() const +const ImplFontCharMap* PspGraphics::GetImplFontCharMap() const { - // TODO: get ImplFontCharMap directly from fonts if( !m_pServerFont[0] ) return NULL; - CmapResult aCmapResult; - if( !m_pServerFont[0]->GetFontCodeRanges( aCmapResult ) ) - return NULL; - return new ImplFontCharMap( aCmapResult ); + const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap(); + return pIFCMap; } USHORT PspGraphics::SetFont( ImplFontSelectData *pEntry, int nFallbackLevel ) @@ -885,7 +887,7 @@ void PspGraphics::GetDevFontSubstList( OutputDevice* pOutDev ) } } -void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric ) +void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric, int ) { const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); psp::PrintFontInfo aInfo; diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx index 15e391256344..9dfbfff22d03 100644 --- a/vcl/unx/source/gdi/salgdi.cxx +++ b/vcl/unx/source/gdi/salgdi.cxx @@ -113,10 +113,7 @@ X11SalGraphics::X11SalGraphics() pFontGC_ = NULL; for( int i = 0; i < MAX_FALLBACK; ++i ) - { - mXFont[i] = NULL; mpServerFont[i] = NULL; - } nTextPixel_ = 0; nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black @@ -338,13 +335,8 @@ GC X11SalGraphics::SelectBrush() { XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ ); - #if defined(_USE_PRINT_EXTENSION_) - XSetBackground( pDisplay, pBrushGC_, - WhitePixel(pDisplay, DefaultScreen(pDisplay)) ); - #else if( bPrinter_ ) XSetTile( pDisplay, pBrushGC_, None ); - #endif } else { @@ -757,6 +749,7 @@ void X11SalGraphics::SetXORMode( bool bSet, bool ) { bXORMode_ = bSet; bPenGC_ = FALSE; + bFontGC_ = FALSE; bBrushGC_ = FALSE; bMonoGC_ = FALSE; bCopyGC_ = FALSE; @@ -1089,7 +1082,7 @@ SystemGraphicsData X11SalGraphics::GetGraphicsData() const // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // draw a poly-polygon -bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency) +bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPolyPoly, double fTransparency ) { // nothing to do for empty polypolygons const int nOrigPolyCount = rOrigPolyPoly.count(); @@ -1127,6 +1120,8 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly basegfx::B2DTrapezoidVector aB2DTrapVector; basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aPolyPoly ); const int nTrapCount = aB2DTrapVector.size(); + if( !nTrapCount ) + return true; const bool bDrawn = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency ); return bDrawn; } @@ -1203,7 +1198,7 @@ bool X11SalGraphics::drawFilledTrapezoids( const ::basegfx::B2DTrapezoid* pB2DTr // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin) +bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin) { const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2); @@ -1238,12 +1233,17 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const : basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() ); // draw tesselation result - const int nTrapCount = aB2DTrapVector.size(); - const bool bDrawOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, 0.0 ); + if( ! aB2DTrapVector.empty() ) + { + const int nTrapCount = aB2DTrapVector.size(); + const bool bDrawOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency ); - // restore the original brush GC - nBrushColor_ = aKeepBrushColor; - return bDrawOk; + // restore the original brush GC + nBrushColor_ = aKeepBrushColor; + return bDrawOk; + } + else + return true; } // get the area polygon for the line polygon @@ -1271,7 +1271,7 @@ bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const : for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) { const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) ); - bDrawOk = drawPolyPolygon( aOnePoly, 0.0 ); + bDrawOk = drawPolyPolygon( aOnePoly, fTransparency ); if( !bDrawOk ) break; } diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index 6024b66f6010..d9f81c0f67d2 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -46,11 +46,7 @@ #include "salgdi.h" #include "pspgraphics.h" #include "salvd.h" -#include "xfont.hxx" #include <vcl/sysdata.hxx> -#include "xlfd_attr.hxx" -#include "xlfd_smpl.hxx" -#include "xlfd_extd.hxx" #include "salcvt.hxx" #include "vcl/printergfx.hxx" @@ -112,391 +108,6 @@ struct _XRegion }; using namespace rtl; -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -// ---------------------------------------------------------------------------- -// -// manage X11 fonts and self rastered fonts -// -// ---------------------------------------------------------------------------- - -#ifndef _USE_PRINT_EXTENSION_ - -class FontLookup -{ - public: - - struct hash; - struct equal; - typedef ::std::hash_set< FontLookup, - FontLookup::hash, - FontLookup::equal > fl_hashset; - - private: - - rtl::OString maName; - FontWeight mnWeight; - FontItalic mnItalic; - sal_Bool mbDisplay; - - public: - - FontLookup ( ::std::list< psp::fontID >::iterator& it, - const psp::PrintFontManager& rMgr ); - FontLookup (const Xlfd& rFont); - FontLookup (const FontLookup &rRef) : - maName (rRef.maName), - mnWeight (rRef.mnWeight), - mnItalic (rRef.mnItalic), - mbDisplay(rRef.mbDisplay) - {} - ~FontLookup () - {} - - static void BuildSet (fl_hashset& rSet); - static bool InSet (const fl_hashset& rSet, const Xlfd& rXfld); - bool InSet (const fl_hashset& rSet) const; - - bool operator== (const FontLookup &rRef) const - { - return (abs(mnWeight - rRef.mnWeight) < 2) - && (mnItalic == rRef.mnItalic) - && (maName == rRef.maName) - && (mbDisplay== rRef.mbDisplay); - } - FontLookup& operator= (const FontLookup &rRef) - { - mnWeight = rRef.mnWeight; - mnItalic = rRef.mnItalic; - maName = rRef.maName; - mbDisplay= rRef.mbDisplay; - - return *this; - } - size_t Hash() const - { - return maName.hashCode (); - } - - struct equal - { - bool operator()(const FontLookup &r1, const FontLookup &r2) const - { - return r1 == r2; - } - }; - struct hash - { - size_t operator()(const FontLookup &rArg) const - { - return rArg.Hash(); - } - }; -}; - -FontLookup::FontLookup ( ::std::list< psp::fontID >::iterator& it, - const psp::PrintFontManager& rMgr ) -{ - psp::FastPrintFontInfo aInfo; - if (rMgr.getFontFastInfo (*it, aInfo)) - { - mnItalic = PspGraphics::ToFontItalic (aInfo.m_eItalic); - mnWeight = PspGraphics::ToFontWeight (aInfo.m_eWeight); - mbDisplay= aInfo.m_eType == psp::fonttype::Builtin - || aInfo.m_eType == psp::fonttype::Unknown ? False : True; - maName = rtl::OUStringToOString - ( aInfo.m_aFamilyName, - RTL_TEXTENCODING_ISO_8859_1).toAsciiLowerCase(); - - sal_Int32 n_length = maName.getLength(); - const sal_Char* p_from = maName.getStr(); - sal_Char* p_to = (sal_Char*)alloca (n_length + 1); - - sal_Int32 i, j; - for (i = 0, j = 0; i < n_length; i++) - { - if ( p_from[i] != ' ' ) - p_to[j++] = p_from[i]; - } - maName = rtl::OString (p_to, j); - if (mnItalic == ITALIC_OBLIQUE) - mnItalic = ITALIC_NORMAL; - } - else - { - mnItalic = ITALIC_DONTKNOW; - mnWeight = WEIGHT_DONTKNOW; - mbDisplay= False; - } -} - -FontLookup::FontLookup (const Xlfd& rFont) -{ - AttributeProvider* pFactory = rFont.mpFactory; - Attribute* pAttr; - - pAttr = pFactory->RetrieveSlant (rFont.mnSlant); - mnItalic = (FontItalic)pAttr->GetValue(); - pAttr = pFactory->RetrieveWeight (rFont.mnWeight); - mnWeight = (FontWeight)pAttr->GetValue(); - pAttr = pFactory->RetrieveFamily (rFont.mnFamily); - maName = pAttr->GetKey(); - - if (mnItalic == ITALIC_OBLIQUE) - mnItalic = ITALIC_NORMAL; - - mbDisplay = True; -} - -void -FontLookup::BuildSet (FontLookup::fl_hashset &rSet) -{ - ::std::list< psp::fontID > aIdList; - - psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - rMgr.getFontList( aIdList, NULL, false ); - - ::std::list< psp::fontID >::iterator it; - for (it = aIdList.begin(); it != aIdList.end(); ++it) - { - FontLookup aItem (it, rMgr); - rSet.insert (aItem); - } -} - -bool -FontLookup::InSet (const FontLookup::fl_hashset& rSet) const -{ - fl_hashset::const_iterator it = rSet.find(*this); - return it == rSet.end() ? false : true; -} - -bool -FontLookup::InSet (const FontLookup::fl_hashset& rSet, const Xlfd& rXlfd) -{ - FontLookup aNeedle (rXlfd); - return aNeedle.InSet (rSet); -} - -#endif - -// ---------------------------------------------------------------------------- -// -// SalDisplay -// -// ---------------------------------------------------------------------------- - -XlfdStorage* -SalDisplay::GetXlfdList() const -{ - if ( mpFontList != NULL ) - { - return mpFontList; - } - else - { - const_cast<SalDisplay*>(this)->mpFactory = new AttributeProvider; - const_cast<SalDisplay*>(this)->mpFontList = new XlfdStorage; - const_cast<SalDisplay*>(this)->mpFallbackFactory = new VirtualXlfd; - - int i, nFontCount; - const int nMaxCount = 64 * 1024 - 1; - Display *pDisplay = GetDisplay(); - char **ppFontList = XListFonts(pDisplay, "-*", nMaxCount, &nFontCount); - - // - // create a list of simple Xlfd font information - // - - Xlfd *pXlfdList = (Xlfd*)malloc( nFontCount * sizeof(Xlfd) ); - int nXlfdCount = 0; - - for ( i = 0; i < nFontCount; i++ ) - { - if ( pXlfdList[ nXlfdCount ].FromString(ppFontList[i], mpFactory) ) - ++nXlfdCount; - } - - XFreeFontNames( ppFontList ); - - mpFactory->AddClassification(); - // add some pretty print description - mpFactory->AddAnnotation(); - // misc feature checking - mpFactory->TagFeature(); - - // sort according to font style - qsort( pXlfdList, nXlfdCount, sizeof(Xlfd), XlfdCompare ); - -#ifndef _USE_PRINT_EXTENSION_ - // create a list of fonts already managed by the fontmanager - FontLookup::fl_hashset aSet; - FontLookup::BuildSet (aSet); -#endif - - // - // create a font list with merged encoding information - // - - BitmapXlfdStorage aBitmapList; - ScalableXlfd *pScalableFont = NULL; - - int nFrom = 0; - for ( i = 0; i < nXlfdCount; i++ ) - { - // exclude openlook glyph and cursor - Attribute *pAttr = mpFactory->RetrieveFamily(pXlfdList[i].mnFamily); - if ( pAttr->HasFeature( XLFD_FEATURE_OL_GLYPH - | XLFD_FEATURE_OL_CURSOR) ) - continue; - // exclude fonts with unknown encoding - if ( pXlfdList[i].GetEncoding() == RTL_TEXTENCODING_DONTKNOW ) - continue; - // exclude "interface system" and "interface user" - if (pAttr->HasFeature( XLFD_FEATURE_APPLICATION_FONT ) ) - continue; - // exclude fonts already managed by fontmanager, anyway keep - // gui fonts: they are candidates for GetInterfaceFont () - if (pXlfdList[i].Fonttype() == eTypeScalable) - ((VirtualXlfd*)mpFallbackFactory)->FilterInterfaceFont (pXlfdList + i); -#ifndef _USE_PRINT_EXTENSION_ - if (FontLookup::InSet (aSet, pXlfdList[i])) - continue; -#endif - Bool bSameOutline = pXlfdList[i].SameFontoutline(pXlfdList + nFrom); - XlfdFonttype eType = pXlfdList[i].Fonttype(); - - // flush the old merged font list if the name doesn't match any more - if ( !bSameOutline ) - { - mpFontList->Add( pScalableFont ); - mpFontList->Add( &aBitmapList ); - pScalableFont = NULL; - aBitmapList.Reset(); - } - - // merge the font or generate a new one - switch( eType ) - { - case eTypeScalable: - if ( pScalableFont == NULL ) - pScalableFont = new ScalableXlfd; - pScalableFont->AddEncoding(pXlfdList + i); - break; - - case eTypeBitmap: - aBitmapList.AddBitmapFont( pXlfdList + i ); - break; - - case eTypeScalableBitmap: - // ignore scaled X11 bitmap fonts because they look too ugly - default: - break; - } - - nFrom = i; - } - - // flush the merged list into the global list - mpFontList->Add( pScalableFont ); - mpFontList->Add( &aBitmapList ); - if (mpFallbackFactory->NumEncodings() > 0) - mpFontList->Add( mpFallbackFactory ); - // cleanup the list of simple font information - if ( pXlfdList != NULL ) - free( pXlfdList ); - - return mpFontList; - } -} - -// --------------------------------------------------------------------------- - -ExtendedFontStruct* -SalDisplay::GetFont( const ExtendedXlfd *pRequestedFont, - const Size& rPixelSize, sal_Bool bVertical ) const -{ - // TODO: either get rid of X11 fonts or get rid of the non-hashmapped cache - if( !m_pFontCache ) - { - m_pFontCache = new SalFontCache( 64, 64, 16 ); // ??? - } - else - { - ExtendedFontStruct *pItem; - for ( pItem = m_pFontCache->First(); - pItem != NULL; - pItem = m_pFontCache->Next() ) - { - if ( pItem->Match(pRequestedFont, rPixelSize, bVertical) ) - { - if( m_pFontCache->GetCurPos() ) - { - m_pFontCache->Remove( pItem ); - m_pFontCache->Insert( pItem, 0UL ); - } - return pItem; - } - } - } - - // before we expand the cache, we look for very old and unused items - if( m_pFontCache->Count() >= 64 ) - { - ExtendedFontStruct *pItem; - for ( pItem = m_pFontCache->Last(); - pItem != NULL; - pItem = m_pFontCache->Prev() ) - { - if( 1 == pItem->GetRefCount() ) - { - m_pFontCache->Remove( pItem ); - pItem->ReleaseRef(); - if( m_pFontCache->Count() < 64 ) - break; - } - } - } - - ExtendedFontStruct *pItem = new ExtendedFontStruct( GetDisplay(), - rPixelSize, bVertical, - const_cast<ExtendedXlfd*>(pRequestedFont) ); - m_pFontCache->Insert( pItem, 0UL ); - pItem->AddRef(); - - return pItem; -} - -// --------------------------------------------------------------------------- - -void -SalDisplay::DestroyFontCache() -{ - if( m_pFontCache ) - { - ExtendedFontStruct *pItem = m_pFontCache->First(); - while( pItem ) - { - delete pItem; - pItem = m_pFontCache->Next(); - } - delete m_pFontCache; - } - if( mpFontList ) - { - mpFontList->Dispose(); - delete mpFontList; - } - if ( mpFactory ) - { - delete mpFactory; - } - - m_pFontCache = (SalFontCache*)NULL; - mpFontList = (XlfdStorage*)NULL; - mpFactory = (AttributeProvider*)NULL; -} - // =========================================================================== // PspKernInfo allows on-demand-querying of psprint provided kerning info (#i29881#) @@ -538,7 +149,7 @@ void PspKernInfo::Initialize() const // ---------------------------------------------------------------------------- GC -X11SalGraphics::SelectFont() +X11SalGraphics::GetFontGC() { Display *pDisplay = GetXDisplay(); @@ -549,18 +160,10 @@ X11SalGraphics::SelectFont() values.fill_rule = EvenOddRule; // Pict import/ Gradient values.graphics_exposures = False; values.foreground = nTextPixel_; -#ifdef _USE_PRINT_EXTENSION_ - values.background = xColormap_->GetWhitePixel(); - pFontGC_ = XCreateGC( pDisplay, hDrawable_, - GCSubwindowMode | GCFillRule - | GCGraphicsExposures | GCBackground | GCForeground, - &values ); -#else pFontGC_ = XCreateGC( pDisplay, hDrawable_, GCSubwindowMode | GCFillRule | GCGraphicsExposures | GCForeground, &values ); -#endif } if( !bFontGC_ ) { @@ -594,8 +197,6 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev // release all no longer needed font resources for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) { - mXFont[i] = NULL; // ->ReleaseRef() - if( mpServerFont[i] != NULL ) { // old server side font is no longer referenced @@ -614,18 +215,6 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev if( !pEntry->mpFontData ) return false; - // handle the request for a native X11-font - if( ImplX11FontData::CheckFontData( *pEntry->mpFontData ) ) - { - const ImplX11FontData* pRequestedFont = static_cast<const ImplX11FontData*>( pEntry->mpFontData ); - const ExtendedXlfd& rX11Font = pRequestedFont->GetExtendedXlfd(); - - Size aReqSize( pEntry->mnWidth, pEntry->mnHeight ); - mXFont[ nFallbackLevel ] = GetDisplay()->GetFont( &rX11Font, aReqSize, bFontVertical_ ); - bFontGC_ = FALSE; - return true; - } - // handle the request for a non-native X11-font => use the GlyphCache ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry ); if( pServerFont != NULL ) @@ -674,83 +263,6 @@ void ImplServerFontEntry::HandleFontOptions( void ) //-------------------------------------------------------------------------- -inline sal_Unicode SwapBytes( const sal_Unicode nIn ) -{ - return ((nIn >> 8) & 0x00ff) | ((nIn & 0x00ff) << 8); -} - -// draw string in a specific multibyte encoding -static void -ConvertTextItem16( XTextItem16* pTextItem, rtl_TextEncoding nEncoding ) -{ - if ( (pTextItem == NULL) || (pTextItem->nchars <= 0) ) - return; - - SalConverterCache* pCvt = SalConverterCache::GetInstance(); - // convert the string into the font encoding - sal_Size nSize; - sal_Size nBufferSize = pTextItem->nchars * 2; - sal_Char *pBuffer = (sal_Char*)alloca( nBufferSize ); - - nSize = pCvt->ConvertStringUTF16( (sal_Unicode*)pTextItem->chars, pTextItem->nchars, - pBuffer, nBufferSize, nEncoding); - - sal_Char *pTextChars = (sal_Char*)pTextItem->chars; - unsigned int n = 0, m = 0; - - if ( nEncoding == RTL_TEXTENCODING_GB_2312 - || nEncoding == RTL_TEXTENCODING_GBT_12345 - || nEncoding == RTL_TEXTENCODING_GBK - || nEncoding == RTL_TEXTENCODING_BIG5 ) - { - // GB and Big5 needs special treatment since chars can be single or - // double byte: encoding is - // [ 0x00 - 0x7f ] | [ 0x81 - 0xfe ] [ 0x40 - 0x7e 0x80 - 0xfe ] - while ( n < nSize ) - { - if ( (unsigned char)pBuffer[ n ] < 0x80 ) - { - pTextChars[ m++ ] = 0x0; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - else - { - pTextChars[ m++ ] = pBuffer[ n++ ]; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - } - pTextItem->nchars = m / 2; - } - else - if ( pCvt->IsSingleByteEncoding(nEncoding) ) - { - // Single Byte encoding has to be padded - while ( n < nSize ) - { - pTextChars[ m++ ] = 0x0; - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - pTextItem->nchars = nSize; - } - else - { - while ( n < nSize ) - { - pTextChars[ m++ ] = pBuffer[ n++ ]; - } - pTextItem->nchars = nSize / 2; - } - - // XXX FIXME - if ( (nEncoding == RTL_TEXTENCODING_GB_2312) - || (nEncoding == RTL_TEXTENCODING_EUC_KR) ) - { - for (unsigned int n_char = 0; n_char < m; n_char++ ) - pTextChars[ n_char ] &= 0x7F; - } -} - -//-------------------------------------------------------------------------- namespace { class CairoWrapper @@ -1289,7 +801,7 @@ bool X11SalGraphics::DrawServerAAForcedString( const ServerFontLayout& rLayout ) } // prepare context - GC nGC = SelectFont(); + GC nGC = GetFontGC(); XGCValues aGCVal; XGetGCValues( pDisplay, nGC, GCForeground, &aGCVal ); @@ -1376,7 +888,7 @@ void X11SalGraphics::DrawServerSimpleFontString( const ServerFontLayout& rSalLay X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer(); Display* pDisplay = GetXDisplay(); - GC nGC = SelectFont(); + GC nGC = GetFontGC(); XGCValues aGCVal; aGCVal.fill_style = FillStippled; @@ -1439,75 +951,13 @@ void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) //-------------------------------------------------------------------------- -void X11SalGraphics::DrawStringUCS2MB( ExtendedFontStruct& rFont, - const Point& rPoint, const sal_Unicode* pStr, int nLength ) +const ImplFontCharMap* X11SalGraphics::GetImplFontCharMap() const { - Display* pDisplay = GetXDisplay(); - GC nGC = SelectFont(); - - if( rFont.GetAsciiEncoding() == RTL_TEXTENCODING_UNICODE ) - { - // plain Unicode, can handle all chars and can be handled straight forward - XFontStruct* pFontStruct = rFont.GetFontStruct( RTL_TEXTENCODING_UNICODE ); - if( !pFontStruct ) - return; - - XSetFont( pDisplay, nGC, pFontStruct->fid ); - - #ifdef OSL_LITENDIAN - sal_Unicode *pBuffer = (sal_Unicode*)alloca( nLength * sizeof(sal_Unicode) ); - for ( int i = 0; i < nLength; i++ ) - pBuffer[ i ] = SwapBytes(pStr[ i ]) ; - #else - sal_Unicode *pBuffer = const_cast<sal_Unicode*>(pStr); - #endif - - XDrawString16( pDisplay, hDrawable_, nGC, rPoint.X(), rPoint.Y(), (XChar2b*)pBuffer, nLength ); - } - else - { - XTextItem16 *pTextItem = (XTextItem16*)alloca( nLength * sizeof(XTextItem16) ); - XChar2b *pMBChar = (XChar2b*)pStr; - int nItem = 0; - - DBG_ASSERT( nLength<=1, "#i49902# DrawStringUCS2MB with nLength>1 => problems with XOrg6.8.[0123]"); - - for( int nChar = 0; nChar < nLength; ++nChar ) - { - rtl_TextEncoding nEnc; - XFontStruct* pFontStruct = rFont.GetFontStruct( pStr[nChar], &nEnc ); - if( !pFontStruct ) - continue; - - pTextItem[ nItem ].chars = pMBChar + nChar; - pTextItem[ nItem ].delta = 0; - pTextItem[ nItem ].font = pFontStruct->fid; - pTextItem[ nItem ].nchars = 1; - - ConvertTextItem16( &pTextItem[ nItem ], nEnc ); - ++nItem; - } - - XDrawText16( pDisplay, hDrawable_, nGC, rPoint.X(), rPoint.Y(), pTextItem, nItem ); - } -} - -//-------------------------------------------------------------------------- - -ImplFontCharMap* X11SalGraphics::GetImplFontCharMap() const -{ - // TODO: get ImplFontCharMap directly from fonts if( !mpServerFont[0] ) -#if 0 // RIP XLFD fonts - if( mXFont[0] ) - // TODO?: nPairCount = mXFont[0]->GetFontCodeRanges( NULL ); -#endif return NULL; - CmapResult aCmapResult; - if( !mpServerFont[0]->GetFontCodeRanges( aCmapResult ) ) - return NULL; - return new ImplFontCharMap( aCmapResult ); + const ImplFontCharMap* pIFCMap = mpServerFont[0]->GetImplFontCharMap(); + return pIFCMap; } // ---------------------------------------------------------------------------- @@ -1582,15 +1032,6 @@ void RegisterFontSubstitutors( ImplDevFontList* ); void X11SalGraphics::GetDevFontList( ImplDevFontList *pList ) { - // allow disabling of native X11 fonts - static const char* pEnableX11FontStr = getenv( "SAL_ENABLE_NATIVE_XFONTS" ); - if( pEnableX11FontStr && (pEnableX11FontStr[0] != '0') ) - { - // announce X11 fonts - XlfdStorage* pX11FontList = GetDisplay()->GetXlfdList(); - pX11FontList->AnnounceFonts( pList ); - } - // prepare the GlyphCache using psprint's font infos X11GlyphCache& rGC = X11GlyphCache::GetInstance(); @@ -1763,18 +1204,15 @@ bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, // ---------------------------------------------------------------------------- void -X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric ) +X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel ) { - if( mpServerFont[0] != NULL ) + if( nFallbackLevel >= MAX_FALLBACK ) + return; + + if( mpServerFont[nFallbackLevel] != NULL ) { long rDummyFactor; - mpServerFont[0]->FetchFontMetric( *pMetric, rDummyFactor ); - } - else if( mXFont[0] != NULL ) - { - mXFont[0]->ToImplFontMetricData( pMetric ); - if ( bFontVertical_ ) - pMetric->mnOrientation = 0; + mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor ); } } @@ -1863,10 +1301,6 @@ SalLayout* X11SalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe #endif pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); } - else if( mXFont[ nFallbackLevel ] ) - pLayout = new X11FontLayout( *mXFont[ nFallbackLevel ] ); - else - pLayout = NULL; return pLayout; } @@ -1930,7 +1364,6 @@ BOOL X11SalGraphics::CreateFontSubset( const void* X11SalGraphics::GetEmbedFontData( const ImplFontData* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen ) { -#ifndef _USE_PRINT_EXTENSION_ // in this context the pFont->GetFontId() is a valid PSP // font since they are the only ones left after the PDF // export has filtered its list of subsettable fonts (for @@ -1938,25 +1371,19 @@ const void* X11SalGraphics::GetEmbedFontData( const ImplFontData* pFont, const s // be to have the GlyphCache search for the ImplFontData pFont psp::fontID aFont = pFont->GetFontId(); return PspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen ); -#else - return NULL; -#endif } //-------------------------------------------------------------------------- void X11SalGraphics::FreeEmbedFontData( const void* pData, long nLen ) { -#ifndef _USE_PRINT_EXTENSION_ PspGraphics::DoFreeEmbedFontData( pData, nLen ); -#endif } //-------------------------------------------------------------------------- const Ucs2SIntMap* X11SalGraphics::GetFontEncodingVector( const ImplFontData* pFont, const Ucs2OStrMap** pNonEncoded ) { -#ifndef _USE_PRINT_EXTENSION_ // in this context the pFont->GetFontId() is a valid PSP // font since they are the only ones left after the PDF // export has filtered its list of subsettable fonts (for @@ -1964,9 +1391,6 @@ const Ucs2SIntMap* X11SalGraphics::GetFontEncodingVector( const ImplFontData* pF // be to have the GlyphCache search for the ImplFontData pFont psp::fontID aFont = pFont->GetFontId(); return PspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded ); -#else - return NULL; -#endif } //-------------------------------------------------------------------------- diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx index 3491622f783c..ece724d717cb 100644 --- a/vcl/unx/source/gdi/salprnpsp.cxx +++ b/vcl/unx/source/gdi/salprnpsp.cxx @@ -54,6 +54,8 @@ #include "vcl/svapp.hxx" #include "vcl/jobset.h" #include "vcl/print.h" +#include "vcl/print.hxx" +#include "vcl/pdfwriter.hxx" #include "vcl/salptype.hxx" #include "vcl/printerinfomanager.hxx" @@ -63,6 +65,7 @@ using namespace psp; using namespace rtl; +using namespace com::sun::star; /* * static helpers @@ -617,6 +620,7 @@ BOOL PspSalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pJobSetup ) // copy everything to job setup copyJobDataToJobSetup( pJobSetup, aInfo ); + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, m_aJobData ); return TRUE; } return FALSE; @@ -694,6 +698,18 @@ BOOL PspSalInfoPrinter::SetData( pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : NULL; + + // some PPD files do not specify the standard paper names (e.g. C5 instead of EnvC5) + // try to find the correct paper anyway using the size + if( pKey && ! pValue && pJobSetup->mePaperFormat != PAPER_USER ) + { + PaperInfo aInfo( pJobSetup->mePaperFormat ); + aPaper = aData.m_pParser->matchPaper( + TenMuToPt( aInfo.getWidth() ), + TenMuToPt( aInfo.getHeight() ) ); + pValue = pKey->getValueCaseInsensitive( aPaper ); + } + if( ! ( pKey && pValue && aData.m_aContext.setValue( pKey, pValue, false ) == pValue ) ) return FALSE; } @@ -879,9 +895,26 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT case PRINTER_CAPABILITIES_FAX: return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "fax" ) ? 1 : 0; case PRINTER_CAPABILITIES_PDF: - return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "pdf" ) ? 1 : 0; + if( PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "pdf" ) ) + return 1; + else + { + // see if the PPD contains a value to set Collate to True + JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ); + if( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + return aData.m_nPDFDevice > 0 ? 1 : 0; + } case PRINTER_CAPABILITIES_EXTERNALDIALOG: return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "external_dialog" ) ? 1 : 0; + case PRINTER_CAPABILITIES_USEPULLMODEL: + { + // see if the PPD contains a value to set Collate to True + JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ); + if( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + return aData.m_nPDFDevice > 0 ? 1 : 0; + } default: break; }; return 0; @@ -897,6 +930,7 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT : m_bFax( false ), m_bPdf( false ), m_bSwallowFaxNo( false ), + m_bIsPDFWriterJob( false ), m_pGraphics( NULL ), m_nCopies( 1 ), m_bCollate( false ), @@ -1008,22 +1042,28 @@ BOOL PspSalPrinter::StartJob( BOOL PspSalPrinter::EndJob() { - BOOL bSuccess = m_aPrintJob.EndJob(); - - if( bSuccess ) + BOOL bSuccess = FALSE; + if( m_bIsPDFWriterJob ) + bSuccess = TRUE; + else { - // check for fax - if( m_bFax ) - { + bSuccess = m_aPrintJob.EndJob(); - const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); - // sendAFax removes the file after use - bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand ); - } - else if( m_bPdf ) + if( bSuccess ) { - const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); - bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand ); + // check for fax + if( m_bFax ) + { + + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + // sendAFax removes the file after use + bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand ); + } + else if( m_bPdf ) + { + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand ); + } } } vcl_sal::PrinterUpdate::jobEnded(); @@ -1076,6 +1116,271 @@ ULONG PspSalPrinter::GetErrorCode() return 0; } +// ----------------------------------------------------------------------- + +struct PDFNewJobParameters +{ + Size maPageSize; + USHORT mnPaperBin; + + PDFNewJobParameters( const Size& i_rSize = Size(), + USHORT i_nPaperBin = 0xffff ) + : maPageSize( i_rSize ), mnPaperBin( i_nPaperBin ) {} + + bool operator!=(const PDFNewJobParameters& rComp ) const + { + Size aCompLSSize( rComp.maPageSize.Height(), rComp.maPageSize.Width() ); + return + (maPageSize != rComp.maPageSize && maPageSize != aCompLSSize) + || mnPaperBin != rComp.mnPaperBin + ; + } + + bool operator==(const PDFNewJobParameters& rComp) const + { + return ! this->operator!=(rComp); + } +}; + +struct PDFPrintFile +{ + rtl::OUString maTmpURL; + PDFNewJobParameters maParameters; + + PDFPrintFile( const rtl::OUString& i_rURL, const PDFNewJobParameters& i_rNewParameters ) + : maTmpURL( i_rURL ) + , maParameters( i_rNewParameters ) {} +}; + +BOOL PspSalPrinter::StartJob( const String* i_pFileName, const String& i_rJobName, const String& i_rAppName, + ImplJobSetup* i_pSetupData, vcl::PrinterController& i_rController ) +{ + OSL_TRACE( "StartJob with controller: pFilename = %s", i_pFileName ? rtl::OUStringToOString( *i_pFileName, RTL_TEXTENCODING_UTF8 ).getStr() : "<nil>" ); + // mark for endjob + m_bIsPDFWriterJob = true; + // reset IsLastPage + i_rController.setLastPage( sal_False ); + + // update job data + if( i_pSetupData ) + JobData::constructFromStreamBuffer( i_pSetupData->mpDriverData, i_pSetupData->mnDriverDataLen, m_aJobData ); + + OSL_ASSERT( m_aJobData.m_nPDFDevice > 0 ); + m_aJobData.m_nPDFDevice = 1; + + // 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; + } + + int nCopies = i_rController.getPrinter()->GetCopyCount(); + bool bCollate = i_rController.getPrinter()->IsCollateCopy(); + + // notify start of real print job + i_rController.jobStarted(); + + // setup PDFWriter context + vcl::PDFWriter::PDFWriterContext aContext; + aContext.Version = vcl::PDFWriter::PDF_1_4; + aContext.Tagged = false; + aContext.EmbedStandardFonts = true; + aContext.DocumentLocale = Application::GetSettings().GetLocale(); + + // prepare doc info + aContext.DocumentInfo.Title = i_rJobName; + aContext.DocumentInfo.Creator = i_rAppName; + aContext.DocumentInfo.Producer = i_rAppName; + + // define how we handle metafiles in PDFWriter + vcl::PDFWriter::PlayMetafileContext aMtfContext; + aMtfContext.m_bOnlyLosslessCompression = true; + + boost::shared_ptr<vcl::PDFWriter> pWriter; + std::vector< PDFPrintFile > aPDFFiles; + boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); + int nAllPages = i_rController.getFilteredPageCount(); + i_rController.createProgressDialog(); + bool bAborted = false; + PDFNewJobParameters aLastParm; + + aContext.DPIx = pPrinter->ImplGetDPIX(); + aContext.DPIy = pPrinter->ImplGetDPIY(); + for( int nPage = 0; nPage < nAllPages && ! bAborted; nPage++ ) + { + if( nPage == nAllPages-1 ) + i_rController.setLastPage( sal_True ); + + // get the page's metafile + GDIMetaFile aPageFile; + vcl::PrinterController::PageSize aPageSize = i_rController.getFilteredPageFile( nPage, aPageFile ); + if( i_rController.isProgressCanceled() ) + { + bAborted = true; + if( nPage != nAllPages-1 ) + { + i_rController.createProgressDialog(); + i_rController.setLastPage( sal_True ); + i_rController.getFilteredPageFile( nPage, aPageFile ); + } + } + else + { + pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); + pPrinter->SetPaperSizeUser( aPageSize.aSize, true ); + PDFNewJobParameters aNewParm( pPrinter->GetPaperSize(), pPrinter->GetPaperBin() ); + + // create PDF writer on demand + // either on first page + // or on paper format change - cups does not support multiple paper formats per job (yet?) + // so we need to start a new job to get a new paper format from the printer + // orientation switches (that is switch of height and width) is handled transparently by CUPS + if( ! pWriter || + (aNewParm != aLastParm && ! i_pFileName ) ) + { + if( pWriter ) + { + pWriter->Emit(); + } + // produce PDF file + OUString aPDFUrl; + if( i_pFileName ) + aPDFUrl = *i_pFileName; + else + osl_createTempFile( NULL, NULL, &aPDFUrl.pData ); + // normalize to file URL + if( aPDFUrl.compareToAscii( "file:", 5 ) != 0 ) + { + // this is not a file URL, but it should + // form it into a osl friendly file URL + rtl::OUString aTmp; + osl_getFileURLFromSystemPath( aPDFUrl.pData, &aTmp.pData ); + aPDFUrl = aTmp; + } + // save current file and paper format + aLastParm = aNewParm; + aPDFFiles.push_back( PDFPrintFile( aPDFUrl, aNewParm ) ); + // update context + aContext.URL = aPDFUrl; + + // create and initialize PDFWriter + #if defined __SUNPRO_CC + #pragma disable_warn + #endif + pWriter.reset( new vcl::PDFWriter( aContext, uno::Reference< beans::XMaterialHolder >() ) ); + #if defined __SUNPRO_CC + #pragma enable_warn + #endif + } + + pWriter->NewPage( TenMuToPt( aNewParm.maPageSize.Width() ), + TenMuToPt( aNewParm.maPageSize.Height() ), + vcl::PDFWriter::Portrait ); + + pWriter->PlayMetafile( aPageFile, aMtfContext, NULL ); + } + } + + // emit the last file + if( pWriter ) + pWriter->Emit(); + + // handle collate, copy count and multiple jobs correctly + int nOuterJobs = 1; + if( bSinglePrintJobs ) + { + nOuterJobs = nCopies; + m_aJobData.m_nCopies = 1; + } + else + { + if( bCollate ) + { + if( aPDFFiles.size() == 1 && pPrinter->HasSupport( SUPPORT_COLLATECOPY ) ) + { + m_aJobData.setCollate( true ); + m_aJobData.m_nCopies = nCopies; + } + else + { + nOuterJobs = nCopies; + m_aJobData.m_nCopies = 1; + } + } + else + { + m_aJobData.setCollate( false ); + m_aJobData.m_nCopies = nCopies; + } + } + + // spool files + if( ! i_pFileName && ! bAborted ) + { + bool bFirstJob = true; + for( int nCurJob = 0; nCurJob < nOuterJobs; nCurJob++ ) + { + for( size_t i = 0; i < aPDFFiles.size(); i++ ) + { + oslFileHandle pFile = NULL; + osl_openFile( aPDFFiles[i].maTmpURL.pData, &pFile, osl_File_OpenFlag_Read ); + if( pFile ) + { + osl_setFilePos( pFile, osl_Pos_Absolut, 0 ); + std::vector< char > buffer( 0x10000, 0 ); + // update job data with current page size + Size aPageSize( aPDFFiles[i].maParameters.maPageSize ); + m_aJobData.setPaper( TenMuToPt( aPageSize.Width() ), TenMuToPt( aPageSize.Height() ) ); + // update job data with current paperbin + m_aJobData.setPaperBin( aPDFFiles[i].maParameters.mnPaperBin ); + + // spool current file + FILE* fp = PrinterInfoManager::get().startSpool( pPrinter->GetName(), i_rController.isDirectPrint() ); + if( fp ) + { + sal_uInt64 nBytesRead = 0; + do + { + osl_readFile( pFile, &buffer[0], buffer.size(), &nBytesRead ); + if( nBytesRead > 0 ) + fwrite( &buffer[0], 1, nBytesRead, fp ); + } while( nBytesRead == buffer.size() ); + rtl::OUStringBuffer aBuf( i_rJobName.Len() + 8 ); + aBuf.append( i_rJobName ); + if( i > 0 || nCurJob > 0 ) + { + aBuf.append( sal_Unicode(' ') ); + aBuf.append( sal_Int32( i + nCurJob * aPDFFiles.size() ) ); + } + PrinterInfoManager::get().endSpool( pPrinter->GetName(), aBuf.makeStringAndClear(), fp, m_aJobData, bFirstJob ); + bFirstJob = false; + } + } + osl_closeFile( pFile ); + } + } + } + + // job has been spooled + i_rController.setJobState( bAborted ? view::PrintableState_JOB_ABORTED : view::PrintableState_JOB_SPOOLED ); + + // clean up the temporary PDF files + if( ! i_pFileName || bAborted ) + { + for( size_t i = 0; i < aPDFFiles.size(); i++ ) + { + osl_removeFile( aPDFFiles[i].maTmpURL.pData ); + OSL_TRACE( "removed print PDF file %s\n", rtl::OUStringToOString( aPDFFiles[i].maTmpURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + return TRUE; +} + + + /* * vcl::PrinterUpdate */ diff --git a/vcl/unx/source/gdi/xfont.cxx b/vcl/unx/source/gdi/xfont.cxx deleted file mode 100644 index f6d19909cd4a..000000000000 --- a/vcl/unx/source/gdi/xfont.cxx +++ /dev/null @@ -1,780 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#include <salunx.h> -#include "xfont.hxx" -#include "xlfd_extd.hxx" -#include "salcvt.hxx" -#include <tools/string.hxx> -#include <vcl/outfont.hxx> -#include <saldisp.hxx> -#include <salgdi.h> - -// for GetMirroredChar -#include <vcl/svapp.hxx> - -#if OSL_DEBUG_LEVEL > 1 -#include <cstdio> -#endif - -#include <algorithm> - -#define VCLASS_ROTATE 0 -#define VCLASS_ROTATE_REVERSE 1 -#define VCLASS_TRANSFORM1 2 -#define VCLASS_TRANSFORM2 3 -#define VCLASS_CJK 4 -#define VCLASS_DONTKNOW 5 -#define VCLASS_FONT_NUM 2 // Other than rotate and rotate_reverse, - // don't have spacial font - -// Select the max size of a font, which is token for real -// This routine is (and should be) called only once, the result should be -// stored in some static variable - -static int GetMaxFontHeight() -{ - static int nMaxFontHeight = 0; - if( nMaxFontHeight <= 0 ) - { - const char *pFontHeight = getenv ("SAL_MAXFONTHEIGHT"); - if( pFontHeight ) - nMaxFontHeight = atoi( pFontHeight ); - static const int DEFAULT_MAXFONTHEIGHT = 250; - if (nMaxFontHeight <= 20) - nMaxFontHeight = DEFAULT_MAXFONTHEIGHT; - } - - return nMaxFontHeight; -} - - -ExtendedFontStruct::ExtendedFontStruct( Display* pDisplay, const Size& rPixelSize, - sal_Bool bVertical, ExtendedXlfd* pXlfd ) : - mpDisplay( pDisplay ), - maPixelSize( rPixelSize ), - mfXScale(1.0), mfYScale(1.0), - mbVertical( bVertical ), - mnCachedEncoding( RTL_TEXTENCODING_DONTKNOW ), - mpXlfd( pXlfd ), - mpRangeCodes(NULL), - mnRangeCount(-1) -{ - if( !maPixelSize.Width() ) - maPixelSize.Width() = maPixelSize.Height(); - mnAsciiEncoding = GetAsciiEncoding (NULL); - mnDefaultWidth = GetDefaultWidth(); - - mpXFontStruct = (XFontStruct**)calloc( mpXlfd->NumEncodings(), - sizeof(XFontStruct*) ); -} - -ExtendedFontStruct::~ExtendedFontStruct() -{ - delete[] mpRangeCodes; - - for ( int nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ ) - if ( mpXFontStruct[nIdx] != NULL ) - XFreeFont( mpDisplay, mpXFontStruct[nIdx] ); - - free(mpXFontStruct); -} - -rtl_TextEncoding -ExtendedFontStruct::GetAsciiEncoding( int *pAsciiRange ) const -{ - return mpXlfd->GetAsciiEncoding( pAsciiRange ); -} - -FontPitch -ExtendedFontStruct::GetSpacing( rtl_TextEncoding nEncoding ) -{ - return mpXlfd->GetPitch( nEncoding ); -} - -static XFontStruct* -LoadXFont (Display* pDisplay, const char* pFontName) -{ - XFontStruct* pFont = XLoadQueryFont (pDisplay, pFontName); - if ((pFont != NULL) && (pFont->fid == 0)) - pFont->fid = XLoadFont(pDisplay, pFontName); - -#ifdef HDU_DEBUG - fprintf( stderr, "XLoadFont \"%s\" => %d\n", pFontName, (pFont!= NULL) ); -#endif - return pFont; -} - -int -ExtendedFontStruct::LoadEncoding( rtl_TextEncoding nEncoding ) -{ - int nIdx = mpXlfd->GetEncodingIdx( nEncoding ); - if ( (nIdx < 0) || (mpXFontStruct[ nIdx ] != NULL) ) - return nIdx; - - // limit font height that gets requested from the XServer - // see BugId #44528# FontWork (-> #45038#) and as well Bug #47127# - int nReqPixelHeight = maPixelSize.Height(); - if( nReqPixelHeight > GetMaxFontHeight() ) - nReqPixelHeight = GetMaxFontHeight(); - else if( nReqPixelHeight < 2 ) - nReqPixelHeight = 2; - - // get the X11 font from a matching XLFD - ByteString aFontName; - mpXlfd->ToString( aFontName, nReqPixelHeight, nEncoding ); - mpXFontStruct[ nIdx ] = LoadXFont( mpDisplay, aFontName.GetBuffer() ); - if (mpXFontStruct[nIdx] == NULL) - mpXFontStruct[nIdx] = LoadXFont( mpDisplay, "fixed" ); - - // calculate correction factors to improve matching - // the selected font size to the used bitmap font - int nRealPixelSize = mpXlfd->GetPixelSize(); - if( !nRealPixelSize ) // check for scalable mpXlfd - nRealPixelSize = nReqPixelHeight; - if( nRealPixelSize && (nRealPixelSize != maPixelSize.Width()) ) - mfXScale = (float)maPixelSize.Width() / nRealPixelSize; - if( nRealPixelSize && (nRealPixelSize != maPixelSize.Height()) ) - mfYScale = (float)maPixelSize.Height() / nRealPixelSize; - - return nIdx; -} - -XFontStruct* -ExtendedFontStruct::GetFontStruct( rtl_TextEncoding nEncoding ) -{ - int nIdx = LoadEncoding( nEncoding ); - return nIdx < 0 ? NULL : mpXFontStruct[nIdx] ; -} - -bool -ExtendedFontStruct::GetFontBoundingBox( XCharStruct *pCharStruct, - int *pAscent, int *pDescent ) -{ - pCharStruct->lbearing = 0; - pCharStruct->rbearing = 0; - pCharStruct->width = 0; - pCharStruct->ascent = 0; - pCharStruct->descent = 0; - - *pAscent = 0; - *pDescent = 0; - - int nIdx; - - // check if there is at least one encoding already loaded - bool bEmpty = true; - for ( nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ ) - bEmpty &= (mpXFontStruct[nIdx] == NULL); - if ( bEmpty ) - LoadEncoding( mpXlfd->GetAsciiEncoding() ); - - // get the max bounding box from all font structs - for ( nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ ) - if ( mpXFontStruct[ nIdx ] != NULL ) - { - *pAscent = std::max( mpXFontStruct[nIdx]->ascent, *pAscent ); - *pDescent = std::max( mpXFontStruct[nIdx]->descent, *pDescent ); - - XCharStruct* pMaxBounds = &(mpXFontStruct[nIdx]->max_bounds); - - pCharStruct->lbearing = std::max( pMaxBounds->lbearing, - pCharStruct->lbearing ); - pCharStruct->rbearing = std::max( pMaxBounds->rbearing, - pCharStruct->rbearing ); - pCharStruct->width = std::max( pMaxBounds->width, - pCharStruct->width ); - pCharStruct->ascent = std::max( pMaxBounds->ascent, - pCharStruct->ascent ); - pCharStruct->descent = std::max( pMaxBounds->descent, - pCharStruct->descent ); - } - - // apply correction factors to better match selected size to available size - if( mfYScale != 1.0 ) - { - *pAscent = int(*pAscent * mfYScale); - *pDescent = int(*pDescent * mfYScale); - pCharStruct->ascent = (short int)(pCharStruct->ascent * mfYScale); - pCharStruct->descent = (short int)(pCharStruct->descent * mfYScale); - } - if( mfXScale != 1.0 ) - { - pCharStruct->lbearing = (short int)(pCharStruct->lbearing * mfXScale); - pCharStruct->rbearing = (short int)(pCharStruct->rbearing * mfXScale); - pCharStruct->width = (short int)(pCharStruct->width * mfXScale); - } - - return (pCharStruct->width > 0); -} - -bool -ExtendedFontStruct::ToImplFontMetricData(ImplFontMetricData *pFontMetric) -{ - pFontMetric->mnOrientation = 0; - pFontMetric->mnSlant = 0; - pFontMetric->mbDevice = true; - pFontMetric->mbScalableFont = mpXlfd->IsScalable(); - pFontMetric->mbKernableFont = false; - pFontMetric->mbSymbolFlag= mpXlfd->IsSymbolFont(); - pFontMetric->meFamily = mpXlfd->GetFamilyType(); - pFontMetric->meWeight = mpXlfd->GetWeight(); - pFontMetric->mePitch = mpXlfd->GetPitch(); - pFontMetric->meItalic = mpXlfd->GetSlant(); - - int nAscent, nDescent; - XCharStruct aBoundingBox; - if ( GetFontBoundingBox(&aBoundingBox, &nAscent, &nDescent) ) - { - pFontMetric->mnWidth = aBoundingBox.width; - pFontMetric->mnAscent = aBoundingBox.ascent; - pFontMetric->mnDescent = aBoundingBox.descent; - pFontMetric->mnIntLeading = std::max(0, aBoundingBox.ascent - nAscent - + aBoundingBox.descent - nDescent ); - pFontMetric->mnExtLeading = 0; // TODO!!! - return true; - } - else - { - return false; - } -} - -bool -ExtendedFontStruct::Match( const ExtendedXlfd *pXlfd, - const Size& rPixelSize, sal_Bool bVertical ) const -{ - if( mpXlfd != pXlfd ) - return false; - - if( bVertical != mbVertical ) - return FALSE; - - if( rPixelSize.Height() != maPixelSize.Height() ) - return FALSE; - - long nReqWidth = rPixelSize.Width(); - if( !nReqWidth ) - nReqWidth = rPixelSize.Height(); - if( nReqWidth != maPixelSize.Width() ) - return FALSE; - - return true; -} - -// Get an appropriate x-font that contains a glyph for the given unicode -// code point. -// This routine is designed to be called for each character in a text. -// It first checks the given encoding to optimize for the fact that two -// adjacent characters in a text most probably have the same encoding -// In the first call initialize pEncodingInOut to dontknow, this causes -// EncodingHasChar() to fail and thus bootstraps the encoding, otherwise -// make sure that the initial value of pFontInOut matches the encoding and -// that the encoding is valid for the font. -XFontStruct* -ExtendedFontStruct::GetFontStruct( sal_Unicode nChar, rtl_TextEncoding *pEncoding ) -{ - SalConverterCache *pCvt = SalConverterCache::GetInstance(); - - if ( pCvt->EncodingHasChar(mnAsciiEncoding, nChar) ) - { - *pEncoding = mnAsciiEncoding; - return GetFontStruct (mnAsciiEncoding); - } - else - if ( pCvt->EncodingHasChar(mnCachedEncoding, nChar) ) - { - *pEncoding = mnCachedEncoding; - return GetFontStruct (mnCachedEncoding); - } - else - { - for ( int nIdx = 0; nIdx < mpXlfd->NumEncodings(); nIdx++ ) - { - rtl_TextEncoding nEnc = mpXlfd->GetEncoding(nIdx); - if ( (nEnc != mnCachedEncoding) && (nEnc != mnAsciiEncoding) - && pCvt->EncodingHasChar(nEnc, nChar)) - { - mnCachedEncoding = nEnc; - *pEncoding = mnCachedEncoding; - return GetFontStruct (mnCachedEncoding); - } - } - } - - *pEncoding = RTL_TEXTENCODING_DONTKNOW; - return NULL; -} - -// --------------------------------------------------------------------------- -// utility functions to handle xfontstruct information, this is all to -// calculate charwidth information -// --------------------------------------------------------------------------- - -static bool -CharExists( const XCharStruct* pChar ) -{ - if ( pChar == NULL ) - return false; - - return pChar->width - || pChar->ascent || pChar->descent - || pChar->lbearing || pChar->rbearing; -} - -// this relies on non-null per_char information in the fontstruct -static XCharStruct* -GetCharinfo( const XFontStruct *pXFontStruct, sal_MultiByte nChar ) -{ - unsigned int nRow = nChar >> 8; - unsigned int nCol = nChar & 0xFF; - - unsigned int nMinRow = pXFontStruct->min_byte1; - unsigned int nMaxRow = pXFontStruct->max_byte1; - unsigned int nMinCol = pXFontStruct->min_char_or_byte2; - unsigned int nMaxCol = pXFontStruct->max_char_or_byte2; - - if ( nRow >= nMinRow && nRow <= nMaxRow - && nCol >= nMinCol && nCol <= nMaxCol ) - { - return &pXFontStruct->per_char[ - (nRow-nMinRow) * (nMaxCol-nMinCol+1) + (nCol-nMinCol) ]; - } - - return NULL; -} - -static sal_Size -QueryCharWidth16( Display* pDisplay, XLIB_Font nFontID, sal_MultiByte nChar, - sal_Size nDefaultWidth ) -{ - int nDirection, nFontAscent, nFontDescent; - XCharStruct aBoundingBox; - - XQueryTextExtents16( pDisplay, nFontID, (XChar2b*)&nChar, 1, - &nDirection, &nFontAscent, &nFontDescent, &aBoundingBox ); - - return CharExists( &aBoundingBox ) ? aBoundingBox.width : nDefaultWidth; -} - -#if 0 -// currently not used -static sal_Size -QueryCharWidth8( XFontStruct* pXFontStruct, sal_Char nChar, - sal_Size nDefaultWidth ) -{ - int nDirection, nFontAscent, nFontDescent; - XCharStruct aBoundingBox; - - XTextExtents( pXFontStruct, &nChar, 1, - &nDirection, &nFontAscent, &nFontDescent, &aBoundingBox ); - - return CharExists( &aBoundingBox ) ? aBoundingBox.width : nDefaultWidth; -} -#endif - -sal_Size -ExtendedFontStruct::GetDefaultWidth() -{ - return (maPixelSize.Width() + 1) / 2; -} - -// Handle single byte fonts which do not require conversion, this exploits -// the fact that unicode equals latin1 or ansi1252 in the range [0..0xff] and -// is compatible with iso8859-X at least in the range to 0x7f -sal_Size -ExtendedFontStruct::GetCharWidth8( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32* pWidthArray, rtl_TextEncoding nEncoding ) -{ - if ( !(nFrom <= nTo) ) - return 0; - - XFontStruct* pXFontStruct = GetFontStruct( nEncoding ); - if ( pXFontStruct == NULL ) - return 0; - - // query the font metrics - if ( (pXFontStruct->max_bounds.width == pXFontStruct->min_bounds.width) - || (pXFontStruct->per_char == NULL) ) - { - // fixed width font - for ( int nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ ) - *pWidthArray = pXFontStruct->max_bounds.width; - } - else - { - // variable width font - int nMinChar = pXFontStruct->min_char_or_byte2; - int nMaxChar = pXFontStruct->max_char_or_byte2; - - int nIdx = nFrom; - - for ( ; nIdx < std::min((int)nTo, nMinChar); nIdx++, pWidthArray++ ) - *pWidthArray = mnDefaultWidth; - for ( ; nIdx <= std::min((int)nTo, nMaxChar); nIdx++, pWidthArray++ ) - { - XCharStruct* pChar = &(pXFontStruct->per_char[nIdx - nMinChar]); - *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth; - } - for ( ; nIdx <= nTo; nIdx++, pWidthArray++ ) - *pWidthArray = mnDefaultWidth; - } - - // return amount of handled chars - return nTo - nFrom + 1; -} - -// Handle utf16 encoded fonts, which do not require conversion -sal_Size -ExtendedFontStruct::GetCharWidthUTF16( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32* pWidthArray ) -{ - if ( !(nFrom <= nTo) ) - return 0; - - XFontStruct* pXFontStruct = GetFontStruct( RTL_TEXTENCODING_UNICODE ); - FontPitch nSpacing = mpXlfd->GetPitch( RTL_TEXTENCODING_UNICODE ); - - if ( pXFontStruct == NULL ) - return 0; - - // query the font metrics - if ( nSpacing == PITCH_VARIABLE - && pXFontStruct->per_char == NULL) - { - // get per_char information from the server - for ( sal_Int32 nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ ) - *pWidthArray = QueryCharWidth16( mpDisplay, pXFontStruct->fid, - nIdx, mnDefaultWidth ); - } - else - if ( (pXFontStruct->max_bounds.width == pXFontStruct->min_bounds.width) - || (pXFontStruct->per_char == NULL) ) - { - // really a fixed width font - for ( sal_Int32 nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ ) - *pWidthArray = pXFontStruct->max_bounds.width; - } - else - { - // get per_char information from the xfontstruct - for ( sal_Int32 nIdx = nFrom; nIdx <= nTo; nIdx++, pWidthArray++ ) - { - XCharStruct* pChar = GetCharinfo( pXFontStruct, nIdx ); - *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth; - } - } - - // return amount of handled chars - return nTo - nFrom + 1; -} - -// handle non unicode fonts that are converted into encoding matching the -// font in fontstruct, 8 and 16 bit fonts are handled the same way -sal_Size -ExtendedFontStruct::GetCharWidth16( sal_Unicode nFrom, sal_Unicode nTo, - sal_Int32* pWidthArray, ExtendedFontStruct *pFallback ) -{ - if ( nFrom > nTo ) - return 0; - - sal_Char pBuffer[64]; - - SalConverterCache *pCvt = SalConverterCache::GetInstance(); - for ( sal_Int32 nIdx = nFrom ; nIdx <= nTo ; nIdx++, pWidthArray++ ) - { - FontPitch nSpacing; - sal_Size nSize; - sal_Unicode nUniIdx = (sal_Unicode)nIdx; - - // get a matching fontstruct - rtl_TextEncoding nEnc; - XFontStruct *pFont; - - if ( (pFont = GetFontStruct(nUniIdx, &nEnc)) != NULL ) - { - nSpacing = GetSpacing( nEnc ); - } - else - if ( (pFallback != NULL) - && ((pFont = pFallback->GetFontStruct(nUniIdx, &nEnc)) != NULL) ) - { - nSpacing = pFallback->GetSpacing( nEnc ); - } - else - if ( (pFallback != NULL) - && ((pFont = pFallback->GetFontStruct(nUniIdx = '?', &nEnc)) != NULL) ) - { - nSpacing = pFallback->GetSpacing( nEnc ); - } - else - { - // TODO What should the default value be? - nSpacing = PITCH_FIXED; - } - - if ( pFont ) - { - nSize = pCvt->ConvertStringUTF16(&nUniIdx, 1, pBuffer, sizeof(pBuffer), nEnc); - // XXX FIXME - if ((nEnc == RTL_TEXTENCODING_GB_2312) || (nEnc == RTL_TEXTENCODING_EUC_KR)) - { - for (unsigned int n_char = 0; n_char < nSize; n_char++ ) - pBuffer[ n_char ] &= 0x7F; - } - } - - // query font metrics - if ( pFont && (nSize == 1 || nSize == 2) ) - { - sal_MultiByte nChar = (nSize == 1) ? (unsigned char)pBuffer[0] : - ((sal_MultiByte)pBuffer[0] << 8) + (sal_MultiByte)pBuffer[1]; - - if ( nSpacing == PITCH_VARIABLE - && pFont->per_char == NULL) - { - // get per_char information from the x-server - *pWidthArray = QueryCharWidth16( mpDisplay, pFont->fid, - nChar, mnDefaultWidth ); - } - else - if ( (pFont->max_bounds.width == pFont->min_bounds.width) - || (pFont->per_char == NULL) ) - { - // fixed width font - *pWidthArray = pFont->max_bounds.width; - } - else - { - // get per_char information from the xfontstruct - XCharStruct* pChar = GetCharinfo( pFont, nChar ); - *pWidthArray = CharExists(pChar) ? pChar->width : mnDefaultWidth; - } - } - else - { - // conversion error - *pWidthArray = mnDefaultWidth; - } - } - - // return amount of handled chars - return nTo - nFrom + 1; -} - -sal_Size -ExtendedFontStruct::GetCharWidth( sal_Unicode cChar, sal_Int32 *pPhysicalWidth, - sal_Int32 *pLogicalWidth ) -{ - sal_Size nConverted = 0; - - // dispatch querying of metrics to most promising encoding candidate - int nAsciiRange; - rtl_TextEncoding nEncoding = mpXlfd->GetAsciiEncoding(&nAsciiRange); - if ( nEncoding == RTL_TEXTENCODING_UNICODE ) - { - // if we have a unicode encoded system font than we get the charwidth - // straight forward - nConverted = GetCharWidthUTF16( cChar, cChar, pPhysicalWidth ); - } - else - { - if ( cChar < nAsciiRange ) - { - // optimize the most frequent case, requesting only the latin1 - // chars which are mappable to a single encoding - nConverted = GetCharWidth8( cChar, cChar, pPhysicalWidth, nEncoding ); - } - - // if further requests are pending, then the according unicode - // codepoint has to be dispatched to one of the system fonts and - // converted to this fonts encoding - nConverted += GetCharWidth16( cChar + nConverted, cChar, - pPhysicalWidth + nConverted, NULL ); - } - - // convert physical width to logical width, apply correction factor if needed - *pLogicalWidth = *pPhysicalWidth; - if( mfXScale != 1.0 ) - *pLogicalWidth = sal_Int32(*pLogicalWidth * mfXScale); - - return nConverted; -} - -bool ExtendedFontStruct::HasUnicodeChar( sal_Unicode cChar ) const -{ - // #i18818# return false if there are no known encodings - if( !mnRangeCount ) - return false; - - // init unicode range cache if needed - if( mnRangeCount < 0 ) - { - mnRangeCount = mpXlfd->GetFontCodeRanges( NULL ); - if( !mnRangeCount ) - return false; - mpRangeCodes = new sal_uInt32[ 2*mnRangeCount ]; - mpXlfd->GetFontCodeRanges( mpRangeCodes ); - // TODO: make sure everything is sorted - } - - // binary search in unicode ranges - int nLower = 0; - int nMid = mnRangeCount; - int nUpper = 2 * mnRangeCount - 1; - while( nLower < nUpper ) - { - if( cChar >= mpRangeCodes[ nMid ] ) - nLower = nMid; - else - nUpper = nMid - 1; - nMid = (nLower + nUpper + 1) / 2; - } - if( (nMid == 0) && (cChar < mpRangeCodes[0]) ) - return false; - return (nMid & 1) ? false: true; -} - -int ExtendedFontStruct::GetFontCodeRanges( sal_uInt32* pCodePairs ) const -{ - // make sure unicode range cache is initialized - HasUnicodeChar(0); - - // transfer range pairs if requested - if( pCodePairs ) - { - for( int i = 0; i < 2*mnRangeCount; ++i ) - pCodePairs[i] = mpRangeCodes[i]; - } - - return mnRangeCount; -} - -// ======================================================================= - -X11FontLayout::X11FontLayout( ExtendedFontStruct& rFont ) -: mrFont( rFont ) -{} - -// ----------------------------------------------------------------------- - -bool X11FontLayout::LayoutText( ImplLayoutArgs& rArgs ) -{ - Point aNewPos( 0, 0 ); - bool bRightToLeft; - int nCharPos; - - for( nCharPos = -1; rArgs.GetNextPos( &nCharPos, &bRightToLeft ); ) - { - sal_UCS4 cChar = rArgs.mpStr[ nCharPos ]; - if( bRightToLeft ) - cChar = GetMirroredChar( cChar ); - int nGlyphIndex = cChar | GF_ISCHAR; - - // check if the font supports the char - if( !mrFont.HasUnicodeChar( cChar ) ) - { - // try to replace the failing char using the same font - const char* pApproxUTF8 = GetAutofallback( cChar ); - cChar = 0; - if( pApproxUTF8 ) - { - String aApproxStr( pApproxUTF8, RTL_TEXTENCODING_UTF8 ); - if( aApproxStr.Len() == 1 ) - { - // TODO: support Autofallback for len>1 - sal_Unicode cApprox = aApproxStr.GetChar( 0 ); - if( mrFont.HasUnicodeChar( cApprox ) ) - nGlyphIndex = (cChar = cApprox) | GF_ISCHAR; - } - } - // request fallback glyph if necessary - if( !cChar ) - { - rArgs.NeedFallback( nCharPos, bRightToLeft ); - if( rArgs.mnFlags & SAL_LAYOUT_FOR_FALLBACK ) - nGlyphIndex = 0; // drop NotDef fallback glyphs - } - } - - sal_Int32 nPhysGlyphWidth, nLogGlyphWidth; - mrFont.GetCharWidth( cChar, &nPhysGlyphWidth, &nLogGlyphWidth ); - int nGlyphFlags = (nPhysGlyphWidth > 0) ? 0 : GlyphItem::IS_IN_CLUSTER; - if( bRightToLeft ) - nGlyphFlags |= GlyphItem::IS_RTL_GLYPH; - GlyphItem aGI( nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nPhysGlyphWidth ); - aGI.mnNewWidth = nLogGlyphWidth; - AppendGlyph( aGI ); - - aNewPos.X() += nLogGlyphWidth; - } - - return (nCharPos >= 0); -} - -// ----------------------------------------------------------------------- - -void X11FontLayout::AdjustLayout( ImplLayoutArgs& rArgs ) -{ - GenericSalLayout::AdjustLayout( rArgs ); - SetOrientation( 0 ); // X11 fonts are to be rotated in upper layers -} - -// ----------------------------------------------------------------------- - -void X11FontLayout::DrawText( SalGraphics& rSalGraphics ) const -{ - static const int MAXGLYPHS = 160; - int nMaxGlyphs = GetOrientation() ? 1 : MAXGLYPHS; - - // workaround for #i49902# similar to #b6228733 with XDrawText items - // => output each item separately for non-unicode font encodings! - // this is done here instead of in DrawStringUCS2MB() because - // it needs the item positions and they are easily available here - if( mrFont.GetAsciiEncoding() != RTL_TEXTENCODING_UNICODE ) - nMaxGlyphs = 1; - - Point aPos; - sal_GlyphId aGlyphAry[ MAXGLYPHS ]; - sal_Unicode pStr[ MAXGLYPHS ]; - for( int nStart=0;;) - { - int nGlyphCount = GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart ); - if( !nGlyphCount ) - break; - - for( int i = 0; i < nGlyphCount; ++i ) - pStr[ i ] = aGlyphAry[ i ] & GF_IDXMASK; - - static_cast<X11SalGraphics&>(rSalGraphics).DrawStringUCS2MB( mrFont, aPos, pStr, nGlyphCount ); - } -} - -// ======================================================================= diff --git a/vcl/unx/source/gdi/xlfd_attr.cxx b/vcl/unx/source/gdi/xlfd_attr.cxx deleted file mode 100644 index ca49a8548afb..000000000000 --- a/vcl/unx/source/gdi/xlfd_attr.cxx +++ /dev/null @@ -1,686 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sal/alloca.h> -#include "xlfd_attr.hxx" -#include <rtl/tencinfo.h> -#include <vcl/vclenum.hxx> - -// --------------------------------------------------------------------------- -// -// -// Attribute is a container for simple name value pairs -// eg. ( "times", FAMILY_ROMAN ) or ( "demi bold", WEIGHT_SEMIBOLD ) -// enriched with an annotation which is a pretty-printed version of the -// string, i.e. "itc avant garde" would get an annotation of "Itc Avant Garde" -// -// -// --------------------------------------------------------------------------- - -// release the stored string -void -Attribute::Release() -{ - if ( mpAnnotation != NULL ) - delete mpAnnotation; - if ( mpKeyName != NULL ) - delete mpKeyName; - if ( mpName != NULL ) - free( (void*)mpName ); -} - -// get a private copy of the given argument -void -Attribute::SetName( const char *p, int nLen ) -{ - mpName = (char*)malloc( nLen + 1 ); - mnLength = nLen; - memcpy( (void*)mpName, p, mnLength ); - ((char*)mpName)[ mnLength ] = '\0'; -} - -// Compare whether two strings a equal for the first nLen bytes -// i.e. arial == arialnarrow -int -Attribute::Compare( const char *p, int nLen ) -{ - return strncmp( mpName, p, nLen ); -} - -// Get a all lowercase name with all blanks removed -const rtl::OString& -Attribute::GetKey () -{ - static rtl::OString aEmptyStr; - - if (mpKeyName != NULL) - return *mpKeyName; - if (mnLength == 0) - return aEmptyStr; - - sal_Char* pBuffer = (sal_Char*)alloca (mnLength); - - sal_Int32 i, j; - for (i = 0, j = 0; i < mnLength; i++) - { - if ( mpName[i] != ' ' ) - pBuffer[j++] = mpName[i]; - } - mpKeyName = new rtl::OString(pBuffer, j); - - return *mpKeyName; -} - -void -Attribute::InitKey () -{ - mpKeyName = NULL; -} - -// Compare two strings, they have to be equal for nLen bytes, after nLen -// bytes both strings have to be terminated either by '\0' or by '-' -// this is for comparing a string being a substring in a Xlfd with a -// zeroterminated string -Bool -Attribute::ExactMatch( const char *p, int nLen ) -{ - Bool bMatch; - if ( nLen > 0 ) - bMatch = Compare( p, nLen ) == 0; - else - bMatch = True; - if ( bMatch ) - { - char c1 = p[ nLen ]; - char c2 = mpName[ nLen ]; - bMatch = (c1 == '-' || c1 == '\0') && (c2 == '-' || c2 == '\0'); - } - - return bMatch; -} - -void -Attribute::TagFeature( unsigned short nFeature ) -{ - if ( (nFeature & XLFD_FEATURE_NARROW) - && (strstr(mpName, "narrow") != NULL) ) - { - mnFeature |= XLFD_FEATURE_NARROW; - } - - if ( (nFeature & XLFD_FEATURE_OL_CURSOR) - && (strcmp(mpName, "open look cursor") == 0) ) - { - mnFeature |= XLFD_FEATURE_OL_CURSOR; - } - - if ( (nFeature & XLFD_FEATURE_OL_GLYPH) - && (strcmp(mpName, "open look glyph") == 0) ) - { - mnFeature |= XLFD_FEATURE_OL_GLYPH; - } - - if ( (nFeature & XLFD_FEATURE_APPLICATION_FONT) - && ( (strcmp(mpName, "interface user") == 0) - || (strcmp(mpName, "interface system") == 0))) - { - mnFeature |= XLFD_FEATURE_APPLICATION_FONT; - } - - if (nFeature & XLFD_FEATURE_INTERFACE_FONT) - { - // european - if (strcmp(mpName, "arial") == 0) - mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_HQ | XLFD_FEATURE_MQ); - else - if (strcmp(mpName, "helvetica") == 0) - mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_HQ); - else - if ( (strcmp(mpName, "lucidux sans") == 0) - || (strcmp(mpName, "luxi sans") == 0)) - mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_MQ | XLFD_FEATURE_LQ); - else - if (strcmp(mpName, "charter") == 0) - mnFeature |= (XLFD_FEATURE_INTERFACE_FONT | XLFD_FEATURE_MQ); - else - // japanese - if ( (strcmp(mpName, "hg mincho l") == 0) /* Solaris: jisx0208 jisx0201 */ - || (strcmp(mpName, "heiseimin") == 0) /* Solaris: jisx0212 */ - || (strcmp(mpName, "minchol") == 0) /* TurboLinux */ - || (strcmp(mpName, "mincho") == 0)) /* Redhat 6.2 JP */ - { - mnFeature |= XLFD_FEATURE_INTERFACE_FONT; - } - else - // chinese - if ( (strcmp(mpName, "kai") == 0) /* Solaris */ - || (strcmp(mpName, "ar pl mingti2l big5") == 0)) /* TurboLinux */ - { - mnFeature |= XLFD_FEATURE_INTERFACE_FONT; - } - else - // korean - if ( (strcmp(mpName, "myeongjo") == 0)) /* Solaris */ - { - mnFeature |= XLFD_FEATURE_INTERFACE_FONT; - } - } - - if ( nFeature & XLFD_FEATURE_REDUNDANTSTYLE ) - { - switch ( mpName[0] ) - { - case '\0': - mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE; - break; - - case 'b': - if ( (strcmp(mpName, "bold") == 0) - || (strcmp(mpName, "bold italic") == 0) - || (strcmp(mpName, "bold sans") == 0) ) - mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE; - break; - - case 'd': - if ( (strcmp(mpName, "demi") == 0) - || (strcmp(mpName, "demi italic") == 0) ) - mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE; - break; - - case 'i': - if ( strcmp(mpName, "italic") == 0 ) - mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE; - break; - - case 's': - if ( (strcmp(mpName, "sans") == 0) - || (strcmp(mpName, "serif") == 0) ) - mnFeature |= XLFD_FEATURE_REDUNDANTSTYLE; - break; - } - } -} - -// given Attribute classifications, strings have to be in alphabetical -// order, since they are treated by binary search algorithm - -#define InitializeAttributeWith( p, a ) p, sizeof(p) - 1, a, 0, NULL, NULL -#define MembersOf( p ) (sizeof(p) / sizeof(p[0]) ) - -const Attribute pFamilyAttribute[] = { - { InitializeAttributeWith( "arial", FAMILY_SWISS ) }, - { InitializeAttributeWith( "arioso", FAMILY_SCRIPT ) }, - { InitializeAttributeWith( "avant garde", FAMILY_SWISS ) }, - { InitializeAttributeWith( "avantgarde", FAMILY_SWISS ) }, - { InitializeAttributeWith( "bembo", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "bookman", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "conga", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "courier", FAMILY_MODERN ) }, - { InitializeAttributeWith( "curl", FAMILY_SCRIPT ) }, - { InitializeAttributeWith( "fixed", FAMILY_MODERN ) }, - { InitializeAttributeWith( "gill", FAMILY_SWISS ) }, - { InitializeAttributeWith( "helmet", FAMILY_MODERN ) }, - { InitializeAttributeWith( "helvetica", FAMILY_SWISS ) }, - { InitializeAttributeWith( "international", FAMILY_MODERN ) }, - { InitializeAttributeWith( "lucida", FAMILY_SWISS ) }, - { InitializeAttributeWith( "new century schoolbook", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "palatino", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "roman", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "sans serif", FAMILY_SWISS ) }, - { InitializeAttributeWith( "sansserif", FAMILY_SWISS ) }, - { InitializeAttributeWith( "serf", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "serif", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "times", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "utopia", FAMILY_ROMAN ) }, - { InitializeAttributeWith( "zapf chancery", FAMILY_SCRIPT ) }, - { InitializeAttributeWith( "zapfchancery", FAMILY_SCRIPT ) } -}; - -const Attribute pWeightAttribute[] = { - { InitializeAttributeWith( "black", WEIGHT_BLACK ) }, - { InitializeAttributeWith( "bold", WEIGHT_BOLD ) }, - { InitializeAttributeWith( "book", WEIGHT_LIGHT ) }, - { InitializeAttributeWith( "demi", WEIGHT_SEMIBOLD ) }, - { InitializeAttributeWith( "demi bold", WEIGHT_SEMIBOLD ) }, - { InitializeAttributeWith( "demibold", WEIGHT_SEMIBOLD ) }, - { InitializeAttributeWith( "light", WEIGHT_LIGHT ) }, - { InitializeAttributeWith( "medium", WEIGHT_MEDIUM ) }, - { InitializeAttributeWith( "normal", WEIGHT_NORMAL ) }, - { InitializeAttributeWith( "regular", WEIGHT_NORMAL ) }, - { InitializeAttributeWith( "roman", WEIGHT_NORMAL ) }, - { InitializeAttributeWith( "semicondensed", WEIGHT_LIGHT ) }, - { InitializeAttributeWith( "ultrabold", WEIGHT_ULTRABOLD ) } -}; - -const Attribute pSlantAttribute[] = { - { InitializeAttributeWith( "i", ITALIC_NORMAL ) }, - { InitializeAttributeWith( "o", ITALIC_OBLIQUE ) }, - { InitializeAttributeWith( "r", ITALIC_NONE ) } -}; - -const Attribute pSetwidthAttribute[] = { - { InitializeAttributeWith( "bold", WIDTH_SEMI_EXPANDED ) }, - { InitializeAttributeWith( "condensed", WIDTH_CONDENSED ) }, - { InitializeAttributeWith( "double wide", WIDTH_ULTRA_EXPANDED ) }, - { InitializeAttributeWith( "expanded", WIDTH_EXPANDED ) }, - { InitializeAttributeWith( "extracondensed", WIDTH_EXTRA_CONDENSED ) }, - { InitializeAttributeWith( "extraexpanded", WIDTH_EXTRA_EXPANDED ) }, - { InitializeAttributeWith( "medium", WIDTH_NORMAL ) }, - { InitializeAttributeWith( "narrow", WIDTH_CONDENSED ) }, - { InitializeAttributeWith( "normal", WIDTH_NORMAL ) }, - { InitializeAttributeWith( "semicondensed", WIDTH_SEMI_CONDENSED ) }, - { InitializeAttributeWith( "semiexpanded", WIDTH_SEMI_EXPANDED ) }, - { InitializeAttributeWith( "ultracondensed", WIDTH_ULTRA_CONDENSED ) }, - { InitializeAttributeWith( "ultraexpanded", WIDTH_ULTRA_EXPANDED ) }, - { InitializeAttributeWith( "wide", WIDTH_EXPANDED ) } -}; - -const Attribute pEnhancedCharsetAttribute[] = { - { InitializeAttributeWith( "iso8859-1", RTL_TEXTENCODING_MS_1252 ) }, - { InitializeAttributeWith( "iso8859_1", RTL_TEXTENCODING_MS_1252 ) } -}; - -// ------------------------------------------------------------------------- -// -// String handling utility functions -// -// ------------------------------------------------------------------------- - - -void -AppendAttribute( Attribute *pAttribute, ByteString &rString ) -{ - if ( pAttribute == NULL ) - return ; - - int nLength = pAttribute->GetLength(); - char *pBuffer = (char*)alloca( nLength + 1); - - pBuffer[ 0 ] = '-'; - memcpy( pBuffer + 1, pAttribute->GetName(), nLength ); - rString.Append( pBuffer, nLength + 1); -} - -// -// Prettify the font name: make each leading character of a fontname -// uppercase. For example -// times new roman -> Times New Roman -// - -static void -ToUpper( char *pCharacter ) -{ - // replace [a,z] with [A,Z] - if ( (*pCharacter >= 97) && (*pCharacter <= 122) ) - *pCharacter -= 32; -} - -static String* -Capitalize( const char *pStr, int nLength ) -{ - char *pCopy = (char*)alloca( nLength + 1 ); - char *pPtr = pCopy; - memcpy( pPtr, pStr, nLength + 1 ); - - // loop over string data and uppercase first char and all chars - // following a space (other white space would be unexpected here) - char nPreviousChar = ' '; - while ( *pPtr ) - { - if ( nPreviousChar == ' ' ) - ToUpper( pPtr ); - nPreviousChar = *pPtr++; - } - - return new String( pCopy, RTL_TEXTENCODING_ISO_8859_1 ); -} - -String* -AnnotateString( const Attribute& rAttribute ) -{ - return Capitalize(rAttribute.GetName(), rAttribute.GetLength()); -} - -String* -AnnotateSlant( const Attribute& rAttribute ) -{ - const char* pStr = rAttribute.GetName(); - int nLen = rAttribute.GetLength(); - - static const struct { - const char *pFrom; const char *pTo; - } pTranslation[] = { - { "r", "Roman" }, - { "o", "Oblique" }, - { "i", "Italic" }, - { "ri", "Reverse Italic" }, - { "ro", "Reverse Oblique" }, - { "ot", "Other" } - }; - - for ( unsigned int i = 0; i < MembersOf(pTranslation); i++ ) - if ( strcmp(pStr, pTranslation[i].pFrom) == 0 ) - { - return new String( pTranslation[i].pTo, - RTL_TEXTENCODING_ISO_8859_1 ); - } - - return Capitalize(pStr, nLen); -} - -String* -AnnotateNone( const Attribute& ) -{ - return new String(); -} - -// --------------------------------------------------------------------------- -// -// -// manage global lists of Attributes -// since XListFonts does never list more than 64K fonts this storage does -// handle array size and indices with unsigned short values for low -// memory consumption -// -// -// --------------------------------------------------------------------------- - -AttributeStorage::AttributeStorage( unsigned short nDefaultValue ) : - mpList( NULL ), - mnSize( 0 ), - mnCount( 0 ), - mnLastmatch( 0 ), - mnDefaultValue( nDefaultValue ) -{ -} - -AttributeStorage::~AttributeStorage() -{ - if ( mpList != NULL ) - { - for ( int i = 0; i < mnCount; i++ ) - mpList[i].Release(); - free( mpList ); - } -} - -#if OSL_DEBUG_LEVEL > 1 -void -AttributeStorage::Dump() -{ - fprintf(stderr, "AttributeStorage: size=%i, used=%i\n", mnSize, mnCount); - for ( int i = 0; i < mnCount; i++ ) - { - ByteString aAnnotation = ByteString( - mpList[i].GetAnnotation(), - RTL_TEXTENCODING_ISO_8859_1 ); - fprintf(stderr, "\t%4i: <%s><len=%i><val=%i><%s>\n", i, mpList[i].GetName(), - mpList[i].GetLength(), mpList[i].GetValue(), - aAnnotation.GetBuffer() ); - } - fprintf(stderr, "\n"); -} -#endif - -Attribute* -AttributeStorage::Retrieve( unsigned short nIndex ) const -{ - return nIndex < mnCount ? &mpList[ nIndex ] : (Attribute*)NULL ; -} - -// pClassification contains a list of name-value pairs. If names in -// the AttributeStorage match those in the pClassification then -// the according value is copied. Matching means match for the length -// of the string in pClassification (i.e. arial matches arialnarrow) -// the strings in pClassification must be in alphabetical order, all -// strings Lowercase -void -AttributeStorage::AddClassification( Attribute *pClassification, - unsigned short nNum ) -{ - for ( int i = 0; i < mnCount; i++ ) - { - unsigned int nLower = 0; - unsigned int nUpper = nNum; - unsigned int nCurrent; - int nComparison = 1; - Attribute *pHaystack = 0, *pNeedle; - - pNeedle = &mpList[ i ]; - - // binary search - while ( nLower < nUpper ) - { - nCurrent = (nLower + nUpper) / 2; - pHaystack = &pClassification[ nCurrent ]; - nComparison = pNeedle->Compare( pHaystack->GetName(), - pHaystack->GetLength() ); - if (nComparison < 0) - nUpper = nCurrent; - else - if (nComparison > 0) - nLower = nCurrent + 1; - else - break; - } - - // if there's a match store the according classification in the - // Attribute storage, otherwise do nothing since defaults are - // already provided in AttributeStorage::Insert() - if ( nComparison == 0 ) - pNeedle->SetValue( pHaystack->GetValue() ); - } -} - -void -AttributeStorage::AddClassification( AttributeClassifierT Classify ) -{ - for ( int i = 0; i < mnCount; i++ ) - { - Attribute& rCurrent = mpList[i] ; - int nValue = Classify( rCurrent.GetName() ); - rCurrent.SetValue( nValue ); - } -} - -void -AttributeStorage::AddAnnotation( AttributeAnnotatorT Annotate ) -{ - for ( int i = 0; i < mnCount; i++ ) - { - String* pAnnotation = Annotate( mpList[i] ); - mpList[i].SetAnnotation( pAnnotation ); - } -} - -void -AttributeStorage::TagFeature( unsigned short nFeature ) -{ - for ( int i = 0; i < mnCount; i++ ) - mpList[i].TagFeature( nFeature ); -} - -// Enlarge the list of Attributes -void -AttributeStorage::Enlarge() -{ - if ( mnSize == 0 ) - { - mnSize = 8; - mpList = (Attribute*) malloc( mnSize * sizeof(Attribute) ); - } - else - { - mnSize = mnSize < 32768 ? (mnSize * 2) : 65535; - mpList = (Attribute*) realloc( mpList, mnSize * sizeof(Attribute) ); - } -} - -// nLength is the length as it would be reported by strlen(3) -// for an null-terminated string. if a string is part of a Xlfd -// the field separator '-' is taken as '\0' -// the AttributeStorage itself is NOT sorted to make sure that the -// leased keys are still valid -unsigned short -AttributeStorage::Insert( const char *pString, int nLength ) -{ - // check whether the last match is still equal to the current - // string since XListFonts lists fonts in sets of similar fontnames - if ( mnLastmatch < mnCount ) - { - if ( mpList[mnLastmatch].ExactMatch(pString, nLength) ) - return mnLastmatch; - } - - // otherwise search in list - for ( int i = 0; i < mnCount; i++ ) - { - if ( mpList[i].ExactMatch(pString, nLength) ) - return mnLastmatch = i; - } - - // if still not found we have to Insert the new string - if ( mnSize == mnCount ) - Enlarge(); - mpList[mnCount].SetName( pString, nLength ); - mpList[mnCount].SetValue( mnDefaultValue ); - mpList[mnCount].SetAnnotation( NULL ); - mpList[mnCount].SetFeature( XLFD_FEATURE_NONE ); - mpList[mnCount].InitKey( ); - mnLastmatch = mnCount; - mnCount = mnCount < 65535 ? mnCount + 1 : mnCount; - - return mnLastmatch; -} - - -// --------------------------------------------------------------------------- -// -// -// Attribute provider is a frame for a set of AttributeStorages. -// -// -// --------------------------------------------------------------------------- - -AttributeProvider::AttributeProvider () -{ - mpField[eXLFDFoundry ] = new AttributeStorage(0); - mpField[eXLFDFamilyName ] = new AttributeStorage(FAMILY_DONTKNOW); - mpField[eXLFDWeightName ] = new AttributeStorage(WEIGHT_NORMAL); - mpField[eXLFDSlant ] = new AttributeStorage(ITALIC_NONE); - mpField[eXLFDSetwidthName] = new AttributeStorage(WIDTH_NORMAL); - mpField[eXLFDAddstyleName] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW); - mpField[eXLFDCharset ] = new AttributeStorage(RTL_TEXTENCODING_DONTKNOW); -} - -AttributeProvider::~AttributeProvider() -{ - for ( int i = 0; i < eXLFDMaxEntry; i++ ) - delete mpField[ i ]; -} - -#if OSL_DEBUG_LEVEL > 1 -void -AttributeProvider::Dump() -{ - for ( int i = 0; i < eXLFDMaxEntry; i++ ) - mpField[ i ]->Dump(); -} -#endif - -extern "C" rtl_TextEncoding -GetTextEncodingFromAddStylename( const sal_Char *pAddStylename ) -{ - int nBufferLength = strlen( pAddStylename ) + 1; - sal_Char *pBuffer = (sal_Char*)alloca( nBufferLength ); - for ( int i = 0; i < nBufferLength; i++ ) - pBuffer[i] = pAddStylename[i] == '_' ? '-' : pAddStylename[i] ; - - return rtl_getTextEncodingFromUnixCharset( pBuffer ); -} - - -// classification information is needed before sorting because of course the -// classification is the sort criteria -void -AttributeProvider::AddClassification() -{ - /* mpField[ eXLFDFoundry ] doesn't need classification */ - mpField[ eXLFDFamilyName ]->AddClassification( - (Attribute*)pFamilyAttribute, - MembersOf(pFamilyAttribute) ); - mpField[ eXLFDWeightName ]->AddClassification( - (Attribute*)pWeightAttribute, - MembersOf(pWeightAttribute) ); - mpField[ eXLFDSlant ]->AddClassification( - (Attribute*)pSlantAttribute, - MembersOf(pSlantAttribute) ); - mpField[ eXLFDSetwidthName ]->AddClassification( - (Attribute*)pSetwidthAttribute, - MembersOf(pSetwidthAttribute) ); - mpField[ eXLFDAddstyleName ]->AddClassification( - GetTextEncodingFromAddStylename ); - mpField[ eXLFDCharset ]->AddClassification( - rtl_getTextEncodingFromUnixCharset ); -} - -// add some pretty print description -void -AttributeProvider::AddAnnotation() -{ - mpField[ eXLFDFoundry ]->AddAnnotation( AnnotateNone ); - mpField[ eXLFDFamilyName ]->AddAnnotation( AnnotateString ); - mpField[ eXLFDWeightName ]->AddAnnotation( AnnotateString ); - mpField[ eXLFDSlant ]->AddAnnotation( AnnotateSlant ); - mpField[ eXLFDSetwidthName ]->AddAnnotation( AnnotateString ); - mpField[ eXLFDAddstyleName ]->AddAnnotation( AnnotateNone ); - mpField[ eXLFDCharset ]->AddAnnotation( AnnotateNone ); -} - -// this is the misc or any section: dirty hacks for dirty xlfd usage -void -AttributeProvider::TagFeature() -{ - mpField[ eXLFDFamilyName ]->TagFeature( - XLFD_FEATURE_OL_GLYPH - | XLFD_FEATURE_OL_CURSOR - | XLFD_FEATURE_NARROW - | XLFD_FEATURE_INTERFACE_FONT - | XLFD_FEATURE_APPLICATION_FONT); - - mpField[ eXLFDSetwidthName ]->TagFeature( - XLFD_FEATURE_NARROW ); - - mpField[ eXLFDAddstyleName ]->TagFeature( - XLFD_FEATURE_REDUNDANTSTYLE ); -} - diff --git a/vcl/unx/source/gdi/xlfd_attr.hxx b/vcl/unx/source/gdi/xlfd_attr.hxx deleted file mode 100644 index b721310da506..000000000000 --- a/vcl/unx/source/gdi/xlfd_attr.hxx +++ /dev/null @@ -1,228 +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 XLFD_ATTRIBUTE_HXX -#define XLFD_ATTRIBUTE_HXX - -#include <salunx.h> -#include <tools/string.hxx> - - -struct Attribute { - - const char* mpName; - unsigned short mnLength; - unsigned short mnValue; - unsigned short mnFeature; - String* mpAnnotation; - rtl::OString* mpKeyName; - - const char* GetName() const - { return mpName; } - unsigned short GetValue() const - { return mnValue; } - unsigned short GetLength() const - { return mnLength; } - Bool HasFeature( unsigned short nFeature ) const - { return ((mnFeature & nFeature) != 0); } - const String &GetAnnotation() const - { return *mpAnnotation; } - const rtl::OString& - GetKey(); - void InitKey(); - - void SetName( const char *p, int nLen ); - void SetValue( unsigned short nIn ) - { mnValue = nIn; } - void SetAnnotation( String *pString ) - { mpAnnotation = pString; } - void SetFeature( unsigned short nFeature ) - { mnFeature = nFeature; } - void TagFeature( unsigned short nFeature ); - - int Compare( const char *p, int nLen ); - Bool ExactMatch( const char *p, int nLen ); - void Release(); -}; - - -void -AppendAttribute( Attribute *pAttribute, ByteString &rString ); - - -typedef String*(*AttributeAnnotatorT)(const Attribute &rAttribute); -extern "C" { -typedef rtl_TextEncoding(*AttributeClassifierT)(const char* pStr); -} - -#define XLFD_FEATURE_NONE 0x0000 -#define XLFD_FEATURE_NARROW 0x0001 -#define XLFD_FEATURE_OL_GLYPH 0x0002 -#define XLFD_FEATURE_OL_CURSOR 0x0004 -#define XLFD_FEATURE_REDUNDANTSTYLE 0x0008 -#define XLFD_FEATURE_APPLICATION_FONT 0x0010 - -#define XLFD_FEATURE_INTERFACE_FONT 0x0020 -#define XLFD_FEATURE_LQ 0x0040 -#define XLFD_FEATURE_MQ 0x0080 -#define XLFD_FEATURE_HQ 0x0100 - -// --------------------------------------------------------------------------- -// -// -// manage global lists of Attributes -// since XListFonts does never list more than 64K fonts this storage does -// handle array size and indices with unsigned short values for low -// memory consumption -// -// -// --------------------------------------------------------------------------- - -class AttributeStorage { - - private: - - Attribute* mpList; - unsigned short mnSize; - unsigned short mnCount; - unsigned short mnLastmatch; - unsigned short mnDefaultValue; - - void Enlarge(); - AttributeStorage(); - - public: - - AttributeStorage( unsigned short nDefaultValue ); - ~AttributeStorage(); - unsigned short Insert( const char *pString, int nLength ); - Attribute* Retrieve( unsigned short nIndex ) const ; - void AddClassification( Attribute *pClassification, - unsigned short nNum ); - void AddClassification( AttributeClassifierT Classify ); - void TagFeature( unsigned short nFeature ); - void AddAnnotation( AttributeAnnotatorT Annotate ); - #if OSL_DEBUG_LEVEL > 1 - void Dump(); - #endif -}; - - -// --------------------------------------------------------------------------- -// -// -// Attribute provider is a frame for a set of AttributeStorages. For XLFD -// interpretation and efficient storage, AttributeStorages for foundry, -// family_name, weight_name, slant, setwidth_name, add_style_name and combined -// charset_registry and charset_encoding are used. pixel_size, point_size, -// resolution_x and resolution_y are stored as numbers. please note that this -// does not allow storage of matrix-enhanced fonts. spacing is stored as -// a char, since only the 'm', 'c' and 'p' types are defined. -// -// -// --------------------------------------------------------------------------- - -enum eXLFDAttributeT { - eXLFDFoundry = 0, - eXLFDFamilyName, - eXLFDWeightName, - eXLFDSlant, - eXLFDSetwidthName, - eXLFDAddstyleName, - eXLFDCharset, - eXLFDMaxEntry -}; - -class AttributeProvider { - - private: - - AttributeStorage* mpField[ eXLFDMaxEntry ]; - - AttributeStorage* GetField( eXLFDAttributeT eXLFDField ) - { return mpField[ eXLFDField]; } - public: - - AttributeProvider (); - ~AttributeProvider (); - - void AddClassification(); - void AddAnnotation(); - void TagFeature(); - #if OSL_DEBUG_LEVEL > 1 - void Dump(); - #endif - - // these are just shortcuts or proxies for the most common used - // AttributeStorage functionality - AttributeStorage* GetFoundry() - { return GetField(eXLFDFoundry); } - AttributeStorage* GetFamily() - { return GetField(eXLFDFamilyName); } - AttributeStorage* GetWeight() - { return GetField(eXLFDWeightName); } - AttributeStorage* GetSlant() - { return GetField(eXLFDSlant); } - AttributeStorage* GetSetwidth() - { return GetField(eXLFDSetwidthName); } - AttributeStorage* GetAddstyle() - { return GetField(eXLFDAddstyleName); } - AttributeStorage* GetCharset() - { return GetField(eXLFDCharset); } - - Attribute* RetrieveFoundry( unsigned short nIndex ) - { return GetFoundry()->Retrieve(nIndex); } - Attribute* RetrieveFamily( unsigned short nIndex ) - { return GetFamily()->Retrieve(nIndex); } - Attribute* RetrieveWeight( unsigned short nIndex ) - { return GetWeight()->Retrieve(nIndex); } - Attribute* RetrieveSlant( unsigned short nIndex ) - { return GetSlant()->Retrieve(nIndex); } - Attribute* RetrieveSetwidth( unsigned short nIndex ) - { return GetSetwidth()->Retrieve(nIndex); } - Attribute* RetrieveAddstyle( unsigned short nIndex ) - { return GetAddstyle()->Retrieve(nIndex); } - Attribute* RetrieveCharset( unsigned short nIndex ) - { return GetCharset()->Retrieve(nIndex); } - - unsigned short InsertFoundry( const char *pString, int nLength ) - { return GetFoundry()->Insert(pString, nLength); } - unsigned short InsertFamily( const char *pString, int nLength ) - { return GetFamily()->Insert(pString, nLength); } - unsigned short InsertWeight( const char *pString, int nLength ) - { return GetWeight()->Insert(pString, nLength); } - unsigned short InsertSlant( const char *pString, int nLength ) - { return GetSlant()->Insert(pString, nLength); } - unsigned short InsertSetwidth( const char *pString, int nLength ) - { return GetSetwidth()->Insert(pString, nLength);} - unsigned short InsertAddstyle( const char *pString, int nLength ) - { return GetAddstyle()->Insert(pString, nLength);} - unsigned short InsertCharset( const char *pString, int nLength ) - { return GetCharset()->Insert(pString, nLength); } -}; - -#endif /* XLFD_ATTRIBUTE_HXX */ - diff --git a/vcl/unx/source/gdi/xlfd_extd.cxx b/vcl/unx/source/gdi/xlfd_extd.cxx deleted file mode 100644 index 73731eddf115..000000000000 --- a/vcl/unx/source/gdi/xlfd_extd.cxx +++ /dev/null @@ -1,1001 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "xlfd_attr.hxx" -#include "xlfd_smpl.hxx" -#include "xlfd_extd.hxx" -#include <vcl/outfont.hxx> -#include <rtl/alloc.h> - -#ifndef _RTL_TENCINFO_H_ -#include <rtl/tencinfo.h> -#endif - -#include <set> - -// -------------------------------------------------------------------------- - -ImplX11FontData::ImplX11FontData( const ExtendedXlfd& rXlfd, int nHeight ) -: ImplFontData( rXlfd, X11IFD_MAGIC ), - mrXlfd( rXlfd ) -{ - mnHeight = nHeight; - mnWidth = 0; -} - -ImplFontEntry* ImplX11FontData::CreateFontInstance( ImplFontSelectData& rFSD ) const -{ - ImplFontEntry* pEntry = new ImplFontEntry( rFSD ); - return pEntry; -} - -sal_IntPtr ImplX11FontData::GetFontId() const -{ - return reinterpret_cast<sal_IntPtr>(&mrXlfd); -} - -// -------------------------------------------------------------------------- -// -// classes for Xlfd handling that contain more than a single encoding. -// Members that may vary through different encodings are stored in -// a mpEncodingInfo member. There are three different classes: -// true scalable fonts (truetype and type1) scalable bitmap fonts -// (the ugly ones) and bitmap fonts. The ExtendedXlfd stores all the members -// that are specific to a font outline -// ( e.g. adobe-times-roman-medium-r-normal- X -p- X ) -// and specifies the interface. -// -// -------------------------------------------------------------------------- - -ExtendedXlfd::EncodingInfo& -ExtendedXlfd::EncodingInfo::operator= ( const Xlfd *pXlfd ) -{ - mcSpacing = pXlfd->mcSpacing; - mnResolutionX = pXlfd->mnResolutionX; - mnResolutionY = pXlfd->mnResolutionY; - mnAddstyle = pXlfd->mnAddstyle; - mnCharset = pXlfd->mnCharset; - mnEncoding = pXlfd->GetEncoding(); - - return *this; -} - -// ------ base class -------------------------------------------------------- - -ExtendedXlfd::ExtendedXlfd( bool bScalable ) -: mbScalable( bScalable ), - mnEncodings( 0 ), - mnEncCapacity( 0 ), - mpEncodingInfo( NULL ) -{ - mbOrientation = false; - mbDevice = false; - mbSubsettable = false; - mbEmbeddable = false; - - mnQuality = -1; -} - -ExtendedXlfd::~ExtendedXlfd() -{ - if ( mnEncodings != 0 ) - rtl_freeMemory( mpEncodingInfo ); -} - -inline void* -Realloc( void *pPtr, sal_Size nSize ) -{ - return rtl_reallocateMemory( pPtr, nSize ); -} - -int -ExtendedXlfd::GetEncodingIdx( rtl_TextEncoding nEncoding ) const -{ - for ( int i = 0; i < mnEncodings; i++ ) - if ( nEncoding == mpEncodingInfo[i].mnEncoding ) - return i; - return -1; -} - -bool -ExtendedXlfd::HasEncoding( rtl_TextEncoding nEncoding ) const -{ - return !(GetEncodingIdx( nEncoding ) < 0) ; -} - -rtl_TextEncoding -ExtendedXlfd::GetEncoding( int i ) const -{ - if ( i < mnEncodings && i >= 0 ) - return mpEncodingInfo[i].mnEncoding; - - return RTL_TEXTENCODING_DONTKNOW; -} - -rtl_TextEncoding -ExtendedXlfd::GetEncoding() const -{ - return mnEncodings == 1 ? mpEncodingInfo[0].mnEncoding : RTL_TEXTENCODING_DONTKNOW; -} - -// query the most unicode / Ascii compatible font: either one of the fonts -// is utf16 encoded or there's a single byte font which is unicode -// compatible for the first 256 chars (latin1) or for at least 128 -// chars (most latin-X encodings, cyrillic encodings) -rtl_TextEncoding -ExtendedXlfd::GetAsciiEncoding( int *pAsciiRange ) const -{ - rtl_TextEncoding nBestEncoding = RTL_TEXTENCODING_DONTKNOW; - int nLargestRange = 0x0000; - - for ( int i = 0; i < mnEncodings && nLargestRange < 0xffff; i++ ) - { - rtl_TextEncoding nCurEncoding = mpEncodingInfo[i].mnEncoding; - switch ( nCurEncoding ) - { - case RTL_TEXTENCODING_UNICODE: - nLargestRange = 0xffff; - nBestEncoding = nCurEncoding; - break; - - case RTL_TEXTENCODING_ISO_8859_1: - case RTL_TEXTENCODING_MS_1252: - nLargestRange = 0x00ff; - nBestEncoding = nCurEncoding; - break; - - case RTL_TEXTENCODING_ISO_8859_2: - case RTL_TEXTENCODING_ISO_8859_4: - case RTL_TEXTENCODING_ISO_8859_5: - case RTL_TEXTENCODING_ISO_8859_6: - case RTL_TEXTENCODING_ISO_8859_7: - case RTL_TEXTENCODING_ISO_8859_8: - case RTL_TEXTENCODING_ISO_8859_9: - case RTL_TEXTENCODING_ISO_8859_13: - case RTL_TEXTENCODING_ISO_8859_15: - case RTL_TEXTENCODING_MS_1251: - case RTL_TEXTENCODING_KOI8_R: - case RTL_TEXTENCODING_JIS_X_0201: - if ( nLargestRange < 0x0080 ) - { - nLargestRange = 0x0080; - nBestEncoding = nCurEncoding; - } - break; - - default: - if ( nLargestRange == 0x0000 ) - { - nBestEncoding = nCurEncoding; - } - break; - } - } - - if ( pAsciiRange != NULL ) - *pAsciiRange = nLargestRange; - - return nBestEncoding; -} - -bool -ExtendedXlfd::AddEncoding( const Xlfd *pXlfd ) -{ - rtl_TextEncoding nEncoding = pXlfd->GetEncoding(); - if ( HasEncoding(nEncoding) ) - return false; - - if ( mnEncodings == 0 ) - { - // bootstrap - mnFoundry = pXlfd->mnFoundry; - mnFamily = pXlfd->mnFamily; - mnWeight = pXlfd->mnWeight; - mnSlant = pXlfd->mnSlant; - mnSetwidth = pXlfd->mnSetwidth; - mpFactory = pXlfd->mpFactory; - - Attribute *pFamilyAttr = mpFactory->RetrieveFamily( mnFamily ); - Attribute *pWeightAttr = mpFactory->RetrieveWeight( mnWeight ); - Attribute *pWidthAttr = mpFactory->RetrieveSetwidth( mnSetwidth ); - Attribute *pSlantAttr = mpFactory->RetrieveSlant( mnSlant ); - - meFamily = GetFamilyType(); - meWeight = GetWeight(); - meItalic = GetSlant(); - meWidthType = GetWidthType(); - mbSymbolFlag= (GetEncoding() == RTL_TEXTENCODING_SYMBOL); - mePitch = GetPitch(); - - maName = pFamilyAttr->GetAnnotation(); - - // the helvetica narrow hack - if ( ! pFamilyAttr->HasFeature(XLFD_FEATURE_NARROW) - && pWidthAttr->HasFeature(XLFD_FEATURE_NARROW) ) - { - static const String aNarrow( RTL_CONSTASCII_USTRINGPARAM(" Narrow") ); - maName += aNarrow; - } - - // stylename = weight + slant + width - // XXX Fix me: there may be a space missing between them - if ( meWeight != WEIGHT_NORMAL ) - maStyleName += pWeightAttr->GetAnnotation(); - if ( meItalic != ITALIC_NONE ) - maStyleName += pSlantAttr->GetAnnotation(); - if ( (meWidthType != WIDTH_NORMAL) - && (! pWidthAttr->HasFeature(XLFD_FEATURE_NARROW)) ) - maStyleName += pWidthAttr->GetAnnotation(); - } - - if( mnEncodings <= mnEncCapacity ) - { - mnEncCapacity += mnEncodings + 4; - mpEncodingInfo = (EncodingInfo*)Realloc( mpEncodingInfo, mnEncCapacity * sizeof(EncodingInfo) ); - } - - mpEncodingInfo[ mnEncodings ] = pXlfd; - mnEncodings += 1; - return true; -} - -void -ExtendedXlfd::ToString( ByteString &rString, - unsigned short /*nPixelSize*/, rtl_TextEncoding /*nEncoding*/ ) const -{ - AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry), rString ); - AppendAttribute( mpFactory->RetrieveFamily(mnFamily), rString ); - AppendAttribute( mpFactory->RetrieveWeight(mnWeight), rString ); - AppendAttribute( mpFactory->RetrieveSlant(mnSlant), rString ); - AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString ); -} - -void -ExtendedXlfd::ToString( ByteString &rString, - unsigned short /*nPixelSize*/, char* /*pMatricsString*/, rtl_TextEncoding /*nEncoding*/ ) const -{ - AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry), rString ); - AppendAttribute( mpFactory->RetrieveFamily(mnFamily), rString ); - AppendAttribute( mpFactory->RetrieveWeight(mnWeight), rString ); - AppendAttribute( mpFactory->RetrieveSlant(mnSlant), rString ); - AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString ); -} - -static FontPitch GetPitchFromX11Pitch( const char cSpacing ) -{ - switch ( cSpacing ) - { - case 'c': // fall through - case 'm': return PITCH_FIXED; - case 'p': return PITCH_VARIABLE; - default: return PITCH_DONTKNOW; - } -} - -// you must not call any of the ExtendedXlfd::GetXXX() functions if the -// ExtendedXlfd is really empty (i.e. mnEncodings is zero) - -FontPitch ExtendedXlfd::GetPitch() const -{ - if( mnEncodings > 1 ) - return PITCH_VARIABLE; - if( mnEncodings == 1 ) - return GetPitchFromX11Pitch( mpEncodingInfo[0].mcSpacing ); - return PITCH_DONTKNOW; -} - -FontPitch ExtendedXlfd::GetPitch( rtl_TextEncoding nEncoding ) const -{ - for ( int nIdx = 0; nIdx < mnEncodings; nIdx++ ) - if ( mpEncodingInfo[nIdx].mnEncoding == nEncoding ) - return GetPitchFromX11Pitch( mpEncodingInfo[nIdx].mcSpacing ); - return PITCH_DONTKNOW; -} - -FontFamily ExtendedXlfd::GetFamilyType() const -{ - Attribute *pFamilyAttr= mpFactory->RetrieveFamily(mnFamily); - return (FontFamily)pFamilyAttr->GetValue(); -} - -FontWeight ExtendedXlfd::GetWeight() const -{ - Attribute *pWeightAttr = mpFactory->RetrieveWeight(mnWeight); - return (FontWeight)pWeightAttr->GetValue(); -} - -FontItalic ExtendedXlfd::GetSlant() const -{ - Attribute *pSlantAttr = mpFactory->RetrieveSlant(mnSlant); - return (FontItalic)pSlantAttr->GetValue(); -} - -FontWidth ExtendedXlfd::GetWidthType() const -{ - Attribute *pWidthAttr = mpFactory->RetrieveSetwidth(mnSetwidth); - return (FontWidth)pWidthAttr->GetValue(); -} - -class CodeRange -{ -public: - CodeRange( int nMin, int nEnd ) : mnMin( nMin ), mnEnd( nEnd ) {} - - sal_uInt32 GetMin() const { return mnMin; } - sal_uInt32 GetEnd() const { return mnEnd; } - - bool operator<( const CodeRange& r ) const - { return (mnMin<r.mnMin) || ((mnMin==r.mnMin) && (mnEnd<r.mnEnd)); } - -private: - sal_uInt32 mnMin, mnEnd; -}; - - -int ExtendedXlfd::GetFontCodeRanges( sal_uInt32* pCodePairs ) const -{ - bool bHasUnicode = false; - bool bHasUnknownEncoding = false; - - // approximate unicode ranges from encodings - typedef std::set<CodeRange> RangeSet; - RangeSet aRangeSet; - - for( unsigned short i = 0; i < mnEncodings; ++i ) - { - // TODO: move encoding -> unicode range mapping to RTL - // NOTE: for now only some are VERY roughly approximated - const rtl_TextEncoding eEncoding = mpEncodingInfo[i].mnEncoding; - switch( mpEncodingInfo[i].mnEncoding ) - { - case RTL_TEXTENCODING_SYMBOL: // postscript symbol encoding - aRangeSet.insert( CodeRange( 0x0020, 0x0100 ) ); // symbol aliasing - aRangeSet.insert( CodeRange( 0xF020, 0xF100 ) ); - break; - - case RTL_TEXTENCODING_ISO_8859_15: - aRangeSet.insert( CodeRange( 0x20AC, 0x20AD ) ); // Euro currency symbol - // fall through - case RTL_TEXTENCODING_APPLE_ROMAN: - case RTL_TEXTENCODING_ISO_8859_1: - case RTL_TEXTENCODING_MS_1252: - case RTL_TEXTENCODING_IBM_437: - case RTL_TEXTENCODING_IBM_852: - aRangeSet.insert( CodeRange( 0x0020, 0x0080 ) ); - aRangeSet.insert( CodeRange( 0x00A0, 0x0100 ) ); - break; - - // Traditional, Simplified, Japanese - case RTL_TEXTENCODING_APPLE_CHINSIMP: - case RTL_TEXTENCODING_APPLE_CHINTRAD: - case RTL_TEXTENCODING_APPLE_JAPANESE: - case RTL_TEXTENCODING_SHIFT_JIS: - case RTL_TEXTENCODING_GB_2312: - case RTL_TEXTENCODING_GBT_12345: - case RTL_TEXTENCODING_GBK: - case RTL_TEXTENCODING_BIG5: - case RTL_TEXTENCODING_EUC_JP: - case RTL_TEXTENCODING_EUC_CN: - case RTL_TEXTENCODING_EUC_TW: - case RTL_TEXTENCODING_ISO_2022_JP: - case RTL_TEXTENCODING_ISO_2022_CN: - case RTL_TEXTENCODING_GB_18030: - case RTL_TEXTENCODING_BIG5_HKSCS: - case RTL_TEXTENCODING_JIS_X_0201: - case RTL_TEXTENCODING_JIS_X_0208: - case RTL_TEXTENCODING_JIS_X_0212: - case RTL_TEXTENCODING_MS_932: - case RTL_TEXTENCODING_MS_936: - case RTL_TEXTENCODING_MS_950: - aRangeSet.insert( CodeRange( 0x3000, 0xA000 ) ); - aRangeSet.insert( CodeRange( 0xF900, 0xFB00 ) ); - break; - - // Korean - case RTL_TEXTENCODING_APPLE_KOREAN: - case RTL_TEXTENCODING_MS_949: - case RTL_TEXTENCODING_MS_1361: - case RTL_TEXTENCODING_EUC_KR: - case RTL_TEXTENCODING_ISO_2022_KR: - aRangeSet.insert( CodeRange( 0x1100, 0x1200 ) ); - aRangeSet.insert( CodeRange( 0x3130, 0x3190 ) ); - aRangeSet.insert( CodeRange( 0xAC00, 0xD7A4 ) ); - break; - - // unknown encoding - case RTL_TEXTENCODING_DONTKNOW: - bHasUnknownEncoding = true; - break; - - // Unicode - case RTL_TEXTENCODING_UNICODE: - case RTL_TEXTENCODING_UTF7: - case RTL_TEXTENCODING_UTF8: - bHasUnicode = true; - break; - - // misc 8bit encodings - default: - if( !rtl_isOctetTextEncoding( eEncoding ) ) - bHasUnknownEncoding = true; - else - { - // use the unicode converter to get the coverage of an 8bit encoding - rtl_TextToUnicodeConverter aConverter = rtl_createTextToUnicodeConverter( eEncoding ); - rtl_UnicodeToTextContext aCvtContext = rtl_createTextToUnicodeContext( aConverter ); - if( !aConverter || !aCvtContext ) - bHasUnknownEncoding = true; - else - { - sal_Char cCharsInp[ 0x100 ]; - for( int j = 0x20; j < 0x080; ++j ) - cCharsInp[ j-0x20 ] = j; - for( int j = 0xA0; j < 0x100; ++j ) - cCharsInp[ j-0x40 ] = j; - - sal_Unicode cCharsOut[ 0x100 ]; - sal_uInt32 nCvtInfo; - sal_Size nSrcCvtBytes; - int nOutLen = rtl_convertTextToUnicode( - aConverter, aCvtContext, - cCharsInp, 0xC0, - cCharsOut, sizeof(cCharsOut)/sizeof(*cCharsOut), - RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE - | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE, - &nCvtInfo, &nSrcCvtBytes ); - - for( int j = 0; j < nOutLen; ++j ) - aRangeSet.insert( CodeRange( cCharsOut[j], cCharsOut[j]+1 ) ); - - rtl_destroyTextToUnicodeConverter( aCvtContext ); - rtl_destroyTextToUnicodeConverter( aConverter ); - } - } - break; - } - } - - // unicode encoded fonts usually do not cover the entire unicode range - // => only use them to determine coverage when no other encodings are available - if( aRangeSet.empty() && (bHasUnicode || bHasUnknownEncoding) ) - { - if( pCodePairs ) - { - pCodePairs[0] = 0x0020; - pCodePairs[1] = 0xD800; - pCodePairs[2] = 0xE000; - pCodePairs[3] = 0xFFFE; - } - return 2; - } - - if( aRangeSet.empty() ) - return 0; - - // sort and merge the code pairs - sal_uInt32* pDst = pCodePairs; - RangeSet::const_iterator it = aRangeSet.begin(); - for( sal_uInt32 nEnd = 0; it != aRangeSet.end(); ++it ) - { - // check overlap with to previous range - const CodeRange& rSrc = *it; - if( nEnd < rSrc.GetMin() ) - { - nEnd = rSrc.GetEnd(); - if( pCodePairs ) - { - pDst[0] = rSrc.GetMin(); - pDst[1] = rSrc.GetEnd(); - } - pDst += 2; - } - else - { - // merge overlapping ranges - if( nEnd < rSrc.GetEnd() ) - { - nEnd = rSrc.GetEnd(); - if( pCodePairs ) - pDst[-1] = nEnd; - } - } - } - - int nRangeCount = (pDst - pCodePairs) / 2; - return nRangeCount; -} - -// ------ class to handle scalable bitmap fonts ------------------------------ - -ScalableBitmapXlfd::ScalableBitmapXlfd() -: ExtendedXlfd( true ) -{} - -ScalableBitmapXlfd::~ScalableBitmapXlfd() -{} - -void -ScalableBitmapXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding ); - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += '-'; - rString += ByteString::CreateFromInt32( nPixelSize ); - rString += "-0-"; - rString += ByteString::CreateFromInt32( rInfo.mnResolutionX ); - rString += '-'; - rString += ByteString::CreateFromInt32( rInfo.mnResolutionY ); - rString += '-'; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-0"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -void -ScalableBitmapXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, char *pMatricsString, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding ); - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += "-*-"; - char pTmp[256]; - snprintf( pTmp, sizeof(pTmp), pMatricsString, nPixelSize, nPixelSize ); - rString += pTmp; - rString += "-*-*-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-*"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -ImplFontData* ScalableBitmapXlfd::GetImplFontData() const -{ - ImplX11FontData* pFontData = new ImplX11FontData( *this, 0 ); - pFontData->mnQuality= 0; - return pFontData; -} - -// ------ class to handle true bitmap fonts ---------------------------------- - -void -BitmapXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, char *pMatricsString, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding ); - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += "-*-"; - char pTmp[256]; - snprintf( pTmp, sizeof(pTmp), pMatricsString, nPixelSize, nPixelSize ); - rString += pTmp; - rString += "-*-*-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-*"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -BitmapXlfd::BitmapXlfd( ) -: ExtendedXlfd( false ) -{} - -BitmapXlfd::~BitmapXlfd( ) -{} - -bool -BitmapXlfd::AddEncoding( const Xlfd *pXlfd ) -{ - if ( mnEncodings == 0 ) - { - mnPixelSize = pXlfd->mnPixelSize; - mnPointSize = pXlfd->mnPointSize; - mnAverageWidth = pXlfd->mnAverageWidth; - } - - return ExtendedXlfd::AddEncoding( pXlfd ); -} - -void -BitmapXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding ); - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - rString += '-'; - rString += ByteString::CreateFromInt32( mnPixelSize ); - rString += "-*-*-*-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-*"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -ImplFontData* BitmapXlfd::GetImplFontData() const -{ - ImplX11FontData* pFontData = new ImplX11FontData( *this, mnPixelSize ); - pFontData->mnQuality= 100; - return pFontData; -} - -// ------ class to handle true scalable fonts -------------------------------- - -ScalableXlfd::ScalableXlfd() -: ExtendedXlfd( true ) -{} - -ScalableXlfd::~ScalableXlfd() -{} - -void -ScalableXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding); - - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += '-'; - rString += ByteString::CreateFromInt32( nPixelSize ); - rString += "-0-0-0-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-0"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -void -ScalableXlfd::ToString( ByteString &rString, - unsigned short nPixelSize, char* pMatricsString, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtendedXlfd::ToString( rString, nPixelSize, nEncoding); - - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += "-*-"; - char pTmp[256]; - snprintf( pTmp, sizeof(pTmp), pMatricsString, nPixelSize, nPixelSize ); - rString += pTmp; - rString += "-*-*-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-*"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -ImplFontData* ScalableXlfd::GetImplFontData() const -{ - ImplX11FontData* pFontData = new ImplX11FontData( *this, 0 ); - pFontData->mnQuality= 200; - return pFontData; -} - -/* ------- virtual fonts for user interface ------------------------------- */ - -VirtualXlfd::ExtEncodingInfo& -VirtualXlfd::ExtEncodingInfo::operator= ( const Xlfd *pXlfd ) -{ - mnFoundry = pXlfd->mnFoundry; - mnFamily = pXlfd->mnFamily; - mnWeight = pXlfd->mnWeight; - mnSlant = pXlfd->mnSlant; - mnSetwidth = pXlfd->mnSetwidth; - - return *this; -} - -VirtualXlfd::VirtualXlfd() -: ExtendedXlfd( true ), - mnExtCapacity(0), - mpExtEncodingInfo(NULL) -{ - mnFoundry = 0; - mnFamily = 0; - mnWeight = 0; - mnSlant = 0; - mnSetwidth = 0; -} - -VirtualXlfd::~VirtualXlfd() -{ - if ( mpExtEncodingInfo != NULL ) - rtl_freeMemory( mpExtEncodingInfo ); -} - -int -VirtualXlfd::GetFontQuality (unsigned short nFamily) -{ - Attribute *pFamily = mpFactory->RetrieveFamily(nFamily); - int nQuality = 0; - - if (pFamily->HasFeature(XLFD_FEATURE_HQ)) - nQuality += 16; - if (pFamily->HasFeature(XLFD_FEATURE_MQ)) - nQuality += 8; - if (pFamily->HasFeature(XLFD_FEATURE_LQ)) - nQuality += 4; - return nQuality; -} - -bool -VirtualXlfd::AddEncoding( const Xlfd *pXlfd ) -{ - // add new font - bool bRC = ExtendedXlfd::AddEncoding( pXlfd ); - - int nIdx; - if( bRC ) - { - // new encoding => append the new pXlfd - nIdx = mnEncodings - 1; - if( nIdx >= mnExtCapacity ) - { - mnExtCapacity = mnEncCapacity; - mpExtEncodingInfo = (ExtEncodingInfo*)Realloc( mpExtEncodingInfo, - mnExtCapacity * sizeof(ExtEncodingInfo) ); - } - } - else - { - // existing encoding => check if the new pXlfd is better - rtl_TextEncoding nEncoding = pXlfd->GetEncoding(); - nIdx = GetEncodingIdx( nEncoding ); - - int nOldQuality = GetFontQuality( mpExtEncodingInfo[nIdx].mnFamily ); - int nNewQuality = GetFontQuality( pXlfd->mnFamily ); - if( nOldQuality >= nNewQuality ) - return false; - } - - mpExtEncodingInfo[ nIdx ] = pXlfd; - return true; -} - -void -VirtualXlfd::FilterInterfaceFont (const Xlfd *pXlfd) -{ - Attribute *pAttr; - AttributeProvider *pFactory = pXlfd->mpFactory; - - if (! pXlfd->Fonttype() == TYPE_SCALABLE) - return; - pAttr = pFactory->RetrieveFamily(pXlfd->mnFamily); - if (! pAttr->HasFeature(XLFD_FEATURE_INTERFACE_FONT)) - return; - pAttr = pFactory->RetrieveSlant(pXlfd->mnSlant); - if (! (FontItalic)pAttr->GetValue() == ITALIC_NONE) - return; - pAttr = pFactory->RetrieveSetwidth(pXlfd->mnSetwidth); - if (pAttr->HasFeature(XLFD_FEATURE_NARROW)) - return; - pAttr = pFactory->RetrieveWeight(pXlfd->mnWeight); - FontWeight eWeight = (FontWeight)pAttr->GetValue(); - if ((eWeight != WEIGHT_NORMAL) && (eWeight != WEIGHT_MEDIUM)) - return; - - AddEncoding (pXlfd); -} - -void -VirtualXlfd::ToString( ByteString &rString, unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtEncodingInfo &rExtInfo = mpExtEncodingInfo[ nIdx ]; - - AppendAttribute( mpFactory->RetrieveFoundry(rExtInfo.mnFoundry), rString ); - AppendAttribute( mpFactory->RetrieveFamily(rExtInfo.mnFamily), rString ); - AppendAttribute( mpFactory->RetrieveWeight(rExtInfo.mnWeight), rString ); - AppendAttribute( mpFactory->RetrieveSlant(rExtInfo.mnSlant), rString ); - AppendAttribute( mpFactory->RetrieveSetwidth(rExtInfo.mnSetwidth), rString ); - - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += '-'; - rString += ByteString::CreateFromInt32( nPixelSize ); - rString += "-0-0-0-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-0"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -void -VirtualXlfd::ToString( ByteString &rString, unsigned short nPixelSize, - char* pMatricsString, rtl_TextEncoding nEncoding ) const -{ - int nIdx = GetEncodingIdx( nEncoding ); - if ( nIdx < 0 ) - return; - - ExtEncodingInfo &rExtInfo = mpExtEncodingInfo[ nIdx ]; - - AppendAttribute( mpFactory->RetrieveFoundry(rExtInfo.mnFoundry), rString ); - AppendAttribute( mpFactory->RetrieveFamily(rExtInfo.mnFamily), rString ); - AppendAttribute( mpFactory->RetrieveWeight(rExtInfo.mnWeight), rString ); - AppendAttribute( mpFactory->RetrieveSlant(rExtInfo.mnSlant), rString ); - AppendAttribute( mpFactory->RetrieveSetwidth(rExtInfo.mnSetwidth), rString ); - - EncodingInfo& rInfo = mpEncodingInfo[ nIdx ]; - AppendAttribute( mpFactory->RetrieveAddstyle(rInfo.mnAddstyle), rString ); - - rString += "-*-"; - char pTmp[256]; - snprintf( pTmp, sizeof(pTmp), pMatricsString, nPixelSize, nPixelSize ); - rString += pTmp; - rString += "-*-*-"; - rString += static_cast< char >(rInfo.mcSpacing); - rString += "-*"; - - AppendAttribute( mpFactory->RetrieveCharset(rInfo.mnCharset), rString ); -} - -ImplFontData* VirtualXlfd::GetImplFontData() const -{ - ImplX11FontData* pFontData = new ImplX11FontData( *this, 0 ); - - // family name - static const String aFontName( RTL_CONSTASCII_USTRINGPARAM("Interface User") ); - pFontData->maName = aFontName; - // pFontData->maStyleName = aStyleName; - pFontData->meFamily = FAMILY_SWISS; - pFontData->meWeight = WEIGHT_NORMAL; - pFontData->meItalic = ITALIC_NONE; - pFontData->meWidthType = WIDTH_NORMAL; - pFontData->mePitch = PITCH_VARIABLE; - - pFontData->mbSymbolFlag = false; - pFontData->mbOrientation= false; - pFontData->mbDevice = true; - pFontData->mnQuality = 100; - - return pFontData; -} - -// ------ font list ------------------------------------------------------- - -XlfdStorage::XlfdStorage() -{ - maXlfdList.reserve( 256 ); -} - -void -XlfdStorage::Dispose() -{ - XlfdList::const_iterator it = maXlfdList.begin(); - for(; it != maXlfdList.end(); ++it ) - delete *it; - maXlfdList.clear(); -} - -void -XlfdStorage::Reset() -{ - maXlfdList.clear(); -} - -void -XlfdStorage::Add( const ExtendedXlfd* pXlfd ) -{ - if ( pXlfd != NULL ) - maXlfdList.push_back( pXlfd ); -} - -void -XlfdStorage::Add( const XlfdStorage* pXlfd ) -{ - if ( !pXlfd || pXlfd->maXlfdList.empty() ) - return; - - maXlfdList.reserve( maXlfdList.size() + pXlfd->maXlfdList.size() ); - XlfdList::const_iterator it = pXlfd->maXlfdList.begin(); - for(; it != pXlfd->maXlfdList.end(); ++it ) - maXlfdList.push_back( *it ); -} - -void XlfdStorage::AnnounceFonts( ImplDevFontList* pList ) const -{ - XlfdList::const_iterator it = maXlfdList.begin(); - for(; it != maXlfdList.end(); ++it ) - { - const ExtendedXlfd* pXlfd = *it; - ImplFontData* pFontData = pXlfd->GetImplFontData(); - pList->Add( pFontData ); - } -} - -// ------ bitmap font list -------------------------------------------------- - -void -BitmapXlfdStorage::AddBitmapFont( const Xlfd *pXlfd ) -{ - if ( pXlfd == NULL ) - return; - - int nPixelSize = pXlfd->mnPixelSize; - XlfdList::const_iterator it = maXlfdList.begin(); - for(; it != maXlfdList.end(); ++it ) - { - BitmapXlfd* pBitmapXlfd = (BitmapXlfd*)*it; - if( nPixelSize == pBitmapXlfd->GetPixelSize() ) - { - // we need to add an encoding to an existing bitmap font - pBitmapXlfd->AddEncoding( pXlfd ); - return; - } - } - - // we have a new bitmap font - BitmapXlfd* pBitmapXlfd = new BitmapXlfd; - pBitmapXlfd->AddEncoding( pXlfd ); - Add( pBitmapXlfd ); -} diff --git a/vcl/unx/source/gdi/xlfd_extd.hxx b/vcl/unx/source/gdi/xlfd_extd.hxx deleted file mode 100644 index 523f87fac477..000000000000 --- a/vcl/unx/source/gdi/xlfd_extd.hxx +++ /dev/null @@ -1,272 +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 XLFD_EXTENDED_HXX -#define XLFD_EXTENDED_HXX - -#include <salunx.h> -#ifndef _VCL_VCLENUM_HXX -#include <vcl/enum.hxx> -#endif -#ifndef _VCL_OUTFONT_HXX -#include <vcl/outfont.hxx> -#endif - -#include <vector> - -class Xlfd; -class AttributeProvider; -class ImplDevFontList; -class ByteString; - -// -------------------------------------------------------------------------- -// -// classes for Xlfd handling that contain more than a single encoding. -// Members that may vary through different encodings are stored in -// a mpEncodingInfo member. There are three different classes: -// true scalable fonts (truetype and type1) scalable bitmap fonts -// (the ugly ones) and bitmap fonts. The ExtendedXlfd stores all the members -// that are specific to a font outline -// ( e.g. adobe-times-roman-medium-r-normal- * -p- * ) -// and specifies the interface. -// -// -------------------------------------------------------------------------- - -// base class - -class ExtendedXlfd : public ImplDevFontAttributes -{ - public: - ExtendedXlfd( bool bScalable ); - virtual ~ExtendedXlfd(); - virtual bool AddEncoding( const Xlfd* ); - bool HasEncoding( rtl_TextEncoding ) const; - int GetEncodingIdx( rtl_TextEncoding nEncoding ) const; - unsigned short NumEncodings() const - { return mnEncodings; } - virtual int GetPixelSize() const - { return 0; } - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const ; - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - char* pMatricsString, - rtl_TextEncoding nEncoding ) const; - - virtual ImplFontData* GetImplFontData() const = 0; - bool IsScalable() const { return mbScalable; } - virtual FontFamily GetFamilyType() const; - virtual FontWeight GetWeight() const; - virtual FontItalic GetSlant() const; - virtual FontWidth GetWidthType() const; - virtual FontPitch GetPitch() const; - virtual FontPitch GetPitch( rtl_TextEncoding ) const; - rtl_TextEncoding GetAsciiEncoding( int *pAsciiRange = NULL ) const; - rtl_TextEncoding GetEncoding() const; - rtl_TextEncoding GetEncoding( int i ) const; - - int GetFontCodeRanges( sal_uInt32* pCodePairs ) const; - - protected: - AttributeProvider* mpFactory; - - public: - unsigned short mnFoundry; - unsigned short mnFamily; - unsigned short mnWeight; - unsigned short mnSlant; - unsigned short mnSetwidth; - bool mbScalable; - - protected: - unsigned short mnEncodings; - unsigned short mnEncCapacity; - struct EncodingInfo { - unsigned char mcSpacing; - unsigned short mnResolutionX; - unsigned short mnResolutionY; - unsigned short mnAddstyle; - unsigned short mnCharset; - rtl_TextEncoding mnEncoding; - - EncodingInfo& operator= ( const Xlfd *pXlfd ); - } *mpEncodingInfo; -}; - -// class to handle scalable bitmap fonts - -class ScalableBitmapXlfd : public ExtendedXlfd { - - public: - ScalableBitmapXlfd(); - virtual ~ScalableBitmapXlfd(); - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const; - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - char* pMatricsString, - rtl_TextEncoding nEncoding ) const; - - virtual ImplFontData* GetImplFontData() const ; -}; - -// class to handle true bitmap fonts - -class ScalableXlfd; - -class BitmapXlfd : public ExtendedXlfd { - - public: - BitmapXlfd(); - ~BitmapXlfd(); - bool AddEncoding( const Xlfd* ); - virtual int GetPixelSize() const - { return mnPixelSize; } - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const; - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - char* pMatricsString, - rtl_TextEncoding nEncoding ) const; - virtual ImplFontData* GetImplFontData() const ; - protected: - - unsigned short mnPixelSize; - unsigned short mnPointSize; - unsigned short mnAverageWidth; -}; - -// class to handle true scalable fonts - -class ScalableXlfd : public ExtendedXlfd { - - friend class BitmapXlfd; - - public: - ScalableXlfd(); - virtual ~ScalableXlfd(); - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const; - - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - char* pMatricsString, - rtl_TextEncoding nEncoding ) const; - virtual ImplFontData* GetImplFontData() const ; -}; - -// class to maintain a list of fonts ( bitmap and scalable ) - -class XlfdStorage { - - public: - XlfdStorage(); - - void Dispose(); - void Reset(); - - void Add( const ExtendedXlfd *pXlfd ); - void Add( const XlfdStorage *pXlfd ); - void AnnounceFonts( ImplDevFontList* ) const; - - protected: - - typedef ::std::vector<const ExtendedXlfd*> XlfdList; - XlfdList maXlfdList; -}; - -// list of fonts specific for bitmap fonts - -class BitmapXlfdStorage : public XlfdStorage { - - public: - - void AddBitmapFont( const Xlfd *pXlfd ); -}; - - -/* Virtual font for User Interface */ - -class VirtualXlfd : public ExtendedXlfd -{ - private: - - int GetFontQuality (unsigned short nFamily); - - public: - VirtualXlfd(); - virtual ~VirtualXlfd(); - virtual bool AddEncoding( const Xlfd* ); - void FilterInterfaceFont (const Xlfd *pXlfd); - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - rtl_TextEncoding nEncoding ) const ; - virtual void ToString( ByteString &rString, - unsigned short nPixelSize, - char* pMatricsString, - rtl_TextEncoding nEncoding ) const; - - virtual ImplFontData* GetImplFontData() const ; - protected: - - unsigned short mnExtCapacity; - struct ExtEncodingInfo { - unsigned short mnFoundry; - unsigned short mnFamily; - unsigned short mnWeight; - unsigned short mnSlant; - unsigned short mnSetwidth; - - ExtEncodingInfo& operator= ( const Xlfd *pXlfd ); - } *mpExtEncodingInfo; - - friend class ExtEncodingInfo; -}; - - -// class to describe a X11 physically available font face - -class ImplX11FontData : public ImplFontData -{ -private: - enum { X11IFD_MAGIC = 0x111FDA1C }; - const ExtendedXlfd& mrXlfd; - -public: - ImplX11FontData( const ExtendedXlfd&, int nHeight ); - const ExtendedXlfd& GetExtendedXlfd() const { return mrXlfd; } - virtual ImplFontData* Clone() const { return new ImplX11FontData( *this ); } - virtual ImplFontEntry* CreateFontInstance( ImplFontSelectData& ) const; - virtual sal_IntPtr GetFontId() const; - - static bool CheckFontData( const ImplFontData& r ) { return r.CheckMagic( X11IFD_MAGIC ); } -}; - -#endif /* XLFD_EXTENDED_HXX */ diff --git a/vcl/unx/source/gdi/xlfd_smpl.cxx b/vcl/unx/source/gdi/xlfd_smpl.cxx deleted file mode 100644 index 6cf18d98de1e..000000000000 --- a/vcl/unx/source/gdi/xlfd_smpl.cxx +++ /dev/null @@ -1,268 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "xlfd_attr.hxx" -#include "xlfd_smpl.hxx" - -// -------------------------------------------------------------------------- -// -// -// broken down structure equivalent to a Xlfd string -// -// -// -------------------------------------------------------------------------- - -Xlfd::Xlfd() -{ -} - -// XlfdCompare abi has to be qsort(3) compatible, the sorting result must -// guarantee that fonts with SameFontoutline() are successive -// XlfdCompare relies on vFrom->mpFactory eq vTo->mpFactory. Since comparing -// Xlfd's is done by comparing attributes there is no way around this. -extern "C" int -XlfdCompare( const void *vFrom, const void *vTo ) -{ - const Xlfd *pFrom = (Xlfd*)vFrom; - const Xlfd *pTo = (Xlfd*)vTo; - - // Compare outline description - if ( pFrom->mnFoundry != pTo->mnFoundry ) - return (int)pFrom->mnFoundry - (int)pTo->mnFoundry; - if ( pFrom->mnFamily != pTo->mnFamily ) - return (int)pFrom->mnFamily - (int)pTo->mnFamily; - if ( pFrom->mnWeight != pTo->mnWeight ) - return (int)pFrom->mnWeight - (int)pTo->mnWeight; - if ( pFrom->mnSlant != pTo->mnSlant ) - return (int)pFrom->mnSlant - (int)pTo->mnSlant; - if ( pFrom->mnSetwidth != pTo->mnSetwidth ) - return (int)pFrom->mnSetwidth - (int)pTo->mnSetwidth; - - // Addstyle name is futile tricky. it may contain encoding information - // (like "ansi_1251") which Compares equal, or it may contain style - // information (like "serif") which Compares unequal, anyway if the font - // is "interface user" or "interface system" then compare equal anyway to - // build fontsets as large as possible - if ( pFrom->mnAddstyle == pTo->mnAddstyle ) - return 0; - - AttributeProvider *pFactory = pFrom->mpFactory; - Attribute *pFamily = pFactory->RetrieveFamily( pFrom->mnFamily ); - if ( pFamily->HasFeature(XLFD_FEATURE_APPLICATION_FONT) ) - return 0; - - Attribute *pFromAddStyle = pFactory->RetrieveAddstyle( pFrom->mnAddstyle ); - Attribute *pToAddStyle = pFactory->RetrieveAddstyle( pTo->mnAddstyle ); - - // if both addstyles denote encodings or if one denotes an - // encoding and the other denotes a style which really - // duplicates weight and slant information - - int nFromCompare = (pFromAddStyle->GetValue() != RTL_TEXTENCODING_DONTKNOW) - || (pFromAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ? - -1 : pFrom->mnAddstyle; - int nToCompare = (pToAddStyle->GetValue() != RTL_TEXTENCODING_DONTKNOW) - || (pToAddStyle->HasFeature(XLFD_FEATURE_REDUNDANTSTYLE)) ? - -1 : pTo->mnAddstyle; - - return nFromCompare - nToCompare; -} - -// check whether two fonts are identical as appearance is concerned -// this does not Compare the actual scaling of two fonts -Bool -Xlfd::SameFontoutline( const Xlfd* pComparedTo ) const -{ - void* pThis = (void*)this; - return XlfdCompare( (void*)pThis, (void*)pComparedTo ) == 0 ; -} - -unsigned short -Xlfd::GetEncoding() const -{ - Attribute *pAddstyle = mpFactory->RetrieveAddstyle( mnAddstyle ); - if ( pAddstyle->GetValue() != RTL_TEXTENCODING_DONTKNOW ) - return pAddstyle->GetValue(); - - Attribute *pEncoding = mpFactory->RetrieveCharset( mnCharset ); - return pEncoding->GetValue(); -} - -XlfdFonttype -Xlfd::Fonttype() const -{ - if ( (mnAverageWidth == 0) && (mnPixelSize == 0) && (mnPointSize == 0) ) - { - return (mnResolutionX == 0) - && (mnResolutionY == 0) ? eTypeScalable : eTypeScalableBitmap; - } - - return eTypeBitmap; -} - -void -Advance( const char** pFrom, const char** pTo ) -{ - const char *pTmp = *pTo; - - for( ; (*pTmp != '\0') && (*pTmp++ != '-'); ) - {} - *pFrom = *pTo; - *pTo = pTmp; -} - -Bool -Xlfd::IsConformant (const char* pXlfd) const -{ - // X FontNameRegistry prefix "-" - if (*pXlfd++ != '-') - return False; - - // All Xlfd FontName fields are defined - int nNumFields = 1; - while (*pXlfd != '\0') - { - if (*pXlfd++ == '-') - nNumFields++; - } - // enough entries ? - if (nNumFields != 14) - return False; - // and the last one is not empty as well ? - if (*(pXlfd - 1) == '-') - return False; - - return True; -} - -// this is the real workhorse function. Since this is called for every font -// in the fontpath it has to be as fast a possible -Bool -Xlfd::FromString( const char* pXlfdstring, AttributeProvider *pFactory ) -{ - if (!IsConformant(pXlfdstring)) - return False; - - const char* pFrom = pXlfdstring + 1; - const char* pTo = pFrom; - mpFactory = pFactory; - - Advance( &pFrom, &pTo ); //-foundry-* - mnFoundry = mpFactory->InsertFoundry( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); // -*-family-* - mnFamily = mpFactory->InsertFamily( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); // -*-*-weight-* - mnWeight = mpFactory->InsertWeight( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); //-*-*-*-slant-* - mnSlant = mpFactory->InsertSlant( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-setwidth-* - mnSetwidth = mpFactory->InsertSetwidth( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-Addstyle-* - mnAddstyle = mpFactory->InsertAddstyle( pFrom, pTo - pFrom - 1 ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-height-* - mnPixelSize = atoi( pFrom ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-pt height-* - mnPointSize = atoi( pFrom ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-x resolution-* - mnResolutionX = atoi( pFrom ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-y resolution-* - mnResolutionY = atoi( pFrom ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-spacing-* - mcSpacing = pFrom == pTo ? '\0' : *pFrom; - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-average-* - mnAverageWidth = atoi( pFrom ); - - Advance( &pFrom, &pTo ); //-*-*-*-*-*-*-*-*-*-*-*-*-registry-encoding - const char* pTmp = pFrom; - Advance( &pTmp, &pTo ); - mnCharset = mpFactory->InsertCharset( pFrom, pTo - pFrom ); - - // sanity check whether we have really found a valid XLFD, if not - // throw away the whole font, since we have no idea what parts of - // the XLFD contains the error. - if ( !(pTo > pFrom) ) - return False; - - // a non-empty family name is essential, since otherwise the font - // would match the "default font" #52299# - Attribute* pFamily = mpFactory->RetrieveFamily( mnFamily ); - const char* pFamilyName = pFamily->GetName(); - if ( pFamilyName[0] == '\0' ) - return False; - - // well done - return True; -} - -#if OSL_DEBUG_LEVEL > 1 -// pure debug for now: this is only to inspect/pretty print a Xlfd struct -const char* -Xlfd::ToString( ByteString &rString ) const -{ - AppendAttribute( mpFactory->RetrieveFoundry(mnFoundry), rString ); - AppendAttribute( mpFactory->RetrieveFamily(mnFamily), rString ); - AppendAttribute( mpFactory->RetrieveWeight(mnWeight), rString ); - AppendAttribute( mpFactory->RetrieveSlant(mnSlant), rString ); - AppendAttribute( mpFactory->RetrieveSetwidth(mnSetwidth), rString ); - AppendAttribute( mpFactory->RetrieveAddstyle(mnAddstyle), rString ); - - rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPixelSize ) ); - rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnPointSize ) ); - rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionX ) ); - rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnResolutionY ) ); - rString.Append("-"); rString.Append( (char)mcSpacing ); - rString.Append("-"); rString.Append( ByteString::CreateFromInt32( mnAverageWidth ) ); - - AppendAttribute( mpFactory->RetrieveCharset(mnCharset), rString ); - - return rString.GetBuffer() ; -} - -void -Xlfd::Dump() const -{ - ByteString aString; - fprintf(stderr, "Xlfd: %s\n", ToString(aString) ); -} -#endif - diff --git a/vcl/unx/source/gdi/xlfd_smpl.hxx b/vcl/unx/source/gdi/xlfd_smpl.hxx deleted file mode 100644 index f62ac381e6b9..000000000000 --- a/vcl/unx/source/gdi/xlfd_smpl.hxx +++ /dev/null @@ -1,92 +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 XLFD_SIMPLE_HXX -#define XLFD_SIMPLE_HXX - -#include <salunx.h> -#include <vcl/vclenum.hxx> -#include <tools/string.hxx> - -class AttributeProvider; - -// -------------------------------------------------------------------------- -// -// -// broken down structure equivalent to a Xlfd string -// -// -// -------------------------------------------------------------------------- - -enum XlfdFonttype { - eTypeUnknown = TYPE_DONTKNOW, - eTypeBitmap = TYPE_RASTER, - eTypeScalableBitmap = TYPE_VECTOR, - eTypeScalable = TYPE_SCALABLE -}; - -class Xlfd { - - public: - - unsigned short mnFoundry; - unsigned short mnFamily; - unsigned short mnWeight; - unsigned short mnSlant; - unsigned short mnSetwidth; - unsigned short mnAddstyle; - unsigned short mnPixelSize; - unsigned short mnPointSize; - unsigned short mnResolutionX; - unsigned short mnResolutionY; - unsigned char mcSpacing; - unsigned short mnAverageWidth; - unsigned short mnCharset; - - // all foundry, family, weight ... information referres - // to this factory - AttributeProvider *mpFactory; - - Bool IsConformant( const char* pXlfdstring ) const; - - public: - Xlfd(); - Bool FromString( const char* pXlfdstring, - AttributeProvider *pFactory ); - Bool SameFontoutline( const Xlfd *pComparedTo ) const ; - XlfdFonttype Fonttype() const ; - unsigned short GetEncoding() const ; - #if OSL_DEBUG_LEVEL > 1 - const char* ToString( ByteString &rString ) const ; - void Dump() const; - #endif -}; - -extern "C" int -XlfdCompare( const void *vFrom, const void *vTo ); - -#endif /* XLFD_SIMPLE_HXX */ - diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx index a438760cffba..fd49ee34f543 100644 --- a/vcl/unx/source/plugadapt/salplug.cxx +++ b/vcl/unx/source/plugadapt/salplug.cxx @@ -36,6 +36,7 @@ #include "vcl/salinst.hxx" #include "saldata.hxx" +#include "vcl/printerinfomanager.hxx" #include <cstdio> #include <unistd.h> @@ -291,10 +292,12 @@ const OUString& SalGetDesktopEnvironment() SalData::SalData() : m_pInstance(NULL), - m_pPlugin(NULL) + m_pPlugin(NULL), + m_pPIManager(NULL) { } SalData::~SalData() { + psp::PrinterInfoManager::release(); } diff --git a/vcl/unx/source/printer/cupsmgr.cxx b/vcl/unx/source/printer/cupsmgr.cxx index e245b2548c79..caf3249b5f46 100644 --- a/vcl/unx/source/printer/cupsmgr.cxx +++ b/vcl/unx/source/printer/cupsmgr.cxx @@ -524,12 +524,18 @@ void CUPSManager::initialize() // introduced in dests with 1.2 // this is needed to check for %%IncludeFeature support // (#i65684#, #i65491#) + bool bUsePDF = false; cups_dest_t* pDest = ((cups_dest_t*)m_pDests); const char* pOpt = m_pCUPSWrapper->cupsGetOption( "printer-info", pDest->num_options, pDest->options ); if( pOpt ) + { m_bUseIncludeFeature = true; + bUsePDF = true; + if( m_aGlobalDefaults.m_nPSLevel == 0 && m_aGlobalDefaults.m_nPDFDevice == 0 ) + m_aGlobalDefaults.m_nPDFDevice = 1; + } // do not send include JobPatch; CUPS will insert that itself // TODO: currently unknwon which versions of CUPS insert JobPatches // so currently it is assumed CUPS = don't insert JobPatch files @@ -593,6 +599,8 @@ void CUPSManager::initialize() aPrinter.m_aInfo.m_pParser = c_it->second.getParser(); aPrinter.m_aInfo.m_aContext = c_it->second; } + if( bUsePDF && aPrinter.m_aInfo.m_nPSLevel == 0 && aPrinter.m_aInfo.m_nPDFDevice == 0 ) + aPrinter.m_aInfo.m_nPDFDevice = 1; aPrinter.m_aInfo.m_aDriverName = aBuf.makeStringAndClear(); aPrinter.m_bModified = false; @@ -826,8 +834,15 @@ void CUPSManager::setupJobContextData( FILE* CUPSManager::startSpool( const OUString& rPrintername, bool bQuickCommand ) { + OSL_TRACE( "endSpool: %s, %s", + rtl::OUStringToOString( rPrintername, RTL_TEXTENCODING_UTF8 ).getStr(), + bQuickCommand ? "true" : "false" ); + if( m_aCUPSDestMap.find( rPrintername ) == m_aCUPSDestMap.end() ) + { + OSL_TRACE( "defer to PrinterInfoManager::startSpool" ); return PrinterInfoManager::startSpool( rPrintername, bQuickCommand ); + } #ifdef ENABLE_CUPS OUString aTmpURL, aTmpFile; @@ -850,7 +865,7 @@ struct less_ppd_key : public ::std::binary_function<double, double, bool> { return left->getOrderDependency() < right->getOrderDependency(); } }; -void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOptions, void** rOptions ) const +void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner, int& rNumOptions, void** rOptions ) const { rNumOptions = 0; *rOptions = NULL; @@ -880,10 +895,26 @@ void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOpt } } } + + if( rJob.m_nPDFDevice > 0 && rJob.m_nCopies > 1 ) + { + rtl::OString aVal( rtl::OString::valueOf( sal_Int32( rJob.m_nCopies ) ) ); + rNumOptions = m_pCUPSWrapper->cupsAddOption( "copies", aVal.getStr(), rNumOptions, (cups_option_t**)rOptions ); + } + if( ! bBanner ) + { + rNumOptions = m_pCUPSWrapper->cupsAddOption( "job-sheets", "none", rNumOptions, (cups_option_t**)rOptions ); + } } -int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ) +int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ) { + OSL_TRACE( "endSpool: %s, %s, copy count = %d", + rtl::OUStringToOString( rPrintername, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( rJobTitle, RTL_TEXTENCODING_UTF8 ).getStr(), + rDocumentJobData.m_nCopies + ); + int nJobID = 0; osl::MutexGuard aGuard( m_aCUPSMutex ); @@ -891,7 +922,10 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit std::hash_map< OUString, int, OUStringHash >::iterator dest_it = m_aCUPSDestMap.find( rPrintername ); if( dest_it == m_aCUPSDestMap.end() ) - return PrinterInfoManager::endSpool( rPrintername, rJobTitle, pFile, rDocumentJobData ); + { + OSL_TRACE( "defer to PrinterInfoManager::endSpool" ); + return PrinterInfoManager::endSpool( rPrintername, rJobTitle, pFile, rDocumentJobData, bBanner ); + } #ifdef ENABLE_CUPS std::hash_map< FILE*, OString, FPtrHash >::const_iterator it = m_aSpoolFiles.find( pFile ); @@ -903,7 +937,7 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit // setup cups options int nNumOptions = 0; cups_option_t* pOptions = NULL; - getOptionsFromDocumentSetup( rDocumentJobData, nNumOptions, (void**)&pOptions ); + getOptionsFromDocumentSetup( rDocumentJobData, bBanner, nNumOptions, (void**)&pOptions ); cups_dest_t* pDest = ((cups_dest_t*)m_pDests) + dest_it->second; nJobID = m_pCUPSWrapper->cupsPrintFile( pDest->name, diff --git a/vcl/unx/source/printer/jobdata.cxx b/vcl/unx/source/printer/jobdata.cxx index a1bca9441f77..d4211eae31df 100644 --- a/vcl/unx/source/printer/jobdata.cxx +++ b/vcl/unx/source/printer/jobdata.cxx @@ -51,6 +51,7 @@ JobData& JobData::operator=(const JobData& rRight) m_pParser = rRight.m_pParser; m_aContext = rRight.m_aContext; m_nPSLevel = rRight.m_nPSLevel; + m_nPDFDevice = rRight.m_nPDFDevice; m_nColorDevice = rRight.m_nColorDevice; if( ! m_pParser && m_aPrinterName.getLength() ) @@ -83,6 +84,34 @@ void JobData::setCollate( bool bCollate ) } } +bool JobData::setPaper( int i_nWidth, int i_nHeight ) +{ + bool bSuccess = false; + if( m_pParser ) + { + rtl::OUString aPaper( m_pParser->matchPaper( i_nWidth, i_nHeight ) ); + + const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); + const PPDValue* pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : NULL; + + bSuccess = pKey && pValue && m_aContext.setValue( pKey, pValue, false ); + } + return bSuccess; +} + +bool JobData::setPaperBin( int i_nPaperBin ) +{ + bool bSuccess = false; + if( m_pParser ) + { + const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ); + const PPDValue* pValue = pKey ? pKey->getValue( i_nPaperBin ) : NULL; + + bSuccess = pKey && pValue && m_aContext.setValue( pKey, pValue, false ); + } + return bSuccess; +} + bool JobData::getStreamBuffer( void*& pData, int& bytes ) { // consistency checks @@ -128,6 +157,10 @@ bool JobData::getStreamBuffer( void*& pData, int& bytes ) aLine += ByteString::CreateFromInt32( m_nPSLevel ); aStream.WriteLine( aLine ); + aLine = "pdfdevice="; + aLine += ByteString::CreateFromInt32( m_nPDFDevice ); + aStream.WriteLine( aLine ); + aLine = "colordevice="; aLine += ByteString::CreateFromInt32( m_nColorDevice ); aStream.WriteLine( aLine ); @@ -158,6 +191,7 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa bool bColorDepth = false; bool bColorDevice = false; bool bPSLevel = false; + bool bPDFDevice = false; while( ! aStream.IsEof() ) { aStream.ReadLine( aLine ); @@ -202,6 +236,11 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa bPSLevel = true; rJobData.m_nPSLevel = aLine.Copy( 8 ).ToInt32(); } + else if( aLine.CompareTo( "pdfdevice=", 10 ) == COMPARE_EQUAL ) + { + bPDFDevice = true; + rJobData.m_nPDFDevice = aLine.Copy( 10 ).ToInt32(); + } else if( aLine.Equals( "PPDContexData" ) ) { if( bPrinter ) @@ -222,5 +261,5 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa } } - return bVersion && bPrinter && bOrientation && bCopies && bContext && bMargin && bPSLevel && bColorDevice && bColorDepth; + return bVersion && bPrinter && bOrientation && bCopies && bContext && bMargin && bPSLevel && bPDFDevice && bColorDevice && bColorDepth; } diff --git a/vcl/unx/source/printer/ppdparser.cxx b/vcl/unx/source/printer/ppdparser.cxx index b2549573d099..587e58be5bc7 100644 --- a/vcl/unx/source/printer/ppdparser.cxx +++ b/vcl/unx/source/printer/ppdparser.cxx @@ -405,51 +405,53 @@ void PPDParser::scanPPDDir( const String& rDir ) const int nSuffixes = sizeof(pSuffixes)/sizeof(pSuffixes[0]); osl::Directory aDir( rDir ); - aDir.open(); - osl::DirectoryItem aItem; - - INetURLObject aPPDDir(rDir); - while( aDir.getNextItem( aItem ) == osl::FileBase::E_None ) + if ( aDir.open() == osl::FileBase::E_None ) { - osl::FileStatus aStatus( FileStatusMask_FileName ); - if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) + osl::DirectoryItem aItem; + + INetURLObject aPPDDir(rDir); + while( aDir.getNextItem( aItem ) == osl::FileBase::E_None ) { - rtl::OUStringBuffer aURLBuf( rDir.Len() + 64 ); - aURLBuf.append( rDir ); - aURLBuf.append( sal_Unicode( '/' ) ); - aURLBuf.append( aStatus.getFileName() ); + osl::FileStatus aStatus( FileStatusMask_FileName ); + if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) + { + rtl::OUStringBuffer aURLBuf( rDir.Len() + 64 ); + aURLBuf.append( rDir ); + aURLBuf.append( sal_Unicode( '/' ) ); + aURLBuf.append( aStatus.getFileName() ); - rtl::OUString aFileURL, aFileName; - osl::FileStatus::Type eType = osl::FileStatus::Unknown; + rtl::OUString aFileURL, aFileName; + osl::FileStatus::Type eType = osl::FileStatus::Unknown; - if( resolveLink( aURLBuf.makeStringAndClear(), aFileURL, aFileName, eType ) == osl::FileBase::E_None ) - { - if( eType == osl::FileStatus::Regular ) + if( resolveLink( aURLBuf.makeStringAndClear(), aFileURL, aFileName, eType ) == osl::FileBase::E_None ) { - INetURLObject aPPDFile = aPPDDir; - aPPDFile.Append( aFileName ); - - // match extension - for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ ) + if( eType == osl::FileStatus::Regular ) { - if( aFileName.getLength() > pSuffixes[nSuffix].nSuffixLen ) + INetURLObject aPPDFile = aPPDDir; + aPPDFile.Append( aFileName ); + + // match extension + for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ ) { - if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) ) + if( aFileName.getLength() > pSuffixes[nSuffix].nSuffixLen ) { - (*pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName(); - break; + if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) ) + { + (*pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName(); + break; + } } } } - } - else if( eType == osl::FileStatus::Directory ) - { - scanPPDDir( aFileURL ); + else if( eType == osl::FileStatus::Directory ) + { + scanPPDDir( aFileURL ); + } } } } + aDir.close(); } - aDir.close(); } void PPDParser::initPPDFiles() diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx index e1d499c40ca5..af189b1b01b5 100644 --- a/vcl/unx/source/printer/printerinfomanager.cxx +++ b/vcl/unx/source/printer/printerinfomanager.cxx @@ -35,6 +35,7 @@ #include "cupsmgr.hxx" #include "vcl/fontmanager.hxx" #include "vcl/strhelper.hxx" +#include "saldata.hxx" #include "tools/urlobj.hxx" #include "tools/stream.hxx" @@ -92,22 +93,28 @@ namespace psp PrinterInfoManager& PrinterInfoManager::get() { - static PrinterInfoManager* pManager = NULL; + SalData* pSalData = GetSalData(); - if( ! pManager ) + if( ! pSalData->m_pPIManager ) { - pManager = CUPSManager::tryLoadCUPS(); - if( ! pManager ) - pManager = new PrinterInfoManager(); + pSalData->m_pPIManager = CUPSManager::tryLoadCUPS(); + if( ! pSalData->m_pPIManager ) + pSalData->m_pPIManager = new PrinterInfoManager(); - if( pManager ) - pManager->initialize(); + pSalData->m_pPIManager->initialize(); #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "PrinterInfoManager::get create Manager of type %d\n", pManager->getType() ); + fprintf( stderr, "PrinterInfoManager::get create Manager of type %d\n", pSalData->m_pPIManager->getType() ); #endif } - return *pManager; + return *pSalData->m_pPIManager; +} + +void PrinterInfoManager::release() +{ + SalData* pSalData = GetSalData(); + delete pSalData->m_pPIManager; + pSalData->m_pPIManager = NULL; } // ----------------------------------------------------------------- @@ -130,6 +137,9 @@ PrinterInfoManager::PrinterInfoManager( Type eType ) : PrinterInfoManager::~PrinterInfoManager() { delete m_pQueueInfo; + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "PrinterInfoManager: destroyed Manager of type %d\n", getType() ); + #endif } // ----------------------------------------------------------------- @@ -283,6 +293,10 @@ void PrinterInfoManager::initialize() if( aValue.Len() ) m_aGlobalDefaults.m_nPSLevel = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PDFDevice" ); + if( aValue.Len() ) + m_aGlobalDefaults.m_nPDFDevice = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PerformFontSubstitution" ); if( aValue.Len() ) { @@ -324,7 +338,7 @@ void PrinterInfoManager::initialize() } } #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "global settings: fontsubst = %s, %d substitutes\n", m_aGlobalDefaults.m_bPerformFontSubstitution ? "true" : "false", m_aGlobalDefaults.m_aFontSubstitutes.size() ); + fprintf( stderr, "global settings: fontsubst = %s, %d substitutes\n", m_aGlobalDefaults.m_bPerformFontSubstitution ? "true" : "false", (int)m_aGlobalDefaults.m_aFontSubstitutes.size() ); #endif } } @@ -494,6 +508,10 @@ void PrinterInfoManager::initialize() if( aValue.Len() ) aPrinter.m_aInfo.m_nPSLevel = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PDFDevice" ); + if( aValue.Len() ) + aPrinter.m_aInfo.m_nPDFDevice = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PerformFontSubstitution" ); if( ! aValue.Equals( "0" ) && ! aValue.EqualsIgnoreCaseAscii( "false" ) ) aPrinter.m_aInfo.m_bPerformFontSubstitution = true; @@ -624,7 +642,7 @@ const PrinterInfo& PrinterInfoManager::getPrinterInfo( const OUString& rPrinter static PrinterInfo aEmptyInfo; ::std::hash_map< OUString, Printer, OUStringHash >::const_iterator it = m_aPrinters.find( rPrinter ); - DBG_ASSERT( it != m_aPrinters.end(), "Do not ask for info about nonexistant printers" ); + DBG_ASSERT( it != m_aPrinters.end(), "Do not ask for info about nonexistent printers" ); return it != m_aPrinters.end() ? it->second.m_aInfo : aEmptyInfo; } @@ -758,6 +776,7 @@ bool PrinterInfoManager::writePrinterConfig() pConfig->WriteKey( "Copies", ByteString::CreateFromInt32( it->second.m_aInfo.m_nCopies ) ); pConfig->WriteKey( "Orientation", it->second.m_aInfo.m_eOrientation == orientation::Landscape ? "Landscape" : "Portrait" ); pConfig->WriteKey( "PSLevel", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPSLevel ) ); + pConfig->WriteKey( "PDFDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPDFDevice ) ); pConfig->WriteKey( "ColorDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDevice ) ); pConfig->WriteKey( "ColorDepth", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDepth ) ); aValue = ByteString::CreateFromInt32( it->second.m_aInfo.m_nLeftMarginAdjust ); @@ -845,9 +864,10 @@ bool PrinterInfoManager::addPrinter( const OUString& rPrinterName, const OUStrin m_aPrinters[ rPrinterName ] = aPrinter; bSuccess = true; #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "new printer %s, level = %d, colordevice = %d, depth = %d\n", + fprintf( stderr, "new printer %s, level = %d, pdfdevice = %d, colordevice = %d, depth = %d\n", OUStringToOString( rPrinterName, osl_getThreadTextEncoding() ).getStr(), m_aPrinters[rPrinterName].m_aInfo.m_nPSLevel, + m_aPrinters[rPrinterName].m_aInfo.m_nPDFDevice, m_aPrinters[rPrinterName].m_aInfo.m_nColorDevice, m_aPrinters[rPrinterName].m_aInfo.m_nColorDepth ); #endif @@ -1095,7 +1115,7 @@ FILE* PrinterInfoManager::startSpool( const OUString& rPrintername, bool bQuickC return popen (aShellCommand.getStr(), "w"); } -int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/ ) +int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ ) { return (0 == pclose( pFile )); } @@ -1166,7 +1186,11 @@ SystemQueueInfo::SystemQueueInfo() : SystemQueueInfo::~SystemQueueInfo() { - terminate(); + static const char* pNoSyncDetection = getenv( "SAL_DISABLE_SYNCHRONOUS_PRINTER_DETECTION" ); + if( ! pNoSyncDetection || !*pNoSyncDetection ) + join(); + else + terminate(); } bool SystemQueueInfo::hasChanged() const diff --git a/vcl/unx/source/printergfx/printerjob.cxx b/vcl/unx/source/printergfx/printerjob.cxx index 3e885d8af5b4..af2cf14b1a0c 100644 --- a/vcl/unx/source/printergfx/printerjob.cxx +++ b/vcl/unx/source/printergfx/printerjob.cxx @@ -284,7 +284,8 @@ removeSpoolDir (const rtl::OUString& rSpoolDir) nChar = psp::appendStr ("rm -rf ", pSystem); nChar += psp::appendStr (aSysPathByte.getStr(), pSystem + nChar); - system (pSystem); + if (system (pSystem) == -1) + OSL_ENSURE( 0, "psprint: couldn't remove spool directory" ); } /* creates a spool directory with a "pidgin random" value based on @@ -340,7 +341,8 @@ PrinterJob::~PrinterJob () delete mpJobTrailer; // XXX should really call osl::remove routines - removeSpoolDir (maSpoolDirName); + if( maSpoolDirName.getLength() ) + removeSpoolDir (maSpoolDirName); // osl::Directory::remove (maSpoolDirName); } @@ -494,6 +496,10 @@ PrinterJob::StartJob ( sal_Bool PrinterJob::EndJob () { + // no pages ? that really means no print job + if( maPageList.empty() ) + return sal_False; + // write document setup (done here because it // includes the accumulated fonts if( mpJobHeader ) @@ -609,7 +615,7 @@ PrinterJob::EndJob () { PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get(); if (0 == rPrinterInfoManager.endSpool( m_aLastJobData.m_aPrinterName, - maJobTitle, pDestFILE, m_aDocumentJobData )) + maJobTitle, pDestFILE, m_aDocumentJobData, true )) { bSuccess = sal_False; } diff --git a/vcl/unx/source/window/makefile.mk b/vcl/unx/source/window/makefile.mk index 808b712903f3..c5cd95ba6b1c 100644 --- a/vcl/unx/source/window/makefile.mk +++ b/vcl/unx/source/window/makefile.mk @@ -48,7 +48,7 @@ dummy: .ELSE # "$(GUIBASE)"!="unx" SLOFILES= \ - $(SLO)/FWS.obj $(SLO)/salframe.obj $(SLO)/salobj.obj $(SLO)/salmenu.obj + $(SLO)/FWS.obj $(SLO)/salframe.obj $(SLO)/salobj.obj .ENDIF # "$(GUIBASE)"!="unx" diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx index 6d243e41db8c..11c20aa40f5a 100644 --- a/vcl/unx/source/window/salframe.cxx +++ b/vcl/unx/source/window/salframe.cxx @@ -665,6 +665,7 @@ X11SalFrame::X11SalFrame( SalFrame *pParent, ULONG nSalFrameStyle, SystemParentD mhStackingWindow = None; mhForeignParent = None; mhBackgroundPixmap = None; + m_bSetFocusOnMap = false; pGraphics_ = NULL; pFreeGraphics_ = NULL; @@ -1226,14 +1227,11 @@ void X11SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) } XLIB_Time nUserTime = 0; - if( ! bNoActivate && (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) - { - if( GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("Metacity") ) - nUserTime = pDisplay_->GetLastUserEventTime( true ); - else - nUserTime = pDisplay_->GetLastUserEventTime(); - } + if( ! bNoActivate && (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) == 0 ) + nUserTime = pDisplay_->GetLastUserEventTime( true ); GetDisplay()->getWMAdaptor()->setUserTime( this, nUserTime ); + if( ! bNoActivate && (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) ) + m_bSetFocusOnMap = true; // actually map the window if( m_bXEmbed ) @@ -3146,6 +3144,100 @@ GetAlternateKeyCode( const USHORT nKeyCode ) return aAlternate; } +void X11SalFrame::beginUnicodeSequence() +{ + rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() ); + DeletionListener aDeleteWatch( this ); + + if( rSeq.getLength() ) + endUnicodeSequence(); + + rSeq = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "u" ) ); + + if( ! aDeleteWatch.isDeleted() ) + { + USHORT nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; + SalExtTextInputEvent aEv; + aEv.mnTime = 0; + aEv.maText = rSeq; + aEv.mpTextAttr = &nTextAttr; + aEv.mnCursorPos = 0; + aEv.mnDeltaStart = 0; + aEv.mnCursorFlags = 0; + aEv.mbOnlyCursor = FALSE; + + CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv); + } +} + +bool X11SalFrame::appendUnicodeSequence( sal_Unicode c ) +{ + bool bRet = false; + rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() ); + if( rSeq.getLength() > 0 ) + { + // range check + if( (c >= sal_Unicode('0') && c <= sal_Unicode('9')) || + (c >= sal_Unicode('a') && c <= sal_Unicode('f')) || + (c >= sal_Unicode('A') && c <= sal_Unicode('F')) ) + { + rtl::OUStringBuffer aBuf( rSeq.getLength() + 1 ); + aBuf.append( rSeq ); + aBuf.append( c ); + rSeq = aBuf.makeStringAndClear(); + std::vector<USHORT> attribs( rSeq.getLength(), SAL_EXTTEXTINPUT_ATTR_UNDERLINE ); + + SalExtTextInputEvent aEv; + aEv.mnTime = 0; + aEv.maText = rSeq; + aEv.mpTextAttr = &attribs[0]; + aEv.mnCursorPos = 0; + aEv.mnDeltaStart = 0; + aEv.mnCursorFlags = 0; + aEv.mbOnlyCursor = FALSE; + + CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv); + bRet = true; + } + else + bRet = endUnicodeSequence(); + } + else + endUnicodeSequence(); + return bRet; +} + +bool X11SalFrame::endUnicodeSequence() +{ + rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() ); + + DeletionListener aDeleteWatch( this ); + if( rSeq.getLength() > 1 && rSeq.getLength() < 6 ) + { + // cut the "u" + rtl::OUString aNumbers( rSeq.copy( 1 ) ); + sal_Int32 nValue = aNumbers.toInt32( 16 ); + if( nValue >= 32 ) + { + USHORT nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; + SalExtTextInputEvent aEv; + aEv.mnTime = 0; + aEv.maText = rtl::OUString( sal_Unicode(nValue) ); + aEv.mpTextAttr = &nTextAttr; + aEv.mnCursorPos = 0; + aEv.mnDeltaStart = 0; + aEv.mnCursorFlags = 0; + aEv.mbOnlyCursor = FALSE; + CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv); + } + } + bool bWasInput = rSeq.getLength() > 0; + rSeq = rtl::OUString(); + if( bWasInput && ! aDeleteWatch.isDeleted() ) + CallCallback(SALEVENT_ENDEXTTEXTINPUT, NULL); + return bWasInput; +} + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent ) { @@ -3191,6 +3283,9 @@ long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent ) if( pEvent->state & Mod1Mask ) nModCode |= KEY_MOD2; + if( nModCode != (KEY_SHIFT|KEY_MOD1) ) + endUnicodeSequence(); + if( nKeySym == XK_Shift_L || nKeySym == XK_Shift_R || nKeySym == XK_Control_L || nKeySym == XK_Control_R || nKeySym == XK_Alt_L || nKeySym == XK_Alt_R @@ -3314,6 +3409,33 @@ long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent ) if( !nKeyCode && !nLen && !nKeyString) return 0; + DeletionListener aDeleteWatch( this ); + + if( nModCode == (KEY_SHIFT | KEY_MOD1) && pEvent->type == XLIB_KeyPress ) + { + USHORT nSeqKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy ); + if( nSeqKeyCode == KEY_U ) + { + beginUnicodeSequence(); + return 1; + } + else if( nSeqKeyCode >= KEY_0 && nSeqKeyCode <= KEY_9 ) + { + if( appendUnicodeSequence( sal_Unicode( '0' ) + sal_Unicode(nSeqKeyCode - KEY_0) ) ) + return 1; + } + else if( nSeqKeyCode >= KEY_A && nSeqKeyCode <= KEY_F ) + { + if( appendUnicodeSequence( sal_Unicode( 'a' ) + sal_Unicode(nSeqKeyCode - KEY_A) ) ) + return 1; + } + else + endUnicodeSequence(); + } + + if( aDeleteWatch.isDeleted() ) + return 0; + rtl_TextEncoding nEncoding; if (mpInputContext != NULL && mpInputContext->IsMultiLingual() ) @@ -3372,8 +3494,6 @@ long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent ) nSize = 0; } - DeletionListener aDeleteWatch( this ); - if ( mpInputContext != NULL && mpInputContext->UseContext() && KeyRelease != pEvent->type @@ -3468,9 +3588,7 @@ long X11SalFrame::HandleFocusEvent( XFocusChangeEvent *pEvent ) if( FocusIn == pEvent->type ) { -#ifndef _USE_PRINT_EXTENSION_ vcl_sal::PrinterUpdate::update(); -#endif mbInputFocus = True; ImplSVData* pSVData = ImplGetSVData(); @@ -4172,6 +4290,7 @@ long X11SalFrame::Dispatch( XEvent *pEvent ) &aEvent ); } + bool bSetFocus = m_bSetFocusOnMap; /* #99570# another workaround for sawfish: if a transient window for the same parent is shown * sawfish does not set the focus to it. Applies only for click to focus mode. */ @@ -4181,7 +4300,7 @@ long X11SalFrame::Dispatch( XEvent *pEvent ) // since this will lead to a parent loose-focus, close status, // reget focus, open status, .... flicker loop if ( (I18NStatus::get().getStatusFrame() != this) ) - XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent, CurrentTime ); + bSetFocus = true; } /* @@ -4219,10 +4338,21 @@ long X11SalFrame::Dispatch( XEvent *pEvent ) mpParent->GetShellWindow(), RevertToParent, CurrentTime ); + bSetFocus = false; } + if( bSetFocus ) + { + XSetInputFocus( GetXDisplay(), + GetShellWindow(), + RevertToParent, + CurrentTime ); + } + + RestackChildren(); mbInShow = FALSE; + m_bSetFocusOnMap = false; } break; diff --git a/vcl/unx/source/window/salmenu.cxx b/vcl/unx/source/window/salmenu.cxx deleted file mode 100644 index 0739b6cd5352..000000000000 --- a/vcl/unx/source/window/salmenu.cxx +++ /dev/null @@ -1,132 +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. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - - -#include <saldata.hxx> -#include <salinst.h> -#include <salmenu.h> - - -// ======================================================================= - -// X11SalInst factory methods - -SalMenu* X11SalInstance::CreateMenu( BOOL /*bMenuBar*/ ) -{ - return NULL; // no support for native menues -} - -void X11SalInstance::DestroyMenu( SalMenu* pSalMenu ) -{ - delete pSalMenu; -} - - -SalMenuItem* X11SalInstance::CreateMenuItem( const SalItemParams* ) -{ - return NULL; // no support for native menues -} - -void X11SalInstance::DestroyMenuItem( SalMenuItem* pSalMenuItem ) -{ - delete pSalMenuItem; -} - - -// ======================================================================= - - -/* - * X11SalMenu - */ - - -X11SalMenu::~X11SalMenu() -{ -} - -BOOL X11SalMenu::VisibleMenuBar() -{ - return FALSE; -} - -void X11SalMenu::SetFrame( const SalFrame* ) -{ -} - -void X11SalMenu::InsertItem( SalMenuItem*, unsigned ) -{ -} - -void X11SalMenu::RemoveItem( unsigned ) -{ -} - -void X11SalMenu::SetSubMenu( SalMenuItem*, SalMenu*, unsigned ) -{ -} - -void X11SalMenu::CheckItem( unsigned, BOOL ) -{ -} - -void X11SalMenu::EnableItem( unsigned, BOOL ) -{ -} - -void X11SalMenu::SetItemImage( unsigned, SalMenuItem*, const Image& ) -{ -} - -void X11SalMenu::SetItemText( unsigned, SalMenuItem*, const XubString& ) -{ -} - -void X11SalMenu::SetAccelerator( unsigned, SalMenuItem*, const KeyCode&, const XubString& ) -{ -} - -void X11SalMenu::GetSystemMenuData( SystemMenuData* ) -{ -} - -// ======================================================================= - -/* - * SalMenuItem - */ - - -X11SalMenuItem::~X11SalMenuItem() -{ -} - -// ------------------------------------------------------------------- - diff --git a/vcl/unx/source/window/salobj.cxx b/vcl/unx/source/window/salobj.cxx index 647b95ae032c..2ff6d05c35c6 100644 --- a/vcl/unx/source/window/salobj.cxx +++ b/vcl/unx/source/window/salobj.cxx @@ -559,3 +559,10 @@ long X11SalObject::Dispatch( XEvent* pEvent ) } return 0; } + +// ----------------------------------------------------------------------- + +void X11SalObject::InterceptChildWindowKeyDown( sal_Bool /*bIntercept*/ ) +{ +} + diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk index eb54531c375c..8d1de2ed30f0 100644 --- a/vcl/util/makefile.mk +++ b/vcl/util/makefile.mk @@ -125,7 +125,6 @@ HXXDEPNLST= $(INC)$/vcl$/accel.hxx \ $(INC)$/vcl$/virdev.hxx \ $(INC)$/vcl$/wall.hxx \ $(INC)$/vcl$/waitobj.hxx \ - $(INC)$/vcl$/wintypes.hxx \ $(INC)$/vcl$/window.hxx \ $(INC)$/vcl$/wrkwin.hxx @@ -312,7 +311,7 @@ SHL2STDLIBS=\ # prepare linking of Xinerama .IF "$(USE_XINERAMA)" != "NO" -.IF "$(OS)"=="MACOSX" +.IF "$(OS)"=="MACOSX" || "$(OS)$(CPU)" == "LINUXX" XINERAMALIBS=-lXinerama .ELSE .IF "$(OS)" != "SOLARIS" || "$(USE_XINERAMA_VERSION)" == "Xorg" @@ -397,6 +396,9 @@ SHL4STDLIBS+= $(XRANDR_LIBS) .IF "$(ENABLE_KDE)" != "" .IF "$(KDE_ROOT)"!="" EXTRALIBPATHS+=-L$(KDE_ROOT)$/lib +.IF "$(OS)$(CPU)" == "LINUXX" +EXTRALIBPATHS+=-L$(KDE_ROOT)$/lib64 +.ENDIF .ENDIF LIB5TARGET=$(SLB)$/ikde_plug_ LIB5FILES=$(SLB)$/kdeplug.lib @@ -458,3 +460,16 @@ SHL6STDLIBS+= $(XRANDR_LIBS) .INCLUDE : target.mk +ALLTAR : $(MISC)/vcl.component + +.IF "$(OS)" == "MACOSX" +my_platform = .macosx +.ELIF "$(OS)" == "WNT" +my_platform = .windows +.END + +$(MISC)/vcl.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + vcl.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt vcl$(my_platform).component diff --git a/vcl/util/makefile2.pmk b/vcl/util/makefile2.pmk index df9ba1a214d7..ac2977ca8eab 100644 --- a/vcl/util/makefile2.pmk +++ b/vcl/util/makefile2.pmk @@ -36,6 +36,6 @@ CFLAGSCXX+=$(OBJCXXFLAGS) #building with stlport, but graphite was not built with stlport .IF "$(USE_SYSTEM_STL)"!="YES" .IF "$(SYSTEM_GRAPHITE)"=="YES" -CDEFS += -DADAPT_EXT_STL +CFLAGSCXX+=-DADAPT_EXT_STL .ENDIF .ENDIF diff --git a/vcl/util/target.pmk b/vcl/util/target.pmk index 3144acc4bc05..8ec15475bc90 100644 --- a/vcl/util/target.pmk +++ b/vcl/util/target.pmk @@ -37,8 +37,3 @@ ONLYDLL .SETDIR=$(PRJ)$/util: $(SLOFILES) dmake debug=t prjpch=t linkinc=t compinc=t ..$/$(OUTPATH)$/bin$/sv$(DLLPOSTFIX).dll @echo "READY" -.IF "$(USE_XPRINT)"!="TRUE" -.ELSE -CFLAGS+=-D_USE_PRINT_EXTENSION_=1 -.ENDIF - diff --git a/vcl/util/vcl.component b/vcl/util/vcl.component new file mode 100644 index 000000000000..da20fc916c32 --- /dev/null +++ b/vcl/util/vcl.component @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.datatransfer.X11ClipboardSupport"> + <service name="com.sun.star.datatransfer.clipboard.SystemClipboard"/> + </implementation> + <implementation name="com.sun.star.datatransfer.dnd.XdndDropTarget"> + <service name="com.sun.star.datatransfer.dnd.X11DropTarget"/> + </implementation> + <implementation name="com.sun.star.datatransfer.dnd.XdndSupport"> + <service name="com.sun.star.datatransfer.dnd.X11DragSource"/> + </implementation> + <implementation name="com.sun.star.frame.VCLSessionManagerClient"> + <service name="com.sun.star.frame.SessionManagerClient"/> + </implementation> + <implementation name="vcl::DisplayAccess"> + <service name="com.sun.star.awt.DisplayAccess"/> + </implementation> + <implementation name="vcl::FontIdentificator"> + <service name="com.sun.star.awt.FontIdentificator"/> + </implementation> +</component> diff --git a/vcl/util/vcl.macosx.component b/vcl/util/vcl.macosx.component new file mode 100644 index 000000000000..3aabcd8c7050 --- /dev/null +++ b/vcl/util/vcl.macosx.component @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.datatransfer.dnd.OleDragSource_V1"> + <service name="com.sun.star.datatransfer.dnd.OleDragSource"/> + </implementation> + <implementation name="com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"> + <service name="com.sun.star.datatransfer.dnd.OleDropTarget"/> + </implementation> + <implementation name="com.sun.star.datatransfer.clipboard.AquaClipboard"> + <service name="com.sun.star.datatransfer.clipboard.SystemClipboard"/> + </implementation> + <implementation name="com.sun.star.frame.VCLSessionManagerClient"> + <service name="com.sun.star.frame.SessionManagerClient"/> + </implementation> + <implementation name="vcl::DisplayAccess"> + <service name="com.sun.star.awt.DisplayAccess"/> + </implementation> + <implementation name="vcl::FontIdentificator"> + <service name="com.sun.star.awt.FontIdentificator"/> + </implementation> +</component> diff --git a/vcl/util/vcl.windows.component b/vcl/util/vcl.windows.component new file mode 100644 index 000000000000..72f7ace9f251 --- /dev/null +++ b/vcl/util/vcl.windows.component @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.frame.VCLSessionManagerClient"> + <service name="com.sun.star.frame.SessionManagerClient"/> + </implementation> + <implementation name="vcl::DisplayAccess"> + <service name="com.sun.star.awt.DisplayAccess"/> + </implementation> + <implementation name="vcl::FontIdentificator"> + <service name="com.sun.star.awt.FontIdentificator"/> + </implementation> +</component> diff --git a/vcl/win/inc/saldata.hxx b/vcl/win/inc/saldata.hxx index ec67272ed07f..48180bbe185b 100644..100755 --- a/vcl/win/inc/saldata.hxx +++ b/vcl/win/inc/saldata.hxx @@ -33,6 +33,8 @@ #include <vcl/salwtype.hxx> #include <wincomp.hxx> +#include "osl/module.h" + #include <set> // for hMenu validation #include <map> @@ -46,6 +48,8 @@ class Font; struct HDCCache; struct TempFontItem; +typedef HRESULT (WINAPI *DwmIsCompositionEnabled_ptr)(WIN_BOOL*); + // -------------------- // - Standard-Defines - // -------------------- @@ -131,12 +135,15 @@ public: SalIcon* mpFirstIcon; // icon cache, points to first icon, NULL if none TempFontItem* mpTempFontItem; BOOL mbThemeChanged; // true if visual theme was changed: throw away theme handles + BOOL mbThemeMenuSupport; // for GdiPlus GdiplusStartup/GdiplusShutdown ULONG_PTR gdiplusToken; std::set< HMENU > mhMenuSet; // keeps track of menu handles created by VCL, used by IsKnownMenuHandle() std::map< UINT,USHORT > maVKMap; // map some dynamic VK_* entries + oslModule maDwmLib; + DwmIsCompositionEnabled_ptr mpDwmIsCompositionEnabled; }; inline void SetSalData( SalData* pData ) { ImplGetSVData()->mpSalData = (void*)pData; } @@ -154,7 +161,6 @@ struct SalShlData UINT mnWheelScrollChars; // WheelScrollChars UINT mnWheelMsgId; // Wheel-Message-Id fuer W95 WORD mnVersion; // System-Version (311 == 3.11) - WIN_BOOL mbWNT; // kein W16/W95/W98 sondern ein NT WIN_BOOL mbW40; // Is System-Version >= 4.0 WIN_BOOL mbWXP; // Windows XP WIN_BOOL mbWPrinter; // true: use unicode printer functions @@ -213,6 +219,7 @@ void ImplSalYieldMutexAcquire(); void ImplSalYieldMutexRelease(); ULONG ImplSalReleaseYieldMutex(); void ImplSalAcquireYieldMutex( ULONG nCount ); +sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg ); // \\WIN\SOURCE\WINDOW\SALFRAME.CXX LRESULT CALLBACK SalFrameWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); diff --git a/vcl/win/inc/salgdi.h b/vcl/win/inc/salgdi.h index 4b97eeb98c0b..f592f53ae29c 100644..100755 --- a/vcl/win/inc/salgdi.h +++ b/vcl/win/inc/salgdi.h @@ -57,10 +57,10 @@ class ImplFontAttrCache; class ImplWinFontData : public ImplFontData { public: - ImplWinFontData( const ImplDevFontAttributes&, + explicit ImplWinFontData( const ImplDevFontAttributes&, int nFontHeight, WIN_BYTE eWinCharSet, WIN_BYTE nPitchAndFamily ); - ~ImplWinFontData(); + virtual ~ImplWinFontData(); virtual ImplFontData* Clone() const; virtual ImplFontEntry* CreateFontInstance( ImplFontSelectData& ) const; @@ -82,7 +82,7 @@ public: bool SupportsGraphite() const { return mbHasGraphiteSupport; } #endif - ImplFontCharMap* GetImplFontCharMap() const; + const ImplFontCharMap* GetImplFontCharMap() const; const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; } void SetEncodingVector( const Ucs2SIntMap* pNewVec ) const { @@ -127,9 +127,9 @@ public: #endif // GNG_VERT_HACK }; -// ------------------- -// - SalGraphicsData - -// ------------------- +// ------------------ +// - WinSalGraphics - +// ------------------ class WinSalGraphics : public SalGraphics { @@ -179,7 +179,7 @@ public: HFONT ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFontScale, HFONT& o_rOldFont ); public: - WinSalGraphics(); + explicit WinSalGraphics(); virtual ~WinSalGraphics(); protected: @@ -194,7 +194,7 @@ protected: virtual void drawPolygon( ULONG nPoints, const SalPoint* pPtAry ); virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ); virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ); - virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin); + virtual bool drawPolyLine( const ::basegfx::B2DPolygon&, double fTransparency, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin ); virtual sal_Bool drawPolyLineBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolygonBezier( ULONG nPoints, const SalPoint* pPtAry, const BYTE* pFlgAry ); virtual sal_Bool drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry ); @@ -227,17 +227,17 @@ protected: virtual BOOL drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize ); // native widget rendering methods that require mirroring - virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ); - virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, + virtual BOOL drawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption ); - virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, + virtual BOOL getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const rtl::OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion ); + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion ); virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, @@ -282,12 +282,12 @@ public: // set the font virtual USHORT SetFont( ImplFontSelectData*, int nFallbackLevel ); // get the current font's etrics - virtual void GetFontMetric( ImplFontMetricData* ); + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ); // get kernign pairs of the current font // return only PairCount if (pKernPairs == NULL) virtual ULONG GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ); // get the repertoire of the current font - virtual ImplFontCharMap* GetImplFontCharMap() const; + virtual const ImplFontCharMap* GetImplFontCharMap() const; // graphics must fill supplied font list virtual void GetDevFontList( ImplDevFontList* ); // graphics should call ImplAddDevFontSubstitute on supplied @@ -359,11 +359,11 @@ public: }; // Init/Deinit Graphics -void ImplSalInitGraphics( WinSalGraphics* mpData ); -void ImplSalDeInitGraphics( WinSalGraphics* mpData ); +void ImplSalInitGraphics( WinSalGraphics* ); +void ImplSalDeInitGraphics( WinSalGraphics* ); void ImplUpdateSysColorEntries(); int ImplIsSysColorEntry( SalColor nSalColor ); -void ImplGetLogFontFromFontSelect( HDC hDC, const ImplFontSelectData*, +void ImplGetLogFontFromFontSelect( HDC, const ImplFontSelectData*, LOGFONTW&, bool bTestVerticalAvail ); // ----------- @@ -397,7 +397,10 @@ inline bool ImplWinFontData::HasChar( sal_uInt32 cChar ) const cChar -= 0xF000; else if( mbAliasSymbolsHigh && (cChar <= 0xFF) ) cChar += 0xF000; + else + return false; return mpUnicodeMap->HasChar( cChar ); } #endif // _SV_SALGDI_H + diff --git a/vcl/win/inc/salinst.h b/vcl/win/inc/salinst.h index f3005e3ad30b..1ab59f8f7f9f 100644 --- a/vcl/win/inc/salinst.h +++ b/vcl/win/inc/salinst.h @@ -77,9 +77,11 @@ public: virtual vos::IMutex* GetYieldMutex(); virtual ULONG ReleaseYieldMutex(); virtual void AcquireYieldMutex( ULONG nCount ); + virtual bool CheckYieldMutex(); + virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); virtual bool AnyInput( USHORT nType ); - virtual SalMenu* CreateMenu( BOOL bMenuBar ); + virtual SalMenu* CreateMenu( BOOL bMenuBar, Menu* ); virtual void DestroyMenu( SalMenu* ); virtual SalMenuItem* CreateMenuItem( const SalItemParams* pItemData ); virtual void DestroyMenuItem( SalMenuItem* ); diff --git a/vcl/win/inc/salobj.h b/vcl/win/inc/salobj.h index 11ae96931321..ae7ea5271800 100644 --- a/vcl/win/inc/salobj.h +++ b/vcl/win/inc/salobj.h @@ -46,6 +46,7 @@ public: RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data RECT* mpNextClipRect; // Naechstes ClipRegion-Rect BOOL mbFirstClipRect; // Flag for first cliprect to insert + sal_Bool mbInterceptChildWindowKeyDown; // Intercept the KeyDown event sent to system child window WinSalObject* mpNextObject; // pointer to next object @@ -64,6 +65,7 @@ public: virtual void SetBackground(); virtual void SetBackground( SalColor nSalColor ); virtual const SystemEnvData* GetSystemData() const; + virtual void InterceptChildWindowKeyDown( sal_Bool bIntercept ); }; #endif // _SV_SALOBJ_H diff --git a/vcl/win/source/app/saldata.cxx b/vcl/win/source/app/saldata.cxx index bb8a198a96e6..5f94029ad817 100644 --- a/vcl/win/source/app/saldata.cxx +++ b/vcl/win/source/app/saldata.cxx @@ -119,42 +119,28 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 ) LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong ) { - if ( aSalShlData.mbWNT ) - return SetWindowLongW( hWnd, nIndex, dwNewLong ); - else - return SetWindowLongA( hWnd, nIndex, dwNewLong ); + return SetWindowLongW( hWnd, nIndex, dwNewLong ); } // ----------------------------------------------------------------------- LONG ImplGetWindowLong( HWND hWnd, int nIndex ) { - if ( aSalShlData.mbWNT ) - return GetWindowLongW( hWnd, nIndex ); - else - return GetWindowLongA( hWnd, nIndex ); + return GetWindowLongW( hWnd, nIndex ); } // ----------------------------------------------------------------------- WIN_BOOL ImplPostMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) { - if ( aSalShlData.mbWNT ) - return PostMessageW( hWnd, nMsg, wParam, lParam ); - else - return PostMessageA( hWnd, nMsg, wParam, lParam ); + return PostMessageW( hWnd, nMsg, wParam, lParam ); } // ----------------------------------------------------------------------- WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) { - WIN_BOOL bRet; - if ( aSalShlData.mbWNT ) - bRet = SendMessageW( hWnd, nMsg, wParam, lParam ); - else - bRet = SendMessageA( hWnd, nMsg, wParam, lParam ); - + WIN_BOOL bRet = SendMessageW( hWnd, nMsg, wParam, lParam ); return bRet; } @@ -162,29 +148,20 @@ WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax ) { - if ( aSalShlData.mbWNT ) - return GetMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax ); - else - return GetMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax ); + return GetMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax ); } // ----------------------------------------------------------------------- WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ) { - if ( aSalShlData.mbWNT ) - return PeekMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg ); - else - return PeekMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg ); + return PeekMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg ); } // ----------------------------------------------------------------------- LONG ImplDispatchMessage( CONST MSG *lpMsg ) { - if ( aSalShlData.mbWNT ) - return DispatchMessageW( lpMsg ); - else - return DispatchMessageA( lpMsg ); + return DispatchMessageW( lpMsg ); } diff --git a/vcl/win/source/app/salinfo.cxx b/vcl/win/source/app/salinfo.cxx index b7ea81d313ae..14cb5d63437a 100644 --- a/vcl/win/source/app/salinfo.cxx +++ b/vcl/win/source/app/salinfo.cxx @@ -160,7 +160,8 @@ bool WinSalSystem::initMonitors() std::hash_map< rtl::OUString, int, rtl::OUStringHash > aDeviceStringCount; while( EnumDisplayDevicesW( NULL, nDevice++, &aDev, 0 ) ) { - if( (aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0 ) // sort out non monitors + if( (aDev.StateFlags & DISPLAY_DEVICE_ACTIVE) + && !(aDev.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ) // sort out non/disabled monitors { aDev.DeviceName[31] = 0; aDev.DeviceString[127] = 0; diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx index 97dbb5285cca..2a2a1827a515 100644..100755 --- a/vcl/win/source/app/salinst.cxx +++ b/vcl/win/source/app/salinst.cxx @@ -47,7 +47,7 @@ #include <salobj.h> #include <vcl/salsys.hxx> #include <saltimer.h> -#include <vcl/salatype.hxx> +#include <vcl/apptypes.hxx> #include <salbmp.h> #include <vcl/salimestatus.hxx> #include <vcl/timer.hxx> @@ -323,10 +323,9 @@ void ImplSalAcquireYieldMutex( ULONG nCount ) // ----------------------------------------------------------------------- -#ifdef DBG_UTIL - -void ImplDbgTestSolarMutex() +bool WinSalInstance::CheckYieldMutex() { + bool bRet = true; SalData* pSalData = GetSalData(); DWORD nCurThreadId = GetCurrentThreadId(); if ( pSalData->mnAppThreadId != nCurThreadId ) @@ -336,7 +335,7 @@ void ImplDbgTestSolarMutex() SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; if ( pYieldMutex->mnThreadId != nCurThreadId ) { - DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" ); + bRet = false; } } } @@ -347,14 +346,13 @@ void ImplDbgTestSolarMutex() SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->mpSalYieldMutex; if ( pYieldMutex->mnThreadId != nCurThreadId ) { - DBG_ERROR( "SolarMutex not locked in the main thread" ); + bRet = false; } } } + return bRet; } -#endif - // ======================================================================= void SalData::initKeyCodeMap() @@ -436,9 +434,12 @@ SalData::SalData() mpFirstIcon = 0; // icon cache, points to first icon, NULL if none mpTempFontItem = 0; mbThemeChanged = FALSE; // true if visual theme was changed: throw away theme handles + mbThemeMenuSupport = FALSE; // init with NULL gdiplusToken = 0; + maDwmLib = 0; + mpDwmIsCompositionEnabled = 0; initKeyCodeMap(); @@ -505,7 +506,6 @@ SalInstance* CreateSalInstance() SalData* pSalData = GetSalData(); // determine the windows version - aSalShlData.mbWNT = 0; aSalShlData.mbWXP = 0; aSalShlData.mbWPrinter = 0; WORD nVer = (WORD)GetVersion(); @@ -518,7 +518,6 @@ SalInstance* CreateSalInstance() { if ( aSalShlData.maVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) { - aSalShlData.mbWNT = 1; // Windows XP ? if ( aSalShlData.maVersionInfo.dwMajorVersion > 5 || ( aSalShlData.maVersionInfo.dwMajorVersion == 5 && aSalShlData.maVersionInfo.dwMinorVersion >= 1 ) ) @@ -533,8 +532,6 @@ SalInstance* CreateSalInstance() // register frame class if ( !pSalData->mhPrevInst ) { - if ( aSalShlData.mbWNT ) - { WNDCLASSEXW aWndClassEx; aWndClassEx.cbSize = sizeof( aWndClassEx ); aWndClassEx.style = CS_OWNDC; @@ -570,53 +567,11 @@ SalInstance* CreateSalInstance() aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW; if ( !RegisterClassExW( &aWndClassEx ) ) return NULL; - } - else - { - WNDCLASSEXA aWndClassEx; - aWndClassEx.cbSize = sizeof( aWndClassEx ); - aWndClassEx.style = CS_OWNDC; - aWndClassEx.lpfnWndProc = SalFrameWndProcA; - aWndClassEx.cbClsExtra = 0; - aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA; - aWndClassEx.hInstance = pSalData->mhInst; - aWndClassEx.hCursor = 0; - aWndClassEx.hbrBackground = 0; - aWndClassEx.lpszMenuName = 0; - aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEA; - ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm ); - if ( !RegisterClassExA( &aWndClassEx ) ) - return NULL; - - aWndClassEx.hIcon = 0; - aWndClassEx.hIconSm = 0; - aWndClassEx.style |= CS_SAVEBITS; - aWndClassEx.lpszClassName = SAL_SUBFRAME_CLASSNAMEA; - if ( !RegisterClassExA( &aWndClassEx ) ) - return NULL; - - aWndClassEx.style = 0; - aWndClassEx.lpfnWndProc = SalComWndProcA; - aWndClassEx.cbWndExtra = 0; - aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEA; - if ( !RegisterClassExA( &aWndClassEx ) ) - return NULL; - } } - HWND hComWnd; - if ( aSalShlData.mbWNT ) - { - hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW, + HWND hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW, L"", WS_POPUP, 0, 0, 0, 0, 0, 0, pSalData->mhInst, NULL ); - } - else - { - hComWnd = CreateWindowExA( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEA, - "", WS_POPUP, 0, 0, 0, 0, 0, 0, - pSalData->mhInst, NULL ); - } if ( !hComWnd ) return NULL; @@ -721,8 +676,12 @@ void ImplSalYield( BOOL bWait, BOOL bHandleAllCurrentEvents ) { if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplSalDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } + bOneEvent = bWasMsg = true; } else @@ -733,8 +692,11 @@ void ImplSalYield( BOOL bWait, BOOL bHandleAllCurrentEvents ) { if ( ImplGetMessage( &aMsg, 0, 0, 0 ) ) { - TranslateMessage( &aMsg ); - ImplSalDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } } } } diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx index 444df039dd69..141c812dcd31 100644 --- a/vcl/win/source/gdi/salbmp.cxx +++ b/vcl/win/source/gdi/salbmp.cxx @@ -509,8 +509,8 @@ void WinSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) { PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB ); const USHORT nCount = pBuffer->maPalette.GetEntryCount(); - - memcpy( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGBQUAD ) ); + const USHORT nDIBColorCount = ImplGetDIBColorCount( mhDIB ); + memcpy( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), Min( nDIBColorCount, nCount ) * sizeof( RGBQUAD ) ); GlobalUnlock( mhDIB ); } diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index d1b5a9cfdeae..91662fb8aded 100644..100755 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -533,9 +533,10 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( const ImplFontData* pFace, // avoid fonts with unknown CMAP subtables for glyph fallback if( !pCharMap || pCharMap->IsDefaultMap() ) return false; + pCharMap->AddReference(); int nMatchCount = 0; - // static const int nMaxMatchCount = 1; // TODO: check more missing characters? + // static const int nMaxMatchCount = 1; // TODO: tolerate more missing characters? const sal_Int32 nStrLen = rMissingChars.getLength(); for( sal_Int32 nStrIdx = 0; nStrIdx < nStrLen; ++nStrIdx ) { @@ -543,6 +544,7 @@ bool WinGlyphFallbackSubstititution::HasMissingChars( const ImplFontData* pFace, nMatchCount += pCharMap->HasChar( uChar ); break; // for now } + pCharMap->DeReference(); const bool bHasMatches = (nMatchCount > 0); return bHasMatches; @@ -1206,11 +1208,10 @@ bool ImplWinFontData::IsGSUBstituted( sal_UCS4 cChar ) const // ----------------------------------------------------------------------- -ImplFontCharMap* ImplWinFontData::GetImplFontCharMap() const +const ImplFontCharMap* ImplWinFontData::GetImplFontCharMap() const { if( !mpUnicodeMap ) return NULL; - mpUnicodeMap->AddReference(); return mpUnicodeMap; } @@ -1320,6 +1321,7 @@ void ImplWinFontData::ReadCmapTable( HDC hDC ) const if( !mpUnicodeMap ) mpUnicodeMap = ImplFontCharMap::GetDefaultMap( bIsSymbolFont ); + mpUnicodeMap->AddReference(); } // ======================================================================= @@ -1364,10 +1366,6 @@ int CALLBACK SalEnumQueryFontProcExA( const ENUMLOGFONTEXA*, bool ImplIsFontAvailable( HDC hDC, const UniString& rName ) { - bool bAvailable = false; - - if ( aSalShlData.mbWNT ) - { // Test, if Font available LOGFONTW aLogFont; memset( &aLogFont, 0, sizeof( aLogFont ) ); @@ -1379,27 +1377,9 @@ bool ImplIsFontAvailable( HDC hDC, const UniString& rName ) memcpy( aLogFont.lfFaceName, rName.GetBuffer(), nNameLen*sizeof( wchar_t ) ); aLogFont.lfFaceName[nNameLen] = 0; - EnumFontFamiliesExW( hDC, &aLogFont, (FONTENUMPROCW)SalEnumQueryFontProcExW, - (LPARAM)(void*)&bAvailable, 0 ); - } - else - { - ByteString aTemp = ImplSalGetWinAnsiString( rName ); - - // Test, if Font available - LOGFONTA aLogFont; - memset( &aLogFont, 0, sizeof( aLogFont ) ); - aLogFont.lfCharSet = DEFAULT_CHARSET; - - UINT nNameLen = aTemp.Len(); - if ( nNameLen > sizeof( aLogFont.lfFaceName )-1 ) - nNameLen = sizeof( aLogFont.lfFaceName )-1; - memcpy( aLogFont.lfFaceName, aTemp.GetBuffer(), nNameLen ); - aLogFont.lfFaceName[nNameLen] = 0; - - EnumFontFamiliesExA( hDC, &aLogFont, (FONTENUMPROCA)SalEnumQueryFontProcExA, + bool bAvailable = false; + EnumFontFamiliesExW( hDC, &aLogFont, (FONTENUMPROCW)SalEnumQueryFontProcExW, (LPARAM)(void*)&bAvailable, 0 ); - } return bAvailable; } @@ -1562,7 +1542,7 @@ HFONT WinSalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFont // only required for virtual devices, see below for details hdcScreen = GetDC(0); - if( aSalShlData.mbWNT ) + if( true/*aSalShlData.mbWNT*/ ) { LOGFONTW aLogFont; ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true ); @@ -1622,63 +1602,6 @@ HFONT WinSalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFont hNewFont = hNewFont2; } } - else - { - if( !mpLogFont ) - // mpLogFont is needed for getting the kerning pairs - // TODO: get them from somewhere else - mpLogFont = new LOGFONTA; - LOGFONTA& aLogFont = *mpLogFont; - ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true ); - - // on the display we prefer Courier New when Courier is a - // bitmap only font and we need to stretch or rotate it - if( mbScreen - && (i_pFont->mnWidth != 0 - || i_pFont->mnOrientation != 0 - || i_pFont->mpFontData == NULL - || (i_pFont->mpFontData->GetHeight() != i_pFont->mnHeight)) - && !bImplSalCourierScalable - && bImplSalCourierNew - && (stricmp( aLogFont.lfFaceName, "Courier" ) == 0) ) - strncpy( aLogFont.lfFaceName, "Courier New", 11 ); - - // limit font requests to MAXFONTHEIGHT to work around driver problems - // TODO: share MAXFONTHEIGHT font instance - if( -aLogFont.lfHeight <= MAXFONTHEIGHT ) - o_rFontScale = 1.0; - else - { - o_rFontScale = -aLogFont.lfHeight / (float)MAXFONTHEIGHT; - aLogFont.lfHeight = -MAXFONTHEIGHT; - aLogFont.lfWidth = static_cast<LONG>( aLogFont.lfWidth / o_rFontScale ); - } - - hNewFont = ::CreateFontIndirectA( &aLogFont ); - if( hdcScreen ) - { - // select font into screen hdc first to get an antialiased font - // see knowledge base article 305290: - // "PRB: Fonts Not Drawn Antialiased on Device Context for DirectDraw Surface" - ::SelectFont( hdcScreen, ::SelectFont( hdcScreen , hNewFont ) ); - } - o_rOldFont = ::SelectFont( mhDC, hNewFont ); - - TEXTMETRICA aTextMetricA; - // when the font doesn't work try a replacement - if ( !::GetTextMetricsA( mhDC, &aTextMetricA ) ) - { - // the selected font doesn't work => try a replacement - // TODO: use its font fallback instead - LOGFONTA aTempLogFont = aLogFont; - strncpy( aTempLogFont.lfFaceName, "Courier New", 11 ); - aTempLogFont.lfPitchAndFamily = FIXED_PITCH; - HFONT hNewFont2 = CreateFontIndirectA( &aTempLogFont ); - ::SelectFont( mhDC, hNewFont2 ); - ::DeleteFont( hNewFont ); - hNewFont = hNewFont2; - } - } if( hdcScreen ) ::ReleaseDC( NULL, hdcScreen ); @@ -1760,23 +1683,21 @@ USHORT WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel ) // ----------------------------------------------------------------------- -void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) +void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { - if ( aSalShlData.mbWNT ) - { + // temporarily change the HDC to the font in the fallback level + HFONT hOldFont = SelectFont( mhDC, mhFonts[nFallbackLevel] ); + wchar_t aFaceName[LF_FACESIZE+60]; if( ::GetTextFaceW( mhDC, sizeof(aFaceName)/sizeof(wchar_t), aFaceName ) ) pMetric->maName = reinterpret_cast<const sal_Unicode*>(aFaceName); - } - else - { - char aFaceName[LF_FACESIZE+60]; - if( ::GetTextFaceA( mhDC, sizeof(aFaceName), aFaceName ) ) - pMetric->maName = ImplSalGetUniString( aFaceName ); - } + // get the font metric TEXTMETRICA aWinMetric; - if( !GetTextMetricsA( mhDC, &aWinMetric ) ) + const bool bOK = GetTextMetricsA( mhDC, &aWinMetric ); + // restore the HDC to the font in the base level + SelectFont( mhDC, hOldFont ); + if( !bOK ) return; // device independent font attributes @@ -1815,7 +1736,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) // #107888# improved metric compatibility for Asian fonts... // TODO: assess workaround below for CWS >= extleading // TODO: evaluate use of aWinMetric.sTypo* members for CJK - if( mpWinFontData[0] && mpWinFontData[0]->SupportsCJK() ) + if( mpWinFontData[nFallbackLevel] && mpWinFontData[nFallbackLevel]->SupportsCJK() ) { pMetric->mnIntLeading += pMetric->mnExtLeading; @@ -1833,11 +1754,6 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric ) pMetric->mnAscent += nHalfTmpExtLeading; pMetric->mnDescent += nOtherHalfTmpExtLeading; - - // #109280# HACK korean only: increase descent for wavelines and impr - if( !aSalShlData.mbWNT ) - if( mpWinFontData[0]->SupportsKorean() ) - pMetric->mnDescent += pMetric->mnExtLeading; } pMetric->mnMinKashida = GetMinKashidaWidth(); @@ -1991,45 +1907,21 @@ ULONG WinSalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) } mnFontKernPairCount = 0; - if ( aSalShlData.mbWNT ) + KERNINGPAIR* pPairs = NULL; + int nCount = ::GetKerningPairsW( mhDC, 0, NULL ); + if( nCount ) { - KERNINGPAIR* pPairs = NULL; - int nCount = ::GetKerningPairsW( mhDC, 0, NULL ); - if( nCount ) - { -#ifdef GCP_KERN_HACK - pPairs = new KERNINGPAIR[ nCount+1 ]; - mpFontKernPairs = pPairs; - mnFontKernPairCount = nCount; - ::GetKerningPairsW( mhDC, nCount, pPairs ); -#else // GCP_KERN_HACK - pPairs = pKernPairs; - nCount = (nCount < nPairs) : nCount : nPairs; - ::GetKerningPairsW( mhDC, nCount, pPairs ); - return nCount; -#endif // GCP_KERN_HACK - } - } - else - { - if ( !mnFontCharSetCount ) - ImplGetAllFontCharSets( this ); - - if ( mnFontCharSetCount <= 1 ) - ImplAddKerningPairs( this ); - else - { - // Query All Kerning Pairs from all possible CharSets - for ( BYTE i = 0; i < mnFontCharSetCount; i++ ) - { - mpLogFont->lfCharSet = mpFontCharSets[i]; - HFONT hNewFont = CreateFontIndirectA( mpLogFont ); - HFONT hOldFont = SelectFont( mhDC, hNewFont ); - ImplAddKerningPairs( this ); - SelectFont( mhDC, hOldFont ); - DeleteFont( hNewFont ); - } - } + #ifdef GCP_KERN_HACK + pPairs = new KERNINGPAIR[ nCount+1 ]; + mpFontKernPairs = pPairs; + mnFontKernPairCount = nCount; + ::GetKerningPairsW( mhDC, nCount, pPairs ); + #else // GCP_KERN_HACK + pPairs = pKernPairs; + nCount = (nCount < nPairs) : nCount : nPairs; + ::GetKerningPairsW( mhDC, nCount, pPairs ); + return nCount; + #endif // GCP_KERN_HACK } mbFontKernInit = FALSE; @@ -2053,7 +1945,7 @@ ULONG WinSalGraphics::GetKernPairs( ULONG nPairs, ImplKernPairData* pKernPairs ) // ----------------------------------------------------------------------- -ImplFontCharMap* WinSalGraphics::GetImplFontCharMap() const +const ImplFontCharMap* WinSalGraphics::GetImplFontCharMap() const { if( !mpWinFontData[0] ) return ImplFontCharMap::GetDefaultMap(); @@ -2261,19 +2153,7 @@ void ImplReleaseTempFonts( SalData& rSalData ) } else { - if( aSalShlData.mbWNT ) - ::RemoveFontResourceW( reinterpret_cast<LPCWSTR>(p->maFontFilePath.getStr()) ); - else - { - // poor man's string conversion because converter is gone - int nLen = p->maFontFilePath.getLength(); - char* pNameA = new char[ nLen + 1 ]; - for( int i = 0; i < nLen; ++i ) - pNameA[i] = (char)(p->maFontFilePath.getStr())[i]; - pNameA[ nLen ] = 0; - ::RemoveFontResourceA( pNameA ); - delete[] pNameA; - } + ::RemoveFontResourceW( reinterpret_cast<LPCWSTR>(p->maFontFilePath.getStr()) ); } rSalData.mpTempFontItem = p->mpNextItem; @@ -2415,14 +2295,6 @@ bool WinSalGraphics::AddTempDevFont( ImplDevFontList* pFontList, return false; UINT nPreferedCharSet = DEFAULT_CHARSET; - if ( !aSalShlData.mbWNT ) - { - // for W98 guess charset preference from active codepage - CHARSETINFO aCharSetInfo; - DWORD nCP = GetACP(); - if ( TranslateCharsetInfo( (DWORD*)nCP, &aCharSetInfo, TCI_SRCCODEPAGE ) ) - nPreferedCharSet = aCharSetInfo.ciCharset; - } // create matching FontData struct aDFA.mbSymbolFlag = false; // TODO: how to know it without accessing the font? @@ -2527,24 +2399,12 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) if ( TranslateCharsetInfo( (DWORD*)nCP, &aCharSetInfo, TCI_SRCCODEPAGE ) ) aInfo.mnPreferedCharSet = aCharSetInfo.ciCharset; - if ( aSalShlData.mbWNT ) - { - LOGFONTW aLogFont; - memset( &aLogFont, 0, sizeof( aLogFont ) ); - aLogFont.lfCharSet = DEFAULT_CHARSET; - aInfo.mpLogFontW = &aLogFont; - EnumFontFamiliesExW( mhDC, &aLogFont, + LOGFONTW aLogFont; + memset( &aLogFont, 0, sizeof( aLogFont ) ); + aLogFont.lfCharSet = DEFAULT_CHARSET; + aInfo.mpLogFontW = &aLogFont; + EnumFontFamiliesExW( mhDC, &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW, (LPARAM)(void*)&aInfo, 0 ); - } - else - { - LOGFONTA aLogFont; - memset( &aLogFont, 0, sizeof( aLogFont ) ); - aLogFont.lfCharSet = DEFAULT_CHARSET; - aInfo.mpLogFontA = &aLogFont; - EnumFontFamiliesExA( mhDC, &aLogFont, - (FONTENUMPROCA)SalEnumFontsProcExA, (LPARAM)(void*)&aInfo, 0 ); - } // Feststellen, was es fuer Courier-Schriften auf dem Bildschirm gibt, // um in SetFont() evt. Courier auf Courier New zu mappen @@ -2583,12 +2443,7 @@ BOOL WinSalGraphics::GetGlyphBoundRect( long nIndex, Rectangle& rRect ) GLYPHMETRICS aGM; aGM.gmptGlyphOrigin.x = aGM.gmptGlyphOrigin.y = 0; aGM.gmBlackBoxX = aGM.gmBlackBoxY = 0; - DWORD nSize = GDI_ERROR; - if ( aSalShlData.mbWNT ) - nSize = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, &aGM, 0, NULL, &aMat ); - else if( (nGGOFlags & GGO_GLYPH_INDEX) || (nIndex <= 255) ) - nSize = ::GetGlyphOutlineA( hDC, nIndex, nGGOFlags, &aGM, 0, NULL, &aMat ); - + DWORD nSize = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, &aGM, 0, NULL, &aMat ); if( nSize == GDI_ERROR ) return false; @@ -2608,7 +2463,6 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex, { rB2DPolyPoly.clear(); - BOOL bRet = FALSE; HDC hDC = mhDC; // use unity matrix @@ -2622,171 +2476,160 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex, nIndex &= GF_IDXMASK; GLYPHMETRICS aGlyphMetrics; - DWORD nSize1 = GDI_ERROR; - if ( aSalShlData.mbWNT ) - nSize1 = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, &aGlyphMetrics, 0, NULL, &aMat ); - else if( (nGGOFlags & GGO_GLYPH_INDEX) || (nIndex <= 255) ) - nSize1 = ::GetGlyphOutlineA( hDC, nIndex, nGGOFlags, &aGlyphMetrics, 0, NULL, &aMat ); - + const DWORD nSize1 = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, &aGlyphMetrics, 0, NULL, &aMat ); if( !nSize1 ) // blank glyphs are ok - bRet = TRUE; - else if( nSize1 != GDI_ERROR ) - { - BYTE* pData = new BYTE[ nSize1 ]; - DWORD nSize2; - if ( aSalShlData.mbWNT ) - nSize2 = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, - &aGlyphMetrics, nSize1, pData, &aMat ); - else - nSize2 = ::GetGlyphOutlineA( hDC, nIndex, nGGOFlags, - &aGlyphMetrics, nSize1, pData, &aMat ); + return TRUE; + else if( nSize1 == GDI_ERROR ) + return FALSE; - if( nSize1 == nSize2 ) - { - bRet = TRUE; + BYTE* pData = new BYTE[ nSize1 ]; + const DWORD nSize2 = ::GetGlyphOutlineW( hDC, nIndex, nGGOFlags, + &aGlyphMetrics, nSize1, pData, &aMat ); + + if( nSize1 != nSize2 ) + return FALSE; + + // TODO: avoid tools polygon by creating B2DPolygon directly + int nPtSize = 512; + Point* pPoints = new Point[ nPtSize ]; + BYTE* pFlags = new BYTE[ nPtSize ]; + + TTPOLYGONHEADER* pHeader = (TTPOLYGONHEADER*)pData; + while( (BYTE*)pHeader < pData+nSize2 ) + { + // only outline data is interesting + if( pHeader->dwType != TT_POLYGON_TYPE ) + break; + + // get start point; next start points are end points + // of previous segment + USHORT nPnt = 0; - int nPtSize = 512; - Point* pPoints = new Point[ nPtSize ]; - BYTE* pFlags = new BYTE[ nPtSize ]; + long nX = IntTimes256FromFixed( pHeader->pfxStart.x ); + long nY = IntTimes256FromFixed( pHeader->pfxStart.y ); + pPoints[ nPnt ] = Point( nX, nY ); + pFlags[ nPnt++ ] = POLY_NORMAL; - TTPOLYGONHEADER* pHeader = (TTPOLYGONHEADER*)pData; - while( (BYTE*)pHeader < pData+nSize2 ) + bool bHasOfflinePoints = false; + TTPOLYCURVE* pCurve = (TTPOLYCURVE*)( pHeader + 1 ); + pHeader = (TTPOLYGONHEADER*)( (BYTE*)pHeader + pHeader->cb ); + while( (BYTE*)pCurve < (BYTE*)pHeader ) + { + int nNeededSize = nPnt + 16 + 3 * pCurve->cpfx; + if( nPtSize < nNeededSize ) { - // only outline data is interesting - if( pHeader->dwType != TT_POLYGON_TYPE ) - break; - - // get start point; next start points are end points - // of previous segment - USHORT nPnt = 0; - - long nX = IntTimes256FromFixed( pHeader->pfxStart.x ); - long nY = IntTimes256FromFixed( pHeader->pfxStart.y ); - pPoints[ nPnt ] = Point( nX, nY ); - pFlags[ nPnt++ ] = POLY_NORMAL; - - bool bHasOfflinePoints = false; - TTPOLYCURVE* pCurve = (TTPOLYCURVE*)( pHeader + 1 ); - pHeader = (TTPOLYGONHEADER*)( (BYTE*)pHeader + pHeader->cb ); - while( (BYTE*)pCurve < (BYTE*)pHeader ) + Point* pOldPoints = pPoints; + BYTE* pOldFlags = pFlags; + nPtSize = 2 * nNeededSize; + pPoints = new Point[ nPtSize ]; + pFlags = new BYTE[ nPtSize ]; + for( USHORT i = 0; i < nPnt; ++i ) { - int nNeededSize = nPnt + 16 + 3 * pCurve->cpfx; - if( nPtSize < nNeededSize ) - { - Point* pOldPoints = pPoints; - BYTE* pOldFlags = pFlags; - nPtSize = 2 * nNeededSize; - pPoints = new Point[ nPtSize ]; - pFlags = new BYTE[ nPtSize ]; - for( USHORT i = 0; i < nPnt; ++i ) - { - pPoints[ i ] = pOldPoints[ i ]; - pFlags[ i ] = pOldFlags[ i ]; - } - delete[] pOldPoints; - delete[] pOldFlags; - } + pPoints[ i ] = pOldPoints[ i ]; + pFlags[ i ] = pOldFlags[ i ]; + } + delete[] pOldPoints; + delete[] pOldFlags; + } - int i = 0; - if( TT_PRIM_LINE == pCurve->wType ) + int i = 0; + if( TT_PRIM_LINE == pCurve->wType ) + { + while( i < pCurve->cpfx ) + { + nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); + nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); + ++i; + pPoints[ nPnt ] = Point( nX, nY ); + pFlags[ nPnt ] = POLY_NORMAL; + ++nPnt; + } + } + else if( TT_PRIM_QSPLINE == pCurve->wType ) + { + bHasOfflinePoints = true; + while( i < pCurve->cpfx ) + { + // get control point of quadratic bezier spline + nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); + nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); + ++i; + Point aControlP( nX, nY ); + + // calculate first cubic control point + // P0 = 1/3 * (PBeg + 2 * PQControl) + nX = pPoints[ nPnt-1 ].X() + 2 * aControlP.X(); + nY = pPoints[ nPnt-1 ].Y() + 2 * aControlP.Y(); + pPoints[ nPnt+0 ] = Point( (2*nX+3)/6, (2*nY+3)/6 ); + pFlags[ nPnt+0 ] = POLY_CONTROL; + + // calculate endpoint of segment + nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); + nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); + + if ( i+1 >= pCurve->cpfx ) { - while( i < pCurve->cpfx ) - { - nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); - nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); - ++i; - pPoints[ nPnt ] = Point( nX, nY ); - pFlags[ nPnt ] = POLY_NORMAL; - ++nPnt; - } + // endpoint is either last point in segment => advance + ++i; } - else if( TT_PRIM_QSPLINE == pCurve->wType ) + else { - bHasOfflinePoints = true; - while( i < pCurve->cpfx ) - { - // get control point of quadratic bezier spline - nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); - nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); - ++i; - Point aControlP( nX, nY ); - - // calculate first cubic control point - // P0 = 1/3 * (PBeg + 2 * PQControl) - nX = pPoints[ nPnt-1 ].X() + 2 * aControlP.X(); - nY = pPoints[ nPnt-1 ].Y() + 2 * aControlP.Y(); - pPoints[ nPnt+0 ] = Point( (2*nX+3)/6, (2*nY+3)/6 ); - pFlags[ nPnt+0 ] = POLY_CONTROL; - - // calculate endpoint of segment - nX = IntTimes256FromFixed( pCurve->apfx[ i ].x ); - nY = IntTimes256FromFixed( pCurve->apfx[ i ].y ); - - if ( i+1 >= pCurve->cpfx ) - { - // endpoint is either last point in segment => advance - ++i; - } - else - { - // or endpoint is the middle of two control points - nX += IntTimes256FromFixed( pCurve->apfx[ i-1 ].x ); - nY += IntTimes256FromFixed( pCurve->apfx[ i-1 ].y ); - nX = (nX + 1) / 2; - nY = (nY + 1) / 2; - // no need to advance, because the current point - // is the control point in next bezier spline - } - - pPoints[ nPnt+2 ] = Point( nX, nY ); - pFlags[ nPnt+2 ] = POLY_NORMAL; - - // calculate second cubic control point - // P1 = 1/3 * (PEnd + 2 * PQControl) - nX = pPoints[ nPnt+2 ].X() + 2 * aControlP.X(); - nY = pPoints[ nPnt+2 ].Y() + 2 * aControlP.Y(); - pPoints[ nPnt+1 ] = Point( (2*nX+3)/6, (2*nY+3)/6 ); - pFlags[ nPnt+1 ] = POLY_CONTROL; - - nPnt += 3; - } + // or endpoint is the middle of two control points + nX += IntTimes256FromFixed( pCurve->apfx[ i-1 ].x ); + nY += IntTimes256FromFixed( pCurve->apfx[ i-1 ].y ); + nX = (nX + 1) / 2; + nY = (nY + 1) / 2; + // no need to advance, because the current point + // is the control point in next bezier spline } - // next curve segment - pCurve = (TTPOLYCURVE*)&pCurve->apfx[ i ]; - } + pPoints[ nPnt+2 ] = Point( nX, nY ); + pFlags[ nPnt+2 ] = POLY_NORMAL; - // end point is start point for closed contour - // disabled, because Polygon class closes the contour itself - // pPoints[nPnt++] = pPoints[0]; - // #i35928# - // Added again, but add only when not yet closed - if(pPoints[nPnt - 1] != pPoints[0]) - { - if( bHasOfflinePoints ) - pFlags[nPnt] = pFlags[0]; + // calculate second cubic control point + // P1 = 1/3 * (PEnd + 2 * PQControl) + nX = pPoints[ nPnt+2 ].X() + 2 * aControlP.X(); + nY = pPoints[ nPnt+2 ].Y() + 2 * aControlP.Y(); + pPoints[ nPnt+1 ] = Point( (2*nX+3)/6, (2*nY+3)/6 ); + pFlags[ nPnt+1 ] = POLY_CONTROL; - pPoints[nPnt++] = pPoints[0]; + nPnt += 3; } + } - // convert y-coordinates W32 -> VCL - for( int i = 0; i < nPnt; ++i ) - pPoints[i].Y() = -pPoints[i].Y(); + // next curve segment + pCurve = (TTPOLYCURVE*)&pCurve->apfx[ i ]; + } - // insert into polypolygon - Polygon aPoly( nPnt, pPoints, (bHasOfflinePoints ? pFlags : NULL) ); - // convert to B2DPolyPolygon - // TODO: get rid of the intermediate PolyPolygon - rB2DPolyPoly.append( aPoly.getB2DPolygon() ); - } + // end point is start point for closed contour + // disabled, because Polygon class closes the contour itself + // pPoints[nPnt++] = pPoints[0]; + // #i35928# + // Added again, but add only when not yet closed + if(pPoints[nPnt - 1] != pPoints[0]) + { + if( bHasOfflinePoints ) + pFlags[nPnt] = pFlags[0]; - delete[] pPoints; - delete[] pFlags; + pPoints[nPnt++] = pPoints[0]; } - delete[] pData; + // convert y-coordinates W32 -> VCL + for( int i = 0; i < nPnt; ++i ) + pPoints[i].Y() = -pPoints[i].Y(); + + // insert into polypolygon + Polygon aPoly( nPnt, pPoints, (bHasOfflinePoints ? pFlags : NULL) ); + // convert to B2DPolyPolygon + // TODO: get rid of the intermediate PolyPolygon + rB2DPolyPoly.append( aPoly.getB2DPolygon() ); } + delete[] pPoints; + delete[] pFlags; + + delete[] pData; + // rescaling needed for the PolyPolygon conversion if( rB2DPolyPoly.count() ) { @@ -2794,7 +2637,7 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex, rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor)); } - return bRet; + return TRUE; } // ----------------------------------------------------------------------- @@ -2875,8 +2718,6 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, ImplDoSetFont( &aIFSD, fScale, hOldFont ); ImplWinFontData* pWinFontData = (ImplWinFontData*)aIFSD.mpFontData; - pWinFontData->UpdateFromHDC( mhDC ); -/*const*/ ImplFontCharMap* pImplFontCharMap = pWinFontData->GetImplFontCharMap(); #if OSL_DEBUG_LEVEL > 1 // get font metrics @@ -2899,6 +2740,10 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, const RawFontData aRawCffData( mhDC, nCffTag ); if( aRawCffData.get() ) { + pWinFontData->UpdateFromHDC( mhDC ); + const ImplFontCharMap* pCharMap = pWinFontData->GetImplFontCharMap(); + pCharMap->AddReference(); + long nRealGlyphIds[ 256 ]; for( int i = 0; i < nGlyphCount; ++i ) { @@ -2906,13 +2751,15 @@ BOOL WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, // TODO: use GDI's GetGlyphIndices instead? Does it handle GSUB properly? sal_uInt32 nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK; if( pGlyphIDs[i] & GF_ISCHAR ) // remaining pseudo-glyphs need to be translated - nGlyphIdx = pImplFontCharMap->GetGlyphIndex( nGlyphIdx ); + nGlyphIdx = pCharMap->GetGlyphIndex( nGlyphIdx ); if( (pGlyphIDs[i] & (GF_ROTMASK|GF_GSUB)) != 0) // TODO: vertical substitution {/*####*/} nRealGlyphIds[i] = nGlyphIdx; } + pCharMap->DeReference(); // TODO: and and use a RAII object + // provide a font subset from the CFF-table FILE* pOutFile = fopen( aToFile.GetBuffer(), "wb" ); rInfo.LoadFont( FontSubsetInfo::CFF_FONT, aRawCffData.get(), aRawCffData.size() ); @@ -3160,8 +3007,9 @@ void WinSalGraphics::GetGlyphWidths( const ImplFontData* pFont, rUnicodeEnc.clear(); } const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFont); - ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap(); + const ImplFontCharMap* pMap = pWinFont->GetImplFontCharMap(); DBG_ASSERT( pMap && pMap->GetCharCount(), "no map" ); + pMap->AddReference(); int nCharCount = pMap->GetCharCount(); sal_uInt32 nChar = pMap->GetFirstChar(); @@ -3177,6 +3025,8 @@ void WinSalGraphics::GetGlyphWidths( const ImplFontData* pFont, } nChar = pMap->GetNextChar( nChar ); } + + pMap->DeReference(); // TODO: and and use a RAII object } } else if( pFont->IsEmbeddable() ) diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index c621d81dce40..88efbb29d30a 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -189,14 +189,15 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly return true; } -bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin) +bool WinSalGraphics::drawPolyLine( const basegfx::B2DPolygon& rPolygon, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin ) { const sal_uInt32 nCount(rPolygon.count()); if(mbPen && nCount) { Gdiplus::Graphics aGraphics(mhDC); - Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); + const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) ); + Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX())); Gdiplus::GraphicsPath aPath; bool bNoLineJoin(false); diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index be5d7f8360bc..97e3e1b48c79 100644..100755 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -188,6 +188,8 @@ void SalData::deInitNWF( void ) iter++; } aThemeMap.clear(); + if( maDwmLib ) + osl_unloadModule( maDwmLib ); } static HTHEME getThemeHandle( HWND hWnd, LPCWSTR name ) @@ -286,6 +288,22 @@ BOOL WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP case CTRL_MENUBAR: if( nPart == PART_ENTIRE_CONTROL ) hTheme = getThemeHandle( mhWnd, L"Rebar"); + else if( GetSalData()->mbThemeMenuSupport ) + { + if( nPart == PART_MENU_ITEM ) + hTheme = getThemeHandle( mhWnd, L"Menu" ); + } + break; + case CTRL_MENU_POPUP: + if( GetSalData()->mbThemeMenuSupport ) + { + if( nPart == PART_ENTIRE_CONTROL || + nPart == PART_MENU_ITEM || + nPart == PART_MENU_ITEM_CHECK_MARK || + nPart == PART_MENU_ITEM_RADIO_MARK || + nPart == PART_MENU_SEPARATOR ) + hTheme = getThemeHandle( mhWnd, L"Menu" ); + } break; case CTRL_PROGRESS: if( nPart == PART_ENTIRE_CONTROL ) @@ -317,7 +335,7 @@ BOOL WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP */ BOOL WinSalGraphics::hitTestNativeControl( ControlType, ControlPart, - const Region&, + const Rectangle&, const Point&, BOOL& ) { @@ -553,9 +571,9 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, } if( nType == CTRL_SPINBUTTONS && nPart == PART_ALL_BUTTONS ) { - SpinbuttonValue *pValue = (SpinbuttonValue*) aValue.getOptionalVal(); - if( pValue ) + if( aValue.getType() == CTRL_SPINBUTTONS ) { + const SpinbuttonValue *pValue = static_cast<const SpinbuttonValue*>(&aValue); BOOL bOk = FALSE; RECT rect; @@ -578,9 +596,9 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, //rc.bottom--; if( nPart == PART_ALL_BUTTONS ) { - SpinbuttonValue *pValue = (SpinbuttonValue*) aValue.getOptionalVal(); - if( pValue ) + if( aValue.getType() == CTRL_SPINBUTTONS ) { + const SpinbuttonValue *pValue = static_cast<const SpinbuttonValue*>(&aValue); BOOL bOk = FALSE; RECT rect; @@ -787,20 +805,19 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, iPart = TABP_TABITEMLEFTEDGE; rc.bottom--; - TabitemValue *pValue = (TabitemValue*) aValue.getOptionalVal(); - if( pValue ) + OSL_ASSERT( aValue.getType() == CTRL_TAB_ITEM ); + + const TabitemValue *pValue = static_cast<const TabitemValue*>(&aValue); + if( pValue->isBothAligned() ) { - if( pValue->isBothAligned() ) - { - iPart = TABP_TABITEMLEFTEDGE; - rc.right--; - } - else if( pValue->isLeftAligned() ) - iPart = TABP_TABITEMLEFTEDGE; - else if( pValue->isRightAligned() ) - iPart = TABP_TABITEMRIGHTEDGE; - else iPart = TABP_TABITEM; + iPart = TABP_TABITEMLEFTEDGE; + rc.right--; } + else if( pValue->isLeftAligned() ) + iPart = TABP_TABITEMLEFTEDGE; + else if( pValue->isRightAligned() ) + iPart = TABP_TABITEMRIGHTEDGE; + else iPart = TABP_TABITEM; if( !(nState & CTRL_STATE_ENABLED) ) iState = TILES_DISABLED; @@ -856,22 +873,35 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, } else if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT ) { - ToolbarValue *pValue = (ToolbarValue*) aValue.getOptionalVal(); - if( pValue && pValue->mbIsTopDockingArea ) - rc.top = 0; // extend potential gradient to cover menu bar as well + if( aValue.getType() == CTRL_TOOLBAR ) + { + const ToolbarValue *pValue = static_cast<const ToolbarValue*>(&aValue); + if( pValue->mbIsTopDockingArea ) + rc.top = 0; // extend potential gradient to cover menu bar as well + } return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); } } if( nType == CTRL_MENUBAR ) { - if( nPart != PART_ENTIRE_CONTROL ) - return FALSE; - - MenubarValue *pValue = (MenubarValue*) aValue.getOptionalVal(); - if( pValue ) - rc.bottom += pValue->maTopDockingAreaHeight; // extend potential gradient to cover docking area as well - return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + if( nPart == PART_ENTIRE_CONTROL ) + { + if( aValue.getType() == CTRL_MENUBAR ) + { + const MenubarValue *pValue = static_cast<const MenubarValue*>(&aValue); + rc.bottom += pValue->maTopDockingAreaHeight; // extend potential gradient to cover docking area as well + } + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption); + } + else if( nPart == PART_MENU_ITEM ) + { + if( (nState & CTRL_STATE_ENABLED) ) + iState = (nState & CTRL_STATE_SELECTED) ? MBI_HOT : MBI_NORMAL; + else + iState = (nState & CTRL_STATE_SELECTED) ? MBI_DISABLEDHOT : MBI_DISABLED; + return ImplDrawTheme( hTheme, hDC, MENU_BARITEM, iState, rc, aCaption ); + } } if( nType == CTRL_PROGRESS ) @@ -918,7 +948,8 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, ImplDrawTheme( hTheme, hDC, iPart, iState, aTRect, aCaption ); RECT aThumbRect; - SliderValue* pVal = (SliderValue*)aValue.getOptionalVal(); + OSL_ASSERT( aValue.getType() == CTRL_SLIDER ); + const SliderValue* pVal = static_cast<const SliderValue*>(&aValue); aThumbRect.left = pVal->maThumbRect.Left(); aThumbRect.top = pVal->maThumbRect.Top(); aThumbRect.right = pVal->maThumbRect.Right(); @@ -949,6 +980,69 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption ); } + if( GetSalData()->mbThemeMenuSupport ) + { + if( nType == CTRL_MENU_POPUP ) + { + if( nPart == PART_ENTIRE_CONTROL ) + { + RECT aGutterRC = rc; + aGutterRC.left += aValue.getNumericVal(); + aGutterRC.right = aGutterRC.left+3; + return + ImplDrawTheme( hTheme, hDC, MENU_POPUPBACKGROUND, 0, rc, aCaption ) && + ImplDrawTheme( hTheme, hDC, MENU_POPUPGUTTER, 0, aGutterRC, aCaption ) + ; + } + else if( nPart == PART_MENU_ITEM ) + { + if( (nState & CTRL_STATE_ENABLED) ) + iState = (nState & CTRL_STATE_SELECTED) ? MPI_HOT : MPI_NORMAL; + else + iState = (nState & CTRL_STATE_SELECTED) ? MPI_DISABLEDHOT : MPI_DISABLED; + return ImplDrawTheme( hTheme, hDC, MENU_POPUPITEM, iState, rc, aCaption ); + } + else if( nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK ) + { + if( (nState & CTRL_STATE_PRESSED) ) + { + RECT aBGRect = rc; + if( aValue.getType() == CTRL_MENU_POPUP ) + { + const MenupopupValue& rMVal( static_cast<const MenupopupValue&>(aValue) ); + aBGRect.left = rMVal.maItemRect.Left(); + aBGRect.top = rMVal.maItemRect.Top(); + aBGRect.bottom = rMVal.maItemRect.Bottom()+1; // see below in drawNativeControl + aBGRect.right = rMVal.getNumericVal(); + + // FIXME: magic + aBGRect.left += 1; aBGRect.top += 1; aBGRect.bottom +=1; + } + iState = (nState & CTRL_STATE_ENABLED) ? MCB_NORMAL : MCB_DISABLED; + ImplDrawTheme( hTheme, hDC, MENU_POPUPCHECKBACKGROUND, iState, aBGRect, aCaption ); + if( nPart == PART_MENU_ITEM_CHECK_MARK ) + iState = (nState & CTRL_STATE_ENABLED) ? MC_CHECKMARKNORMAL : MC_CHECKMARKDISABLED; + else + iState = (nState & CTRL_STATE_ENABLED) ? MC_BULLETNORMAL : MC_BULLETDISABLED; + return ImplDrawTheme( hTheme, hDC, MENU_POPUPCHECK, iState, rc, aCaption ); + } + else + return true; // unchecked: do nothing + } + else if( nPart == PART_MENU_SEPARATOR ) + { + rc.left += aValue.getNumericVal(); // adjust for gutter position + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, + MENU_POPUPSEPARATOR, 0, Rectangle( rc.left, rc.top, rc.right, rc.bottom ) ) ); + // center the separator inside the passed rectangle + long nDY = ((rc.bottom - rc.top + 1) - aRect.GetHeight()) / 2; + rc.top += nDY; + rc.bottom = rc.top+aRect.GetHeight()-1; + return ImplDrawTheme( hTheme, hDC, MENU_POPUPSEPARATOR, 0, rc, aCaption ); + } + } + } + return false; } @@ -963,7 +1057,7 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, */ BOOL WinSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption ) @@ -1022,6 +1116,11 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, case CTRL_MENUBAR: if( nPart == PART_ENTIRE_CONTROL ) hTheme = getThemeHandle( mhWnd, L"Rebar"); + else if( GetSalData()->mbThemeMenuSupport ) + { + if( nPart == PART_MENU_ITEM ) + hTheme = getThemeHandle( mhWnd, L"Menu" ); + } break; case CTRL_PROGRESS: if( nPart == PART_ENTIRE_CONTROL ) @@ -1035,6 +1134,16 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) hTheme = getThemeHandle( mhWnd, L"Trackbar" ); break; + case CTRL_MENU_POPUP: + if( GetSalData()->mbThemeMenuSupport ) + { + if( nPart == PART_ENTIRE_CONTROL || nPart == PART_MENU_ITEM || + nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK || + nPart == PART_MENU_SEPARATOR + ) + hTheme = getThemeHandle( mhWnd, L"Menu" ); + } + break; default: hTheme = NULL; break; @@ -1043,7 +1152,7 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, if( !hTheme ) return false; - Rectangle buttonRect = rControlRegion.GetBoundRect(); + Rectangle buttonRect = rControlRegion; RECT rc; rc.left = buttonRect.Left(); rc.right = buttonRect.Right()+1; @@ -1080,7 +1189,7 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, */ BOOL WinSalGraphics::drawNativeControlText( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -1104,12 +1213,12 @@ BOOL WinSalGraphics::drawNativeControlText( ControlType, */ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& rControlValue, const OUString&, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion ) { BOOL bRet = FALSE; @@ -1146,7 +1255,7 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, if( hTheme ) { Rectangle aRect( ImplGetThemeRect( hTheme, hDC, TP_SPLITBUTTONDROPDOWN, - TS_HOT, rControlRegion.GetBoundRect() ) ); + TS_HOT, rControlRegion ) ); rNativeContentRegion = aRect; rNativeBoundingRegion = rNativeContentRegion; if( !rNativeContentRegion.IsEmpty() ) @@ -1160,7 +1269,7 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, if( hTheme ) { Rectangle aRect( ImplGetThemeRect( hTheme, hDC, PP_BAR, - 0, rControlRegion.GetBoundRect() ) ); + 0, rControlRegion ) ); rNativeContentRegion = aRect; rNativeBoundingRegion = rNativeContentRegion; if( !rNativeContentRegion.IsEmpty() ) @@ -1172,12 +1281,9 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, HTHEME hTheme = getThemeHandle( mhWnd, L"Combobox"); if( hTheme ) { - Rectangle aBoxRect( rControlRegion.GetBoundRect() ); + Rectangle aBoxRect( rControlRegion ); Rectangle aRect( ImplGetThemeRect( hTheme, hDC, CP_DROPDOWNBUTTON, CBXS_NORMAL, aBoxRect ) ); - Rectangle aBrdRect( ImplGetThemeRect( hTheme, hDC, CP_BORDER, - CBB_HOT, aBoxRect ) ); - aRect.Top() -= aBrdRect.GetHeight(); if( aRect.GetHeight() > aBoxRect.GetHeight() ) aBoxRect.Bottom() = aBoxRect.Top() + aRect.GetHeight(); if( aRect.GetWidth() > aBoxRect.GetWidth() ) @@ -1194,8 +1300,8 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, HTHEME hTheme = getThemeHandle( mhWnd, L"Edit"); if( hTheme ) { - // get borderr size - Rectangle aBoxRect( rControlRegion.GetBoundRect() ); + // get border size + Rectangle aBoxRect( rControlRegion ); Rectangle aRect( ImplGetThemeRect( hTheme, hDC, EP_BACKGROUNDWITHBORDER, EBWBS_HOT, aBoxRect ) ); // ad app font height @@ -1223,6 +1329,29 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, } } + if( GetSalData()->mbThemeMenuSupport ) + { + if( nType == CTRL_MENU_POPUP ) + { + if( nPart == PART_MENU_ITEM_CHECK_MARK || + nPart == PART_MENU_ITEM_RADIO_MARK ) + { + HTHEME hTheme = getThemeHandle( mhWnd, L"Menu"); + Rectangle aBoxRect( rControlRegion ); + Rectangle aRect( ImplGetThemeRect( hTheme, hDC, + MENU_POPUPCHECK, + MC_CHECKMARKNORMAL, + aBoxRect ) ); + if( aBoxRect.GetWidth() && aBoxRect.GetHeight() ) + { + rNativeContentRegion = aRect; + rNativeBoundingRegion = rNativeContentRegion; + bRet = TRUE; + } + } + } + } + if( nType == CTRL_SLIDER && ( (nPart == PART_THUMB_HORZ) || (nPart == PART_THUMB_VERT) ) ) { HTHEME hTheme = getThemeHandle( mhWnd, L"Trackbar"); @@ -1234,7 +1363,7 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, if( nPart == PART_THUMB_HORZ ) { long nW = aThumbRect.GetWidth(); - Rectangle aRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( rControlRegion ); aRect.Right() = aRect.Left() + nW - 1; rNativeContentRegion = aRect; rNativeBoundingRegion = rNativeContentRegion; @@ -1242,7 +1371,7 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, else { long nH = aThumbRect.GetHeight(); - Rectangle aRect( rControlRegion.GetBoundRect() ); + Rectangle aRect( rControlRegion ); aRect.Bottom() = aRect.Top() + nH - 1; rNativeContentRegion = aRect; rNativeBoundingRegion = rNativeContentRegion; @@ -1253,30 +1382,30 @@ BOOL WinSalGraphics::getNativeControlRegion( ControlType nType, if ( ( nType == CTRL_TAB_ITEM ) && ( nPart == PART_ENTIRE_CONTROL ) ) { - Rectangle aControlRect( rControlRegion.GetBoundRect() ); + Rectangle aControlRect( rControlRegion ); rNativeContentRegion = aControlRect; --aControlRect.Bottom(); - TabitemValue *pValue = static_cast< TabitemValue* >( rControlValue.getOptionalVal() ); - if ( pValue ) + if( rControlValue.getType() == CTRL_TAB_ITEM ) { + const TabitemValue *pValue = static_cast<const TabitemValue*>(&rControlValue); if ( pValue->isBothAligned() ) --aControlRect.Right(); - } - if ( nState & CTRL_STATE_SELECTED ) - { - aControlRect.Left() -= 2; - if ( pValue && !pValue->isBothAligned() ) + if ( nState & CTRL_STATE_SELECTED ) { - if ( pValue->isLeftAligned() || pValue->isNotAligned() ) - aControlRect.Right() += 2; - if ( pValue->isRightAligned() ) - aControlRect.Right() += 1; + aControlRect.Left() -= 2; + if ( pValue && !pValue->isBothAligned() ) + { + if ( pValue->isLeftAligned() || pValue->isNotAligned() ) + aControlRect.Right() += 2; + if ( pValue->isRightAligned() ) + aControlRect.Right() += 1; + } + aControlRect.Top() -= 2; + aControlRect.Bottom() += 2; } - aControlRect.Top() -= 2; - aControlRect.Bottom() += 2; } rNativeBoundingRegion = aControlRect; bRet = TRUE; diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index 9d8d41723f64..702ff639ed84 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -1798,8 +1798,11 @@ WIN_BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ ) MSG aMsg; if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + } i++; if ( i > 15 ) bWhile = FALSE; @@ -2060,8 +2063,12 @@ BOOL WinSalPrinter::StartJob( const XubString* pFileName, MSG aMsg; if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) { - TranslateMessage( &aMsg ); - ImplDispatchMessage( &aMsg ); + if ( !ImplInterceptChildWindowKeyDown( aMsg ) ) + { + TranslateMessage( &aMsg ); + ImplDispatchMessage( &aMsg ); + } + i++; if ( i > 15 ) bWhile = FALSE; diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index ba19f2255646..a4c588f059d4 100644..100755 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -244,24 +244,11 @@ HFONT WinLayout::DisableFontScaling() const if( mfFontScale == 1.0 ) return 0; - HFONT hHugeFont = 0; - if( aSalShlData.mbWNT ) - { - LOGFONTW aLogFont; - ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); - aLogFont.lfHeight = (LONG)(mfFontScale * aLogFont.lfHeight); - aLogFont.lfWidth = (LONG)(mfFontScale * aLogFont.lfWidth); - hHugeFont = ::CreateFontIndirectW( &aLogFont); - } - else - { - LOGFONTA aLogFont; - ::GetObjectA( mhFont, sizeof(LOGFONTA), &aLogFont); - aLogFont.lfHeight = (LONG)(mfFontScale * aLogFont.lfHeight); - aLogFont.lfWidth = (LONG)(mfFontScale * aLogFont.lfWidth); - hHugeFont = ::CreateFontIndirectA( &aLogFont); - } - + LOGFONTW aLogFont; + ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); + aLogFont.lfHeight = (LONG)(mfFontScale * aLogFont.lfHeight); + aLogFont.lfWidth = (LONG)(mfFontScale * aLogFont.lfWidth); + HFONT hHugeFont = ::CreateFontIndirectW( &aLogFont); if( !hHugeFont ) return 0; @@ -671,57 +658,31 @@ void SimpleWinLayout::DrawText( SalGraphics& rGraphics ) const Point aPos = GetDrawPosition( Point( mnBaseAdv, 0 ) ); - // #108267#, limit the number of glyphs to avoid paint errors - UINT limitedGlyphCount = Min( 8192, mnGlyphCount ); - if( mnDrawOptions || aSalShlData.mbWNT ) - { - // #108267#, break up into glyph portions of a limited size required by Win32 API - const unsigned int maxGlyphCount = 8192; - UINT numGlyphPortions = mnGlyphCount / maxGlyphCount; - UINT remainingGlyphs = mnGlyphCount % maxGlyphCount; - - if( numGlyphPortions ) - { - // #108267#,#109387# break up string into smaller chunks - // the output positions will be updated by windows (SetTextAlign) - unsigned int i,n; - POINT oldPos; - UINT oldTa = ::GetTextAlign( aHDC ); - ::SetTextAlign( aHDC, (oldTa & ~TA_NOUPDATECP) | TA_UPDATECP ); - ::MoveToEx( aHDC, aPos.X(), aPos.Y(), &oldPos ); - for( i=n=0; n<numGlyphPortions; n++, i+=maxGlyphCount ) - ::ExtTextOutW( aHDC, 0, 0, mnDrawOptions, NULL, - mpOutGlyphs+i, maxGlyphCount, mpGlyphAdvances+i ); + // #108267#, break up into glyph portions of a limited size required by Win32 API + const unsigned int maxGlyphCount = 8192; + UINT numGlyphPortions = mnGlyphCount / maxGlyphCount; + UINT remainingGlyphs = mnGlyphCount % maxGlyphCount; + + if( numGlyphPortions ) + { + // #108267#,#109387# break up string into smaller chunks + // the output positions will be updated by windows (SetTextAlign) + POINT oldPos; + UINT oldTa = ::GetTextAlign( aHDC ); + ::SetTextAlign( aHDC, (oldTa & ~TA_NOUPDATECP) | TA_UPDATECP ); + ::MoveToEx( aHDC, aPos.X(), aPos.Y(), &oldPos ); + unsigned int i = 0; + for( unsigned int n = 0; n < numGlyphPortions; ++n, i+=maxGlyphCount ) ::ExtTextOutW( aHDC, 0, 0, mnDrawOptions, NULL, - mpOutGlyphs+i, remainingGlyphs, mpGlyphAdvances+i ); - ::MoveToEx( aHDC, oldPos.x, oldPos.y, (LPPOINT) NULL); - ::SetTextAlign( aHDC, oldTa ); - } - else - ::ExtTextOutW( aHDC, aPos.X(), aPos.Y(), mnDrawOptions, NULL, - mpOutGlyphs, mnGlyphCount, mpGlyphAdvances ); + mpOutGlyphs+i, maxGlyphCount, mpGlyphAdvances+i ); + ::ExtTextOutW( aHDC, 0, 0, mnDrawOptions, NULL, + mpOutGlyphs+i, remainingGlyphs, mpGlyphAdvances+i ); + ::MoveToEx( aHDC, oldPos.x, oldPos.y, (LPPOINT) NULL); + ::SetTextAlign( aHDC, oldTa ); } else - { - // #108267#, On Win9x, we get paint errors when drawing huge strings, even when - // split into pieces (see above), seems to be a problem in the internal text clipping - // so we just cut off the string - if( !mpGlyphOrigAdvs ) - ::ExtTextOutW( aHDC, aPos.X(), aPos.Y(), 0, NULL, - mpOutGlyphs, limitedGlyphCount, NULL ); - else - { - // workaround for problem in #106259# - long nXPos = mnBaseAdv; - for( unsigned int i = 0; i < limitedGlyphCount; ++i ) - { - ::ExtTextOutW( aHDC, aPos.X(), aPos.Y(), 0, NULL, - mpOutGlyphs+i, 1, NULL ); - nXPos += mpGlyphAdvances[ i ]; - aPos = GetDrawPosition( Point( nXPos, 0 ) ); - } - } - } + ::ExtTextOutW( aHDC, aPos.X(), aPos.Y(), mnDrawOptions, NULL, + mpOutGlyphs, mnGlyphCount, mpGlyphAdvances ); if( hOrigFont ) DeleteFont( SelectFont( aHDC, hOrigFont ) ); @@ -2076,6 +2037,13 @@ void UniscribeLayout::MoveGlyph( int nStartx8, long nNewXPos ) // move the visual item by having an offset pVI->mnXOffset += nDelta; } + // move subsequent items - this often isn't necessary because subsequent + // moves will correct subsequent items. However, if there is a contiguous + // range not involving fallback which spans items, this will be needed + while (++pVI - mpVisualItems < mnItemCount) + { + pVI->mnXOffset += nDelta; + } } // ----------------------------------------------------------------------- @@ -2203,7 +2171,9 @@ void UniscribeLayout::Simplify( bool /*bIsBase*/ ) const int k = mpGlyphs2Chars[ i ]; mpGlyphs2Chars[ j ] = k; const int nRelGlyphPos = (j++) - rVI.mnMinGlyphPos; - mpLogClusters[ k ] = static_cast<WORD>(nRelGlyphPos); + if( k < 0) // extra glyphs are already mapped + continue; + mpLogClusters[ k ] = static_cast<WORD>(nRelGlyphPos); } rVI.mnEndGlyphPos = j; @@ -2362,6 +2332,10 @@ void UniscribeLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const if( rVisualItem.IsEmpty() ) continue; + if (mnLayoutFlags & SAL_LAYOUT_FOR_FALLBACK) + { + nXPos = rVisualItem.mnXOffset; + } // get glyph positions // TODO: handle when rVisualItem's glyph range is only partially used for( i = rVisualItem.mnMinGlyphPos; i < rVisualItem.mnEndGlyphPos; ++i ) @@ -2395,13 +2369,17 @@ void UniscribeLayout::GetCaretPositions( int nMaxIdx, long* pCaretXArray ) const } } - // fixup unknown character positions to neighbor - for( i = 0; i < nMaxIdx; ++i ) + if (!(mnLayoutFlags & SAL_LAYOUT_FOR_FALLBACK)) { - if( pCaretXArray[ i ] >= 0 ) - nXPos = pCaretXArray[ i ]; - else - pCaretXArray[ i ] = nXPos; + nXPos = 0; + // fixup unknown character positions to neighbor + for( i = 0; i < nMaxIdx; ++i ) + { + if( pCaretXArray[ i ] >= 0 ) + nXPos = pCaretXArray[ i ]; + else + pCaretXArray[ i ] = nXPos; + } } } @@ -2821,7 +2799,7 @@ sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth) class GraphiteWinLayout : public WinLayout { private: - mutable gr::WinFont mpFont; + mutable GraphiteWinFont mpFont; grutils::GrFeatureParser * mpFeatures; mutable GraphiteLayoutWinImpl maImpl; public: @@ -2894,6 +2872,11 @@ void GraphiteWinLayout::RestoreDC(gr::Segment & segment) const bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args) { + if (args.mnMinCharPos >= args.mnEndCharPos) + { + maImpl.clear(); + return true; + } HFONT hUnRotatedFont; if (args.mnOrientation) { diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index 7314fd2b6164..89a191c99ef6 100644..100755 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -161,7 +161,7 @@ BOOL WinSalFrame::mbInReparent = FALSE; // ======================================================================= static void UpdateFrameGeometry( HWND hWnd, WinSalFrame* pFrame ); -static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame ); +static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect = NULL ); static void ImplSaveFrameState( WinSalFrame* pFrame ) { @@ -182,6 +182,25 @@ static void ImplSaveFrameState( WinSalFrame* pFrame ) if ( bVisible ) pFrame->mnShowState = SW_SHOWMAXIMIZED; pFrame->mbRestoreMaximize = TRUE; + + WINDOWPLACEMENT aPlacement; + aPlacement.length = sizeof(aPlacement); + if( GetWindowPlacement( pFrame->mhWnd, &aPlacement ) ) + { + RECT aRect = aPlacement.rcNormalPosition; + RECT aRect2 = aRect; + AdjustWindowRectEx( &aRect2, GetWindowStyle( pFrame->mhWnd ), + FALSE, GetWindowExStyle( pFrame->mhWnd ) ); + long nTopDeco = abs( aRect.top - aRect2.top ); + long nLeftDeco = abs( aRect.left - aRect2.left ); + long nBottomDeco = abs( aRect.bottom - aRect2.bottom ); + long nRightDeco = abs( aRect.right - aRect2.right ); + + pFrame->maState.mnX = aRect.left + nLeftDeco; + pFrame->maState.mnY = aRect.top + nTopDeco; + pFrame->maState.mnWidth = aRect.right - aRect.left - nLeftDeco - nRightDeco; + pFrame->maState.mnHeight = aRect.bottom - aRect.top - nTopDeco - nBottomDeco; + } } else { @@ -489,7 +508,7 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, } // create frame - if ( aSalShlData.mbWNT ) + if( true/*aSalShlData.mbWNT*/ ) { LPCWSTR pClassName; if ( bSubFrame ) @@ -517,17 +536,6 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, lpfnSetLayeredWindowAttributes( hWnd, 0, 230, 0x00000002 /*LWA_ALPHA*/ ); #endif } - else - { - LPCSTR pClassName; - if ( bSubFrame ) - pClassName = SAL_SUBFRAME_CLASSNAMEA; - else - pClassName = SAL_FRAME_CLASSNAMEA; - hWnd = CreateWindowExA( nExSysStyle, pClassName, "", nSysStyle, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, - hWndParent, 0, pInst->mhInst, (void*)pFrame ); - } if ( !hWnd ) { delete pFrame; @@ -598,21 +606,10 @@ HWND ImplSalReCreateHWND( HWND hWndParent, HWND oldhWnd, BOOL bAsChild ) nExSysStyle = 0; } - HWND hWnd = NULL; - if ( aSalShlData.mbWNT ) - { - LPCWSTR pClassName = SAL_SUBFRAME_CLASSNAMEW; - hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, - hWndParent, 0, hInstance, (void*)GetWindowPtr( oldhWnd ) ); - } - else - { - LPCSTR pClassName = SAL_SUBFRAME_CLASSNAMEA; - hWnd = CreateWindowExA( nExSysStyle, pClassName, "", nSysStyle, + LPCWSTR pClassName = SAL_SUBFRAME_CLASSNAMEW; + HWND hWnd = CreateWindowExW( nExSysStyle, pClassName, L"", nSysStyle, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, hInstance, (void*)GetWindowPtr( oldhWnd ) ); - } return hWnd; } @@ -1934,17 +1931,25 @@ void WinSalFrame::SetWindowState( const SalFrameState* pState ) } } - // Wenn Fenster nicht minimiert/maximiert ist oder nicht optisch - // umgesetzt werden muss, dann SetWindowPos() benutzen, da - // SetWindowPlacement() die TaskBar mit einrechnet + // if a window is neither minimized nor maximized or need not be + // positioned visibly (that is in visible state), do not use + // SetWindowPlacement since it calculates including the TaskBar if ( !IsIconic( mhWnd ) && !IsZoomed( mhWnd ) && (!bVisible || (aPlacement.showCmd == SW_RESTORE)) ) { if( bUpdateHiddenFramePos ) { + RECT aStateRect; + aStateRect.left = nX; + aStateRect.top = nY; + aStateRect.right = nX+nWidth; + aStateRect.bottom = nY+nHeight; // #96084 set a useful internal window size because // the window will not be maximized (and the size updated) before show() - SetMaximizedFrameGeometry( mhWnd, this ); + SetMaximizedFrameGeometry( mhWnd, this, &aStateRect ); + SetWindowPos( mhWnd, 0, + maGeometry.nX, maGeometry.nY, maGeometry.nWidth, maGeometry.nHeight, + SWP_NOZORDER | SWP_NOACTIVATE | nPosSize ); } else SetWindowPos( mhWnd, 0, @@ -2504,7 +2509,7 @@ static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf, int nKeyLen = 0; if ( lParam ) { - if ( aSalShlData.mbWNT ) + if ( true/*aSalShlData.mbWNT*/ ) { nKeyLen = GetKeyNameTextW( lParam, aKeyBuf, nMaxKeyLen ); // #i12401# the current unicows.dll has a bug in CharUpperBuffW, which corrupts the stack @@ -2526,32 +2531,6 @@ static void ImplGetKeyNameText( LONG lParam, sal_Unicode* pBuf, } } } - else // !mbWnt - { - sal_Char aAnsiKeyBuf[ nMaxKeyLen ]; - int nAnsiKeyLen = GetKeyNameTextA( lParam, aAnsiKeyBuf, nMaxKeyLen ); - DBG_ASSERT( nAnsiKeyLen <= nMaxKeyLen, "Invalid key name length!" ); - if( nAnsiKeyLen > nMaxKeyLen ) - nAnsiKeyLen = 0; - else if( nAnsiKeyLen > 0 ) - { - // Capitalize just the first letter of key names - // TODO: check MCBS key names - CharLowerBuffA( aAnsiKeyBuf, nAnsiKeyLen ); - - bool bUpper = true; - for( sal_Char *pA=aAnsiKeyBuf, *pE=pA+nAnsiKeyLen; pA < pE; ++pA ) - { - if( bUpper ) - CharUpperBuffA( pA, 1 ); - bUpper = (*pA=='+') || (*pA=='-') || (*pA==' ') || (*pA=='.'); - } - - // Convert to Unicode and copy the data in the Unicode Buffer - nKeyLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, - aAnsiKeyBuf, nAnsiKeyLen, aKeyBuf, nMaxKeyLen ); - } - } } if ( (nKeyLen > 0) || pReplace ) @@ -2856,6 +2835,29 @@ static long ImplA2I( const BYTE* pStr ) } // ----------------------------------------------------------------------- +static HRESULT WINAPI backwardCompatibleDwmIsCompositionEnabled( WIN_BOOL* pOut ) +{ + *pOut = FALSE; + return S_OK; +} + +static WIN_BOOL ImplDwmIsCompositionEnabled() +{ + SalData* pSalData = GetSalData(); + if( ! pSalData->mpDwmIsCompositionEnabled ) + { + rtl::OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "Dwmapi.dll" ) ); + pSalData->maDwmLib = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT ); + if( pSalData->maDwmLib ) + pSalData->mpDwmIsCompositionEnabled = (DwmIsCompositionEnabled_ptr)osl_getAsciiFunctionSymbol( pSalData->maDwmLib, "DwmIsCompositionEnabled" ); + if( ! pSalData->mpDwmIsCompositionEnabled ) // something failed + pSalData->mpDwmIsCompositionEnabled = backwardCompatibleDwmIsCompositionEnabled; + } + WIN_BOOL aResult = FALSE; + HRESULT nError = pSalData->mpDwmIsCompositionEnabled( &aResult ); + return nError == S_OK && aResult; +} + void WinSalFrame::UpdateSettings( AllSettings& rSettings ) { @@ -2888,30 +2890,26 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings ) } StyleSettings aStyleSettings = rSettings.GetStyleSettings(); - BOOL bCompBorder = (aStyleSettings.GetOptions() & (STYLE_OPTION_MACSTYLE | STYLE_OPTION_UNIXSTYLE)) == 0; // TODO: once those options vanish: just set bCompBorder to TRUE // to have the system colors read aStyleSettings.SetScrollBarSize( GetSystemMetrics( SM_CXVSCROLL ) ); aStyleSettings.SetSpinSize( GetSystemMetrics( SM_CXVSCROLL ) ); aStyleSettings.SetCursorBlinkTime( GetCaretBlinkTime() ); - if ( bCompBorder ) - { - aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) ); - aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) ); - aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) ); - aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) ); - if ( aSalShlData.mnVersion >= 410 ) - { - aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) ); - aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) ); - } - aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) ); - aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); - aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) ); - aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) ); - aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); - aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) ); - } + aStyleSettings.SetFloatTitleHeight( GetSystemMetrics( SM_CYSMCAPTION ) ); + aStyleSettings.SetTitleHeight( GetSystemMetrics( SM_CYCAPTION ) ); + aStyleSettings.SetActiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVEBORDER ) ) ); + aStyleSettings.SetDeactiveBorderColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVEBORDER ) ) ); + if ( aSalShlData.mnVersion >= 410 ) + { + aStyleSettings.SetActiveColor2( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTACTIVECAPTION ) ) ); + aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_GRADIENTINACTIVECAPTION ) ) ); + } + aStyleSettings.SetFaceColor( ImplWinColorToSal( GetSysColor( COLOR_3DFACE ) ) ); + aStyleSettings.SetInactiveTabColor( aStyleSettings.GetFaceColor() ); + aStyleSettings.SetLightColor( ImplWinColorToSal( GetSysColor( COLOR_3DHILIGHT ) ) ); + aStyleSettings.SetLightBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DLIGHT ) ) ); + aStyleSettings.SetShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); + aStyleSettings.SetDarkShadowColor( ImplWinColorToSal( GetSysColor( COLOR_3DDKSHADOW ) ) ); aStyleSettings.SetWorkspaceColor( ImplWinColorToSal( GetSysColor( COLOR_APPWORKSPACE ) ) ); aStyleSettings.SetHelpColor( ImplWinColorToSal( GetSysColor( COLOR_INFOBK ) ) ); aStyleSettings.SetHelpTextColor( ImplWinColorToSal( GetSysColor( COLOR_INFOTEXT ) ) ); @@ -2933,37 +2931,52 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings ) aStyleSettings.SetHighlightTextColor( ImplWinColorToSal( GetSysColor( COLOR_HIGHLIGHTTEXT ) ) ); aStyleSettings.SetMenuHighlightColor( aStyleSettings.GetHighlightColor() ); aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetHighlightTextColor() ); - if ( bCompBorder ) - { - aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) ); - aStyleSettings.SetMenuBarColor( aStyleSettings.GetMenuColor() ); - aStyleSettings.SetMenuBorderColor( aStyleSettings.GetLightBorderColor() ); // overriden below for flat menus - aStyleSettings.SetUseFlatBorders( FALSE ); - aStyleSettings.SetUseFlatMenues( FALSE ); - aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); - aStyleSettings.SetMenuBarTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); - aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) ); - aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) ); - aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) ); - aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) ); - if ( aSalShlData.mbWXP ) + + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maNWFData.mnMenuFormatExtraBorder = 0; + pSVData->maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT ); + GetSalData()->mbThemeMenuSupport = FALSE; + aStyleSettings.SetMenuColor( ImplWinColorToSal( GetSysColor( COLOR_MENU ) ) ); + aStyleSettings.SetMenuBarColor( aStyleSettings.GetMenuColor() ); + aStyleSettings.SetMenuBorderColor( aStyleSettings.GetLightBorderColor() ); // overriden below for flat menus + aStyleSettings.SetUseFlatBorders( FALSE ); + aStyleSettings.SetUseFlatMenues( FALSE ); + aStyleSettings.SetMenuTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); + aStyleSettings.SetMenuBarTextColor( ImplWinColorToSal( GetSysColor( COLOR_MENUTEXT ) ) ); + aStyleSettings.SetActiveColor( ImplWinColorToSal( GetSysColor( COLOR_ACTIVECAPTION ) ) ); + aStyleSettings.SetActiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_CAPTIONTEXT ) ) ); + aStyleSettings.SetDeactiveColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTION ) ) ); + aStyleSettings.SetDeactiveTextColor( ImplWinColorToSal( GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ) ); + if ( aSalShlData.mbWXP ) + { + // only xp supports a different menu bar color + long bFlatMenues = 0; + SystemParametersInfo( SPI_GETFLATMENU, 0, &bFlatMenues, 0); + if( bFlatMenues ) { - // only xp supports a different menu bar color - long bFlatMenues = 0; - SystemParametersInfo( SPI_GETFLATMENU, 0, &bFlatMenues, 0); - if( bFlatMenues ) - { - aStyleSettings.SetUseFlatMenues( TRUE ); - aStyleSettings.SetMenuBarColor( ImplWinColorToSal( GetSysColor( COLOR_MENUBAR ) ) ); - aStyleSettings.SetMenuHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_MENUHILIGHT ) ) ); - aStyleSettings.SetMenuBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); - - // flat borders for our controls etc. as well in this mode (ie, no 3d borders) - // this is not active in the classic style appearance - aStyleSettings.SetUseFlatBorders( TRUE ); - } + aStyleSettings.SetUseFlatMenues( TRUE ); + aStyleSettings.SetMenuBarColor( ImplWinColorToSal( GetSysColor( COLOR_MENUBAR ) ) ); + aStyleSettings.SetMenuHighlightColor( ImplWinColorToSal( GetSysColor( COLOR_MENUHILIGHT ) ) ); + aStyleSettings.SetMenuBorderColor( ImplWinColorToSal( GetSysColor( COLOR_3DSHADOW ) ) ); + + // flat borders for our controls etc. as well in this mode (ie, no 3d borders) + // this is not active in the classic style appearance + aStyleSettings.SetUseFlatBorders( TRUE ); } } + // check if vista or newer runs + // in Aero theme (and similar ?) the menu text color does not change + // for selected items; also on WinXP and earlier menus are not themed + if( aSalShlData.maVersionInfo.dwMajorVersion >= 6 && + ImplDwmIsCompositionEnabled() + ) + { + // in aero menuitem highlight text is drawn in the same color as normal + aStyleSettings.SetMenuHighlightTextColor( aStyleSettings.GetMenuTextColor() ); + pSVData->maNWFData.mnMenuFormatExtraBorder = 2; + pSVData->maNWFData.maMenuBarHighlightTextColor = aStyleSettings.GetMenuTextColor(); + GetSalData()->mbThemeMenuSupport = TRUE; + } // Bei hellgrau geben wir die Farbe vor, damit es besser aussieht if ( aStyleSettings.GetFaceColor() == COL_LIGHTGRAY ) aStyleSettings.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) ); @@ -3000,7 +3013,7 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings ) Font aAppFont = aStyleSettings.GetAppFont(); Font aIconFont = aStyleSettings.GetIconFont(); HDC hDC = GetDC( 0 ); - if ( aSalShlData.mbWNT ) + if( true/*aSalShlData.mbWNT*/ ) { NONCLIENTMETRICSW aNonClientMetrics; aNonClientMetrics.cbSize = sizeof( aNonClientMetrics ); @@ -3017,23 +3030,6 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings ) ImplSalUpdateStyleFontW( hDC, aLogFont, aIconFont ); } } - else - { - NONCLIENTMETRICSA aNonClientMetrics; - aNonClientMetrics.cbSize = sizeof( aNonClientMetrics ); - if ( SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof( aNonClientMetrics ), &aNonClientMetrics, 0 ) ) - { - ImplSalUpdateStyleFontA( hDC, aNonClientMetrics.lfMenuFont, aMenuFont ); - ImplSalUpdateStyleFontA( hDC, aNonClientMetrics.lfCaptionFont, aTitleFont ); - ImplSalUpdateStyleFontA( hDC, aNonClientMetrics.lfSmCaptionFont, aFloatTitleFont ); - ImplSalUpdateStyleFontA( hDC, aNonClientMetrics.lfStatusFont, aHelpFont ); - ImplSalUpdateStyleFontA( hDC, aNonClientMetrics.lfMessageFont, aAppFont ); - - LOGFONTA aLogFont; - if ( SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, &aLogFont, 0 ) ) - ImplSalUpdateStyleFontA( hDC, aLogFont, aIconFont ); - } - } // get screen font resolution to calculate toolbox item size long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY ); @@ -3622,27 +3618,7 @@ static void ImplUpdateInputLang( WinSalFrame* pFrame ) // If we are on Windows NT we use Unicode FrameProcs and so we // get Unicode charcodes directly from Windows // no need to set up a code page - if ( aSalShlData.mbWNT ) - return; - - if ( !nLang ) - { - pFrame->mnInputLang = 0; - pFrame->mnInputCodePage = GetACP(); - } - else if ( bLanguageChange ) - { - sal_Char aBuf[10]; - if ( GetLocaleInfoA( MAKELCID( nLang, SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE, - aBuf, sizeof(aBuf) ) > 0 ) - { - pFrame->mnInputCodePage = ImplStrToNum( aBuf ); - if ( !pFrame->mnInputCodePage ) - pFrame->mnInputCodePage = GetACP(); - } - else - pFrame->mnInputCodePage = GetACP(); - } + return; } @@ -3652,29 +3628,7 @@ static sal_Unicode ImplGetCharCode( WinSalFrame* pFrame, WPARAM nCharCode ) // If we are on Windows NT we use Unicode FrameProcs and so we // get Unicode charcodes directly from Windows - if ( aSalShlData.mbWNT ) - return (sal_Unicode)nCharCode; - - sal_Char aCharBuf[2]; - int nCharLen; - WCHAR c; - if ( nCharCode > 0xFF ) - { - aCharBuf[0] = (sal_Char)(nCharCode>>8); - aCharBuf[1] = (sal_Char)nCharCode; - nCharLen = 2; - } - else - { - aCharBuf[0] = (sal_Char)nCharCode; - nCharLen = 1; - } - if ( ::MultiByteToWideChar( pFrame->mnInputCodePage, - MB_PRECOMPOSED, - aCharBuf, nCharLen, &c, 1 ) ) - return (sal_Unicode)c; - else - return (sal_Unicode)nCharCode; + return (sal_Unicode)nCharCode; } // ----------------------------------------------------------------------- @@ -4197,23 +4151,27 @@ static void ImplHandlePaintMsg2( HWND hWnd, RECT* pRect ) // ----------------------------------------------------------------------- -static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame ) +static void SetMaximizedFrameGeometry( HWND hWnd, WinSalFrame* pFrame, RECT* pParentRect ) { // calculate and set frame geometry of a maximized window - useful if the window is still hidden // dualmonitor support: // Get screensize of the monitor whith the mouse pointer - POINT pt; - GetCursorPos( &pt ); RECT aRectMouse; - aRectMouse.left = pt.x; - aRectMouse.top = pt.y; - aRectMouse.right = pt.x+2; - aRectMouse.bottom = pt.y+2; + if( ! pParentRect ) + { + POINT pt; + GetCursorPos( &pt ); + aRectMouse.left = pt.x; + aRectMouse.top = pt.y; + aRectMouse.right = pt.x+2; + aRectMouse.bottom = pt.y+2; + pParentRect = &aRectMouse; + } RECT aRect; - ImplSalGetWorkArea( hWnd, &aRect, &aRectMouse ); + ImplSalGetWorkArea( hWnd, &aRect, pParentRect ); // a maximized window has no other borders than the caption pFrame->maGeometry.nLeftDecoration = pFrame->maGeometry.nRightDecoration = pFrame->maGeometry.nBottomDecoration = 0; @@ -4476,16 +4434,8 @@ static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg, { if ( lParam ) { - if ( aSalShlData.mbWNT ) - { if ( ImplSalWICompareAscii( (const wchar_t*)lParam, "devices" ) == 0 ) nSalEvent = SALEVENT_PRINTERCHANGED; - } - else - { - if ( stricmp( (const char*)lParam, "devices" ) == 0 ) - nSalEvent = SALEVENT_PRINTERCHANGED; - } } } diff --git a/vcl/win/source/window/salmenu.cxx b/vcl/win/source/window/salmenu.cxx index 1eb75969ea38..47da911b012e 100644 --- a/vcl/win/source/window/salmenu.cxx +++ b/vcl/win/source/window/salmenu.cxx @@ -59,7 +59,7 @@ BOOL SalData::IsKnownMenuHandle( HMENU hMenu ) // WinSalInst factory methods -SalMenu* WinSalInstance::CreateMenu( BOOL bMenuBar ) +SalMenu* WinSalInstance::CreateMenu( BOOL bMenuBar, Menu* ) { WinSalMenu *pSalMenu = new WinSalMenu(); diff --git a/vcl/win/source/window/salobj.cxx b/vcl/win/source/window/salobj.cxx index 2f657968284f..bf0f29bb72d3 100644 --- a/vcl/win/source/window/salobj.cxx +++ b/vcl/win/source/window/salobj.cxx @@ -39,6 +39,7 @@ #include <salframe.h> #include <salobj.h> #include <tools/debug.hxx> +#include <vcl/svapp.hxx> // ======================================================================= @@ -103,6 +104,46 @@ WinSalFrame* ImplFindSalObjectFrame( HWND hWnd ) // ----------------------------------------------------------------------- +sal_Bool ImplInterceptChildWindowKeyDown( MSG& rMsg ) +{ + sal_Bool bResult = sal_False; + if ( rMsg.message == WM_KEYDOWN ) + { + wchar_t pClassName[10]; + sal_Int32 nLen = GetClassNameW( rMsg.hwnd, pClassName, 10 ); + if ( !( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) ) + { + // look for the first SalObject in the parent hierarchy + HWND hWin = rMsg.hwnd; + HWND hLastOLEWindow = hWin; + WinSalObject* pSalObj = NULL; + do + { + hLastOLEWindow = hWin; + hWin = ::GetParent( hWin ); + if ( hWin ) + { + nLen = GetClassNameW( hWin, pClassName, 10 ); + if ( nLen == 9 && wcsncmp( pClassName, SAL_OBJECT_CLASSNAMEW, nLen ) == 0 ) + pSalObj = GetSalObjWindowPtr( hWin ); + } + } while( hWin && !pSalObj ); + + if ( pSalObj && pSalObj->mbInterceptChildWindowKeyDown && pSalObj->maSysData.hWnd ) + { + bResult = ( 1 == ImplSendMessage( pSalObj->maSysData.hWnd, rMsg.message, rMsg.wParam, rMsg.lParam ) ); + } + } + } + + return bResult; +} + +// ----------------------------------------------------------------------- + + +// ----------------------------------------------------------------------- + LRESULT CALLBACK SalSysMsgProc( int nCode, WPARAM wParam, LPARAM lParam ) { // Used for Unicode and none Unicode @@ -493,20 +534,10 @@ SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent ) // Hook installieren, wenn es das erste SalObject ist if ( !pSalData->mpFirstObject ) { - if ( aSalShlData.mbWNT ) - { - pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC, - SalSysMsgProc, - pSalData->mhInst, - pSalData->mnAppThreadId ); - } - else - { - pSalData->mhSalObjMsgHook = SetWindowsHookExA( WH_CALLWNDPROC, + pSalData->mhSalObjMsgHook = SetWindowsHookExW( WH_CALLWNDPROC, SalSysMsgProc, pSalData->mhInst, pSalData->mnAppThreadId ); - } } if ( !pSalData->mbObjClassInit ) @@ -623,6 +654,7 @@ WinSalObject::WinSalObject() mhLastFocusWnd = 0; maSysData.nSize = sizeof( SystemEnvData ); mpStdClipRgnData = NULL; + mbInterceptChildWindowKeyDown = sal_False; // Insert object in objectlist mpNextObject = pSalData->mpFirstObject; @@ -836,3 +868,11 @@ const SystemEnvData* WinSalObject::GetSystemData() const { return &maSysData; } + +// ----------------------------------------------------------------------- + +void WinSalObject::InterceptChildWindowKeyDown( sal_Bool bIntercept ) +{ + mbInterceptChildWindowKeyDown = bIntercept; +} + diff --git a/vcl/workben/makefile.mk b/vcl/workben/makefile.mk index 67c0289cc24f..abd0c23a3607 100644 --- a/vcl/workben/makefile.mk +++ b/vcl/workben/makefile.mk @@ -34,6 +34,8 @@ TARGETTYPE=GUI ENABLE_EXCEPTIONS=TRUE +my_components = i18npool i18nsearch + # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk @@ -136,16 +138,18 @@ APP5STDLIBS+=-lsocket .ENDIF .INCLUDE : target.mk -.IF "$(L10N_framework)"=="" -ALLTAR : $(BIN)$/applicat.rdb +ALLTAR : $(BIN)/applicat.rdb $(BIN)/types.rdb +$(BIN)/applicat.rdb .ERRREMOVE : $(SOLARENV)/bin/packcomponents.xslt \ + $(MISC)/applicat.input $(my_components:^"$(SOLARXMLDIR)/":+".component") + $(XSLTPROC) --nonet --stringparam prefix $(SOLARXMLDIR)/ -o $@ \ + $(SOLARENV)/bin/packcomponents.xslt $(MISC)/applicat.input -$(BIN)$/applicat.rdb : makefile.mk $(UNOUCRRDB) - rm -f $@ - $(GNUCOPY) $(UNOUCRRDB) $@ - cd $(BIN) && \ - $(REGCOMP) -register -r applicat.rdb \ - -c i18nsearch.uno$(DLLPOST) \ - -c i18npool.uno$(DLLPOST) -.ENDIF +$(MISC)/applicat.input : + echo \ + '<list>$(my_components:^"<filename>":+".component</filename>")</list>' \ + > $@ + +$(BIN)/types.rdb : $(SOLARBINDIR)/types.rdb + $(COPY) $< $@ diff --git a/vcl/workben/svdem.cxx b/vcl/workben/svdem.cxx index 5822f4024a59..297660d4b8df 100644 --- a/vcl/workben/svdem.cxx +++ b/vcl/workben/svdem.cxx @@ -55,7 +55,7 @@ SAL_IMPLEMENT_MAIN() tools::extendApplicationEnvironment(); Reference< XMultiServiceFactory > xMS; - xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); + xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "types.rdb" ) ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); InitVCL( xMS ); ::Main(); diff --git a/vcl/workben/svptest.cxx b/vcl/workben/svptest.cxx index cc7c0f2b0cce..8f901d1c200b 100644 --- a/vcl/workben/svptest.cxx +++ b/vcl/workben/svptest.cxx @@ -61,7 +61,7 @@ SAL_IMPLEMENT_MAIN() tools::extendApplicationEnvironment(); Reference< XMultiServiceFactory > xMS; - xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); + xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "types.rdb" ) ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); InitVCL( xMS ); ::Main(); diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 41ca76144e5c..dafd546b3d68 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -60,7 +60,7 @@ SAL_IMPLEMENT_MAIN() tools::extendApplicationEnvironment(); Reference< XMultiServiceFactory > xMS; - xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); + xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "types.rdb" ) ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); InitVCL( xMS ); ::Main(); |