Reformat and fix paste.
[bertos.git] / wizard / BModulePage.py
index 00d9d4bdcb2d46a3f9d0785b1dec2b39409c266a..8d382be26ab953624106fb9b331b6aafe87d0790 100644 (file)
@@ -1,8 +1,32 @@
 #!/usr/bin/env python
 # encoding: utf-8
 #
 #!/usr/bin/env python
 # encoding: utf-8
 #
-# Copyright 2009 Develer S.r.l. (http://www.develer.com/)
-# All rights reserved.
+# This file is part of BeRTOS.
+#
+# Bertos is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# As a special exception, you may use this file as part of a free software
+# library without restriction.  Specifically, if other files instantiate
+# templates or use macros or inline functions from this file, or you compile
+# this file and link it with other files to produce an executable, this
+# file does not by itself cause the resulting executable to be covered by
+# the GNU General Public License.  This exception does not however
+# invalidate any other reasons why the executable file might be covered by
+# the GNU General Public License.
+#
+# Copyright 2008 Develer S.r.l. (http://www.develer.com/)
 #
 # $Id$
 #
 #
 # $Id$
 #
@@ -53,6 +77,7 @@ class BModulePage(BWizardPage):
         Overload of the BWizardPage connectSignals method.
         """
         self.connect(self.pageContent.moduleTree, SIGNAL("itemPressed(QTreeWidgetItem*, int)"), self.fillPropertyTable)
         Overload of the BWizardPage connectSignals method.
         """
         self.connect(self.pageContent.moduleTree, SIGNAL("itemPressed(QTreeWidgetItem*, int)"), self.fillPropertyTable)
+        self.connect(self.pageContent.moduleTree, SIGNAL("itemPressed(QTreeWidgetItem*, int)"), self.moduleClicked)
         self.connect(self.pageContent.moduleTree, SIGNAL("itemChanged(QTreeWidgetItem*, int)"), self.dependencyCheck)
         self.connect(self.pageContent.propertyTable, SIGNAL("itemSelectionChanged()"), self.showPropertyDescription)
 
         self.connect(self.pageContent.moduleTree, SIGNAL("itemChanged(QTreeWidgetItem*, int)"), self.dependencyCheck)
         self.connect(self.pageContent.propertyTable, SIGNAL("itemSelectionChanged()"), self.showPropertyDescription)
 
@@ -70,6 +95,9 @@ class BModulePage(BWizardPage):
     
     ## Slots ##
 
     
     ## Slots ##
 
+    def moduleClicked(self, item, column):
+        self.setBold(item, False)
+
     def fillPropertyTable(self):
         """
         Slot called when the user selects a module from the module tree.
     def fillPropertyTable(self):
         """
         Slot called when the user selects a module from the module tree.
@@ -131,7 +159,12 @@ class BModulePage(BWizardPage):
             if self.pageContent.propertyTable.rowCount() == 0:
                 module_label = self.pageContent.moduleLabel.text()
                 module_label += "\n\nNo configuration needed."
             if self.pageContent.propertyTable.rowCount() == 0:
                 module_label = self.pageContent.moduleLabel.text()
                 module_label += "\n\nNo configuration needed."
-                self.pageContent.moduleLabel.setText(module_label)
+                self.pageContent.moduleLabel.setText(module_label) 
+        else:
+            self.pageContent.moduleLabel.setText("")
+            self.pageContent.moduleLabel.setVisible(False)
+            self.pageContent.propertyTable.clear()
+            self.pageContent.propertyTable.setRowCount(0)
 
     def dependencyCheck(self, item):
         """
 
     def dependencyCheck(self, item):
         """
@@ -165,7 +198,7 @@ class BModulePage(BWizardPage):
         configuration = self.projectInfo("MODULES")[self.currentModule()]["configuration"]
         configurations = self.projectInfo("CONFIGURATIONS")
         if "type" not in configurations[configuration][property]["informations"] or configurations[configuration][property]["informations"]["type"] == "int":
         configuration = self.projectInfo("MODULES")[self.currentModule()]["configuration"]
         configurations = self.projectInfo("CONFIGURATIONS")
         if "type" not in configurations[configuration][property]["informations"] or configurations[configuration][property]["informations"]["type"] == "int":
-            configurations[configuration][property]["value"] = str(int(self.pageContent.propertyTable.cellWidget(index, 1).value()))
+            configurations[configuration][property]["value"] = unicode(int(self.pageContent.propertyTable.cellWidget(index, 1).value()))
         elif configurations[configuration][property]["informations"]["type"] == "enum":
             configurations[configuration][property]["value"] = unicode(self.pageContent.propertyTable.cellWidget(index, 1).currentText())
         elif configurations[configuration][property]["informations"]["type"] == "boolean":
         elif configurations[configuration][property]["informations"]["type"] == "enum":
             configurations[configuration][property]["value"] = unicode(self.pageContent.propertyTable.cellWidget(index, 1).currentText())
         elif configurations[configuration][property]["informations"]["type"] == "boolean":
