def mouseReleaseEvent(self, event):
        pos = event.pos()
        if self.current_rectangle > -1 and self.add_connection_mode:
            for index, rec in enumerate(self.rectangles):
                if rec.contains(pos):
                    if self.current_rectangle != index and (
                            self.current_rectangle,
                            index) not in self.transformations:
                        dlg = AddTransformationDialog(
                            self.labels[self.current_rectangle],
                            self.labels[index])
                        value = dlg.exec_()
                        if value == QDialog.Accepted:
                            self.transformations[self.current_rectangle,
                                                 index] = dlg.transformation
                            self.transformations[
                                index, self.
                                current_rectangle] = dlg.transformation.inverse(
                                )

                            if is_connected(list(range(len(self.rectangles))),
                                            self.transformations.keys()):
                                self.btnAddConnect.setEnabled(False)
                                self.btnSave.setEnabled(True)
                        break
        self.add_connection_mode = False
        self.btnAddConnect.setChecked(False)

        self.current_rectangle = -1
        self.repaint()
        self.statusbar.clearMessage()
 def load(self):
     msg = QMessageBox.warning(
         None, 'Confirm load',
         'Do you want to load configuration file?\n(Your current workspace will be erased)',
         QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
     if msg == QMessageBox.Cancel:
         return
     filename, _ = QFileDialog.getOpenFileName(
         self,
         'Choose the file name',
         '',
         'All files (*)',
         options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog)
     if not filename:
         return
     try:
         with open(filename, 'r') as f:
             new_labels = f.readline().rstrip().split('|')
             coords = f.readline().rstrip().split('|')
             new_rectangles = []
             for coord in coords:
                 x, y = map(int, coord.split(','))
                 new_rectangles.append(
                     QRect(x, y, self.recWidth, self.recHeight))
             new_transformations = {}
             for line in f.readlines():
                 i, j, params = line.rstrip().split('|')
                 i, j = int(i), int(j)
                 angle, scalexy, scalez, dx, dy, dz = map(
                     float, params.split())
                 new_transformations[i, j] = Transformation(
                     angle, scalexy, scalez, dx, dy, dz)
                 new_transformations[j,
                                     i] = new_transformations[i,
                                                              j].inverse()
         if len(new_labels) < 2:
             raise ValueError
         if not is_connected(list(range(len(new_labels))),
                             new_transformations.keys()):
             raise ValueError
     except (ValueError, IndexError):
         QMessageBox.critical(self, 'Error',
                              'The configuration is not valid.',
                              QMessageBox.Ok)
         return
     self.btnAddConnect.setEnabled(False)
     self.btnSave.setEnabled(True)
     self.labels = new_labels
     self.rectangles = new_rectangles
     self.transformations = new_transformations
     self.repaint()
    def mouseDoubleClickEvent(self, event):
        current_index = -1
        pos = event.pos()
        for index, rec in enumerate(self.rectangles):
            if rec.contains(pos):
                current_index = index
                break
        if current_index > -1:
            dlg = EditSystemDialog(self.labels[current_index], len(self.labels) > 2)
            value = dlg.exec_()
            if value == QDialog.Accepted:
                self.labels[current_index] = dlg.labelBox.text()
            elif value == QDialog.Rejected and dlg.deleted:
                self.rectangles = [self.rectangles[i] for i in range(len(self.rectangles)) if i != current_index]
                self.labels = [self.labels[i] for i in range(len(self.labels)) if i != current_index]
                new_transformation = {}
                for i, j in self.transformations:
                    if i == current_index or j == current_index:
                        continue
                    new_i, new_j = i-1 if i > current_index else i, j-1 if j > current_index else j
                    new_transformation[new_i, new_j] = self.transformations[i, j]

                self.transformations = new_transformation
                if is_connected(list(range(len(self.rectangles))), self.transformations.keys()):
                    self.btnAddConnect.setEnabled(False)
                    self.btnSave.setEnabled(True)
                else:
                    self.btnAddConnect.setEnabled(True)
                    self.btnSave.setEnabled(False)

            self.repaint()
        else:
            for i, j in self.transformations:
                if i > j:
                    continue
                p1, p2 = self.rectangles[i].center(), self.rectangles[j].center()
                x_center, y_center = (p1.x()+p2.x())/2, (p1.y()+p2.y())/2
                if max(abs(x_center-event.x()), abs(y_center-event.y())) < self.circleRadius:
                    dlg = EditTransformationDialog(self.labels[i], self.labels[j],
                                                   self.transformations[i, j], self.transformations[j, i])
                    value = dlg.exec_()
                    if value == QDialog.Accepted:
                        self.transformations[i, j] = dlg.trans
                        self.transformations[j, i] = dlg.inverse_trans
                    elif value == QDialog.Rejected and dlg.deleted:
                        del self.transformations[i, j]
                        del self.transformations[j, i]

                        self.btnAddConnect.setEnabled(True)
                        self.btnSave.setEnabled(False)
                    break