4 # This file is part of BeRTOS.
6 # Bertos is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 # As a special exception, you may use this file as part of a free software
21 # library without restriction. Specifically, if other files instantiate
22 # templates or use macros or inline functions from this file, or you compile
23 # this file and link it with other files to produce an executable, this
24 # file does not by itself cause the resulting executable to be covered by
25 # the GNU General Public License. This exception does not however
26 # invalidate any other reasons why the executable file might be covered by
27 # the GNU General Public License.
29 # Copyright 2008 Develer S.r.l. (http://www.develer.com/)
32 # Author: Lorenzo Berni <duplo@develer.com>
38 from BWizardPage import *
39 from BCreationPage import BCreationPage
41 import BToolchainSearch
43 import qvariant_converter
45 from toolchain_manager import ToolchainManager
49 class BToolchainPage(BWizardPage):
51 Page of the wizard that permits to choose the toolchain to use for the
56 BWizardPage.__init__(self, UI_LOCATION + "/toolchain_select.ui")
57 self.setTitle(self.tr("Select toolchain"))
58 self.setSubTitle(self.tr("You can look for more toolchains in your system by pressing the \"Search\" button, or manually add them with the \"+\" button"))
59 self._valid_items = []
60 self._toolchain_manager = ToolchainManager()
62 ## Overloaded QWizardPage methods. ##
66 Overload of the QWizard isComplete method.
68 if self.pageContent.toolchainList.currentRow() != -1:
69 self.setProjectInfo("TOOLCHAIN",
70 qvariant_converter.getStringDict(self.pageContent.toolchainList.currentItem().data(Qt.UserRole)))
77 Overload of the QWizardPage nextId method.
79 # Route to Output page if it's a predefined easy project.
80 if self.projectInfo("PROJECT_FROM_PRESET") and self.projectInfo("BASE_MODE"):
81 return self.wizard().pageIndex(BCreationPage)
83 return QWizardPage.nextId(self)
87 ## Overloaded BWizardPage methods. ##
91 Sets up the user interface.
93 self.pageContent.infoLabel.setVisible(False)
95 def connectSignals(self):
97 Connects the signals with the related slots.
99 self.connect(self.pageContent.toolchainList, SIGNAL("currentItemChanged(QListWidgetItem *, QListWidgetItem*)"), self.selectionChanged)
100 self.connect(self.pageContent.addButton, SIGNAL("clicked()"), self.addToolchain)
101 self.connect(self.pageContent.removeButton, SIGNAL("clicked()"), self.removeToolchain)
102 self.connect(self.pageContent.searchButton, SIGNAL("clicked()"), self.searchToolchain)
103 self.connect(self.pageContent.checkButton, SIGNAL("clicked()"), self.validateAllToolchains)
105 def reloadData(self, previous_id=None):
107 Overload of the BWizard reloadData method.
109 if previous_id is None or previous_id < self.wizard().currentId():
112 self._populateToolchainList()
113 if len(self._valid_items) >= 1:
114 self.pageContent.toolchainList.setCurrentItem(self._valid_items[0])
120 def selectionChanged(self):
122 Slot called when the user click on an entry of the toolchain list.
124 if self.pageContent.toolchainList.currentRow() != -1:
125 infos = collections.defaultdict(lambda: unicode("not defined"))
126 infos.update(qvariant_converter.getStringDict(self.pageContent.toolchainList.currentItem().data(Qt.UserRole)))
127 self.pageContent.infoLabel.setText("GCC " + infos["version"] + " (" + infos["build"] + ")\nTarget: " + infos["target"] + "\nPath: " + os.path.normpath(infos["path"]))
128 self.pageContent.infoLabel.setVisible(True)
129 if self.isDefaultToolchain(infos):
130 self.disableRemoveButton()
132 self.enableRemoveButton()
133 self.emit(SIGNAL("completeChanged()"))
135 def addToolchain(self):
137 Slot called when the user adds manually a toolchain.
139 sel_toolchain = unicode(QFileDialog.getOpenFileName(self, self.tr("Choose the toolchain"), ""))
140 if sel_toolchain != "":
141 item = QListWidgetItem(sel_toolchain)
142 item.setData(Qt.UserRole, qvariant_converter.convertStringDict({"path": sel_toolchain}))
143 self.pageContent.toolchainList.addItem(item)
144 self._toolchain_manager.addToolchain(sel_toolchain)
146 def removeToolchain(self):
148 Slot called when the user removes manually a toolchain.
150 if self.pageContent.toolchainList.currentRow() != -1:
151 item = self.pageContent.toolchainList.takeItem(self.pageContent.toolchainList.currentRow())
152 toolchain = qvariant_converter.getStringDict(item.data(Qt.UserRole))["path"]
153 self._toolchain_manager.removeToolchain(toolchain)
155 def searchToolchain(self):
157 Slot called when the user clicks on the 'search' button. It opens the
158 toolchain search dialog.
160 search = BToolchainSearch.BToolchainSearch()
161 self.connect(search, SIGNAL("accepted()"), self._search)
164 def validateAllToolchains(self):
166 Slot called when the user clicks on the validate button. It starts the
167 toolchain validation procedure for all the toolchains.
170 QApplication.instance().setOverrideCursor(Qt.WaitCursor)
171 for i in range(self.pageContent.toolchainList.count()):
172 data = qvariant_converter.getStringDict(self.pageContent.toolchainList.item(i).data(Qt.UserRole))
173 self.validateToolchain(data["path"])
174 self._populateToolchainList()
176 QApplication.instance().restoreOverrideCursor()
180 def _populateToolchainList(self):
182 Fills the toolchain list with the toolchains stored in the QSettings.
184 self.pageContent.toolchainList.clear()
185 self._valid_items = []
186 toolchains = self._toolchain_manager.predefined_toolchains + self._toolchain_manager.toolchains
193 for key, value in toolchains:
194 if os.path.exists(key):
195 item_data = {"path":key}
197 item_data.update(value)
198 if value is not None:
199 k, data = self.validateToolchain(key)
200 item_data.update(data)
201 toolchain_dict[k].append(item_data)
203 toolchain_dict["unverified"].append(item_data)
204 self._processItems(toolchain_dict["valid"], self._validItem)
205 self._processItems(toolchain_dict["non-valid"], self._invalidItem)
206 self._processItems(toolchain_dict["unknown"], self._unknownItem)
207 self._processItems(toolchain_dict["unverified"])
209 def _processItems(self, item_list, procedure=lambda x: None):
210 sel_toolchain = self.projectInfo("TOOLCHAIN")
211 for item_data in item_list:
212 item = QListWidgetItem(item_data["path"])
213 item.setData(Qt.UserRole, qvariant_converter.convertStringDict(item_data))
214 self.pageContent.toolchainList.addItem(item)
216 if sel_toolchain and sel_toolchain["path"] == item_data["path"]:
217 self.pageContent.toolchainList.setCurrentItem(item)
219 def currentToolchain(self):
220 selected_toolchain = qvariant_converter.getStringDict(self.pageContent.toolchainList.currentItem().data(Qt.UserRole))
221 return selected_toolchain
223 def _clearList(self):
225 Removes all the toolchain from the list.
227 self.pageContent.toolchainList.clear()
231 Searches for toolchains in the stored directories, and stores them in the
234 dir_list = self.searchDirList()
235 if self.pathSearch():
236 dir_list += [element for element in bertos_utils.getSystemPath()]
237 _toolchain_dict = self._toolchain_manager.storedToolchainDict()
238 toolchain_list = bertos_utils.findToolchains(dir_list)
239 for toolchain in toolchain_list:
240 self._toolchain_manager.addToolchain(toolchain, _toolchain_dict.get(toolchain, False))
241 self._populateToolchainList()
242 self.showMessage(self.tr("Toolchain search result."), self.tr("%1 toolchains found").arg(len(toolchain_list)))
244 def _validItem(self, item):
246 Sets the item at index as a valid item and associates the given info to it.
248 data = qvariant_converter.getStringDict(item.data(Qt.UserRole))
249 item.setIcon(QIcon(":/images/ok.png"))
250 self._valid_items.append(item)
251 if "version" in data and "target" in data:
252 item.setText("GCC " + data["version"] + " - " + data["target"].strip())
254 def _invalidItem(self, item):
255 data = qvariant_converter.getStringDict(item.data(Qt.UserRole))
256 item.setIcon(QIcon(":/images/warning.png"))
257 if "version" in data and "target" in data:
258 item.setText("GCC " + data["version"] + " - " + data["target"].strip())
260 def _unknownItem(self, item):
262 Sets the item at index as an invalid item.
264 item.setIcon(QIcon(":/images/error.png"))
266 def validateToolchain(self, filename):
268 Toolchain validation procedure.
270 info = self._toolchain_manager.validateToolchain(filename)
272 needed = self.projectInfo("CPU_INFOS")
273 if "target" in info and info["target"].find(needed["TOOLCHAIN"]) != -1:
276 return 'non-valid', info
278 return 'unknown', {'path': filename}
280 def isDefaultToolchain(self, toolchain):
282 Returns True if the given toolchain is one of the default toolchains.
284 return toolchain["path"] in self._toolchain_manager._predefined_toolchain_set
286 def disableRemoveButton(self):
288 Disable the remove button.
290 self.pageContent.removeButton.setEnabled(False)
292 def enableRemoveButton(self):
294 Enable the remove button.
296 self.pageContent.removeButton.setEnabled(True)
298 def currentItem(self):
299 return self.pageContent.toolchainList.currentItem()