Sat, 02 Sep 2017 20:00:57 +0200
Started implementing a downloader and installer for web browser spell check dictionaries.
# -*- coding: utf-8 -*- # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing a dialog to install spell checking dictionaries. """ from __future__ import unicode_literals from PyQt5.QtCore import pyqtSlot, Qt, QUrl from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ QListWidgetItem from PyQt5.QtNetwork import QNetworkConfigurationManager, QNetworkRequest, \ QNetworkReply from E5Gui import E5MessageBox from .Ui_InstallDictionariesDialog import Ui_InstallDictionariesDialog from WebBrowser.WebBrowserWindow import WebBrowserWindow import Preferences class InstallDictionariesDialog(QDialog, Ui_InstallDictionariesDialog): """ Class implementing a dialog to install spell checking dictionaries. """ FilenameRole = Qt.UserRole def __init__(self, writeableDirectories, parent=None): """ Constructor @param writeableDirectories list of writable directories @type list of str @param parent reference to the parent widget @type QWidget """ super(InstallDictionariesDialog, self).__init__(parent) self.setupUi(self) self.__refreshButton = self.buttonBox.addButton( self.tr("Refresh"), QDialogButtonBox.ActionRole) self.__installButton = self.buttonBox.addButton( self.tr("Install Selected"), QDialogButtonBox.ActionRole) self.__installButton.setEnabled(False) self.__cancelButton = self.buttonBox.addButton( self.tr("Cancel"), QDialogButtonBox.ActionRole) self.__cancelButton.setEnabled(False) self.locationComboBox.addItems(writeableDirectories) self.dictionariesUrlEdit.setText( Preferences.getWebBrowser("SpellCheckDictionariesUrl")) if Preferences.getUI("DynamicOnlineCheck"): self.__networkConfigurationManager = \ QNetworkConfigurationManager(self) self.__onlineStateChanged( self.__networkConfigurationManager.isOnline()) self.__networkConfigurationManager.onlineStateChanged.connect( self.__onlineStateChanged) else: self.__networkConfigurationManager = None self.__onlineStateChanged(True) self.__replies = [] self.__downloadCancelled = False self.__dictionariesToDownload = [] self.__populateList() @pyqtSlot(bool) def __onlineStateChanged(self, online): """ Private slot handling online state changes. @param online flag indicating the online status @type bool """ self.__refreshButton.setEnabled(online) if online: msg = self.tr("Network Status: online") else: msg = self.tr("Network Status: offline") self.statusLabel.setText(msg) def __isOnline(self): """ Private method to check the online status. @return flag indicating the online status @rtype bool """ if self.__networkConfigurationManager is not None: return self.__networkConfigurationManager.isOnline() else: return True @pyqtSlot(QAbstractButton) def on_buttonBox_clicked(self, button): """ Private slot to handle the click of a button of the button box. @param button reference to the button pressed @type QAbstractButton """ if button == self.__refreshButton: self.__populateList() elif button == self.__cancelButton: self.__downloadCancel() elif button == self.__installButton: self.__installSelected() @pyqtSlot() def on_dictionariesList_itemSelectionChanged(self): """ Private slot to handle a change of the selection. """ self.__installButton.setEnabled( len(self.dictionariesList.selectedItems()) > 0) def __populateList(self): """ Private method to populate the list of available plugins. """ self.dictionariesList.clear() self.downloadProgress.setValue(0) if self.__isOnline(): self.__refreshButton.setEnabled(False) self.__installButton.setEnabled(False) self.__cancelButton.setEnabled(True) url = self.dictionariesUrlEdit.text() self.statusLabel.setText(url) self.__downloadCancelled = False request = QNetworkRequest(QUrl(url)) request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) reply = WebBrowserWindow.networkManager().get(request) reply.finished.connect(self.__listFileDownloaded) reply.downloadProgress.connect(self.__downloadProgress) self.__replies.append(reply) def __listFileDownloaded(self): """ Private method called, after the dictionaries list file has been downloaded from the Internet. """ self.__refreshButton.setEnabled(True) self.__cancelButton.setEnabled(False) self.__onlineStateChanged(self.__isOnline()) reply = self.sender() if reply in self.__replies: self.__replies.remove(reply) if reply.error() != QNetworkReply.NoError: if not self.__downloadCancelled: E5MessageBox.warning( self, self.tr("Error downloading dictionaries list"), self.tr( """<p>Could not download the dictionaries list""" """ from {0}.</p><p>Error: {1}</p>""" ).format(self.repositoryUrlEdit.text(), reply.errorString()) ) self.downloadProgress.setValue(0) reply.deleteLater() return listFileData = reply.readAll() reply.deleteLater() # extract the dictionaries from E5XML.SpellCheckDictionariesReader import \ SpellCheckDictionariesReader reader = SpellCheckDictionariesReader(listFileData, self.addEntry) reader.readXML() url = Preferences.getWebBrowser("SpellCheckDictionariesUrl") if url != self.dictionariesUrlEdit.text(): self.dictionariesUrlEdit.setText(url) E5MessageBox.warning( self, self.tr("Dictionaries URL Changed"), self.tr( """The URL of the spell check dictionaries has""" """ changed. Select the "Refresh" button to get""" """ the new dictionaries list.""")) def __downloadCancel(self): """ Private slot to cancel the current download. """ if self.__replies: reply = self.__replies[0] self.__downloadCancelled = True self.__dictionariesToDownload = [] reply.abort() def __downloadProgress(self, done, total): """ Private slot to show the download progress. @param done number of bytes downloaded so far @type int @param total total bytes to be downloaded @type int """ if total: self.downloadProgress.setMaximum(total) self.downloadProgress.setValue(done) def addEntry(self, short, filename): """ Public method to add an entry to the list. @param short data for the description field @type str @param filename data for the filename field @type str """ itm = QListWidgetItem(short, self.dictionariesList) itm.setData(InstallDictionariesDialog.FilenameRole, filename) def __installSelected(self): """ Private method to install the selected dictionaries. """ self.__dictionariesToDownload = [ itm.data(InstallDictionariesDialog.FilenameRole) for itm in self.dictionariesList.selectedItems() ] self.__refreshButton.setEnabled(False) self.__installButton.setEnabled(False) self.__cancelButton.setEnabled(True) self.__downloadCancelled = False self.__downloadDictionary() def __downloadDictionary(self): """ Private slot to download a dictionary. """ # TODO: implement this # use __installDictionary as finish slot def __installDictionary(self): """ Private slot to install the downloaded dictionary. """ # TODO: implement this if not bool(self.__dictionariesToDownload): self.__installationFinished() def __installationFinished(self): """ Private method called after all selected dictionaries have been installed. """ # TODO: implement this