src/eric7/VCS/StatusWidget.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
10 import contextlib 10 import contextlib
11 import os 11 import os
12 12
13 from PyQt6.QtCore import pyqtSlot, Qt, QEvent 13 from PyQt6.QtCore import pyqtSlot, Qt, QEvent
14 from PyQt6.QtWidgets import ( 14 from PyQt6.QtWidgets import (
15 QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QListView, 15 QWidget,
16 QListWidget, QListWidgetItem, QToolButton, QAbstractItemView, QMenu, 16 QVBoxLayout,
17 QGroupBox, QDialog 17 QHBoxLayout,
18 QLabel,
19 QSizePolicy,
20 QListView,
21 QListWidget,
22 QListWidgetItem,
23 QToolButton,
24 QAbstractItemView,
25 QMenu,
26 QGroupBox,
27 QDialog,
18 ) 28 )
19 29
20 from EricWidgets.EricApplication import ericApp 30 from EricWidgets.EricApplication import ericApp
21 from EricWidgets import EricMessageBox 31 from EricWidgets import EricMessageBox
22 from EricWidgets.EricSpellCheckedTextEdit import EricSpellCheckedTextEdit 32 from EricWidgets.EricSpellCheckedTextEdit import EricSpellCheckedTextEdit
29 39
30 class StatusWidget(QWidget): 40 class StatusWidget(QWidget):
31 """ 41 """
32 Class implementing a VCS Status widget for the sidebar/toolbox. 42 Class implementing a VCS Status widget for the sidebar/toolbox.
33 """ 43 """
44
34 StatusDataRole = Qt.ItemDataRole.UserRole + 1 45 StatusDataRole = Qt.ItemDataRole.UserRole + 1
35 46
36 def __init__(self, project, viewmanager, parent=None): 47 def __init__(self, project, viewmanager, parent=None):
37 """ 48 """
38 Constructor 49 Constructor
39 50
40 @param project reference to the project object 51 @param project reference to the project object
41 @type Project 52 @type Project
42 @param viewmanager reference to the viewmanager object 53 @param viewmanager reference to the viewmanager object
43 @type ViewManager 54 @type ViewManager
44 @param parent reference to the parent widget (defaults to None) 55 @param parent reference to the parent widget (defaults to None)
45 @type QWidget (optional) 56 @type QWidget (optional)
46 """ 57 """
47 super().__init__(parent) 58 super().__init__(parent)
48 self.setObjectName("VcsStatusWidget") 59 self.setObjectName("VcsStatusWidget")
49 60
50 self.__project = project 61 self.__project = project
51 self.__vm = viewmanager 62 self.__vm = viewmanager
52 63
53 self.__layout = QVBoxLayout() 64 self.__layout = QVBoxLayout()
54 self.__layout.setObjectName("MainLayout") 65 self.__layout.setObjectName("MainLayout")
55 self.__layout.setContentsMargins(0, 3, 0, 0) 66 self.__layout.setContentsMargins(0, 3, 0, 0)
56 self.__topLayout = QHBoxLayout() 67 self.__topLayout = QHBoxLayout()
57 self.__topLayout.setObjectName("topLayout") 68 self.__topLayout.setObjectName("topLayout")
58 69
59 # Create the top area 70 # Create the top area
60 self.__infoLabel = QLabel(self) 71 self.__infoLabel = QLabel(self)
61 self.__infoLabel.setSizePolicy( 72 self.__infoLabel.setSizePolicy(
62 QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) 73 QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred
74 )
63 self.__topLayout.addWidget(self.__infoLabel) 75 self.__topLayout.addWidget(self.__infoLabel)
64 76
65 self.__commitToggleButton = QToolButton(self) 77 self.__commitToggleButton = QToolButton(self)
66 self.__commitToggleButton.setIcon(UI.PixmapCache.getIcon("check")) 78 self.__commitToggleButton.setIcon(UI.PixmapCache.getIcon("check"))
67 self.__commitToggleButton.setToolTip( 79 self.__commitToggleButton.setToolTip(
68 self.tr("Press to toggle the commit markers")) 80 self.tr("Press to toggle the commit markers")
81 )
69 self.__commitToggleButton.clicked.connect(self.__toggleCheckMark) 82 self.__commitToggleButton.clicked.connect(self.__toggleCheckMark)
70 self.__topLayout.addWidget(self.__commitToggleButton) 83 self.__topLayout.addWidget(self.__commitToggleButton)
71 84
72 self.__commitButton = QToolButton(self) 85 self.__commitButton = QToolButton(self)
73 self.__commitButton.setIcon(UI.PixmapCache.getIcon("vcsCommit")) 86 self.__commitButton.setIcon(UI.PixmapCache.getIcon("vcsCommit"))
74 self.__commitButton.setToolTip( 87 self.__commitButton.setToolTip(
75 self.tr("Press to commit the marked entries with options")) 88 self.tr("Press to commit the marked entries with options")
89 )
76 self.__commitButton.clicked.connect(self.__commit) 90 self.__commitButton.clicked.connect(self.__commit)
77 self.__topLayout.addWidget(self.__commitButton) 91 self.__topLayout.addWidget(self.__commitButton)
78 92
79 self.__addButton = QToolButton(self) 93 self.__addButton = QToolButton(self)
80 self.__addButton.setIcon(UI.PixmapCache.getIcon("vcsAdd")) 94 self.__addButton.setIcon(UI.PixmapCache.getIcon("vcsAdd"))
81 self.__addButton.setToolTip( 95 self.__addButton.setToolTip(
82 self.tr("Press to add the selected, untracked entries")) 96 self.tr("Press to add the selected, untracked entries")
97 )
83 self.__addButton.clicked.connect(self.__addUntracked) 98 self.__addButton.clicked.connect(self.__addUntracked)
84 self.__topLayout.addWidget(self.__addButton) 99 self.__topLayout.addWidget(self.__addButton)
85 100
86 self.__reloadButton = QToolButton(self) 101 self.__reloadButton = QToolButton(self)
87 self.__reloadButton.setIcon(UI.PixmapCache.getIcon("reload")) 102 self.__reloadButton.setIcon(UI.PixmapCache.getIcon("reload"))
88 self.__reloadButton.setToolTip( 103 self.__reloadButton.setToolTip(self.tr("Press to reload the status list"))
89 self.tr("Press to reload the status list"))
90 self.__reloadButton.clicked.connect(self.__reload) 104 self.__reloadButton.clicked.connect(self.__reload)
91 self.__topLayout.addWidget(self.__reloadButton) 105 self.__topLayout.addWidget(self.__reloadButton)
92 106
93 self.__actionsButton = QToolButton(self) 107 self.__actionsButton = QToolButton(self)
94 self.__actionsButton.setIcon( 108 self.__actionsButton.setIcon(UI.PixmapCache.getIcon("actionsToolButton"))
95 UI.PixmapCache.getIcon("actionsToolButton")) 109 self.__actionsButton.setToolTip(self.tr("Select action from menu"))
96 self.__actionsButton.setToolTip( 110 self.__actionsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
97 self.tr("Select action from menu"))
98 self.__actionsButton.setPopupMode(
99 QToolButton.ToolButtonPopupMode.InstantPopup)
100 self.__topLayout.addWidget(self.__actionsButton) 111 self.__topLayout.addWidget(self.__actionsButton)
101 112
102 self.__layout.addLayout(self.__topLayout) 113 self.__layout.addLayout(self.__topLayout)
103 ################################################################### 114 ###################################################################
104 115
105 # Create the middle part 116 # Create the middle part
106 self.__statusList = QListWidget(self) 117 self.__statusList = QListWidget(self)
107 self.__statusList.setAlternatingRowColors(True) 118 self.__statusList.setAlternatingRowColors(True)
108 self.__statusList.setSortingEnabled(True) 119 self.__statusList.setSortingEnabled(True)
109 self.__statusList.setViewMode(QListView.ViewMode.ListMode) 120 self.__statusList.setViewMode(QListView.ViewMode.ListMode)
110 self.__statusList.setTextElideMode(Qt.TextElideMode.ElideLeft) 121 self.__statusList.setTextElideMode(Qt.TextElideMode.ElideLeft)
111 self.__statusList.setSelectionMode( 122 self.__statusList.setSelectionMode(
112 QAbstractItemView.SelectionMode.ExtendedSelection) 123 QAbstractItemView.SelectionMode.ExtendedSelection
113 self.__statusList.itemSelectionChanged.connect( 124 )
114 self.__updateEnabledStates) 125 self.__statusList.itemSelectionChanged.connect(self.__updateEnabledStates)
115 self.__statusList.itemDoubleClicked.connect(self.__itemDoubleClicked) 126 self.__statusList.itemDoubleClicked.connect(self.__itemDoubleClicked)
116 self.__statusList.itemChanged.connect(self.__updateEnabledStates) 127 self.__statusList.itemChanged.connect(self.__updateEnabledStates)
117 self.__layout.addWidget(self.__statusList) 128 self.__layout.addWidget(self.__statusList)
118 ################################################################### 129 ###################################################################
119 130
120 # create the Quick Commit area 131 # create the Quick Commit area
121 self.__quickCommitGroup = QGroupBox(self.tr("Quick Commit"), self) 132 self.__quickCommitGroup = QGroupBox(self.tr("Quick Commit"), self)
122 self.__quickCommitLayout = QVBoxLayout() 133 self.__quickCommitLayout = QVBoxLayout()
123 self.__quickCommitEdit = EricSpellCheckedTextEdit(self) 134 self.__quickCommitEdit = EricSpellCheckedTextEdit(self)
124 self.__quickCommitEdit.setSizePolicy( 135 self.__quickCommitEdit.setSizePolicy(
125 QSizePolicy.Policy.Expanding, 136 QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred
126 QSizePolicy.Policy.Preferred) 137 )
127 self.__quickCommitEdit.setMaximumHeight(100) 138 self.__quickCommitEdit.setMaximumHeight(100)
128 self.__quickCommitEdit.setTabChangesFocus(True) 139 self.__quickCommitEdit.setTabChangesFocus(True)
129 self.__quickCommitEdit.installEventFilter(self) 140 self.__quickCommitEdit.installEventFilter(self)
130 self.__quickCommitEdit.textChanged.connect( 141 self.__quickCommitEdit.textChanged.connect(self.__quickCommitEditTextChanged)
131 self.__quickCommitEditTextChanged)
132 self.__quickCommitLayout.addWidget(self.__quickCommitEdit) 142 self.__quickCommitLayout.addWidget(self.__quickCommitEdit)
133 143
134 self.__quickCommitLayout2 = QHBoxLayout() 144 self.__quickCommitLayout2 = QHBoxLayout()
135 self.__quickCommitLayout2.addStretch() 145 self.__quickCommitLayout2.addStretch()
136 146
137 self.__quickCommitHistoryButton = QToolButton(self) 147 self.__quickCommitHistoryButton = QToolButton(self)
138 self.__quickCommitHistoryButton.setIcon( 148 self.__quickCommitHistoryButton.setIcon(UI.PixmapCache.getIcon("history"))
139 UI.PixmapCache.getIcon("history"))
140 self.__quickCommitHistoryButton.setToolTip( 149 self.__quickCommitHistoryButton.setToolTip(
141 self.tr("Select commit message from previous commits")) 150 self.tr("Select commit message from previous commits")
142 self.__quickCommitHistoryButton.clicked.connect( 151 )
143 self.__selectQuickCommitMessage) 152 self.__quickCommitHistoryButton.clicked.connect(self.__selectQuickCommitMessage)
144 self.__quickCommitLayout2.addWidget(self.__quickCommitHistoryButton) 153 self.__quickCommitLayout2.addWidget(self.__quickCommitHistoryButton)
145 154
146 self.__quickCommitHistoryClearButton = QToolButton(self) 155 self.__quickCommitHistoryClearButton = QToolButton(self)
147 self.__quickCommitHistoryClearButton.setIcon( 156 self.__quickCommitHistoryClearButton.setIcon(
148 UI.PixmapCache.getIcon("historyClear")) 157 UI.PixmapCache.getIcon("historyClear")
158 )
149 self.__quickCommitHistoryClearButton.setToolTip( 159 self.__quickCommitHistoryClearButton.setToolTip(
150 self.tr("Clear the list of saved commit messages")) 160 self.tr("Clear the list of saved commit messages")
151 self.__quickCommitHistoryClearButton.clicked.connect( 161 )
152 self.__clearCommitMessages) 162 self.__quickCommitHistoryClearButton.clicked.connect(self.__clearCommitMessages)
153 self.__quickCommitLayout2.addWidget( 163 self.__quickCommitLayout2.addWidget(self.__quickCommitHistoryClearButton)
154 self.__quickCommitHistoryClearButton) 164
155
156 self.__quickCommitButton = QToolButton(self) 165 self.__quickCommitButton = QToolButton(self)
157 self.__quickCommitButton.setIcon( 166 self.__quickCommitButton.setIcon(UI.PixmapCache.getIcon("vcsCommit"))
158 UI.PixmapCache.getIcon("vcsCommit"))
159 self.__quickCommitButton.setToolTip( 167 self.__quickCommitButton.setToolTip(
160 self.tr("Press to commit the marked entries")) 168 self.tr("Press to commit the marked entries")
169 )
161 self.__quickCommitButton.clicked.connect(self.__quickCommit) 170 self.__quickCommitButton.clicked.connect(self.__quickCommit)
162 self.__quickCommitLayout2.addWidget(self.__quickCommitButton) 171 self.__quickCommitLayout2.addWidget(self.__quickCommitButton)
163 172
164 self.__quickCommitLayout.addLayout(self.__quickCommitLayout2) 173 self.__quickCommitLayout.addLayout(self.__quickCommitLayout2)
165 self.__quickCommitGroup.setLayout(self.__quickCommitLayout) 174 self.__quickCommitGroup.setLayout(self.__quickCommitLayout)
166 self.__layout.addWidget(self.__quickCommitGroup) 175 self.__layout.addWidget(self.__quickCommitGroup)
167 ################################################################### 176 ###################################################################
168 177
169 self.setLayout(self.__layout) 178 self.setLayout(self.__layout)
170 179
171 self.__statusIcons = { 180 self.__statusIcons = {
172 "A": "vcs-added", # added 181 "A": "vcs-added", # added
173 "M": "vcs-modified", # modified 182 "M": "vcs-modified", # modified
174 "O": "vcs-removed", # removed 183 "O": "vcs-removed", # removed
175 "R": "vcs-renamed", # renamed 184 "R": "vcs-renamed", # renamed
176 "U": "vcs-update-required", # update needed 185 "U": "vcs-update-required", # update needed
177 "Z": "vcs-conflicting", # conflict 186 "Z": "vcs-conflicting", # conflict
178 "?": "vcs-untracked", # not tracked 187 "?": "vcs-untracked", # not tracked
179 "!": "vcs-missing", # missing 188 "!": "vcs-missing", # missing
180 } 189 }
181 self.__statusTexts = { 190 self.__statusTexts = {
182 "A": self.tr("added"), 191 "A": self.tr("added"),
183 "M": self.tr("modified"), 192 "M": self.tr("modified"),
184 "O": self.tr("removed"), 193 "O": self.tr("removed"),
186 "U": self.tr("needs update"), 195 "U": self.tr("needs update"),
187 "Z": self.tr("conflict"), 196 "Z": self.tr("conflict"),
188 "?": self.tr("not tracked"), 197 "?": self.tr("not tracked"),
189 "!": self.tr("missing"), 198 "!": self.tr("missing"),
190 } 199 }
191 200
192 self.__initActionsMenu() 201 self.__initActionsMenu()
193 202
194 self.__reset() 203 self.__reset()
195 204
196 if self.__project.isOpen(): 205 if self.__project.isOpen():
197 self.__projectOpened() 206 self.__projectOpened()
198 else: 207 else:
199 self.__projectClosed() 208 self.__projectClosed()
200 209
201 self.__addedItemsText = [] 210 self.__addedItemsText = []
202 211
203 self.__project.projectOpened.connect(self.__projectOpened) 212 self.__project.projectOpened.connect(self.__projectOpened)
204 self.__project.projectClosed.connect(self.__projectClosed) 213 self.__project.projectClosed.connect(self.__projectClosed)
205 self.__project.projectPropertiesChanged.connect( 214 self.__project.projectPropertiesChanged.connect(self.__setProjectSpellCheckData)
206 self.__setProjectSpellCheckData)
207 self.__project.vcsCommitted.connect(self.__committed) 215 self.__project.vcsCommitted.connect(self.__committed)
208 self.__project.vcsStatusMonitorInfo.connect(self.__setInfoText) 216 self.__project.vcsStatusMonitorInfo.connect(self.__setInfoText)
209 self.__project.vcsStatusMonitorAllData.connect( 217 self.__project.vcsStatusMonitorAllData.connect(self.__processStatusData)
210 self.__processStatusData) 218
211
212 def __initActionsMenu(self): 219 def __initActionsMenu(self):
213 """ 220 """
214 Private method to initialize the actions menu. 221 Private method to initialize the actions menu.
215 """ 222 """
216 self.__actionsMenu = QMenu() 223 self.__actionsMenu = QMenu()
217 self.__actionsMenu.setToolTipsVisible(True) 224 self.__actionsMenu.setToolTipsVisible(True)
218 self.__actionsMenu.aboutToShow.connect(self.__showActionsMenu) 225 self.__actionsMenu.aboutToShow.connect(self.__showActionsMenu)
219 226
220 self.__commitAct = self.__actionsMenu.addAction( 227 self.__commitAct = self.__actionsMenu.addAction(
221 UI.PixmapCache.getIcon("vcsCommit"), 228 UI.PixmapCache.getIcon("vcsCommit"), self.tr("Commit"), self.__commit
222 self.tr("Commit"), self.__commit) 229 )
223 self.__commitAct.setToolTip(self.tr( 230 self.__commitAct.setToolTip(self.tr("Commit the marked entries with options"))
224 "Commit the marked entries with options"))
225 self.__commitSelectAct = self.__actionsMenu.addAction( 231 self.__commitSelectAct = self.__actionsMenu.addAction(
226 self.tr("Select all for commit"), self.__commitSelectAll) 232 self.tr("Select all for commit"), self.__commitSelectAll
233 )
227 self.__commitDeselectAct = self.__actionsMenu.addAction( 234 self.__commitDeselectAct = self.__actionsMenu.addAction(
228 self.tr("Unselect all from commit"), self.__commitDeselectAll) 235 self.tr("Unselect all from commit"), self.__commitDeselectAll
229 236 )
237
230 self.__actionsMenu.addSeparator() 238 self.__actionsMenu.addSeparator()
231 239
232 self.__addAct = self.__actionsMenu.addAction( 240 self.__addAct = self.__actionsMenu.addAction(
233 UI.PixmapCache.getIcon("vcsAdd"), 241 UI.PixmapCache.getIcon("vcsAdd"), self.tr("Add"), self.__addUntracked
234 self.tr("Add"), self.__addUntracked) 242 )
235 self.__addAct.setToolTip(self.tr( 243 self.__addAct.setToolTip(self.tr("Add the selected, untracked entries"))
236 "Add the selected, untracked entries"))
237 self.__addAllAct = self.__actionsMenu.addAction( 244 self.__addAllAct = self.__actionsMenu.addAction(
238 self.tr("Add All"), self.__addAllUntracked) 245 self.tr("Add All"), self.__addAllUntracked
239 self.__addAllAct.setToolTip(self.tr( 246 )
240 "Add all untracked entries")) 247 self.__addAllAct.setToolTip(self.tr("Add all untracked entries"))
241 248
242 self.__actionsMenu.addSeparator() 249 self.__actionsMenu.addSeparator()
243 250
244 self.__diffAct = self.__actionsMenu.addAction( 251 self.__diffAct = self.__actionsMenu.addAction(
245 UI.PixmapCache.getIcon("vcsDiff"), 252 UI.PixmapCache.getIcon("vcsDiff"), self.tr("Differences"), self.__diff
246 self.tr("Differences"), self.__diff) 253 )
247 self.__diffAct.setToolTip(self.tr( 254 self.__diffAct.setToolTip(
248 "Shows the differences of the selected entry in a" 255 self.tr(
249 " separate dialog")) 256 "Shows the differences of the selected entry in a" " separate dialog"
257 )
258 )
250 self.__sbsDiffAct = self.__actionsMenu.addAction( 259 self.__sbsDiffAct = self.__actionsMenu.addAction(
251 UI.PixmapCache.getIcon("vcsSbsDiff"), 260 UI.PixmapCache.getIcon("vcsSbsDiff"),
252 self.tr("Differences Side-By-Side"), self.__sbsDiff) 261 self.tr("Differences Side-By-Side"),
253 self.__sbsDiffAct.setToolTip(self.tr( 262 self.__sbsDiff,
254 "Shows the differences of the selected entry side-by-side in" 263 )
255 " a separate dialog")) 264 self.__sbsDiffAct.setToolTip(
265 self.tr(
266 "Shows the differences of the selected entry side-by-side in"
267 " a separate dialog"
268 )
269 )
256 self.__diffAllAct = self.__actionsMenu.addAction( 270 self.__diffAllAct = self.__actionsMenu.addAction(
257 self.tr("All Differences"), self.__diffAll) 271 self.tr("All Differences"), self.__diffAll
258 self.__diffAllAct.setToolTip(self.tr( 272 )
259 "Shows the differences of all entries in a separate dialog")) 273 self.__diffAllAct.setToolTip(
260 274 self.tr("Shows the differences of all entries in a separate dialog")
275 )
276
261 self.__actionsMenu.addSeparator() 277 self.__actionsMenu.addSeparator()
262 278
263 self.__revertAct = self.__actionsMenu.addAction( 279 self.__revertAct = self.__actionsMenu.addAction(
264 UI.PixmapCache.getIcon("vcsRevert"), 280 UI.PixmapCache.getIcon("vcsRevert"), self.tr("Revert"), self.__revert
265 self.tr("Revert"), self.__revert) 281 )
266 self.__revertAct.setToolTip(self.tr( 282 self.__revertAct.setToolTip(
267 "Reverts the changes of the selected files")) 283 self.tr("Reverts the changes of the selected files")
268 284 )
285
269 self.__actionsMenu.addSeparator() 286 self.__actionsMenu.addSeparator()
270 287
271 self.__forgetAct = self.__actionsMenu.addAction( 288 self.__forgetAct = self.__actionsMenu.addAction(
272 self.tr("Forget Missing"), self.__forgetMissing) 289 self.tr("Forget Missing"), self.__forgetMissing
273 self.__forgetAct.setToolTip(self.tr( 290 )
274 "Forgets about the selected missing files")) 291 self.__forgetAct.setToolTip(self.tr("Forgets about the selected missing files"))
275 self.__restoreAct = self.__actionsMenu.addAction( 292 self.__restoreAct = self.__actionsMenu.addAction(
276 self.tr("Restore Missing"), self.__restoreMissing) 293 self.tr("Restore Missing"), self.__restoreMissing
277 self.__restoreAct.setToolTip(self.tr( 294 )
278 "Restores the selected missing files")) 295 self.__restoreAct.setToolTip(self.tr("Restores the selected missing files"))
279 self.__actionsMenu.addSeparator() 296 self.__actionsMenu.addSeparator()
280 297
281 self.__editAct = self.__actionsMenu.addAction( 298 self.__editAct = self.__actionsMenu.addAction(
282 UI.PixmapCache.getIcon("open"), 299 UI.PixmapCache.getIcon("open"),
283 self.tr("Edit Conflict"), self.__editConflict) 300 self.tr("Edit Conflict"),
284 self.__editAct.setToolTip(self.tr( 301 self.__editConflict,
285 "Edit the selected conflicting file")) 302 )
303 self.__editAct.setToolTip(self.tr("Edit the selected conflicting file"))
286 self.__resolvedAct = self.__actionsMenu.addAction( 304 self.__resolvedAct = self.__actionsMenu.addAction(
287 UI.PixmapCache.getIcon("vcsResolved"), 305 UI.PixmapCache.getIcon("vcsResolved"),
288 self.tr("Conflict Resolved"), self.__conflictResolved) 306 self.tr("Conflict Resolved"),
289 self.__resolvedAct.setToolTip(self.tr( 307 self.__conflictResolved,
290 "Mark the selected conflicting file as resolved")) 308 )
291 309 self.__resolvedAct.setToolTip(
310 self.tr("Mark the selected conflicting file as resolved")
311 )
312
292 self.__actionsButton.setMenu(self.__actionsMenu) 313 self.__actionsButton.setMenu(self.__actionsMenu)
293 314
294 @pyqtSlot() 315 @pyqtSlot()
295 def __projectOpened(self): 316 def __projectOpened(self):
296 """ 317 """
297 Private slot to handle the opening of a project. 318 Private slot to handle the opening of a project.
298 """ 319 """
299 self.__reloadButton.setEnabled(True) 320 self.__reloadButton.setEnabled(True)
300 self.__setProjectSpellCheckData() 321 self.__setProjectSpellCheckData()
301 322
302 @pyqtSlot() 323 @pyqtSlot()
303 def __setProjectSpellCheckData(self): 324 def __setProjectSpellCheckData(self):
304 """ 325 """
305 Private slot to set the spell check properties of the 326 Private slot to set the spell check properties of the
306 quick commit area. 327 quick commit area.
307 """ 328 """
308 pwl, pel = self.__project.getProjectDictionaries() 329 pwl, pel = self.__project.getProjectDictionaries()
309 language = self.__project.getProjectSpellLanguage() 330 language = self.__project.getProjectSpellLanguage()
310 self.__quickCommitEdit.setLanguageWithPWL( 331 self.__quickCommitEdit.setLanguageWithPWL(language, pwl or None, pel or None)
311 language, pwl or None, pel or None) 332
312
313 @pyqtSlot() 333 @pyqtSlot()
314 def __projectClosed(self): 334 def __projectClosed(self):
315 """ 335 """
316 Private slot to handle the closing of a project. 336 Private slot to handle the closing of a project.
317 """ 337 """
318 self.__infoLabel.setText(self.tr("No project open.")) 338 self.__infoLabel.setText(self.tr("No project open."))
319 339
320 self.__reloadButton.setEnabled(False) 340 self.__reloadButton.setEnabled(False)
321 341
322 self.__reset() 342 self.__reset()
323 343
324 @pyqtSlot(str) 344 @pyqtSlot(str)
325 def __setInfoText(self, info): 345 def __setInfoText(self, info):
326 """ 346 """
327 Private slot to set the info label text. 347 Private slot to set the info label text.
328 348
329 @param info text to be shown 349 @param info text to be shown
330 @type str 350 @type str
331 """ 351 """
332 self.__infoLabel.setText(info) 352 self.__infoLabel.setText(info)
333 353
334 @pyqtSlot() 354 @pyqtSlot()
335 def __reload(self): 355 def __reload(self):
336 """ 356 """
337 Private slot to reload the status list. 357 Private slot to reload the status list.
338 """ 358 """
339 self.__project.checkVCSStatus() 359 self.__project.checkVCSStatus()
340 360
341 def __reset(self): 361 def __reset(self):
342 """ 362 """
343 Private method to reset the widget to default. 363 Private method to reset the widget to default.
344 """ 364 """
345 self.__statusList.clear() 365 self.__statusList.clear()
346 366
347 self.__commitToggleButton.setEnabled(False) 367 self.__commitToggleButton.setEnabled(False)
348 self.__commitButton.setEnabled(False) 368 self.__commitButton.setEnabled(False)
349 self.__addButton.setEnabled(False) 369 self.__addButton.setEnabled(False)
350 370
351 self.__quickCommitEdit.clear() 371 self.__quickCommitEdit.clear()
352 self.__quickCommitGroup.setEnabled(False) 372 self.__quickCommitGroup.setEnabled(False)
353 373
354 def __updateEnabledStates(self): 374 def __updateEnabledStates(self):
355 """ 375 """
356 Private method to set the enabled states depending on the list state. 376 Private method to set the enabled states depending on the list state.
357 """ 377 """
358 modified = len(self.__getModifiedItems()) 378 modified = len(self.__getModifiedItems())
359 unversioned = len(self.__getSelectedUnversionedItems()) 379 unversioned = len(self.__getSelectedUnversionedItems())
360 commitable = len(self.__getCommitableItems()) 380 commitable = len(self.__getCommitableItems())
361 381
362 self.__commitToggleButton.setEnabled(modified) 382 self.__commitToggleButton.setEnabled(modified)
363 self.__commitButton.setEnabled(commitable) 383 self.__commitButton.setEnabled(commitable)
364 self.__addButton.setEnabled(unversioned) 384 self.__addButton.setEnabled(unversioned)
365 385
366 self.__quickCommitGroup.setEnabled(commitable) 386 self.__quickCommitGroup.setEnabled(commitable)
367 387
368 @pyqtSlot(dict) 388 @pyqtSlot(dict)
369 def __processStatusData(self, data): 389 def __processStatusData(self, data):
370 """ 390 """
371 Private slot to process the status data emitted by the project. 391 Private slot to process the status data emitted by the project.
372 392
373 Each entry of the status data consists of a status flag and and the 393 Each entry of the status data consists of a status flag and and the
374 path relative to the project directory starting with the third column. 394 path relative to the project directory starting with the third column.
375 The known status flags are: 395 The known status flags are:
376 <ul> 396 <ul>
377 <li>"A" path was added but not yet committed</li> 397 <li>"A" path was added but not yet committed</li>
382 <li>"Z" path contains a conflict</li> 402 <li>"Z" path contains a conflict</li>
383 <li>"?" path is not tracked</li> 403 <li>"?" path is not tracked</li>
384 <li>"!" path is missing</li> 404 <li>"!" path is missing</li>
385 <li>" " path is back at normal</li> 405 <li>" " path is back at normal</li>
386 </ul> 406 </ul>
387 407
388 @param data dictionary containing the status data 408 @param data dictionary containing the status data
389 @type dict 409 @type dict
390 """ 410 """
391 # step 1: remember all currently checked entries 411 # step 1: remember all currently checked entries
392 checkedEntries = [itm.text() for itm in self.__getCommitableItems()] 412 checkedEntries = [itm.text() for itm in self.__getCommitableItems()]
393 selectedEntries = [itm.text() 413 selectedEntries = [itm.text() for itm in self.__statusList.selectedItems()]
394 for itm in self.__statusList.selectedItems()] 414 knownEntries = [
395 knownEntries = [self.__statusList.item(row).text() 415 self.__statusList.item(row).text()
396 for row in range(self.__statusList.count())] 416 for row in range(self.__statusList.count())
397 417 ]
418
398 # step 2: clear the list and re-populate it with new data 419 # step 2: clear the list and re-populate it with new data
399 self.__statusList.clear() 420 self.__statusList.clear()
400 421
401 block = self.__statusList.blockSignals(True) 422 block = self.__statusList.blockSignals(True)
402 for name, status in data.items(): 423 for name, status in data.items():
403 if status: 424 if status:
404 itm = QListWidgetItem(name, self.__statusList) 425 itm = QListWidgetItem(name, self.__statusList)
405 with contextlib.suppress(KeyError): 426 with contextlib.suppress(KeyError):
406 itm.setToolTip(self.__statusTexts[status]) 427 itm.setToolTip(self.__statusTexts[status])
407 itm.setIcon(UI.PixmapCache.getIcon( 428 itm.setIcon(UI.PixmapCache.getIcon(self.__statusIcons[status]))
408 self.__statusIcons[status]))
409 itm.setData(self.StatusDataRole, status) 429 itm.setData(self.StatusDataRole, status)
410 if status in "AMOR": 430 if status in "AMOR":
411 itm.setFlags( 431 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
412 itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
413 if ( 432 if (
414 name in checkedEntries or 433 name in checkedEntries
415 name not in knownEntries or 434 or name not in knownEntries
416 name in self.__addedItemsText 435 or name in self.__addedItemsText
417 ): 436 ):
418 itm.setCheckState(Qt.CheckState.Checked) 437 itm.setCheckState(Qt.CheckState.Checked)
419 else: 438 else:
420 itm.setCheckState(Qt.CheckState.Unchecked) 439 itm.setCheckState(Qt.CheckState.Unchecked)
421 else: 440 else:
422 itm.setFlags( 441 itm.setFlags(itm.flags() & ~Qt.ItemFlag.ItemIsUserCheckable)
423 itm.flags() & ~Qt.ItemFlag.ItemIsUserCheckable)
424 itm.setSelected(name in selectedEntries) 442 itm.setSelected(name in selectedEntries)
425 443
426 self.__statusList.sortItems(Qt.SortOrder.AscendingOrder) 444 self.__statusList.sortItems(Qt.SortOrder.AscendingOrder)
427 self.__statusList.blockSignals(block) 445 self.__statusList.blockSignals(block)
428 446
429 self.__updateEnabledStates() 447 self.__updateEnabledStates()
430 448
431 @pyqtSlot() 449 @pyqtSlot()
432 def __toggleCheckMark(self): 450 def __toggleCheckMark(self):
433 """ 451 """
434 Private slot to toggle the check marks. 452 Private slot to toggle the check marks.
435 """ 453 """
436 itemList = ( 454 itemList = (
437 self.__statusList.selectedItems() 455 self.__statusList.selectedItems()
438 if len(self.__statusList.selectedItems()) else 456 if len(self.__statusList.selectedItems())
439 [self.__statusList.item(row) 457 else [
440 for row in range(self.__statusList.count())] 458 self.__statusList.item(row) for row in range(self.__statusList.count())
459 ]
441 ) 460 )
442 for itm in itemList: 461 for itm in itemList:
443 if ( 462 if (
444 itm.flags() & Qt.ItemFlag.ItemIsUserCheckable == 463 itm.flags() & Qt.ItemFlag.ItemIsUserCheckable
445 Qt.ItemFlag.ItemIsUserCheckable 464 == Qt.ItemFlag.ItemIsUserCheckable
446 ): 465 ):
447 if itm.checkState() == Qt.CheckState.Unchecked: 466 if itm.checkState() == Qt.CheckState.Unchecked:
448 itm.setCheckState(Qt.CheckState.Checked) 467 itm.setCheckState(Qt.CheckState.Checked)
449 else: 468 else:
450 itm.setCheckState(Qt.CheckState.Unchecked) 469 itm.setCheckState(Qt.CheckState.Unchecked)
451 470
452 def __setCheckMark(self, checked): 471 def __setCheckMark(self, checked):
453 """ 472 """
454 Private method to set or unset all check marks. 473 Private method to set or unset all check marks.
455 474
456 @param checked check mark state to be set 475 @param checked check mark state to be set
457 @type bool 476 @type bool
458 """ 477 """
459 for row in range(self.__statusList.count()): 478 for row in range(self.__statusList.count()):
460 itm = self.__statusList.item(row) 479 itm = self.__statusList.item(row)
461 if ( 480 if (
462 itm.flags() & Qt.ItemFlag.ItemIsUserCheckable == 481 itm.flags() & Qt.ItemFlag.ItemIsUserCheckable
463 Qt.ItemFlag.ItemIsUserCheckable 482 == Qt.ItemFlag.ItemIsUserCheckable
464 ): 483 ):
465 if checked: 484 if checked:
466 itm.setCheckState(Qt.CheckState.Checked) 485 itm.setCheckState(Qt.CheckState.Checked)
467 else: 486 else:
468 itm.setCheckState(Qt.CheckState.Unchecked) 487 itm.setCheckState(Qt.CheckState.Unchecked)
469 488
470 @pyqtSlot() 489 @pyqtSlot()
471 def __commit(self): 490 def __commit(self):
472 """ 491 """
473 Private slot to handle the commit button. 492 Private slot to handle the commit button.
474 """ 493 """
475 projectPath = self.__project.getProjectPath() 494 projectPath = self.__project.getProjectPath()
476 names = [] 495 names = []
477 496
478 for row in range(self.__statusList.count()): 497 for row in range(self.__statusList.count()):
479 itm = self.__statusList.item(row) 498 itm = self.__statusList.item(row)
480 if itm.checkState() == Qt.CheckState.Checked: 499 if itm.checkState() == Qt.CheckState.Checked:
481 names.append(os.path.join(projectPath, itm.text())) 500 names.append(os.path.join(projectPath, itm.text()))
482 501
483 if not names: 502 if not names:
484 EricMessageBox.information( 503 EricMessageBox.information(
485 self, 504 self,
486 self.tr("Commit"), 505 self.tr("Commit"),
487 self.tr("""There are no entries selected to be""" 506 self.tr("""There are no entries selected to be""" """ committed."""),
488 """ committed.""")) 507 )
489 return 508 return
490 509
491 if Preferences.getVCS("AutoSaveFiles"): 510 if Preferences.getVCS("AutoSaveFiles"):
492 vm = ericApp().getObject("ViewManager") 511 vm = ericApp().getObject("ViewManager")
493 for name in names: 512 for name in names:
494 vm.saveEditor(name) 513 vm.saveEditor(name)
495 vcs = self.__project.getVcs() 514 vcs = self.__project.getVcs()
496 vcs and vcs.vcsCommit(names, '') 515 vcs and vcs.vcsCommit(names, "")
497 516
498 @pyqtSlot() 517 @pyqtSlot()
499 def __committed(self): 518 def __committed(self):
500 """ 519 """
501 Private slot called after the commit has been completed. 520 Private slot called after the commit has been completed.
502 """ 521 """
503 self.__reload() 522 self.__reload()
504 523
505 @pyqtSlot() 524 @pyqtSlot()
506 def __commitSelectAll(self): 525 def __commitSelectAll(self):
507 """ 526 """
508 Private slot to select all entries for commit. 527 Private slot to select all entries for commit.
509 """ 528 """
510 self.__setCheckMark(True) 529 self.__setCheckMark(True)
511 530
512 @pyqtSlot() 531 @pyqtSlot()
513 def __commitDeselectAll(self): 532 def __commitDeselectAll(self):
514 """ 533 """
515 Private slot to deselect all entries from commit. 534 Private slot to deselect all entries from commit.
516 """ 535 """
517 self.__setCheckMark(False) 536 self.__setCheckMark(False)
518 537
519 @pyqtSlot() 538 @pyqtSlot()
520 def __addUntracked(self, allItems=False): 539 def __addUntracked(self, allItems=False):
521 """ 540 """
522 Private slot to add the selected untracked entries. 541 Private slot to add the selected untracked entries.
523 542
524 @param allItems flag indicating to show the differences of all files 543 @param allItems flag indicating to show the differences of all files
525 (defaults to False) 544 (defaults to False)
526 @type bool (optional) 545 @type bool (optional)
527 """ 546 """
528 projectPath = self.__project.getProjectPath() 547 projectPath = self.__project.getProjectPath()
529 548
530 names = [ 549 names = (
531 os.path.join(projectPath, itm.text()) 550 [
532 for itm in self.__getUnversionedItems() 551 os.path.join(projectPath, itm.text())
533 ] if allItems else [ 552 for itm in self.__getUnversionedItems()
534 os.path.join(projectPath, itm.text()) 553 ]
535 for itm in self.__getSelectedUnversionedItems() 554 if allItems
536 ] 555 else [
537 556 os.path.join(projectPath, itm.text())
557 for itm in self.__getSelectedUnversionedItems()
558 ]
559 )
560
538 if not names: 561 if not names:
539 EricMessageBox.information( 562 EricMessageBox.information(
540 self, 563 self,
541 self.tr("Add"), 564 self.tr("Add"),
542 self.tr("""There are no unversioned entries""" 565 self.tr(
543 """ available/selected.""")) 566 """There are no unversioned entries""" """ available/selected."""
567 ),
568 )
544 return 569 return
545 570
546 self.__addedItemsText = [ 571 self.__addedItemsText = (
547 itm.text() for itm in self.__getUnversionedItems() 572 [itm.text() for itm in self.__getUnversionedItems()]
548 ] if allItems else [ 573 if allItems
549 itm.text() for itm in self.__getSelectedUnversionedItems() 574 else [itm.text() for itm in self.__getSelectedUnversionedItems()]
550 ] 575 )
551 576
552 vcs = self.__project.getVcs() 577 vcs = self.__project.getVcs()
553 vcs and vcs.vcsAdd(names) 578 vcs and vcs.vcsAdd(names)
554 self.__reload() 579 self.__reload()
555 580
556 @pyqtSlot(QListWidgetItem) 581 @pyqtSlot(QListWidgetItem)
557 def __itemDoubleClicked(self, itm): 582 def __itemDoubleClicked(self, itm):
558 """ 583 """
559 Private slot to handle double clicking an item. 584 Private slot to handle double clicking an item.
560 585
561 @param itm reference to the double clicked item 586 @param itm reference to the double clicked item
562 @type QListWidgetItem 587 @type QListWidgetItem
563 """ 588 """
564 projectPath = self.__project.getProjectPath() 589 projectPath = self.__project.getProjectPath()
565 590
566 if itm.data(self.StatusDataRole) in "MZ": 591 if itm.data(self.StatusDataRole) in "MZ":
567 # modified and conflicting items 592 # modified and conflicting items
568 name = os.path.join(projectPath, itm.text()) 593 name = os.path.join(projectPath, itm.text())
569 vcs = self.__project.getVcs() 594 vcs = self.__project.getVcs()
570 vcs and vcs.vcsDiff(name) 595 vcs and vcs.vcsDiff(name)
571 596
572 ########################################################################### 597 ###########################################################################
573 ## Menu handling methods 598 ## Menu handling methods
574 ########################################################################### 599 ###########################################################################
575 600
576 def __showActionsMenu(self): 601 def __showActionsMenu(self):
577 """ 602 """
578 Private slot to prepare the actions button menu before it is shown. 603 Private slot to prepare the actions button menu before it is shown.
579 """ 604 """
580 modified = len(self.__getSelectedModifiedItems()) 605 modified = len(self.__getSelectedModifiedItems())
597 self.__commitAct.setEnabled(commitable) 622 self.__commitAct.setEnabled(commitable)
598 self.__commitSelectAct.setEnabled(commitableUnselected) 623 self.__commitSelectAct.setEnabled(commitableUnselected)
599 self.__commitDeselectAct.setEnabled(commitable) 624 self.__commitDeselectAct.setEnabled(commitable)
600 self.__editAct.setEnabled(conflicting == 1) 625 self.__editAct.setEnabled(conflicting == 1)
601 self.__resolvedAct.setEnabled(conflicting) 626 self.__resolvedAct.setEnabled(conflicting)
602 627
603 def __getCommitableItems(self): 628 def __getCommitableItems(self):
604 """ 629 """
605 Private method to retrieve all entries the user wants to commit. 630 Private method to retrieve all entries the user wants to commit.
606 631
607 @return list of all items, the user has checked 632 @return list of all items, the user has checked
608 @rtype list of QListWidgetItem 633 @rtype list of QListWidgetItem
609 """ 634 """
610 commitableItems = [] 635 commitableItems = []
611 for row in range(self.__statusList.count()): 636 for row in range(self.__statusList.count()):
612 itm = self.__statusList.item(row) 637 itm = self.__statusList.item(row)
613 if ( 638 if itm.checkState() == Qt.CheckState.Checked:
614 itm.checkState() == Qt.CheckState.Checked
615 ):
616 commitableItems.append(itm) 639 commitableItems.append(itm)
617 return commitableItems 640 return commitableItems
618 641
619 def __getCommitableUnselectedItems(self): 642 def __getCommitableUnselectedItems(self):
620 """ 643 """
621 Private method to retrieve all entries the user may commit but hasn't 644 Private method to retrieve all entries the user may commit but hasn't
622 selected. 645 selected.
623 646
624 @return list of all items, the user has checked 647 @return list of all items, the user has checked
625 @rtype list of QListWidgetItem 648 @rtype list of QListWidgetItem
626 """ 649 """
627 items = [] 650 items = []
628 for row in range(self.__statusList.count()): 651 for row in range(self.__statusList.count()):
629 itm = self.__statusList.item(row) 652 itm = self.__statusList.item(row)
630 if ( 653 if (
631 (itm.flags() & Qt.ItemFlag.ItemIsUserCheckable == 654 itm.flags() & Qt.ItemFlag.ItemIsUserCheckable
632 Qt.ItemFlag.ItemIsUserCheckable) and 655 == Qt.ItemFlag.ItemIsUserCheckable
633 itm.checkState() == Qt.CheckState.Unchecked 656 ) and itm.checkState() == Qt.CheckState.Unchecked:
634 ):
635 items.append(itm) 657 items.append(itm)
636 return items 658 return items
637 659
638 def __getModifiedItems(self): 660 def __getModifiedItems(self):
639 """ 661 """
640 Private method to retrieve all entries, that have a modified status. 662 Private method to retrieve all entries, that have a modified status.
641 663
642 @return list of all items with a modified status 664 @return list of all items with a modified status
643 @rtype list of QListWidgetItem 665 @rtype list of QListWidgetItem
644 """ 666 """
645 items = [] 667 items = []
646 for row in range(self.__statusList.count()): 668 for row in range(self.__statusList.count()):
647 itm = self.__statusList.item(row) 669 itm = self.__statusList.item(row)
648 if itm.data(self.StatusDataRole) in "AMOR": 670 if itm.data(self.StatusDataRole) in "AMOR":
649 items.append(itm) 671 items.append(itm)
650 return items 672 return items
651 673
652 def __getSelectedModifiedItems(self): 674 def __getSelectedModifiedItems(self):
653 """ 675 """
654 Private method to retrieve all selected entries, that have a modified 676 Private method to retrieve all selected entries, that have a modified
655 status. 677 status.
656 678
657 @return list of all selected entries with a modified status 679 @return list of all selected entries with a modified status
658 @rtype list of QListWidgetItem 680 @rtype list of QListWidgetItem
659 """ 681 """
660 return [itm for itm in self.__statusList.selectedItems() 682 return [
661 if itm.data(self.StatusDataRole) in "AMOR"] 683 itm
662 684 for itm in self.__statusList.selectedItems()
685 if itm.data(self.StatusDataRole) in "AMOR"
686 ]
687
663 def __getUnversionedItems(self): 688 def __getUnversionedItems(self):
664 """ 689 """
665 Private method to retrieve all entries, that have an unversioned 690 Private method to retrieve all entries, that have an unversioned
666 status. 691 status.
667 692
668 @return list of all items with an unversioned status 693 @return list of all items with an unversioned status
669 @rtype list of QListWidgetItem 694 @rtype list of QListWidgetItem
670 """ 695 """
671 items = [] 696 items = []
672 for row in range(self.__statusList.count()): 697 for row in range(self.__statusList.count()):
673 itm = self.__statusList.item(row) 698 itm = self.__statusList.item(row)
674 if itm.data(self.StatusDataRole) == "?": 699 if itm.data(self.StatusDataRole) == "?":
675 items.append(itm) 700 items.append(itm)
676 return items 701 return items
677 702
678 def __getSelectedUnversionedItems(self): 703 def __getSelectedUnversionedItems(self):
679 """ 704 """
680 Private method to retrieve all selected entries, that have an 705 Private method to retrieve all selected entries, that have an
681 unversioned status. 706 unversioned status.
682 707
683 @return list of all items with an unversioned status 708 @return list of all items with an unversioned status
684 @rtype list of QListWidgetItem 709 @rtype list of QListWidgetItem
685 """ 710 """
686 return [itm for itm in self.__statusList.selectedItems() 711 return [
687 if itm.data(self.StatusDataRole) == "?"] 712 itm
688 713 for itm in self.__statusList.selectedItems()
714 if itm.data(self.StatusDataRole) == "?"
715 ]
716
689 def __getMissingItems(self): 717 def __getMissingItems(self):
690 """ 718 """
691 Private method to retrieve all entries, that have a missing status. 719 Private method to retrieve all entries, that have a missing status.
692 720
693 @return list of all items with a missing status 721 @return list of all items with a missing status
694 @rtype list of QListWidgetItem 722 @rtype list of QListWidgetItem
695 """ 723 """
696 return [itm for itm in self.__statusList.selectedItems() 724 return [
697 if itm.data(self.StatusDataRole) == "!"] 725 itm
698 726 for itm in self.__statusList.selectedItems()
727 if itm.data(self.StatusDataRole) == "!"
728 ]
729
699 def __getSelectedConflictingItems(self): 730 def __getSelectedConflictingItems(self):
700 """ 731 """
701 Private method to retrieve all selected entries, that have a conflict 732 Private method to retrieve all selected entries, that have a conflict
702 status. 733 status.
703 734
704 @return list of all selected entries with a conflict status 735 @return list of all selected entries with a conflict status
705 @rtype list of QListWidgetItem 736 @rtype list of QListWidgetItem
706 """ 737 """
707 return [itm for itm in self.__statusList.selectedItems() 738 return [
708 if itm.data(self.StatusDataRole) == "Z"] 739 itm
709 740 for itm in self.__statusList.selectedItems()
741 if itm.data(self.StatusDataRole) == "Z"
742 ]
743
710 @pyqtSlot() 744 @pyqtSlot()
711 def __addAllUntracked(self): 745 def __addAllUntracked(self):
712 """ 746 """
713 Private slot to handle the Add All action menu entry. 747 Private slot to handle the Add All action menu entry.
714 """ 748 """
715 self.__addUntracked(allItems=True) 749 self.__addUntracked(allItems=True)
716 750
717 @pyqtSlot() 751 @pyqtSlot()
718 def __diff(self, allItems=False): 752 def __diff(self, allItems=False):
719 """ 753 """
720 Private slot to handle the Differences action menu entry. 754 Private slot to handle the Differences action menu entry.
721 755
722 @param allItems flag indicating to show the differences of all files 756 @param allItems flag indicating to show the differences of all files
723 (defaults to False) 757 (defaults to False)
724 @type bool (optional) 758 @type bool (optional)
725 """ 759 """
726 projectPath = self.__project.getProjectPath() 760 projectPath = self.__project.getProjectPath()
727 761
762 names = (
763 [os.path.join(projectPath, itm.text()) for itm in self.__getModifiedItems()]
764 if allItems
765 else [
766 os.path.join(projectPath, itm.text())
767 for itm in self.__getSelectedModifiedItems()
768 ]
769 )
770 if not names:
771 EricMessageBox.information(
772 self,
773 self.tr("Differences"),
774 self.tr(
775 """There are no uncommitted changes""" """ available/selected."""
776 ),
777 )
778 return
779
780 vcs = self.__project.getVcs()
781 vcs and vcs.vcsDiff(names)
782
783 @pyqtSlot()
784 def __diffAll(self):
785 """
786 Private slot to handle the All Differences action menu entry.
787 """
788 self.__diff(allItems=True)
789
790 @pyqtSlot()
791 def __sbsDiff(self):
792 """
793 Private slot to handle the Side-By-Side Differences action menu entry.
794 """
795 projectPath = self.__project.getProjectPath()
796
728 names = [ 797 names = [
729 os.path.join(projectPath, itm.text())
730 for itm in self.__getModifiedItems()
731 ] if allItems else [
732 os.path.join(projectPath, itm.text()) 798 os.path.join(projectPath, itm.text())
733 for itm in self.__getSelectedModifiedItems() 799 for itm in self.__getSelectedModifiedItems()
734 ] 800 ]
735 if not names: 801 if not names:
736 EricMessageBox.information( 802 EricMessageBox.information(
737 self, 803 self,
738 self.tr("Differences"),
739 self.tr("""There are no uncommitted changes"""
740 """ available/selected."""))
741 return
742
743 vcs = self.__project.getVcs()
744 vcs and vcs.vcsDiff(names)
745
746 @pyqtSlot()
747 def __diffAll(self):
748 """
749 Private slot to handle the All Differences action menu entry.
750 """
751 self.__diff(allItems=True)
752
753 @pyqtSlot()
754 def __sbsDiff(self):
755 """
756 Private slot to handle the Side-By-Side Differences action menu entry.
757 """
758 projectPath = self.__project.getProjectPath()
759
760 names = [os.path.join(projectPath, itm.text())
761 for itm in self.__getSelectedModifiedItems()]
762 if not names:
763 EricMessageBox.information(
764 self,
765 self.tr("Differences Side-By-Side"), 804 self.tr("Differences Side-By-Side"),
766 self.tr("""There are no uncommitted changes""" 805 self.tr(
767 """ available/selected.""")) 806 """There are no uncommitted changes""" """ available/selected."""
807 ),
808 )
768 return 809 return
769 elif len(names) > 1: 810 elif len(names) > 1:
770 EricMessageBox.information( 811 EricMessageBox.information(
771 self, 812 self,
772 self.tr("Differences Side-By-Side"), 813 self.tr("Differences Side-By-Side"),
773 self.tr("""Only one file with uncommitted changes""" 814 self.tr(
774 """ must be selected.""")) 815 """Only one file with uncommitted changes"""
816 """ must be selected."""
817 ),
818 )
775 return 819 return
776 820
777 vcs = self.__project.getVcs() 821 vcs = self.__project.getVcs()
778 vcs and vcs.vcsSbsDiff(names[0]) 822 vcs and vcs.vcsSbsDiff(names[0])
779 823
780 @pyqtSlot() 824 @pyqtSlot()
781 def __revert(self): 825 def __revert(self):
782 """ 826 """
783 Private slot to handle the Revert action menu entry. 827 Private slot to handle the Revert action menu entry.
784 """ 828 """
785 projectPath = self.__project.getProjectPath() 829 projectPath = self.__project.getProjectPath()
786 830
787 names = [os.path.join(projectPath, itm.text()) 831 names = [
788 for itm in self.__getSelectedModifiedItems()] 832 os.path.join(projectPath, itm.text())
833 for itm in self.__getSelectedModifiedItems()
834 ]
789 if not names: 835 if not names:
790 EricMessageBox.information( 836 EricMessageBox.information(
791 self, 837 self,
792 self.tr("Revert"), 838 self.tr("Revert"),
793 self.tr("""There are no uncommitted changes""" 839 self.tr(
794 """ available/selected.""")) 840 """There are no uncommitted changes""" """ available/selected."""
841 ),
842 )
795 return 843 return
796 844
797 vcs = self.__project.getVcs() 845 vcs = self.__project.getVcs()
798 vcs and vcs.vcsRevert(names) 846 vcs and vcs.vcsRevert(names)
799 self.__reload() 847 self.__reload()
800 848
801 @pyqtSlot() 849 @pyqtSlot()
802 def __forgetMissing(self): 850 def __forgetMissing(self):
803 """ 851 """
804 Private slot to handle the Forget action menu entry. 852 Private slot to handle the Forget action menu entry.
805 """ 853 """
806 projectPath = self.__project.getProjectPath() 854 projectPath = self.__project.getProjectPath()
807 855
808 names = [os.path.join(projectPath, itm.text()) 856 names = [
809 for itm in self.__getMissingItems()] 857 os.path.join(projectPath, itm.text()) for itm in self.__getMissingItems()
858 ]
810 if not names: 859 if not names:
811 EricMessageBox.information( 860 EricMessageBox.information(
812 self, 861 self,
813 self.tr("Forget Missing"), 862 self.tr("Forget Missing"),
814 self.tr("""There are no missing entries""" 863 self.tr("""There are no missing entries""" """ available/selected."""),
815 """ available/selected.""")) 864 )
816 return 865 return
817 866
818 vcs = self.__project.getVcs() 867 vcs = self.__project.getVcs()
819 vcs and vcs.vcsForget(names) 868 vcs and vcs.vcsForget(names)
820 self.__reload() 869 self.__reload()
821 870
822 @pyqtSlot() 871 @pyqtSlot()
823 def __restoreMissing(self): 872 def __restoreMissing(self):
824 """ 873 """
825 Private slot to handle the Restore Missing context menu entry. 874 Private slot to handle the Restore Missing context menu entry.
826 """ 875 """
827 projectPath = self.__project.getProjectPath() 876 projectPath = self.__project.getProjectPath()
828 877
829 names = [os.path.join(projectPath, itm.text()) 878 names = [
830 for itm in self.__getMissingItems()] 879 os.path.join(projectPath, itm.text()) for itm in self.__getMissingItems()
880 ]
831 if not names: 881 if not names:
832 EricMessageBox.information( 882 EricMessageBox.information(
833 self, 883 self,
834 self.tr("Restore Missing"), 884 self.tr("Restore Missing"),
835 self.tr("""There are no missing entries""" 885 self.tr("""There are no missing entries""" """ available/selected."""),
836 """ available/selected.""")) 886 )
837 return 887 return
838 888
839 vcs = self.__project.getVcs() 889 vcs = self.__project.getVcs()
840 vcs and vcs.vcsRevert(names) 890 vcs and vcs.vcsRevert(names)
841 self.__reload() 891 self.__reload()
842 892
843 @pyqtSlot() 893 @pyqtSlot()
844 def __editConflict(self): 894 def __editConflict(self):
845 """ 895 """
846 Private slot to handle the Edit Conflict action menu entry. 896 Private slot to handle the Edit Conflict action menu entry.
847 """ 897 """
848 projectPath = self.__project.getProjectPath() 898 projectPath = self.__project.getProjectPath()
849 899
850 itm = self.__getSelectedConflictingItems()[0] 900 itm = self.__getSelectedConflictingItems()[0]
851 filename = os.path.join(projectPath, itm.text()) 901 filename = os.path.join(projectPath, itm.text())
852 if Utilities.MimeTypes.isTextFile(filename): 902 if Utilities.MimeTypes.isTextFile(filename):
853 self.__vm.getEditor(filename) 903 self.__vm.getEditor(filename)
854 904
855 @pyqtSlot() 905 @pyqtSlot()
856 def __conflictResolved(self): 906 def __conflictResolved(self):
857 """ 907 """
858 Private slot to handle the Conflict Resolved action menu entry. 908 Private slot to handle the Conflict Resolved action menu entry.
859 """ 909 """
860 projectPath = self.__project.getProjectPath() 910 projectPath = self.__project.getProjectPath()
861 911
862 names = [os.path.join(projectPath, itm.text()) 912 names = [
863 for itm in self.__getSelectedConflictingItems()] 913 os.path.join(projectPath, itm.text())
914 for itm in self.__getSelectedConflictingItems()
915 ]
864 if not names: 916 if not names:
865 EricMessageBox.information( 917 EricMessageBox.information(
866 self, 918 self,
867 self.tr("Conflict Resolved"), 919 self.tr("Conflict Resolved"),
868 self.tr("""There are no conflicting entries""" 920 self.tr(
869 """ available/selected.""")) 921 """There are no conflicting entries""" """ available/selected."""
922 ),
923 )
870 return 924 return
871 925
872 vcs = self.__project.getVcs() 926 vcs = self.__project.getVcs()
873 vcs and vcs.vcsResolved(names) 927 vcs and vcs.vcsResolved(names)
874 self.__reload() 928 self.__reload()
875 929
876 ####################################################################### 930 #######################################################################
877 ## Quick Commit handling methods 931 ## Quick Commit handling methods
878 ####################################################################### 932 #######################################################################
879 933
880 @pyqtSlot() 934 @pyqtSlot()
881 def __selectQuickCommitMessage(self): 935 def __selectQuickCommitMessage(self):
882 """ 936 """
883 Private slot to select a commit message from the list of 937 Private slot to select a commit message from the list of
884 saved messages. 938 saved messages.
890 commitMessages, 944 commitMessages,
891 selectionMode=QAbstractItemView.SelectionMode.SingleSelection, 945 selectionMode=QAbstractItemView.SelectionMode.SingleSelection,
892 title=self.tr("Quick Commit"), 946 title=self.tr("Quick Commit"),
893 message=self.tr("Select your commit message:"), 947 message=self.tr("Select your commit message:"),
894 doubleClickOk=True, 948 doubleClickOk=True,
895 parent=self 949 parent=self,
896 ) 950 )
897 if dlg.exec() == QDialog.DialogCode.Accepted: 951 if dlg.exec() == QDialog.DialogCode.Accepted:
898 selection = dlg.getSelection() 952 selection = dlg.getSelection()
899 if selection: 953 if selection:
900 self.__quickCommitEdit.setPlainText(selection[0]) 954 self.__quickCommitEdit.setPlainText(selection[0])
901 955
902 @pyqtSlot() 956 @pyqtSlot()
903 def __clearCommitMessages(self): 957 def __clearCommitMessages(self):
904 """ 958 """
905 Private slot to clear the list of saved commit messages. 959 Private slot to clear the list of saved commit messages.
906 """ 960 """
907 vcs = self.__project.getVcs() 961 vcs = self.__project.getVcs()
908 vcs and vcs.vcsClearCommitMessages() 962 vcs and vcs.vcsClearCommitMessages()
909 963
910 @pyqtSlot() 964 @pyqtSlot()
911 def __quickCommit(self): 965 def __quickCommit(self):
912 """ 966 """
913 Private slot to commit all marked entries with the entered 967 Private slot to commit all marked entries with the entered
914 commit message. 968 commit message.
915 """ 969 """
916 projectPath = self.__project.getProjectPath() 970 projectPath = self.__project.getProjectPath()
917 names = [] 971 names = []
918 972
919 for row in range(self.__statusList.count()): 973 for row in range(self.__statusList.count()):
920 itm = self.__statusList.item(row) 974 itm = self.__statusList.item(row)
921 if itm.checkState() == Qt.CheckState.Checked: 975 if itm.checkState() == Qt.CheckState.Checked:
922 names.append(os.path.join(projectPath, itm.text())) 976 names.append(os.path.join(projectPath, itm.text()))
923 977
924 if not names: 978 if not names:
925 EricMessageBox.information( 979 EricMessageBox.information(
926 self, 980 self,
927 self.tr("Commit"), 981 self.tr("Commit"),
928 self.tr("""There are no entries selected to be""" 982 self.tr("""There are no entries selected to be""" """ committed."""),
929 """ committed.""")) 983 )
930 return 984 return
931 985
932 if Preferences.getVCS("AutoSaveFiles"): 986 if Preferences.getVCS("AutoSaveFiles"):
933 vm = ericApp().getObject("ViewManager") 987 vm = ericApp().getObject("ViewManager")
934 for name in names: 988 for name in names:
935 vm.saveEditor(name) 989 vm.saveEditor(name)
936 990
937 commitMessage = self.__quickCommitEdit.toPlainText() 991 commitMessage = self.__quickCommitEdit.toPlainText()
938 vcs = self.__project.getVcs() 992 vcs = self.__project.getVcs()
939 if vcs: 993 if vcs:
940 vcs.vcsCommit(names, commitMessage, noDialog=True) 994 vcs.vcsCommit(names, commitMessage, noDialog=True)
941 vcs.vcsAddCommitMessage(commitMessage) 995 vcs.vcsAddCommitMessage(commitMessage)
942 self.__quickCommitEdit.clear() 996 self.__quickCommitEdit.clear()
943 997
944 @pyqtSlot() 998 @pyqtSlot()
945 def __quickCommitEditTextChanged(self): 999 def __quickCommitEditTextChanged(self):
946 """ 1000 """
947 Private slot to react upon changes of the quick commit text. 1001 Private slot to react upon changes of the quick commit text.
948 """ 1002 """
949 self.__quickCommitButton.setEnabled(bool( 1003 self.__quickCommitButton.setEnabled(bool(self.__quickCommitEdit.toPlainText()))
950 self.__quickCommitEdit.toPlainText())) 1004
951
952 def eventFilter(self, obj, evt): 1005 def eventFilter(self, obj, evt):
953 """ 1006 """
954 Public method to process some events for the Commit edit. 1007 Public method to process some events for the Commit edit.
955 1008
956 @param obj reference to the object the event was meant for 1009 @param obj reference to the object the event was meant for
957 @type QObject 1010 @type QObject
958 @param evt reference to the event object 1011 @param evt reference to the event object
959 @type QEvent 1012 @type QEvent
960 @return flag to indicate that the event was handled 1013 @return flag to indicate that the event was handled
961 @rtype bool 1014 @rtype bool
962 """ 1015 """
963 if ( 1016 if (
964 obj is self.__quickCommitEdit and 1017 obj is self.__quickCommitEdit
965 evt.type() == QEvent.Type.KeyPress and 1018 and evt.type() == QEvent.Type.KeyPress
966 evt.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter) and 1019 and evt.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter)
967 evt.modifiers() == Qt.KeyboardModifier.ControlModifier 1020 and evt.modifiers() == Qt.KeyboardModifier.ControlModifier
968 ): 1021 ):
969 # Ctrl-Enter or Ctrl-Return => commit 1022 # Ctrl-Enter or Ctrl-Return => commit
970 self.__quickCommitButton.animateClick() 1023 self.__quickCommitButton.animateClick()
971 return True 1024 return True
972 else: 1025 else:

eric ide

mercurial