FreeCAD
125 строк · 5.7 Кб
1# SPDX-License-Identifier: LGPL-2.1-or-later
2# ***************************************************************************
3# * *
4# * Copyright (c) 2022 FreeCAD Project Association *
5# * *
6# * This file is part of FreeCAD. *
7# * *
8# * FreeCAD is free software: you can redistribute it and/or modify it *
9# * under the terms of the GNU Lesser General Public License as *
10# * published by the Free Software Foundation, either version 2.1 of the *
11# * License, or (at your option) any later version. *
12# * *
13# * FreeCAD is distributed in the hope that it will be useful, but *
14# * WITHOUT ANY WARRANTY; without even the implied warranty of *
15# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16# * Lesser General Public License for more details. *
17# * *
18# * You should have received a copy of the GNU Lesser General Public *
19# * License along with FreeCAD. If not, see *
20# * <https://www.gnu.org/licenses/>. *
21# * *
22# ***************************************************************************
23
24""" System for checking the network connection status asynchronously. """
25
26import FreeCAD27
28from PySide import QtCore, QtWidgets29
30import NetworkManager31from addonmanager_workers_utility import ConnectionChecker32
33translate = FreeCAD.Qt.translate34
35
36class ConnectionCheckerGUI(QtCore.QObject):37"""Determine whether there is an active network connection, showing a progress message if it38starts to take too long, and an error message if the network cannot be accessed."""
39
40connection_available = QtCore.Signal()41check_complete = QtCore.Signal()42
43def __init__(self):44super().__init__()45
46# Check the connection in a new thread, so FreeCAD stays responsive47self.connection_checker = ConnectionChecker()48self.signals_connected = False49
50self.connection_message_timer = None51self.connection_check_message = None52
53def start(self):54"""Start the connection check"""55self.connection_checker.start()56self.connection_checker.success.connect(self._check_succeeded)57self.connection_checker.failure.connect(self._network_connection_failed)58self.signals_connected = True59
60# If it takes longer than a half second to check the connection, show a message:61self.connection_message_timer = QtCore.QTimer.singleShot(62500, self._show_connection_check_message63)64
65def _show_connection_check_message(self):66"""Display a message informing the user that the check is in process"""67if not self.connection_checker.isFinished():68self.connection_check_message = QtWidgets.QMessageBox(69QtWidgets.QMessageBox.Information,70translate("AddonsInstaller", "Checking connection"),71translate("AddonsInstaller", "Checking for connection to GitHub..."),72QtWidgets.QMessageBox.Cancel,73)74self.connection_check_message.buttonClicked.connect(self.cancel_network_check)75self.connection_check_message.show()76
77def cancel_network_check(self, _):78"""Cancel the check"""79if not self.connection_checker.isFinished():80self._disconnect_signals()81self.connection_checker.requestInterruption()82self.connection_checker.wait(500)83self.connection_check_message.close()84self.check_complete.emit()85
86def _network_connection_failed(self, message: str) -> None:87"""Callback for failed connection check. Displays an error message, then emits the88check_complete signal (but not the connection available signal)."""
89# This must run on the main GUI thread90if hasattr(self, "connection_check_message") and self.connection_check_message:91self.connection_check_message.close()92if NetworkManager.HAVE_QTNETWORK:93QtWidgets.QMessageBox.critical(94None, translate("AddonsInstaller", "Connection failed"), message95)96else:97# pylint: disable=line-too-long98QtWidgets.QMessageBox.critical(99None,100translate("AddonsInstaller", "Missing dependency"),101translate(102"AddonsInstaller",103"Could not import QtNetwork -- see Report View for details. Addon Manager "104"unavailable.",105),106)107
108self._disconnect_signals()109self.check_complete.emit()110
111def _check_succeeded(self):112"""Emit both the connection_available and the check_complete signals, in that order."""113
114if hasattr(self, "connection_check_message") and self.connection_check_message:115self.connection_check_message.close()116
117self.connection_available.emit()118self._disconnect_signals()119self.check_complete.emit()120
121def _disconnect_signals(self):122if self.signals_connected:123self.connection_checker.success.disconnect(self._check_succeeded)124self.connection_checker.failure.disconnect(self._network_connection_failed)125self.signals_connected = False126