@@ -174,6 +207,8 @@ class BModulePage(BWizardPage):
             else:
                 configurations[configuration][property]["value"] = "0"
         self.setProjectInfo("CONFIGURATIONS", configurations)
             else:
                 configurations[configuration][property]["value"] = "0"
         self.setProjectInfo("CONFIGURATIONS", configurations)
+        if self.moduleItem(self.currentModule()).checkState(0) == Qt.Checked:
+            self.dependencyCheck(self.moduleItem(self.currentModule()))
 
     ####
     
 
     ####
     
@@ -198,6 +233,7 @@ class BModulePage(BWizardPage):
         """
         Fills the module tree with the module entries separated in categories.
         """
         """
         Fills the module tree with the module entries separated in categories.
         """
+        self.pageContent.moduleTree.clear()
         modules = self.projectInfo("MODULES")
         if not modules:
             return
         modules = self.projectInfo("MODULES")
         if not modules:
             return
@@ -224,6 +260,7 @@ class BModulePage(BWizardPage):
                     module_item.setCheckState(0, Qt.Unchecked)
             self.pageContent.moduleTree.addTopLevelItem(item)
         self.pageContent.moduleTree.sortItems(0, Qt.AscendingOrder)
                     module_item.setCheckState(0, Qt.Unchecked)
             self.pageContent.moduleTree.addTopLevelItem(item)
         self.pageContent.moduleTree.sortItems(0, Qt.AscendingOrder)
+        self.fillPropertyTable()
             
     def insertCheckBox(self, index, value):
         """
             
     def insertCheckBox(self, index, value):
         """
@@ -304,6 +341,15 @@ class BModulePage(BWizardPage):
             return unicode(current_module.text(0))
         else:
             return None
             return unicode(current_module.text(0))
         else:
             return None
+
+    def moduleItem(self, module):
+        for top_level_index in range(self.pageContent.moduleTree.topLevelItemCount()):
+            top_level_item = self.pageContent.moduleTree.topLevelItem(top_level_index)
+            for child_index in range(top_level_item.childCount()):
+                child_item = top_level_item.child(child_index)
+                if unicode(child_item.text(0)) == module:
+                    return child_item
+        return None
     
     def currentModuleConfigurations(self):
         """
     
     def currentModuleConfigurations(self):
         """
@@ -344,6 +390,13 @@ class BModulePage(BWizardPage):
                 break
             self.pageContent.propertyTable.item(index, 0).setText(self.currentModuleConfigurations()[property_name]['brief'])
     
                 break
             self.pageContent.propertyTable.item(index, 0).setText(self.currentModuleConfigurations()[property_name]['brief'])
     
+    def setBold(self, item, bold):
+        self.pageContent.moduleTree.blockSignals(True)
+        font = item.font(0)
+        font.setBold(bold)
+        item.setFont(0, font)
+        self.pageContent.moduleTree.blockSignals(False)
+
     def moduleSelected(self, selectedModule):
         """
         Resolves the selection dependencies.
     def moduleSelected(self, selectedModule):
         """
         Resolves the selection dependencies.
@@ -363,6 +416,8 @@ class BModulePage(BWizardPage):
                 item = self.pageContent.moduleTree.topLevelItem(category)
                 for child in range(item.childCount()):
                     if unicode(item.child(child).text(0)) in unsatisfied:
                 item = self.pageContent.moduleTree.topLevelItem(category)
                 for child in range(item.childCount()):
                     if unicode(item.child(child).text(0)) in unsatisfied:
+                        self.setBold(item.child(child), True)
+                        self.setBold(item, True)
                         item.child(child).setCheckState(0, Qt.Checked)
     
     def moduleUnselected(self, unselectedModule):
                         item.child(child).setCheckState(0, Qt.Checked)
     
     def moduleUnselected(self, unselectedModule):
@@ -373,12 +428,24 @@ class BModulePage(BWizardPage):
         modules[unselectedModule]["enabled"] = False
         self.setProjectInfo("MODULES", modules)
         unsatisfied = []
         modules[unselectedModule]["enabled"] = False
         self.setProjectInfo("MODULES", modules)
         unsatisfied = []
+        unsatisfied_params = []
         if self.pageContent.automaticFix.isChecked():
         if self.pageContent.automaticFix.isChecked():
