diff options
71 files changed, 1481 insertions, 806 deletions
diff --git a/i18npool/source/isolang/isolang.cxx b/i18npool/source/isolang/isolang.cxx index 28c86d39673e..9d80bf7050e6 100644 --- a/i18npool/source/isolang/isolang.cxx +++ b/i18npool/source/isolang/isolang.cxx @@ -287,7 +287,8 @@ static MsLangId::IsoLangEntry const aImplIsoLangEntries[] = { LANGUAGE_BELARUSIAN, "be", "BY" }, { LANGUAGE_CATALAN, "ca", "ES" }, // Spain (default) { LANGUAGE_CATALAN, "ca", "AD" }, // Andorra - { LANGUAGE_USER_CATALAN_VALENCIAN, "ca", "XV" }, // XV: ISO 3166 user-assigned; workaround for UI localization only, do not use in document content! + { LANGUAGE_USER_CATALAN_VALENCIAN, "ca", "XV" }, // XV: ISO 3166 user-assigned; old workaround for UI localization only, do not use in document content! Kept just in case.. + { LANGUAGE_USER_CATALAN_VALENCIAN, "qcv", "ES" }, // qcv: ISO 639-3 reserved-for-local-use; for UI localization, use in document content on own risk! { LANGUAGE_FRENCH_CAMEROON, "fr", "CM" }, { LANGUAGE_FRENCH_COTE_D_IVOIRE, "fr", "CI" }, { LANGUAGE_FRENCH_HAITI, "fr", "HT" }, diff --git a/padmin/source/padialog.cxx b/padmin/source/padialog.cxx index 3ea15e28141c..583e14c06caa 100644 --- a/padmin/source/padialog.cxx +++ b/padmin/source/padialog.cxx @@ -147,6 +147,11 @@ void PADialog::Init() ::psp::PrintFontManager& rFontManager( ::psp::PrintFontManager::get() ); if( ! rFontManager.checkImportPossible() ) m_aFontsPB.Enable( FALSE ); + if( rFontManager.hasFontconfig() ) + { + m_aFontsPB.Enable( FALSE ); + m_aFontsPB.Show( FALSE ); + } } PADialog::~PADialog() diff --git a/rsc/inc/rsctools.hxx b/rsc/inc/rsctools.hxx index 287a079f63c8..3a3eff653cd7 100644 --- a/rsc/inc/rsctools.hxx +++ b/rsc/inc/rsctools.hxx @@ -68,7 +68,6 @@ class RscChar { public: static char * MakeUTF8( char * pStr, UINT16 nTextEncoding ); - static char * MakeUTF8FromL( char * pStr ); }; /****************** R s c P t r P t r ************************************/ diff --git a/rsc/source/tools/rscchar.cxx b/rsc/source/tools/rscchar.cxx index ca421dde372a..c23022e4222e 100644 --- a/rsc/source/tools/rscchar.cxx +++ b/rsc/source/tools/rscchar.cxx @@ -194,136 +194,3 @@ char * RscChar::MakeUTF8( char * pStr, UINT16 nTextEncoding ) return pUtf8; }; - -/************************************************************************* -|* -|* RscChar::MakeChar() -|* -|* Beschreibung Der String wird nach C-Konvention umgesetzt -|* Ersterstellung MM 20.03.91 -|* Letzte Aenderung MM 20.03.91 -|* -*************************************************************************/ -char * RscChar::MakeUTF8FromL( char * pStr ) -{ - sal_Size nUniPos = 0; - sal_Unicode * pUniCode = new sal_Unicode[ strlen( pStr ) + 1 ]; - - char cOld = '1'; - while( cOld != 0 ) - { - sal_Unicode c; - if( *pStr == '\\' ) - { - ++pStr; - switch( *pStr ) - { - case 'a': - c = '\a'; - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case '\\': - c = '\\'; - break; - case '?': - c = '\?'; - break; - case '\'': - c = '\''; - break; - case '\"': - c = '\"'; - break; - default: - { - if( '0' <= *pStr && '7' >= *pStr ) - { - UINT32 nChar = 0; - int i = 0; - while( '0' <= *pStr && '7' >= *pStr && i != 6 ) - { - nChar = nChar * 8 + (BYTE)*pStr - (BYTE)'0'; - ++pStr; - i++; - } - if( nChar > 0xFFFF ) - // Wert zu gross, oder kein 3 Ziffern - return( FALSE ); - c = (UINT16)nChar; - pStr--; - } - else if( 'x' == *pStr || 'X' == *pStr ) - { - UINT32 nChar = 0; - int i = 0; - ++pStr; - while( isxdigit( *pStr ) && i != 4 ) - { - if( isdigit( *pStr ) ) - nChar = nChar * 16 + (BYTE)*pStr - (BYTE)'0'; - else if( isupper( *pStr ) ) - nChar = nChar * 16 + (BYTE)*pStr - (BYTE)'A' +10; - else - nChar = nChar * 16 + (BYTE)*pStr - (BYTE)'a' +10; - ++pStr; - i++; - } - c = (UINT16)nChar; - pStr--; - } - else - c = *pStr; - }; - } - } - else - c = *pStr; - - pUniCode[ nUniPos++ ] = c; - cOld = *pStr; - pStr++; - } - - // factor fo 6 is the maximum size of an UNICODE character as utf8 - sal_Size nMaxUtf8Len = nUniPos * 6; - if( nUniPos * 6 > 0x0FFFFF ) - RscExit( 10 ); - - char * pUtf8 = (char *)rtl_allocateMemory( nMaxUtf8Len ); - rtl_TextToUnicodeConverter hConv = rtl_createUnicodeToTextConverter( RTL_TEXTENCODING_UTF8 ); - - sal_uInt32 nInfo; - sal_Size nSrcCvtBytes; - rtl_convertUnicodeToText( hConv, 0, - pUniCode, nUniPos, - pUtf8, nMaxUtf8Len, - RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT - | RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT - | RTL_UNICODETOTEXT_FLAGS_FLUSH, - &nInfo, - &nSrcCvtBytes ); - - rtl_destroyUnicodeToTextConverter( hConv ); - - delete[] pUniCode; - - return pUtf8; -}; - diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx index b8bed49b603b..60c622208d53 100644 --- a/svl/source/items/style.cxx +++ b/svl/source/items/style.cxx @@ -28,7 +28,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svl.hxx" -#ifndef GCC +#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_ +#include <com/sun/star/lang/XComponent.hpp> #endif #define _SVSTDARR_STRINGS @@ -808,6 +809,16 @@ void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p ) { // Alle Styles umsetzen, deren Parent dieser hier ist ChangeParent( p->GetName(), p->GetParent() ); + + com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); + if( xComp.is() ) try + { + xComp->dispose(); + } + catch( com::sun::star::uno::Exception& ) + { + } + aStyles.erase(aIter); Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *p ) ); } @@ -838,6 +849,15 @@ void SfxStyleSheetBasePool::Clear() SfxStyles::iterator aIter( aClearStyles.begin() ); while( aIter != aClearStyles.end() ) { + com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY ); + if( xComp.is() ) try + { + xComp->dispose(); + } + catch( com::sun::star::uno::Exception& ) + { + } + Broadcast( SfxStyleSheetHint( SFX_STYLESHEET_ERASED, *(*aIter++).get() ) ); } } diff --git a/svl/source/misc/inettype.cxx b/svl/source/misc/inettype.cxx index bec8b91e7c22..ee9aa5932525 100644 --- a/svl/source/misc/inettype.cxx +++ b/svl/source/misc/inettype.cxx @@ -806,16 +806,13 @@ namespace unnamed_svl_inettype { MediaTypeEntry const * seekEntry(UniString const & rTypeName, MediaTypeEntry const * pMap, sal_Size nSize) { -#if defined DBG_UTIL || defined INETTYPE_DEBUG - static bool bChecked = false; - if (!bChecked) - { - for (sal_Size i = 0; i < nSize - 1; ++i) - DBG_ASSERT(pMap[i].m_pTypeName < pMap[i + 1].m_pTypeName, - "seekEntry(): Bad map"); - bChecked = true; - } -#endif // DBG_UTIL, INETTYPE_DEBUG +#if defined DBG_UTIL + for (sal_Size i = 0; i < nSize - 1; ++i) + DBG_ASSERT( + rtl_str_compare( + pMap[i].m_pTypeName, pMap[i + 1].m_pTypeName) < 0, + "seekEntry(): Bad map"); +#endif sal_Size nLow = 0; sal_Size nHigh = nSize; diff --git a/svl/source/misc/urihelper.cxx b/svl/source/misc/urihelper.cxx index a3a3f63367c1..46063564193d 100644 --- a/svl/source/misc/urihelper.cxx +++ b/svl/source/misc/urihelper.cxx @@ -123,8 +123,7 @@ inline UniString SmartRel2Abs_Impl(INetURLObject const & rTheBaseURIRef, eStyle); if (bCheckFileExists && !bWasAbsolute - && (aAbsURIRef.GetProtocol() == INET_PROT_FILE - || aAbsURIRef.GetProtocol() == INET_PROT_VND_SUN_STAR_WFS)) + && (aAbsURIRef.GetProtocol() == INET_PROT_FILE)) { INetURLObject aNonFileURIRef; aNonFileURIRef.SetSmartURL(rTheRelURIRef, diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index 5b7821aa457e..32c65b06d2f1 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -675,7 +675,7 @@ SvNumberformat::SvNumberformat(String& rString, xub_StrLen nAnzChars = ImpGetNumber(rString, nPos, sStr); if (nAnzChars > 0) { - short F_Type; + short F_Type = NUMBERFORMAT_UNDEFINED; if (!pISc->IsNumberFormat(sStr,F_Type,fNumber) || ( F_Type != NUMBERFORMAT_NUMBER && F_Type != NUMBERFORMAT_SCIENTIFIC) ) diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx index 21f6e69c8d9e..bf176015fd77 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.cxx +++ b/svtools/source/filter.vcl/wmf/winmtf.cxx @@ -36,7 +36,7 @@ // ------------------------------------------------------------------------ -#define WIN_MTF_MAX_POLYPOLYCOUNT 16 +#define WIN_MTF_MAX_CLIP_DEPTH 16 void WinMtfClipPath::ImpUpdateType() { @@ -54,26 +54,28 @@ void WinMtfClipPath::IntersectClipRect( const Rectangle& rRect ) { if ( !aPolyPoly.Count() ) aPolyPoly = Polygon( rRect ); - else if ( aPolyPoly.Count() < WIN_MTF_MAX_POLYPOLYCOUNT ) + else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) { Polygon aPolygon( rRect ); PolyPolygon aIntersection; PolyPolygon aPolyPolyRect( aPolygon ); aPolyPoly.GetIntersection( aPolyPolyRect, aIntersection ); aPolyPoly = aIntersection; + nDepth++; } ImpUpdateType(); } void WinMtfClipPath::ExcludeClipRect( const Rectangle& rRect ) { - if ( aPolyPoly.Count() && ( aPolyPoly.Count() < WIN_MTF_MAX_POLYPOLYCOUNT ) ) + if ( aPolyPoly.Count() && ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) ) { Polygon aPolygon( rRect ); PolyPolygon aPolyPolyRect( aPolygon ); PolyPolygon aDifference; aPolyPoly.GetDifference( aPolyPolyRect, aDifference ); aPolyPoly = aDifference; + nDepth++; } ImpUpdateType(); } @@ -82,8 +84,10 @@ void WinMtfClipPath::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nCl { if ( !rPolyPolygon.Count() ) aPolyPoly = rPolyPolygon; - else if ( rPolyPolygon.Count() < WIN_MTF_MAX_POLYPOLYCOUNT ) + else if ( nDepth < WIN_MTF_MAX_CLIP_DEPTH ) { + nDepth++; + PolyPolygon aNewClipPath; // #115345# Watch out for empty aPolyPoly here - conceptually, diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx index beb1f62e22d6..fb4fd2fe0c57 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.hxx +++ b/svtools/source/filter.vcl/wmf/winmtf.hxx @@ -314,6 +314,7 @@ class WinMtfClipPath { PolyPolygon aPolyPoly; WinMtfClipPathType eType; + sal_Int32 nDepth; void ImpUpdateType(); @@ -321,7 +322,7 @@ class WinMtfClipPath sal_Bool bNeedsUpdate; - WinMtfClipPath(): eType(EMPTY), bNeedsUpdate( sal_False ){}; + WinMtfClipPath(): eType(EMPTY), nDepth( 0 ), bNeedsUpdate( sal_False ){}; void SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode ); void IntersectClipRect( const Rectangle& rRect ); diff --git a/toolkit/source/layout/core/box-base.cxx b/toolkit/source/layout/core/box-base.cxx index dbe9163e2117..d203e63ce2ed 100644 --- a/toolkit/source/layout/core/box-base.cxx +++ b/toolkit/source/layout/core/box-base.cxx @@ -104,15 +104,16 @@ Box_Base::addChild (uno::Reference <awt::XLayoutConstrains> const& xChild) } Box_Base::ChildData* -Box_Base::removeChildData( std::list< ChildData* > lst, css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) +Box_Base::removeChildData( std::list< ChildData* >& lst, css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) { for ( std::list< ChildData* >::iterator it = lst.begin(); it != lst.end(); it++ ) { if ( (*it)->mxChild == xChild ) { + ChildData* pRet = *it; lst.erase( it ); - return *it; + return pRet; } } return 0; diff --git a/toolkit/source/layout/core/box-base.hxx b/toolkit/source/layout/core/box-base.hxx index 4f50f55bf5c4..685e0e35e8b6 100644 --- a/toolkit/source/layout/core/box-base.hxx +++ b/toolkit/source/layout/core/box-base.hxx @@ -62,7 +62,7 @@ protected: virtual ChildData *createChild( css::uno::Reference< css::awt::XLayoutConstrains > const& xChild ) = 0; virtual ChildProps *createChildProps( ChildData* pData ) = 0; - ChildData *removeChildData( std::list< ChildData *>, css::uno::Reference< css::awt::XLayoutConstrains > const& Child ); + ChildData *removeChildData( std::list< ChildData *>&, css::uno::Reference< css::awt::XLayoutConstrains > const& Child ); public: void AddChild( const css::uno::Reference< css::awt::XLayoutConstrains >& Child); diff --git a/toolkit/src2xml/include.lst b/toolkit/src2xml/include.lst index a93449625585..2bf5fced6fd3 100644 --- a/toolkit/src2xml/include.lst +++ b/toolkit/src2xml/include.lst @@ -106,7 +106,6 @@ ../../basic/unxlngi6.pro/inc ../../boost/unxlngi6.pro/inc ../../XmlSearch/unxlngi6.pro/inc -../../fondu/unxlngi6.pro/inc ../../forms/inc ../../forms/source/inc ../../forms/source/solar/inc diff --git a/tools/inc/tools/solar.h b/tools/inc/tools/solar.h index 1d248853f895..2ae0fa5f2f32 100644 --- a/tools/inc/tools/solar.h +++ b/tools/inc/tools/solar.h @@ -384,6 +384,8 @@ template<typename T> inline T Abs(T a) { return (a>=0?a:-a); } #define __DLLEXTENSION "lm.so" #elif defined LINUX && defined HPPA #define __DLLEXTENSION "lh.so" +#elif defined LINUX && defined AXP + #define __DLLEXTENSION "ll.so" #elif defined LINUX #error unknown plattform #elif defined FREEBSD && defined X86 diff --git a/tools/inc/tools/urlobj.hxx b/tools/inc/tools/urlobj.hxx index 86a8114ab0b8..17d52432e206 100644 --- a/tools/inc/tools/urlobj.hxx +++ b/tools/inc/tools/urlobj.hxx @@ -125,22 +125,21 @@ enum INetProtocol INET_PROT_DATA = 15, INET_PROT_CID = 16, INET_PROT_OUT = 17, - INET_PROT_VND_SUN_STAR_WFS = 18, - INET_PROT_VND_SUN_STAR_HIER = 19, - INET_PROT_VIM = 20, - INET_PROT_UNO = 21, - INET_PROT_COMPONENT = 22, - INET_PROT_VND_SUN_STAR_PKG = 23, - INET_PROT_LDAP = 24, - INET_PROT_DB = 25, - INET_PROT_VND_SUN_STAR_CMD = 26, - INET_PROT_VND_SUN_STAR_ODMA = 27, - INET_PROT_TELNET = 28, - INET_PROT_VND_SUN_STAR_EXPAND = 29, - INET_PROT_VND_SUN_STAR_TDOC = 30, - INET_PROT_GENERIC = 31, - INET_PROT_SMB = 32, - INET_PROT_END = 33 + INET_PROT_VND_SUN_STAR_HIER = 18, + INET_PROT_VIM = 19, + INET_PROT_UNO = 20, + INET_PROT_COMPONENT = 21, + INET_PROT_VND_SUN_STAR_PKG = 22, + INET_PROT_LDAP = 23, + INET_PROT_DB = 24, + INET_PROT_VND_SUN_STAR_CMD = 25, + INET_PROT_VND_SUN_STAR_ODMA = 26, + INET_PROT_TELNET = 27, + INET_PROT_VND_SUN_STAR_EXPAND = 28, + INET_PROT_VND_SUN_STAR_TDOC = 29, + INET_PROT_GENERIC = 30, + INET_PROT_SMB = 31, + INET_PROT_END = 32 }; //============================================================================ diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx index 07c532e60dd7..a6d7bc6fd04e 100644 --- a/tools/source/fsys/urlobj.cxx +++ b/tools/source/fsys/urlobj.cxx @@ -191,11 +191,6 @@ using namespace com::sun; name = *(escaped / alphanum / "!" / "$" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "?" / "@" / "_" / "~" - ; prvate (see RFC 1738, RFC 2396) - vnd-sun-star-wfs-url = "VND.SUN.STAR.WFS://" [host / "LOCALHOST"] ["/" segment *("/" segment)] - segment = *pchar - - ; private vnd-sun-star-hier-url = "VND.SUN.STAR.HIER:" ["//"reg_name] *("/" *pchar) reg_name = 1*(escaped / alphanum / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / "-" / "." / ":" / ";" / "=" / "@" / "_" / "~") @@ -403,8 +398,6 @@ static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END] false, false }, { "out", "out://", 0, true, false, false, false, false, false, false, false }, - { "vnd.sun.star.wfs", "vnd.sun.star.wfs://", 0, true, false, false, - false, true, true, true, false }, { "vnd.sun.star.hier", "vnd.sun.star.hier:", 0, true, false, false, false, false, false, true, false }, { "vim", "vim://", 0, true, true, false, true, false, false, true, @@ -429,7 +422,7 @@ static INetURLObject::SchemeInfo const aSchemeInfoMap[INET_PROT_END] false, false, false, false, false }, { "vnd.sun.star.tdoc", "vnd.sun.star.tdoc:", 0, false, false, false, false, false, false, true, false }, - { "", "", 0, false, false, false, false, false, false, false, false }, + { "", "", 0, false, false, false, false, true, true, true, false }, { "smb", "smb://", 139, true, true, false, true, true, true, true, true } }; @@ -1338,7 +1331,7 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef, if (pHostPortBegin) { sal_Unicode const * pPort = pHostPortEnd; - if (getSchemeInfo().m_bPort && pHostPortBegin < pHostPortEnd) + if ( getSchemeInfo().m_bPort && pHostPortBegin < pHostPortEnd ) { sal_Unicode const * p1 = pHostPortEnd - 1; while (p1 > pHostPortBegin && INetMIME::isDigit(*p1)) @@ -1350,7 +1343,6 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef, switch (m_eScheme) { case INET_PROT_FILE: - case INET_PROT_VND_SUN_STAR_WFS: // If the host equals "LOCALHOST" (unencoded and ignoring // case), turn it into an empty host: if (INetMIME::equalIgnoreCase(pHostPortBegin, pPort, @@ -1367,7 +1359,6 @@ bool INetURLObject::setAbsURIRef(rtl::OUString const & rTheAbsURIRef, return false; } break; - default: if (pHostPortBegin == pPort) { @@ -1609,7 +1600,23 @@ bool INetURLObject::convertRelToAbs(rtl::OUString const & rTheRelURIRef, STATE_DONE }; rtl::OUStringBuffer aSynAbsURIRef; - aSynAbsURIRef.appendAscii(getSchemeInfo().m_pScheme); + // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme + // is empty ("") in that case, so take the scheme from m_aAbsURIRef + if (m_eScheme != INET_PROT_GENERIC) + { + aSynAbsURIRef.appendAscii(getSchemeInfo().m_pScheme); + } + else + { + sal_Unicode const * pSchemeBegin + = m_aAbsURIRef.getStr(); + sal_Unicode const * pSchemeEnd = pSchemeBegin; + while (pSchemeEnd[0] != ':') + { + ++pSchemeEnd; + } + aSynAbsURIRef.append(pSchemeBegin, pSchemeEnd - pSchemeBegin); + } aSynAbsURIRef.append(sal_Unicode(':')); sal_Char cEscapePrefix = getEscapePrefix(); @@ -2162,11 +2169,7 @@ INetURLObject::getPrefix(sal_Unicode const *& rBegin, { "vnd.sun.star.tdoc:", 0, INET_PROT_VND_SUN_STAR_TDOC, PrefixInfo::OFFICIAL }, { "vnd.sun.star.webdav:", 0, INET_PROT_VND_SUN_STAR_WEBDAV, - PrefixInfo::OFFICIAL }, - { "vnd.sun.star.wfs:", 0, INET_PROT_VND_SUN_STAR_WFS, - PrefixInfo::OFFICIAL }, - { "wfs:", "vnd.sun.star.wfs:", INET_PROT_VND_SUN_STAR_WFS, - PrefixInfo::ALIAS } }; + PrefixInfo::OFFICIAL } }; PrefixInfo const * pFirst = aMap + 1; PrefixInfo const * pLast = aMap + sizeof aMap / sizeof (PrefixInfo) - 1; PrefixInfo const * pMatch = 0; @@ -2889,7 +2892,6 @@ bool INetURLObject::setHost(rtl::OUString const & rTheHost, bool bOctets, switch (m_eScheme) { case INET_PROT_FILE: - case INET_PROT_VND_SUN_STAR_WFS: { rtl::OUString sTemp(aSynHost); if (sTemp.equalsIgnoreAsciiCaseAsciiL( @@ -2985,7 +2987,6 @@ bool INetURLObject::parsePath(INetProtocol eScheme, break; case INET_PROT_FILE: - case INET_PROT_VND_SUN_STAR_WFS: { if (bSkippedInitialSlash) aTheSynPath.append(sal_Unicode('/')); @@ -3398,7 +3399,6 @@ bool INetURLObject::parsePath(INetProtocol eScheme, if (aTheSynPath.getLength() == 0) return false; break; - default: OSL_ASSERT(false); break; @@ -3825,7 +3825,27 @@ INetURLObject::getAbbreviated( OSL_ENSURE(rStringWidth.is(), "specification violation"); sal_Char cEscapePrefix = getEscapePrefix(); rtl::OUStringBuffer aBuffer; - aBuffer.appendAscii(getSchemeInfo().m_pScheme); + // make sure that the scheme is copied for generic schemes: getSchemeInfo().m_pScheme + // is empty ("") in that case, so take the scheme from m_aAbsURIRef + if (m_eScheme != INET_PROT_GENERIC) + { + aBuffer.appendAscii(getSchemeInfo().m_pScheme); + } + else + { + if (m_aAbsURIRef) + { + sal_Unicode const * pSchemeBegin + = m_aAbsURIRef.getStr(); + sal_Unicode const * pSchemeEnd = pSchemeBegin; + + while (pSchemeEnd[0] != ':') + { + ++pSchemeEnd; + } + aBuffer.append(pSchemeBegin, pSchemeEnd - pSchemeBegin); + } + } aBuffer.append(static_cast< sal_Unicode >(':')); bool bAuthority = getSchemeInfo().m_bAuthority; sal_Unicode const * pCoreBegin @@ -4007,7 +4027,6 @@ bool INetURLObject::operator ==(INetURLObject const & rObject) const switch (m_eScheme) { case INET_PROT_FILE: - case INET_PROT_VND_SUN_STAR_WFS: { // If the URL paths of two file URLs only differ in that one has a // final '/' and the other has not, take the two paths as @@ -4162,7 +4181,6 @@ bool INetURLObject::ConcatData(INetProtocol eTheScheme, switch (m_eScheme) { case INET_PROT_FILE: - case INET_PROT_VND_SUN_STAR_WFS: { rtl::OUString sTemp(aSynHost); if (sTemp.equalsIgnoreAsciiCaseAsciiL( diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx index 694698297680..0930dfcc5239 100644 --- a/tools/workben/urltest.cxx +++ b/tools/workben/urltest.cxx @@ -523,6 +523,8 @@ main() /*TODO "vnd.sun.star.wfs:///c|/xyz/",*/ /*TODO "vnd.sun.star.wfs://xxx/yyy?zzz",*/ "vnd.sun.star.wfs:///x/y/z", + "vnd.sun.star.generic:///x/y/z", + "vnd.sun.star.generic://host:34/x/y/z" /*TODO "wfs://",*/ /*TODO "wfs://LocalHost",*/ /*TODO "wfs:///c|/xyz/",*/ @@ -533,13 +535,21 @@ main() INetURLObject aUrl(aTest[i]); if (aUrl.HasError()) printf("BAD %s\n", aTest[i]); - else if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI). - equalsAscii(aTest[i]) != sal_True) + else { + if (aUrl.GetProtocol() != INET_PROT_GENERIC) { + printf("BAD PROTOCOL %i -> %i\n", + aUrl.GetProtocol(), + INET_PROT_GENERIC); + } + if (aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI). + equalsAscii(aTest[i]) != sal_True) + { String sTest(aUrl.GetMainURL(INetURLObject::DECODE_TO_IURI)); printf("BAD %s -> %s\n", aTest[i], ByteString(sTest, RTL_TEXTENCODING_ASCII_US).GetBuffer()); + } } } } diff --git a/ucbhelper/inc/ucbhelper/configureucb.hxx b/ucbhelper/inc/ucbhelper/configureucb.hxx deleted file mode 100644 index 2e70467a4e9f..000000000000 --- a/ucbhelper/inc/ucbhelper/configureucb.hxx +++ /dev/null @@ -1,201 +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 _UCBHELPER_CONFIGUREUCB_HXX_ -#define _UCBHELPER_CONFIGUREUCB_HXX_ - -#include <com/sun/star/uno/Reference.hxx> -#include <com/sun/star/uno/RuntimeException.hpp> -#include <com/sun/star/uno/Sequence.hxx> -#include <rtl/ustring.hxx> - -#include <vector> -#include "ucbhelper/ucbhelperdllapi.h" - -namespace com { namespace sun { namespace star { - namespace lang { class XMultiServiceFactory; } - namespace ucb { - class XContentProvider; - class XContentProviderManager; - } - namespace uno { class Any; } -} } } - -namespace ucbhelper { - -//============================================================================ -/** Information about a registered content provider, passed from - <method>configureUcb</method> to <method>unconfigureUcb</method> (and from - <method>registerAtUcb</method> to <method>deregisterFromUcb</method>). - */ -struct ContentProviderRegistrationInfo -{ - /** The registered content provider (or null if registration failed). - */ - com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > - m_xProvider; - - /** The arguments the content provider was instantiated with. - */ - rtl::OUString m_aArguments; - - /** The URL template the content provider is registered on. - */ - rtl::OUString m_aTemplate; -}; - //@@@ if registerucb.hxx were exported, too, this might better reside in - // there... - -typedef std::vector< ContentProviderRegistrationInfo > - ContentProviderRegistrationInfoList; - -//============================================================================ -/** Information about a content provider, passed to - <method>configureUcb</method>. - */ -struct ContentProviderData -{ - /** The UNO service name to use to instanciate the content provider. - */ - rtl::OUString ServiceName; - - /** The URL template to use to instanciate the content provider. - */ - rtl::OUString URLTemplate; - - /** The arguments to use to instanciate the content provider. - */ - rtl::OUString Arguments; - - ContentProviderData() {}; - ContentProviderData( const rtl::OUString & rService, - const rtl::OUString & rTemplate, - const rtl::OUString & rArgs ) - : ServiceName( rService ), URLTemplate( rTemplate ), Arguments( rArgs ) {} -}; - -typedef std::vector< ContentProviderData > ContentProviderDataList; - -//============================================================================ -/** Configure a (newly instantiated) Universal Content Broker. - - @descr This function tries to register at the given content provider - manager all the content provider services listed under a given key in the - configuration database. - - @param rManager A content provider manager (normally, this would be a - newly intantiated UCB). - - @param rServiceFactory A service factory through which to obtain the - various services required. - - @param rData A list containing the data for the content providers for - the UCB to configure. - - @pInfos If not null, an entry will be added to this vector for every - content provider that is registered (sucessfully or not). - - @return True if the UCB has successfuly been configured (though not all - content providers have necessarily been registered due to individual - problems). - */ -bool -configureUcb( - com::sun::star::uno::Reference< - com::sun::star::ucb::XContentProviderManager > const & - rManager, - com::sun::star::uno::Reference< - com::sun::star::lang::XMultiServiceFactory > const & - rServiceFactory, - ContentProviderDataList const & rData, - ContentProviderRegistrationInfoList * pInfos) - throw (com::sun::star::uno::RuntimeException); - - -//============================================================================ -/** Configure a (newly instantiated) Universal Content Broker. - - @descr This function tries to register at the given content provider - manager all the content provider services listed under a given key in the - configuration database. - - @param rManager A content provider manager (normally, this would be a - newly intantiated UCB). - - @param rServiceFactory A service factory through which to obtain the - various services required. - - @param rArguments A sequence of at least two strings: the primary and - secondary key addressing a chosen UCB configuration in the configuration - database. The sequence can be longer, in which case the excess elements - must be strings that form key/value pairs. These key/value pairs will be - used to replace placeholders in the data from the configuration database - with (dynamic) values. This is a (rather unstructured) sequence of - <type>Any<type/>s, since normally this parameter will simply be forwarded - by the UCB's <method>initialize<method/> method, which has a parameter of - the same type. - - @pInfos If not null, an entry will be added to this vector for every - content provider that is registered (sucessfully or not). - - @return True if the UCB has successfuly been configured (though not all - content providers have necessarily been registered due to individual - problems). - */ -UCBHELPER_DLLPUBLIC bool -configureUcb( - com::sun::star::uno::Reference< - com::sun::star::ucb::XContentProviderManager > const & - rManager, - com::sun::star::uno::Reference< - com::sun::star::lang::XMultiServiceFactory > const & - rServiceFactory, - com::sun::star::uno::Sequence< com::sun::star::uno::Any > const & - rArguments, - std::vector< ContentProviderRegistrationInfo > * pInfos) - throw (com::sun::star::uno::RuntimeException); - -//============================================================================ -/** Undo the configuration of a Universal Content Broker. - - @descr This function is the reverse of <method>configureUcb</method>. - - @param rManager A content provider manager. - - @param rInfos Information about all the registered content providers. - */ -void -unconfigureUcb( - com::sun::star::uno::Reference< - com::sun::star::ucb::XContentProviderManager > const & - rManager, - std::vector< ContentProviderRegistrationInfo > const & rInfos) - throw (com::sun::star::uno::RuntimeException); - -} - -#endif // _UCBHELPER_CONFIGUREUCB_HXX_ diff --git a/ucbhelper/inc/ucbhelper/contentbroker.hxx b/ucbhelper/inc/ucbhelper/contentbroker.hxx index eea72cc689e0..54139d3ffdea 100644 --- a/ucbhelper/inc/ucbhelper/contentbroker.hxx +++ b/ucbhelper/inc/ucbhelper/contentbroker.hxx @@ -41,7 +41,7 @@ namespace com { namespace sun { namespace star { namespace ucb { class XContentProviderManager; class XCommandProcessor; } } } } -#include <ucbhelper/configureucb.hxx> +#include <ucbhelper/registerucb.hxx> #include "ucbhelper/ucbhelperdllapi.h" namespace ucbhelper diff --git a/ucbhelper/inc/ucbhelper/registerucb.hxx b/ucbhelper/inc/ucbhelper/registerucb.hxx new file mode 100644 index 000000000000..e2427248dce2 --- /dev/null +++ b/ucbhelper/inc/ucbhelper/registerucb.hxx @@ -0,0 +1,129 @@ +/************************************************************************* +* +* 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 _UCBHELPER_REGISTERUCB_HXX_ +#define _UCBHELPER_REGISTERUCB_HXX_ + +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentProviderManager.hpp> +#include <vector> + +#include "ucbhelper/ucbhelperdllapi.h" + +namespace com { namespace sun { namespace star { + namespace lang { class XMultiServiceFactory; } +} } } + +namespace rtl { class OUString; } + +namespace ucbhelper { + +//============================================================================ +/** Information about a registered content provider. + */ +struct ContentProviderRegistrationInfo +{ + /** The registered content provider (or null if registration failed). + */ + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > + m_xProvider; + + /** The arguments the content provider was instantiated with. + */ + rtl::OUString m_aArguments; + + /** The URL template the content provider is registered on. + */ + rtl::OUString m_aTemplate; +}; + +typedef std::vector< ContentProviderRegistrationInfo > + ContentProviderRegistrationInfoList; + +//============================================================================ +/** Information about a content provider, passed to + <method>configureUcb</method>. + */ +struct ContentProviderData +{ + /** The UNO service name to use to instanciate the content provider. + */ + rtl::OUString ServiceName; + + /** The URL template to use to instanciate the content provider. + */ + rtl::OUString URLTemplate; + + /** The arguments to use to instanciate the content provider. + */ + rtl::OUString Arguments; + + ContentProviderData() {}; + ContentProviderData( const rtl::OUString & rService, + const rtl::OUString & rTemplate, + const rtl::OUString & rArgs ) + : ServiceName( rService ), URLTemplate( rTemplate ), Arguments( rArgs ) {} +}; + +typedef std::vector< ContentProviderData > ContentProviderDataList; +//============================================================================ +/** Register a content provider at a Universal Content Broker. + + @param rManager A content provider manager (normally, this would be a + UCB). May be null, which is only useful if the content provider is an + <type>XParamterizedContentProvider</type>s. + + @param rServiceFactory A factory through which to obtain the required + services. + + @param rName The service name of the content provider. + + @param rArguments Any arguments to instantiate the content provider with. + + @param rTemplate The URL template to register the content provider on. + + @param pInfo If not null, this output parameter is filled with + information about the (atemptively) registered provider. + */ + +UCBHELPER_DLLPUBLIC bool registerAtUcb( + com::sun::star::uno::Reference< + com::sun::star::ucb::XContentProviderManager > const & + rManager, + com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > const & + rServiceFactory, + rtl::OUString const & rName, + rtl::OUString const & rArguments, + rtl::OUString const & rTemplate, + ContentProviderRegistrationInfo * pInfo) + throw (com::sun::star::uno::RuntimeException); + +} +#endif // _UCBHELPER_REGISTERUCB_HXX_ diff --git a/ucbhelper/prj/d.lst b/ucbhelper/prj/d.lst index 64da268b6143..21a46483789b 100644 --- a/ucbhelper/prj/d.lst +++ b/ucbhelper/prj/d.lst @@ -9,7 +9,7 @@ mkdir: %_DEST%\inc%_EXT%\ucbhelper ..\inc\ucbhelper\configurationkeys.hxx %_DEST%\inc%_EXT%\ucbhelper\configurationkeys.hxx -..\inc\ucbhelper\configureucb.hxx %_DEST%\inc%_EXT%\ucbhelper\configureucb.hxx +..\inc\ucbhelper\registerucb.hxx %_DEST%\inc%_EXT%\ucbhelper\registerucb.hxx ..\inc\ucbhelper\content.hxx %_DEST%\inc%_EXT%\ucbhelper\content.hxx ..\inc\ucbhelper\contentbroker.hxx %_DEST%\inc%_EXT%\ucbhelper\contentbroker.hxx ..\inc\ucbhelper\commandenvironment.hxx %_DEST%\inc%_EXT%\ucbhelper\commandenvironment.hxx diff --git a/ucbhelper/source/client/contentbroker.cxx b/ucbhelper/source/client/contentbroker.cxx index 7e0e7f3657ca..408ff6af0dee 100644 --- a/ucbhelper/source/client/contentbroker.cxx +++ b/ucbhelper/source/client/contentbroker.cxx @@ -298,14 +298,18 @@ bool ContentBroker_Impl::initialize() if ( m_xProviderMgr.is() ) { - if ( !configureUcb( m_xProviderMgr, - m_xSMgr, - m_aProvData, - 0 ) ) + ContentProviderDataList::const_iterator aEnd(m_aProvData.end()); + for (ContentProviderDataList::const_iterator aIt(m_aProvData.begin()); + aIt != aEnd; ++aIt) { - OSL_ENSURE( false, "Failed to configure UCB!" ); - return false; + registerAtUcb(m_xProviderMgr, + m_xSMgr, + aIt->ServiceName, + aIt->Arguments, + aIt->URLTemplate, + 0); } + } } } diff --git a/ucbhelper/source/provider/makefile.mk b/ucbhelper/source/provider/makefile.mk index db06a5df131c..5999192f7bdb 100644 --- a/ucbhelper/source/provider/makefile.mk +++ b/ucbhelper/source/provider/makefile.mk @@ -43,7 +43,6 @@ ENABLE_EXCEPTIONS=TRUE .IF "$(header)" == "" SLOFILES=\ - $(SLO)$/configureucb.obj \ $(SLO)$/contentidentifier.obj \ $(SLO)$/providerhelper.obj \ $(SLO)$/contenthelper.obj \ @@ -53,7 +52,6 @@ SLOFILES=\ $(SLO)$/resultsetmetadata.obj \ $(SLO)$/resultset.obj \ $(SLO)$/resultsethelper.obj \ - $(SLO)$/provconf.obj \ $(SLO)$/commandenvironmentproxy.obj \ $(SLO)$/interactionrequest.obj \ $(SLO)$/simpleinteractionrequest.obj \ diff --git a/ucbhelper/source/provider/registerucb.cxx b/ucbhelper/source/provider/registerucb.cxx index 0a749c9ccb5c..e6ccaf4743a8 100644 --- a/ucbhelper/source/provider/registerucb.cxx +++ b/ucbhelper/source/provider/registerucb.cxx @@ -27,7 +27,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_ucbhelper.hxx" -#include <registerucb.hxx> +#include <ucbhelper/registerucb.hxx> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/ucb/XContentProviderManager.hpp> #include <com/sun/star/ucb/XParameterizedContentProvider.hpp> @@ -35,7 +35,6 @@ #include <com/sun/star/uno/RuntimeException.hpp> #include "osl/diagnose.h" -#include <ucbhelper/configureucb.hxx> using namespace com::sun::star; @@ -162,41 +161,4 @@ registerAtUcb( return bSuccess; } -//============================================================================ -// -// deregisterFromUcb -// -//============================================================================ - -void -deregisterFromUcb( - uno::Reference< ucb::XContentProviderManager > const & rManager, - ContentProviderRegistrationInfo const & rInfo) - throw (uno::RuntimeException) -{ - uno::Reference< ucb::XContentProvider > - xProvider(rInfo.m_xProvider); - uno::Reference< ucb::XParameterizedContentProvider > - xParameterized(xProvider, uno::UNO_QUERY); - if (xParameterized.is()) - { - uno::Reference< ucb::XContentProvider > xInstance; - try - { - xInstance - = xParameterized->deregisterInstance(rInfo.m_aTemplate, - rInfo.m_aArguments); - } - catch (lang::IllegalArgumentException const &) {} - - if (xInstance.is()) - xProvider = xInstance; - } - - if (rManager.is()) - rManager->deregisterContentProvider(xProvider, rInfo.m_aTemplate); - //@@@ if this fails, a roll-back of deregisterInstance() is - // missing -} - } diff --git a/ucbhelper/source/provider/registerucb.hxx b/ucbhelper/source/provider/registerucb.hxx deleted file mode 100644 index f17321c76cd5..000000000000 --- a/ucbhelper/source/provider/registerucb.hxx +++ /dev/null @@ -1,96 +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 _UCBHELPER_REGISTERUCB_HXX_ -#define _UCBHELPER_REGISTERUCB_HXX_ - -#include <com/sun/star/uno/RuntimeException.hpp> -#include <com/sun/star/uno/Reference.h> - -namespace com { namespace sun { namespace star { - namespace lang { class XMultiServiceFactory; } - namespace ucb { class XContentProviderManager; } -} } } -namespace rtl { class OUString; } - -namespace ucbhelper { - -struct ContentProviderRegistrationInfo; - -//============================================================================ -/** Register a content provider at a Universal Content Broker. - - @param rManager A content provider manager (normally, this would be a - UCB). May be null, which is only useful if the content provider is an - <type>XParamterizedContentProvider</type>s. - - @param rServiceFactory A factory through which to obtain the required - services. - - @param rName The service name of the content provider. - - @param rArguments Any arguments to instantiate the content provider with. - - @param rTemplate The URL template to register the content provider on. - - @param pInfo If not null, this output parameter is filled with - information about the (atemptively) registered provider. - */ -bool -registerAtUcb( - com::sun::star::uno::Reference< - com::sun::star::ucb::XContentProviderManager > const & - rManager, - com::sun::star::uno::Reference< - com::sun::star::lang::XMultiServiceFactory > const & - rServiceFactory, - rtl::OUString const & rName, - rtl::OUString const & rArguments, - rtl::OUString const & rTemplate, - ContentProviderRegistrationInfo * pInfo) - throw (com::sun::star::uno::RuntimeException); - -//============================================================================ -/** Deregister a content provider from a Universal Content Broker. - - @param rManager A content provider manager (normally, this would be a - UCB). May be null, which is only useful if the content provider is an - <type>XParamterizedContentProvider</type>s. - - @param rInfo Information about the content provider to deregister. - */ -void -deregisterFromUcb( - com::sun::star::uno::Reference< - com::sun::star::ucb::XContentProviderManager > const & - rManager, - ContentProviderRegistrationInfo const & rInfo) - throw (com::sun::star::uno::RuntimeException); - -} - -#endif // _UCBHELPER_REGISTERUCB_HXX_ diff --git a/vcl/aqua/inc/salframe.h b/vcl/aqua/inc/salframe.h index fd783270875e..c2ded3267f45 100644 --- a/vcl/aqua/inc/salframe.h +++ b/vcl/aqua/inc/salframe.h @@ -184,6 +184,8 @@ public: NSView* getView() const { return mpView; } unsigned int getStyleMask() const { return mnStyleMask; } + void getResolution( long& o_rDPIX, long& o_rDPIY ); + // actually the follwing methods do the same thing: flipping y coordinates // but having two of them makes clearer what the coordinate system // is supposed to be before and after diff --git a/vcl/aqua/inc/salinst.h b/vcl/aqua/inc/salinst.h index 8a44f7ef3304..0bceb99d1d0e 100644 --- a/vcl/aqua/inc/salinst.h +++ b/vcl/aqua/inc/salinst.h @@ -32,6 +32,7 @@ #include "vos/mutex.hxx" #include "vos/thread.hxx" #include "vcl/salinst.hxx" +#include "osl/conditn.h" #include "aquavcltypes.h" @@ -96,6 +97,7 @@ public: int mnActivePrintJobs; std::list< SalUserEvent > maUserEvents; oslMutex maUserEventListMutex; + oslCondition maWaitingYieldCond; typedef std::list<const ApplicationEvent*> AppEventList; static AppEventList aAppEventList; diff --git a/vcl/aqua/source/a11y/aqua11yfactory.mm b/vcl/aqua/source/a11y/aqua11yfactory.mm index eb745ea24aa5..7732ce202cd2 100644 --- a/vcl/aqua/source/a11y/aqua11yfactory.mm +++ b/vcl/aqua/source/a11y/aqua11yfactory.mm @@ -48,6 +48,7 @@ #include "aqua11ywrappersplitter.h" #include "aqua11ywrappertabgroup.h" #include "aqua11ywrappertoolbar.h" +#include "aqua11ytablewrapper.h" #include <com/sun/star/accessibility/AccessibleStateType.hpp> using namespace ::com::sun::star::accessibility; @@ -142,6 +143,8 @@ static bool enabled = false; aWrapper = [ [ AquaA11yWrapperList alloc ] initWithAccessibleContext: rxAccessibleContext ]; } else if ( [ nativeRole isEqualToString: NSAccessibilitySplitterRole ] ) { aWrapper = [ [ AquaA11yWrapperSplitter alloc ] initWithAccessibleContext: rxAccessibleContext ]; + } else if ( [ nativeRole isEqualToString: NSAccessibilityTableRole ] ) { + aWrapper = [ [ AquaA11yTableWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ]; } else { aWrapper = [ [ AquaA11yWrapper alloc ] initWithAccessibleContext: rxAccessibleContext ]; } diff --git a/vcl/aqua/source/a11y/aqua11ytablewrapper.h b/vcl/aqua/source/a11y/aqua11ytablewrapper.h index 8753365377e3..7bf3e44a2945 100644 --- a/vcl/aqua/source/a11y/aqua11ytablewrapper.h +++ b/vcl/aqua/source/a11y/aqua11ytablewrapper.h @@ -30,9 +30,15 @@ #include "aqua11ywrapper.h" -@interface AquaA11yTableWrapper : NSObject +#define MAXIMUM_ACCESSIBLE_TABLE_CELLS 1000 + +@interface AquaA11yTableWrapper : AquaA11yWrapper { } -+(id)childrenAttributeForElement:(AquaA11yWrapper *)wrapper; ++(id)childrenAttributeForElement:(AquaA11yTableWrapper *)wrapper; ++(void)addAttributeNamesTo: (NSMutableArray *)attributeNames object: (AquaA11yWrapper*)pObject; + +-(id)rowsAttribute; +-(id)columnsAttribute; @end #endif // _SV_AQUA11TABLEWRAPPER_H diff --git a/vcl/aqua/source/a11y/aqua11ytablewrapper.mm b/vcl/aqua/source/a11y/aqua11ytablewrapper.mm index 08205ac8a66b..98454ab8d57b 100644 --- a/vcl/aqua/source/a11y/aqua11ytablewrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ytablewrapper.mm @@ -35,38 +35,120 @@ using namespace ::com::sun::star::accessibility; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::uno; -@implementation AquaA11yTableWrapper : NSObject +@implementation AquaA11yTableWrapper : AquaA11yWrapper -+(id)childrenAttributeForElement:(AquaA11yWrapper *)wrapper ++(id)childrenAttributeForElement:(AquaA11yTableWrapper *)wrapper { - try + XAccessibleTable * accessibleTable = [ wrapper accessibleTable ]; + NSArray* pResult = nil; + if( accessibleTable ) { NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; - XAccessibleComponent * accessibleComponent = [ wrapper accessibleComponent ]; - XAccessibleTable * accessibleTable = [ wrapper accessibleTable ]; - // find out which cells are actually visible by determining the top-left-cell and the bottom-right-cell - Size tableSize = accessibleComponent -> getSize(); - Point point; - point.X = 0; - point.Y = 0; - Reference < XAccessible > rAccessibleTopLeft = accessibleComponent -> getAccessibleAtPoint ( point ); - point.X = tableSize.Width - 1; - point.Y = tableSize.Height - 1; - Reference < XAccessible > rAccessibleBottomRight = accessibleComponent -> getAccessibleAtPoint ( point ); - if ( rAccessibleTopLeft.is() && rAccessibleBottomRight.is() ) + try { - sal_Int32 idxTopLeft = rAccessibleTopLeft -> getAccessibleContext() -> getAccessibleIndexInParent(); - sal_Int32 idxBottomRight = rAccessibleBottomRight -> getAccessibleContext() -> getAccessibleIndexInParent(); - sal_Int32 rowTopLeft = accessibleTable -> getAccessibleRow ( idxTopLeft ); - sal_Int32 columnTopLeft = accessibleTable -> getAccessibleColumn ( idxTopLeft ); - sal_Int32 rowBottomRight = accessibleTable -> getAccessibleRow ( idxBottomRight ); - sal_Int32 columnBottomRight = accessibleTable -> getAccessibleColumn ( idxBottomRight ); - // create an array containing the visible cells - for ( sal_Int32 rowCount = rowTopLeft; rowCount <= rowBottomRight; rowCount++ ) + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) { - for ( sal_Int32 columnCount = columnTopLeft; columnCount <= columnBottomRight; columnCount++ ) + // make all children visible to the hierarchy + for ( sal_Int32 rowCount = 0; rowCount < nRows; rowCount++ ) { - Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + for ( sal_Int32 columnCount = 0; columnCount < nCols; columnCount++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + } + } + else + { + XAccessibleComponent * accessibleComponent = [ wrapper accessibleComponent ]; + // find out which cells are actually visible by determining the top-left-cell and the bottom-right-cell + Size tableSize = accessibleComponent -> getSize(); + Point point; + point.X = 0; + point.Y = 0; + Reference < XAccessible > rAccessibleTopLeft = accessibleComponent -> getAccessibleAtPoint ( point ); + point.X = tableSize.Width - 1; + point.Y = tableSize.Height - 1; + Reference < XAccessible > rAccessibleBottomRight = accessibleComponent -> getAccessibleAtPoint ( point ); + if ( rAccessibleTopLeft.is() && rAccessibleBottomRight.is() ) + { + sal_Int32 idxTopLeft = rAccessibleTopLeft -> getAccessibleContext() -> getAccessibleIndexInParent(); + sal_Int32 idxBottomRight = rAccessibleBottomRight -> getAccessibleContext() -> getAccessibleIndexInParent(); + sal_Int32 rowTopLeft = accessibleTable -> getAccessibleRow ( idxTopLeft ); + sal_Int32 columnTopLeft = accessibleTable -> getAccessibleColumn ( idxTopLeft ); + sal_Int32 rowBottomRight = accessibleTable -> getAccessibleRow ( idxBottomRight ); + sal_Int32 columnBottomRight = accessibleTable -> getAccessibleColumn ( idxBottomRight ); + // create an array containing the visible cells + for ( sal_Int32 rowCount = rowTopLeft; rowCount <= rowBottomRight; rowCount++ ) + { + for ( sal_Int32 columnCount = columnTopLeft; columnCount <= columnBottomRight; columnCount++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( rowCount, columnCount ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + } + } + } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + } + [cells autorelease]; + } + + return pResult; +} + ++(void)addAttributeNamesTo: (NSMutableArray *)attributeNames object: (AquaA11yWrapper*)pObject +{ + XAccessibleTable * accessibleTable = [ pObject accessibleTable ]; + if( accessibleTable ) + { + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + + + if( nRows*nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + [ attributeNames addObject: NSAccessibilityRowsAttribute ]; + [ attributeNames addObject: NSAccessibilityColumnsAttribute ]; + } + } +} + +-(id)rowsAttribute +{ + NSArray* pResult = nil; + + XAccessibleTable * accessibleTable = [ self accessibleTable ]; + if( accessibleTable ) + { + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; + try + { + // find out number of rows + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + for( sal_Int32 n = 0; n < nRows; n++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( n, 0 ); if ( rAccessibleCell.is() ) { id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; @@ -74,16 +156,56 @@ using namespace ::com::sun::star::uno; [ cell_wrapper release ]; } } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + pResult = nil; } + [ cells autorelease ]; } - [ cells autorelease ]; - return NSAccessibilityUnignoredChildren( cells ); } - catch (const Exception &e) + + return pResult; +} + +-(id)columnsAttribute +{ + NSArray* pResult = nil; + + XAccessibleTable * accessibleTable = [ self accessibleTable ]; + + if( accessibleTable ) { - // TODO: Log - return nil; + sal_Int32 nRows = accessibleTable->getAccessibleRowCount(); + sal_Int32 nCols = accessibleTable->getAccessibleColumnCount(); + if( nRows * nCols < MAXIMUM_ACCESSIBLE_TABLE_CELLS ) + { + NSMutableArray * cells = [ [ NSMutableArray alloc ] init ]; + try + { + // find out number of columns + for( sal_Int32 n = 0; n < nCols; n++ ) + { + Reference < XAccessible > rAccessibleCell = accessibleTable -> getAccessibleCellAt ( 0, n ); + if ( rAccessibleCell.is() ) + { + id cell_wrapper = [ AquaA11yFactory wrapperForAccessibleContext: rAccessibleCell -> getAccessibleContext() ]; + [ cells addObject: cell_wrapper ]; + [ cell_wrapper release ]; + } + } + pResult = NSAccessibilityUnignoredChildren( cells ); + } + catch (const Exception &e) + { + pResult = nil; + } + [ cells autorelease ]; + } } + + return pResult; } @end diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm b/vcl/aqua/source/a11y/aqua11ywrapper.mm index 959746d533dc..e86676e725f2 100644 --- a/vcl/aqua/source/a11y/aqua11ywrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm @@ -29,6 +29,8 @@ #include "precompiled_vcl.hxx" #include "salinst.h" +#include "saldata.hxx" + #include "aqua11ywrapper.h" #include "aqua11yactionwrapper.h" #include "aqua11ycomponentwrapper.h" @@ -41,6 +43,7 @@ #include "aqua11yfocuslistener.hxx" #include "aqua11yfocustracker.hxx" #include "aqua11yrolehelper.h" + #include <com/sun/star/accessibility/AccessibleRole.hpp> #include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> @@ -217,7 +220,8 @@ static MacOSBOOL isPopupMenuOpen = NO; -(id)roleAttribute { if ( mActsAsRadioGroup ) { return NSAccessibilityRadioGroupRole; - } else { + } + else { return [ AquaA11yRoleHelper getNativeRoleFrom: [ self accessibleContext ] ]; } } @@ -323,8 +327,10 @@ static MacOSBOOL isPopupMenuOpen = NO; } } return children; - } else if ( [ self accessibleTable ] != nil ) { - return [ AquaA11yTableWrapper childrenAttributeForElement: self ]; + } else if ( [ self accessibleTable ] != nil ) + { + AquaA11yTableWrapper* pTable = [self isKindOfClass: [AquaA11yTableWrapper class]] ? (AquaA11yTableWrapper*)self : nil; + return [ AquaA11yTableWrapper childrenAttributeForElement: pTable ]; } else { try { NSMutableArray * children = [ [ NSMutableArray alloc ] init ]; @@ -663,6 +669,7 @@ static MacOSBOOL isPopupMenuOpen = NO; if ( isPopupMenuOpen ) { return nil; } + id value = nil; // if we are no longer in the wrapper repository, we have been disposed AquaA11yWrapper * theWrapper = [ AquaA11yFactory wrapperForAccessibleContext: [ self accessibleContext ] createIfNotExists: NO ]; @@ -717,6 +724,7 @@ static MacOSBOOL isPopupMenuOpen = NO; NSString * nativeSubrole = nil; NSString * title = nil; NSMutableArray * attributeNames = nil; + sal_Int32 nAccessibleChildren = 0; try { // Default Attributes attributeNames = [ NSMutableArray arrayWithObjects: @@ -737,8 +745,9 @@ static MacOSBOOL isPopupMenuOpen = NO; } try { - if ( [ self accessibleContext ] -> getAccessibleChildCount() > 0 ) { - [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; + nAccessibleChildren = [ self accessibleContext ] -> getAccessibleChildCount(); + if ( nAccessibleChildren > 0 ) { + [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; } } catch( DisposedException& ) {} @@ -754,6 +763,9 @@ static MacOSBOOL isPopupMenuOpen = NO; [ attributeNames addObject: NSAccessibilityServesAsTitleForUIElementsAttribute ]; } // Special Attributes depending on interface + if( [self accessibleContext ] -> getAccessibleRole() == AccessibleRole::TABLE ) + [AquaA11yTableWrapper addAttributeNamesTo: attributeNames object: self]; + if ( [ self accessibleText ] != nil ) { [ AquaA11yTextWrapper addAttributeNamesTo: attributeNames ]; } @@ -953,14 +965,15 @@ static MacOSBOOL isPopupMenuOpen = NO; return hit; } -Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAccessibleContext > rxAccessibleContext ) { +Reference < XAccessibleContext > hitTestRunner ( com::sun::star::awt::Point point, + Reference < XAccessibleContext > rxAccessibleContext ) { Reference < XAccessibleContext > hitChild; Reference < XAccessibleContext > emptyReference; try { Reference < XAccessibleComponent > rxAccessibleComponent ( rxAccessibleContext, UNO_QUERY ); if ( rxAccessibleComponent.is() ) { - Point location = rxAccessibleComponent -> getLocationOnScreen(); - Point hitPoint ( point.X - location.X , point.Y - location.Y); + com::sun::star::awt::Point location = rxAccessibleComponent -> getLocationOnScreen(); + com::sun::star::awt::Point hitPoint ( point.X - location.X , point.Y - location.Y); Reference < XAccessible > rxAccessible = rxAccessibleComponent -> getAccessibleAtPoint ( hitPoint ); if ( rxAccessible.is() && rxAccessible -> getAccessibleContext().is() ) { if ( rxAccessible -> getAccessibleContext() -> getAccessibleChildCount() > 0 ) { @@ -999,7 +1012,7 @@ Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAcces } Reference < XAccessibleContext > hitChild; NSRect screenRect = [ [ NSScreen mainScreen ] frame ]; - Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); + com::sun::star::awt::Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); // check child windows first NSWindow * window = (NSWindow *) [ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ]; NSArray * childWindows = [ window childWindows ]; diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index 62c59e78c963..b8a2261ed9db 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -474,6 +474,7 @@ AquaSalInstance::AquaSalInstance() mbWaitingYield = false; maUserEventListMutex = osl_createMutex(); mnActivePrintJobs = 0; + maWaitingYieldCond = osl_createCondition(); } // ----------------------------------------------------------------------- @@ -484,6 +485,7 @@ AquaSalInstance::~AquaSalInstance() mpSalYieldMutex->release(); delete mpSalYieldMutex; osl_destroyMutex( maUserEventListMutex ); + osl_destroyCondition( maWaitingYieldCond ); } // ----------------------------------------------------------------------- @@ -713,6 +715,7 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( aEvent.mpFrame && AquaSalFrame::isAlive( aEvent.mpFrame ) ) { aEvent.mpFrame->CallCallback( aEvent.mnType, aEvent.mpData ); + osl_setCondition( maWaitingYieldCond ); // return if only one event is asked for if( ! bHandleAllCurrentEvents ) return; @@ -785,6 +788,18 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) (*it)->maInvalidRect.SetEmpty(); } } + osl_setCondition( maWaitingYieldCond ); + } + else if( bWait ) + { + // #i103162# + // wait until any thread (most likely the main thread) + // has dispatched an event, cop out at 200 ms + osl_resetCondition( maWaitingYieldCond ); + TimeValue aVal = { 0, 200000000 }; + ULONG nCount = ReleaseYieldMutex(); + osl_waitCondition( maWaitingYieldCond, &aVal ); + AcquireYieldMutex( nCount ); } // we get some apple events way too early diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index 38fb068bb353..1ef370f43a92 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -694,6 +694,13 @@ void AquaSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) { + if( nX1 == nX2 && nY1 == nY2 ) + { + // #i109453# platform independent code expects at least one pixel to be drawn + drawPixel( nX1, nY1 ); + return; + } + if( !CheckContext() ) return; diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx index 71c84ee0c2f1..0fd028864bf4 100644 --- a/vcl/aqua/source/window/salframe.cxx +++ b/vcl/aqua/source/window/salframe.cxx @@ -1128,6 +1128,16 @@ static Font getFont( NSFont* pFont, long nDPIY, const Font& rDefault ) return aResult; } +void AquaSalFrame::getResolution( long& o_rDPIX, long& o_rDPIY ) +{ + if( ! mpGraphics ) + { + GetGraphics(); + ReleaseGraphics( mpGraphics ); + } + mpGraphics->GetResolution( o_rDPIX, o_rDPIY ); +} + // on OSX-Aqua the style settings are independent of the frame, so it does // not really belong here. Since the connection to the Appearance_Manager // is currently done in salnativewidgets.cxx this would be a good place. @@ -1157,13 +1167,8 @@ void AquaSalFrame::UpdateSettings( AllSettings& rSettings ) // get the system font settings Font aAppFont = aStyleSettings.GetAppFont(); - if( ! mpGraphics ) - { - GetGraphics(); - ReleaseGraphics( mpGraphics ); - } long nDPIX = 72, nDPIY = 72; - mpGraphics->GetResolution( nDPIX, nDPIY ); + getResolution( nDPIX, nDPIY ); aAppFont = getFont( [NSFont systemFontOfSize: 0], nDPIY, aAppFont ); // TODO: better mapping of aqua<->ooo font settings diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm index 67926a38608d..0dfa0fa356aa 100755 --- a/vcl/aqua/source/window/salframeview.mm +++ b/vcl/aqua/source/window/salframeview.mm @@ -37,7 +37,9 @@ #include "vcl/window.hxx" #include "vcl/svapp.hxx" - + +#define WHEEL_EVENT_FACTOR 1.5 + static USHORT ImplGetModifierMask( unsigned int nMask ) { USHORT nRet = 0; @@ -654,11 +656,12 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); - aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -667,11 +670,11 @@ private: if( dZ != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dZ)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dZ < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dZ < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; + aEvent.mnScrollLines = dZ > 0 ? dZ/WHEEL_EVENT_FACTOR : -dZ/WHEEL_EVENT_FACTOR; if( aEvent.mnScrollLines == 0 ) aEvent.mnScrollLines = 1; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -712,10 +715,11 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -724,9 +728,9 @@ private: if( dX != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dX)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dX < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = TRUE; aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -734,9 +738,9 @@ private: if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame )) { aEvent.mnDelta = static_cast<long>(floor(dY)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dY < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); @@ -771,10 +775,11 @@ private: mpFrame->CocoaToVCL( aPt ); SalWheelMouseEvent aEvent; - aEvent.mnTime = mpFrame->mnLastEventTime; - aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; - aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; - aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mnTime = mpFrame->mnLastEventTime; + aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; + aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; + aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); + aEvent.mbDeltaIsPixel = TRUE; // --- RTL --- (mirror mouse pos) if( Application::GetSettings().GetLayoutRTL() ) @@ -783,30 +788,27 @@ private: if( dX != 0.0 ) { aEvent.mnDelta = static_cast<long>(floor(dX)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dX < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = TRUE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; + aEvent.mnScrollLines = dY > 0 ? dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR; if( aEvent.mnScrollLines == 0 ) aEvent.mnScrollLines = 1; - if( aEvent.mnScrollLines > 15 ) - aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); } if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) { aEvent.mnDelta = static_cast<long>(floor(dY)); - aEvent.mnNotchDelta = aEvent.mnDelta / 8; - if( aEvent.mnNotchDelta == 0 ) - aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1; + aEvent.mnNotchDelta = dY < 0 ? -1 : 1; + if( aEvent.mnDelta == 0 ) + aEvent.mnDelta = aEvent.mnNotchDelta; aEvent.mbHorz = FALSE; - aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta; - if( aEvent.mnScrollLines == 0 ) + aEvent.mnScrollLines = dY > 0 ? dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR; + if( aEvent.mnScrollLines < 1 ) aEvent.mnScrollLines = 1; - if( aEvent.mnScrollLines > 15 ) - aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; - + mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); } } diff --git a/vcl/inc/vcl/button.hxx b/vcl/inc/vcl/button.hxx index 317a98026f45..8f4b94bf7b18 100644 --- a/vcl/inc/vcl/button.hxx +++ b/vcl/inc/vcl/button.hxx @@ -60,7 +60,7 @@ public: SAL_DLLPRIVATE USHORT ImplGetTextStyle( XubString& rText, WinBits nWinStyle, ULONG nDrawFlags ); SAL_DLLPRIVATE void ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos, Size& rSize, BOOL bLayout, ULONG nImageSep, ULONG nDrawFlags, - USHORT nTextStyle, Rectangle *pSymbolRect=NULL ); + USHORT nTextStyle, Rectangle *pSymbolRect=NULL, bool bAddImageSep = false ); SAL_DLLPRIVATE void ImplSetFocusRect( const Rectangle &rFocusRect ); SAL_DLLPRIVATE const Rectangle& ImplGetFocusRect() const; SAL_DLLPRIVATE void ImplSetSymbolAlign( SymbolAlign eAlign ); diff --git a/vcl/inc/vcl/cmdevt.hxx b/vcl/inc/vcl/cmdevt.hxx index 0faac8472253..7e968b6c7a54 100644 --- a/vcl/inc/vcl/cmdevt.hxx +++ b/vcl/inc/vcl/cmdevt.hxx @@ -138,18 +138,20 @@ private: USHORT mnMode; USHORT mnCode; BOOL mbHorz; + BOOL mbDeltaIsPixel; public: CommandWheelData(); CommandWheelData( long nWheelDelta, long nWheelNotchDelta, ULONG nScrollLines, USHORT nWheelMode, USHORT nKeyModifier, - BOOL mbHorz = FALSE ); + BOOL bHorz = FALSE, BOOL bDeltaIsPixel = FALSE ); long GetDelta() const { return mnDelta; } long GetNotchDelta() const { return mnNotchDelta; } ULONG GetScrollLines() const { return mnLines; } BOOL IsHorz() const { return mbHorz; } + BOOL IsDeltaPixel() const { return mbDeltaIsPixel; } USHORT GetMode() const { return mnMode; } @@ -173,12 +175,13 @@ inline CommandWheelData::CommandWheelData() mnMode = 0; mnCode = 0; mbHorz = FALSE; + mbDeltaIsPixel = FALSE; } inline CommandWheelData::CommandWheelData( long nWheelDelta, long nWheelNotchDelta, ULONG nScrollLines, USHORT nWheelMode, USHORT nKeyModifier, - BOOL bHorz ) + BOOL bHorz, BOOL bDeltaIsPixel ) { mnDelta = nWheelDelta; mnNotchDelta = nWheelNotchDelta; @@ -186,6 +189,7 @@ inline CommandWheelData::CommandWheelData( long nWheelDelta, long nWheelNotchDel mnMode = nWheelMode; mnCode = nKeyModifier; mbHorz = bHorz; + mbDeltaIsPixel = bDeltaIsPixel; } // --------------------- diff --git a/vcl/inc/vcl/glyphcache.hxx b/vcl/inc/vcl/glyphcache.hxx index fa3e99f2373f..a77c1626dc24 100644 --- a/vcl/inc/vcl/glyphcache.hxx +++ b/vcl/inc/vcl/glyphcache.hxx @@ -51,6 +51,7 @@ class RawBitmap; class CmapResult; #include <vcl/outfont.hxx> +#include <vcl/impfont.hxx> class ServerFontLayout; #include <vcl/sallayout.hxx> @@ -258,11 +259,15 @@ class VCL_DLLPUBLIC ImplServerFontEntry : public ImplFontEntry { private: ServerFont* mpServerFont; + ImplFontOptions maFontOptions; + bool mbGotFontOptions; + bool mbValidFontOptions; public: ImplServerFontEntry( ImplFontSelectData& ); virtual ~ImplServerFontEntry(); void SetServerFont( ServerFont* p) { mpServerFont = p; } + void HandleFontOptions(); }; // ======================================================================= diff --git a/vcl/inc/vcl/outfont.hxx b/vcl/inc/vcl/outfont.hxx index 995fcd6009ff..4bbf7176ddb2 100644 --- a/vcl/inc/vcl/outfont.hxx +++ b/vcl/inc/vcl/outfont.hxx @@ -39,6 +39,8 @@ #include <hash_map> +#include <com/sun/star/linguistic2/XLinguServiceManager.hpp> + class ImplDevFontListData; class ImplGetDevFontList; class ImplGetDevSizeList; @@ -186,6 +188,7 @@ public: // TODO: change to private class VCL_DLLPUBLIC ImplDevFontList { private: + friend class WinGlyphFallbackSubstititution; mutable bool mbMatchData; // true if matching attributes are initialized bool mbMapNames; // true if MapNames are available @@ -222,6 +225,9 @@ public: ImplGetDevFontList* GetDevFontList() const; ImplGetDevSizeList* GetDevSizeList( const String& rFontName ) const; + //used by 2-level font fallback + ImplDevFontListData* ImplFindByLocale(com::sun::star::lang::Locale lc) const; + protected: void InitMatchData() const; bool AreMapNamesAvailable() const { return mbMapNames; } diff --git a/vcl/inc/vcl/salwtype.hxx b/vcl/inc/vcl/salwtype.hxx index c67d36ac4ea9..95b3806d648b 100644 --- a/vcl/inc/vcl/salwtype.hxx +++ b/vcl/inc/vcl/salwtype.hxx @@ -180,6 +180,11 @@ struct SalWheelMouseEvent ULONG mnScrollLines; // Aktuelle Anzahl zu scrollende Zeilen USHORT mnCode; // SV-ModifierCode (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT) BOOL mbHorz; // Horizontal + BOOL mbDeltaIsPixel; // delta value is a pixel value (on mac) + + SalWheelMouseEvent() + : mnTime( 0 ), mnX( 0 ), mnY( 0 ), mnDelta( 0 ), mnNotchDelta( 0 ), mnScrollLines( 0 ), mnCode( 0 ), mbHorz( FALSE ), mbDeltaIsPixel( FALSE ) + {} }; // MOUSEACTIVATE diff --git a/vcl/os2/source/window/salframe.cxx b/vcl/os2/source/window/salframe.cxx index 7ecc27ff9754..f3314c725255 100644 --- a/vcl/os2/source/window/salframe.cxx +++ b/vcl/os2/source/window/salframe.cxx @@ -3032,10 +3032,8 @@ static void ImplHandleMoveMsg( HWND hWnd) // ----------------------------------------------------------------------- -static long ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 ) +static void ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 ) { - long nRet; - Os2SalFrame* pFrame = GetWindowPtr( hWnd ); if ( pFrame ) { @@ -3047,11 +3045,10 @@ static long ImplHandleSizeMsg( HWND hWnd, MPARAM nMP2 ) pFrame->mpGraphics->mnHeight = (int)SHORT2FROMMP(nMP2); // Status merken ImplSaveFrameState( pFrame ); - nRet = pFrame->CallCallback( SALEVENT_RESIZE, 0 ); + pFrame->CallCallback( SALEVENT_RESIZE, 0 ); if ( WinIsWindowVisible( pFrame->mhWndFrame ) && !pFrame->mbInShow ) WinUpdateWindow( pFrame->mhWndClient ); } - return nRet; } // ----------------------------------------------------------------------- diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index 5ad3f6787461..980e0f1c5b58 100755 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -188,7 +188,7 @@ ImplMouseData::ImplMouseData() mnActionDelay = 250; mnMenuDelay = 150; mnFollow = MOUSE_FOLLOW_MENU | MOUSE_FOLLOW_DDLIST; - mnWheelBehavior = MOUSE_WHEEL_FOCUS_ONLY; + mnWheelBehavior = MOUSE_WHEEL_ALWAYS; } // ----------------------------------------------------------------------- diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx index 1f45b5902381..08759f37d7a6 100644 --- a/vcl/source/control/button.cxx +++ b/vcl/source/control/button.cxx @@ -367,7 +367,8 @@ USHORT Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle, void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos, Size& rSize, BOOL bLayout, ULONG nImageSep, ULONG nDrawFlags, - USHORT nTextStyle, Rectangle *pSymbolRect ) + USHORT nTextStyle, Rectangle *pSymbolRect, + bool bAddImageSep ) { XubString aText( GetText() ); BOOL bDrawImage = HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE ); @@ -502,6 +503,13 @@ void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos, if ( aTSSize.Height() < aTextSize.Height() ) aTSSize.Height() = aTextSize.Height(); + + if( bAddImageSep && bDrawImage ) + { + long nDiff = (aImageSize.Height() - aTextSize.Height()) / 3; + if( nDiff > 0 ) + nImageSep += nDiff; + } } aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width(); @@ -880,7 +888,9 @@ void PushButton::ImplInitSettings( BOOL bFont, EnableChildTransparentMode( TRUE ); SetParentClipMode( PARENTCLIPMODE_NOCLIP ); SetPaintTransparent( TRUE ); - mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects; + mpWindowImpl->mbUseNativeFocus = (GetStyle() & WB_FLATBUTTON) + ? false + : ImplGetSVData()->maNWFData.mbNoFocusRects; } else { @@ -1194,8 +1204,10 @@ void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags 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 ); + nTextStyle, IsSymbol() ? &aSymbolRect : NULL, (GetStyle() & WB_FLATBUTTON) != 0 ); if ( IsSymbol() && ! bLayout ) { @@ -1363,7 +1375,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); aPBVal.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); - if( ((nState & CTRL_STATE_ROLLOVER) || HasFocus()) || ! (GetStyle() & WB_FLATBUTTON) ) + if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) ) { bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); @@ -1388,7 +1400,7 @@ void PushButton::ImplDrawPushButton( bool bLayout ) if( (GetStyle() & WB_FLATBUTTON) ) { Rectangle aTempRect( aInRect ); - if( ! bLayout && (bRollOver || HasFocus()) ) + if( ! bLayout && bRollOver ) ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle ); aInRect.Left() += 2; aInRect.Top() += 2; @@ -1879,7 +1891,8 @@ long PushButton::PreNotify( NotifyEvent& rNEvt ) pBorder->Update(); } } - else if( IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) ) + else if( (GetStyle() & WB_FLATBUTTON) || + IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) ) { Invalidate(); } diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx index 741267044829..89fbe6d3db78 100644 --- a/vcl/source/control/tabctrl.cxx +++ b/vcl/source/control/tabctrl.cxx @@ -1156,8 +1156,6 @@ void TabControl::MouseButtonDown( const MouseEvent& rMEvt ) ImplTabItem* pItem = ImplGetItem( nPageId ); if( pItem && pItem->mbEnabled ) SelectTabPage( nPageId ); - else - Sound::Beep( SOUND_ERROR, this ); } } } diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx index 9884e7016fee..620ca64f44d9 100644 --- a/vcl/source/fontsubset/cff.cxx +++ b/vcl/source/fontsubset/cff.cxx @@ -33,6 +33,7 @@ #include <assert.h> #include <vcl/fontsubset.hxx> +#include <vcl/strhelper.hxx> //#define IGNORE_HINTS @@ -2027,6 +2028,17 @@ void Type1Emitter::emitAllCrypted( void) // -------------------------------------------------------------------- +// #i110387# quick-and-dirty double->ascii conversion +// needed because sprintf/ecvt/etc. alone are too localized (LC_NUMERIC) +// also strip off trailing zeros in fraction while we are at it +inline int dbl2str( char* pOut, double fVal, int nPrecision=6) +{ + const int nLen = psp::getValueOfDouble( pOut, fVal, nPrecision); + return nLen; +} + +// -------------------------------------------------------------------- + void Type1Emitter::emitValVector( const char* pLineHead, const char* pLineTail, const ValVector& rVector) { @@ -2042,10 +2054,11 @@ void Type1Emitter::emitValVector( const char* pLineHead, const char* pLineTail, aVal = *it; if( ++it == rVector.end() ) break; - mpPtr += sprintf( mpPtr, "%g ", aVal); + mpPtr += dbl2str( mpPtr, aVal); + *(mpPtr++) = ' '; } // emit the last value - mpPtr += sprintf( mpPtr, "%g", aVal); + mpPtr += dbl2str( mpPtr, aVal); // emit the line tail mpPtr += sprintf( mpPtr, pLineTail); } @@ -2202,18 +2215,33 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, rEmitter.emitValVector( "/FamilyBlues [", "]ND\n", mpCffLocal->maFamilyBlues); rEmitter.emitValVector( "/FamilyOtherBlues [", "]ND\n", mpCffLocal->maFamilyOtherBlues); - if( mpCffLocal->mfBlueScale) - pOut += sprintf( pOut, "/BlueScale %.6f def\n", mpCffLocal->mfBlueScale); - if( mpCffLocal->mfBlueShift) // default BlueShift==7 - pOut += sprintf( pOut, "/BlueShift %.1f def\n", mpCffLocal->mfBlueShift); - if( mpCffLocal->mfBlueFuzz) // default BlueFuzz==1 - pOut += sprintf( pOut, "/BlueFuzz %.1f def\n", mpCffLocal->mfBlueFuzz); + if( mpCffLocal->mfBlueScale) { + pOut += sprintf( pOut, "/BlueScale "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueScale, 6); + pOut += sprintf( pOut, " def\n"); + } + if( mpCffLocal->mfBlueShift) { // default BlueShift==7 + pOut += sprintf( pOut, "/BlueShift "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueShift); + pOut += sprintf( pOut, " def\n"); + } + if( mpCffLocal->mfBlueFuzz) { // default BlueFuzz==1 + pOut += sprintf( pOut, "/BlueFuzz "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueFuzz); + pOut += sprintf( pOut, " def\n"); + } // emit stem hint related privdict entries - if( mpCffLocal->maStemStdHW) - pOut += sprintf( pOut, "/StdHW [%g] def\n", mpCffLocal->maStemStdHW); - if( mpCffLocal->maStemStdVW) - pOut += sprintf( pOut, "/StdVW [%g] def\n", mpCffLocal->maStemStdVW); + if( mpCffLocal->maStemStdHW) { + pOut += sprintf( pOut, "/StdHW ["); + pOut += dbl2str( pOut, mpCffLocal->maStemStdHW); + pOut += sprintf( pOut, "] def\n"); + } + if( mpCffLocal->maStemStdVW) { + pOut += sprintf( pOut, "/StdVW ["); + pOut += dbl2str( pOut, mpCffLocal->maStemStdVW); + pOut += sprintf( pOut, "] def\n"); + } rEmitter.emitValVector( "/StemSnapH [", "]ND\n", mpCffLocal->maStemSnapH); rEmitter.emitValVector( "/StemSnapV [", "]ND\n", mpCffLocal->maStemSnapV); @@ -2224,8 +2252,11 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, pOut += sprintf( pOut, "/LanguageGroup %d def\n", mpCffLocal->mnLangGroup); if( mpCffLocal->mnLangGroup == 1) // compatibility with ancient printers pOut += sprintf( pOut, "/RndStemUp false def\n"); - if( mpCffLocal->mfExpFactor) - pOut += sprintf( pOut, "/ExpansionFactor %.2f def\n", mpCffLocal->mfExpFactor); + if( mpCffLocal->mfExpFactor) { + pOut += sprintf( pOut, "/ExpansionFactor "); + pOut += dbl2str( pOut, mpCffLocal->mfExpFactor); + pOut += sprintf( pOut, " def\n"); + } #endif // IGNORE_HINTS // emit remaining privdict entries @@ -2248,6 +2279,7 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, // emit used GlobalSubr charstrings // these are the just the default subrs + // TODO: do we need them as the flex hints are resolved differently? static const char aSubrs[] = "/Subrs 5 array\n" "dup 0 15 RD \x5F\x3D\x6B\xAC\x3C\xBD\x74\x3D\x3E\x17\xA0\x86\x58\x08\x85 NP\n" diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx index 51c76b5a4626..074935086b0b 100644 --- a/vcl/source/gdi/bitmap.cxx +++ b/vcl/source/gdi/bitmap.cxx @@ -323,7 +323,23 @@ BOOL Bitmap::HasGreyPalette() const BOOL bRet = FALSE; if( 1 == nBitCount ) - bRet = TRUE; + { + BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess(); + + if( pRAcc ) + { + const BitmapColor& rCol0( pRAcc->GetPaletteColor( 0 ) ); + const BitmapColor& rCol1( pRAcc->GetPaletteColor( 1 ) ); + if( rCol0.GetRed() == rCol0.GetGreen() && rCol0.GetRed() == rCol0.GetBlue() && + rCol1.GetRed() == rCol1.GetGreen() && rCol1.GetRed() == rCol1.GetBlue() ) + { + bRet = TRUE; + } + ( (Bitmap*) this )->ReleaseAccess( pRAcc ); + } + else + bRet = TRUE; + } else if( 4 == nBitCount || 8 == nBitCount ) { BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess(); diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 630e58a1f2bf..f4fcba72b0c2 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -1672,6 +1672,18 @@ void ImplDevFontList::InitMatchData() const } } +//---------------------------------------------------------------------------- +ImplDevFontListData* ImplDevFontList::ImplFindByLocale(com::sun::star::lang::Locale lc) const +{ + // get the default font for a specified locale + const DefaultFontConfiguration& rDefaults = *DefaultFontConfiguration::get(); + String aDefault = rDefaults.getUserInterfaceFont( lc ); + ImplDevFontListData* pFontData = ImplFindByTokenNames( aDefault ); + if( pFontData ) + return pFontData; + return 0; +} + // ----------------------------------------------------------------------- ImplDevFontListData* ImplDevFontList::ImplFindByAttributes( ULONG nSearchType, diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 6a24775219d9..7ee5889ba532 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -11733,7 +11733,7 @@ sal_Int32 PDFWriterImpl::findRadioGroupWidget( const PDFWriter::RadioButtonWidge m_aWidgets.back().m_nPage = m_nCurrentPage; m_aWidgets.back().m_eType = PDFWriter::RadioButton; m_aWidgets.back().m_nRadioGroup = rBtn.RadioGroup; - m_aWidgets.back().m_nFlags |= 0x00008000; + m_aWidgets.back().m_nFlags |= 0x0000C000; // NoToggleToOff and Radio bits createWidgetFieldName( sal_Int32(m_aWidgets.size()-1), rBtn ); } diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index bf462d1d8add..80ae3a3a8c7f 100755 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -1800,8 +1800,8 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) int nRunStart, nRunEnd; while (rArgs.GetNextRun(&nRunStart, &nRunEnd, &bRtl)) { - if (bRtl) std::fill(vRtl.begin() + nRunStart - rArgs.mnMinCharPos, - vRtl.begin() + nRunEnd - rArgs.mnMinCharPos, true); + if (bRtl) std::fill(vRtl.begin() + ( nRunStart - rArgs.mnMinCharPos ), + vRtl.begin() + ( nRunEnd - rArgs.mnMinCharPos ), true); } rArgs.ResetPos(); diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx index ea0f18896b7a..1953ecf553c4 100644 --- a/vcl/source/glyphs/glyphcache.cxx +++ b/vcl/source/glyphs/glyphcache.cxx @@ -519,8 +519,10 @@ bool ServerFont::IsGlyphInvisible( int nGlyphIndex ) // ======================================================================= ImplServerFontEntry::ImplServerFontEntry( ImplFontSelectData& rFSD ) -: ImplFontEntry( rFSD ), - mpServerFont( NULL ) +: ImplFontEntry( rFSD ) +, mpServerFont( NULL ) +, mbGotFontOptions( false ) +, mbValidFontOptions( false ) {} // ----------------------------------------------------------------------- diff --git a/vcl/source/src/print.src b/vcl/source/src/print.src index 3158926f5e6d..58f0a477c848 100644 --- a/vcl/source/src/print.src +++ b/vcl/source/src/print.src @@ -356,7 +356,7 @@ ModalDialog SV_DLG_PRINT { Pos = MAP_APPFONT( 5, 35 ); Size = MAP_APPFONT( 150, 10 ); - Text [en-US] = "Range and Copies"; + Text [en-US] = "Range and copies"; }; FixedText SV_PRINT_COPYCOUNT { diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index 33e58b51d6d0..35077b1cff0e 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -647,7 +647,7 @@ void PrintDialog::JobTabPage::setupLayout() // add printer fixed line maLayout.addWindow( &maPrinterFL ); // add print LB - maLayout.addWindow( &maPrinters ); + maLayout.addWindow( &maPrinters, 3 ); // create a row for details button/text and properties button boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( &maLayout, false ) ); diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx index 95ac5940b6d2..7b0512a1320b 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -1474,6 +1474,7 @@ static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEv USHORT nMode; USHORT nCode = rEvt.mnCode; bool bHorz = rEvt.mbHorz; + bool bPixel = rEvt.mbDeltaIsPixel; if ( nCode & KEY_MOD1 ) nMode = COMMAND_WHEEL_ZOOM; else if ( nCode & KEY_MOD2 ) @@ -1486,7 +1487,7 @@ static long ImplHandleWheelEvent( Window* pWindow, const SalWheelMouseEvent& rEv bHorz = true; } - CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz ); + CommandWheelData aWheelData( rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel ); Point aMousePos( rEvt.mnX, rEvt.mnY ); BOOL bRet = TRUE; diff --git a/vcl/unx/gtk/a11y/atkbridge.cxx b/vcl/unx/gtk/a11y/atkbridge.cxx index 47efde7d3dfd..25add8e0dd18 100644 --- a/vcl/unx/gtk/a11y/atkbridge.cxx +++ b/vcl/unx/gtk/a11y/atkbridge.cxx @@ -40,10 +40,7 @@ bool InitAtkBridge(void) { const char* pVersion = atk_get_toolkit_version(); if( ! pVersion ) - { - // g_warning( "unable to get gail version number" ); return false; - } unsigned int major, minor, micro; diff --git a/vcl/unx/gtk/a11y/atktext.cxx b/vcl/unx/gtk/a11y/atktext.cxx index f346a6a5a02c..e6d3276891de 100644 --- a/vcl/unx/gtk/a11y/atktext.cxx +++ b/vcl/unx/gtk/a11y/atktext.cxx @@ -454,6 +454,84 @@ text_wrapper_set_caret_offset (AtkText *text, return FALSE; } +// --> OD 2010-03-04 #i92232# +AtkAttributeSet* +handle_text_markup_as_run_attribute( accessibility::XAccessibleTextMarkup* pTextMarkup, + const gint nTextMarkupType, + const gint offset, + AtkAttributeSet* pSet, + gint *start_offset, + gint *end_offset ) +{ + const gint nTextMarkupCount( pTextMarkup->getTextMarkupCount( nTextMarkupType ) ); + if ( nTextMarkupCount > 0 ) + { + for ( gint nTextMarkupIndex = 0; + nTextMarkupIndex < nTextMarkupCount; + ++nTextMarkupIndex ) + { + accessibility::TextSegment aTextSegment = + pTextMarkup->getTextMarkup( nTextMarkupIndex, nTextMarkupType ); + const gint nStartOffsetTextMarkup = aTextSegment.SegmentStart; + const gint nEndOffsetTextMarkup = aTextSegment.SegmentEnd; + if ( nStartOffsetTextMarkup <= offset ) + { + if ( offset < nEndOffsetTextMarkup ) + { + // text markup at <offset> + *start_offset = ::std::max( *start_offset, + nStartOffsetTextMarkup ); + *end_offset = ::std::min( *end_offset, + nEndOffsetTextMarkup ); + switch ( nTextMarkupType ) + { + case com::sun::star::text::TextMarkupType::SPELLCHECK: + { + pSet = attribute_set_prepend_misspelled( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_INSERTION: + { + pSet = attribute_set_prepend_tracked_change_insertion( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_DELETION: + { + pSet = attribute_set_prepend_tracked_change_deletion( pSet ); + } + break; + case com::sun::star::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE: + { + pSet = attribute_set_prepend_tracked_change_formatchange( pSet ); + } + break; + default: + { + OSL_ASSERT( false ); + } + } + break; // no further iteration needed. + } + else + { + *start_offset = ::std::max( *start_offset, + nEndOffsetTextMarkup ); + // continue iteration. + } + } + else + { + *end_offset = ::std::min( *end_offset, + nStartOffsetTextMarkup ); + break; // no further iteration. + } + } // eof iteration over text markups + } + + return pSet; +} +// <-- + static AtkAttributeSet * text_wrapper_get_run_attributes( AtkText *text, gint offset, @@ -491,41 +569,41 @@ text_wrapper_get_run_attributes( AtkText *text, } } - // Special handling for missspelled + // Special handling for misspelled text + // --> OD 2010-03-01 #i92232# + // - add special handling for tracked changes and refactor the + // corresponding code for handling misspelled text. accessibility::XAccessibleTextMarkup* pTextMarkup = getTextMarkup( text ); if( pTextMarkup ) { - uno::Sequence< accessibility::TextSegment > aTextSegmentSeq = - pTextMarkup->getTextMarkupAtIndex( offset, com::sun::star::text::TextMarkupType::SPELLCHECK ); - if( aTextSegmentSeq.getLength() > 0 ) + // Get attribute run here if it hasn't been done before + if( !bOffsetsAreValid ) { - accessibility::TextSegment aTextSegment = aTextSegmentSeq[0]; - gint nStartOffsetMisspelled = aTextSegment.SegmentStart; - gint nEndOffsetMisspelled = aTextSegment.SegmentEnd; - - // Get attribute run here if it hasn't been done before - if( !bOffsetsAreValid ) - { - accessibility::TextSegment aAttributeTextSegment = - pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); - *start_offset = aAttributeTextSegment.SegmentStart; - *end_offset = aAttributeTextSegment.SegmentEnd; - } - - if( nEndOffsetMisspelled <= offset ) - *start_offset = ::std::max( *start_offset, nEndOffsetMisspelled ); - else if( nStartOffsetMisspelled <= offset ) - *start_offset = ::std::max( *start_offset, nStartOffsetMisspelled ); - - if( nStartOffsetMisspelled > offset ) - *end_offset = ::std::min( *end_offset, nStartOffsetMisspelled ); - else if( nEndOffsetMisspelled > offset ) - *end_offset = ::std::min( *end_offset, nEndOffsetMisspelled ); - - if( nStartOffsetMisspelled <= offset && nEndOffsetMisspelled > offset ) - pSet = attribute_set_prepend_misspelled( pSet ); + accessibility::TextSegment aAttributeTextSegment = + pText->getTextAtIndex(offset, accessibility::AccessibleTextType::ATTRIBUTE_RUN); + *start_offset = aAttributeTextSegment.SegmentStart; + *end_offset = aAttributeTextSegment.SegmentEnd; } + // handle misspelled text + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::SPELLCHECK, + offset, pSet, start_offset, end_offset ); + // handle tracked changes + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_INSERTION, + offset, pSet, start_offset, end_offset ); + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_DELETION, + offset, pSet, start_offset, end_offset ); + pSet = handle_text_markup_as_run_attribute( + pTextMarkup, + com::sun::star::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE, + offset, pSet, start_offset, end_offset ); } + // <-- } catch(const uno::Exception& e){ diff --git a/vcl/unx/gtk/a11y/atktextattributes.cxx b/vcl/unx/gtk/a11y/atktextattributes.cxx index 02624a9628cf..04498810597f 100644 --- a/vcl/unx/gtk/a11y/atktextattributes.cxx +++ b/vcl/unx/gtk/a11y/atktextattributes.cxx @@ -74,6 +74,12 @@ static AtkTextAttribute atk_text_attribute_tab_stops = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_writing_mode = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_vertical_align = ATK_TEXT_ATTR_INVALID; static AtkTextAttribute atk_text_attribute_misspelled = ATK_TEXT_ATTR_INVALID; +// --> OD 2010-03-01 #i92232# +static AtkTextAttribute atk_text_attribute_tracked_change = ATK_TEXT_ATTR_INVALID; +// <-- +// --> OD 2010-03-05 #i92233# +static AtkTextAttribute atk_text_attribute_mm_to_pixel_ratio = ATK_TEXT_ATTR_INVALID; +// <-- /*****************************************************************************/ @@ -103,6 +109,9 @@ enum ExportedAttribute TEXT_ATTRIBUTE_STRIKETHROUGH, TEXT_ATTRIBUTE_UNDERLINE, TEXT_ATTRIBUTE_WEIGHT, + // --> OD 2010-03-05 #i92233# + TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO, + // <-- TEXT_ATTRIBUTE_JUSTIFICATION, TEXT_ATTRIBUTE_BOTTOM_MARGIN, TEXT_ATTRIBUTE_FIRST_LINE_INDENT, @@ -137,6 +146,9 @@ static const char * ExportedTextAttributes[TEXT_ATTRIBUTE_LAST] = "CharStrikeout", // TEXT_ATTRIBUTE_STRIKETHROUGH "CharUnderline", // TEXT_ATTRIBUTE_UNDERLINE "CharWeight", // TEXT_ATTRIBUTE_WEIGHT + // --> OD 2010-03-05 #i92233# + "MMToPixelRatio", // TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO + // <-- "ParaAdjust", // TEXT_ATTRIBUTE_JUSTIFICATION "ParaBottomMargin", // TEXT_ATTRIBUTE_BOTTOM_MARGIN "ParaFirstLineIndent", // TEXT_ATTRIBUTE_FIRST_LINE_INDENT @@ -1293,6 +1305,14 @@ attribute_set_new_from_property_values( attribute_set = attribute_set_prepend(attribute_set, atk_text_attribute_tab_stops, get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_TAB_STOPS], TabStops2String)); + // --> OD 2010-03-05 #i92233# + if( ATK_TEXT_ATTR_INVALID == atk_text_attribute_mm_to_pixel_ratio ) + atk_text_attribute_mm_to_pixel_ratio = atk_text_attribute_register("mm-to-pixel-ratio"); + + attribute_set = attribute_set_prepend( attribute_set, atk_text_attribute_mm_to_pixel_ratio, + get_value(rAttributeList, aIndexList[TEXT_ATTRIBUTE_MM_TO_PIXEL_RATIO], Float2String)); + // <-- + return attribute_set; } @@ -1308,6 +1328,49 @@ AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_se return attribute_set; } +// --> OD 2010-03-01 #i92232# +AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "insertion" ) ); + + return attribute_set; +} + +AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "deletion" ) ); + + return attribute_set; +} + +AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ) +{ + if ( ATK_TEXT_ATTR_INVALID == atk_text_attribute_tracked_change ) + { + atk_text_attribute_tracked_change = atk_text_attribute_register( "text-tracked-change" ); + } + + attribute_set = attribute_set_prepend( attribute_set, + atk_text_attribute_tracked_change, + g_strdup_printf( "attribute-change" ) ); + + return attribute_set; +} +// <-- /*****************************************************************************/ diff --git a/vcl/unx/gtk/a11y/atktextattributes.hxx b/vcl/unx/gtk/a11y/atktextattributes.hxx index e363460bb578..9c7628bf927e 100644 --- a/vcl/unx/gtk/a11y/atktextattributes.hxx +++ b/vcl/unx/gtk/a11y/atktextattributes.hxx @@ -45,5 +45,10 @@ attribute_set_map_to_property_values( com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rValueList ); AtkAttributeSet* attribute_set_prepend_misspelled( AtkAttributeSet* attribute_set ); +// --> OD 2010-03-01 #i92232# +AtkAttributeSet* attribute_set_prepend_tracked_change_insertion( AtkAttributeSet* attribute_set ); +AtkAttributeSet* attribute_set_prepend_tracked_change_deletion( AtkAttributeSet* attribute_set ); +AtkAttributeSet* attribute_set_prepend_tracked_change_formatchange( AtkAttributeSet* attribute_set ); +// <-- #endif diff --git a/vcl/unx/gtk/a11y/atkwindow.cxx b/vcl/unx/gtk/a11y/atkwindow.cxx index f588c1e345e4..5448235998e8 100644 --- a/vcl/unx/gtk/a11y/atkwindow.cxx +++ b/vcl/unx/gtk/a11y/atkwindow.cxx @@ -143,6 +143,22 @@ ooo_window_wrapper_real_focus_gtk (GtkWidget *, GdkEventFocus *) return FALSE; } +static gboolean ooo_tooltip_map( GtkWidget* pToolTip, gpointer ) +{ + AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); + if( pAccessible ) + atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, TRUE ); + return FALSE; +} + +static gboolean ooo_tooltip_unmap( GtkWidget* pToolTip, gpointer ) +{ + AtkObject* pAccessible = gtk_widget_get_accessible( pToolTip ); + if( pAccessible ) + atk_object_notify_state_change( pAccessible, ATK_STATE_SHOWING, FALSE ); + return FALSE; +} + /*****************************************************************************/ static bool @@ -208,6 +224,16 @@ ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data) g_signal_connect_after( GTK_WIDGET( data ), "focus-out-event", G_CALLBACK (ooo_window_wrapper_real_focus_gtk), NULL); + + if( obj->role == ATK_ROLE_TOOL_TIP ) + { + g_signal_connect_after( GTK_WIDGET( data ), "map-event", + G_CALLBACK (ooo_tooltip_map), + NULL); + g_signal_connect_after( GTK_WIDGET( data ), "unmap-event", + G_CALLBACK (ooo_tooltip_unmap), + NULL); + } } /*****************************************************************************/ diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx index 5beb838c0e82..10f75309708d 100644 --- a/vcl/unx/gtk/a11y/atkwrapper.cxx +++ b/vcl/unx/gtk/a11y/atkwrapper.cxx @@ -283,7 +283,9 @@ static AtkRole mapToAtkRole( sal_Int16 nRole ) ATK_ROLE_RULER, ATK_ROLE_UNKNOWN, // SECTION - registered below ATK_ROLE_UNKNOWN, // TREE_ITEM - registered below - ATK_ROLE_TREE_TABLE + ATK_ROLE_TREE_TABLE, + ATK_ROLE_SCROLL_PANE, // COMMENT - mapped to atk_role_scroll_pane + ATK_ROLE_UNKNOWN // COMMENT_END - mapped to atk_role_unknown }; static bool initialized = false; diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index d1e5c5954352..f63f999738a7 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -800,15 +800,12 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) */ bool bDispatchThread = false; + gboolean wasEvent = FALSE; { // release YieldMutex (and re-acquire at block end) YieldMutexReleaser aReleaser; if( osl_tryToAcquireMutex( m_aDispatchMutex ) ) - { - // we are the dispatch thread - osl_resetCondition( m_aDispatchCondition ); bDispatchThread = true; - } else if( ! bWait ) return; // someone else is waiting already, return @@ -816,7 +813,7 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( bDispatchThread ) { int nMaxEvents = bHandleAllCurrentEvents ? 100 : 1; - gboolean wasEvent = FALSE, wasOneEvent = TRUE; + gboolean wasOneEvent = TRUE; while( nMaxEvents-- && wasOneEvent ) { wasOneEvent = g_main_context_iteration( NULL, FALSE ); @@ -824,17 +821,17 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) wasEvent = TRUE; } if( bWait && ! wasEvent ) - g_main_context_iteration( NULL, TRUE ); + wasEvent = g_main_context_iteration( NULL, TRUE ); } - else if( userEventFn( this ) ) + else if( bWait ) { /* #i41693# in case the dispatch thread hangs in join * for this thread the condition will never be set * workaround: timeout of 1 second a emergency exit */ - TimeValue aValue; - aValue.Seconds = 1; - aValue.Nanosec = 0; + // we are the dispatch thread + osl_resetCondition( m_aDispatchCondition ); + TimeValue aValue = { 1, 0 }; osl_waitCondition( m_aDispatchCondition, &aValue ); } } @@ -842,8 +839,8 @@ void GtkXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) if( bDispatchThread ) { osl_releaseMutex( m_aDispatchMutex ); - osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields - osl_resetCondition( m_aDispatchCondition ); + if( wasEvent ) + osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields } } diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index ef356eb57aa9..16e478c22f6e 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -690,7 +690,7 @@ static void lcl_set_accept_focus( GtkWindow* pWindow, gboolean bAccept, bool bBe XFree( pHints ); if (GetX11SalData()->GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii("compiz")) - return; + return; /* remove WM_TAKE_FOCUS protocol; this would usually be the * right thing, but gtk handles it internally whereas we @@ -844,7 +844,8 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle ) eType = GDK_WINDOW_TYPE_HINT_UTILITY; } - if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) { eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); @@ -1304,7 +1305,8 @@ void GtkSalFrame::Show( BOOL bVisible, BOOL bNoActivate ) { if( m_pWindow ) { - if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ) + if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); if( bVisible ) { @@ -1465,6 +1467,12 @@ void GtkSalFrame::setMinMaxSize() aHints |= GDK_HINT_MAX_SIZE; } } + if( m_bFullscreen ) + { + aGeo.max_width = m_aMaxSize.Width(); + aGeo.max_height = m_aMaxSize.Height(); + aHints |= GDK_HINT_MAX_SIZE; + } if( aHints ) gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), NULL, @@ -1816,8 +1824,6 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) { m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) ); - // workaround different window managers have different opinions about - // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); if( bVisible ) Show( FALSE ); @@ -1834,12 +1840,22 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) gtk_window_move( GTK_WINDOW(m_pWindow), maGeometry.nX = aNewPosSize.Left(), maGeometry.nY = aNewPosSize.Top() ); + // #i110881# for the benefit of compiz set a max size here + // else setting to fullscreen fails for unknown reasons + m_aMaxSize.Width() = aNewPosSize.GetWidth()+100; + m_aMaxSize.Height() = aNewPosSize.GetHeight()+100; + // workaround different legacy version window managers have different opinions about + // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); if( bVisible ) Show( TRUE ); } else { bool bVisible = GTK_WIDGET_MAPPED(m_pWindow); + if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); if( bVisible ) Show( FALSE ); m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; @@ -1862,8 +1878,11 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) { if( bFullScreen ) { - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); + 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) ); moveToScreen( nScreen ); Size aScreenSize = pDisp->GetScreenSize( m_nScreen ); @@ -1875,8 +1894,11 @@ void GtkSalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) else { gtk_window_unfullscreen( GTK_WINDOW(m_pWindow) ); - if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) - gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + if( getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + { + if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) + gtk_window_set_resizable( GTK_WINDOW(m_pWindow), FALSE ); + } moveToScreen( nScreen ); } } @@ -3184,6 +3206,15 @@ gboolean GtkSalFrame::signalState( GtkWidget*, GdkEvent* pEvent, gpointer frame } pThis->m_nState = pEvent->window_state.new_window_state; + #if OSL_DEBUG_LEVEL > 1 + if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) + { + fprintf( stderr, "window %p %s full screen state\n", + pThis, + (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); + } + #endif + return FALSE; } diff --git a/vcl/unx/inc/saldata.hxx b/vcl/unx/inc/saldata.hxx index 3810558d470d..7e38e0a89bf2 100644 --- a/vcl/unx/inc/saldata.hxx +++ b/vcl/unx/inc/saldata.hxx @@ -62,6 +62,7 @@ protected: SalXLib *pXLib_; SalDisplay *m_pSalDisplay; pthread_t hMainThread_; + rtl::OUString maLocalHostName; public: X11SalData(); @@ -87,6 +88,9 @@ public: inline void StopTimer(); void Timeout() const; + const rtl::OUString& GetLocalHostName() const + { return maLocalHostName; } + static int XErrorHdl( Display*, XErrorEvent* ); static int XIOErrorHdl( Display* ); diff --git a/vcl/unx/inc/wmadaptor.hxx b/vcl/unx/inc/wmadaptor.hxx index c628cfe091ef..cbedede2cc99 100644 --- a/vcl/unx/inc/wmadaptor.hxx +++ b/vcl/unx/inc/wmadaptor.hxx @@ -58,6 +58,8 @@ public: NET_WM_NAME, NET_WM_DESKTOP, NET_WM_ICON_NAME, + NET_WM_PID, + NET_WM_PING, NET_WM_STATE, NET_WM_STATE_MAXIMIZED_HORZ, NET_WM_STATE_MAXIMIZED_VERT, @@ -160,6 +162,7 @@ protected: m_aWMWorkAreas; bool m_bTransientBehaviour; bool m_bEnableAlwaysOnTopWorks; + bool m_bLegacyPartialFullscreen; int m_nWinGravity; int m_nInitWinGravity; @@ -220,6 +223,18 @@ public: virtual void setWMName( X11SalFrame* pFrame, const String& rWMName ) const; /* + * set NET_WM_PID + */ + virtual void setPID( X11SalFrame* pFrame ) const; + + /* + * set WM_CLIENT_MACHINE + */ + virtual void setClientMachine( X11SalFrame* pFrame ) const; + + virtual void answerPing( X11SalFrame*, XClientMessageEvent* ) const; + + /* * maximizes frame * maximization can be toggled in either direction * to get the original position and size @@ -231,6 +246,15 @@ public: */ virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const; /* + * tell whether legacy partial full screen handling is necessary + * see #i107249#: NET_WM_STATE_FULLSCREEN is not well defined, but de facto + * modern WM's interpret it the "right" way, namely they make "full screen" + * taking twin view or Xinerama into accound and honor the positioning hints + * to see which screen actually was meant to use for fullscreen. + */ + bool isLegacyPartialFullscreen() const + { return m_bLegacyPartialFullscreen; } + /* * set window struts */ virtual void setFrameStruts( X11SalFrame*pFrame, diff --git a/vcl/unx/source/app/saldata.cxx b/vcl/unx/source/app/saldata.cxx index 4155887a9875..75d18de0787a 100644 --- a/vcl/unx/source/app/saldata.cxx +++ b/vcl/unx/source/app/saldata.cxx @@ -276,6 +276,7 @@ X11SalData::X11SalData() m_pPlugin = NULL; hMainThread_ = pthread_self(); + osl_getLocalHostname( &maLocalHostName.pData ); } X11SalData::~X11SalData() diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index 2ed699ad0eb5..aa2afab93657 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -322,12 +322,12 @@ sal_IsLocalDisplay( Display *pDisplay ) if( pPtr != NULL ) { - OUString aLocalHostname; - if( osl_getLocalHostname( &aLocalHostname.pData ) == osl_Socket_Ok) + const OUString& rLocalHostname( GetX11SalData()->GetLocalHostName() ); + if( rLocalHostname.getLength() ) { *pPtr = '\0'; OUString aDisplayHostname( pDisplayHost, strlen( pDisplayHost ), osl_getThreadTextEncoding() ); - bEqual = sal_EqualHosts( aLocalHostname, aDisplayHostname ); + bEqual = sal_EqualHosts( rLocalHostname, aDisplayHostname ); bEqual = bEqual && sal_IsDisplayNumber( pPtr + 1 ); } } diff --git a/vcl/unx/source/app/wmadaptor.cxx b/vcl/unx/source/app/wmadaptor.cxx index 89c8bb56291c..fb2317e19573 100644 --- a/vcl/unx/source/app/wmadaptor.cxx +++ b/vcl/unx/source/app/wmadaptor.cxx @@ -34,6 +34,7 @@ #include <sal/alloca.h> #include <wmadaptor.hxx> #include <saldisp.hxx> +#include <saldata.hxx> #include <salframe.h> #include <vcl/salgdi.hxx> #include <osl/thread.h> @@ -118,6 +119,7 @@ static const WMAdaptorProtocol aProtocolTab[] = { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS }, { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP }, { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME }, + { "_NET_WM_PING", WMAdaptor::NET_WM_PING }, { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE }, { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP }, { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN }, @@ -179,7 +181,8 @@ static const WMAdaptorProtocol aAtomTab[] = { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS }, { "_XEMBED", WMAdaptor::XEMBED }, { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO }, - { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME } + { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME }, + { "_NET_WM_PID", WMAdaptor::NET_WM_PID } }; extern "C" { @@ -233,6 +236,7 @@ WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) : m_pSalDisplay( pDisplay ), m_bTransientBehaviour( true ), m_bEnableAlwaysOnTopWorks( false ), + m_bLegacyPartialFullscreen( false ), m_nWinGravity( StaticGravity ), m_nInitWinGravity( StaticGravity ) { @@ -909,6 +913,40 @@ bool WMAdaptor::getNetWmName() XFree( pProperty ); pProperty = NULL; } + // if this is metacity, check for version to enable a legacy workaround + if( m_aWMName.EqualsAscii( "Metacity" ) ) + { + int nVersionMajor = 0, nVersionMinor = 0; + Atom nVersionAtom = XInternAtom( m_pDisplay, "_METACITY_VERSION", True ); + if( nVersionAtom ) + { + if( XGetWindowProperty( m_pDisplay, + aWMChild, + nVersionAtom, + 0, 256, + False, + m_aWMAtoms[ UTF8_STRING ], + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && nItems != 0 + ) + { + String aMetaVersion( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 ); + nVersionMajor = aMetaVersion.GetToken( 0, '.' ).ToInt32(); + nVersionMinor = aMetaVersion.GetToken( 1, '.' ).ToInt32(); + } + if( pProperty ) + { + XFree( pProperty ); + pProperty = NULL; + } + } + if( nVersionMajor < 2 || (nVersionMajor == 2 && nVersionMinor < 12) ) + m_bLegacyPartialFullscreen = true; + } } } else if( pProperty ) @@ -2412,3 +2450,52 @@ void NetWMAdaptor::setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const ); } } + +/* + * WMAdaptor::setPID + */ +void WMAdaptor::setPID( X11SalFrame* i_pFrame ) const +{ + if( m_aWMAtoms[NET_WM_PID] ) + { + long nPID = (long)getpid(); + XChangeProperty( m_pDisplay, + i_pFrame->GetShellWindow(), + m_aWMAtoms[NET_WM_PID], + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char*)&nPID, + 1 + ); + } +} + +/* +* WMAdaptor::setClientMachine +*/ +void WMAdaptor::setClientMachine( X11SalFrame* i_pFrame ) const +{ + rtl::OString aWmClient( rtl::OUStringToOString( GetX11SalData()->GetLocalHostName(), RTL_TEXTENCODING_ASCII_US ) ); + XTextProperty aClientProp = { (unsigned char*)aWmClient.getStr(), XA_STRING, 8, aWmClient.getLength() }; + XSetWMClientMachine( m_pDisplay, i_pFrame->GetShellWindow(), &aClientProp ); +} + +void WMAdaptor::answerPing( X11SalFrame* i_pFrame, XClientMessageEvent* i_pEvent ) const +{ + if( m_aWMAtoms[NET_WM_PING] && + i_pEvent->message_type == m_aWMAtoms[ WM_PROTOCOLS ] && + (Atom)i_pEvent->data.l[0] == m_aWMAtoms[ NET_WM_PING ] ) + { + XEvent aEvent; + aEvent.xclient = *i_pEvent; + aEvent.xclient.window = m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ); + XSendEvent( m_pDisplay, + m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &aEvent + ); + XFlush( m_pDisplay ); + } +} diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index 7cf2009a3e07..f00ee26c0d4d 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -641,13 +641,11 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev mpServerFont[ nFallbackLevel ] = pServerFont; // apply font specific-hint settings if needed + // TODO: also disable it for reference devices if( !bPrinter_ ) { - // TODO: is it worth it to cache the hint settings, e.g. in the ImplFontEntry? - ImplFontOptions aFontOptions; - bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions&); - if( GetFCFontOptions( *pEntry->mpFontData, pEntry->mnHeight, aFontOptions ) ) - pServerFont->SetFontOptions( aFontOptions ); + ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry ); + pSFE->HandleFontOptions(); } return true; @@ -656,6 +654,24 @@ bool X11SalGraphics::setFont( const ImplFontSelectData *pEntry, int nFallbackLev return false; } +void ImplServerFontEntry::HandleFontOptions( void ) +{ + bool GetFCFontOptions( const ImplFontAttributes&, int nSize, ImplFontOptions& ); + + if( !mpServerFont ) + return; + if( !mbGotFontOptions ) + { + // get and cache the font options + mbGotFontOptions = true; + mbValidFontOptions = GetFCFontOptions( *maFontSelData.mpFontData, + maFontSelData.mnHeight, maFontOptions ); + } + // apply the font options + if( mbValidFontOptions ) + mpServerFont->SetFontOptions( maFontOptions ); +} + //-------------------------------------------------------------------------- inline sal_Unicode SwapBytes( const sal_Unicode nIn ) @@ -1633,11 +1649,13 @@ void X11SalGraphics::GetDevFontSubstList( OutputDevice* ) void cairosubcallback( void* pPattern ) { CairoWrapper& rCairo = CairoWrapper::get(); - if( rCairo.isValid() ) - { + if( !rCairo.isValid() ) + return; const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); - rCairo.ft_font_options_substitute( rStyleSettings.GetCairoFontOptions(), pPattern); - } + const void* pFontOptions = rStyleSettings.GetCairoFontOptions(); + if( !pFontOptions ) + return; + rCairo.ft_font_options_substitute( pFontOptions, pPattern ); } bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, @@ -1664,7 +1682,6 @@ bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, default: aInfo.m_eItalic = psp::italic::Unknown; break; - } // set weight switch( rFontAttributes.GetWeight() ) @@ -1740,7 +1757,6 @@ bool GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize, const psp::PrintFontManager& rPFM = psp::PrintFontManager::get(); bool bOK = rPFM.getFontOptions( aInfo, nSize, cairosubcallback, rFontOptions); - return bOK; } diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx index c42c22bc0592..a438760cffba 100644 --- a/vcl/unx/source/plugadapt/salplug.cxx +++ b/vcl/unx/source/plugadapt/salplug.cxx @@ -98,6 +98,14 @@ static SalInstance* tryInstance( const OUString& rModuleBase ) { pCloseModule = NULL; } + /* + * #i109007# KDE3 seems to have the same problem; an atexit cleanup + * handler, which cannot be resolved anymore if the plugin is already unloaded. + */ + else if( rModuleBase.equalsAscii("kde") ) + { + pCloseModule = NULL; + } GetSalData()->m_pPlugin = aMod; } diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx index 5b538626a634..6d243e41db8c 100644 --- a/vcl/unx/source/window/salframe.cxx +++ b/vcl/unx/source/window/salframe.cxx @@ -528,6 +528,8 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa Atom a[4]; int n = 0; a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); + if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) ) + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ); if( ! s_pSaveYourselfFrame && ! mpParent) { // at all times have only one frame with SaveYourself @@ -549,11 +551,23 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity(); pHints->x = 0; pHints->y = 0; + if( mbFullScreen ) + { + pHints->flags |= PMaxSize | PMinSize; + pHints->max_width = w+100; + pHints->max_height = h+100; + pHints->min_width = w; + pHints->min_height = h; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); XFree (pHints); + // set PID and WM_CLIENT_MACHINE + pDisplay_->getWMAdaptor()->setClientMachine( this ); + pDisplay_->getWMAdaptor()->setPID( this ); + // set client leader if( aClientLeader ) { @@ -605,7 +619,8 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa eType = WMAdaptor::windowType_Utility; if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) eType = WMAdaptor::windowType_Toolbar; - if( nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + if( (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) + && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) eType = WMAdaptor::windowType_Dock; GetDisplay()->getWMAdaptor()-> @@ -735,6 +750,8 @@ void X11SalFrame::passOnSaveYourSelf() int n = 0; a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF ); + if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) ) + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ); XSetWMProtocols( GetXDisplay(), s_pSaveYourselfFrame->GetShellWindow(), a, n ); } } @@ -1130,7 +1147,7 @@ void X11SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) // even though transient frames should be kept above their parent // this does not necessarily hold true for DOCK type windows // so artificially set ABOVE and remove it again on hide - if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) + if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen()) pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible ); bMapped_ = bVisible; @@ -1322,11 +1339,6 @@ void X11SalFrame::Show( BOOL bVisible, BOOL bNoActivate ) } else { -#if OSL_DEBUG_LEVEL > 1 - if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) - fprintf( stderr, "hide on ownerdraw\n" ); -#endif - if( getInputContext() ) getInputContext()->Unmap( this ); @@ -1616,6 +1628,7 @@ void X11SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, USHOR } else SetPosSize( aPosSize ); + bDefaultPosition_ = False; } @@ -2042,6 +2055,12 @@ void X11SalFrame::SetPosSize( const Rectangle &rPosSize ) pHints->y = values.y; pHints->win_gravity = pDisplay_->getWMAdaptor()->getPositionWinGravity(); } + if( mbFullScreen ) + { + pHints->max_width = 10000; + pHints->max_height = 10000; + pHints->flags |= PMaxSize; + } XSetWMNormalHints( GetXDisplay(), GetShellWindow(), pHints ); @@ -2199,28 +2218,15 @@ void X11SalFrame::ShowFullScreen( BOOL bFullScreen, sal_Int32 nScreen ) maGeometry.nWidth = aRect.GetWidth(); maGeometry.nHeight = aRect.GetHeight(); mbMaximizedHorz = mbMaximizedVert = false; + mbFullScreen = true; createNewWindow( None, m_nScreen ); - GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); - #if 0 - // this would give additional intent to the window - // manager to force the positioning of the window; - // alas all other windows will be expunged from that - // region, leaving us in a pity state afterwards - Size aScreenSize = pDisplay_->GetScreenSize( m_nScreen ); - pDisplay_->getWMAdaptor()->setFrameStruts( this, - aRect.Left(), aRect.Top(), - aScreenSize.Width() - aRect.Right(), - aScreenSize.Height() - aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom(), - aRect.Left(), aRect.Right(), - aRect.Top(), aRect.Bottom() - ); - #endif - + if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) + GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true ); + else + GetDisplay()->getWMAdaptor()->showFullScreen( this, true ); if( bVisible ) Show(TRUE); - mbFullScreen = true; + } else { @@ -3927,52 +3933,56 @@ long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent ) Close(); // ??? return 1; } - else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) - && ! ( nStyle_ & SAL_FRAME_STYLE_PLUG ) - && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)) - ) + else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) ) { - if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) - { - Close(); - return 1; - } - else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) ) - { - // do nothing, we set the input focus in ToTop() if necessary -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n", - (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? - "ownerdraw" : "NON OWNERDRAW" ); -#endif - } - else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) ) + if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::NET_WM_PING ) ) + rWMAdaptor.answerPing( this, pEvent ); + else if( ! ( nStyle_ & SAL_FRAME_STYLE_PLUG ) + && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)) + ) { - bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" ); - - if( ! bSession ) + if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) + { + Close(); + return 1; + } + else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) ) { - if( this == s_pSaveYourselfFrame ) + // do nothing, we set the input focus in ToTop() if necessary + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n", + (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? + "ownerdraw" : "NON OWNERDRAW" ); + #endif + } + else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) ) + { + bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" ); + + if( ! bSession ) { - ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() ); - const char* argv[2]; - argv[0] = "/bin/sh"; - argv[1] = const_cast<char*>(aExec.GetBuffer()); -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] ); -#endif - XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 ); + if( this == s_pSaveYourselfFrame ) + { + ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() ); + const char* argv[2]; + argv[0] = "/bin/sh"; + argv[1] = const_cast<char*>(aExec.GetBuffer()); + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] ); + #endif + XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 ); + } + else + // can only happen in race between WM and window closing + XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 ); } else - // can only happen in race between WM and window closing - XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 ); - } - else - { - // save open documents; would be good for non Dtwm, too, - // but there is no real Shutdown message in the ancient - // SM protocol; on Dtwm SaveYourself really means Shutdown, too. - IceSalSession::handleOldX11SaveYourself( this ); + { + // save open documents; would be good for non Dtwm, too, + // but there is no real Shutdown message in the ancient + // SM protocol; on Dtwm SaveYourself really means Shutdown, too. + IceSalSession::handleOldX11SaveYourself( this ); + } } } } diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index ebe470d3eb7e..1638c4e1bd36 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -47,11 +47,15 @@ #include "vcl/fontsubset.hxx" #include "vcl/sallayout.hxx" +#include "vcl/outdev.h" // for ImplGlyphFallbackFontSubstitution +#include "unotools/fontcfg.hxx" // for IMPL_FONT_ATTR_SYMBOL + #include "rtl/logfile.hxx" #include "rtl/tencinfo.h" #include "rtl/textcvt.h" #include "rtl/bootstrap.hxx" +#include "i18npool/mslangid.hxx" #include "osl/module.h" #include "osl/file.hxx" @@ -82,7 +86,6 @@ #include <set> #include <map> - using namespace vcl; static const int MAXFONTHEIGHT = 2048; @@ -314,6 +317,308 @@ RawFontData::RawFontData( HDC hDC, DWORD nTableTag ) } } +// =========================================================================== +// platform specific font substitution hooks for glyph fallback enhancement +// TODO: move into i18n module (maybe merge with svx/ucsubset.* +// or merge with i18nutil/source/utility/unicode_data.h) +struct Unicode2LangType +{ + sal_UCS4 mnMinCode; + sal_UCS4 mnMaxCode; + LanguageType mnLangID; +}; + +// entries marked with default-CJK get replaced with the default-CJK language +#define LANGUAGE_DEFAULT_CJK 0xFFF0 + +// map unicode ranges to languages supported by OOo +// NOTE: due to the binary search used this list must be sorted by mnMinCode +static Unicode2LangType aLangFromCodeChart[]= { + {0x0000, 0x007F, LANGUAGE_ENGLISH}, // Basic Latin + {0x0080, 0x024F, LANGUAGE_ENGLISH}, // Latin Extended-A and Latin Extended-B + {0x0250, 0x02AF, LANGUAGE_SYSTEM}, // IPA Extensions + {0x0370, 0x03FF, LANGUAGE_GREEK}, // Greek + {0x0590, 0x05FF, LANGUAGE_HEBREW}, // Hebrew + {0x0600, 0x06FF, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic + {0x0900, 0x097F, LANGUAGE_HINDI}, // Devanagari + {0x0980, 0x09FF, LANGUAGE_BENGALI}, // Bengali + {0x0A80, 0x0AFF, LANGUAGE_GUJARATI}, // Gujarati + {0x0B00, 0x0B7F, LANGUAGE_ORIYA}, // Oriya + {0x0B80, 0x0BFF, LANGUAGE_TAMIL}, // Tamil + {0x0C00, 0x0C7F, LANGUAGE_TELUGU}, // Telugu + {0x0C80, 0x0CFF, LANGUAGE_KANNADA}, // Kannada + {0x0D00, 0x0D7F, LANGUAGE_MALAYALAM}, // Malayalam + {0x0D80, 0x0D7F, LANGUAGE_SINHALESE_SRI_LANKA}, // Sinhala + {0x0E00, 0x0E7F, LANGUAGE_THAI}, // Thai + {0x0E80, 0x0EFF, LANGUAGE_LAO}, // Lao + {0x0F00, 0x0FFF, LANGUAGE_TIBETAN}, // Tibetan + {0x1000, 0x109F, LANGUAGE_BURMESE}, // Burmese + {0x10A0, 0x10FF, LANGUAGE_GEORGIAN}, // Georgian + {0x1100, 0x11FF, LANGUAGE_KOREAN}, // Hangul Jamo, Korean-specific +// {0x1200, 0x139F, LANGUAGE_AMHARIC_ETHIOPIA}, // Ethiopic +// {0x1200, 0x139F, LANGUAGE_TIGRIGNA_ETHIOPIA}, // Ethiopic + {0x13A0, 0x13FF, LANGUAGE_CHEROKEE_UNITED_STATES}, // Cherokee +// {0x1400, 0x167F, LANGUAGE_CANADIAN_ABORIGINAL}, // Canadian Aboriginial Syllabics +// {0x1680, 0x169F, LANGUAGE_OGHAM}, // Ogham +// {0x16A0, 0x16F0, LANGUAGE_RUNIC}, // Runic +// {0x1700, 0x171F, LANGUAGE_TAGALOG}, // Tagalog +// {0x1720, 0x173F, LANGUAGE_HANUNOO}, // Hanunoo +// {0x1740, 0x175F, LANGUAGE_BUHID}, // Buhid +// {0x1760, 0x177F, LANGUAGE_TAGBANWA}, // Tagbanwa + {0x1780, 0x17FF, LANGUAGE_KHMER}, // Khmer + {0x18A0, 0x18AF, LANGUAGE_MONGOLIAN}, // Mongolian +// {0x1900, 0x194F, LANGUAGE_LIMBU}, // Limbu +// {0x1950, 0x197F, LANGUAGE_TAILE}, // Tai Le +// {0x1980, 0x19DF, LANGUAGE_TAILUE}, // Tai Lue + {0x19E0, 0x19FF, LANGUAGE_KHMER}, // Khmer Symbols +// {0x1A00, 0x1A1F, LANGUAGE_BUGINESE}, // Buginese/Lontara +// {0x1B00, 0x1B7F, LANGUAGE_BALINESE}, // Balinese +// {0x1D00, 0x1DFF, LANGUAGE_NONE}, // Phonetic Symbols + {0x1E00, 0x1EFF, LANGUAGE_ENGLISH}, // Latin Extended Additional + {0x1F00, 0x1FFF, LANGUAGE_GREEK}, // Greek Extended + {0x2C60, 0x2C7F, LANGUAGE_ENGLISH}, // Latin Extended-C + {0x2E80, 0x2FFf, LANGUAGE_CHINESE_SIMPLIFIED}, // CJK Radicals Supplement + Kangxi Radical + Ideographic Description Characters + {0x3000, 0x303F, LANGUAGE_DEFAULT_CJK}, // CJK Symbols and punctuation + {0x3040, 0x30FF, LANGUAGE_JAPANESE}, // Japanese Hiragana + Katakana + {0x3100, 0x312F, LANGUAGE_CHINESE_TRADITIONAL}, // Bopomofo + {0x3130, 0x318F, LANGUAGE_KOREAN}, // Hangul Compatibility Jamo, Kocrean-specific + {0x3190, 0x319F, LANGUAGE_JAPANESE}, // Kanbun + {0x31A0, 0x31BF, LANGUAGE_CHINESE_TRADITIONAL}, // Bopomofo Extended + {0x31C0, 0x31EF, LANGUAGE_DEFAULT_CJK}, // CJK Ideographs + {0x31F0, 0x31FF, LANGUAGE_JAPANESE}, // Japanese Katakana Phonetic Extensions + {0x3200, 0x321F, LANGUAGE_KOREAN}, // Parenthesized Hangul + {0x3220, 0x325F, LANGUAGE_DEFAULT_CJK}, // Parenthesized Ideographs + {0x3260, 0x327F, LANGUAGE_KOREAN}, // Circled Hangul + {0x3280, 0x32CF, LANGUAGE_DEFAULT_CJK}, // Circled Ideographs + {0x32d0, 0x32FF, LANGUAGE_JAPANESE}, // Japanese Circled Katakana + {0x3400, 0x4DBF, LANGUAGE_DEFAULT_CJK}, // CJK Unified Ideographs Extension A + {0x4E00, 0x9FCF, LANGUAGE_DEFAULT_CJK}, // Unified CJK Ideographs + {0xA720, 0xA7FF, LANGUAGE_ENGLISH}, // Latin Extended-D + {0xAC00, 0xD7AF, LANGUAGE_KOREAN}, // Hangul Syllables, Korean-specific + {0xF900, 0xFAFF, LANGUAGE_DEFAULT_CJK}, // CJK Compatibility Ideographs + {0xFB00, 0xFB4F, LANGUAGE_HEBREW}, // Hebrew Presentation Forms + {0xFB50, 0xFDFF, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic Presentation Forms-A + {0xFE70, 0xFEFE, LANGUAGE_ARABIC_PRIMARY_ONLY}, // Arabic Presentation Forms-B + {0xFF65, 0xFF9F, LANGUAGE_JAPANESE}, // Japanese Halfwidth Katakana variant + {0xFFA0, 0xFFDC, LANGUAGE_KOREAN}, // Kocrean halfwidth hangual variant + {0x10140, 0x1018F, LANGUAGE_GREEK}, // Ancient Greak numbers + {0x1D200, 0x1D24F, LANGUAGE_GREEK}, // Ancient Greek Musical + {0x20000, 0x2A6DF, LANGUAGE_DEFAULT_CJK}, // CJK Unified Ideographs Extension B + {0x2F800, 0x2FA1F, LANGUAGE_DEFAULT_CJK} // CJK Compatibility Ideographs Supplement +}; + +// get language matching to the missing char +LanguageType MapCharToLanguage( sal_UCS4 uChar ) +{ + // entries marked with default-CJK get replaced with the prefered CJK language + static bool bFirst = true; + if( bFirst ) + { + bFirst = false; + + // use method suggested in #i97086# to determnine the systems default language + // TODO: move into i18npool or sal/osl/w32/nlsupport.c + LanguageType nDefaultLang = 0; + HKEY hKey = NULL; + LONG lResult = ::RegOpenKeyExA( HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Control\\Nls\\Language", + 0, KEY_QUERY_VALUE, &hKey ); + char aKeyValBuf[16]; + DWORD nKeyValSize = sizeof(aKeyValBuf); + if( ERROR_SUCCESS == lResult ) + lResult = RegQueryValueExA( hKey, "Default", NULL, NULL, (LPBYTE)aKeyValBuf, &nKeyValSize ); + aKeyValBuf[ sizeof(aKeyValBuf)-1 ] = '\0'; + if( ERROR_SUCCESS == lResult ) + nDefaultLang = (LanguageType)rtl_str_toInt32( aKeyValBuf, 16 ); + + // TODO: use the default-CJK language selected in + // Tools->Options->LangSettings->Languages when it becomes available here + if( !nDefaultLang ) + nDefaultLang = Application::GetSettings().GetUILanguage(); + + LanguageType nDefaultCJK = LANGUAGE_CHINESE; + switch( nDefaultLang ) + { + case LANGUAGE_JAPANESE: + case LANGUAGE_KOREAN: + case LANGUAGE_KOREAN_JOHAB: + case LANGUAGE_CHINESE_SIMPLIFIED: + case LANGUAGE_CHINESE_TRADITIONAL: + case LANGUAGE_CHINESE_SINGAPORE: + case LANGUAGE_CHINESE_HONGKONG: + case LANGUAGE_CHINESE_MACAU: + nDefaultCJK = nDefaultLang; + break; + default: + nDefaultCJK = LANGUAGE_CHINESE; + break; + } + + // change the marked entries to prefered language + static const int nCount = (sizeof(aLangFromCodeChart) / sizeof(*aLangFromCodeChart)); + for( int i = 0; i < nCount; ++i ) + { + if( aLangFromCodeChart[ i].mnLangID == LANGUAGE_DEFAULT_CJK ) + aLangFromCodeChart[ i].mnLangID = nDefaultCJK; + } + } + + // binary search + int nLow = 0; + int nHigh = (sizeof(aLangFromCodeChart) / sizeof(*aLangFromCodeChart)) - 1; + while( nLow <= nHigh ) + { + int nMiddle = (nHigh + nLow) / 2; + if( uChar < aLangFromCodeChart[ nMiddle].mnMinCode ) + nHigh = nMiddle - 1; + else if( uChar > aLangFromCodeChart[ nMiddle].mnMaxCode ) + nLow = nMiddle + 1; + else + return aLangFromCodeChart[ nMiddle].mnLangID; + } + + return LANGUAGE_DONTKNOW; +} + +class WinGlyphFallbackSubstititution +: public ImplGlyphFallbackFontSubstitution +{ +public: + explicit WinGlyphFallbackSubstititution( HDC ); + + bool FindFontSubstitute( ImplFontSelectData&, rtl::OUString& rMissingChars ) const; +private: + HDC mhDC; + bool HasMissingChars( const ImplFontData*, const rtl::OUString& rMissingChars ) const; +}; + +inline WinGlyphFallbackSubstititution::WinGlyphFallbackSubstititution( HDC hDC ) +: mhDC( hDC ) +{} + +void ImplGetLogFontFromFontSelect( HDC, const ImplFontSelectData*, + LOGFONTW&, bool /*bTestVerticalAvail*/ ); + +// does a font face hold the given missing characters? +bool WinGlyphFallbackSubstititution::HasMissingChars( const ImplFontData* pFace, const rtl::OUString& rMissingChars ) const +{ + const ImplWinFontData* pWinFont = static_cast<const ImplWinFontData*>(pFace); + const ImplFontCharMap* pCharMap = pWinFont->GetImplFontCharMap(); + if( !pCharMap ) + { + // construct a Size structure as the parameter of constructor of class ImplFontSelectData + const Size aSize( pFace->GetWidth(), pFace->GetHeight() ); + // create a ImplFontSelectData object for getting s LOGFONT + const ImplFontSelectData aFSD( *pFace, aSize, (float)aSize.Height(), 0, false ); + // construct log font + LOGFONTW aLogFont; + ImplGetLogFontFromFontSelect( mhDC, &aFSD, aLogFont, true ); + + // create HFONT from log font + HFONT hNewFont = ::CreateFontIndirectW( &aLogFont ); + // select the new font into device + HFONT hOldFont = ::SelectFont( mhDC, hNewFont ); + + // read CMAP table to update their pCharMap + pWinFont->UpdateFromHDC( mhDC );; + + // cleanup temporary font + ::SelectFont( mhDC, hOldFont ); + ::DeleteFont( hNewFont ); + + // get the new charmap + pCharMap = pWinFont->GetImplFontCharMap(); + } + + // avoid fonts with unknown CMAP subtables for glyph fallback + if( !pCharMap || pCharMap->IsDefaultMap() ) + return false; + + int nMatchCount = 0; + // static const int nMaxMatchCount = 1; // TODO: check more missing characters? + const sal_Int32 nStrLen = rMissingChars.getLength(); + for( sal_Int32 nStrIdx = 0; nStrIdx < nStrLen; ++nStrIdx ) + { + const sal_UCS4 uChar = rMissingChars.iterateCodePoints( &nStrIdx ); + nMatchCount += pCharMap->HasChar( uChar ); + break; // for now + } + + const bool bHasMatches = (nMatchCount > 0); + return bHasMatches; +} + +// find a fallback font for missing characters +// TODO: should stylistic matches be searched and prefered? +bool WinGlyphFallbackSubstititution::FindFontSubstitute( ImplFontSelectData& rFontSelData, rtl::OUString& rMissingChars ) const +{ + // guess a locale matching to the missing chars + com::sun::star::lang::Locale aLocale; + + sal_Int32 nStrIdx = 0; + const sal_Int32 nStrLen = rMissingChars.getLength(); + while( nStrIdx < nStrLen ) + { + const sal_UCS4 uChar = rMissingChars.iterateCodePoints( &nStrIdx ); + const LanguageType eLang = MapCharToLanguage( uChar ); + if( eLang == LANGUAGE_DONTKNOW ) + continue; + MsLangId::convertLanguageToLocale( eLang, aLocale ); + break; + } + + // fall back to default UI locale if the missing characters are inconclusive + if( nStrIdx >= nStrLen ) + aLocale = Application::GetSettings().GetUILocale(); + + // first level fallback: + // try use the locale specific default fonts defined in VCL.xcu + const ImplDevFontList* pDevFontList = ImplGetSVData()->maGDIData.mpScreenFontList; + /*const*/ ImplDevFontListData* pDevFont = pDevFontList->ImplFindByLocale( aLocale ); + if( pDevFont ) + { + const ImplFontData* pFace = pDevFont->FindBestFontFace( rFontSelData ); + if( HasMissingChars( pFace, rMissingChars ) ) + { + rFontSelData.maSearchName = pDevFont->GetSearchName(); + return true; + } + } + + // are the missing characters symbols? + pDevFont = pDevFontList->ImplFindByAttributes( IMPL_FONT_ATTR_SYMBOL, + rFontSelData.meWeight, rFontSelData.meWidthType, + rFontSelData.meFamily, rFontSelData.meItalic, rFontSelData.maSearchName ); + if( pDevFont ) + { + const ImplFontData* pFace = pDevFont->FindBestFontFace( rFontSelData ); + if( HasMissingChars( pFace, rMissingChars ) ) + { + rFontSelData.maSearchName = pDevFont->GetSearchName(); + return true; + } + } + + // last level fallback, check each font type face one by one + const ImplGetDevFontList* pTestFontList = pDevFontList->GetDevFontList(); + // limit the count of fonts to be checked to prevent hangs + static const int MAX_GFBFONT_COUNT = 600; + int nTestFontCount = pTestFontList->Count(); + if( nTestFontCount > MAX_GFBFONT_COUNT ) + nTestFontCount = MAX_GFBFONT_COUNT; + + for( int i = 0; i < nTestFontCount; ++i ) + { + const ImplFontData* pFace = pTestFontList->Get( i ); + if( !HasMissingChars( pFace, rMissingChars ) ) + continue; + rFontSelData.maSearchName = pFace->maName; + return true; + } + + return false; +} + // ======================================================================= struct ImplEnumInfo @@ -903,6 +1208,8 @@ bool ImplWinFontData::IsGSUBstituted( sal_UCS4 cChar ) const ImplFontCharMap* ImplWinFontData::GetImplFontCharMap() const { + if( !mpUnicodeMap ) + return NULL; mpUnicodeMap->AddReference(); return mpUnicodeMap; } @@ -2237,6 +2544,10 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) bImplSalCourierScalable = aInfo.mbImplSalCourierScalable; bImplSalCourierNew = aInfo.mbImplSalCourierNew; } + + // set glyph fallback hook + static WinGlyphFallbackSubstititution aSubstFallback( mhDC ); + pFontList->SetFallbackHook( &aSubstFallback ); } // ---------------------------------------------------------------------------- diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index 1b7ed7dcfccb..d1f11433d532 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -295,6 +295,10 @@ BOOL WinSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nP if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) hTheme = getThemeHandle( mhWnd, L"Trackbar" ); break; + case CTRL_LISTNODE: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"TreeView" ); + break; default: hTheme = NULL; break; @@ -926,6 +930,27 @@ BOOL ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc, return ImplDrawTheme( hTheme, hDC, iPart, iState, aThumbRect, aCaption ); } + if( nType == CTRL_LISTNODE ) + { + if( nPart != PART_ENTIRE_CONTROL ) + return FALSE; + + ButtonValue aButtonValue = aValue.getTristateVal(); + iPart = TVP_GLYPH; + switch( aButtonValue ) + { + case BUTTONVALUE_ON: + iState = GLPS_OPENED; + break; + case BUTTONVALUE_OFF: + iState = GLPS_CLOSED; + break; + default: + return FALSE; + } + return ImplDrawTheme( hTheme, hDC, iPart, iState, rc, aCaption ); + } + return false; } @@ -1006,6 +1031,10 @@ BOOL WinSalGraphics::drawNativeControl( ControlType nType, if( nPart == PART_ENTIRE_CONTROL ) hTheme = getThemeHandle( mhWnd, L"Progress"); break; + case CTRL_LISTNODE: + if( nPart == PART_ENTIRE_CONTROL ) + hTheme = getThemeHandle( mhWnd, L"TreeView"); + break; case CTRL_SLIDER: if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA ) hTheme = getThemeHandle( mhWnd, L"Trackbar" ); |