eric7/Plugins/VcsPlugins/vcsGit/GitSubmodulesStatusDialog.py

branch
eric7
changeset 8312
800c432b34c8
parent 8218
7c09585bd960
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2017 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to show the status of the submodules of the
8 project.
9 """
10
11 import os
12
13 from PyQt5.QtCore import pyqtSlot, Qt, QProcess
14 from PyQt5.QtWidgets import (
15 QDialog, QDialogButtonBox, QTreeWidgetItem, QHeaderView, QAbstractButton
16 )
17
18 from .Ui_GitSubmodulesStatusDialog import Ui_GitSubmodulesStatusDialog
19
20 import Preferences
21
22
23 class GitSubmodulesStatusDialog(QDialog, Ui_GitSubmodulesStatusDialog):
24 """
25 Class implementing a dialog to show the status of the submodules of the
26 project.
27 """
28 def __init__(self, vcs, parent=None):
29 """
30 Constructor
31
32 @param vcs reference to the vcs object
33 @type Git
34 @param parent reference to the parent widget
35 @type QWidget
36 """
37 super().__init__(parent)
38 self.setupUi(self)
39
40 self.__statusCodes = {
41 " ": self.tr("up-to-date"),
42 "-": self.tr("not initialized"),
43 "+": self.tr("different to index"),
44 "U": self.tr("merge conflicts")
45 }
46
47 self.__vcs = vcs
48 self.__repodir = None
49
50 self.refreshButton = self.buttonBox.addButton(
51 self.tr("Refresh"), QDialogButtonBox.ButtonRole.ActionRole)
52 self.refreshButton.setToolTip(
53 self.tr("Press to refresh the status display"))
54
55 def start(self, projectDir):
56 """
57 Public method to populate the status list.
58
59 @param projectDir name of the project directory
60 @type str
61 """
62 # find the root of the repo
63 self.__repodir = projectDir
64 while not os.path.isdir(os.path.join(self.__repodir,
65 self.__vcs.adminDir)):
66 self.__repodir = os.path.dirname(self.__repodir)
67 if os.path.splitdrive(self.__repodir)[1] == os.sep:
68 return
69
70 self.errorGroup.hide()
71 self.errors.clear()
72 self.statusList.clear()
73 self.buttonBox.setEnabled(False)
74
75 args = self.__vcs.initCommand("submodule")
76 args.append("status")
77 if self.recursiveCheckBox.isChecked():
78 args.append("--recursive")
79 if self.indexCheckBox.isChecked():
80 args.append("--cached")
81
82 process = QProcess()
83 process.setWorkingDirectory(self.__repodir)
84 process.start('git', args)
85 procStarted = process.waitForStarted(5000)
86 if procStarted:
87 finished = process.waitForFinished(30000)
88 if finished and process.exitCode() == 0:
89 ioEncoding = Preferences.getSystem("IOEncoding")
90 output = str(process.readAllStandardOutput(),
91 ioEncoding, 'replace')
92 error = str(process.readAllStandardError(),
93 ioEncoding, 'replace')
94 if error:
95 self.errors.setText(error)
96 self.errorGroup.show()
97 self.__processOutput(output)
98 else:
99 if not finished:
100 self.errors.setText(self.tr(
101 "The process {0} did not finish within 30 seconds.")
102 .format("git"))
103 else:
104 self.errors.setText(self.tr(
105 "The process {0} finished with an error.\n"
106 "Error: {1}")
107 .format("git", process.errorString()))
108 self.errorGroup.show()
109 else:
110 self.errors.setText(self.tr(
111 "The process {0} could not be started. "
112 "Ensure, that it is in the search path.").format("git"))
113 self.errorGroup.show()
114
115 self.buttonBox.setEnabled(True)
116 self.buttonBox.setFocus()
117
118 def __processOutput(self, output):
119 """
120 Private method to process the output and populate the list.
121
122 @param output output of the submodule status command
123 @type str
124 """
125 for line in output.splitlines():
126 try:
127 status = self.__statusCodes[line[0]]
128 except KeyError:
129 status = self.tr("unknown")
130 lineParts = line[1:].split(None, 2)
131 if len(lineParts) == 3 and lineParts[2][0] == "(":
132 # get rid of leading and trailing brackets
133 lineParts[2] = lineParts[2][1:-1]
134 QTreeWidgetItem(self.statusList, [
135 lineParts[1], # submodule name
136 status, # submodule status
137 lineParts[0], # commit ID
138 lineParts[2], # additional info
139 ])
140
141 self.statusList.header().resizeSections(
142 QHeaderView.ResizeMode.ResizeToContents)
143
144 self.statusList.setSortingEnabled(True)
145 self.statusList.sortItems(0, Qt.SortOrder.AscendingOrder)
146 self.statusList.setSortingEnabled(False)
147
148 @pyqtSlot(QAbstractButton)
149 def on_buttonBox_clicked(self, button):
150 """
151 Private slot called by a button of the button box clicked.
152
153 @param button button that was clicked (QAbstractButton)
154 """
155 if button == self.buttonBox.button(
156 QDialogButtonBox.StandardButton.Close
157 ):
158 self.close()
159 elif button == self.refreshButton:
160 self.on_refreshButton_clicked()
161
162 @pyqtSlot()
163 def on_refreshButton_clicked(self):
164 """
165 Private slot to refresh the status display.
166 """
167 self.start(self.__repodir)
168
169 @pyqtSlot(bool)
170 def on_indexCheckBox_toggled(self, checked):
171 """
172 Private slot handling a change of the index check box.
173
174 @param checked check state of the check box
175 @type bool
176 """
177 self.on_refreshButton_clicked()
178
179 @pyqtSlot(bool)
180 def on_recursiveCheckBox_toggled(self, checked):
181 """
182 Private slot handling a change of the recursive check box.
183
184 @param checked check state of the check box
185 @type bool
186 """
187 self.on_refreshButton_clicked()

eric ide

mercurial