Correct if caluses
[bertos.git] / wizard / BToolchainPage.py
1 #!/usr/bin/env python
2 # encoding: utf-8
3 #
4 # Copyright 2008 Develer S.r.l. (http://www.develer.com/)
5 # All rights reserved.
6 #
7 # $Id$
8 #
9 # Author: Lorenzo Berni <duplo@develer.com>
10 #
11
12 import os
13 import collections
14
15 from BWizardPage import *
16 import BToolchainSearch
17 import bertos_utils
18 import qvariant_converter
19
20 from const import *
21
22 class BToolchainPage(BWizardPage):
23     """
24     Page of the wizard that permits to choose the toolchain to use for the
25     project.
26     """
27
28     def __init__(self):
29         BWizardPage.__init__(self, UI_LOCATION + "/toolchain_select.ui")
30         self.setTitle(self.tr("Select toolchain"))
31         self._validation_process = None
32
33     ## Overloaded QWizardPage methods. ##
34
35     def isComplete(self):
36         """
37         Overload of the QWizard isComplete method.
38         """
39         if self.pageContent.toolchainList.currentRow() != -1:
40             self.setProjectInfo("TOOLCHAIN",
41                 qvariant_converter.getStringDict(self.pageContent.toolchainList.currentItem().data(Qt.UserRole)))
42             return True
43         else:
44             return False
45
46     ####
47
48     ## Overloaded BWizardPage methods. ##
49
50     def setupUi(self):
51         """
52         Sets up the user interface.
53         """
54         self.pageContent.infoLabel.setVisible(False)
55
56     def connectSignals(self):
57         """
58         Connects the signals with the related slots.
59         """
60         self.connect(self.pageContent.toolchainList, SIGNAL("itemSelectionChanged()"), self.selectionChanged)
61         self.connect(self.pageContent.addButton, SIGNAL("clicked()"), self.addToolchain)
62         self.connect(self.pageContent.removeButton, SIGNAL("clicked()"), self.removeToolchain)
63         self.connect(self.pageContent.searchButton, SIGNAL("clicked()"), self.searchToolchain)
64         self.connect(self.pageContent.checkButton, SIGNAL("clicked()"), self.validateAllToolchains)
65
66     def reloadData(self):
67         """
68         Overload of the BWizard reloadData method.
69         """
70         self._clearList()
71         self.setupUi()
72         self._populateToolchainList()
73
74     ####
75
76     ## Slots ##
77
78     def selectionChanged(self):
79         """
80         Slot called when the user click on an entry of the toolchain list.
81         """
82         if self.pageContent.toolchainList.currentRow() != -1:
83             infos = collections.defaultdict(lambda: unicode("not defined"))
84             infos.update(qvariant_converter.getStringDict(self.pageContent.toolchainList.currentItem().data(Qt.UserRole)))
85             self.pageContent.infoLabel.setText("GCC " + infos["version"] + " (" + infos["build"] + ")\nTarget: " + infos["target"] + "\nPath: " + os.path.normpath(infos["path"]))
86             self.pageContent.infoLabel.setVisible(True)
87             self.emit(SIGNAL("completeChanged()"))
88
89     def addToolchain(self):
90         """
91         Slot called when the user adds manually a toolchain.
92         """
93         sel_toolchain = unicode(QFileDialog.getOpenFileName(self, self.tr("Choose the toolchain"), ""))
94         if sel_toolchain != "":
95             item = QListWidgetItem(sel_toolchain)
96             item.setData(Qt.UserRole, qvariant_converter.convertStringDict({"path": sel_toolchain}))
97             self.pageContent.toolchainList.addItem(item)
98             toolchains = self.toolchains()
99             toolchains[sel_toolchain] = False
100             self.setToolchains(toolchains)
101
102     def removeToolchain(self):
103         """
104         Slot called when the user removes manually a toolchain.
105         """
106         if self.pageContent.toolchainList.currentRow() != -1:
107             item = self.pageContent.toolchainList.takeItem(self.pageContent.toolchainList.currentRow())
108             toolchain = qvariant_converter.getStringDict(item.data(Qt.UserRole))["path"]
109             toolchains = self.toolchains()
110             del toolchains[toolchain]
111             self.setToolchains(toolchains)
112
113     def searchToolchain(self):
114         """
115         Slot called when the user clicks on the 'search' button. It opens the
116         toolchain search dialog.
117         """
118         search = BToolchainSearch.BToolchainSearch()
119         self.connect(search, SIGNAL("accepted()"), self._search)
120         search.exec_()
121
122     def validateAllToolchains(self):
123         """
124         Slot called when the user clicks on the validate button. It starts the
125         toolchain validation procedure for all the toolchains.
126         """
127         QApplication.instance().setOverrideCursor(Qt.WaitCursor)
128         for i in range(self.pageContent.toolchainList.count()):
129             self.validateToolchain(i)
130         QApplication.instance().restoreOverrideCursor()
131
132     ####
133
134     def _populateToolchainList(self):
135         """
136         Fills the toolchain list with the toolchains stored in the QSettings.
137         """
138         toolchains = self.toolchains()
139         sel_toolchain = self.projectInfo("TOOLCHAIN")
140         for key, value in toolchains.items():
141             item = QListWidgetItem(key)
142             item.setData(Qt.UserRole, qvariant_converter.convertStringDict({"path": key}))
143             self.pageContent.toolchainList.addItem(item)
144             if sel_toolchain and sel_toolchain["path"] == key:
145                 self.pageContent.toolchainList.setCurrentItem(item)
146             if value:
147                 self.validateToolchain(self.pageContent.toolchainList.row(item))
148
149     def _clearList(self):
150         """
151         Removes all the toolchain from the list.
152         """
153         self.pageContent.toolchainList.clear()
154
155     def _search(self):
156         """
157         Searches for toolchains in the stored directories, and stores them in the
158         QSettings.
159         """
160         dir_list = self.searchDirList()
161         if self.pathSearch():
162             dir_list += [element for element in bertos_utils.getSystemPath()]
163         toolchain_list = bertos_utils.findToolchains(dir_list)
164         stored_toolchains = self.toolchains()
165         for element in toolchain_list:
166             if not element in stored_toolchains:
167                 item = QListWidgetItem(element)
168                 item.setData(Qt.UserRole, qvariant_converter.convertStringDict({"path": element}))
169                 self.pageContent.toolchainList.addItem(item)
170                 stored_toolchains[element] = False
171         self.setToolchains(stored_toolchains)
172         self.showMessage(self.tr("Toolchain search result."), self.tr("%1 toolchains founded").arg(len(stored_toolchains)))
173
174     def _validItem(self, index, infos):
175         """
176         Sets the item at index as a valid item and associates the given info to it.
177         """
178         item = self.pageContent.toolchainList.item(index)
179         new_data = qvariant_converter.getStringDict(self.pageContent.toolchainList.item(index).data(Qt.UserRole))
180         new_data.update(infos)
181         item.setData(Qt.UserRole, qvariant_converter.convertStringDict(new_data))
182         needed = self.projectInfo("CPU_INFOS")
183         if "target" in infos and infos["target"].find(needed["TOOLCHAIN"]) != -1:
184             item.setIcon(QIcon(":/images/ok.png"))
185         else:
186             item.setIcon(QIcon(":/images/warning.png"))
187         if "version" in infos and "target" in infos:
188             item.setText("GCC " + infos["version"] + " - " + infos["target"].strip())
189
190     def _invalidItem(self, index):
191         """
192         Sets the item at index as an invalid item.
193         """
194         item = self.pageContent.toolchainList.item(index)
195         item.setIcon(QIcon(":/images/error.png"))
196
197     def validateToolchain(self, i):
198         """
199         Toolchain validation procedure.
200         """
201         filename = qvariant_converter.getStringDict(self.pageContent.toolchainList.item(i).data(Qt.UserRole))["path"]
202         valid = False
203         info = {}
204         # Check for the other tools of the toolchain
205         for tool in TOOLCHAIN_ITEMS:
206             if os.path.exists(filename.replace("gcc", tool)):
207                 valid = True
208             else:
209                 valid = False
210                 break
211         # Try to retrieve the informations about the toolchain only for the valid toolchains
212         if valid:
213             self._validation_process = QProcess()
214             self._validation_process.start(filename, ["-v"])
215             self._validation_process.waitForStarted(1000)
216             if self._validation_process.waitForFinished(200):
217                 description = str(self._validation_process.readAllStandardError())
218                 info = bertos_utils.getToolchainInfo(description)
219                 if len(info) >= 4:
220                     valid = True
221             else:
222                 self._validation_process.kill()
223         # Add the item in the list with the appropriate associate data.
224         if valid:
225             self._validItem(i, info)
226         else:
227             self._invalidItem(i)
228         toolchains = self.toolchains()
229         toolchains[filename] = True
230         self.setToolchains(toolchains)