feat: remote printer (#11231)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -3789,3 +3789,29 @@ void updateTextAndPreserveSelection(
|
||||
baseOffset: 0, extentOffset: controller.value.text.length);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> getPrinterNames() {
|
||||
final printerNamesJson = bind.mainGetPrinterNames();
|
||||
if (printerNamesJson.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
final List<dynamic> printerNamesList = jsonDecode(printerNamesJson);
|
||||
final appPrinterName = '$appName Printer';
|
||||
return printerNamesList
|
||||
.map((e) => e.toString())
|
||||
.where((name) => name != appPrinterName)
|
||||
.toList();
|
||||
} catch (e) {
|
||||
debugPrint('failed to parse printer names, err: $e');
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
String _appName = '';
|
||||
String get appName {
|
||||
if (_appName.isEmpty) {
|
||||
_appName = bind.mainGetAppNameSync();
|
||||
}
|
||||
return _appName;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'dart:convert';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_hbb/common/shared_state.dart';
|
||||
import 'package:flutter_hbb/common/widgets/setting_widgets.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
|
||||
@@ -98,6 +98,7 @@ const String kOptionVideoSaveDirectory = "video-save-directory";
|
||||
const String kOptionAccessMode = "access-mode";
|
||||
const String kOptionEnableKeyboard = "enable-keyboard";
|
||||
// "Settings -> Security -> Permissions"
|
||||
const String kOptionEnableRemotePrinter = "enable-remote-printer";
|
||||
const String kOptionEnableClipboard = "enable-clipboard";
|
||||
const String kOptionEnableFileTransfer = "enable-file-transfer";
|
||||
const String kOptionEnableAudio = "enable-audio";
|
||||
@@ -219,6 +220,14 @@ const double kDefaultQuality = 50;
|
||||
const double kMaxQuality = 100;
|
||||
const double kMaxMoreQuality = 2000;
|
||||
|
||||
const String kKeyPrinterIncommingJobAction = 'printer-incomming-job-action';
|
||||
const String kValuePrinterIncomingJobDismiss = 'dismiss';
|
||||
const String kValuePrinterIncomingJobDefault = '';
|
||||
const String kValuePrinterIncomingJobSelected = 'selected';
|
||||
const String kKeyPrinterSelected = 'printer-selected-name';
|
||||
const String kKeyPrinterSave = 'allow-printer-dialog-save';
|
||||
const String kKeyPrinterAllowAutoPrint = 'allow-printer-auto-print';
|
||||
|
||||
double kNewWindowOffset = isWindows
|
||||
? 56.0
|
||||
: isLinux
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
|
||||
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
||||
import 'package:flutter_hbb/mobile/widgets/dialog.dart';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
import 'package:flutter_hbb/models/printer_model.dart';
|
||||
import 'package:flutter_hbb/models/server_model.dart';
|
||||
import 'package:flutter_hbb/models/state_model.dart';
|
||||
import 'package:flutter_hbb/plugin/manager.dart';
|
||||
@@ -55,6 +56,7 @@ enum SettingsTabKey {
|
||||
display,
|
||||
plugin,
|
||||
account,
|
||||
printer,
|
||||
about,
|
||||
}
|
||||
|
||||
@@ -74,6 +76,7 @@ class DesktopSettingPage extends StatefulWidget {
|
||||
if (!isWeb && !bind.isIncomingOnly() && bind.pluginFeatureIsEnabled())
|
||||
SettingsTabKey.plugin,
|
||||
if (!bind.isDisableAccount()) SettingsTabKey.account,
|
||||
if (isWindows) SettingsTabKey.printer,
|
||||
SettingsTabKey.about,
|
||||
];
|
||||
|
||||
@@ -198,6 +201,10 @@ class _DesktopSettingPageState extends State<DesktopSettingPage>
|
||||
settingTabs.add(
|
||||
_TabInfo(tab, 'Account', Icons.person_outline, Icons.person));
|
||||
break;
|
||||
case SettingsTabKey.printer:
|
||||
settingTabs
|
||||
.add(_TabInfo(tab, 'Printer', Icons.print_outlined, Icons.print));
|
||||
break;
|
||||
case SettingsTabKey.about:
|
||||
settingTabs
|
||||
.add(_TabInfo(tab, 'About', Icons.info_outline, Icons.info));
|
||||
@@ -229,6 +236,9 @@ class _DesktopSettingPageState extends State<DesktopSettingPage>
|
||||
case SettingsTabKey.account:
|
||||
children.add(const _Account());
|
||||
break;
|
||||
case SettingsTabKey.printer:
|
||||
children.add(const _Printer());
|
||||
break;
|
||||
case SettingsTabKey.about:
|
||||
children.add(const _About());
|
||||
break;
|
||||
@@ -963,6 +973,10 @@ class _SafetyState extends State<_Safety> with AutomaticKeepAliveClientMixin {
|
||||
_OptionCheckBox(
|
||||
context, 'Enable keyboard/mouse', kOptionEnableKeyboard,
|
||||
enabled: enabled, fakeValue: fakeValue),
|
||||
if (isWindows)
|
||||
_OptionCheckBox(
|
||||
context, 'Enable remote printer', kOptionEnableRemotePrinter,
|
||||
enabled: enabled, fakeValue: fakeValue),
|
||||
_OptionCheckBox(context, 'Enable clipboard', kOptionEnableClipboard,
|
||||
enabled: enabled, fakeValue: fakeValue),
|
||||
_OptionCheckBox(
|
||||
@@ -1881,6 +1895,153 @@ class _PluginState extends State<_Plugin> {
|
||||
}
|
||||
}
|
||||
|
||||
class _Printer extends StatefulWidget {
|
||||
const _Printer({super.key});
|
||||
|
||||
@override
|
||||
State<_Printer> createState() => __PrinterState();
|
||||
}
|
||||
|
||||
class __PrinterState extends State<_Printer> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scrollController = ScrollController();
|
||||
return ListView(controller: scrollController, children: [
|
||||
outgoing(context),
|
||||
incomming(context),
|
||||
]).marginOnly(bottom: _kListViewBottomMargin);
|
||||
}
|
||||
|
||||
Widget outgoing(BuildContext context) {
|
||||
final isSupportPrinterDriver =
|
||||
bind.mainGetCommonSync(key: 'is-support-printer-driver') == 'true';
|
||||
|
||||
Widget tipOsNotSupported() {
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(translate('printer-os-requirement-tip')),
|
||||
).marginOnly(left: _kCardLeftMargin);
|
||||
}
|
||||
|
||||
Widget tipClientNotInstalled() {
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child:
|
||||
Text(translate('printer-requires-installed-{$appName}-client-tip')),
|
||||
).marginOnly(left: _kCardLeftMargin);
|
||||
}
|
||||
|
||||
Widget tipPrinterNotInstalled() {
|
||||
final failedMsg = ''.obs;
|
||||
platformFFI.registerEventHandler(
|
||||
'install-printer-res', 'install-printer-res', (evt) async {
|
||||
if (evt['success'] as bool) {
|
||||
setState(() {});
|
||||
} else {
|
||||
failedMsg.value = evt['msg'] as String;
|
||||
}
|
||||
}, replace: true);
|
||||
return Column(children: [
|
||||
Obx(
|
||||
() => failedMsg.value.isNotEmpty
|
||||
? Offstage()
|
||||
: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(translate('printer-{$appName}-not-installed-tip'))
|
||||
.marginOnly(bottom: 10.0),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => failedMsg.value.isEmpty
|
||||
? Offstage()
|
||||
: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(failedMsg.value,
|
||||
style: DefaultTextStyle.of(context)
|
||||
.style
|
||||
.copyWith(color: Colors.red))
|
||||
.marginOnly(bottom: 10.0)),
|
||||
),
|
||||
_Button('Install {$appName} Printer', () {
|
||||
failedMsg.value = '';
|
||||
bind.mainSetCommon(key: 'install-printer', value: '');
|
||||
})
|
||||
]).marginOnly(left: _kCardLeftMargin, bottom: 2.0);
|
||||
}
|
||||
|
||||
Widget tipReady() {
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(translate('printer-{$appName}-ready-tip')),
|
||||
).marginOnly(left: _kCardLeftMargin);
|
||||
}
|
||||
|
||||
final installed = bind.mainIsInstalled();
|
||||
// `is-printer-installed` may fail, but it's rare case.
|
||||
// Add additional error message here if it's really needed.
|
||||
final driver_installed =
|
||||
bind.mainGetCommonSync(key: 'is-printer-installed') == 'true';
|
||||
|
||||
final List<Widget> children = [];
|
||||
if (!isSupportPrinterDriver) {
|
||||
children.add(tipOsNotSupported());
|
||||
} else {
|
||||
children.addAll([
|
||||
if (!installed) tipClientNotInstalled(),
|
||||
if (installed && !driver_installed) tipPrinterNotInstalled(),
|
||||
if (installed && driver_installed) tipReady()
|
||||
]);
|
||||
}
|
||||
return _Card(title: 'Outgoing Print Jobs', children: children);
|
||||
}
|
||||
|
||||
Widget incomming(BuildContext context) {
|
||||
onRadioChanged(String value) async {
|
||||
await bind.mainSetLocalOption(
|
||||
key: kKeyPrinterIncommingJobAction, value: value);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
PrinterOptions printerOptions = PrinterOptions.load();
|
||||
return _Card(title: 'Incomming Print Jobs', children: [
|
||||
_Radio(context,
|
||||
value: kValuePrinterIncomingJobDismiss,
|
||||
groupValue: printerOptions.action,
|
||||
label: 'Dismiss',
|
||||
onChanged: onRadioChanged),
|
||||
_Radio(context,
|
||||
value: kValuePrinterIncomingJobDefault,
|
||||
groupValue: printerOptions.action,
|
||||
label: 'use-the-default-printer-tip',
|
||||
onChanged: onRadioChanged),
|
||||
_Radio(context,
|
||||
value: kValuePrinterIncomingJobSelected,
|
||||
groupValue: printerOptions.action,
|
||||
label: 'use-the-selected-printer-tip',
|
||||
onChanged: onRadioChanged),
|
||||
if (printerOptions.printerNames.isNotEmpty)
|
||||
ComboBox(
|
||||
initialKey: printerOptions.printerName,
|
||||
keys: printerOptions.printerNames,
|
||||
values: printerOptions.printerNames,
|
||||
enabled: printerOptions.action == kValuePrinterIncomingJobSelected,
|
||||
onChanged: (value) async {
|
||||
await bind.mainSetLocalOption(
|
||||
key: kKeyPrinterSelected, value: value);
|
||||
setState(() {});
|
||||
},
|
||||
).marginOnly(left: 10),
|
||||
_OptionCheckBox(
|
||||
context,
|
||||
'auto-print-tip',
|
||||
kKeyPrinterAllowAutoPrint,
|
||||
isServer: false,
|
||||
enabled: printerOptions.action != kValuePrinterIncomingJobDismiss,
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
class _About extends StatefulWidget {
|
||||
const _About({Key? key}) : super(key: key);
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ class _InstallPageBodyState extends State<_InstallPageBody>
|
||||
late final TextEditingController controller;
|
||||
final RxBool startmenu = true.obs;
|
||||
final RxBool desktopicon = true.obs;
|
||||
final RxBool printer = true.obs;
|
||||
final RxBool showProgress = false.obs;
|
||||
final RxBool btnEnabled = true.obs;
|
||||
|
||||
@@ -79,6 +80,7 @@ class _InstallPageBodyState extends State<_InstallPageBody>
|
||||
final installOptions = jsonDecode(bind.installInstallOptions());
|
||||
startmenu.value = installOptions['STARTMENUSHORTCUTS'] != '0';
|
||||
desktopicon.value = installOptions['DESKTOPSHORTCUTS'] != '0';
|
||||
printer.value = installOptions['PRINTER'] != '0';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -161,7 +163,9 @@ class _InstallPageBodyState extends State<_InstallPageBody>
|
||||
).marginSymmetric(vertical: 2 * em),
|
||||
Option(startmenu, label: 'Create start menu shortcuts')
|
||||
.marginOnly(bottom: 7),
|
||||
Option(desktopicon, label: 'Create desktop icon'),
|
||||
Option(desktopicon, label: 'Create desktop icon')
|
||||
.marginOnly(bottom: 7),
|
||||
Option(printer, label: 'Install {$appName} Printer'),
|
||||
Container(
|
||||
padding: EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
@@ -253,6 +257,7 @@ class _InstallPageBodyState extends State<_InstallPageBody>
|
||||
String args = '';
|
||||
if (startmenu.value) args += ' startmenu';
|
||||
if (desktopicon.value) args += ' desktopicon';
|
||||
if (printer.value) args += ' printer';
|
||||
bind.installInstallMe(options: args, path: controller.text);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,15 @@ enum SortBy {
|
||||
class JobID {
|
||||
int _count = 0;
|
||||
int next() {
|
||||
_count++;
|
||||
return _count;
|
||||
String v = bind.mainGetCommonSync(key: 'transfer-job-id');
|
||||
try {
|
||||
return int.parse(v);
|
||||
} catch (e) {
|
||||
// unreachable. But we still handle it to make it safe.
|
||||
// If we return -1, we have to check it in the caller.
|
||||
_count++;
|
||||
return _count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_hbb/common/widgets/peers_view.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/models/ab_model.dart';
|
||||
@@ -19,6 +18,7 @@ import 'package:flutter_hbb/models/file_model.dart';
|
||||
import 'package:flutter_hbb/models/group_model.dart';
|
||||
import 'package:flutter_hbb/models/peer_model.dart';
|
||||
import 'package:flutter_hbb/models/peer_tab_model.dart';
|
||||
import 'package:flutter_hbb/models/printer_model.dart';
|
||||
import 'package:flutter_hbb/models/server_model.dart';
|
||||
import 'package:flutter_hbb/models/user_model.dart';
|
||||
import 'package:flutter_hbb/models/state_model.dart';
|
||||
@@ -412,12 +412,186 @@ class FfiModel with ChangeNotifier {
|
||||
isMobile) {
|
||||
parent.target?.recordingModel.updateStatus(evt['start'] == 'true');
|
||||
}
|
||||
} else if (name == "printer_request") {
|
||||
_handlePrinterRequest(evt, sessionId, peerId);
|
||||
} else {
|
||||
debugPrint('Event is not handled in the fixed branch: $name');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_handlePrinterRequest(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
final id = evt['id'];
|
||||
final path = evt['path'];
|
||||
final dialogManager = parent.target!.dialogManager;
|
||||
dialogManager.show((setState, close, context) {
|
||||
PrinterOptions printerOptions = PrinterOptions.load();
|
||||
final saveSettings = mainGetLocalBoolOptionSync(kKeyPrinterSave).obs;
|
||||
final dontShowAgain = false.obs;
|
||||
final Rx<String> selectedPrinterName = printerOptions.printerName.obs;
|
||||
final printerNames = printerOptions.printerNames;
|
||||
final defaultOrSelectedGroupValue =
|
||||
(printerOptions.action == kValuePrinterIncomingJobDismiss
|
||||
? kValuePrinterIncomingJobDefault
|
||||
: printerOptions.action)
|
||||
.obs;
|
||||
|
||||
onRatioChanged(String? value) {
|
||||
defaultOrSelectedGroupValue.value =
|
||||
value ?? kValuePrinterIncomingJobDefault;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
final printerName = defaultOrSelectedGroupValue.isEmpty
|
||||
? ''
|
||||
: selectedPrinterName.value;
|
||||
bind.sessionPrinterResponse(
|
||||
sessionId: sessionId, id: id, path: path, printerName: printerName);
|
||||
if (saveSettings.value || dontShowAgain.value) {
|
||||
bind.mainSetLocalOption(key: kKeyPrinterSelected, value: printerName);
|
||||
bind.mainSetLocalOption(
|
||||
key: kKeyPrinterIncommingJobAction,
|
||||
value: defaultOrSelectedGroupValue.value);
|
||||
}
|
||||
if (dontShowAgain.value) {
|
||||
mainSetLocalBoolOption(kKeyPrinterAllowAutoPrint, true);
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
if (dontShowAgain.value) {
|
||||
bind.mainSetLocalOption(
|
||||
key: kKeyPrinterIncommingJobAction,
|
||||
value: kValuePrinterIncomingJobDismiss);
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
final printerItemHeight = 30.0;
|
||||
final selectionAreaHeight =
|
||||
printerItemHeight * min(8.0, max(printerNames.length, 3.0));
|
||||
final content = Column(
|
||||
children: [
|
||||
Text(translate('print-incoming-job-confirm-tip')),
|
||||
Row(
|
||||
children: [
|
||||
Obx(() => Radio<String>(
|
||||
value: kValuePrinterIncomingJobDefault,
|
||||
groupValue: defaultOrSelectedGroupValue.value,
|
||||
onChanged: onRatioChanged)),
|
||||
GestureDetector(
|
||||
child: Text(translate('use-the-default-printer-tip')),
|
||||
onTap: () => onRatioChanged(kValuePrinterIncomingJobDefault)),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Row(children: [
|
||||
Obx(() => Radio<String>(
|
||||
value: kValuePrinterIncomingJobSelected,
|
||||
groupValue: defaultOrSelectedGroupValue.value,
|
||||
onChanged: onRatioChanged)),
|
||||
GestureDetector(
|
||||
child: Text(translate('use-the-selected-printer-tip')),
|
||||
onTap: () =>
|
||||
onRatioChanged(kValuePrinterIncomingJobSelected)),
|
||||
]),
|
||||
SizedBox(
|
||||
height: selectionAreaHeight,
|
||||
width: 500,
|
||||
child: ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return Obx(() => GestureDetector(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: selectedPrinterName.value ==
|
||||
printerNames[index]
|
||||
? (defaultOrSelectedGroupValue.value ==
|
||||
kValuePrinterIncomingJobSelected
|
||||
? MyTheme.button
|
||||
: MyTheme.button.withOpacity(0.5))
|
||||
: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(5.0),
|
||||
),
|
||||
),
|
||||
key: ValueKey(printerNames[index]),
|
||||
height: printerItemHeight,
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0),
|
||||
child: Text(
|
||||
printerNames[index],
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: defaultOrSelectedGroupValue.value ==
|
||||
kValuePrinterIncomingJobSelected
|
||||
? () {
|
||||
selectedPrinterName.value =
|
||||
printerNames[index];
|
||||
}
|
||||
: null,
|
||||
));
|
||||
},
|
||||
itemCount: printerNames.length),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Obx(() => Checkbox(
|
||||
value: saveSettings.value,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
saveSettings.value = value;
|
||||
mainSetLocalBoolOption(kKeyPrinterSave, value);
|
||||
}
|
||||
})),
|
||||
GestureDetector(
|
||||
child: Text(translate('save-settings-tip')),
|
||||
onTap: () {
|
||||
saveSettings.value = !saveSettings.value;
|
||||
mainSetLocalBoolOption(kKeyPrinterSave, saveSettings.value);
|
||||
}),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Obx(() => Checkbox(
|
||||
value: dontShowAgain.value,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
dontShowAgain.value = value;
|
||||
}
|
||||
})),
|
||||
GestureDetector(
|
||||
child: Text(translate('dont-show-again-tip')),
|
||||
onTap: () {
|
||||
dontShowAgain.value = !dontShowAgain.value;
|
||||
}),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate('Incoming Print Job')),
|
||||
content: content,
|
||||
actions: [
|
||||
dialogButton('OK', onPressed: onSubmit),
|
||||
dialogButton('Cancel', onPressed: onCancel),
|
||||
],
|
||||
onSubmit: onSubmit,
|
||||
onCancel: onCancel,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
_handleUseTextureRender(
|
||||
Map<String, dynamic> evt, SessionID sessionId, String peerId) {
|
||||
parent.target?.imageModel.setUseTextureRender(evt['v'] == 'Y');
|
||||
|
||||
@@ -60,14 +60,14 @@ class PlatformFFI {
|
||||
}
|
||||
|
||||
bool registerEventHandler(
|
||||
String eventName, String handlerName, HandleEvent handler) {
|
||||
String eventName, String handlerName, HandleEvent handler, {bool replace = false}) {
|
||||
debugPrint('registerEventHandler $eventName $handlerName');
|
||||
var handlers = _eventHandlers[eventName];
|
||||
if (handlers == null) {
|
||||
_eventHandlers[eventName] = {handlerName: handler};
|
||||
return true;
|
||||
} else {
|
||||
if (handlers.containsKey(handlerName)) {
|
||||
if (!replace && handlers.containsKey(handlerName)) {
|
||||
return false;
|
||||
} else {
|
||||
handlers[handlerName] = handler;
|
||||
|
||||
48
flutter/lib/models/printer_model.dart
Normal file
48
flutter/lib/models/printer_model.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/models/platform_model.dart';
|
||||
|
||||
class PrinterOptions {
|
||||
String action;
|
||||
List<String> printerNames;
|
||||
String printerName;
|
||||
|
||||
PrinterOptions(
|
||||
{required this.action,
|
||||
required this.printerNames,
|
||||
required this.printerName});
|
||||
|
||||
static PrinterOptions load() {
|
||||
var action = bind.mainGetLocalOption(key: kKeyPrinterIncommingJobAction);
|
||||
if (![
|
||||
kValuePrinterIncomingJobDismiss,
|
||||
kValuePrinterIncomingJobDefault,
|
||||
kValuePrinterIncomingJobSelected
|
||||
].contains(action)) {
|
||||
action = kValuePrinterIncomingJobDefault;
|
||||
}
|
||||
|
||||
final printerNames = getPrinterNames();
|
||||
var selectedPrinterName = bind.mainGetLocalOption(key: kKeyPrinterSelected);
|
||||
if (!printerNames.contains(selectedPrinterName)) {
|
||||
if (action == kValuePrinterIncomingJobSelected) {
|
||||
action = kValuePrinterIncomingJobDefault;
|
||||
bind.mainSetLocalOption(
|
||||
key: kKeyPrinterIncommingJobAction,
|
||||
value: kValuePrinterIncomingJobDefault);
|
||||
if (printerNames.isEmpty) {
|
||||
selectedPrinterName = '';
|
||||
} else {
|
||||
selectedPrinterName = printerNames.first;
|
||||
}
|
||||
bind.mainSetLocalOption(
|
||||
key: kKeyPrinterSelected, value: selectedPrinterName);
|
||||
}
|
||||
}
|
||||
|
||||
return PrinterOptions(
|
||||
action: action,
|
||||
printerNames: printerNames,
|
||||
printerName: selectedPrinterName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user