1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing the VCS project browser helper for Mercurial. 8""" 9 10import os 11 12from PyQt5.QtWidgets import QMenu, QDialog 13 14from E5Gui.E5Application import e5App 15 16from Project.ProjectBrowserModel import ProjectBrowserFileItem 17 18from VCS.ProjectBrowserHelper import VcsProjectBrowserHelper 19 20import UI.PixmapCache 21 22 23class HgProjectBrowserHelper(VcsProjectBrowserHelper): 24 """ 25 Class implementing the VCS project browser helper for Mercurial. 26 """ 27 def __init__(self, vcsObject, browserObject, projectObject, 28 isTranslationsBrowser, parent=None, name=None): 29 """ 30 Constructor 31 32 @param vcsObject reference to the vcs object 33 @param browserObject reference to the project browser object 34 @param projectObject reference to the project object 35 @param isTranslationsBrowser flag indicating, the helper is requested 36 for the translations browser (this needs some special treatment) 37 @param parent parent widget (QWidget) 38 @param name name of this object (string) 39 """ 40 VcsProjectBrowserHelper.__init__(self, vcsObject, browserObject, 41 projectObject, isTranslationsBrowser, 42 parent, name) 43 44 # instantiate the extensions 45 from .ShelveExtension.ProjectBrowserHelper import ( 46 ShelveProjectBrowserHelper 47 ) 48 from .LargefilesExtension.ProjectBrowserHelper import ( 49 LargefilesProjectBrowserHelper 50 ) 51 self.__extensions = { 52 "shelve": ShelveProjectBrowserHelper( 53 vcsObject, browserObject, projectObject), 54 "largefiles": LargefilesProjectBrowserHelper( 55 vcsObject, browserObject, projectObject), 56 } 57 58 self.__extensionMenuTitles = {} 59 for extension in self.__extensions: 60 self.__extensionMenuTitles[ 61 self.__extensions[extension].menuTitle()] = extension 62 self.__extensionMenus = {} 63 for extension in self.__extensions: 64 self.__extensionMenus[extension] = ( 65 self.__extensions[extension].initMenus() 66 ) 67 68 def __showExtensionMenu(self, key, controlled): 69 """ 70 Private slot showing the extensions menu. 71 72 @param key menu key (string, one of 'mainMenu', 'multiMenu', 73 'backMenu', 'dirMenu' or 'dirMultiMenu') 74 @param controlled flag indicating to show the menu for a 75 version controlled entry or a non-version controlled entry 76 (boolean) 77 """ 78 for extensionName in self.__extensionMenus: 79 if key in self.__extensionMenus[extensionName]: 80 self.__extensionMenus[extensionName][key].setEnabled( 81 self.vcs.isExtensionActive(extensionName)) 82 if self.__extensionMenus[extensionName][key].isEnabled(): 83 # adjust individual extension menu entries 84 self.__extensions[extensionName].showExtensionMenu( 85 key, controlled) 86 if (not self.__extensionMenus[extensionName][key] 87 .isEnabled() and self.__extensionMenus[extensionName][key] 88 .isTearOffMenuVisible()): 89 self.__extensionMenus[extensionName][key].hideTearOffMenu() 90 91 def showContextMenu(self, menu, standardItems): 92 """ 93 Public slot called before the context menu is shown. 94 95 It enables/disables the VCS menu entries depending on the overall 96 VCS status and the file status. 97 98 @param menu reference to the menu to be shown 99 @param standardItems array of standard items that need 100 activation/deactivation depending on the overall VCS status 101 """ 102 if self.browser.currentItem().data(1) == self.vcs.vcsName(): 103 controlled = True 104 for act in self.vcsMenuActions: 105 act.setEnabled(True) 106 for act in self.vcsAddMenuActions: 107 act.setEnabled(False) 108 for act in standardItems: 109 act.setEnabled(False) 110 if not hasattr(self.browser.currentItem(), 'fileName'): 111 self.annotateAct.setEnabled(False) 112 else: 113 controlled = False 114 for act in self.vcsMenuActions: 115 act.setEnabled(False) 116 for act in self.vcsAddMenuActions: 117 act.setEnabled(True) 118 for act in standardItems: 119 act.setEnabled(True) 120 self.__showExtensionMenu("mainMenu", controlled) 121 122 def showContextMenuMulti(self, menu, standardItems): 123 """ 124 Public slot called before the context menu (multiple selections) is 125 shown. 126 127 It enables/disables the VCS menu entries depending on the overall 128 VCS status and the files status. 129 130 @param menu reference to the menu to be shown 131 @param standardItems array of standard items that need 132 activation/deactivation depending on the overall VCS status 133 """ 134 vcsName = self.vcs.vcsName() 135 items = self.browser.getSelectedItems() 136 vcsItems = 0 137 # determine number of selected items under VCS control 138 for itm in items: 139 if itm.data(1) == vcsName: 140 vcsItems += 1 141 142 if vcsItems > 0: 143 controlled = True 144 if vcsItems != len(items): 145 for act in self.vcsMultiMenuActions: 146 act.setEnabled(False) 147 else: 148 for act in self.vcsMultiMenuActions: 149 act.setEnabled(True) 150 for act in self.vcsAddMultiMenuActions: 151 act.setEnabled(False) 152 for act in standardItems: 153 act.setEnabled(False) 154 else: 155 controlled = False 156 for act in self.vcsMultiMenuActions: 157 act.setEnabled(False) 158 for act in self.vcsAddMultiMenuActions: 159 act.setEnabled(True) 160 for act in standardItems: 161 act.setEnabled(True) 162 self.__showExtensionMenu("multiMenu", controlled) 163 164 def showContextMenuDir(self, menu, standardItems): 165 """ 166 Public slot called before the context menu is shown. 167 168 It enables/disables the VCS menu entries depending on the overall 169 VCS status and the directory status. 170 171 @param menu reference to the menu to be shown 172 @param standardItems array of standard items that need 173 activation/deactivation depending on the overall VCS status 174 """ 175 if self.browser.currentItem().data(1) == self.vcs.vcsName(): 176 controlled = True 177 for act in self.vcsDirMenuActions: 178 act.setEnabled(True) 179 for act in self.vcsAddDirMenuActions: 180 act.setEnabled(False) 181 for act in standardItems: 182 act.setEnabled(False) 183 else: 184 controlled = False 185 for act in self.vcsDirMenuActions: 186 act.setEnabled(False) 187 for act in self.vcsAddDirMenuActions: 188 act.setEnabled(True) 189 for act in standardItems: 190 act.setEnabled(True) 191 self.__showExtensionMenu("dirMenu", controlled) 192 193 def showContextMenuDirMulti(self, menu, standardItems): 194 """ 195 Public slot called before the context menu is shown. 196 197 It enables/disables the VCS menu entries depending on the overall 198 VCS status and the directory status. 199 200 @param menu reference to the menu to be shown 201 @param standardItems array of standard items that need 202 activation/deactivation depending on the overall VCS status 203 """ 204 vcsName = self.vcs.vcsName() 205 items = self.browser.getSelectedItems() 206 vcsItems = 0 207 # determine number of selected items under VCS control 208 for itm in items: 209 if itm.data(1) == vcsName: 210 vcsItems += 1 211 212 if vcsItems > 0: 213 controlled = True 214 if vcsItems != len(items): 215 for act in self.vcsDirMultiMenuActions: 216 act.setEnabled(False) 217 else: 218 for act in self.vcsDirMultiMenuActions: 219 act.setEnabled(True) 220 for act in self.vcsAddDirMultiMenuActions: 221 act.setEnabled(False) 222 for act in standardItems: 223 act.setEnabled(False) 224 else: 225 controlled = False 226 for act in self.vcsDirMultiMenuActions: 227 act.setEnabled(False) 228 for act in self.vcsAddDirMultiMenuActions: 229 act.setEnabled(True) 230 for act in standardItems: 231 act.setEnabled(True) 232 self.__showExtensionMenu("dirMultiMenu", controlled) 233 234 ########################################################################### 235 ## Private menu generation methods below 236 ########################################################################### 237 238 def __addExtensionsMenu(self, menu, key): 239 """ 240 Private method to add an extension menu entry. 241 242 @param menu menu to add it to (QMenu) 243 @param key menu key (string, one of 'mainMenu', 'multiMenu', 244 'backMenu', 'dirMenu' or 'dirMultiMenu') 245 @return reference to the menu action (QAction) 246 """ 247 act = None 248 if key in ['mainMenu', 'multiMenu', 'backMenu', 'dirMenu', 249 'dirMultiMenu']: 250 extensionsMenu = QMenu(self.tr("Extensions"), menu) 251 extensionsMenu.setTearOffEnabled(True) 252 for extensionMenuTitle in sorted(self.__extensionMenuTitles): 253 extensionName = self.__extensionMenuTitles[extensionMenuTitle] 254 if key in self.__extensionMenus[extensionName]: 255 extensionsMenu.addMenu( 256 self.__extensionMenus[extensionName][key]) 257 if not extensionsMenu.isEmpty(): 258 if not menu.isEmpty(): 259 menu.addSeparator() 260 act = menu.addMenu(extensionsMenu) 261 return act 262 263 ########################################################################### 264 ## Protected menu generation methods below 265 ########################################################################### 266 267 def _addVCSMenu(self, mainMenu): 268 """ 269 Protected method used to add the VCS menu to all project browsers. 270 271 @param mainMenu reference to the menu to be amended 272 """ 273 self.vcsMenuActions = [] 274 self.vcsAddMenuActions = [] 275 276 menu = QMenu(self.tr("Version Control")) 277 278 act = menu.addAction( 279 UI.PixmapCache.getIcon( 280 os.path.join("VcsPlugins", "vcsMercurial", "icons", 281 "mercurial.svg")), 282 self.vcs.vcsName(), self._VCSInfoDisplay) 283 font = act.font() 284 font.setBold(True) 285 act.setFont(font) 286 menu.addSeparator() 287 288 act = menu.addAction( 289 UI.PixmapCache.getIcon("vcsCommit"), 290 self.tr('Commit changes to repository...'), 291 self._VCSCommit) 292 self.vcsMenuActions.append(act) 293 self.__addExtensionsMenu(menu, 'mainMenu') 294 menu.addSeparator() 295 act = menu.addAction( 296 UI.PixmapCache.getIcon("vcsAdd"), 297 self.tr('Add to repository'), 298 self._VCSAdd) 299 self.vcsAddMenuActions.append(act) 300 act = menu.addAction( 301 UI.PixmapCache.getIcon("vcsRemove"), 302 self.tr('Remove from repository (and disk)'), 303 self._VCSRemove) 304 self.vcsMenuActions.append(act) 305 act = menu.addAction( 306 UI.PixmapCache.getIcon("vcsRemove"), 307 self.tr('Remove from repository only'), 308 self.__HgForget) 309 self.vcsMenuActions.append(act) 310 menu.addSeparator() 311 act = menu.addAction(self.tr('Copy'), self.__HgCopy) 312 self.vcsMenuActions.append(act) 313 act = menu.addAction(self.tr('Move'), self.__HgMove) 314 self.vcsMenuActions.append(act) 315 menu.addSeparator() 316 act = menu.addAction( 317 UI.PixmapCache.getIcon("vcsLog"), 318 self.tr('Show log browser'), self._VCSLogBrowser) 319 self.vcsMenuActions.append(act) 320 menu.addSeparator() 321 act = menu.addAction( 322 UI.PixmapCache.getIcon("vcsStatus"), 323 self.tr('Show status'), self._VCSStatus) 324 self.vcsMenuActions.append(act) 325 menu.addSeparator() 326 act = menu.addAction( 327 UI.PixmapCache.getIcon("vcsDiff"), 328 self.tr('Show differences'), self._VCSDiff) 329 self.vcsMenuActions.append(act) 330 act = menu.addAction( 331 UI.PixmapCache.getIcon("vcsSbsDiff"), 332 self.tr('Show differences side-by-side'), self.__HgSbsDiff) 333 self.vcsMenuActions.append(act) 334 act = menu.addAction( 335 UI.PixmapCache.getIcon("vcsDiff"), 336 self.tr('Show differences (extended)'), 337 self.__HgExtendedDiff) 338 self.vcsMenuActions.append(act) 339 act = menu.addAction( 340 UI.PixmapCache.getIcon("vcsSbsDiff"), 341 self.tr('Show differences side-by-side (extended)'), 342 self.__HgSbsExtendedDiff) 343 self.vcsMenuActions.append(act) 344 self.annotateAct = menu.addAction( 345 self.tr('Show annotated file'), 346 self.__HgAnnotate) 347 self.vcsMenuActions.append(self.annotateAct) 348 menu.addSeparator() 349 act = menu.addAction( 350 UI.PixmapCache.getIcon("vcsRevert"), 351 self.tr('Revert changes'), self.__HgRevert) 352 self.vcsMenuActions.append(act) 353 act = menu.addAction( 354 self.tr('Conflicts resolved'), self.__HgResolved) 355 self.vcsMenuActions.append(act) 356 act = menu.addAction( 357 self.tr('Conflicts unresolved'), self.__HgUnresolved) 358 self.vcsMenuActions.append(act) 359 act = menu.addAction( 360 self.tr('Re-Merge'), self.__HgReMerge) 361 self.vcsMenuActions.append(act) 362 menu.addSeparator() 363 menu.addAction(self.tr('Select all local file entries'), 364 self.browser.selectLocalEntries) 365 menu.addAction(self.tr('Select all versioned file entries'), 366 self.browser.selectVCSEntries) 367 menu.addAction(self.tr('Select all local directory entries'), 368 self.browser.selectLocalDirEntries) 369 menu.addAction(self.tr('Select all versioned directory entries'), 370 self.browser.selectVCSDirEntries) 371 menu.addSeparator() 372 menu.addAction(self.tr("Configure..."), self.__HgConfigure) 373 374 mainMenu.addSeparator() 375 mainMenu.addMenu(menu) 376 self.menu = menu 377 378 def _addVCSMenuMulti(self, mainMenu): 379 """ 380 Protected method used to add the VCS menu for multi selection to all 381 project browsers. 382 383 @param mainMenu reference to the menu to be amended 384 """ 385 self.vcsMultiMenuActions = [] 386 self.vcsAddMultiMenuActions = [] 387 388 menu = QMenu(self.tr("Version Control")) 389 390 act = menu.addAction( 391 UI.PixmapCache.getIcon( 392 os.path.join("VcsPlugins", "vcsMercurial", "icons", 393 "mercurial.svg")), 394 self.vcs.vcsName(), self._VCSInfoDisplay) 395 font = act.font() 396 font.setBold(True) 397 act.setFont(font) 398 menu.addSeparator() 399 400 act = menu.addAction( 401 UI.PixmapCache.getIcon("vcsCommit"), 402 self.tr('Commit changes to repository...'), 403 self._VCSCommit) 404 self.vcsMultiMenuActions.append(act) 405 self.__addExtensionsMenu(menu, 'multiMenu') 406 menu.addSeparator() 407 act = menu.addAction( 408 UI.PixmapCache.getIcon("vcsAdd"), 409 self.tr('Add to repository'), self._VCSAdd) 410 self.vcsAddMultiMenuActions.append(act) 411 act = menu.addAction( 412 UI.PixmapCache.getIcon("vcsRemove"), 413 self.tr('Remove from repository (and disk)'), 414 self._VCSRemove) 415 self.vcsMultiMenuActions.append(act) 416 act = menu.addAction( 417 UI.PixmapCache.getIcon("vcsRemove"), 418 self.tr('Remove from repository only'), 419 self.__HgForget) 420 self.vcsMultiMenuActions.append(act) 421 menu.addSeparator() 422 act = menu.addAction( 423 UI.PixmapCache.getIcon("vcsStatus"), 424 self.tr('Show status'), self._VCSStatus) 425 self.vcsMultiMenuActions.append(act) 426 menu.addSeparator() 427 act = menu.addAction( 428 UI.PixmapCache.getIcon("vcsDiff"), 429 self.tr('Show differences'), self._VCSDiff) 430 self.vcsMultiMenuActions.append(act) 431 act = menu.addAction( 432 UI.PixmapCache.getIcon("vcsDiff"), 433 self.tr('Show differences (extended)'), 434 self.__HgExtendedDiff) 435 self.vcsMultiMenuActions.append(act) 436 menu.addSeparator() 437 act = menu.addAction( 438 UI.PixmapCache.getIcon("vcsRevert"), 439 self.tr('Revert changes'), self.__HgRevert) 440 self.vcsMultiMenuActions.append(act) 441 act = menu.addAction( 442 self.tr('Conflicts resolved'), self.__HgResolved) 443 self.vcsMultiMenuActions.append(act) 444 act = menu.addAction( 445 self.tr('Conflicts unresolved'), self.__HgUnresolved) 446 self.vcsMultiMenuActions.append(act) 447 act = menu.addAction( 448 self.tr('Re-Merge'), self.__HgReMerge) 449 self.vcsMultiMenuActions.append(act) 450 menu.addSeparator() 451 menu.addAction(self.tr('Select all local file entries'), 452 self.browser.selectLocalEntries) 453 menu.addAction(self.tr('Select all versioned file entries'), 454 self.browser.selectVCSEntries) 455 menu.addAction(self.tr('Select all local directory entries'), 456 self.browser.selectLocalDirEntries) 457 menu.addAction(self.tr('Select all versioned directory entries'), 458 self.browser.selectVCSDirEntries) 459 menu.addSeparator() 460 menu.addAction(self.tr("Configure..."), self.__HgConfigure) 461 462 mainMenu.addSeparator() 463 mainMenu.addMenu(menu) 464 self.menuMulti = menu 465 466 def _addVCSMenuBack(self, mainMenu): 467 """ 468 Protected method used to add the VCS menu to all project browsers. 469 470 @param mainMenu reference to the menu to be amended 471 """ 472 menu = QMenu(self.tr("Version Control")) 473 474 act = menu.addAction( 475 UI.PixmapCache.getIcon( 476 os.path.join("VcsPlugins", "vcsMercurial", "icons", 477 "mercurial.svg")), 478 self.vcs.vcsName(), self._VCSInfoDisplay) 479 font = act.font() 480 font.setBold(True) 481 act.setFont(font) 482 menu.addSeparator() 483 484 menu.addAction(self.tr('Select all local file entries'), 485 self.browser.selectLocalEntries) 486 menu.addAction(self.tr('Select all versioned file entries'), 487 self.browser.selectVCSEntries) 488 menu.addAction(self.tr('Select all local directory entries'), 489 self.browser.selectLocalDirEntries) 490 menu.addAction(self.tr('Select all versioned directory entries'), 491 self.browser.selectVCSDirEntries) 492 menu.addSeparator() 493 menu.addAction(self.tr("Configure..."), self.__HgConfigure) 494 495 mainMenu.addSeparator() 496 mainMenu.addMenu(menu) 497 self.menuBack = menu 498 499 def _addVCSMenuDir(self, mainMenu): 500 """ 501 Protected method used to add the VCS menu to all project browsers. 502 503 @param mainMenu reference to the menu to be amended 504 """ 505 if mainMenu is None: 506 return 507 508 self.vcsDirMenuActions = [] 509 self.vcsAddDirMenuActions = [] 510 511 menu = QMenu(self.tr("Version Control")) 512 513 act = menu.addAction( 514 UI.PixmapCache.getIcon( 515 os.path.join("VcsPlugins", "vcsMercurial", "icons", 516 "mercurial.svg")), 517 self.vcs.vcsName(), self._VCSInfoDisplay) 518 font = act.font() 519 font.setBold(True) 520 act.setFont(font) 521 menu.addSeparator() 522 523 act = menu.addAction( 524 UI.PixmapCache.getIcon("vcsCommit"), 525 self.tr('Commit changes to repository...'), 526 self._VCSCommit) 527 self.vcsDirMenuActions.append(act) 528 self.__addExtensionsMenu(menu, 'dirMenu') 529 menu.addSeparator() 530 act = menu.addAction( 531 UI.PixmapCache.getIcon("vcsAdd"), 532 self.tr('Add to repository'), self._VCSAdd) 533 self.vcsAddDirMenuActions.append(act) 534 act = menu.addAction( 535 UI.PixmapCache.getIcon("vcsRemove"), 536 self.tr('Remove from repository (and disk)'), 537 self._VCSRemove) 538 self.vcsDirMenuActions.append(act) 539 menu.addSeparator() 540 act = menu.addAction(self.tr('Copy'), self.__HgCopy) 541 self.vcsDirMenuActions.append(act) 542 act = menu.addAction(self.tr('Move'), self.__HgMove) 543 self.vcsDirMenuActions.append(act) 544 menu.addSeparator() 545 act = menu.addAction( 546 UI.PixmapCache.getIcon("vcsLog"), 547 self.tr('Show log browser'), self._VCSLogBrowser) 548 self.vcsDirMenuActions.append(act) 549 menu.addSeparator() 550 act = menu.addAction( 551 UI.PixmapCache.getIcon("vcsStatus"), 552 self.tr('Show status'), self._VCSStatus) 553 self.vcsDirMenuActions.append(act) 554 menu.addSeparator() 555 act = menu.addAction( 556 UI.PixmapCache.getIcon("vcsDiff"), 557 self.tr('Show differences'), self._VCSDiff) 558 self.vcsDirMenuActions.append(act) 559 act = menu.addAction( 560 UI.PixmapCache.getIcon("vcsDiff"), 561 self.tr('Show differences (extended)'), 562 self.__HgExtendedDiff) 563 self.vcsDirMenuActions.append(act) 564 menu.addSeparator() 565 act = menu.addAction( 566 UI.PixmapCache.getIcon("vcsRevert"), 567 self.tr('Revert changes'), self.__HgRevert) 568 self.vcsDirMenuActions.append(act) 569 act = menu.addAction( 570 self.tr('Conflicts resolved'), self.__HgResolved) 571 self.vcsDirMenuActions.append(act) 572 act = menu.addAction( 573 self.tr('Conflicts unresolved'), self.__HgUnresolved) 574 self.vcsDirMenuActions.append(act) 575 act = menu.addAction( 576 self.tr('Re-Merge'), self.__HgReMerge) 577 self.vcsDirMenuActions.append(act) 578 menu.addSeparator() 579 menu.addAction(self.tr('Select all local file entries'), 580 self.browser.selectLocalEntries) 581 menu.addAction(self.tr('Select all versioned file entries'), 582 self.browser.selectVCSEntries) 583 menu.addAction(self.tr('Select all local directory entries'), 584 self.browser.selectLocalDirEntries) 585 menu.addAction(self.tr('Select all versioned directory entries'), 586 self.browser.selectVCSDirEntries) 587 menu.addSeparator() 588 menu.addAction(self.tr("Configure..."), self.__HgConfigure) 589 590 mainMenu.addSeparator() 591 mainMenu.addMenu(menu) 592 self.menuDir = menu 593 594 def _addVCSMenuDirMulti(self, mainMenu): 595 """ 596 Protected method used to add the VCS menu to all project browsers. 597 598 @param mainMenu reference to the menu to be amended 599 """ 600 if mainMenu is None: 601 return 602 603 self.vcsDirMultiMenuActions = [] 604 self.vcsAddDirMultiMenuActions = [] 605 606 menu = QMenu(self.tr("Version Control")) 607 608 act = menu.addAction( 609 UI.PixmapCache.getIcon( 610 os.path.join("VcsPlugins", "vcsMercurial", "icons", 611 "mercurial.svg")), 612 self.vcs.vcsName(), self._VCSInfoDisplay) 613 font = act.font() 614 font.setBold(True) 615 act.setFont(font) 616 menu.addSeparator() 617 618 act = menu.addAction( 619 UI.PixmapCache.getIcon("vcsCommit"), 620 self.tr('Commit changes to repository...'), 621 self._VCSCommit) 622 self.vcsDirMultiMenuActions.append(act) 623 self.__addExtensionsMenu(menu, 'dirMultiMenu') 624 menu.addSeparator() 625 act = menu.addAction( 626 UI.PixmapCache.getIcon("vcsAdd"), 627 self.tr('Add to repository'), self._VCSAdd) 628 self.vcsAddDirMultiMenuActions.append(act) 629 act = menu.addAction( 630 UI.PixmapCache.getIcon("vcsRemove"), 631 self.tr('Remove from repository (and disk)'), 632 self._VCSRemove) 633 self.vcsDirMultiMenuActions.append(act) 634 menu.addSeparator() 635 act = menu.addAction( 636 UI.PixmapCache.getIcon("vcsStatus"), 637 self.tr('Show status'), self._VCSStatus) 638 self.vcsDirMultiMenuActions.append(act) 639 menu.addSeparator() 640 act = menu.addAction( 641 UI.PixmapCache.getIcon("vcsDiff"), 642 self.tr('Show differences'), self._VCSDiff) 643 self.vcsDirMultiMenuActions.append(act) 644 act = menu.addAction( 645 UI.PixmapCache.getIcon("vcsDiff"), 646 self.tr('Show differences (extended)'), 647 self.__HgExtendedDiff) 648 self.vcsDirMultiMenuActions.append(act) 649 menu.addSeparator() 650 act = menu.addAction( 651 UI.PixmapCache.getIcon("vcsRevert"), 652 self.tr('Revert changes'), self.__HgRevert) 653 self.vcsDirMultiMenuActions.append(act) 654 act = menu.addAction( 655 self.tr('Conflicts resolved'), self.__HgResolved) 656 self.vcsDirMultiMenuActions.append(act) 657 act = menu.addAction( 658 self.tr('Conflicts unresolved'), self.__HgUnresolved) 659 self.vcsDirMultiMenuActions.append(act) 660 act = menu.addAction( 661 self.tr('Re-Merge'), self.__HgReMerge) 662 self.vcsDirMultiMenuActions.append(act) 663 menu.addSeparator() 664 menu.addAction(self.tr('Select all local file entries'), 665 self.browser.selectLocalEntries) 666 menu.addAction(self.tr('Select all versioned file entries'), 667 self.browser.selectVCSEntries) 668 menu.addAction(self.tr('Select all local directory entries'), 669 self.browser.selectLocalDirEntries) 670 menu.addAction(self.tr('Select all versioned directory entries'), 671 self.browser.selectVCSDirEntries) 672 menu.addSeparator() 673 menu.addAction(self.tr("Configure..."), self.__HgConfigure) 674 675 mainMenu.addSeparator() 676 mainMenu.addMenu(menu) 677 self.menuDirMulti = menu 678 679 ########################################################################### 680 ## Menu handling methods below 681 ########################################################################### 682 683 def __HgRevert(self): 684 """ 685 Private slot called by the context menu to revert changes made. 686 """ 687 names = [] 688 for itm in self.browser.getSelectedItems(): 689 try: 690 name = itm.fileName() 691 except AttributeError: 692 name = itm.dirName() 693 names.append(name) 694 self.vcs.hgRevert(names) 695 696 def __HgCopy(self): 697 """ 698 Private slot called by the context menu to copy the selected file. 699 """ 700 itm = self.browser.currentItem() 701 try: 702 fn = itm.fileName() 703 except AttributeError: 704 fn = itm.dirName() 705 self.vcs.hgCopy(fn, self.project) 706 707 def __HgMove(self): 708 """ 709 Private slot called by the context menu to move the selected file. 710 """ 711 itm = self.browser.currentItem() 712 try: 713 fn = itm.fileName() 714 except AttributeError: 715 fn = itm.dirName() 716 isFile = os.path.isfile(fn) 717 movefiles = self.browser.project.getFiles(fn) 718 self.browser.project.stopFileSystemMonitoring() 719 if self.vcs.vcsMove(fn, self.project): 720 if isFile: 721 self.browser.closeSourceWindow.emit(fn) 722 else: 723 for mf in movefiles: 724 self.browser.closeSourceWindow.emit(mf) 725 self.browser.project.startFileSystemMonitoring() 726 727 def __HgExtendedDiff(self): 728 """ 729 Private slot called by the context menu to show the difference of a 730 file to the repository. 731 732 This gives the chance to enter the revisions to compare. 733 """ 734 names = [] 735 for itm in self.browser.getSelectedItems(): 736 try: 737 names.append(itm.fileName()) 738 except AttributeError: 739 names.append(itm.dirName()) 740 self.vcs.hgExtendedDiff(names) 741 742 def __HgSbsDiff(self): 743 """ 744 Private slot called by the context menu to show the difference of a 745 file to the repository side-by-side. 746 """ 747 itm = self.browser.currentItem() 748 fn = itm.fileName() 749 self.vcs.hgSbsDiff(fn) 750 751 def __HgSbsExtendedDiff(self): 752 """ 753 Private slot called by the context menu to show the difference of a 754 file to the repository side-by-side. 755 756 It allows the selection of revisions to compare. 757 """ 758 itm = self.browser.currentItem() 759 fn = itm.fileName() 760 self.vcs.hgSbsDiff(fn, extended=True) 761 762 def __HgAnnotate(self): 763 """ 764 Private slot called by the context menu to show the annotations of a 765 file. 766 """ 767 itm = self.browser.currentItem() 768 fn = itm.fileName() 769 self.vcs.hgAnnotate(fn) 770 771 def __HgResolved(self): 772 """ 773 Private slot called by the context menu to mark conflicts of a file 774 as being resolved. 775 """ 776 names = [] 777 for itm in self.browser.getSelectedItems(): 778 try: 779 names.append(itm.fileName()) 780 except AttributeError: 781 names.append(itm.dirName()) 782 self.vcs.hgResolved(names) 783 784 def __HgUnresolved(self): 785 """ 786 Private slot called by the context menu to mark conflicts of a file 787 as being unresolved. 788 """ 789 names = [] 790 for itm in self.browser.getSelectedItems(): 791 try: 792 names.append(itm.fileName()) 793 except AttributeError: 794 names.append(itm.dirName()) 795 self.vcs.hgResolved(names, unresolve=True) 796 797 def __HgReMerge(self): 798 """ 799 Private slot called by the context menu to re-merge a file. 800 """ 801 names = [] 802 for itm in self.browser.getSelectedItems(): 803 try: 804 names.append(itm.fileName()) 805 except AttributeError: 806 names.append(itm.dirName()) 807 self.vcs.hgReMerge(names) 808 809 def __HgForget(self): 810 """ 811 Private slot called by the context menu to remove the selected file 812 from the Mercurial repository leaving a copy in the project directory. 813 """ 814 from UI.DeleteFilesConfirmationDialog import ( 815 DeleteFilesConfirmationDialog 816 ) 817 if self.isTranslationsBrowser: 818 items = self.browser.getSelectedItems([ProjectBrowserFileItem]) 819 names = [itm.fileName() for itm in items] 820 821 dlg = DeleteFilesConfirmationDialog( 822 self.parent(), 823 self.tr("Remove from repository only"), 824 self.tr( 825 "Do you really want to remove these files" 826 " from the repository?"), 827 names) 828 else: 829 items = self.browser.getSelectedItems() 830 names = [itm.fileName() for itm in items] 831 files = [self.browser.project.getRelativePath(name) 832 for name in names] 833 834 dlg = DeleteFilesConfirmationDialog( 835 self.parent(), 836 self.tr("Remove from repository only"), 837 self.tr( 838 "Do you really want to remove these files" 839 " from the repository?"), 840 files) 841 842 if dlg.exec() == QDialog.DialogCode.Accepted: 843 self.vcs.hgForget(names) 844 845 for fn in names: 846 self._updateVCSStatus(fn) 847 848 def __HgConfigure(self): 849 """ 850 Private method to open the configuration dialog. 851 """ 852 e5App().getObject("UserInterface").showPreferences("zzz_mercurialPage") 853