5 |
5 |
6 """ |
6 """ |
7 Module implementing the main user interface. |
7 Module implementing the main user interface. |
8 """ |
8 """ |
9 |
9 |
10 |
|
11 import os |
10 import os |
12 import sys |
11 import sys |
13 import logging |
12 import logging |
|
13 import shutil |
|
14 import json |
|
15 import datetime |
|
16 import getpass |
14 |
17 |
15 from PyQt5.QtCore import ( |
18 from PyQt5.QtCore import ( |
16 pyqtSlot, QTimer, QFile, QFileInfo, pyqtSignal, PYQT_VERSION_STR, QDate, |
19 pyqtSlot, QTimer, QFile, QFileInfo, pyqtSignal, PYQT_VERSION_STR, QDate, |
17 QIODevice, qVersion, QProcess, QSize, QUrl, QObject, Qt, QUuid, QThread, |
20 QIODevice, qVersion, QProcess, QSize, QUrl, QObject, Qt, QUuid, QThread, |
18 QUrlQuery |
21 QUrlQuery |
1455 |
1459 |
1456 if opens == 0: |
1460 if opens == 0: |
1457 # no files, project or multiproject was given |
1461 # no files, project or multiproject was given |
1458 if not self.__noOpenAtStartup: |
1462 if not self.__noOpenAtStartup: |
1459 self.__openOnStartup() |
1463 self.__openOnStartup() |
1460 |
1464 |
|
1465 def processInstallInfoFile(self): |
|
1466 """ |
|
1467 Public method to process the file containing installation information. |
|
1468 """ |
|
1469 import Globals |
|
1470 |
|
1471 installInfoFile = Globals.getInstallInfoFilePath() |
|
1472 if not os.path.exists(installInfoFile): |
|
1473 filename = os.path.join(getConfig("ericDir"), "eric6install.json") |
|
1474 if os.path.exists(filename): |
|
1475 # eric was installed via the install.py script |
|
1476 shutil.copy2(filename, installInfoFile) |
|
1477 else: |
|
1478 filename = os.path.join(getConfig("ericDir"), |
|
1479 "eric6installpip.json") |
|
1480 if os.path.exists(filename): |
|
1481 # eric was installed via pip (i.e. eric-ide) |
|
1482 try: |
|
1483 installDateTime = datetime.datetime.now(tz=None) |
|
1484 with open(filename, "r") as infoFile: |
|
1485 installInfo = json.load(infoFile) |
|
1486 installInfo["guessed"] = True |
|
1487 installInfo["eric"] = getConfig("ericDir") |
|
1488 installInfo["virtualenv"] = ( |
|
1489 installInfo["eric"].startswith( |
|
1490 os.path.expanduser("~")) |
|
1491 ) |
|
1492 if installInfo["virtualenv"]: |
|
1493 installInfo["user"] = getpass.getuser() |
|
1494 installInfo["exe"] = sys.executable |
|
1495 installInfo["installed"] = True |
|
1496 installInfo["installed_on"] = installDateTime.strftime( |
|
1497 "%Y-%m-%d %H:%M:%S") |
|
1498 installInfo["sudo"] = not os.access( |
|
1499 installInfo["eric"], os.W_OK) |
|
1500 with open(installInfoFile, "w") as infoFile: |
|
1501 json.dump(installInfo, infoFile, indent=2) |
|
1502 except EnvironmentError: |
|
1503 # ignore this |
|
1504 pass |
|
1505 else: |
|
1506 changed = False |
|
1507 with open(installInfoFile, "r") as infoFile: |
|
1508 installInfo = json.load(infoFile) |
|
1509 |
|
1510 # 1. adapt stored file to latest format |
|
1511 if "install_cwd" not in installInfo: |
|
1512 installInfo["install_cwd"] = "" |
|
1513 installInfo["install_cwd_edited"] = False |
|
1514 changed = True |
|
1515 if "installed_on" not in installInfo: |
|
1516 installInfo["installed_on"] = "" |
|
1517 changed = True |
|
1518 |
|
1519 # 2. merge new data into stored file |
|
1520 filename = os.path.join(getConfig("ericDir"), "eric6install.json") |
|
1521 if os.path.exists(filename): |
|
1522 # eric was updated via the install.py script |
|
1523 if ( |
|
1524 os.path.getmtime(filename) > |
|
1525 os.path.getmtime(installInfoFile) |
|
1526 ): |
|
1527 if not installInfo["edited"]: |
|
1528 shutil.copy2(filename, installInfoFile) |
|
1529 else: |
|
1530 with open(filename, "r") as infoFile: |
|
1531 installInfo2 = json.load(infoFile) |
|
1532 if not installInfo["install_cwd_edited"]: |
|
1533 installInfo2["install_cwd"] = installInfo[ |
|
1534 "install_cwd"] |
|
1535 if not installInfo["exe_edited"]: |
|
1536 installInfo2["exe"] = installInfo["exe"] |
|
1537 if not installInfo["argv_edited"]: |
|
1538 installInfo2["argv"] = installInfo["argv"] |
|
1539 if not installInfo["eric_edited"]: |
|
1540 installInfo2["eric"] = installInfo["eric"] |
|
1541 installInfo = installInfo2 |
|
1542 changed = True |
|
1543 else: |
|
1544 filename = os.path.join(getConfig("ericDir"), |
|
1545 "eric6installpip.json") |
|
1546 if os.path.exists(filename): |
|
1547 # eric was updated via pip (i.e. eric-ide) |
|
1548 # just update the installation date and time |
|
1549 installDateTime = datetime.datetime.now(tz=None) |
|
1550 installInfo["installed_on"] = installDateTime.strftime( |
|
1551 "%Y-%m-%d %H:%M:%S") |
|
1552 changed = True |
|
1553 |
|
1554 if changed: |
|
1555 with open(installInfoFile, "w") as infoFile: |
|
1556 json.dump(installInfo, infoFile, indent=2) |
|
1557 |
1461 def __createDockWindow(self, name): |
1558 def __createDockWindow(self, name): |
1462 """ |
1559 """ |
1463 Private method to create a dock window with common properties. |
1560 Private method to create a dock window with common properties. |
1464 |
1561 |
1465 @param name object name of the new dock window (string) |
1562 @param name object name of the new dock window (string) |
2112 """<b>Show Error Log...</b>""" |
2209 """<b>Show Error Log...</b>""" |
2113 """<p>Opens a dialog showing the most recent error log.</p>""" |
2210 """<p>Opens a dialog showing the most recent error log.</p>""" |
2114 )) |
2211 )) |
2115 self.showErrorLogAct.triggered.connect(self.__showErrorLog) |
2212 self.showErrorLogAct.triggered.connect(self.__showErrorLog) |
2116 self.actions.append(self.showErrorLogAct) |
2213 self.actions.append(self.showErrorLogAct) |
|
2214 |
|
2215 self.showInstallInfoAct = E5Action( |
|
2216 self.tr('Show Install Info'), |
|
2217 self.tr('Show Install &Info...'), |
|
2218 0, 0, self, 'show_install_info') |
|
2219 self.showInstallInfoAct.setStatusTip(self.tr( |
|
2220 'Show Installation Information')) |
|
2221 self.showInstallInfoAct.setWhatsThis(self.tr( |
|
2222 """<b>Show Install Info...</b>""" |
|
2223 """<p>Opens a dialog showing some information about the""" |
|
2224 """ installation process.</p>""" |
|
2225 )) |
|
2226 self.showInstallInfoAct.triggered.connect(self.__showInstallInfo) |
|
2227 self.actions.append(self.showInstallInfoAct) |
2117 |
2228 |
2118 self.reportBugAct = E5Action( |
2229 self.reportBugAct = E5Action( |
2119 self.tr('Report Bug'), |
2230 self.tr('Report Bug'), |
2120 self.tr('Report &Bug...'), |
2231 self.tr('Report &Bug...'), |
2121 0, 0, self, 'report_bug') |
2232 0, 0, self, 'report_bug') |
3143 self.__menus["help"].addAction(self.versionAct) |
3254 self.__menus["help"].addAction(self.versionAct) |
3144 self.__menus["help"].addSeparator() |
3255 self.__menus["help"].addSeparator() |
3145 self.__menus["help"].addAction(self.checkUpdateAct) |
3256 self.__menus["help"].addAction(self.checkUpdateAct) |
3146 self.__menus["help"].addAction(self.showVersionsAct) |
3257 self.__menus["help"].addAction(self.showVersionsAct) |
3147 self.__menus["help"].addSeparator() |
3258 self.__menus["help"].addSeparator() |
|
3259 self.__menus["help"].addAction(self.showInstallInfoAct) |
|
3260 self.__menus["help"].addSeparator() |
3148 self.__menus["help"].addAction(self.showErrorLogAct) |
3261 self.__menus["help"].addAction(self.showErrorLogAct) |
3149 self.__menus["help"].addAction(self.reportBugAct) |
3262 self.__menus["help"].addAction(self.reportBugAct) |
3150 self.__menus["help"].addAction(self.requestFeatureAct) |
3263 self.__menus["help"].addAction(self.requestFeatureAct) |
3151 self.__menus["help"].addSeparator() |
3264 self.__menus["help"].addSeparator() |
3152 self.__menus["help"].addAction(self.whatsThisAct) |
3265 self.__menus["help"].addAction(self.whatsThisAct) |
3690 address = FeatureAddress |
3806 address = FeatureAddress |
3691 else: |
3807 else: |
3692 address = BugAddress |
3808 address = BugAddress |
3693 subject = "[eric6] " |
3809 subject = "[eric6] " |
3694 if attachFile is not None: |
3810 if attachFile is not None: |
3695 f = open(attachFile, "r", encoding="utf-8") |
3811 with open(attachFile, "r", encoding="utf-8") as f: |
3696 body = f.read() |
3812 body = f.read() |
3697 f.close() |
|
3698 if deleteAttachFile: |
3813 if deleteAttachFile: |
3699 os.remove(attachFile) |
3814 os.remove(attachFile) |
3700 else: |
3815 else: |
3701 body = "\r\n----\r\n{0}\r\n----\r\n{1}\r\n----\r\n{2}".format( |
3816 body = "\r\n----\r\n{0}\r\n----\r\n{1}\r\n----\r\n{2}".format( |
3702 Utilities.generateVersionInfo("\r\n"), |
3817 Utilities.generateVersionInfo("\r\n"), |
3741 self.ErrorLogFileName) |
3856 self.ErrorLogFileName) |
3742 if os.path.exists(logFile): |
3857 if os.path.exists(logFile): |
3743 from .ErrorLogDialog import ErrorLogDialog |
3858 from .ErrorLogDialog import ErrorLogDialog |
3744 dlg = ErrorLogDialog(logFile, True, self) |
3859 dlg = ErrorLogDialog(logFile, True, self) |
3745 dlg.show() |
3860 dlg.show() |
3746 |
3861 |
|
3862 def __showInstallInfo(self): |
|
3863 """ |
|
3864 Private slot to show a dialog containing information about the |
|
3865 installation process. |
|
3866 """ |
|
3867 from .InstallInfoDialog import InstallInfoDialog |
|
3868 dlg = InstallInfoDialog(self) |
|
3869 if dlg.wasLoaded(): |
|
3870 dlg.exec() |
|
3871 |
3747 def __compareFiles(self): |
3872 def __compareFiles(self): |
3748 """ |
3873 """ |
3749 Private slot to handle the Compare Files dialog. |
3874 Private slot to handle the Compare Files dialog. |
3750 """ |
3875 """ |
3751 aw = self.viewmanager.activeWindow() |
3876 aw = self.viewmanager.activeWindow() |
4754 Private slot to handle the tools configuration menu entry. |
4879 Private slot to handle the tools configuration menu entry. |
4755 """ |
4880 """ |
4756 from Preferences.ToolConfigurationDialog import ToolConfigurationDialog |
4881 from Preferences.ToolConfigurationDialog import ToolConfigurationDialog |
4757 dlg = ToolConfigurationDialog( |
4882 dlg = ToolConfigurationDialog( |
4758 self.toolGroups[self.currentToolGroup][1], self) |
4883 self.toolGroups[self.currentToolGroup][1], self) |
4759 if dlg.exec_() == QDialog.Accepted: |
4884 if dlg.exec() == QDialog.Accepted: |
4760 self.toolGroups[self.currentToolGroup][1] = dlg.getToollist() |
4885 self.toolGroups[self.currentToolGroup][1] = dlg.getToollist() |
4761 self.__updateExternalToolsActions() |
4886 self.__updateExternalToolsActions() |
4762 |
4887 |
4763 def __toolGroupsConfiguration(self): |
4888 def __toolGroupsConfiguration(self): |
4764 """ |
4889 """ |
4767 from Preferences.ToolGroupConfigurationDialog import ( |
4892 from Preferences.ToolGroupConfigurationDialog import ( |
4768 ToolGroupConfigurationDialog |
4893 ToolGroupConfigurationDialog |
4769 ) |
4894 ) |
4770 dlg = ToolGroupConfigurationDialog( |
4895 dlg = ToolGroupConfigurationDialog( |
4771 self.toolGroups, self.currentToolGroup, self) |
4896 self.toolGroups, self.currentToolGroup, self) |
4772 if dlg.exec_() == QDialog.Accepted: |
4897 if dlg.exec() == QDialog.Accepted: |
4773 self.toolGroups, self.currentToolGroup = dlg.getToolGroups() |
4898 self.toolGroups, self.currentToolGroup = dlg.getToolGroups() |
4774 |
4899 |
4775 def __createUnitTestDialog(self): |
4900 def __createUnitTestDialog(self): |
4776 """ |
4901 """ |
4777 Private slot to generate the unit test dialog on demand. |
4902 Private slot to generate the unit test dialog on demand. |
5945 elif self.__lastConfigurationPageName: |
6070 elif self.__lastConfigurationPageName: |
5946 self.__configurationDialog.showConfigurationPageByName( |
6071 self.__configurationDialog.showConfigurationPageByName( |
5947 self.__lastConfigurationPageName) |
6072 self.__lastConfigurationPageName) |
5948 else: |
6073 else: |
5949 self.__configurationDialog.showConfigurationPageByName("empty") |
6074 self.__configurationDialog.showConfigurationPageByName("empty") |
5950 self.__configurationDialog.exec_() |
6075 self.__configurationDialog.exec() |
5951 QApplication.processEvents() |
6076 QApplication.processEvents() |
5952 if self.__configurationDialog.result() == QDialog.Accepted: |
6077 if self.__configurationDialog.result() == QDialog.Accepted: |
5953 self.__configurationDialog.setPreferences() |
6078 self.__configurationDialog.setPreferences() |
5954 Preferences.syncPreferences() |
6079 Preferences.syncPreferences() |
5955 self.__preferencesChanged() |
6080 self.__preferencesChanged() |
6086 Private slot to configure the various view profiles. |
6211 Private slot to configure the various view profiles. |
6087 """ |
6212 """ |
6088 from Preferences.ViewProfileDialog import ViewProfileDialog |
6213 from Preferences.ViewProfileDialog import ViewProfileDialog |
6089 dlg = ViewProfileDialog(self.__layoutType, self.profiles['edit'][1], |
6214 dlg = ViewProfileDialog(self.__layoutType, self.profiles['edit'][1], |
6090 self.profiles['debug'][1]) |
6215 self.profiles['debug'][1]) |
6091 if dlg.exec_() == QDialog.Accepted: |
6216 if dlg.exec() == QDialog.Accepted: |
6092 edit, debug = dlg.getVisibilities() |
6217 edit, debug = dlg.getVisibilities() |
6093 self.profiles['edit'][1] = edit |
6218 self.profiles['edit'][1] = edit |
6094 self.profiles['debug'][1] = debug |
6219 self.profiles['debug'][1] = debug |
6095 Preferences.setUI("ViewProfiles2", self.profiles) |
6220 Preferences.setUI("ViewProfiles2", self.profiles) |
6096 if self.currentProfile == "edit": |
6221 if self.currentProfile == "edit": |
6161 Private slot to show the certificates management dialog. |
6286 Private slot to show the certificates management dialog. |
6162 """ |
6287 """ |
6163 from E5Network.E5SslCertificatesDialog import E5SslCertificatesDialog |
6288 from E5Network.E5SslCertificatesDialog import E5SslCertificatesDialog |
6164 |
6289 |
6165 dlg = E5SslCertificatesDialog(self) |
6290 dlg = E5SslCertificatesDialog(self) |
6166 dlg.exec_() |
6291 dlg.exec() |
6167 |
6292 |
6168 def __clearPrivateData(self): |
6293 def __clearPrivateData(self): |
6169 """ |
6294 """ |
6170 Private slot to clear the private data lists. |
6295 Private slot to clear the private data lists. |
6171 """ |
6296 """ |
6172 from .ClearPrivateDataDialog import ClearPrivateDataDialog |
6297 from .ClearPrivateDataDialog import ClearPrivateDataDialog |
6173 dlg = ClearPrivateDataDialog(self) |
6298 dlg = ClearPrivateDataDialog(self) |
6174 if dlg.exec_() == QDialog.Accepted: |
6299 if dlg.exec() == QDialog.Accepted: |
6175 # recent files, recent projects, recent multi projects, |
6300 # recent files, recent projects, recent multi projects, |
6176 # debug histories, shell histories |
6301 # debug histories, shell histories |
6177 (files, projects, multiProjects, debug, shell, vcs, plugins) = ( |
6302 (files, projects, multiProjects, debug, shell, vcs, plugins) = ( |
6178 dlg.getData() |
6303 dlg.getData() |
6179 ) |
6304 ) |
6626 from PluginManager.PluginInstallDialog import PluginInstallDialog |
6751 from PluginManager.PluginInstallDialog import PluginInstallDialog |
6627 dlg = PluginInstallDialog( |
6752 dlg = PluginInstallDialog( |
6628 self.pluginManager, |
6753 self.pluginManager, |
6629 [] if pluginFileNames is None else pluginFileNames[:], |
6754 [] if pluginFileNames is None else pluginFileNames[:], |
6630 self) |
6755 self) |
6631 dlg.exec_() |
6756 dlg.exec() |
6632 if dlg.restartNeeded(): |
6757 if dlg.restartNeeded(): |
6633 self.__restart(ask=True) |
6758 self.__restart(ask=True) |
6634 |
6759 |
6635 def __deinstallPlugin(self): |
6760 def __deinstallPlugin(self): |
6636 """ |
6761 """ |
6637 Private slot to show a dialog to uninstall a plugin. |
6762 Private slot to show a dialog to uninstall a plugin. |
6638 """ |
6763 """ |
6639 from PluginManager.PluginUninstallDialog import PluginUninstallDialog |
6764 from PluginManager.PluginUninstallDialog import PluginUninstallDialog |
6640 dlg = PluginUninstallDialog(self.pluginManager, self) |
6765 dlg = PluginUninstallDialog(self.pluginManager, self) |
6641 dlg.exec_() |
6766 dlg.exec() |
6642 |
6767 |
6643 def showPluginsAvailable(self): |
6768 def showPluginsAvailable(self): |
6644 """ |
6769 """ |
6645 Public slot to show the plugins available for download. |
6770 Public slot to show the plugins available for download. |
6646 """ |
6771 """ |
6647 from PluginManager.PluginRepositoryDialog import PluginRepositoryDialog |
6772 from PluginManager.PluginRepositoryDialog import PluginRepositoryDialog |
6648 dlg = PluginRepositoryDialog(self.pluginManager, self) |
6773 dlg = PluginRepositoryDialog(self.pluginManager, self) |
6649 res = dlg.exec_() |
6774 res = dlg.exec() |
6650 if res == (QDialog.Accepted + 1): |
6775 if res == (QDialog.Accepted + 1): |
6651 self.__installPlugins(dlg.getDownloadedPlugins()) |
6776 self.__installPlugins(dlg.getDownloadedPlugins()) |
6652 |
6777 |
6653 def __pluginsConfigure(self): |
6778 def __pluginsConfigure(self): |
6654 """ |
6779 """ |