eric7/VCS/ProjectBrowserHelper.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) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the base class of the VCS project browser helper.
8 """
9
10 import os
11
12 from PyQt5.QtCore import QObject, QCoreApplication
13 from PyQt5.QtWidgets import QDialog
14
15 from E5Gui.E5Application import e5App
16
17 from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
18
19 from Project.ProjectBrowserModel import (
20 ProjectBrowserSimpleDirectoryItem, ProjectBrowserFileItem,
21 ProjectBrowserDirectoryItem
22 )
23
24 import Preferences
25
26
27 class VcsProjectBrowserHelper(QObject):
28 """
29 Class implementing the base class of the VCS project browser helper.
30 """
31 def __init__(self, vcsObject, browserObject, projectObject,
32 isTranslationsBrowser, parent=None, name=None):
33 """
34 Constructor
35
36 @param vcsObject reference to the vcs object
37 @param browserObject reference to the project browser object
38 @param projectObject reference to the project object
39 @param isTranslationsBrowser flag indicating, the helper is requested
40 for the translations browser (this needs some special treatment)
41 @param parent parent widget (QWidget)
42 @param name name of this object (string)
43 """
44 super().__init__(parent)
45 if name:
46 self.setObjectName(name)
47
48 self.vcs = vcsObject
49 self.browser = browserObject
50 self.isTranslationsBrowser = isTranslationsBrowser
51 self.project = projectObject
52
53 def addVCSMenus(self, mainMenu, multiMenu, backMenu, dirMenu,
54 dirMultiMenu):
55 """
56 Public method to add the VCS entries to the various project browser
57 menus.
58
59 @param mainMenu reference to the main menu (QPopupMenu)
60 @param multiMenu reference to the multiple selection menu (QPopupMenu)
61 @param backMenu reference to the background menu (QPopupMenu)
62 @param dirMenu reference to the directory menu (QPopupMenu)
63 @param dirMultiMenu reference to the multiple selection directory
64 menu (QPopupMenu)
65 """
66 self._addVCSMenu(mainMenu)
67 self._addVCSMenuMulti(multiMenu)
68 self._addVCSMenuBack(backMenu)
69 self._addVCSMenuDir(dirMenu)
70 self._addVCSMenuDirMulti(dirMultiMenu)
71
72 def showContextMenu(self, menu, standardItems):
73 """
74 Public slot called before the context menu is shown.
75
76 It enables/disables the VCS menu entries depending on the overall
77 VCS status and the file status.
78
79 @param menu reference to the menu to be shown
80 @param standardItems array of standard items that need
81 activation/deactivation depending on the overall VCS status
82 @exception RuntimeError to indicate that this method must be
83 implemented by a subclass
84 """
85 raise RuntimeError('Not implemented')
86
87 def showContextMenuMulti(self, menu, standardItems):
88 """
89 Public slot called before the context menu (multiple selections) is
90 shown.
91
92 It enables/disables the VCS menu entries depending on the overall
93 VCS status and the files status.
94
95 @param menu reference to the menu to be shown
96 @param standardItems array of standard items that need
97 activation/deactivation depending on the overall VCS status
98 @exception RuntimeError to indicate that this method must be
99 implemented by a subclass
100 """
101 raise RuntimeError('Not implemented')
102
103 def showContextMenuDir(self, menu, standardItems):
104 """
105 Public slot called before the context menu is shown.
106
107 It enables/disables the VCS menu entries depending on the overall
108 VCS status and the directory status.
109
110 @param menu reference to the menu to be shown
111 @param standardItems array of standard items that
112 need activation/deactivation depending on the overall VCS status
113 @exception RuntimeError to indicate that this method must be
114 implemented by a subclass
115 """
116 raise RuntimeError('Not implemented')
117
118 def showContextMenuDirMulti(self, menu, standardItems):
119 """
120 Public slot called before the context menu is shown.
121
122 It enables/disables the VCS menu entries depending on the overall
123 VCS status and the directory status.
124
125 @param menu reference to the menu to be shown
126 @param standardItems array of standard items that need
127 activation/deactivation depending on the overall VCS status
128 @exception RuntimeError to indicate that this method must be
129 implemented by a subclass
130 """
131 raise RuntimeError('Not implemented')
132
133 ###########################################################################
134 ## General menu handling methods below
135 ###########################################################################
136
137 def _VCSUpdate(self):
138 """
139 Protected slot called by the context menu to update a file from the
140 VCS repository.
141 """
142 if self.isTranslationsBrowser:
143 names = [itm.dirName()
144 for itm in self.browser.getSelectedItems(
145 [ProjectBrowserSimpleDirectoryItem])]
146 if not names:
147 names = [itm.fileName()
148 for itm in self.browser.getSelectedItems(
149 [ProjectBrowserFileItem])]
150 else:
151 names = []
152 for itm in self.browser.getSelectedItems():
153 try:
154 name = itm.fileName()
155 except AttributeError:
156 name = itm.dirName()
157 names.append(name)
158 self.vcs.vcsUpdate(names)
159
160 def _VCSCommit(self):
161 """
162 Protected slot called by the context menu to commit the changes to the
163 VCS repository.
164 """
165 if self.isTranslationsBrowser:
166 names = [itm.dirName()
167 for itm in self.browser.getSelectedItems(
168 [ProjectBrowserSimpleDirectoryItem])]
169 if not names:
170 names = [itm.fileName()
171 for itm in self.browser.getSelectedItems(
172 [ProjectBrowserFileItem])]
173 else:
174 names = []
175 for itm in self.browser.getSelectedItems():
176 try:
177 name = itm.fileName()
178 except AttributeError:
179 name = itm.dirName()
180 names.append(name)
181 if Preferences.getVCS("AutoSaveFiles"):
182 vm = e5App().getObject("ViewManager")
183 for name in names:
184 vm.saveEditor(name)
185 self.vcs.vcsCommit(names, '')
186
187 def _VCSAdd(self):
188 """
189 Protected slot called by the context menu to add the selected file to
190 the VCS repository.
191 """
192 if self.isTranslationsBrowser:
193 items = self.browser.getSelectedItems(
194 [ProjectBrowserSimpleDirectoryItem])
195 if items:
196 names = [itm.dirName() for itm in items]
197 qnames = []
198 else:
199 items = self.browser.getSelectedItems([ProjectBrowserFileItem])
200 names = []
201 qnames = []
202 for itm in items:
203 name = itm.fileName()
204 if name.endswith('.qm'):
205 qnames.append(name)
206 else:
207 names.append(name)
208 else:
209 names = []
210 for itm in self.browser.getSelectedItems():
211 try:
212 name = itm.fileName()
213 except AttributeError:
214 name = itm.dirName()
215 names.append(name)
216 qnames = []
217
218 if not len(names + qnames):
219 return
220
221 if len(names + qnames) == 1:
222 if names:
223 self.vcs.vcsAdd(names[0], os.path.isdir(names[0]))
224 else:
225 if self.vcs.canDetectBinaries:
226 self.vcs.vcsAdd(qnames)
227 else:
228 self.vcs.vcsAddBinary(qnames)
229 else:
230 if self.vcs.canDetectBinaries:
231 self.vcs.vcsAdd(names + qnames)
232 else:
233 self.vcs.vcsAdd(names)
234 if len(qnames):
235 self.vcs.vcsAddBinary(qnames)
236 for fn in names + qnames:
237 self._updateVCSStatus(fn)
238
239 def _VCSAddTree(self):
240 """
241 Protected slot called by the context menu.
242
243 It is used to add the selected
244 directory tree to the VCS repository.
245 """
246 names = []
247 for itm in self.browser.getSelectedItems():
248 try:
249 name = itm.fileName()
250 except AttributeError:
251 name = itm.dirName()
252 names.append(name)
253 self.vcs.vcsAddTree(names)
254 for fn in names:
255 self._updateVCSStatus(fn)
256
257 def _VCSRemove(self):
258 """
259 Protected slot called by the context menu to remove the selected file
260 from the VCS repository.
261 """
262 if self.isTranslationsBrowser:
263 items = self.browser.getSelectedItems(
264 [ProjectBrowserSimpleDirectoryItem])
265 if items:
266 return # not supported
267
268 isRemoveDirs = False
269 items = self.browser.getSelectedItems([ProjectBrowserFileItem])
270 names = [itm.fileName() for itm in items]
271
272 dlg = DeleteFilesConfirmationDialog(
273 self.parent(),
274 QCoreApplication.translate(
275 "VcsProjectBrowserHelper",
276 "Remove from repository (and disk)"),
277 QCoreApplication.translate(
278 "VcsProjectBrowserHelper",
279 "Do you really want to remove these translation files from"
280 " the repository (and disk)?"),
281 names)
282 else:
283 items = self.browser.getSelectedItems()
284 isRemoveDirs = (
285 len(items) == self.browser.getSelectedItemsCount(
286 [ProjectBrowserSimpleDirectoryItem,
287 ProjectBrowserDirectoryItem])
288 )
289 if isRemoveDirs:
290 names = [itm.dirName() for itm in items]
291 else:
292 names = [itm.fileName() for itm in items]
293 files = [self.browser.project.getRelativePath(name)
294 for name in names]
295
296 dlg = DeleteFilesConfirmationDialog(
297 self.parent(),
298 QCoreApplication.translate(
299 "VcsProjectBrowserHelper",
300 "Remove from repository (and disk)"),
301 QCoreApplication.translate(
302 "VcsProjectBrowserHelper",
303 "Do you really want to remove these files/directories"
304 " from the repository (and disk)?"),
305 files)
306
307 if dlg.exec() == QDialog.DialogCode.Accepted:
308 status = self.vcs.vcsRemove(names)
309 if status:
310 if isRemoveDirs:
311 self.browser._removeDir()
312 # remove directories from Project
313 else:
314 self.browser._removeFile() # remove file(s) from project
315
316 def _VCSLog(self):
317 """
318 Protected slot called by the context menu to show the VCS log of a
319 file/directory.
320 """
321 # kept for backward compatibility for plug-ins
322 self._VCSLogBrowser()
323
324 def _VCSLogBrowser(self):
325 """
326 Protected slot called by the context menu to show the log browser for a
327 file.
328 """
329 itm = self.browser.currentItem()
330 try:
331 fn = itm.fileName()
332 isFile = True
333 except AttributeError:
334 fn = itm.dirName()
335 isFile = False
336 self.vcs.vcsLogBrowser(fn, isFile=isFile)
337
338 def _VCSDiff(self):
339 """
340 Protected slot called by the context menu to show the difference of a
341 file/directory to the repository.
342 """
343 names = []
344 for itm in self.browser.getSelectedItems():
345 try:
346 name = itm.fileName()
347 except AttributeError:
348 name = itm.dirName()
349 names.append(name)
350 self.vcs.vcsDiff(names)
351
352 def _VCSStatus(self):
353 """
354 Protected slot called by the context menu to show the status of a file.
355 """
356 if self.isTranslationsBrowser:
357 items = self.browser.getSelectedItems(
358 [ProjectBrowserSimpleDirectoryItem])
359 if items:
360 names = [itm.dirName() for itm in items]
361 else:
362 items = self.browser.getSelectedItems([ProjectBrowserFileItem])
363 names = [itm.fileName() for itm in items]
364 else:
365 names = []
366 for itm in self.browser.getSelectedItems():
367 try:
368 name = itm.fileName()
369 except AttributeError:
370 name = itm.dirName()
371 names.append(name)
372 self.vcs.vcsStatus(names)
373
374 def _VCSRevert(self):
375 """
376 Protected slot called by the context menu to revert changes made to a
377 file.
378 """
379 names = []
380 for itm in self.browser.getSelectedItems():
381 try:
382 name = itm.fileName()
383 except AttributeError:
384 name = itm.dirName()
385 names.append(name)
386 self.vcs.vcsRevert(names)
387
388 def _VCSMerge(self):
389 """
390 Protected slot called by the context menu to merge changes into to a
391 file.
392 """
393 itm = self.browser.currentItem()
394 try:
395 name = itm.fileName()
396 except AttributeError:
397 name = itm.dirName()
398 self.vcs.vcsMerge(name)
399
400 def _VCSInfoDisplay(self):
401 """
402 Protected slot called to show some vcs information.
403 """
404 from .RepositoryInfoDialog import VcsRepositoryInfoDialog
405 info = self.vcs.vcsRepositoryInfos(self.project.ppath)
406 dlg = VcsRepositoryInfoDialog(None, info)
407 dlg.exec()
408
409 def _updateVCSStatus(self, name):
410 """
411 Protected method to update the VCS status of an item.
412
413 @param name filename or directoryname of the item to be updated
414 (string)
415 """
416 self.project.getModel().updateVCSStatus(name)

eric ide

mercurial