1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing a dialog to enter the URLs for the svn diff command.
8"""
9
10import re
11
12from PyQt5.QtCore import pyqtSlot
13from PyQt5.QtWidgets import QDialog
14
15from E5Gui.E5Application import e5App
16from E5Gui import E5MessageBox
17
18import pysvn
19
20from .Ui_SvnUrlSelectionDialog import Ui_SvnUrlSelectionDialog
21
22import Utilities
23
24
25class SvnUrlSelectionDialog(QDialog, Ui_SvnUrlSelectionDialog):
26    """
27    Class implementing a dialog to enter the URLs for the svn diff command.
28    """
29    def __init__(self, vcs, tagsList, branchesList, path, parent=None):
30        """
31        Constructor
32
33        @param vcs reference to the vcs object
34        @param tagsList list of tags (list of strings)
35        @param branchesList list of branches (list of strings)
36        @param path pathname to determine the repository URL from (string)
37        @param parent parent widget of the dialog (QWidget)
38        """
39        super().__init__(parent)
40        self.setupUi(self)
41
42        if not hasattr(pysvn.Client(), 'diff_summarize'):
43            self.summaryCheckBox.setEnabled(False)
44            self.summaryCheckBox.setChecked(False)
45
46        self.vcs = vcs
47        self.tagsList = tagsList
48        self.branchesList = branchesList
49
50        self.typeCombo1.addItems(["trunk/", "tags/", "branches/"])
51        self.typeCombo2.addItems(["trunk/", "tags/", "branches/"])
52
53        reposURL = self.vcs.svnGetReposName(path)
54        if reposURL is None:
55            E5MessageBox.critical(
56                self,
57                self.tr("Subversion Error"),
58                self.tr(
59                    """The URL of the project repository could not be"""
60                    """ retrieved from the working copy. The operation will"""
61                    """ be aborted"""))
62            self.reject()
63            return
64
65        if self.vcs.otherData["standardLayout"]:
66            # determine the base path of the project in the repository
67            rx_base = re.compile('(.+/)(trunk|tags|branches).*')
68            match = rx_base.fullmatch(reposURL)
69            if match is None:
70                E5MessageBox.critical(
71                    self,
72                    self.tr("Subversion Error"),
73                    self.tr(
74                        """The URL of the project repository has an"""
75                        """ invalid format. The operation will"""
76                        """ be aborted"""))
77                self.reject()
78                return
79
80            reposRoot = match.group(1)
81            self.repoRootLabel1.setText(reposRoot)
82            self.repoRootLabel2.setText(reposRoot)
83        else:
84            project = e5App().getObject('Project')
85            if (
86                Utilities.normcasepath(path) !=
87                Utilities.normcasepath(project.getProjectPath())
88            ):
89                path = project.getRelativePath(path)
90                reposURL = reposURL.replace(path, '')
91            self.repoRootLabel1.hide()
92            self.typeCombo1.hide()
93            self.labelCombo1.addItems([reposURL] + sorted(self.vcs.tagsList))
94            self.labelCombo1.setEnabled(True)
95            self.repoRootLabel2.hide()
96            self.typeCombo2.hide()
97            self.labelCombo2.addItems([reposURL] + sorted(self.vcs.tagsList))
98            self.labelCombo2.setEnabled(True)
99
100        msh = self.minimumSizeHint()
101        self.resize(max(self.width(), msh.width()), msh.height())
102
103    def __changeLabelCombo(self, labelCombo, type_):
104        """
105        Private method used to change the label combo depending on the
106        selected type.
107
108        @param labelCombo reference to the labelCombo object (QComboBox)
109        @param type_ type string (string)
110        """
111        if type_ == "trunk/":
112            labelCombo.clear()
113            labelCombo.setEditText("")
114            labelCombo.setEnabled(False)
115        elif type_ == "tags/":
116            labelCombo.clear()
117            labelCombo.clearEditText()
118            labelCombo.addItems(sorted(self.tagsList))
119            labelCombo.setEnabled(True)
120        elif type_ == "branches/":
121            labelCombo.clear()
122            labelCombo.clearEditText()
123            labelCombo.addItems(sorted(self.branchesList))
124            labelCombo.setEnabled(True)
125
126    @pyqtSlot(int)
127    def on_typeCombo1_currentIndexChanged(self, index):
128        """
129        Private slot called when the selected type was changed.
130
131        @param index index of the current item
132        @type int
133        """
134        type_ = self.typeCombo1.itemText(index)
135        self.__changeLabelCombo(self.labelCombo1, type_)
136
137    @pyqtSlot(int)
138    def on_typeCombo2_currentIndexChanged(self, index):
139        """
140        Private slot called when the selected type was changed.
141
142        @param index index of the current item
143        @type int
144        """
145        type_ = self.typeCombo2.itemText(index)
146        self.__changeLabelCombo(self.labelCombo2, type_)
147
148    def getURLs(self):
149        """
150        Public method to get the entered URLs.
151
152        @return tuple of list of two URL strings (list of strings) and
153            a flag indicating a diff summary (boolean)
154        """
155        if self.vcs.otherData["standardLayout"]:
156            url1 = (
157                self.repoRootLabel1.text() +
158                self.typeCombo1.currentText() +
159                self.labelCombo1.currentText()
160            )
161            url2 = (
162                self.repoRootLabel2.text() +
163                self.typeCombo2.currentText() +
164                self.labelCombo2.currentText()
165            )
166        else:
167            url1 = self.labelCombo1.currentText()
168            url2 = self.labelCombo2.currentText()
169
170        return [url1, url2], self.summaryCheckBox.isChecked()
171