Merge pull request #1511 from fufesou/flutter_desktop_new_remote_menu_4
Flutter desktop new remote menu 4
This commit is contained in:
commit
406be63ffd
@ -330,18 +330,6 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
onHover: (value) => refreshHover.value = value,
|
onHover: (value) => refreshHover.value = value,
|
||||||
),
|
),
|
||||||
const _PasswordPopupMenu(),
|
const _PasswordPopupMenu(),
|
||||||
// FutureBuilder<Widget>(
|
|
||||||
// future: buildPasswordPopupMenu(context),
|
|
||||||
// builder: (context, snapshot) {
|
|
||||||
// if (snapshot.hasError) {
|
|
||||||
// print("${snapshot.error}");
|
|
||||||
// }
|
|
||||||
// if (snapshot.hasData) {
|
|
||||||
// return snapshot.data!;
|
|
||||||
// } else {
|
|
||||||
// return Offstage();
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -353,92 +341,6 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Widget> buildPasswordPopupMenu(BuildContext context) async {
|
|
||||||
var position;
|
|
||||||
RxBool editHover = false.obs;
|
|
||||||
return InkWell(
|
|
||||||
onTapDown: (detail) {
|
|
||||||
final x = detail.globalPosition.dx;
|
|
||||||
final y = detail.globalPosition.dy;
|
|
||||||
position = RelativeRect.fromLTRB(x, y, x, y);
|
|
||||||
},
|
|
||||||
onTap: () async {
|
|
||||||
var method = (String text, String value) => PopupMenuItem(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Offstage(
|
|
||||||
offstage: gFFI.serverModel.verificationMethod != value,
|
|
||||||
child: Icon(Icons.check)),
|
|
||||||
Text(
|
|
||||||
text,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () => gFFI.serverModel.setVerificationMethod(value),
|
|
||||||
);
|
|
||||||
final temporary_enabled =
|
|
||||||
gFFI.serverModel.verificationMethod != kUsePermanentPassword;
|
|
||||||
var menu = <PopupMenuEntry>[
|
|
||||||
method(translate("Use temporary password"), kUseTemporaryPassword),
|
|
||||||
method(translate("Use permanent password"), kUsePermanentPassword),
|
|
||||||
method(translate("Use both passwords"), kUseBothPasswords),
|
|
||||||
PopupMenuDivider(),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: Text(translate("Set permanent password")),
|
|
||||||
value: 'set-permanent-password',
|
|
||||||
enabled: gFFI.serverModel.verificationMethod !=
|
|
||||||
kUseTemporaryPassword),
|
|
||||||
PopupMenuItem(
|
|
||||||
child: PopupMenuButton(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
child: Text(
|
|
||||||
translate("Set temporary password length"),
|
|
||||||
),
|
|
||||||
itemBuilder: (context) => ["6", "8", "10"]
|
|
||||||
.map((e) => PopupMenuItem(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Offstage(
|
|
||||||
offstage: gFFI.serverModel
|
|
||||||
.temporaryPasswordLength !=
|
|
||||||
e,
|
|
||||||
child: Icon(Icons.check)),
|
|
||||||
Text(
|
|
||||||
e,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
if (gFFI.serverModel.temporaryPasswordLength !=
|
|
||||||
e) {
|
|
||||||
() async {
|
|
||||||
await gFFI.serverModel
|
|
||||||
.setTemporaryPasswordLength(e);
|
|
||||||
await bind.mainUpdateTemporaryPassword();
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
enabled: temporary_enabled,
|
|
||||||
),
|
|
||||||
enabled: temporary_enabled),
|
|
||||||
];
|
|
||||||
final v =
|
|
||||||
await showMenu(context: context, position: position, items: menu);
|
|
||||||
if (v == "set-permanent-password") {
|
|
||||||
setPasswordDialog();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onHover: (value) => editHover.value = value,
|
|
||||||
child: Obx(() => Icon(Icons.edit,
|
|
||||||
size: 22,
|
|
||||||
color: editHover.value
|
|
||||||
? MyTheme.color(context).text
|
|
||||||
: Color(0xFFDDDDDD))
|
|
||||||
.marginOnly(bottom: 2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTip(BuildContext context) {
|
buildTip(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding:
|
||||||
@ -469,7 +371,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onTrayMenuItemClick(MenuItem menuItem) {
|
void onTrayMenuItemClick(MenuItem menuItem) {
|
||||||
print("click ${menuItem.key}");
|
print('click ${menuItem.key}');
|
||||||
switch (menuItem.key) {
|
switch (menuItem.key) {
|
||||||
case "quit":
|
case "quit":
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -50,6 +50,8 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
var _isPhysicalMouse = false;
|
var _isPhysicalMouse = false;
|
||||||
var _imageFocused = false;
|
var _imageFocused = false;
|
||||||
|
|
||||||
|
final _onEnterOrLeaveImage = <Function(bool)>[];
|
||||||
|
|
||||||
late FFI _ffi;
|
late FFI _ffi;
|
||||||
|
|
||||||
void _updateTabBarHeight() {
|
void _updateTabBarHeight() {
|
||||||
@ -421,11 +423,17 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
_physicalFocusNode.requestFocus();
|
_physicalFocusNode.requestFocus();
|
||||||
}
|
}
|
||||||
_cursorOverImage.value = true;
|
_cursorOverImage.value = true;
|
||||||
|
for (var f in _onEnterOrLeaveImage) {
|
||||||
|
f(true);
|
||||||
|
}
|
||||||
_ffi.enterOrLeave(true);
|
_ffi.enterOrLeave(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void leaveView(PointerExitEvent evt) {
|
void leaveView(PointerExitEvent evt) {
|
||||||
_cursorOverImage.value = false;
|
_cursorOverImage.value = false;
|
||||||
|
for (var f in _onEnterOrLeaveImage) {
|
||||||
|
f(false);
|
||||||
|
}
|
||||||
_ffi.enterOrLeave(false);
|
_ffi.enterOrLeave(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +477,7 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
paints.add(RemoteMenubar(
|
paints.add(RemoteMenubar(
|
||||||
id: widget.id,
|
id: widget.id,
|
||||||
ffi: _ffi,
|
ffi: _ffi,
|
||||||
|
onEnterOrLeaveImage: _onEnterOrLeaveImage,
|
||||||
));
|
));
|
||||||
return Stack(
|
return Stack(
|
||||||
children: paints,
|
children: paints,
|
||||||
@ -597,8 +606,8 @@ class ImagePaint extends StatelessWidget {
|
|||||||
return FlutterCustomMemoryImageCursor(
|
return FlutterCustomMemoryImageCursor(
|
||||||
pixbuf: cacheLinux.data,
|
pixbuf: cacheLinux.data,
|
||||||
key: key,
|
key: key,
|
||||||
hotx: 0.0,
|
hotx: cacheLinux.hotx,
|
||||||
hoty: 0.0,
|
hoty: cacheLinux.hoty,
|
||||||
imageWidth: (cacheLinux.width * scale).toInt(),
|
imageWidth: (cacheLinux.width * scale).toInt(),
|
||||||
imageHeight: (cacheLinux.height * scale).toInt(),
|
imageHeight: (cacheLinux.height * scale).toInt(),
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -25,11 +26,13 @@ class _MenubarTheme {
|
|||||||
class RemoteMenubar extends StatefulWidget {
|
class RemoteMenubar extends StatefulWidget {
|
||||||
final String id;
|
final String id;
|
||||||
final FFI ffi;
|
final FFI ffi;
|
||||||
|
final List<Function(bool)> onEnterOrLeaveImage;
|
||||||
|
|
||||||
const RemoteMenubar({
|
const RemoteMenubar({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.ffi,
|
required this.ffi,
|
||||||
|
required this.onEnterOrLeaveImage,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -39,12 +42,38 @@ class RemoteMenubar extends StatefulWidget {
|
|||||||
class _RemoteMenubarState extends State<RemoteMenubar> {
|
class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||||
final RxBool _show = false.obs;
|
final RxBool _show = false.obs;
|
||||||
final Rx<Color> _hideColor = Colors.white12.obs;
|
final Rx<Color> _hideColor = Colors.white12.obs;
|
||||||
|
final _rxHideReplay = rxdart.ReplaySubject<int>();
|
||||||
|
final _pinMenubar = false.obs;
|
||||||
|
bool _isCursorOverImage = false;
|
||||||
|
|
||||||
bool get isFullscreen => Get.find<RxBool>(tag: 'fullscreen').isTrue;
|
bool get isFullscreen => Get.find<RxBool>(tag: 'fullscreen').isTrue;
|
||||||
void setFullscreen(bool v) {
|
void _setFullscreen(bool v) {
|
||||||
Get.find<RxBool>(tag: 'fullscreen').value = v;
|
Get.find<RxBool>(tag: 'fullscreen').value = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
widget.onEnterOrLeaveImage.add((enter) {
|
||||||
|
if (enter) {
|
||||||
|
_rxHideReplay.add(0);
|
||||||
|
_isCursorOverImage = true;
|
||||||
|
} else {
|
||||||
|
_isCursorOverImage = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_rxHideReplay
|
||||||
|
.throttleTime(const Duration(milliseconds: 5000),
|
||||||
|
trailing: true, leading: false)
|
||||||
|
.listen((int v) {
|
||||||
|
if (_pinMenubar.isFalse && _show.isTrue && _isCursorOverImage) {
|
||||||
|
_show.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Align(
|
return Align(
|
||||||
@ -76,6 +105,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
Widget _buildMenubar(BuildContext context) {
|
Widget _buildMenubar(BuildContext context) {
|
||||||
final List<Widget> menubarItems = [];
|
final List<Widget> menubarItems = [];
|
||||||
if (!isWebDesktop) {
|
if (!isWebDesktop) {
|
||||||
|
menubarItems.add(_buildPinMenubar(context));
|
||||||
menubarItems.add(_buildFullscreen(context));
|
menubarItems.add(_buildFullscreen(context));
|
||||||
if (widget.ffi.ffiModel.isPeerAndroid) {
|
if (widget.ffi.ffiModel.isPeerAndroid) {
|
||||||
menubarItems.add(IconButton(
|
menubarItems.add(IconButton(
|
||||||
@ -111,11 +141,29 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildPinMenubar(BuildContext context) {
|
||||||
|
return Obx(() => IconButton(
|
||||||
|
tooltip:
|
||||||
|
translate(_pinMenubar.isTrue ? 'Unpin menubar' : 'Pin menubar'),
|
||||||
|
onPressed: () {
|
||||||
|
_pinMenubar.value = !_pinMenubar.value;
|
||||||
|
},
|
||||||
|
icon: Obx(() => Transform.rotate(
|
||||||
|
angle: _pinMenubar.isTrue ? math.pi / 4 : 0,
|
||||||
|
child: Icon(
|
||||||
|
Icons.push_pin,
|
||||||
|
color: _pinMenubar.isTrue
|
||||||
|
? _MenubarTheme.commonColor
|
||||||
|
: Colors.grey,
|
||||||
|
))),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildFullscreen(BuildContext context) {
|
Widget _buildFullscreen(BuildContext context) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
tooltip: translate(isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'),
|
tooltip: translate(isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setFullscreen(!isFullscreen);
|
_setFullscreen(!isFullscreen);
|
||||||
},
|
},
|
||||||
icon: Obx(() => isFullscreen
|
icon: Obx(() => isFullscreen
|
||||||
? const Icon(
|
? const Icon(
|
||||||
@ -250,7 +298,6 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
),
|
),
|
||||||
tooltip: translate('Display Settings'),
|
tooltip: translate('Display Settings'),
|
||||||
position: mod_menu.PopupMenuPosition.under,
|
position: mod_menu.PopupMenuPosition.under,
|
||||||
onSelected: (String item) {},
|
|
||||||
itemBuilder: (BuildContext context) => _getDisplayMenu()
|
itemBuilder: (BuildContext context) => _getDisplayMenu()
|
||||||
.map((entry) => entry.build(
|
.map((entry) => entry.build(
|
||||||
context,
|
context,
|
||||||
@ -273,7 +320,6 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
|||||||
),
|
),
|
||||||
tooltip: translate('Keyboard Settings'),
|
tooltip: translate('Keyboard Settings'),
|
||||||
position: mod_menu.PopupMenuPosition.under,
|
position: mod_menu.PopupMenuPosition.under,
|
||||||
onSelected: (String item) {},
|
|
||||||
itemBuilder: (BuildContext context) => _getKeyboardMenu()
|
itemBuilder: (BuildContext context) => _getKeyboardMenu()
|
||||||
.map((entry) => entry.build(
|
.map((entry) => entry.build(
|
||||||
context,
|
context,
|
||||||
|
@ -409,6 +409,56 @@ enum ScrollStyle {
|
|||||||
scrollauto,
|
scrollauto,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ViewStyle {
|
||||||
|
final String style;
|
||||||
|
final double width;
|
||||||
|
final double height;
|
||||||
|
final int displayWidth;
|
||||||
|
final int displayHeight;
|
||||||
|
ViewStyle({
|
||||||
|
this.style = '',
|
||||||
|
this.width = 0.0,
|
||||||
|
this.height = 0.0,
|
||||||
|
this.displayWidth = 0,
|
||||||
|
this.displayHeight = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
static int _double2Int(double v) => (v * 100).round().toInt();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
other is ViewStyle &&
|
||||||
|
other.runtimeType == runtimeType &&
|
||||||
|
_innerEqual(other);
|
||||||
|
|
||||||
|
bool _innerEqual(ViewStyle other) {
|
||||||
|
return style == other.style &&
|
||||||
|
ViewStyle._double2Int(other.width) == ViewStyle._double2Int(width) &&
|
||||||
|
ViewStyle._double2Int(other.height) == ViewStyle._double2Int(height) &&
|
||||||
|
other.displayWidth == displayWidth &&
|
||||||
|
other.displayHeight == displayHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
style,
|
||||||
|
ViewStyle._double2Int(width),
|
||||||
|
ViewStyle._double2Int(height),
|
||||||
|
displayWidth,
|
||||||
|
displayHeight,
|
||||||
|
).hashCode;
|
||||||
|
|
||||||
|
double get scale {
|
||||||
|
double s = 1.0;
|
||||||
|
if (style == 'adaptive') {
|
||||||
|
final s1 = width / displayWidth;
|
||||||
|
final s2 = height / displayHeight;
|
||||||
|
s = s1 < s2 ? s1 : s2;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CanvasModel with ChangeNotifier {
|
class CanvasModel with ChangeNotifier {
|
||||||
// image offset of canvas
|
// image offset of canvas
|
||||||
double _x = 0;
|
double _x = 0;
|
||||||
@ -425,7 +475,7 @@ class CanvasModel with ChangeNotifier {
|
|||||||
// scroll offset y percent
|
// scroll offset y percent
|
||||||
double _scrollY = 0.0;
|
double _scrollY = 0.0;
|
||||||
ScrollStyle _scrollStyle = ScrollStyle.scrollauto;
|
ScrollStyle _scrollStyle = ScrollStyle.scrollauto;
|
||||||
String? _viewStyle;
|
ViewStyle _lastViewStyle = ViewStyle();
|
||||||
|
|
||||||
WeakReference<FFI> parent;
|
WeakReference<FFI> parent;
|
||||||
|
|
||||||
@ -446,19 +496,27 @@ class CanvasModel with ChangeNotifier {
|
|||||||
|
|
||||||
updateViewStyle() async {
|
updateViewStyle() async {
|
||||||
final style = await bind.sessionGetOption(id: id, arg: 'view-style');
|
final style = await bind.sessionGetOption(id: id, arg: 'view-style');
|
||||||
if (style == null || _viewStyle == style) {
|
if (style == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final sizeWidth = size.width;
|
||||||
_scale = 1.0;
|
final sizeHeight = size.height;
|
||||||
if (style == 'adaptive') {
|
final displayWidth = getDisplayWidth();
|
||||||
final s1 = size.width / getDisplayWidth();
|
final displayHeight = getDisplayHeight();
|
||||||
final s2 = size.height / getDisplayHeight();
|
final viewStyle = ViewStyle(
|
||||||
_scale = s1 < s2 ? s1 : s2;
|
style: style,
|
||||||
|
width: sizeWidth,
|
||||||
|
height: sizeHeight,
|
||||||
|
displayWidth: displayWidth,
|
||||||
|
displayHeight: displayHeight,
|
||||||
|
);
|
||||||
|
if (_lastViewStyle == viewStyle) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
_viewStyle = style;
|
_lastViewStyle = viewStyle;
|
||||||
_x = (size.width - getDisplayWidth() * _scale) / 2;
|
_scale = viewStyle.scale;
|
||||||
_y = (size.height - getDisplayHeight() * _scale) / 2;
|
_x = (sizeWidth - displayWidth * _scale) / 2;
|
||||||
|
_y = (sizeHeight - displayHeight * _scale) / 2;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", "只允许白名单上的IP访问"),
|
("Use IP Whitelisting", "只允许白名单上的IP访问"),
|
||||||
("Network", "网络"),
|
("Network", "网络"),
|
||||||
("Enable RDP", "允许RDP访问"),
|
("Enable RDP", "允许RDP访问"),
|
||||||
|
("Pin menubar", "固定菜单栏"),
|
||||||
|
("Unpin menubar", "取消固定菜单栏"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Připnout panel nabídek"),
|
||||||
|
("Unpin menubar", "Odepnout panel nabídek"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Fastgør menulinjen"),
|
||||||
|
("Unpin menubar", "Frigør menulinjen"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Pin-Menüleiste"),
|
||||||
|
("Unpin menubar", "Menüleiste lösen"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Alpingla menubreto"),
|
||||||
|
("Unpin menubar", "Malfiksi menubreton"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -357,5 +357,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Pin barra de menú"),
|
||||||
|
("Unpin menubar", "Desbloquear barra de menú"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Épingler la barre de menus"),
|
||||||
|
("Unpin menubar", "Détacher la barre de menu"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Menüsor rögzítése"),
|
||||||
|
("Unpin menubar", "Menüsor rögzítésének feloldása"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -357,5 +357,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Pin menubar"),
|
||||||
|
("Unpin menubar", "Unpin menubar"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -343,5 +343,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Blocca la barra dei menu"),
|
||||||
|
("Unpin menubar", "Sblocca la barra dei menu"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -341,5 +341,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "メニューバーを固定する"),
|
||||||
|
("Unpin menubar", "メニューバーのピン留めを外す"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -338,5 +338,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "핀 메뉴 바"),
|
||||||
|
("Unpin menubar", "메뉴 모음 고정 해제"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -319,5 +319,7 @@ lazy_static::lazy_static! {
|
|||||||
("Insecure Connection", "Қатерлі Қосылым"),
|
("Insecure Connection", "Қатерлі Қосылым"),
|
||||||
("Scale original", "Scale original"),
|
("Scale original", "Scale original"),
|
||||||
("Scale adaptive", "Scale adaptive"),
|
("Scale adaptive", "Scale adaptive"),
|
||||||
|
("Pin menubar", "Мәзір жолағын бекіту"),
|
||||||
|
("Unpin menubar", "Мәзір жолағын босату"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -342,5 +342,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Przypnij pasek menu"),
|
||||||
|
("Unpin menubar", "Odepnij pasek menu"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -338,5 +338,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Fixar barra de menu"),
|
||||||
|
("Unpin menubar", "Desenganxa la barra de menús"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", ""),
|
||||||
|
("Unpin menubar", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Закрепить строку меню"),
|
||||||
|
("Unpin menubar", "Открепить строку меню"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Pripnúť panel s ponukami"),
|
||||||
|
("Unpin menubar", "Uvoľniť panel s ponukami"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", ""),
|
||||||
|
("Unpin menubar", ""),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -357,5 +357,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Menü çubuğunu sabitle"),
|
||||||
|
("Unpin menubar", "Menü çubuğunun sabitlemesini kaldır"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", "只允許白名單上的IP訪問"),
|
("Use IP Whitelisting", "只允許白名單上的IP訪問"),
|
||||||
("Network", "網絡"),
|
("Network", "網絡"),
|
||||||
("Enable RDP", "允許RDP訪問"),
|
("Enable RDP", "允許RDP訪問"),
|
||||||
|
("Pin menubar", "固定菜單欄"),
|
||||||
|
("Unpin menubar", "取消固定菜單欄"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
@ -344,5 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("Use IP Whitelisting", ""),
|
("Use IP Whitelisting", ""),
|
||||||
("Network", ""),
|
("Network", ""),
|
||||||
("Enable RDP", ""),
|
("Enable RDP", ""),
|
||||||
|
("Pin menubar", "Ghim thanh menu"),
|
||||||
|
("Unpin menubar", "Bỏ ghim thanh menu"),
|
||||||
].iter().cloned().collect();
|
].iter().cloned().collect();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user