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 FreeCAD
27
28from PySide import QtCore, QtWidgets
29
30import NetworkManager
31from addonmanager_workers_utility import ConnectionChecker
32
33translate = FreeCAD.Qt.translate
34
35
36class ConnectionCheckerGUI(QtCore.QObject):
37"""Determine whether there is an active network connection, showing a progress message if it
38starts 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 responsive
47self.connection_checker = ConnectionChecker()
48self.signals_connected = False
49
50self.connection_message_timer = None
51self.connection_check_message = None
52
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 = True
59
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_message
63)
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 the
88check_complete signal (but not the connection available signal)."""
89# This must run on the main GUI thread
90if 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"), message
95)
96else:
97# pylint: disable=line-too-long
98QtWidgets.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 = False
126