diff --git a/macos/ONLYOFFICE/Code/Controllers/Common/ASCEventsController.mm b/macos/ONLYOFFICE/Code/Controllers/Common/ASCEventsController.mm index f557b627e..0b7a41f7f 100644 --- a/macos/ONLYOFFICE/Code/Controllers/Common/ASCEventsController.mm +++ b/macos/ONLYOFFICE/Code/Controllers/Common/ASCEventsController.mm @@ -665,6 +665,10 @@ public: [[ASCEditorJSVariables instance] setParameter:@"uitheme" withString:uiTheme]; } + if ( [json objectForKey:@"rtl"] != nil ) { + [ASCLinguist setUILayoutDirectionRtl:[json[@"rtl"] boolValue]]; + } + [[ASCEditorJSVariables instance] applyParameters]; } } else if (cmd.find(L"encrypt:isneedbuild") != std::wstring::npos) { diff --git a/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.h b/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.h index 901cd95ba..ecfd2648c 100644 --- a/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.h +++ b/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.h @@ -47,6 +47,8 @@ NS_ASSUME_NONNULL_BEGIN + (NSDictionary *)availableLanguages; + (NSString *)appLanguageCode; + (void)setAppLanguageCode:(NSString *)code; ++ (void)setUILayoutDirectionRtl:(BOOL)value; ++ (BOOL)isUILayoutDirectionRtl; @end diff --git a/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.m b/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.m index f6277d125..42dd3ac3e 100644 --- a/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.m +++ b/macos/ONLYOFFICE/Code/Controllers/Common/ASCLinguist.m @@ -42,10 +42,17 @@ @implementation ASCLinguist +static BOOL uiLayoutDirectionRTL = NO; + + (void)init { [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:[ASCLinguist appLanguageCode]] forKey:@"AppleLanguages"]; [[NSUserDefaults standardUserDefaults] setObject:[ASCLinguist appLanguageCode] forKey:@"AppleLocale"]; [[NSUserDefaults standardUserDefaults] synchronize]; + +// bool l = [NSLocale characterDirectionForLanguage:[ASCLinguist appLanguageCode]] == NSLocaleLanguageDirectionRightToLeft; + NSString * direction = [[NSUserDefaults standardUserDefaults] objectForKey:ASCUserUILayoutDirection]; + if ( direction != nil ) + uiLayoutDirectionRTL = [direction isEqualToString:@"rtl"]; } + (NSString *)appLanguageCode { @@ -67,6 +74,18 @@ [[NSUserDefaults standardUserDefaults] synchronize]; } ++ (void)setUILayoutDirectionRtl:(BOOL)value { + if ( value ) + [[NSUserDefaults standardUserDefaults] setObject:@"rtl" forKey:ASCUserUILayoutDirection]; + else [[NSUserDefaults standardUserDefaults] removeObjectForKey:ASCUserUILayoutDirection]; + + [[NSUserDefaults standardUserDefaults] synchronize]; +} + ++ (BOOL)isUILayoutDirectionRtl { + return uiLayoutDirectionRTL; +} + + (NSDictionary *)availableLanguages { return @{ @"en": @"English", diff --git a/macos/ONLYOFFICE/Code/Controllers/MainWindow/ASCTitleBarController.mm b/macos/ONLYOFFICE/Code/Controllers/MainWindow/ASCTitleBarController.mm index 9b49c34ae..9c73b9ca3 100644 --- a/macos/ONLYOFFICE/Code/Controllers/MainWindow/ASCTitleBarController.mm +++ b/macos/ONLYOFFICE/Code/Controllers/MainWindow/ASCTitleBarController.mm @@ -52,6 +52,7 @@ #import "ASCMenuButtonCell.h" #import "ASCThemesController.h" #import "ASCApplicationManager.h" +#import "ASCLinguist.h" static float kASCWindowDefaultTrafficButtonsLeftMargin = 0; @@ -115,6 +116,10 @@ static float kASCWindowMinTitleWidth = 0; self.standardButtonsDefaults = @[[mainWindow standardWindowButton:NSWindowCloseButton], [mainWindow standardWindowButton:NSWindowMiniaturizeButton], [mainWindow standardWindowButton:NSWindowZoomButton]]; + + if ( [ASCLinguist isUILayoutDirectionRtl] ) { + self.standardButtonsDefaults = [[self.standardButtonsDefaults reverseObjectEnumerator] allObjects]; + } } [self.standardButtonsDefaults enumerateObjectsUsingBlock:^(NSButton *standardButton, NSUInteger idx, BOOL *stop) { @@ -224,6 +229,9 @@ static float kASCWindowMinTitleWidth = 0; } } + if ( [ASCLinguist isUILayoutDirectionRtl] ) + [self.view setUserInterfaceLayoutDirection:NSUserInterfaceLayoutDirectionRightToLeft]; + [self doLayout]; } @@ -250,10 +258,17 @@ static float kASCWindowMinTitleWidth = 0; } - (void)doLayout { + CGFloat btnContainerWidth = CGRectGetWidth([self.standardButtonsDefaults[0] frame]) + 6.0; + CGFloat leftOffset = kASCWindowDefaultTrafficButtonsLeftMargin; + if ( [ASCLinguist isUILayoutDirectionRtl] ) { + CGFloat windowWidth = CGRectGetWidth([[self view] frame]); + leftOffset = windowWidth - kASCWindowDefaultTrafficButtonsLeftMargin - btnContainerWidth * 3; + } + void (^layoutStandartButtons)(NSArray *, BOOL) = ^ (NSArray *views, BOOL hidden) { [views enumerateObjectsUsingBlock:^(NSView *view, NSUInteger idx, BOOL *stop) { NSRect frame = view.frame; - frame.origin.x = kASCWindowDefaultTrafficButtonsLeftMargin + idx * (NSWidth(frame) + 6.0); + frame.origin.x = leftOffset + idx * btnContainerWidth; frame.origin.y = (int)((NSHeight(view.superview.frame) - NSHeight(view.frame)) / 2.0); [view setFrame:frame]; diff --git a/macos/ONLYOFFICE/Code/Utils/ASCConstants.h b/macos/ONLYOFFICE/Code/Utils/ASCConstants.h index e27588153..4226de89f 100644 --- a/macos/ONLYOFFICE/Code/Utils/ASCConstants.h +++ b/macos/ONLYOFFICE/Code/Utils/ASCConstants.h @@ -88,6 +88,7 @@ static NSString * const ASCUserNameApp = @"asc_user_name_ap static NSString * const ASCUserUILanguage = @"asc_user_ui_lang"; static NSString * const ASCUserUITheme = @"asc_user_ui_theme"; static NSString * const ASCUserWebappsHelpUrl = @"user_webapps_help_url"; +static NSString * const ASCUserUILayoutDirection = @"asc_user_ui_layout_direction"; // Application event names static NSString * const ASCEventNameMainWindowSetFrame = @"UI_mainWindowSetFrame"; diff --git a/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.h b/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.h index 5bf12e41f..1591f6559 100644 --- a/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.h +++ b/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.h @@ -48,6 +48,7 @@ - (void)apply; - (void)setVariable:(NSString*)name withString:(NSString *)value; - (void)setVariable:(NSString*)name withObject:(NSDictionary *)value; +- (void)setVariable:(NSString*)name withBool:(BOOL)value; - (void)setParameter:(NSString*)name withString:(NSString *)value; - (void)removeParameter:(NSString*)name; - (void)applyParameters; diff --git a/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.mm b/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.mm index 0abfb9b13..e52ba578f 100644 --- a/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.mm +++ b/macos/ONLYOFFICE/Code/Utils/ASCEditorJSVariables.mm @@ -101,6 +101,10 @@ [_jsVariables setValue:value forKey:name]; } +- (void)setVariable: (NSString*)name withBool:(BOOL)value { + [_jsVariables setValue:@(value) forKey:name]; +} + - (void)setVariable: (NSString*)name withObject:(NSDictionary *)object { [_jsVariables setObject:object forKey:name]; } diff --git a/macos/ONLYOFFICE/main.mm b/macos/ONLYOFFICE/main.mm index 1ffb281c0..01a205bb5 100644 --- a/macos/ONLYOFFICE/main.mm +++ b/macos/ONLYOFFICE/main.mm @@ -117,6 +117,7 @@ int main(int argc, const char * argv[]) { [[ASCEditorJSVariables instance] setVariable:@"theme" withObject:@{@"id":uiTheme, @"system":systemColorScheme, @"type":systemColorScheme}]; + [[ASCEditorJSVariables instance] setVariable:@"rtl" withBool:[ASCLinguist isUILayoutDirectionRtl]]; [[ASCEditorJSVariables instance] apply]; // setup doc sign