class RemoteUpdater(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)): """ | Defines the Application remote updater. | The remote updater is initialized with a list of available online releases ( List of :class:`ReleaseObject` class instances ). """ def __init__(self, parent, releases=None, *args, **kwargs): """ Initializes the class. :param parent: Object parent. :type parent: QObject :param releases: Releases. :type releases: dict :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Keywords arguments. :type \*\*kwargs: \*\* """ LOGGER.debug("> Initializing '{0}()' class.".format( self.__class__.__name__)) super(RemoteUpdater, self).__init__(parent, *args, **kwargs) # --- Setting class attributes. --- self.__container = parent self.__releases = None self.releases = releases self.__uiResourcesDirectory = "resources/" self.__uiResourcesDirectory = os.path.join(os.path.dirname(__file__), self.__uiResourcesDirectory) self.__uiLogoImage = "sIBL_GUI_Small_Logo.png" self.__uiTemplatesImage = "Templates_Logo.png" self.__uiLightGrayColor = QColor(240, 240, 240) self.__uiDarkGrayColor = QColor(160, 160, 160) self.__splitter = "|" self.__view = None self.__headers = [ "data", "Get it!", "Local version", "Repository version", "Release type", "Comment" ] self.__applicationChangesUrl = "http://kelsolaar.hdrlabs.com/sIBL_GUI/Changes/Changes.html" self.__repositoryUrl = "http://kelsolaar.hdrlabs.com/?dir=./sIBL_GUI/Repository" self.__downloadManager = None self.__networkAccessManager = self.__container.networkAccessManager RemoteUpdater.__initializeUi(self) #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def container(self): """ Property for **self.__container** attribute. :return: self.__container. :rtype: QObject """ return self.__container @container.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def container(self, value): """ Setter for **self.__container** attribute. :param value: Attribute value. :type value: QObject """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "container")) @container.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def container(self): """ Deleter for **self.__container** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "container")) @property def releases(self): """ Property for **self.__releases** attribute. :return: self.__releases. :rtype: dict """ return self.__releases @releases.setter @foundations.exceptions.handleExceptions(AssertionError) def releases(self, value): """ Setter for **self.__releases** attribute. :param value: Attribute value. :type value: dict """ if value is not None: assert type( value ) is dict, "'{0}' attribute: '{1}' type is not 'dict'!".format( "releases", value) for key, element in value.iteritems(): assert type( key ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "variables", key) assert type( element ) is ReleaseObject, "'{0}' attribute: '{1}' type is not 'ReleaseObject'!".format( "variables", element) self.__releases = value @releases.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def releases(self): """ Deleter for **self.__releases** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "releases")) @property def uiResourcesDirectory(self): """ Property for **self.__uiResourcesDirectory** attribute. :return: self.__uiResourcesDirectory. :rtype: unicode """ return self.__uiResourcesDirectory @uiResourcesDirectory.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiResourcesDirectory(self, value): """ Setter for **self.__uiResourcesDirectory** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "uiResourcesDirectory")) @uiResourcesDirectory.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiResourcesDirectory(self): """ Deleter for **self.__uiResourcesDirectory** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "uiResourcesDirectory")) @property def uiLogoImage(self): """ Property for **self.__uiLogoImage** attribute. :return: self.__uiLogoImage. :rtype: unicode """ return self.__uiLogoImage @uiLogoImage.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiLogoImage(self, value): """ Setter for **self.__uiLogoImage** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "uiLogoImage")) @uiLogoImage.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiLogoImage(self): """ Deleter for **self.__uiLogoImage** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "uiLogoImage")) @property def uiTemplatesImage(self): """ Property for **self.__uiTemplatesImage** attribute. :return: self.__uiTemplatesImage. :rtype: unicode """ return self.__uiTemplatesImage @uiTemplatesImage.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiTemplatesImage(self, value): """ Setter for **self.__uiTemplatesImage** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "uiTemplatesImage")) @uiTemplatesImage.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiTemplatesImage(self): """ Deleter for **self.__uiTemplatesImage** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "uiTemplatesImage")) @property def uiLightGrayColor(self): """ Property for **self.__uiLightGrayColor** attribute. :return: self.__uiLightGrayColor. :rtype: QColor """ return self.__uiLightGrayColor @uiLightGrayColor.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiLightGrayColor(self, value): """ Setter for **self.__uiLightGrayColor** attribute. :param value: Attribute value. :type value: QColor """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "uiLightGrayColor")) @uiLightGrayColor.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiLightGrayColor(self): """ Deleter for **self.__uiLightGrayColor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "uiLightGrayColor")) @property def uiDarkGrayColor(self): """ Property for **self.__uiDarkGrayColor** attribute. :return: self.__uiDarkGrayColor. :rtype: QColor """ return self.__uiDarkGrayColor @uiDarkGrayColor.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiDarkGrayColor(self, value): """ Setter for **self.__uiDarkGrayColor** attribute. :param value: Attribute value. :type value: QColor """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "uiDarkGrayColor")) @uiDarkGrayColor.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def uiDarkGrayColor(self): """ Deleter for **self.__uiDarkGrayColor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "uiDarkGrayColor")) @property def view(self): """ Property for **self.__view** attribute. :return: self.__view. :rtype: QWidget """ return self.__view @view.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def view(self, value): """ Setter for **self.__view** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "view")) @view.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def view(self): """ Deleter for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "view")) @property def splitter(self): """ Property for **self.__splitter** attribute. :return: self.__splitter. :rtype: unicode """ return self.__splitter @splitter.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def splitter(self, value): """ Setter for **self.__splitter** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "splitter")) @splitter.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def splitter(self): """ Deleter for **self.__splitter** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "splitter")) @property def headers(self): """ Property for **self.__headers** attribute. :return: self.__headers. :rtype: unicode """ return self.__headers @headers.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def headers(self, value): """ Setter for **self.__headers** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "headers")) @headers.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def headers(self): """ Deleter for **self.__headers** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "headers")) @property def applicationChangesUrl(self): """ Property for **self.__applicationChangesUrl** attribute. :return: self.__applicationChangesUrl. :rtype: unicode """ return self.__applicationChangesUrl @applicationChangesUrl.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def applicationChangesUrl(self, value): """ Setter for **self.__applicationChangesUrl** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "applicationChangesUrl")) @applicationChangesUrl.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def applicationChangesUrl(self): """ Deleter for **self.__applicationChangesUrl** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "applicationChangesUrl")) @property def repositoryUrl(self): """ Property for **self.__repositoryUrl** attribute. :return: self.__repositoryUrl. :rtype: unicode """ return self.__repositoryUrl @repositoryUrl.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def repositoryUrl(self, value): """ Setter for **self.__repositoryUrl** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "repositoryUrl")) @repositoryUrl.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def repositoryUrl(self): """ Deleter for **self.__repositoryUrl** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "repositoryUrl")) @property def downloadManager(self): """ Property for **self.__downloadManager** attribute. :return: self.__downloadManager. :rtype: object """ return self.__downloadManager @downloadManager.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def downloadManager(self, value): """ Setter for **self.__downloadManager** attribute. :param value: Attribute value. :type value: object """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "downloadManager")) @downloadManager.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def downloadManager(self): """ Deleter for **self.__downloadManager** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "downloadManager")) @property def networkAccessManager(self): """ Property for **self.__networkAccessManager** attribute. :return: self.__networkAccessManager. :rtype: QNetworkAccessManager """ return self.__networkAccessManager @networkAccessManager.setter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def networkAccessManager(self, value): """ Setter for **self.__networkAccessManager** attribute. :param value: Attribute value. :type value: QNetworkAccessManager """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format( self.__class__.__name__, "networkAccessManager")) @networkAccessManager.deleter @foundations.exceptions.handleExceptions( foundations.exceptions.ProgrammingError) def networkAccessManager(self): """ Deleter for **self.__networkAccessManager** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format( self.__class__.__name__, "networkAccessManager")) #****************************************************************************************************************** #*** Class methods. #****************************************************************************************************************** def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) LOGGER.debug("> Initializing '{0}' ui.".format( self.__class__.__name__)) if Constants.applicationName not in self.__releases: self.sIBL_GUI_frame.hide() self.Get_sIBL_GUI_pushButton.hide() else: self.Logo_label.setPixmap( QPixmap( os.path.join(self.__uiResourcesDirectory, self.__uiLogoImage))) self.Your_Version_label.setText( self.__releases[Constants.applicationName].localVersion) self.Latest_Version_label.setText( self.__releases[Constants.applicationName].repositoryVersion) self.Change_Log_webView.load( QUrl.fromEncoded(QByteArray(self.__applicationChangesUrl))) templatesReleases = dict(self.__releases) if Constants.applicationName in self.__releases: templatesReleases.pop(Constants.applicationName) if not templatesReleases: self.Templates_frame.hide() self.Get_Latest_Templates_pushButton.hide() else: self.Templates_label.setPixmap( QPixmap( os.path.join(self.__uiResourcesDirectory, self.__uiTemplatesImage))) self.Templates_tableWidget.setParent(None) self.Templates_tableWidget = TemplatesReleases_QTableWidget( self, message="No Releases to view!") self.Templates_tableWidget.setObjectName("Templates_tableWidget") self.Templates_frame_gridLayout.addWidget( self.Templates_tableWidget, 1, 0) self.__view = self.Templates_tableWidget self.__view.clear() self.__view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.__view.setRowCount(len(templatesReleases)) self.__view.setColumnCount(len(self.__headers)) self.__view.setHorizontalHeaderLabels(self.__headers) self.__view.hideColumn(0) self.__view.horizontalHeader().setStretchLastSection(True) palette = QPalette() palette.setColor(QPalette.Base, Qt.transparent) self.__view.setPalette(palette) verticalHeaderLabels = [] for row, release in enumerate(sorted(templatesReleases)): verticalHeaderLabels.append(release) tableWidgetItem = QTableWidgetItem() tableWidgetItem.data = templatesReleases[release] self.__view.setItem(row, 0, tableWidgetItem) tableWidgetItem = Variable_QPushButton( self, True, (self.__uiLightGrayColor, self.__uiDarkGrayColor), ("Yes", "No")) tableWidgetItem.setObjectName("Spread_Sheet_pushButton") self.__view.setCellWidget(row, 1, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].localVersion or Constants.nullObject) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 2, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].repositoryVersion) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 3, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].type) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 4, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].comment) self.__view.setItem(row, 5, tableWidgetItem) self.__view.setVerticalHeaderLabels(verticalHeaderLabels) self.__view.resizeColumnsToContents() # Signals / Slots. self.Get_sIBL_GUI_pushButton.clicked.connect( self.__Get_sIBL_GUI_pushButton__clicked) self.Get_Latest_Templates_pushButton.clicked.connect( self.__Get_Latest_Templates_pushButton__clicked) self.Open_Repository_pushButton.clicked.connect( self.__Open_Repository_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked) def __Get_sIBL_GUI_pushButton__clicked(self, checked): """ Defines the slot triggered by **Get_sIBL_GUI_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ urlTokens = self.releases[Constants.applicationName].url.split( self.__splitter) builds = dict(((urlTokens[i].strip(), urlTokens[i + 1].strip(" \"")) for i in range(0, len(urlTokens), 2))) if platform.system() == "Windows" or platform.system() == "Microsoft": url = builds["Windows"] elif platform.system() == "Darwin": url = builds["Mac Os X"] elif platform.system() == "Linux": url = builds["Linux"] self.__downloadManager = DownloadManager(self, self.__networkAccessManager, self.__container.ioDirectory, [url], Qt.Window) self.__downloadManager.downloadFinished.connect( self.__downloadManager__finished) self.__downloadManager.show() self.__downloadManager.startDownload() def __Get_Latest_Templates_pushButton__clicked(self, checked): """ Defines the slot triggered by **Get_Latest_Templates_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ requests = [] for row in range(self.__view.rowCount()): if self.__view.cellWidget(row, 1).state: requests.append(self.__view.item(row, 0).data) if not requests: return downloadDirectory = self.__getTemplatesDownloadDirectory() if not downloadDirectory: return if not foundations.io.isWritable(downloadDirectory): self.__container.engine.notificationsManager.exceptify( "{0} | '{1}' directory is not writable".format( self.__class__.__name__, downloadDirectory)) return LOGGER.debug( "> Templates download directory: '{0}'.".format(downloadDirectory)) self.__downloadManager = DownloadManager( self, self.__networkAccessManager, downloadDirectory, [request.url for request in requests], Qt.Window) self.__downloadManager.downloadFinished.connect( self.__downloadManager__finished) self.__downloadManager.show() self.__downloadManager.startDownload() def __Open_Repository_pushButton__clicked(self, checked): """ Defines the slot triggered by **Open_Repository_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ LOGGER.debug("> Opening url: '{0}'.".format(self.__repositoryUrl)) QDesktopServices.openUrl(QUrl(QString(self.__repositoryUrl))) def __Close_pushButton__clicked(self, checked): """ Closes the RemoteUpdater. :param checked: Checked state. :type checked: bool """ LOGGER.info("{0} | Closing '{1}' updater!".format( self.__class__.__name__, Constants.applicationName)) self.close() def __downloadManager__finished(self): """ Defines the slot triggered by the download Manager when finished. """ for download, data in self.__downloadManager.downloads.iteritems(): networkError, request = data if networkError != 0: self.__container.engine.notificationsManager.exceptify( "{0} | '{1}' file download failed! Error code: '{2}'". format(self.__class__.__name__, request, networkError)) continue if download.endswith(".zip"): if self.extractZipFile(download): LOGGER.info("{0} | Removing '{1}' archive!".format( self.__class__.__name__, download)) os.remove(download) else: self.__container.engine.notificationsManager.exceptify( "{0} | Failed extracting '{1}', proceeding to next file!" .format(self.__class__.__name__, os.path.basename(download))) self.__container.templatesOutliner.addDirectory( os.path.dirname(download), self.__container.templatesOutliner.getCollectionByName( self.__container.templatesOutliner.userCollection).id) else: if self.__container.locationsBrowser.activated: self.__container.locationsBrowser.exploreDirectory( os.path.dirname(download)) def __getTemplatesDownloadDirectory(self): """ Gets the Templates directory. """ LOGGER.debug("> Retrieving Templates download directory.") choice = messageBox.messageBox( "Question", "{0}".format(self.__class__.__name__), "{0} | Which directory do you want to install the Templates into?". format(self.__class__.__name__), buttons=QMessageBox.Cancel, customButtons=((QString("Factory"), QMessageBox.AcceptRole), (QString("User"), QMessageBox.AcceptRole), (QString("Custom"), QMessageBox.AcceptRole))) if choice == 0: return os.path.join(RuntimeGlobals.templatesFactoryDirectory) elif choice == 1: return os.path.join(RuntimeGlobals.templatesUserDirectory) elif choice == 2: return umbra.ui.common.storeLastBrowsedPath( QFileDialog.getExistingDirectory( self, "Choose Templates Directory:", RuntimeGlobals.lastBrowsedPath)) def extractZipFile(self, file): """ Uncompress the given zip file. :param file: File to extract. :type file: unicode :return: Extraction success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' file uncompress.".format(file)) pkzip = Pkzip() pkzip.archive = file return pkzip.extract(os.path.dirname(file))
class RemoteUpdater(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)): """ | Defines the Application remote updater. | The remote updater is initialized with a list of available online releases ( List of :class:`ReleaseObject` class instances ). """ def __init__(self, parent, releases=None, *args, **kwargs): """ Initializes the class. :param parent: Object parent. :type parent: QObject :param releases: Releases. :type releases: dict :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Keywords arguments. :type \*\*kwargs: \*\* """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) super(RemoteUpdater, self).__init__(parent, *args, **kwargs) # --- Setting class attributes. --- self.__container = parent self.__releases = None self.releases = releases self.__uiResourcesDirectory = "resources/" self.__uiResourcesDirectory = os.path.join(os.path.dirname(__file__), self.__uiResourcesDirectory) self.__uiLogoImage = "sIBL_GUI_Small_Logo.png" self.__uiTemplatesImage = "Templates_Logo.png" self.__uiLightGrayColor = QColor(240, 240, 240) self.__uiDarkGrayColor = QColor(160, 160, 160) self.__splitter = "|" self.__view = None self.__headers = ["data", "Get it!", "Local version", "Repository version", "Release type", "Comment"] self.__applicationChangesUrl = "http://kelsolaar.hdrlabs.com/sIBL_GUI/Changes/Changes.html" self.__repositoryUrl = "http://kelsolaar.hdrlabs.com/?dir=./sIBL_GUI/Repository" self.__downloadManager = None self.__networkAccessManager = self.__container.networkAccessManager RemoteUpdater.__initializeUi(self) #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def container(self): """ Property for **self.__container** attribute. :return: self.__container. :rtype: QObject """ return self.__container @container.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def container(self, value): """ Setter for **self.__container** attribute. :param value: Attribute value. :type value: QObject """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "container")) @container.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def container(self): """ Deleter for **self.__container** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "container")) @property def releases(self): """ Property for **self.__releases** attribute. :return: self.__releases. :rtype: dict """ return self.__releases @releases.setter @foundations.exceptions.handleExceptions(AssertionError) def releases(self, value): """ Setter for **self.__releases** attribute. :param value: Attribute value. :type value: dict """ if value is not None: assert type(value) is dict, "'{0}' attribute: '{1}' type is not 'dict'!".format("releases", value) for key, element in value.iteritems(): assert type(key) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "variables", key) assert type(element) is ReleaseObject, "'{0}' attribute: '{1}' type is not 'ReleaseObject'!".format( "variables", element) self.__releases = value @releases.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def releases(self): """ Deleter for **self.__releases** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "releases")) @property def uiResourcesDirectory(self): """ Property for **self.__uiResourcesDirectory** attribute. :return: self.__uiResourcesDirectory. :rtype: unicode """ return self.__uiResourcesDirectory @uiResourcesDirectory.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiResourcesDirectory(self, value): """ Setter for **self.__uiResourcesDirectory** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiResourcesDirectory")) @uiResourcesDirectory.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiResourcesDirectory(self): """ Deleter for **self.__uiResourcesDirectory** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiResourcesDirectory")) @property def uiLogoImage(self): """ Property for **self.__uiLogoImage** attribute. :return: self.__uiLogoImage. :rtype: unicode """ return self.__uiLogoImage @uiLogoImage.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiLogoImage(self, value): """ Setter for **self.__uiLogoImage** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiLogoImage")) @uiLogoImage.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiLogoImage(self): """ Deleter for **self.__uiLogoImage** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiLogoImage")) @property def uiTemplatesImage(self): """ Property for **self.__uiTemplatesImage** attribute. :return: self.__uiTemplatesImage. :rtype: unicode """ return self.__uiTemplatesImage @uiTemplatesImage.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiTemplatesImage(self, value): """ Setter for **self.__uiTemplatesImage** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiTemplatesImage")) @uiTemplatesImage.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiTemplatesImage(self): """ Deleter for **self.__uiTemplatesImage** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiTemplatesImage")) @property def uiLightGrayColor(self): """ Property for **self.__uiLightGrayColor** attribute. :return: self.__uiLightGrayColor. :rtype: QColor """ return self.__uiLightGrayColor @uiLightGrayColor.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiLightGrayColor(self, value): """ Setter for **self.__uiLightGrayColor** attribute. :param value: Attribute value. :type value: QColor """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiLightGrayColor")) @uiLightGrayColor.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiLightGrayColor(self): """ Deleter for **self.__uiLightGrayColor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiLightGrayColor")) @property def uiDarkGrayColor(self): """ Property for **self.__uiDarkGrayColor** attribute. :return: self.__uiDarkGrayColor. :rtype: QColor """ return self.__uiDarkGrayColor @uiDarkGrayColor.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiDarkGrayColor(self, value): """ Setter for **self.__uiDarkGrayColor** attribute. :param value: Attribute value. :type value: QColor """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "uiDarkGrayColor")) @uiDarkGrayColor.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def uiDarkGrayColor(self): """ Deleter for **self.__uiDarkGrayColor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiDarkGrayColor")) @property def view(self): """ Property for **self.__view** attribute. :return: self.__view. :rtype: QWidget """ return self.__view @view.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self, value): """ Setter for **self.__view** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view")) @view.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self): """ Deleter for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view")) @property def splitter(self): """ Property for **self.__splitter** attribute. :return: self.__splitter. :rtype: unicode """ return self.__splitter @splitter.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def splitter(self, value): """ Setter for **self.__splitter** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "splitter")) @splitter.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def splitter(self): """ Deleter for **self.__splitter** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "splitter")) @property def headers(self): """ Property for **self.__headers** attribute. :return: self.__headers. :rtype: unicode """ return self.__headers @headers.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def headers(self, value): """ Setter for **self.__headers** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "headers")) @headers.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def headers(self): """ Deleter for **self.__headers** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "headers")) @property def applicationChangesUrl(self): """ Property for **self.__applicationChangesUrl** attribute. :return: self.__applicationChangesUrl. :rtype: unicode """ return self.__applicationChangesUrl @applicationChangesUrl.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def applicationChangesUrl(self, value): """ Setter for **self.__applicationChangesUrl** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "applicationChangesUrl")) @applicationChangesUrl.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def applicationChangesUrl(self): """ Deleter for **self.__applicationChangesUrl** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "applicationChangesUrl")) @property def repositoryUrl(self): """ Property for **self.__repositoryUrl** attribute. :return: self.__repositoryUrl. :rtype: unicode """ return self.__repositoryUrl @repositoryUrl.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def repositoryUrl(self, value): """ Setter for **self.__repositoryUrl** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "repositoryUrl")) @repositoryUrl.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def repositoryUrl(self): """ Deleter for **self.__repositoryUrl** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "repositoryUrl")) @property def downloadManager(self): """ Property for **self.__downloadManager** attribute. :return: self.__downloadManager. :rtype: object """ return self.__downloadManager @downloadManager.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def downloadManager(self, value): """ Setter for **self.__downloadManager** attribute. :param value: Attribute value. :type value: object """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "downloadManager")) @downloadManager.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def downloadManager(self): """ Deleter for **self.__downloadManager** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "downloadManager")) @property def networkAccessManager(self): """ Property for **self.__networkAccessManager** attribute. :return: self.__networkAccessManager. :rtype: QNetworkAccessManager """ return self.__networkAccessManager @networkAccessManager.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def networkAccessManager(self, value): """ Setter for **self.__networkAccessManager** attribute. :param value: Attribute value. :type value: QNetworkAccessManager """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "networkAccessManager")) @networkAccessManager.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def networkAccessManager(self): """ Deleter for **self.__networkAccessManager** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "networkAccessManager")) #****************************************************************************************************************** #*** Class methods. #****************************************************************************************************************** def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) LOGGER.debug("> Initializing '{0}' ui.".format(self.__class__.__name__)) if Constants.applicationName not in self.__releases: self.sIBL_GUI_frame.hide() self.Get_sIBL_GUI_pushButton.hide() else: self.Logo_label.setPixmap(QPixmap(os.path.join(self.__uiResourcesDirectory, self.__uiLogoImage))) self.Your_Version_label.setText(self.__releases[Constants.applicationName].localVersion) self.Latest_Version_label.setText(self.__releases[Constants.applicationName].repositoryVersion) self.Change_Log_webView.load(QUrl.fromEncoded(QByteArray(self.__applicationChangesUrl))) templatesReleases = dict(self.__releases) if Constants.applicationName in self.__releases: templatesReleases.pop(Constants.applicationName) if not templatesReleases: self.Templates_frame.hide() self.Get_Latest_Templates_pushButton.hide() else: self.Templates_label.setPixmap(QPixmap(os.path.join(self.__uiResourcesDirectory, self.__uiTemplatesImage))) self.Templates_tableWidget.setParent(None) self.Templates_tableWidget = TemplatesReleases_QTableWidget(self, message="No Releases to view!") self.Templates_tableWidget.setObjectName("Templates_tableWidget") self.Templates_frame_gridLayout.addWidget(self.Templates_tableWidget, 1, 0) self.__view = self.Templates_tableWidget self.__view.clear() self.__view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.__view.setRowCount(len(templatesReleases)) self.__view.setColumnCount(len(self.__headers)) self.__view.setHorizontalHeaderLabels(self.__headers) self.__view.hideColumn(0) self.__view.horizontalHeader().setStretchLastSection(True) palette = QPalette() palette.setColor(QPalette.Base, Qt.transparent) self.__view.setPalette(palette) verticalHeaderLabels = [] for row, release in enumerate(sorted(templatesReleases)): verticalHeaderLabels.append(release) tableWidgetItem = QTableWidgetItem() tableWidgetItem.data = templatesReleases[release] self.__view.setItem(row, 0, tableWidgetItem) tableWidgetItem = Variable_QPushButton(self, True, (self.__uiLightGrayColor, self.__uiDarkGrayColor), ("Yes", "No")) tableWidgetItem.setObjectName("Spread_Sheet_pushButton") self.__view.setCellWidget(row, 1, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].localVersion or Constants.nullObject) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 2, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].repositoryVersion) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 3, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].type) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 4, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].comment) self.__view.setItem(row, 5, tableWidgetItem) self.__view.setVerticalHeaderLabels(verticalHeaderLabels) self.__view.resizeColumnsToContents() # Signals / Slots. self.Get_sIBL_GUI_pushButton.clicked.connect(self.__Get_sIBL_GUI_pushButton__clicked) self.Get_Latest_Templates_pushButton.clicked.connect(self.__Get_Latest_Templates_pushButton__clicked) self.Open_Repository_pushButton.clicked.connect(self.__Open_Repository_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked) def __Get_sIBL_GUI_pushButton__clicked(self, checked): """ Defines the slot triggered by **Get_sIBL_GUI_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ urlTokens = self.releases[Constants.applicationName].url.split(self.__splitter) builds = dict(((urlTokens[i].strip(), urlTokens[i + 1].strip(" \"")) for i in range(0, len(urlTokens), 2))) if platform.system() == "Windows" or platform.system() == "Microsoft": url = builds["Windows"] elif platform.system() == "Darwin": url = builds["Mac Os X"] elif platform.system() == "Linux": url = builds["Linux"] self.__downloadManager = DownloadManager(self, self.__networkAccessManager, self.__container.ioDirectory, [url], Qt.Window) self.__downloadManager.downloadFinished.connect(self.__downloadManager__finished) self.__downloadManager.show() self.__downloadManager.startDownload() def __Get_Latest_Templates_pushButton__clicked(self, checked): """ Defines the slot triggered by **Get_Latest_Templates_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ requests = [] for row in range(self.__view.rowCount()): if self.__view.cellWidget(row, 1).state: requests.append(self.__view.item(row, 0).data) if not requests: return downloadDirectory = self.__getTemplatesDownloadDirectory() if not downloadDirectory: return if not foundations.io.isWritable(downloadDirectory): self.__container.engine.notificationsManager.exceptify( "{0} | '{1}' directory is not writable".format( self.__class__.__name__, downloadDirectory)) return LOGGER.debug("> Templates download directory: '{0}'.".format(downloadDirectory)) self.__downloadManager = DownloadManager(self, self.__networkAccessManager, downloadDirectory, [request.url for request in requests], Qt.Window) self.__downloadManager.downloadFinished.connect(self.__downloadManager__finished) self.__downloadManager.show() self.__downloadManager.startDownload() def __Open_Repository_pushButton__clicked(self, checked): """ Defines the slot triggered by **Open_Repository_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ LOGGER.debug("> Opening url: '{0}'.".format(self.__repositoryUrl)) QDesktopServices.openUrl(QUrl(QString(self.__repositoryUrl))) def __Close_pushButton__clicked(self, checked): """ Closes the RemoteUpdater. :param checked: Checked state. :type checked: bool """ LOGGER.info("{0} | Closing '{1}' updater!".format(self.__class__.__name__, Constants.applicationName)) self.close() def __downloadManager__finished(self): """ Defines the slot triggered by the download Manager when finished. """ for download, data in self.__downloadManager.downloads.iteritems(): networkError, request = data if networkError != 0: self.__container.engine.notificationsManager.exceptify( "{0} | '{1}' file download failed! Error code: '{2}'".format( self.__class__.__name__, request, networkError)) continue if download.endswith(".zip"): if self.extractZipFile(download): LOGGER.info("{0} | Removing '{1}' archive!".format(self.__class__.__name__, download)) os.remove(download) else: self.__container.engine.notificationsManager.exceptify( "{0} | Failed extracting '{1}', proceeding to next file!".format(self.__class__.__name__, os.path.basename(download))) self.__container.templatesOutliner.addDirectory(os.path.dirname(download), self.__container.templatesOutliner.getCollectionByName( self.__container.templatesOutliner.userCollection).id) else: if self.__container.locationsBrowser.activated: self.__container.locationsBrowser.exploreDirectory(os.path.dirname(download)) def __getTemplatesDownloadDirectory(self): """ Gets the Templates directory. """ LOGGER.debug("> Retrieving Templates download directory.") choice = messageBox.messageBox("Question", "{0}".format(self.__class__.__name__), "{0} | Which directory do you want to install the Templates into?".format( self.__class__.__name__), buttons=QMessageBox.Cancel, customButtons=((QString("Factory"), QMessageBox.AcceptRole), (QString("User"), QMessageBox.AcceptRole), (QString("Custom"), QMessageBox.AcceptRole))) if choice == 0: return os.path.join(RuntimeGlobals.templatesFactoryDirectory) elif choice == 1: return os.path.join(RuntimeGlobals.templatesUserDirectory) elif choice == 2: return umbra.ui.common.storeLastBrowsedPath(QFileDialog.getExistingDirectory(self, "Choose Templates Directory:", RuntimeGlobals.lastBrowsedPath)) def extractZipFile(self, file): """ Uncompress the given zip file. :param file: File to extract. :type file: unicode :return: Extraction success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' file uncompress.".format(file)) pkzip = Pkzip() pkzip.archive = file return pkzip.extract(os.path.dirname(file))
def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) LOGGER.debug("> Initializing '{0}' ui.".format( self.__class__.__name__)) if Constants.applicationName not in self.__releases: self.sIBL_GUI_frame.hide() self.Get_sIBL_GUI_pushButton.hide() else: self.Logo_label.setPixmap( QPixmap( os.path.join(self.__uiResourcesDirectory, self.__uiLogoImage))) self.Your_Version_label.setText( self.__releases[Constants.applicationName].localVersion) self.Latest_Version_label.setText( self.__releases[Constants.applicationName].repositoryVersion) self.Change_Log_webView.load( QUrl.fromEncoded(QByteArray(self.__applicationChangesUrl))) templatesReleases = dict(self.__releases) if Constants.applicationName in self.__releases: templatesReleases.pop(Constants.applicationName) if not templatesReleases: self.Templates_frame.hide() self.Get_Latest_Templates_pushButton.hide() else: self.Templates_label.setPixmap( QPixmap( os.path.join(self.__uiResourcesDirectory, self.__uiTemplatesImage))) self.Templates_tableWidget.setParent(None) self.Templates_tableWidget = TemplatesReleases_QTableWidget( self, message="No Releases to view!") self.Templates_tableWidget.setObjectName("Templates_tableWidget") self.Templates_frame_gridLayout.addWidget( self.Templates_tableWidget, 1, 0) self.__view = self.Templates_tableWidget self.__view.clear() self.__view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.__view.setRowCount(len(templatesReleases)) self.__view.setColumnCount(len(self.__headers)) self.__view.setHorizontalHeaderLabels(self.__headers) self.__view.hideColumn(0) self.__view.horizontalHeader().setStretchLastSection(True) palette = QPalette() palette.setColor(QPalette.Base, Qt.transparent) self.__view.setPalette(palette) verticalHeaderLabels = [] for row, release in enumerate(sorted(templatesReleases)): verticalHeaderLabels.append(release) tableWidgetItem = QTableWidgetItem() tableWidgetItem.data = templatesReleases[release] self.__view.setItem(row, 0, tableWidgetItem) tableWidgetItem = Variable_QPushButton( self, True, (self.__uiLightGrayColor, self.__uiDarkGrayColor), ("Yes", "No")) tableWidgetItem.setObjectName("Spread_Sheet_pushButton") self.__view.setCellWidget(row, 1, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].localVersion or Constants.nullObject) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 2, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].repositoryVersion) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 3, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].type) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 4, tableWidgetItem) tableWidgetItem = QTableWidgetItem( templatesReleases[release].comment) self.__view.setItem(row, 5, tableWidgetItem) self.__view.setVerticalHeaderLabels(verticalHeaderLabels) self.__view.resizeColumnsToContents() # Signals / Slots. self.Get_sIBL_GUI_pushButton.clicked.connect( self.__Get_sIBL_GUI_pushButton__clicked) self.Get_Latest_Templates_pushButton.clicked.connect( self.__Get_Latest_Templates_pushButton__clicked) self.Open_Repository_pushButton.clicked.connect( self.__Open_Repository_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked)
def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) LOGGER.debug("> Initializing '{0}' ui.".format(self.__class__.__name__)) if Constants.applicationName not in self.__releases: self.sIBL_GUI_frame.hide() self.Get_sIBL_GUI_pushButton.hide() else: self.Logo_label.setPixmap(QPixmap(os.path.join(self.__uiResourcesDirectory, self.__uiLogoImage))) self.Your_Version_label.setText(self.__releases[Constants.applicationName].localVersion) self.Latest_Version_label.setText(self.__releases[Constants.applicationName].repositoryVersion) self.Change_Log_webView.load(QUrl.fromEncoded(QByteArray(self.__applicationChangesUrl))) templatesReleases = dict(self.__releases) if Constants.applicationName in self.__releases: templatesReleases.pop(Constants.applicationName) if not templatesReleases: self.Templates_frame.hide() self.Get_Latest_Templates_pushButton.hide() else: self.Templates_label.setPixmap(QPixmap(os.path.join(self.__uiResourcesDirectory, self.__uiTemplatesImage))) self.Templates_tableWidget.setParent(None) self.Templates_tableWidget = TemplatesReleases_QTableWidget(self, message="No Releases to view!") self.Templates_tableWidget.setObjectName("Templates_tableWidget") self.Templates_frame_gridLayout.addWidget(self.Templates_tableWidget, 1, 0) self.__view = self.Templates_tableWidget self.__view.clear() self.__view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.__view.setRowCount(len(templatesReleases)) self.__view.setColumnCount(len(self.__headers)) self.__view.setHorizontalHeaderLabels(self.__headers) self.__view.hideColumn(0) self.__view.horizontalHeader().setStretchLastSection(True) palette = QPalette() palette.setColor(QPalette.Base, Qt.transparent) self.__view.setPalette(palette) verticalHeaderLabels = [] for row, release in enumerate(sorted(templatesReleases)): verticalHeaderLabels.append(release) tableWidgetItem = QTableWidgetItem() tableWidgetItem.data = templatesReleases[release] self.__view.setItem(row, 0, tableWidgetItem) tableWidgetItem = Variable_QPushButton(self, True, (self.__uiLightGrayColor, self.__uiDarkGrayColor), ("Yes", "No")) tableWidgetItem.setObjectName("Spread_Sheet_pushButton") self.__view.setCellWidget(row, 1, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].localVersion or Constants.nullObject) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 2, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].repositoryVersion) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 3, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].type) tableWidgetItem.setTextAlignment(Qt.AlignCenter) self.__view.setItem(row, 4, tableWidgetItem) tableWidgetItem = QTableWidgetItem(templatesReleases[release].comment) self.__view.setItem(row, 5, tableWidgetItem) self.__view.setVerticalHeaderLabels(verticalHeaderLabels) self.__view.resizeColumnsToContents() # Signals / Slots. self.Get_sIBL_GUI_pushButton.clicked.connect(self.__Get_sIBL_GUI_pushButton__clicked) self.Get_Latest_Templates_pushButton.clicked.connect(self.__Get_Latest_Templates_pushButton__clicked) self.Open_Repository_pushButton.clicked.connect(self.__Open_Repository_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked)