eric6/UI/UserInterface.py

branch
maintenance
changeset 7824
096b3ebc1409
parent 7737
5371a22cf2aa
parent 7814
6fa40642ed7c
child 7850
e64b178499da
equal deleted inserted replaced
7738:10554f5fac78 7824:096b3ebc1409
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
40 from E5Gui.E5ProgressDialog import E5ProgressDialog 43 from E5Gui.E5ProgressDialog import E5ProgressDialog
41 from E5Gui.E5ClickableLabel import E5ClickableLabel 44 from E5Gui.E5ClickableLabel import E5ClickableLabel
42 45
43 import Preferences 46 import Preferences
44 import Utilities 47 import Utilities
48 import Globals
45 49
46 import UI.PixmapCache 50 import UI.PixmapCache
47 51
48 from E5Network.E5NetworkIcon import E5NetworkIcon 52 from E5Network.E5NetworkIcon import E5NetworkIcon
49 from E5Network.E5NetworkProxyFactory import ( 53 from E5Network.E5NetworkProxyFactory import (
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)
3517 Private slot to display the Help menu. 3630 Private slot to display the Help menu.
3518 """ 3631 """
3519 self.checkUpdateAct.setEnabled(not self.__inVersionCheck) 3632 self.checkUpdateAct.setEnabled(not self.__inVersionCheck)
3520 self.showVersionsAct.setEnabled(not self.__inVersionCheck) 3633 self.showVersionsAct.setEnabled(not self.__inVersionCheck)
3521 self.showErrorLogAct.setEnabled(self.__hasErrorLog()) 3634 self.showErrorLogAct.setEnabled(self.__hasErrorLog())
3635
3636 infoFileName = Globals.getInstallInfoFilePath()
3637 self.showInstallInfoAct.setEnabled(os.path.exists(infoFileName))
3522 3638
3523 self.showMenu.emit("Help", self.__menus["help"]) 3639 self.showMenu.emit("Help", self.__menus["help"])
3524 3640
3525 def __showSettingsMenu(self): 3641 def __showSettingsMenu(self):
3526 """ 3642 """
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"),
3719 logFile = os.path.join(Utilities.getConfigDir(), 3834 logFile = os.path.join(Utilities.getConfigDir(),
3720 self.ErrorLogFileName) 3835 self.ErrorLogFileName)
3721 if os.path.exists(logFile): 3836 if os.path.exists(logFile):
3722 from .ErrorLogDialog import ErrorLogDialog 3837 from .ErrorLogDialog import ErrorLogDialog
3723 dlg = ErrorLogDialog(logFile, False, self) 3838 dlg = ErrorLogDialog(logFile, False, self)
3724 dlg.exec_() 3839 dlg.exec()
3725 3840
3726 def __hasErrorLog(self): 3841 def __hasErrorLog(self):
3727 """ 3842 """
3728 Private method to check, if an error log file exists. 3843 Private method to check, if an error log file exists.
3729 3844
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":
6102 """ 6227 """
6103 Private slot to configure the various toolbars. 6228 Private slot to configure the various toolbars.
6104 """ 6229 """
6105 from E5Gui.E5ToolBarDialog import E5ToolBarDialog 6230 from E5Gui.E5ToolBarDialog import E5ToolBarDialog
6106 dlg = E5ToolBarDialog(self.toolbarManager) 6231 dlg = E5ToolBarDialog(self.toolbarManager)
6107 if dlg.exec_() == QDialog.Accepted: 6232 if dlg.exec() == QDialog.Accepted:
6108 Preferences.setUI( 6233 Preferences.setUI(
6109 "ToolbarManagerState", self.toolbarManager.saveState()) 6234 "ToolbarManagerState", self.toolbarManager.saveState())
6110 6235
6111 def __configShortcuts(self): 6236 def __configShortcuts(self):
6112 """ 6237 """
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 """

eric ide

mercurial