-            unsatisfied = self.unselectDependencyCheck(unselectedModule)
-        if len(unsatisfied) > 0:
-            message = self.tr("The module %1 is needed by the following modules:\n%2.\n\nDo you want to remove these modules too?")
-            message = message.arg(unselectedModule).arg(", ".join(unsatisfied))
-            choice = QMessageBox.warning(self, self.tr("Dependency error"), message, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
+            unsatisfied, unsatisfied_params = self.unselectDependencyCheck(unselectedModule)
+        if len(unsatisfied) > 0 or len(unsatisfied_params) > 0:
+            message = []
+            heading = self.tr("The module %1 is needed by").arg(unselectedModule)
+            message.append(heading)
+            module_list = ", ".join(unsatisfied)
+            param_list = ", ".join(["%s (%s)" %(param_name, module) for module, param_name in unsatisfied_params])
+            if module_list:
+                message.append(QString(module_list))
+            if module_list and param_list:
+                message.append(self.tr("and by"))
+            if param_list:
+                message.append(QString(param_list))
+            message_str = QStringList(message).join(" ")
+            message_str.append(self.tr("\n\nDo you want to automatically fix these conflicts?"))
+            choice = QMessageBox.warning(self, self.tr("Dependency error"), message_str, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
             if choice == QMessageBox.Yes:
                 for module in unsatisfied:
                     modules = self.projectInfo("MODULES")
             if choice == QMessageBox.Yes:
                 for module in unsatisfied:
                     modules = self.projectInfo("MODULES")
@@ -388,6 +455,11 @@ class BModulePage(BWizardPage):
                     for child in range(item.childCount()):
                         if unicode(item.child(child).text(0)) in unsatisfied:
                             item.child(child).setCheckState(0, Qt.Unchecked)
                     for child in range(item.childCount()):
                         if unicode(item.child(child).text(0)) in unsatisfied:
                             item.child(child).setCheckState(0, Qt.Unchecked)
+                for module, param in unsatisfied_params:
+                    configuration_file = self.projectInfo("MODULES")[module]["configuration"]
+                    configurations = self.projectInfo("CONFIGURATIONS")
+                    configurations[configuration_file][param]["value"] = "0"
+                    self.setProjectInfo("CONFIGURATIONS", configurations)
     
     def selectDependencyCheck(self, module):
         """
     
     def selectDependencyCheck(self, module):
         """
@@ -396,7 +468,13 @@ class BModulePage(BWizardPage):
         unsatisfied = set()
         modules = self.projectInfo("MODULES")
         files = self.projectInfo("FILES")
         unsatisfied = set()
         modules = self.projectInfo("MODULES")
         files = self.projectInfo("FILES")
-        for dependency in modules[module]["depends"]:
+        configurations = self.projectInfo("CONFIGURATIONS").get(modules[module]["configuration"], {"paramlist": ()})
+        conditional_deps = ()
+        for i, param_name in configurations["paramlist"]:
+            information = configurations[param_name]
+            if information["informations"]["type"] == "boolean" and information["value"] != "0" and "conditional_deps" in information["informations"]:
+                conditional_deps += information["informations"]["conditional_deps"]
+        for dependency in modules[module]["depends"] + conditional_deps:
             if dependency in modules and not modules[dependency]["enabled"]:
                 unsatisfied |= set([dependency])
                 if dependency not in unsatisfied:
             if dependency in modules and not modules[dependency]["enabled"]:
                 unsatisfied |= set([dependency])
                 if dependency not in unsatisfied:
@@ -414,13 +492,27 @@ class BModulePage(BWizardPage):
         Returns the list of unsatisfied dependencies after an unselection.
         """
         unsatisfied = set()
         Returns the list of unsatisfied dependencies after an unselection.
         """
         unsatisfied = set()
+        unsatisfied_params = set()
         modules = self.projectInfo("MODULES")
         for module, informations in modules.items():
         modules = self.projectInfo("MODULES")
         for module, informations in modules.items():
+            configurations = self.projectInfo("CONFIGURATIONS").get(informations["configuration"], {"paramlist": ()})
+            conditional_deps = {}
+            for i, param_name in configurations["paramlist"]:
+                information = configurations[param_name]
+                if information["informations"]["type"] == "boolean" and information["value"] != "0" and "conditional_deps" in information["informations"]:
+                    for dep in information["informations"]["conditional_deps"]:
+                        if not dep in conditional_deps:
+                            conditional_deps[dep] = []
+                        conditional_deps[dep].append((module, param_name))
             if dependency in informations["depends"] and informations["enabled"]:
                 unsatisfied |= set([module])
                 if dependency not in unsatisfied:
             if dependency in informations["depends"] and informations["enabled"]:
                 unsatisfied |= set([module])
                 if dependency not in unsatisfied:
-                    unsatisfied |= self.unselectDependencyCheck(module)
-        return unsatisfied
+                    tmp = self.unselectDependencyCheck(module)
+                    unsatisfied |= tmp[0]
+                    unsatisfied_params |= tmp[1]
+            if dependency in conditional_deps:
+                unsatisfied_params |= set(conditional_deps[dependency])
+        return unsatisfied, unsatisfied_params
     
     def removeFileDependencies(self, module):
         """
     
     def removeFileDependencies(self, module):
         """
@@ -472,4 +564,4 @@ class QControlGroup(QObject):
         Slot called when the value of one of the stored widget changes. It emits
         another signal.
         """
         Slot called when the value of one of the stored widget changes. It emits
         another signal.
         """
-        self.emit(SIGNAL("stateChanged"), id)
\ No newline at end of file
+        self.emit(SIGNAL("stateChanged"), id)