1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2020 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing a dialog to show information about the installation. 8""" 9 10import json 11import os 12 13from PyQt5.QtCore import pyqtSlot 14from PyQt5.QtWidgets import QDialog, QDialogButtonBox 15 16from E5Gui import E5MessageBox 17 18from .Ui_InstallInfoDialog import Ui_InstallInfoDialog 19 20import Globals 21import UI.PixmapCache 22 23 24class InstallInfoDialog(QDialog, Ui_InstallInfoDialog): 25 """ 26 Class implementing a dialog to show information about the installation. 27 """ 28 def __init__(self, parent=None): 29 """ 30 Constructor 31 32 @param parent reference to the parent widget 33 @type QWidget 34 """ 35 super().__init__(parent) 36 self.setupUi(self) 37 38 self.__deleteButton = self.buttonBox.addButton( 39 self.tr("Delete Info"), QDialogButtonBox.ButtonRole.ActionRole) 40 self.__deleteButton.clicked.connect(self.on_deleteButton_clicked) 41 self.__updateButton = self.buttonBox.addButton( 42 self.tr("Upgrade Instructions"), 43 QDialogButtonBox.ButtonRole.ActionRole) 44 self.__updateButton.clicked.connect(self.on_updateButton_clicked) 45 46 self.__edited = False 47 self.__loaded = True 48 49 self.editButton.setIcon(UI.PixmapCache.getIcon("infoEdit")) 50 self.saveButton.setIcon(UI.PixmapCache.getIcon("fileSave")) 51 52 infoFileName = Globals.getInstallInfoFilePath() 53 54 self.__deleteButton.setEnabled(os.path.exists(infoFileName)) 55 56 try: 57 with open(infoFileName, "r") as infoFile: 58 self.__info = json.load(infoFile) 59 60 if Globals.isWindowsPlatform(): 61 self.sudoLabel1.setText(self.tr("Installed as Administrator:")) 62 else: 63 self.sudoLabel1.setText(self.tr("Installed with sudo:")) 64 self.sudoLabel2.setText( 65 self.tr("Yes") if self.__info["sudo"] else self.tr("No")) 66 self.userLabel.setText(self.__info["user"]) 67 self.installedFromEdit.setText(self.__info["install_cwd"]) 68 self.interpreteEdit.setText(self.__info["exe"]) 69 self.commandEdit.setText(self.__info["argv"]) 70 self.installPathEdit.setText(self.__info["eric"]) 71 self.virtenvLabel.setText( 72 self.tr("Yes") if self.__info["virtualenv"] else self.tr("No")) 73 self.remarksEdit.setPlainText(self.__info["remarks"]) 74 if self.__info["pip"]: 75 self.pipLabel.setText(self.tr( 76 "'eric-ide' was installed from PyPI using the pip" 77 " command.")) 78 else: 79 self.pipLabel.hide() 80 if self.__info["guessed"]: 81 self.guessLabel.setText(self.tr( 82 "The information shown in this dialog was guessed at" 83 " the first start of eric.")) 84 else: 85 self.guessLabel.hide() 86 if self.__info["edited"]: 87 self.userProvidedLabel.setText(self.tr( 88 "The installation information was provided by the user." 89 )) 90 else: 91 self.userProvidedLabel.hide() 92 if self.__info["installed_on"]: 93 self.installDateTimeLabel.setText( 94 self.__info["installed_on"] if self.__info["installed_on"] 95 else self.tr("unknown")) 96 97 self.__updateButton.setEnabled(bool(self.__info["exe"])) 98 except OSError as err: 99 E5MessageBox.critical( 100 self, 101 self.tr("Load Install Information"), 102 self.tr("<p>The file containing the install information could" 103 " not be read.</p><p>Reason: {0}</p>""") 104 .format(str(err)) 105 ) 106 self.__loaded = False 107 self.__info = {} 108 109 self.__updateButton.setEnabled(False) 110 111 def wasLoaded(self): 112 """ 113 Public method to check, if the install data was loaded. 114 115 @return flag indicating the data was loaded 116 @rtype bool 117 """ 118 return self.__loaded 119 120 @pyqtSlot(bool) 121 def on_editButton_toggled(self, checked): 122 """ 123 Private slot to switch the dialog into edit mode. 124 125 @param checked flag giving the button check state 126 @type bool 127 """ 128 self.installedFromEdit.setReadOnly(not checked) 129 self.interpreteEdit.setReadOnly(not checked) 130 self.commandEdit.setReadOnly(not checked) 131 self.installPathEdit.setReadOnly(not checked) 132 self.remarksEdit.setReadOnly(not checked) 133 134 if checked: 135 self.__edited = True 136 137 @pyqtSlot() 138 def on_saveButton_clicked(self): 139 """ 140 Private slot handling the save button press. 141 """ 142 if self.__edited: 143 self.__saveData() 144 145 @pyqtSlot() 146 def reject(self): 147 """ 148 Public slot handling the closing of the dialog. 149 """ 150 if self.__edited: 151 yes = E5MessageBox.yesNo( 152 self, 153 self.tr("Install Information"), 154 self.tr("""The install information was edited. Unsaved""" 155 """ changes will be lost. Save first?"""), 156 yesDefault=True) 157 if yes: 158 self.__saveData() 159 160 super().reject() 161 162 def __saveData(self): 163 """ 164 Private method to save the data. 165 """ 166 if self.installedFromEdit.text() != self.__info["install_cwd"]: 167 self.__info["install_cwd"] = self.installedFromEdit.text() 168 self.__info["install_cwd_edited"] = True 169 if self.interpreteEdit.text() != self.__info["exe"]: 170 self.__info["exe"] = self.interpreteEdit.text() 171 self.__info["exe_edited"] = True 172 if self.commandEdit.text() != self.__info["argv"]: 173 self.__info["argv"] = self.commandEdit.text() 174 self.__info["argv_edited"] = True 175 if self.installPathEdit.text() != self.__info["eric"]: 176 self.__info["eric"] = self.installPathEdit.text() 177 self.__info["eric_edited"] = True 178 self.__info["remarks"] = self.remarksEdit.toPlainText() 179 self.__info["edited"] = True 180 181 infoFileName = Globals.getInstallInfoFilePath() 182 try: 183 with open(infoFileName, "w") as infoFile: 184 json.dump(self.__info, infoFile, indent=2) 185 self.__edited = False 186 self.editButton.setChecked(False) 187 except OSError as err: 188 E5MessageBox.critical( 189 self, 190 self.tr("Save Install Information"), 191 self.tr("<p>The file containing the install information could" 192 " not be written.</p><p>Reason: {0}</p>""") 193 .format(str(err)) 194 ) 195 196 @pyqtSlot() 197 def on_deleteButton_clicked(self): 198 """ 199 Private slot deleting the install information file. 200 """ 201 res = E5MessageBox.yesNo( 202 self, 203 self.tr("Delete Installation Information"), 204 self.tr("""Do you really want to delete the installation""" 205 """ information? It will be recreated at the next""" 206 """ start.""")) 207 if not res: 208 return 209 210 infoFileName = Globals.getInstallInfoFilePath() 211 os.remove(infoFileName) 212 213 # local data will be deleted automatically 214 self.__edited = False 215 216 self.close() 217 218 @pyqtSlot() 219 def on_updateButton_clicked(self): 220 """ 221 Private slot to show some upgrade instructions. 222 """ 223 updateTextList = [] 224 cmdPrefix = "" 225 226 if self.__info["sudo"]: 227 if Globals.isWindowsPlatform(): 228 updateTextList.append( 229 self.tr("Perform the following step(s) with Administrator" 230 " privileges.\n")) 231 else: 232 cmdPrefix = "sudo " 233 234 if self.__info["pip"]: 235 updateTextList.append( 236 "{0}{1} -m pip install --upgrade eric-ide".format( 237 cmdPrefix, self.__info["exe"], 238 ) 239 ) 240 else: 241 if ( 242 "install_cwd" in self.__info and 243 bool(self.__info["install_cwd"]) 244 ): 245 updateTextList.append( 246 "cd {0}".format(self.__info["install_cwd"]) 247 ) 248 updateTextList.append( 249 "{0}{1} {2}".format( 250 cmdPrefix, self.__info["exe"], self.__info["argv"], 251 ) 252 ) 253 254 from E5Gui.E5PlainTextDialog import E5PlainTextDialog 255 dlg = E5PlainTextDialog( 256 title=self.tr("Upgrade Instructions"), 257 text="\n".join(updateTextList)) 258 dlg.exec() 259