Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <i18nlangtag/mslangid.hxx>
21 :
22 : #include <vcl/event.hxx>
23 : #include <vcl/svapp.hxx>
24 : #include <vcl/window.hxx>
25 : #include <vcl/virdev.hxx>
26 : #include <vcl/settings.hxx>
27 :
28 : #include <unotools/fontcfg.hxx>
29 : #include <unotools/confignode.hxx>
30 :
31 : #include <comphelper/processfactory.hxx>
32 :
33 : #include <salframe.hxx>
34 : #include <svdata.hxx>
35 : #include <brdwin.hxx>
36 : #include <PhysicalFontCollection.hxx>
37 :
38 : #include <window.h>
39 :
40 : namespace vcl {
41 :
42 77722 : void Window::SetSettings( const AllSettings& rSettings )
43 : {
44 77722 : SetSettings( rSettings, false );
45 77722 : }
46 :
47 83098 : void Window::SetSettings( const AllSettings& rSettings, bool bChild )
48 : {
49 :
50 83098 : if ( mpWindowImpl->mpBorderWindow )
51 : {
52 1406 : mpWindowImpl->mpBorderWindow->SetSettings( rSettings, false );
53 1406 : if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
54 : static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
55 0 : static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->SetSettings( rSettings, true );
56 : }
57 :
58 83098 : AllSettings aOldSettings(*mxSettings);
59 83098 : OutputDevice::SetSettings( rSettings );
60 83098 : sal_uLong nChangeFlags = aOldSettings.GetChangeFlags( rSettings );
61 :
62 : // recalculate AppFont-resolution and DPI-resolution
63 83098 : ImplInitResolutionSettings();
64 :
65 83098 : if ( nChangeFlags )
66 : {
67 3132 : DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
68 3132 : DataChanged( aDCEvt );
69 : }
70 :
71 83098 : if ( bChild || mpWindowImpl->mbChildNotify )
72 : {
73 3970 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
74 10503 : while ( pChild )
75 : {
76 2563 : pChild->SetSettings( rSettings, bChild );
77 2563 : pChild = pChild->mpWindowImpl->mpNext;
78 : }
79 83098 : }
80 83098 : }
81 :
82 4676 : void Window::UpdateSettings( const AllSettings& rSettings, bool bChild )
83 : {
84 :
85 4676 : if ( mpWindowImpl->mpBorderWindow )
86 : {
87 810 : mpWindowImpl->mpBorderWindow->UpdateSettings( rSettings, false );
88 810 : if ( (mpWindowImpl->mpBorderWindow->GetType() == WINDOW_BORDERWINDOW) &&
89 : static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow)->mpMenuBarWindow )
90 4 : static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow)->mpMenuBarWindow->UpdateSettings( rSettings, true );
91 : }
92 :
93 4676 : AllSettings aOldSettings(*mxSettings);
94 4676 : sal_uLong nChangeFlags = mxSettings->Update( mxSettings->GetWindowUpdate(), rSettings );
95 4676 : nChangeFlags |= SETTINGS_IN_UPDATE_SETTINGS; // Set this flag so the receiver of the data changed
96 : // event can distinguish between the changing of global
97 : // setting and a local change ( with SetSettings )
98 :
99 : // recalculate AppFont-resolution and DPI-resolution
100 4676 : ImplInitResolutionSettings();
101 :
102 : /* #i73785#
103 : * do not overwrite a WheelBehavior with false
104 : * this looks kind of a hack, but WheelBehavior
105 : * is always a local change, not a system property,
106 : * so we can spare all our users the hassle of reacting on
107 : * this in their respective DataChanged.
108 : */
109 9352 : MouseSettings aSet( mxSettings->GetMouseSettings() );
110 4676 : aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() );
111 4676 : mxSettings->SetMouseSettings( aSet );
112 :
113 4676 : if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() )
114 : {
115 2948 : Wallpaper aWallpaper = GetBackground();
116 2948 : if( !aWallpaper.IsBitmap() && !aWallpaper.IsGradient() )
117 : {
118 2172 : if ( mpWindowImpl->mnStyle & WB_3DLOOK )
119 : {
120 1474 : if (aOldSettings.GetStyleSettings().GetFaceColor() != rSettings.GetStyleSettings().GetFaceColor())
121 0 : SetBackground( Wallpaper( rSettings.GetStyleSettings().GetFaceColor() ) );
122 : }
123 : else
124 : {
125 698 : if (aOldSettings.GetStyleSettings().GetWindowColor() != rSettings.GetStyleSettings().GetWindowColor())
126 0 : SetBackground( Wallpaper( rSettings.GetStyleSettings().GetWindowColor() ) );
127 : }
128 2948 : }
129 : }
130 :
131 4676 : if ( nChangeFlags )
132 : {
133 4676 : DataChangedEvent aDCEvt( DATACHANGED_SETTINGS, &aOldSettings, nChangeFlags );
134 4676 : DataChanged( aDCEvt );
135 : // notify data change handler
136 4676 : ImplCallEventListeners( VCLEVENT_WINDOW_DATACHANGED, &aDCEvt);
137 : }
138 :
139 4676 : if ( bChild || mpWindowImpl->mbChildNotify )
140 : {
141 3858 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
142 10860 : while ( pChild )
143 : {
144 3144 : pChild->UpdateSettings( rSettings, bChild );
145 3144 : pChild = pChild->mpWindowImpl->mpNext;
146 : }
147 4676 : }
148 4676 : }
149 :
150 1140 : void Window::ImplUpdateGlobalSettings( AllSettings& rSettings, bool bCallHdl )
151 : {
152 1140 : StyleSettings aTmpSt( rSettings.GetStyleSettings() );
153 1140 : aTmpSt.SetHighContrastMode( false );
154 1140 : rSettings.SetStyleSettings( aTmpSt );
155 1140 : ImplGetFrame()->UpdateSettings( rSettings );
156 : // reset default border width for layouters
157 1140 : ImplGetSVData()->maAppData.mnDefaultLayoutBorder = -1;
158 :
159 : // Verify availability of the configured UI font, otherwise choose "Andale Sans UI"
160 :
161 : // WTF, what makes Andale Sans UI a suitable cross-platform fallback font?
162 :
163 2280 : OUString aUserInterfaceFont;
164 1140 : bool bUseSystemFont = rSettings.GetStyleSettings().GetUseSystemUIFonts();
165 :
166 : // check whether system UI font can display a typical UI text
167 1140 : if( bUseSystemFont )
168 1140 : bUseSystemFont = ImplCheckUIFont( rSettings.GetStyleSettings().GetAppFont() );
169 :
170 1140 : if ( !bUseSystemFont )
171 : {
172 0 : OutputDevice *pOutDev = GetOutDev();
173 0 : pOutDev->ImplInitFontList();
174 0 : OUString aConfigFont = utl::DefaultFontConfiguration::get().getUserInterfaceFont( rSettings.GetUILanguageTag() );
175 0 : sal_Int32 nIndex = 0;
176 0 : while( nIndex != -1 )
177 : {
178 0 : OUString aName( aConfigFont.getToken( 0, ';', nIndex ) );
179 0 : if ( !aName.isEmpty() && mpWindowImpl->mpFrameData->mpFontCollection->FindFontFamily( aName ) )
180 : {
181 0 : aUserInterfaceFont = aConfigFont;
182 0 : break;
183 : }
184 0 : }
185 :
186 0 : if ( aUserInterfaceFont.isEmpty() )
187 : {
188 0 : OUString aFallbackFont ("Andale Sans UI" );
189 0 : if ( mpWindowImpl->mpFrameData->mpFontCollection->FindFontFamily( aFallbackFont ) )
190 0 : aUserInterfaceFont = aFallbackFont;
191 0 : }
192 : }
193 :
194 1140 : if ( !bUseSystemFont && !aUserInterfaceFont.isEmpty() )
195 : {
196 0 : StyleSettings aStyleSettings = rSettings.GetStyleSettings();
197 0 : vcl::Font aFont = aStyleSettings.GetAppFont();
198 0 : aFont.SetName( aUserInterfaceFont );
199 0 : aStyleSettings.SetAppFont( aFont );
200 0 : aFont = aStyleSettings.GetHelpFont();
201 0 : aFont.SetName( aUserInterfaceFont );
202 0 : aStyleSettings.SetHelpFont( aFont );
203 0 : aFont = aStyleSettings.GetTitleFont();
204 0 : aFont.SetName( aUserInterfaceFont );
205 0 : aStyleSettings.SetTitleFont( aFont );
206 0 : aFont = aStyleSettings.GetFloatTitleFont();
207 0 : aFont.SetName( aUserInterfaceFont );
208 0 : aStyleSettings.SetFloatTitleFont( aFont );
209 0 : aFont = aStyleSettings.GetMenuFont();
210 0 : aFont.SetName( aUserInterfaceFont );
211 0 : aStyleSettings.SetMenuFont( aFont );
212 0 : aFont = aStyleSettings.GetToolFont();
213 0 : aFont.SetName( aUserInterfaceFont );
214 0 : aStyleSettings.SetToolFont( aFont );
215 0 : aFont = aStyleSettings.GetLabelFont();
216 0 : aFont.SetName( aUserInterfaceFont );
217 0 : aStyleSettings.SetLabelFont( aFont );
218 0 : aFont = aStyleSettings.GetInfoFont();
219 0 : aFont.SetName( aUserInterfaceFont );
220 0 : aStyleSettings.SetInfoFont( aFont );
221 0 : aFont = aStyleSettings.GetRadioCheckFont();
222 0 : aFont.SetName( aUserInterfaceFont );
223 0 : aStyleSettings.SetRadioCheckFont( aFont );
224 0 : aFont = aStyleSettings.GetPushButtonFont();
225 0 : aFont.SetName( aUserInterfaceFont );
226 0 : aStyleSettings.SetPushButtonFont( aFont );
227 0 : aFont = aStyleSettings.GetFieldFont();
228 0 : aFont.SetName( aUserInterfaceFont );
229 0 : aStyleSettings.SetFieldFont( aFont );
230 0 : aFont = aStyleSettings.GetIconFont();
231 0 : aFont.SetName( aUserInterfaceFont );
232 0 : aStyleSettings.SetIconFont( aFont );
233 0 : aFont = aStyleSettings.GetGroupFont();
234 0 : aFont.SetName( aUserInterfaceFont );
235 0 : aStyleSettings.SetGroupFont( aFont );
236 0 : rSettings.SetStyleSettings( aStyleSettings );
237 : }
238 :
239 2280 : StyleSettings aStyleSettings = rSettings.GetStyleSettings();
240 : // #97047: Force all fonts except Menu and Help to a fixed height
241 : // to avoid UI scaling due to large fonts
242 : // - but allow bigger fonts on bigger screens (i16682, i21238)
243 : // dialogs were designed to fit 800x600 with an 8pt font, so scale accordingly
244 1140 : int maxFontheight = 9; // #107886#: 9 is default for some asian systems, so always allow if requested
245 1140 : if( GetDesktopRectPixel().getHeight() > 600 )
246 1140 : maxFontheight = (int) ((( 8.0 * (double) GetDesktopRectPixel().getHeight()) / 600.0) + 1.5);
247 :
248 2280 : vcl::Font aFont = aStyleSettings.GetMenuFont();
249 1140 : int defFontheight = aFont.GetHeight();
250 1140 : if( defFontheight > maxFontheight )
251 0 : defFontheight = maxFontheight;
252 :
253 : // if the UI is korean, chinese or another locale
254 : // where the system font size is kown to be often too small to
255 : // generate readable fonts enforce a minimum font size of 9 points
256 1140 : bool bBrokenLangFontHeight = MsLangId::isCJK(Application::GetSettings().GetUILanguageTag().getLanguageType());
257 1140 : if (bBrokenLangFontHeight)
258 0 : defFontheight = std::max(9, defFontheight);
259 :
260 : // i22098, toolfont will be scaled differently to avoid bloated rulers and status bars for big fonts
261 1140 : int toolfontheight = defFontheight;
262 1140 : if( toolfontheight > 9 )
263 0 : toolfontheight = (defFontheight+8) / 2;
264 :
265 1140 : aFont = aStyleSettings.GetAppFont();
266 1140 : aFont.SetHeight( defFontheight );
267 1140 : aStyleSettings.SetAppFont( aFont );
268 1140 : aFont = aStyleSettings.GetTitleFont();
269 1140 : aFont.SetHeight( defFontheight );
270 1140 : aStyleSettings.SetTitleFont( aFont );
271 1140 : aFont = aStyleSettings.GetFloatTitleFont();
272 1140 : aFont.SetHeight( defFontheight );
273 1140 : aStyleSettings.SetFloatTitleFont( aFont );
274 : // keep menu and help font size from system unless in broken locale size
275 1140 : if( bBrokenLangFontHeight )
276 : {
277 0 : aFont = aStyleSettings.GetMenuFont();
278 0 : if( aFont.GetHeight() < defFontheight )
279 : {
280 0 : aFont.SetHeight( defFontheight );
281 0 : aStyleSettings.SetMenuFont( aFont );
282 : }
283 0 : aFont = aStyleSettings.GetHelpFont();
284 0 : if( aFont.GetHeight() < defFontheight )
285 : {
286 0 : aFont.SetHeight( defFontheight );
287 0 : aStyleSettings.SetHelpFont( aFont );
288 : }
289 : }
290 :
291 : // use different height for toolfont
292 1140 : aFont = aStyleSettings.GetToolFont();
293 1140 : aFont.SetHeight( toolfontheight );
294 1140 : aStyleSettings.SetToolFont( aFont );
295 :
296 1140 : aFont = aStyleSettings.GetLabelFont();
297 1140 : aFont.SetHeight( defFontheight );
298 1140 : aStyleSettings.SetLabelFont( aFont );
299 1140 : aFont = aStyleSettings.GetInfoFont();
300 1140 : aFont.SetHeight( defFontheight );
301 1140 : aStyleSettings.SetInfoFont( aFont );
302 1140 : aFont = aStyleSettings.GetRadioCheckFont();
303 1140 : aFont.SetHeight( defFontheight );
304 1140 : aStyleSettings.SetRadioCheckFont( aFont );
305 1140 : aFont = aStyleSettings.GetPushButtonFont();
306 1140 : aFont.SetHeight( defFontheight );
307 1140 : aStyleSettings.SetPushButtonFont( aFont );
308 1140 : aFont = aStyleSettings.GetFieldFont();
309 1140 : aFont.SetHeight( defFontheight );
310 1140 : aStyleSettings.SetFieldFont( aFont );
311 1140 : aFont = aStyleSettings.GetIconFont();
312 1140 : aFont.SetHeight( defFontheight );
313 1140 : aStyleSettings.SetIconFont( aFont );
314 1140 : aFont = aStyleSettings.GetGroupFont();
315 1140 : aFont.SetHeight( defFontheight );
316 1140 : aStyleSettings.SetGroupFont( aFont );
317 :
318 1140 : rSettings.SetStyleSettings( aStyleSettings );
319 :
320 1140 : bool bForceHCMode = false;
321 :
322 : // auto detect HC mode; if the system already set it to "yes"
323 : // (see above) then accept that
324 1140 : if( !rSettings.GetStyleSettings().GetHighContrastMode() )
325 : {
326 1140 : bool bTmp = false, bAutoHCMode = true;
327 : utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(
328 : comphelper::getProcessComponentContext(),
329 1140 : OUString("org.openoffice.Office.Common/Accessibility") ); // note: case sensitive !
330 1140 : if ( aNode.isValid() )
331 : {
332 1140 : ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString("AutoDetectSystemHC") );
333 1140 : if( aValue >>= bTmp )
334 1140 : bAutoHCMode = bTmp;
335 : }
336 1140 : if( bAutoHCMode )
337 : {
338 0 : if( rSettings.GetStyleSettings().GetFaceColor().IsDark() ||
339 0 : rSettings.GetStyleSettings().GetWindowColor().IsDark() )
340 0 : bForceHCMode = true;
341 1140 : }
342 : }
343 :
344 1140 : static const char* pEnvHC = getenv( "SAL_FORCE_HC" );
345 1140 : if( pEnvHC && *pEnvHC )
346 0 : bForceHCMode = true;
347 :
348 1140 : if( bForceHCMode )
349 : {
350 0 : aStyleSettings = rSettings.GetStyleSettings();
351 0 : aStyleSettings.SetHighContrastMode( true );
352 0 : rSettings.SetStyleSettings( aStyleSettings );
353 : }
354 :
355 : #if defined(DBG_UTIL)
356 : // If needed, set AppFont to bold, in order to check
357 : // if there is enough space available for texts on other systems
358 : if ( DbgIsBoldAppFont() )
359 : {
360 : aStyleSettings = rSettings.GetStyleSettings();
361 : aFont = aStyleSettings.GetAppFont();
362 : aFont.SetWeight( WEIGHT_BOLD );
363 : aStyleSettings.SetAppFont( aFont );
364 : aFont = aStyleSettings.GetGroupFont();
365 : aFont.SetWeight( WEIGHT_BOLD );
366 : aStyleSettings.SetGroupFont( aFont );
367 : aFont = aStyleSettings.GetLabelFont();
368 : aFont.SetWeight( WEIGHT_BOLD );
369 : aStyleSettings.SetLabelFont( aFont );
370 : aFont = aStyleSettings.GetRadioCheckFont();
371 : aFont.SetWeight( WEIGHT_BOLD );
372 : aStyleSettings.SetRadioCheckFont( aFont );
373 : aFont = aStyleSettings.GetPushButtonFont();
374 : aFont.SetWeight( WEIGHT_BOLD );
375 : aStyleSettings.SetPushButtonFont( aFont );
376 : aFont = aStyleSettings.GetFieldFont();
377 : aFont.SetWeight( WEIGHT_BOLD );
378 : aStyleSettings.SetFieldFont( aFont );
379 : aFont = aStyleSettings.GetIconFont();
380 : aFont.SetWeight( WEIGHT_BOLD );
381 : aStyleSettings.SetIconFont( aFont );
382 : rSettings.SetStyleSettings( aStyleSettings );
383 : }
384 : #endif
385 :
386 1140 : if ( bCallHdl )
387 1416 : GetpApp()->OverrideSystemSettings( rSettings );
388 1140 : }
389 :
390 1233 : } /*namespace vcl*/
391 :
392 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|