class ExportWindow(BaseWidget):
    def __init__(self, parent=None):
        BaseWidget.__init__(self, 'Export data', parent_win=parent)

        self.set_margin(5)
        self.setMinimumHeight(600)
        self.setMinimumWidth(800)

        self._tree = ControlTree('Data')
        self._apply = ControlButton('Apply', checkable=True)
        self._progress = ControlProgress('Progress')
        self._add = ControlButton('Add')
        self._remove = ControlButton('Remove')
        self._export_list = ControlList('Columns to export')

        self._outdir = ControlDir('Output directory')
        self._outfile = ControlText('Output file name')

        self._toggleevts = ControlCheckBox('Split files by events')
        self._splitevents = ControlCheckBoxList('Events')
        self._evtsreload = ControlButton('Reload events')

        self._formset = [[['_add', '_tree'], '||',
                          ['_remove', '_export_list']], '_toggleevts',
                         '_evtsreload', '_splitevents', '_outdir', '_outfile',
                         '_apply', '_progress']

        self._add.value = self.__add_column_event
        self._remove.value = self.__remove_column_event
        self._apply.value = self.__apply_btn_event
        self._evtsreload.value = self.__reload_events
        self._outdir.changed_event = self.__update_outfile_name_event
        self._outfile.changed_event = self.__update_outfile_name_event
        self._toggleevts.changed_event = self.__toggleevents_visibility
        self._splitevents.changed_event = self.__update_outfile_name_event
        self._splitevents.selection_changed_event = self.__update_outfile_name_event

        self._tree.show_header = False
        self._apply.icon = conf.ANNOTATOR_ICON_MOTION
        self._evtsreload.icon = conf.ANNOTATOR_ICON_REFRESH
        self._add.icon = conf.ANNOTATOR_ICON_ADD
        self._remove.icon = conf.ANNOTATOR_ICON_REMOVE

        self._progress.hide()
        self._splitevents.hide()
        self._evtsreload.hide()
        self._apply.enabled = False

        self._properties = []

    ###########################################################################
    ### EVENTS ################################################################
    ###########################################################################

    def __toggleevents_visibility(self):
        if self._toggleevts.value:
            self._splitevents.show()
            self._evtsreload.show()
        else:
            self._splitevents.hide()
            self._evtsreload.hide()

    def __field_full_name(self, tree_item):
        name = tree_item.text(0)
        while True:
            tree_item = tree_item.parent()
            if tree_item is None: break
            name = "{0} > {1}".format(tree_item.text(0), name)
        return name

    def __add_column_event(self):
        self.__update_outfile_name_event()
        item = self._tree.selected_item

        if item is None:
            return

        if hasattr(item, 'data_function'):
            self._export_list += [self.__field_full_name(item)]
            self._properties.append((len(item.win), item.data_function))
        elif isinstance(item.win, Value):
            self._export_list += [self.__field_full_name(item)]
            self._properties.append((len(item.win), item.win.get_value))

    def __remove_column_event(self):
        self.__update_outfile_name_event()
        if self._export_list.selected_row_index is None:
            return
        elif self._export_list.selected_row_index >= 0:
            self._properties.pop(self._export_list.selected_row_index)
            self._export_list -= -1

    def __update_outfile_name_event(self):
        """
		Update the output filename
		"""
        filename = self._outfile.value
        if len(filename.strip()) == 0: return

        outfilepath, outfile_extension = os.path.splitext(filename)
        names = [outfilepath] if len(outfilepath) > 0 else []

        if len(list(self._splitevents.value)) > 0:
            if '{event}' not in outfilepath: names.append('{event}')
            if '{start}' not in outfilepath: names.append('{start}')
            if '{end}' not in outfilepath: names.append('{end}')

        self._outfile.value = ('-'.join(names) + '.csv')
        self._apply.enabled = True

    def __apply_btn_event(self):

        if self._apply.checked:

            if len(self._properties) == 0:
                QMessageBox.about(
                    self, "Error",
                    "You need to select at least one value to export.")
                self._apply.checked = False
                return

            if self._outfile.value is None or len(
                    self._outfile.value.strip()) == 0:
                QMessageBox.about(
                    self, "Error",
                    "You need to select the name of the output file.")
                self._apply.checked = False
                return

            if self._outdir.value is None or len(self._outdir.value) == 0:
                QMessageBox.about(
                    self, "Error",
                    "You need to select the name of the output directory.")
                self._apply.checked = False
                return

            self.__update_outfile_name_event()

            self._export_list.enabled = False
            self._tree.enabled = False
            self._add.enabled = False
            self._remove.enabled = False
            self._outdir.enabled = False
            self._outfile.enabled = False
            self._apply.label = 'Cancel'

            ### calculate the video cuts #############################
            timeline = self.parent().timeline

            selected_events = self._splitevents.value
            videocuts = []
            if len(selected_events):
                # use the events to cut the video
                totalframes = 0
                for row in timeline.rows:
                    for event in row.events:
                        if event.title not in selected_events: continue
                        b = event.begin
                        e = event.end
                        totalframes += e - b
                        videocuts.append((int(b), int(e), event.title))
                videocuts = sorted(videocuts, key=lambda x: x[0])
            else:
                # no events were selected
                end = max([size for size, func in self._properties])
                totalframes = end
                videocuts = [(0, int(end), None)]
            ##########################################################

            self._progress.min = 0
            self._progress.max = totalframes
            self._progress.show()

            for b, e, eventname in videocuts:

                filename = self._outfile.value
                filename = filename.format(event=eventname, start=b, end=e)
                filename = os.path.join(self._outdir.value, filename)

                with open(filename, 'w') as out:

                    ## write the csv columns headers
                    out.write('frame;')
                    for values in self._export_list.value:
                        out.write(('{0};'.format(values[0])))
                    out.write('\n')

                    ## write the values
                    for index in range(b, e):
                        out.write('{0};'.format(index))
                        for _, func in self._properties:
                            out.write('{0};'.format(func(index)))
                        out.write('\n')
                        self._progress += 1

            self._export_list.enabled = True
            self._tree.enabled = True
            self._add.enabled = True
            self._remove.enabled = True
            self._outdir.enabled = True
            self._outfile.enabled = True
            self._apply.label = 'Apply'
            self._apply.checked = False
            self._progress.hide()

    def __copy_tree_node(self, item, new_item):
        new_item.win = item.win
        if hasattr(item, 'data_function'):
            new_item.data_function = item.data_function

    def __reload_events(self):
        """
		Find all the events available on the timeline
		"""
        timeline = self.parent().timeline
        rows = timeline.rows

        events = {}
        for row in rows:
            for event in row.events:
                events[event.title] = True

        events = sorted(events.keys())

        loaded_events = dict(self._splitevents.items)
        self._splitevents.value = [(e, loaded_events.get(e, False))
                                   for e in events]

    @property
    def project(self):
        return self._project

    @project.setter
    def project(self, value):
        self._project = value
        self._tree.clear()
        self._tree.clone_tree(value.tree, copy_function=self.__copy_tree_node)
        self.__reload_events()
Ejemplo n.º 2
0
class ContoursGUI(DatasetGUI, Contours, BaseWidget):
    def __init__(self, object2d=None):
        DatasetGUI.__init__(self)
        Contours.__init__(self, object2d)
        BaseWidget.__init__(self, '2D Object', parent_win=object2d)

        self._sel_pts = []

        self._remove_btn = ControlButton('Remove')
        self._layers = ControlCheckBoxList('Layers')
        self._sel_pto_btn = ControlButton('Select point')
        self._switchangle_btn = ControlButton('Switch orientation')
        self._pickcolor = ControlButton('Pick a color',
                                        default=self.__pick_a_color_event)

        self._formset = [
            '_name', '_remove_btn', '_sel_pto_btn', '_switchangle_btn', ' ',
            '_pickcolor', ' ', '_layers'
        ]

        self._switchangle_btn.hide()

        #### set controls ##############################################
        self._remove_btn.icon = conf.ANNOTATOR_ICON_REMOVE
        self._sel_pto_btn.icon = conf.ANNOTATOR_ICON_SELECTPOINT
        self._switchangle_btn.icon = conf.ANNOTATOR_ICON_REMOVE

        #### set events #################################################
        self._remove_btn.value = self.remove_dataset
        self._sel_pto_btn.value = self.__sel_pto_btn_event
        self._switchangle_btn.value = self.__switchangle_btn_event

        self.create_tree_nodes()

        self._layers.value = [('contours', True), ('angle', True),
                              ('velocity vector', True),
                              ('bounding rect', False), ('fit ellipse', False),
                              ('extreme points', False),
                              ('convex hull', False),
                              ('rotated rectangle', False),
                              ('minimum enclosing circle', False),
                              ('minimum enclosing triangle', False)]

    ######################################################################
    ### EVENTS ###########################################################
    ######################################################################
    def __sel_pto_btn_event(self):
        video_index = self.mainwindow._player.video_index - 1

        if video_index < 0 and self.get_position(video_index) is not None:
            return

        self._sel_pts.append(video_index)
        self._sel_pts = sorted(self._sel_pts)
        #store a temporary path for interpolation visualization
        if len(self._sel_pts) == 2:
            self._switchangle_btn.show()
        elif len(self._sel_pts) > 2:
            self._sel_pts = self._sel_pts[-1:]
            self._switchangle_btn.hide()
        else:
            self._switchangle_btn.hide()

        self.mainwindow._player.refresh()

    def __switchangle_btn_event(self):
        if len(self._sel_pts) == 2:
            for i in range(self._sel_pts[0], self._sel_pts[1] + 1):
                head, tail = self.get_extreme_points(i)
                centroid = self.get_position(i)
                self._angles[i] = points_angle(centroid, tail)

            self.mainwindow._player.refresh()

    def __calc_walked_distance(self):
        v1 = self.object2d.create_value()
        v1.name = "Total walked distance"
        v1._values, _ = self.calc_walked_distance()

    def __calc_walked_distance_window(self):
        winsize, ok = QInputDialog.getInt(self,
                                          "Calculate the walked distance",
                                          "Enter the window size", 30)
        if ok:
            v2 = self.object2d.create_value()
            v2.name = "Walked distance in the previous {0} frames".format(
                winsize)
            _, v2._values = self.calc_walked_distance(winsize)

    def __calc_walked_distance_with_direction(self):
        v1 = self.object2d.create_value()
        v1.name = "Total walked distance with direction"
        v1._values, _ = self.calc_walked_distance_with_direction()

    def __calc_walked_distance_window_with_direction(self):
        winsize, ok = QInputDialog.getInt(
            self, "Calculate the walked distance with direction",
            "Enter the window size", 30)
        if ok:
            v2 = self.object2d.create_value()
            v2.name = "Walked distance with direction in the previous {0} frames".format(
                winsize)
            _, v2._values = self.calc_walked_distance_with_direction(winsize)

    def __pick_a_color_event(self):
        color = QColor(self.color[2], self.color[1], self.color[0])
        color = QColorDialog.getColor(color,
                                      parent=self,
                                      title='Pick a color for the path')
        self.color = color.blue(), color.green(), color.red()
        self.mainwindow._player.refresh()

    ######################################################################
    ### FUNCTIONS ########################################################
    ######################################################################
    def create_popupmenu_actions(self):
        self.tree.add_popup_menu_option(label='Remove',
                                        function_action=self.remove_dataset,
                                        item=self.treenode,
                                        icon=conf.ANNOTATOR_ICON_DELETE)

        self.tree.add_popup_menu_option('-', item=self.treenode)

        self.tree.add_popup_menu_option(
            label='Total walked distance',
            function_action=self.__calc_walked_distance,
            item=self.treenode,
            icon=conf.ANNOTATOR_ICON_POSITION)
        self.tree.add_popup_menu_option(
            label='Walked distance in a window',
            function_action=self.__calc_walked_distance_window,
            item=self.treenode,
            icon=conf.ANNOTATOR_ICON_POSITION)

        self.tree.add_popup_menu_option(
            label='Total distance with direction',
            function_action=self.__calc_walked_distance_with_direction,
            item=self.treenode,
            icon=conf.ANNOTATOR_ICON_POSITION)
        self.tree.add_popup_menu_option(
            label='Walked distance in a window with direction',
            function_action=self.__calc_walked_distance_window_with_direction,
            item=self.treenode,
            icon=conf.ANNOTATOR_ICON_POSITION)

    def create_tree_nodes(self):
        self.treenode = self.tree.create_child(
            self.name,
            icon=conf.ANNOTATOR_ICON_CONTOUR,
            parent=self.parent_treenode)
        self.treenode.win = self
        self.create_popupmenu_actions()

        self.create_tracking_tree_nodes()

    ######################################################################
    ### FUNCTIONS ########################################################
    ######################################################################

    def get_angle_angle_value(self, index):
        return self.get_angle(index)

    def get_angle_angularvelocity_value(self, index):
        return self.get_angular_velocity(index)

    def get_angle_difftozero_value(self, index):
        return self.get_angle_diff_to_zero(index)

    def get_position_x_value(self, index):
        v = self.get_position(index)
        return v[0] if v is not None else None

    def get_position_y_value(self, index):
        v = self.get_position(index)
        return v[1] if v is not None else None

    def get_velocity_x_value(self, index):
        v = self.get_velocity(index)
        return v[0] if v is not None else None

    def get_velocity_y_value(self, index):
        v = self.get_velocity(index)
        return v[1] if v is not None else None

    def get_velocity_absolute_value(self, index):
        return self.get_absolute_velocity(index)

    def get_velocity_withdirection_value(self, index):
        return self.get_velocity_with_direction(index)

    def get_velocity_angle_value(self, index):
        return self.get_velocity_angle(index)

    def get_acceleration_x_value(self, index):
        v = self.get_acceleration(index)
        return v[0] if v is not None else None

    def get_acceleration_y_value(self, index):
        v = self.get_acceleration(index)
        return v[1] if v is not None else None

    def get_acceleration_absolute_value(self, index):
        v = self.get_acceleration(index)
        return math.sqrt(v[1]**2 + v[0]**2) if v is not None else None

    ################# BOUNDING RECT ###################################################

    def create_tracking_boundingrect_tree_nodes(self):
        self.create_group_node('bounding rect', icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('bounding rect > left x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('bounding rect > left y',
                              icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('bounding rect > width',
                              icon=conf.ANNOTATOR_ICON_WIDTH)
        self.create_data_node('bounding rect > height',
                              icon=conf.ANNOTATOR_ICON_HEIGHT)
        self.create_data_node('bounding rect > aspect ratio',
                              icon=conf.ANNOTATOR_ICON_ASPECT_RATIO)
        self.create_data_node('bounding rect > area',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('bounding rect > perimeter',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('bounding rect > equivalent diameter',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('bounding rect > extend',
                              icon=conf.ANNOTATOR_ICON_INFO)

    def get_boundingrect_leftx_value(self, index):
        v = self.get_bounding_box(index)
        return v[0] if v is not None else None

    def get_boundingrect_lefty_value(self, index):
        v = self.get_bounding_box(index)
        return v[1] if v is not None else None

    def get_boundingrect_width_value(self, index):
        v = self.get_bounding_box(index)
        return v[2] if v is not None else None

    def get_boundingrect_height_value(self, index):
        v = self.get_bounding_box(index)
        return v[3] if v is not None else None

    def get_boundingrect_aspectratio_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        x, y, w, h = cv2.boundingRect(cnt)
        return float(w) / float(h)

    def get_boundingrect_area_value(self, index):
        v = self.get_bounding_box(index)
        return v[0] * v[1] if v is not None else None

    def get_boundingrect_perimeter_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        area = cv2.contourArea(cnt)
        x, y, w, h = cv2.boundingRect(cnt)
        return 2 * w + 2 * h

    def get_boundingrect_equivalentdiameter_value(self, index):
        area = self.get_boundingrect_area_value(index)
        if area is None: return None
        return np.sqrt(4 * area / np.pi)

    def get_boundingrect_extend_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        area = cv2.contourArea(cnt)
        x, y, w, h = cv2.boundingRect(cnt)
        rect_area = w * h
        return float(area) / float(rect_area)

    ################# BOUNDING RECT ###################################################

    ################# minimum enclosing triangle ###################################################

    def create_tracking_minenclosingtriangle_tree_nodes(self):
        self.create_group_node('minimum enclosing triangle',
                               icon=conf.ANNOTATOR_ICON_AREA)

        self.create_group_node('minimum enclosing triangle > p1',
                               icon=conf.ANNOTATOR_ICON_POINT)
        self.create_data_node('minimum enclosing triangle > p1 > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('minimum enclosing triangle > p1 > y',
                              icon=conf.ANNOTATOR_ICON_Y)

        self.create_group_node('minimum enclosing triangle > p2',
                               icon=conf.ANNOTATOR_ICON_POINT)
        self.create_data_node('minimum enclosing triangle > p2 > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('minimum enclosing triangle > p2 > y',
                              icon=conf.ANNOTATOR_ICON_Y)

        self.create_group_node('minimum enclosing triangle > p3',
                               icon=conf.ANNOTATOR_ICON_POINT)
        self.create_data_node('minimum enclosing triangle > p3 > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('minimum enclosing triangle > p3 > y',
                              icon=conf.ANNOTATOR_ICON_Y)

        self.create_data_node('minimum enclosing triangle > perimeter',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('minimum enclosing triangle > angle',
                              icon=conf.ANNOTATOR_ICON_AREA)

    def get_minimumenclosingtriangle_p1_x_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][0][0]

    def get_minimumenclosingtriangle_p1_y_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][0][1]

    def get_minimumenclosingtriangle_p2_x_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][1][0]

    def get_minimumenclosingtriangle_p2_y_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][1][1]

    def get_minimumenclosingtriangle_p3_x_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][2][0]

    def get_minimumenclosingtriangle_p3_y_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        return triangle[0][2][1]

    def get_minimumenclosingtriangle_perimeter_value(self, index):
        triangle = self.get_minimumenclosingtriangle(index)
        if triangle is None: return None
        p1, p2, p3 = triangle
        return pts_utils.lin_dist(p1[0], p2[0]) + pts_utils.lin_dist(
            p2[0], p3[0]) + pts_utils.lin_dist(p3[0], p1[0])

    def get_minimumenclosingtriangle_angle_value(self, index):
        return self.get_minimumenclosingtriangle_angle(index)

    ################# minimum enclosing triangle ###################################################

    def create_tracking_minenclosingcircle_tree_nodes(self):
        self.create_group_node('minimum enclosing circle',
                               icon=conf.ANNOTATOR_ICON_CIRCLE)
        self.create_data_node('minimum enclosing circle > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('minimum enclosing circle > y',
                              icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('minimum enclosing circle > radius',
                              icon=conf.ANNOTATOR_ICON_WIDTH)

    def get_minimumenclosingcircle_x_value(self, index):
        circle = self.get_minimumenclosingcircle(index)
        if circle is None: return None
        center, radius = circle
        return center[0]

    def get_minimumenclosingcircle_y_value(self, index):
        circle = self.get_minimumenclosingcircle(index)
        if circle is None: return None
        center, radius = circle
        return center[1]

    def get_minimumenclosingcircle_radius_value(self, index):
        circle = self.get_minimumenclosingcircle(index)
        if circle is None: return None
        center, radius = circle
        return radius

    ################# EXTREME POINTS ####################################################

    def create_tracking_extremepoints_tree_nodes(self):
        self.create_group_node('extreme points',
                               icon=conf.ANNOTATOR_ICON_POINT)

        self.create_group_node('extreme points > p1',
                               icon=conf.ANNOTATOR_ICON_POINT)
        self.create_data_node('extreme points > p1 > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('extreme points > p1 > y',
                              icon=conf.ANNOTATOR_ICON_Y)

        self.create_group_node('extreme points > p2',
                               icon=conf.ANNOTATOR_ICON_POINT)
        self.create_data_node('extreme points > p2 > x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('extreme points > p2 > y',
                              icon=conf.ANNOTATOR_ICON_Y)

        self.create_data_node('extreme points > angle',
                              icon=conf.ANNOTATOR_ICON_ANGLE)

    def get_extremepoints_p1_x_value(self, index):
        v = self.get_extreme_points(index)
        return v[0][0] if v is not None else None

    def get_extremepoints_p1_y_value(self, index):
        v = self.get_extreme_points(index)
        return v[0][1] if v is not None else None

    def get_extremepoints_p2_x_value(self, index):
        v = self.get_extreme_points(index)
        return v[1][0] if v is not None else None

    def get_extremepoints_p2_y_value(self, index):
        v = self.get_extreme_points(index)
        return v[1][1] if v is not None else None

    def get_extremepoints_angle_value(self, index):
        v = self.get_extreme_points(index)
        return math.degrees(pts_utils.points_angle(
            v[0], v[1])) if v is not None else None

    ################# FIT ELLISPSE ####################################################

    ################# FIT ELLIPSE ####################################################

    def create_tracking_fitellipse_tree_nodes(self):
        self.create_group_node('fit ellipse', icon=conf.ANNOTATOR_ICON_ELLIPSE)
        self.create_data_node('fit ellipse > center x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('fit ellipse > center y',
                              icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('fit ellipse > major axis size',
                              icon=conf.ANNOTATOR_ICON_HEIGHT)
        self.create_data_node('fit ellipse > minor axis size',
                              icon=conf.ANNOTATOR_ICON_WIDTH)
        self.create_data_node('fit ellipse > angle',
                              icon=conf.ANNOTATOR_ICON_ANGLE)

    def get_fitellipse_centerx_value(self, index):
        v = self.get_fit_ellipse(index)
        return v[0][0] if v is not None else None

    def get_fitellipse_centery_value(self, index):
        v = self.get_fit_ellipse(index)
        return v[0][1] if v is not None else None

    def get_fitellipse_majoraxissize_value(self, index):
        v = self.get_fit_ellipse(index)
        return v[1][1] if v is not None else None

    def get_fitellipse_minoraxissize_value(self, index):
        v = self.get_fit_ellipse(index)
        return v[1][0] if v is not None else None

    def get_fitellipse_angle_value(self, index):
        v = self.get_fit_ellipse(index)
        return v[2] if v is not None else None

    ################# FIT ELLIPSE ####################################################

    ################# CONVEX HULL ####################################################

    def create_tracking_convexhull_tree_nodes(self):
        self.create_group_node('convex hull', icon=conf.ANNOTATOR_ICON_HULL)
        self.create_data_node('convex hull > area',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('convex hull > perimeter',
                              icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('convex hull > equivalent diameter',
                              icon=conf.ANNOTATOR_ICON_CIRCLE)
        self.create_data_node('convex hull > solidity',
                              icon=conf.ANNOTATOR_ICON_BLACK_CIRCLE)

    def get_convexhull_area_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        hull = cv2.convexHull(cnt)
        return cv2.contourArea(hull)

    def get_convexhull_perimeter_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        hull = cv2.convexHull(cnt)
        return cv2.arcLength(hull, True)

    def get_convexhull_equivalentdiameter_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        hull = cv2.convexHull(cnt)
        area = cv2.contourArea(hull)
        return np.sqrt(4 * area / np.pi)

    def get_convexhull_solidity_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        area = cv2.contourArea(cnt)
        hull = cv2.convexHull(cnt)
        hull_area = cv2.contourArea(hull)
        return float(area) / float(hull_area)

    ################# CONVEX HULL ####################################################

    ################# ROTATED RECTANGLE ####################################################

    def create_tracking_rotatedrectangle_tree_nodes(self):
        self.create_group_node('rotated rectangle',
                               icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('rotated rectangle > center x',
                              icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('rotated rectangle > center y',
                              icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('rotated rectangle > width',
                              icon=conf.ANNOTATOR_ICON_HEIGHT)
        self.create_data_node('rotated rectangle > height',
                              icon=conf.ANNOTATOR_ICON_WIDTH)
        self.create_data_node('rotated rectangle > angle',
                              icon=conf.ANNOTATOR_ICON_ANGLE)

    def get_rotatedrectangle_centerx_value(self, index):
        v = self.get_rotatedrectangle(index)
        return v[0][0] if v is not None else None

    def get_rotatedrectangle_centery_value(self, index):
        v = self.get_rotatedrectangle(index)
        return v[0][1] if v is not None else None

    def get_rotatedrectangle_width_value(self, index):
        v = self.get_rotatedrectangle(index)
        return v[1][0] if v is not None else None

    def get_rotatedrectangle_height_value(self, index):
        v = self.get_rotatedrectangle(index)
        return v[1][1] if v is not None else None

    def get_rotatedrectangle_angle_value(self, index):
        v = self.get_rotatedrectangle(index)
        return v[2] if v is not None else None

    ################# ROTATED RECTANGLE ####################################################

    ################# MOMENTS ####################################################

    def create_tracking_moments_tree_nodes(self):
        self.create_group_node('moments', icon=conf.ANNOTATOR_ICON_HULL)
        self.create_data_node('moments > m00', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m10', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m01', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m20', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m11', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m02', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m30', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m21', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m12', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > m03', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu20', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu11', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu02', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu30', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu21', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu12', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > mu03', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu20', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu11', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu02', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu30', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu21', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu12', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('moments > nu03', icon=conf.ANNOTATOR_ICON_X)

    ################# MOMENTS ####################################################

    def get_moments_m00_value(self, index):
        return self.get_moment(index, 'm00')

    def get_moments_m10_value(self, index):
        return self.get_moment(index, 'm10')

    def get_moments_m01_value(self, index):
        return self.get_moment(index, 'm01')

    def get_moments_m20_value(self, index):
        return self.get_moment(index, 'm20')

    def get_moments_m11_value(self, index):
        return self.get_moment(index, 'm11')

    def get_moments_m02_value(self, index):
        return self.get_moment(index, 'm02')

    def get_moments_m30_value(self, index):
        return self.get_moment(index, 'm30')

    def get_moments_m21_value(self, index):
        return self.get_moment(index, 'm21')

    def get_moments_m12_value(self, index):
        return self.get_moment(index, 'm12')

    def get_moments_m03_value(self, index):
        return self.get_moment(index, 'm03')

    def get_moments_mu20_value(self, index):
        return self.get_moment(index, 'mu20')

    def get_moments_mu11_value(self, index):
        return self.get_moment(index, 'mu11')

    def get_moments_mu02_value(self, index):
        return self.get_moment(index, 'mu02')

    def get_moments_mu30_value(self, index):
        return self.get_moment(index, 'mu30')

    def get_moments_mu21_value(self, index):
        return self.get_moment(index, 'mu21')

    def get_moments_mu12_value(self, index):
        return self.get_moment(index, 'mu12')

    def get_moments_mu03_value(self, index):
        return self.get_moment(index, 'mu03')

    def get_moments_nu20_value(self, index):
        return self.get_moment(index, 'nu20')

    def get_moments_nu11_value(self, index):
        return self.get_moment(index, 'nu11')

    def get_moments_nu30_value(self, index):
        return self.get_moment(index, 'nu02')

    def get_moments_nu02_value(self, index):
        return self.get_moment(index, 'nu30')

    def get_moments_nu21_value(self, index):
        return self.get_moment(index, 'nu21')

    def get_moments_nu12_value(self, index):
        return self.get_moment(index, 'nu12')

    def get_moments_nu03_value(self, index):
        return self.get_moment(index, 'nu03')

    ################# HU MOMENTS ####################################################

    def create_tracking_humoments_tree_nodes(self):
        self.create_group_node('hu moments', icon=conf.ANNOTATOR_ICON_HULL)
        self.create_data_node('hu moments > hu0', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu1', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu2', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu3', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu4', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu5', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('hu moments > hu6', icon=conf.ANNOTATOR_ICON_X)

    def get_humoments_hu0_value(self, index):
        return self.get_humoment(index, 0)

    def get_humoments_hu1_value(self, index):
        return self.get_humoment(index, 1)

    def get_humoments_hu2_value(self, index):
        return self.get_humoment(index, 2)

    def get_humoments_hu3_value(self, index):
        return self.get_humoment(index, 3)

    def get_humoments_hu4_value(self, index):
        return self.get_humoment(index, 4)

    def get_humoments_hu5_value(self, index):
        return self.get_humoment(index, 5)

    def get_humoments_hu6_value(self, index):
        return self.get_humoment(index, 6)

    ################# HU MOMENTS ####################################################

    def create_tracking_tree_nodes(self):
        ################# CONTOUR #########################################################
        self.create_data_node('area', icon=conf.ANNOTATOR_ICON_AREA)
        self.create_data_node('perimeter', icon=conf.ANNOTATOR_ICON_AREA)

        self.create_data_node('equivalent diameter',
                              icon=conf.ANNOTATOR_ICON_CIRCLE)

        self.create_group_node('angle', icon=conf.ANNOTATOR_ICON_ANGLE)
        self.create_data_node('angle > angle',
                              icon=conf.ANNOTATOR_ICON_POSITION)
        self.create_data_node('angle > angular velocity',
                              icon=conf.ANNOTATOR_ICON_VELOCITY)
        self.create_data_node('angle > diff to zero',
                              icon=conf.ANNOTATOR_ICON_VELOCITY)

        self.create_group_node('position', icon=conf.ANNOTATOR_ICON_POSITION)
        self.create_data_node('position > x', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('position > y', icon=conf.ANNOTATOR_ICON_Y)

        self.create_group_node('velocity', icon=conf.ANNOTATOR_ICON_VELOCITY)
        self.create_data_node('velocity > x', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('velocity > y', icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('velocity > absolute',
                              icon=conf.ANNOTATOR_ICON_INFO)
        self.create_data_node('velocity > with direction',
                              icon=conf.ANNOTATOR_ICON_INFO)
        self.create_data_node('velocity > angle',
                              icon=conf.ANNOTATOR_ICON_INFO)

        self.create_group_node('acceleration',
                               icon=conf.ANNOTATOR_ICON_ACCELERATION)
        self.create_data_node('acceleration > x', icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('acceleration > y', icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('acceleration > absolute',
                              icon=conf.ANNOTATOR_ICON_INFO)

        self.create_tracking_boundingrect_tree_nodes()
        self.create_tracking_fitellipse_tree_nodes()
        self.create_tracking_extremepoints_tree_nodes()
        self.create_tracking_convexhull_tree_nodes()
        self.create_tracking_rotatedrectangle_tree_nodes()
        self.create_tracking_minenclosingcircle_tree_nodes()
        self.create_tracking_minenclosingtriangle_tree_nodes()
        self.create_tracking_moments_tree_nodes()
        self.create_tracking_humoments_tree_nodes()

    ######################################################################
    ### FUNCTIONS ########################################################
    ######################################################################

    def __draw_point(self, frame, p, color=(100, 0, 100)):
        cv2.circle(frame, p, 5, (255, 255, 255), -1)
        cv2.circle(frame, p, 3, color, -1)

    def draw_contour(self, frame, frame_index):
        cnt = self.get_contour(frame_index)
        if cnt is not None:
            cv2.polylines(frame, np.array([cnt]), True, self.color, 2)

    def draw_angle(self, frame, frame_index):
        angle = self.get_angle(frame_index)
        p1 = self.get_position(frame_index)
        if angle is None or p1 is None: return None

        p2 = int(round(p1[0] + 40 * math.cos(angle))), int(
            round(p1[1] + 40 * math.sin(angle)))
        cv2.line(frame, p1, p2, (255, 100, 0), 2)

    def draw_boundingrect(self, frame, frame_index):
        rect = self.get_bounding_box(frame_index)
        if rect is None: return None
        x, y, w, h = rect
        cv2.rectangle(frame, (x, y), (x + w, y + h), self.color, 2)

    def draw_fitellipse(self, frame, frame_index):
        ellipse = self.get_fit_ellipse(frame_index)
        if ellipse is None: return None
        (x, y), (MA, ma), angle = ellipse
        cv2.ellipse(frame, (int(round(x)), int(round(y))),
                    (int(round(MA)), int(round(ma))), int(round(angle)), 0,
                    360, (0, 0, 255), 1)

    def draw_extremepoints(self, frame, frame_index):
        head, tail = self.get_extreme_points(frame_index)
        if head is not None:
            self.__draw_point(frame, head, color=(100, 0, 100))
        if tail is not None:
            self.__draw_point(frame, tail, color=(100, 100, 0))

    def draw_convexhull(self, frame, frame_index):
        cnt = self.get_contour(frame_index)
        if cnt is None: return None
        hull = cv2.convexHull(cnt)
        cv2.polylines(frame, np.array([hull]), True, self.color, 1)

    def draw_rotatedrectangle(self, frame, frame_index):

        rect = self.get_rotatedrectangle(frame_index)
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(frame, [box], 0, self.color, 1)

    def draw_minimumenclosingcircle(self, frame, frame_index):
        circle = self.get_minimumenclosingcircle(frame_index)
        if circle is not None:
            center, radius = circle
            center = int(round(center[0])), int(round(center[1]))
            cv2.circle(frame, center, int(round(radius)), self.color)

    def draw_minenclosingtriangle(self, frame, frame_index):
        triangle = self.get_minimumenclosingtriangle(frame_index)
        if triangle is not None:
            p1, p2, p3 = triangle
            p1, p2, p3 = tuple(p1[0]), tuple(p2[0]), tuple(p3[0])
            cv2.line(frame, p1, p2, 255)
            cv2.line(frame, p2, p3, 255)
            cv2.line(frame, p3, p1, 255)

    def draw_velocity_vector(self, frame, frame_index):
        vel = self.get_velocity(frame_index)
        p0 = self.get_position(frame_index)
        if vel is not None and p0 is not None:
            p1 = p0[0] - vel[0], p0[1] - vel[1]
            cv2.line(frame, p0, p1, (255, 255, 0))

    def draw(self, frame, frame_index):

        for i in self._sel_pts:  #store a temporary path for interpolation visualization
            p = self.get_position(i)
            cv2.circle(frame, p, 20, (255, 255, 255), 4, lineType=cv2.LINE_AA)  # pylint: disable=no-member
            cv2.circle(frame, p, 20, (50, 50, 255), 1, lineType=cv2.LINE_AA)  # pylint: disable=no-member

        layers = self._layers.value
        if 'contours' in layers: self.draw_contour(frame, frame_index)
        if 'angle' in layers: self.draw_angle(frame, frame_index)
        if 'velocity vector' in layers:
            self.draw_velocity_vector(frame, frame_index)
        if 'bounding rect' in layers:
            self.draw_boundingrect(frame, frame_index)
        if 'fit ellipse' in layers: self.draw_fitellipse(frame, frame_index)
        if 'extreme points' in layers:
            self.draw_extremepoints(frame, frame_index)
        if 'convex hull' in layers: self.draw_convexhull(frame, frame_index)
        if 'rotated rectangle' in layers:
            self.draw_rotatedrectangle(frame, frame_index)
        if 'minimum enclosing circle' in layers:
            self.draw_minimumenclosingcircle(frame, frame_index)
        if 'minimum enclosing triangle' in layers:
            self.draw_minenclosingtriangle(frame, frame_index)

    ################# CONTOUR #########################################################

    def get_angle_value(self, index):
        return self.get_angle(index)

    def get_area_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        return cv2.contourArea(cnt)

    def get_perimeter_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        return cv2.arcLength(cnt, True)

    def get_equivalentdiameter_value(self, index):
        cnt = self.get_contour(index)
        if cnt is None: return None
        area = cv2.contourArea(cnt)
        return np.sqrt(4 * area / np.pi)

    @property
    def mainwindow(self):
        return self.object2d.mainwindow

    @property
    def tree(self):
        return self.object2d.tree

    @property
    def video_capture(self):
        return self._object2d.video_capture

    @property
    def parent_treenode(self):
        return self.object2d.treenode
Ejemplo n.º 3
0
class GraphApp(BaseApp):
	"""Application form"""

	def __init__(self, title='Variables graphs'):
		super(GraphApp,self).__init__(title)

		self._graph   	  = ControlVisVis("Graph")
		self._toggleVars  = ControlButton('Show/Hide variables', checkable=True)
		self._loadGraph   = ControlButton('Apply')
		self._varsList	  = ControlCheckBoxList('Variables')

		self._varsList += ('Frames',True)
		self._varsList += ('X',True)
		self._varsList += ('Y',True)
		self._varsList += ('Z',False)
		self._varsList += ('Velocity',False)
		self._varsList += ('Acceleration',False)

		self._modules_tabs.update({
			'Graphs': [ 
				('_toggleVars',' '),
				'_varsList',
				'_loadGraph',
				'_graph'],
		})
		
		
		self._loadGraph.value 	= self.__calculate_graph
		self._toggleVars.value = self.__show_hide_variables
		self._varsList.hide()
		self._loadGraph.hide()
	
	def __show_hide_variables(self):
		#Show and hide the variables list
		if self._toggleVars.checked:
			self._varsList.show()
			self._loadGraph.show()
		else:
			self._varsList.hide()
			self._loadGraph.hide()
			
	
	def __calculate_graph(self):
		#Render the graph
		if self._data==None:
			self.warning("Please load the data first.", "The data is missing")
			return

		lower  = 0 if self._boundings.value[0]<0 else self._boundings.value[0]
		higher = len(self._data) if self._boundings.value[1]>(len(self._data)+1) else self._boundings.value[1]

		self._progress.min = lower
		self._progress.max = higher

		values = []
		variables = self._varsList.value

		if len(variables)>3:
			self.warning("Please select the maximum of 3 variables.", "Too many variables selected")
			return

		for i in range(int(lower), int(higher)-2 ):
			self._progress.value = i
			if self._data[i]!=None:
				val = []
				pos = self._data[i].position
					
				if 'Frames' in variables: 		val.append(i)
				if 'X' in variables: 			val.append(pos[0])
				if 'Y' in variables: 			val.append(pos[1])
				if 'Z' in variables: 			val.append(pos[2])
				if 'Velocity' in variables: 	val.append(self._velocities[i])
				if 'Acceleration' in variables: val.append(self._accelerations[i])

				values.append( val )
		
		self._graph.value = [values]
class DatasetsDialog(BaseWidget):
    def __init__(self, parent_win=None):
        BaseWidget.__init__(self, 'Datasets', parent_win=parent_win)

        self._panel = ControlEmptyWidget(default=DatasetsSelectorDialog(
            parent_win=self))
        self._interval = ControlBoundingSlider('Interval', horizontal=True)
        self._apply_btn = ControlButton('Apply')

        self.formset = [
            '_panel',
            '_interval',
            '_apply_btn',
        ]

        self._intervals = {}

        self._panel.value.video_selection_changed_event = self.__video_selection_changed_event
        self._interval.changed_event = self.__update_intervals_event
        self._apply_btn.hide()

    #####################################################################
    ### PRIVATE FUNCTIONS ###############################################
    #####################################################################

    def __update_intervals_event(self):
        self._intervals[self.selected_video] = self._interval.value

    def __video_selection_changed_event(self):
        video = self.selected_video

        if video is not None and video.video_capture is not None:
            self._interval.max = video.video_capture.get(7)
            if video not in self._intervals.keys():
                self._intervals[video] = 0, self._interval.max

            self._interval.value = self._intervals[video]
        self.video_selection_changed_event()

    #####################################################################
    ### EVENTS ##########################################################
    #####################################################################

    def video_selection_changed_event(self):
        pass

    def destroy(self, destroyWindow=True, destroySubWindows=True):
        self._panel.value.destroy(destroyWindow, destroySubWindows)
        super(DatasetsDialog, self).destroy(destroyWindow, destroySubWindows)

    #####################################################################
    ### FUNCTIONS #######################################################
    #####################################################################

    def refresh(self):
        self._panel.value.refresh()

    def clear(self):
        self._panel.value.clear()

    def __add__(self, other):
        self._panel.value += other
        return self

    def __sub__(self, other):
        self._panel.value -= other
        return self

    #####################################################################
    ### PROPERTIES ######################################################
    #####################################################################

    @property
    def videos(self):
        return self._panel.value.videos

    @property
    def datasets(self):
        return self._panel.value.datasets

    @property
    def datasets_changed_event(self):
        return self._panel.value.datasets_changed_event

    @datasets_changed_event.setter
    def datasets_changed_event(self, value):
        self._panel.value.datasets_changed_event = value

    @property
    def objects_changed_event(self):
        return self._panel.value.objects_changed_event

    @objects_changed_event.setter
    def objects_changed_event(self, value):
        self._panel.value.objects_changed_event = value

    @property
    def selected_video(self):
        return self._panel.value.selected_video

    @property
    def selected_video_range(self):
        return self._intervals.value

    @property
    def selected_data(self):
        for video, paths in self._panel.value.selected_data:
            begin, end = self._intervals.get(video,
                                             (0, video.video_capture.get(7)))
            yield video, (begin, end), paths

    @property
    def apply_event(self):
        return self._apply_btn.value

    @apply_event.setter
    def apply_event(self, value):
        if value is not None: self._apply_btn.show()
        self._apply_btn.value = value

    @property
    def interval_visible(self):
        return self._interval.visible

    @interval_visible.setter
    def interval_visible(self, value):
        if value:
            self._interval.show()
        else:
            self._interval.hide()

    @property
    def objects_filter(self):
        return self._panel.value.objects_filter

    @objects_filter.setter
    def objects_filter(self, value):
        self._panel.value.objects_filter = value

    @property
    def datasets_filter(self):
        return self._panel.value.datasets_filter

    @datasets_filter.setter
    def datasets_filter(self, value):
        self._panel.value.datasets_filter = value
class EditFundingOpportunitiesApp(ModelFormWidget):

    AUTHORIZED_GROUPS = [settings.PERMISSION_EDIT_FUNDING, 'superuser']

    TITLE = "Edit opportunities"
    MODEL = FundingOpportunity

    FIELDSETS = [
        'h2:Opportunity details',
        segment([
            ('subject', 'fundingopportunity_published',
             'fundingopportunity_rolling'),
            ('fundingopportunity_name', 'fundingopportunity_end'),
            ('_loi', 'fundingopportunity_loideadline',
             'fundingopportunity_fullproposal'),
            ('fundingopportunity_link', 'topics'),
        ]), 'h2:Financing info',
        segment([
            ('financingAgency', 'currency', 'paymentfrequency'),
            ('fundingtype', 'fundingopportunity_value',
             'fundingopportunity_duration'),
        ]), 'h2:Description',
        segment([
            'fundingopportunity_eligibility',
            'fundingopportunity_scope',
            'fundingopportunity_brifdesc',
        ])
    ]

    def __init__(self, *args, **kwargs):
        self._loi = ControlCheckBox('LOI',
                                    changed_event=self.__loi_changed_event)
        self._copybtn = ControlButton('Copy',
                                      default=self.__copybtn_event,
                                      label_visible=False,
                                      css='red')

        super().__init__(*args, **kwargs)

        self.fundingopportunity_loideadline.hide()
        self.fundingopportunity_fullproposal.hide()
        self.__fundingtype_changed_evt()
        self.__loi_changed_event()
        self.fundingtype.changed_event = self.__fundingtype_changed_evt

    def __fundingtype_changed_evt(self):
        if self.fundingtype.value == None:
            self.fundingopportunity_value.show()

        else:
            self.fundingopportunity_value.hide()
            self.fundingopportunity_value.value = None

    def __loi_changed_event(self):
        if self._loi.value:
            self.fundingopportunity_loideadline.show()
            self.fundingopportunity_fullproposal.show()
        else:
            self.fundingopportunity_loideadline.value = None
            self.fundingopportunity_fullproposal.value = None
            self.fundingopportunity_loideadline.hide()
            self.fundingopportunity_fullproposal.hide()

    def delete_event(self):
        res = super(EditFundingOpportunitiesApp, self).delete_event()
        self._copybtn.hide()
        return res

    def save_event(self, obj, new_object):
        res = super(EditFundingOpportunitiesApp,
                    self).save_event(obj, new_object)
        self._copybtn.show()
        return res

    def show_create_form(self):
        super(EditFundingOpportunitiesApp, self).show_create_form()
        self._copybtn.hide()

    def show_edit_form(self, pk=None):
        super(EditFundingOpportunitiesApp, self).show_edit_form(pk)
        self._copybtn.show()

        if self.fundingopportunity_loideadline.value is None and self.fundingopportunity_fullproposal.value is None:
            self.fundingopportunity_loideadline.hide()
            self.fundingopportunity_fullproposal.hide()
            self._loi.value = False
        else:
            self._loi.value = True

    def get_buttons_row(self):
        return [
            no_columns('_save_btn', '_create_btn', '_cancel_btn', ' ',
                       '_copybtn', ' ', '_remove_btn')
        ]

    def __copybtn_event(self):
        obj = self.model_object
        obj.pk = None
        obj.fundingopportunity_name += ' (copy)'
        obj.save()

        for topic in self.model_object.topics.all():
            obj.topics.add(topic)

        app = PyFormsMiddleware.get_instance('opportunities-app')
        app.populate_list()
        app.show_edit_form(obj.pk)
        self.info('Copied')
Ejemplo n.º 6
0
class Dashboard(BaseWidget):

    UID = "dashboard-app"
    TITLE = "New users requests"

    ########################################################
    #### ORQUESTRA CONFIGURATION ###########################
    ########################################################
    LAYOUT_POSITION = conf.ORQUESTRA_HOME
    ORQUESTRA_MENU = "middle-left"
    ORQUESTRA_MENU_ICON = "clipboard outline"
    ORQUESTRA_MENU_ORDER = 10
    ########################################################

    AUTHORIZED_GROUPS = ["superuser"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self._label = ControlLabel()

        self._list = ControlQueryList(
            list_display=["date_joined", "username", "email", "email_confirmed"],
            headers=["Date joined", "Username", "Email", "Email verified"],
        )

        self._edit_btn_label = '<i class="ui edit icon"></i>Edit'
        self._approve_btn_label = '<i class="ui check icon"></i>Approve'
        self._remove_btn_label = '<i class="ui times icon"></i>Remove'

        self._edit = ControlButton(
            self._edit_btn_label,
            label_visible=False,
            css="fluid secondary",
            visible=False,
            default=self.__edit_evt,
        )

        self._approve = ControlButton(
            self._approve_btn_label,
            label_visible=False,
            css="fluid green",
            visible=False,
            default=self.__approve_evt,
        )

        self._remove = ControlButton(
            self._remove_btn_label,
            label_visible=False,
            css="fluid red",
            field_css="",
            visible=False,
            default=self.__remove_evt,
        )

        self.formset = [" ", "_label", ("_remove", "_edit", "_approve"), "_list"]

        self.__enable_actions()

        self._list.item_selection_changed_event = self.__user_selected_evt

        self.populate_users_list()

    def populate_users_list(self):
        queryset = User.objects.filter(is_active=False)

        self.__update_label(queryset)

        if queryset.exists():
            self._list.value = queryset.annotate(
                email_confirmed=F("emailaddress__verified")
            )
            self.__show_actions()
            self.__disable_actions()
        else:
            self._list.hide()
            self._edit.hide()
            self._approve.hide()
            self._remove.hide()

    def __show_actions(self):
        self._edit.show()
        self._approve.show()
        self._remove.show()

    def __enable_actions(self, user=None):
        if user:
            try:
                user.full_clean()
            except ValidationError:
                user_is_valid = False
            else:
                user_is_valid = True

            self._edit.enabled = True if app_settings.USER_EDIT_FORM else False
            self._approve.enabled = user_is_valid
            self._remove.enabled = True
        else:
            self.__disable_actions()

    def __disable_actions(self):
        self._edit.enabled = False
        self._approve.enabled = False
        self._remove.enabled = False

    def __update_label(self, queryset):
        if queryset.exists():
            icon = '<i class="ui info circle icon"></i>'
            msg = "Users listed below require approval for accessing the database."
            css = "info"
        else:
            icon = '<i class="ui check icon"></i>'
            msg = "No users waiting account approval."
            css = "green"
        self._label.value = icon + msg
        self._label.css = css

    def __user_selected_evt(self):
        user_id = self._list.selected_row_id
        user = User.objects.get(pk=user_id)

        self._edit.label = self._edit_btn_label + f" [{user.username}]"
        self._approve.label = self._approve_btn_label + f" [{user.username}]"
        self._remove.label = self._remove_btn_label + f" [{user.username}]"

        self.__enable_actions(user=user)

    def __edit_evt(self):
        app = UserForm(pk=self._list.selected_row_id)
        app.LAYOUT_POSITION = conf.ORQUESTRA_NEW_TAB

    def __approve_evt(self):
        user_id = self._list.selected_row_id
        user = User.objects.get(pk=user_id)
        user.is_active = True

        try:
            user.full_clean()
        except ValidationError as e:
            title = "Can not approve user '%s'" % user.username
            self.alert(e.messages, title=title)
            return

        user.save()

        self.populate_users_list()
        self.__disable_actions()

    def __remove_evt(self):
        user_id = self._list.selected_row_id
        user = User.objects.get(pk=user_id)

        user.delete()

        self.populate_users_list()
        self.__disable_actions()
class GeometryManualDesigner(BaseWidget):
    def __init__(self, title, parent=None):
        super(GeometryManualDesigner, self).__init__(title, parent_win=parent)

        self._threshold_win = None
        self._start_point = None
        self._end_point = None

        self._selected_poly = None
        self._selected_point = None

        self._video = ControlFile("Video file")
        self._player = ControlPlayer("Video")
        self._remove = ControlButton("Remove")
        self._square = ControlButton("Square", checkable=True)
        self._circle = ControlButton("Circle", checkable=True)
        self._threshold = ControlButton("Threshold")
        self._export = ControlButton("Export")
        self._import = ControlButton("Import")
        self._polygons = ControlList('Polygons')

        self._apply = ControlButton('Apply')

        self._formset = [
            '_video', "_player",
            ("_square", "_circle", "_threshold", " ", "_remove", " ",
             "_export", "_import"), "=", "_polygons", '_apply'
        ]

        self._video.changedchanged_event = self.videoSelected
        self._square.value = self.square_toggle
        self._circle.value = self.circle_toggle
        self._remove.value = self.remove_clicked
        self._export.value = self.export_clicked
        self._import.value = self.import_clicked
        self._threshold.value = self.threshold_btn_click

        self._player.drag_event = self.on_player_drag_in_video_window
        self._player.end_drag_event = self.on_player_end_drag_in_video_window
        self._player.click_event = self.on_player_click_in_video_window
        self._player.double_click_event = self.on_player_double_click_in_video_window
        self._player.process_frame_event = self.process_frame
        self._player.key_release_event = self.on_player_key_release

        self._apply.hide()

    def on_player_key_release(self, event):
        if event.key() == QtCore.Qt.Key_Delete:
            if self._selected_poly != None and self._selected_point != None:
                poly = self._polygons.get_value(1, self._selected_poly)
                try:
                    points = list(eval(poly))
                    p = points.pop(self._selected_point)
                    self._polygons.set_value(1, self._selected_poly,
                                             str(points)[1:-1])
                    if not self._player.is_playing: self._player.refresh()
                except:
                    pass

    def export_clicked(self):
        filename = str(QFileDialog.getSaveFileName(self, 'Choose a file', ''))
        if filename != "":
            output = open(filename, 'w')
            for values in self._polygons.value:
                output.write((';'.join(values) + '\n'))
            output.close()

    def import_clicked(self):
        filename = str(QFileDialog.getOpenFileName(self, 'Choose a file', ''))
        if filename != "":
            infile = open(filename, 'r')
            polygons = []
            for line in infile:
                values = line.split(';')
                name = values[0]
                poly = values[1]
                polygons.append((name, poly))
            self._polygons.value += polygons

    def process_frame(self, frame):
        rows = self._polygons.value
        for objIndex, obj in enumerate(rows):
            points = eval(obj[1])
            cv2.polylines(frame, [np.array(points, np.int32)],
                          True, (0, 255, 0),
                          2,
                          lineType=cv2.LINE_AA)
            for pointIndex, point in enumerate(points):
                if self._selected_point == pointIndex and objIndex == self._selected_poly:
                    cv2.circle(frame, point, 4, (0, 0, 255), 2)
                else:
                    cv2.circle(frame, point, 4, (0, 255, 0), 2)

        if self._start_point and self._end_point:
            if self._square.checked:
                cv2.rectangle(frame, self._start_point, self._end_point,
                              (233, 44, 44), 2)
            elif self._circle.checked and self._end_point[
                    0] > self._start_point[0] and self._end_point[
                        1] > self._start_point[1]:
                width = self._end_point[0] - self._start_point[0]
                height = self._end_point[1] - self._start_point[1]
                center = (self._start_point[0] + width / 2,
                          self._start_point[1] + height / 2)

                cv2.ellipse(frame, (center, (width, height), 0), (233, 44, 44),
                            2)

        return frame

    def selectPoint(self, x, y):
        rows = self._polygons.value
        for objIndex, obj in enumerate(rows):
            try:
                mouseCoord = (x, y)
                points = eval(obj[1])
                for pointIndex, point in enumerate(points):
                    if pointsDistance(mouseCoord, point) <= 5:
                        self._selected_point = pointIndex
                        self._selected_poly = objIndex
                        return
                self._selected_point = None
                self._selected_poly = None
            except:
                pass

    def get_intersection_point_distance(self, test_point, point1, point2):
        p1 = np.float32(point1)
        p2 = np.float32(point2)
        p3 = np.float32(test_point)
        dist = np.linalg.norm(np.cross(p2 - p1,
                                       p1 - p3)) / np.linalg.norm(p2 - p1)
        return dist

    def on_player_double_click_in_video_window(self, event, x, y):
        mouse = (int(x), int(y))
        rows = self._polygons.value

        distances = []
        for obj_index, obj in enumerate(rows):
            try:
                points = list(eval(obj[1]))
                n_points = len(points)
                for point_index, point in enumerate(points):
                    next_point = points[(point_index + 1) % n_points]
                    distance = self.get_intersection_point_distance(
                        mouse, point, next_point)
                    if distance <= 5:
                        vector = next_point[0] - point[0], next_point[
                            1] - point[1]
                        center = point[0] + vector[0] / 2, point[
                            1] + vector[1] / 2
                        radius = pointsDistance(center, point)

                        mouse_distance = pointsDistance(center, mouse)
                        if mouse_distance < radius:
                            distances.append(
                                (distance, obj_index, point_index))
            except:
                pass

        if len(distances) > 0:
            distances = sorted(distances, key=lambda x: x[0])
            obj_index = distances[0][1]
            point_index = distances[0][2]
            points = list(eval(rows[obj_index][1]))

            points.insert(point_index + 1, mouse)
            self._polygons.set_value(1, obj_index, str(points)[1:-1])

            self._selected_poly = obj_index
            self._selected_point = point_index + 1

            if not self._player.is_playing: self._player.refresh()

    def on_player_click_in_video_window(self, event, x, y):
        self._selected_poly = None
        self._selected_point = None

        if not self._square.checked and not self._circle.checked:
            self.selectPoint(int(x), int(y))

    def on_player_drag_in_video_window(self, startPoint, endPoint):
        self._start_point = (int(startPoint[0]), int(startPoint[1]))
        self._end_point = (int(endPoint[0]), int(endPoint[1]))

        if self._selected_poly != None and self._selected_point != None:
            poly = self._polygons.get_value(1, self._selected_poly)
            try:
                points = list(eval(poly))
                points[self._selected_point] = self._end_point
                self._polygons.set_value(1, self._selected_poly,
                                         str(points)[1:-1])
            except Exception as e:
                print(e)

        if not self._player.is_playing: self._player.refresh()

    def on_player_end_drag_in_video_window(self, startPoint, endPoint):
        self._start_point = int(startPoint[0]), int(startPoint[1])
        self._end_point = int(endPoint[0]), int(endPoint[1])

        points = None
        if self._square.checked:
            points = createRectanglePoints(self._start_point, self._end_point)
        elif self._circle.checked and self._end_point[0] > self._start_point[
                0] and self._end_point[1] > self._start_point[1]:
            points = createEllipsePoints(self._start_point, self._end_point)

        if points:
            self._polygons += [
                "Poly_%d" % self._polygons.rows_count,
                str(points)[1:-1]
            ]

        self._start_point = None
        self._end_point = None
        self._square.checked = False
        self._circle.checked = False

        if not self._player.is_playing: self._player.refresh()

    def __add_contours_from_threshold_win(self, contours):
        for contour in contours:
            if contour.any():
                points = [tuple(p[0]) for p in contour.tolist()]
                self._polygons += [
                    "Poly_%d" % self._polygons.rows_count,
                    str(points)[1:-1]
                ]

    def videoSelected(self):
        self._player.value = self._video.value

    def square_toggle(self, checked):
        if checked: self._circle.checked = False

    def circle_toggle(self, checked):
        if checked: self._square.checked = False

    def threshold_btn_click(self):
        if self._threshold_win is None:
            self._threshold_win = GeometryFromThreshold(self)
            self._threshold_win.add_contours = self.__add_contours_from_threshold_win

        self._threshold_win.show()
        if len(self._video.value) > 0:
            self._threshold_win._filename.value = self._video.value

    def remove_clicked(self):
        self._polygons -= -1  #Remove the selected row
        if not self._player.is_playing: self._player.refresh()

    @property
    def geometries(self):
        polys = []
        rows = self._polygons.value
        for objIndex, obj in enumerate(rows):
            points = eval(obj[1])
            polys.append([obj[0], points])
        return polys

    @geometries.setter
    def geometries(self, value):
        self._polygons.value = []

        for name, poly in value:
            points = [tuple(p) for p in poly]
            self._polygons += [name, str(points)[1:-1]]

    @property
    def polygons(self):
        polys = []
        rows = self._polygons.value
        for objIndex, obj in enumerate(rows):
            points = eval(obj[1])
            polys.append(np.array(points, np.int32))
        return np.array(polys)

    @property
    def apply_event(self):
        return self._apply.value

    @apply_event.setter
    def apply_event(self, value):
        self._apply.value = value
        self._show_apply = value is not None

    def show(self):
        super(GeometryManualDesigner, self).show()
        if hasattr(self, '_show_apply') and self._show_apply:
            self._apply.show()

    @property
    def video_filename(self):
        return None

    @video_filename.setter
    def video_filename(self, value):
        self._video.hide()
        self._player.value = value

    @property
    def video_capture(self):
        return self.video_capture.value

    @video_capture.setter
    def video_capture(self, value):
        self._video.hide()
        self._player.value = value

    @property
    def total_n_frames(self):
        if self._player._value is not None and self._player.value != '':
            return self._player.max
        else:
            return 0
class PathGUI(DatasetGUI, Path, BaseWidget):

    def __init__(self, object2d=None):
        DatasetGUI.__init__(self)
        Path.__init__(self, object2d)
        BaseWidget.__init__(self, '2D Object', parent_win=object2d)

        self.create_tree_nodes()
        
        self._mark_pto_btn        = ControlButton('&Mark point',   checkable=True, icon=conf.ANNOTATOR_ICON_MARKPLACE )
        self._sel_pto_btn         = ControlButton('&Select point', default=self.__sel_pto_btn_event, icon=conf.ANNOTATOR_ICON_SELECTPOINT)
        self._del_path_btn        = ControlButton('Delete path',   default=self.__del_path_btn_event, icon=conf.ANNOTATOR_ICON_DELETEPATH, visible=False)
        self._del_point_btn       = ControlButton('Delete point',  default=self.__del_point_btn_event, icon=conf.ANNOTATOR_ICON_SELECTPOINT, visible=False)
        self._use_referencial     = ControlCheckBox('Apply')
        self._referencial_pt      = ControlText('Referencial',     changed_event=self.__referencial_pt_changed_event)

        self._interpolation_title = ControlLabel('Interpolation',  default='INTERPOLATION', visible=False)
        self._interpolation_mode  = ControlCombo('Mode',           changed_event=self.__interpolation_mode_changed_event, visible=False)
        self._interpolate_btn     = ControlButton('Apply',         default=self.__interpolate_btn_event, icon=conf.ANNOTATOR_ICON_INTERPOLATE, visible=False)
        self._remove_btn          = ControlButton('Remove dataset',default=self.__remove_path_dataset, icon=conf.ANNOTATOR_ICON_REMOVE)

        self._pickcolor   = ControlButton('Pick a color', default=self.__pick_a_color_event)

        self._show_object_name = ControlCheckBox('Show object name', default=False)
        self._show_name = ControlCheckBox('Show name', default=False)

        self._formset = [ 
            '_name',
            ('_show_name', '_show_object_name'),
            ('_referencial_pt', '_use_referencial'),
            '_remove_btn',            
            ' ',
            '_pickcolor',
            ' ',
            ('_mark_pto_btn', '_sel_pto_btn'),
            '_del_path_btn',
            '_del_point_btn',
            '_interpolation_title',
            ('_interpolation_mode', '_interpolate_btn'),
            ' '
        ]

        #### set controls ##############################################
        self._interpolation_mode.add_item("Auto", -1)
        self._interpolation_mode.add_item("Linear", 'slinear')
        self._interpolation_mode.add_item("Quadratic", 'quadratic')
        self._interpolation_mode.add_item("Cubic", 'cubic')

    ######################################################################
    ### FUNCTIONS ########################################################
    ######################################################################

    def get_velocity(self, index):
        p1 = self.get_position(index)
        p2 = self.get_position(index-1)
        if p1 is None or p2 is None: return None
        return p2[0]-p1[0], p2[1]-p1[1]

    def get_acceleration(self, index):
        v1 = self.get_velocity(index)
        v2 = self.get_velocity(index-1)
        if v1 is None or v2 is None: return None
        return v2[0]-v1[0], v2[1]-v1[1]

    def get_position_x_value(self, index):
        v = self.get_position(index)
        return v[0] if v is not None else None

    def get_position_y_value(self, index):
        v = self.get_position(index)
        return v[1] if v is not None else None

    def get_velocity_x_value(self, index):
        v = self.get_velocity(index)
        return v[0] if v is not None else None

    def get_velocity_y_value(self, index):
        v = self.get_velocity(index)
        return v[1] if v is not None else None

    def get_velocity_absolute_value(self, index):
        v = self.get_velocity(index)
        return math.sqrt(v[1]**2+v[0]**2) if v is not None else None

    def get_acceleration_x_value(self, index):
        v = self.get_acceleration(index)
        return v[0] if v is not None else None

    def get_acceleration_y_value(self, index):
        v = self.get_acceleration(index)
        return v[1] if v is not None else None

    def get_acceleration_absolute_value(self, index):
        v = self.get_acceleration(index)
        return math.sqrt(v[1]**2+v[0]**2) if v is not None else None
        

    ######################################################################
    ### AUX FUNCTIONS ####################################################
    ######################################################################

    def create_popupmenu_actions(self):
        self.tree.add_popup_menu_option(
            label='Duplicate', 
            function_action=self.clone_path, 
            item=self.treenode, icon=conf.ANNOTATOR_ICON_DUPLICATE
        )

        self.tree.add_popup_menu_option(
            label='Remove', 
            function_action=self.__remove_path_dataset, 
            item=self.treenode, icon=conf.ANNOTATOR_ICON_DELETE
        )
        
    def create_tree_nodes(self):
        self.treenode = self.tree.create_child(self.name, icon=conf.ANNOTATOR_ICON_PATH, parent=self.parent_treenode )
        self.treenode.win = self
        self.create_popupmenu_actions()

        self.create_group_node('position',      icon=conf.ANNOTATOR_ICON_POSITION)
        self.create_data_node('position > x',   icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('position > y',   icon=conf.ANNOTATOR_ICON_Y)

        self.create_group_node('velocity',          icon=conf.ANNOTATOR_ICON_VELOCITY)
        self.create_data_node('velocity > x',       icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('velocity > y',       icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('velocity > absolute', icon=conf.ANNOTATOR_ICON_INFO)

        self.create_group_node('acceleration',          icon=conf.ANNOTATOR_ICON_ACCELERATION)
        self.create_data_node('acceleration > x',       icon=conf.ANNOTATOR_ICON_X)
        self.create_data_node('acceleration > y',       icon=conf.ANNOTATOR_ICON_Y)
        self.create_data_node('acceleration > absolute', icon=conf.ANNOTATOR_ICON_INFO)




    ######################################################################
    ### GUI EVENTS #######################################################
    ######################################################################

    def __del_point_btn_event(self):
        video_index = self.mainwindow._player.video_index-1
        if video_index<0:return

        self.set_position(video_index, None, None)
        try:
            self._sel_pts.remove(video_index)
            self._interpolate_btn.hide()
            self._interpolation_mode.hide()
            self._interpolation_title.hide()
            self._del_path_btn.hide()
            self._tmp_points = []
        except ValueError:
            self.calculate_tmp_interpolation()
        
        self.mainwindow._player.refresh()

        if self.visible:
            if len(self._sel_pts)==2:
                self._del_path_btn.show()
            else:
                self._del_path_btn.hide()

    def __sel_pto_btn_event(self):
        video_index = self.mainwindow._player.video_index-1
        if video_index<0:return 
        
        position = self[video_index]
        if position is None: return

        if video_index in self._sel_pts:
            self._sel_pts.remove(video_index)
        else:
            self._sel_pts.append(video_index)
            self._sel_pts = sorted(self._sel_pts)

        if self.visible:
            #store a temporary path for interpolation visualization
            if len(self._sel_pts) >= 2:
                #########################################################
                #In case 2 frames are selected, draw the temporary path##
                #########################################################
                if self.calculate_tmp_interpolation():
                    self._interpolate_btn.show()
                    self._interpolation_mode.show()
                    self._interpolation_title.show()

                    if len(self._sel_pts)==2:
                        self._del_path_btn.show()
                    else:
                        self._del_path_btn.hide()
                #########################################################
            else:
                self._interpolate_btn.hide()
                self._interpolation_mode.hide()
                self._interpolation_title.hide()
                self._del_path_btn.hide()
                self._tmp_points = []

        self.mainwindow._player.refresh()


    def __remove_path_dataset(self):
        item = self.tree.selected_item
        if item is not None: self.object2d -= item.win


    def __referencial_pt_changed_event(self):
        try:
            self._referencial = eval(self._referencial_pt.value)
        except:
            self._referencial = None

    def __pick_a_color_event(self):
        color = QColor(self.color[2], self.color[1], self.color[0])
        color = QColorDialog.getColor(color, parent = self, title = 'Pick a color for the path')
        self.color = color.blue(), color.green(), color.red()
        self.mainwindow._player.refresh()

    ####################################################################

    def __interpolate_btn_event(self): 
        #store a temporary path for interpolation visualization
        if len(self._sel_pts) >= 2:
            mode = None if self._interpolation_mode.value=='Auto' else self._interpolation_mode.value        #store a temporary path for interpolation visualization
            self.interpolate_range( self._sel_pts[0], self._sel_pts[-1], interpolation_mode=mode)
            self.mainwindow._player.refresh()
        else:
            QMessageBox.about(self, "Error", "You need to select 2 frames.")

    def __interpolation_mode_changed_event(self): 
        #store a temporary path for interpolation visualization
        if len(self._sel_pts) >= 2:
            if self.calculate_tmp_interpolation():
                self.mainwindow._player.refresh()

    def __del_path_btn_event(self): #store a temporary path for interpolation visualization
        if len(self._sel_pts) == 2:
            reply = QMessageBox.question(self, 'Confirmation',
                                               "Are you sure you want to delete this path?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes: #store a temporary path for interpolation visualization
                start, end = self._sel_pts[0], self._sel_pts[1]
                self.delete_range(start, end)
                self.calculate_tmp_interpolation()
                self.mainwindow._player.refresh()
        else:
            QMessageBox.about(self, "Error", "You need to select 2 frames.")

    def __lin_dist(self, p1, p2): return np.linalg.norm( (p1[0]-p2[0], p1[1]-p2[1]) )

    ######################################################################
    ### VIDEO EVENTS #####################################################
    ######################################################################


    def on_click(self, event, x, y):
        if event.button== 1:
            frame_index = self.mainwindow._player.video_index-1

            if self._mark_pto_btn.checked:
                frame_index = frame_index if frame_index>=0 else 0
                self.set_position(frame_index, x, y)
                self._mark_pto_btn.checked = False
            else:
                position = self.get_position(frame_index)
                if position is not None and self.__lin_dist(position, (x,y))<10:

                    modifier = int(event.event.modifiers())

                    # If the control button is pressed will add the blob to the previous selections
                    if modifier == QtCore.Qt.ControlModifier:
                        if frame_index not in self._sel_pts: #store a temporary path for interpolation visualization
                            self._sel_pts.append(frame_index)
                            
                        else:
                            # Remove the blob in case it was selected before #store a temporary path for interpolation visualization
                            self._sel_pts.remove(frame_index)
                    else:
                        # The control key was not pressed so will select only one #store a temporary path for interpolation visualization
                        self._sel_pts =[frame_index]
                else: #store a temporary path for interpolation visualization
                    self._sel_pts =[]  # No object selected: remove previous selections #store a temporary path for interpolation visualization
                self._sel_pts = sorted(self._sel_pts)

            if self.visible:
                #store a temporary path for interpolation visualization
                if len(self._sel_pts) >= 2:
                    #########################################################
                    #In case 2 frames are selected, draw the temporary path##
                    #########################################################
                    res = self.calculate_tmp_interpolation()
                    if self.visible & res:
                        self._interpolate_btn.show()
                        self._interpolation_mode.show()
                        self._interpolation_title.show()
                        self._del_path_btn.show()
                        #self._sel_pto_btn.hide()
                    #########################################################
                else:
                    if self.visible:
                        self._interpolate_btn.hide()
                        self._interpolation_mode.hide()
                        self._interpolation_title.hide()
                        self._del_path_btn.hide()
                    self._tmp_points = []

            
            self.mainwindow._player.refresh()

    
        
    def draw(self, frame, frame_index):

        if not self.mainwindow.player.is_playing and self.visible:

            if self[frame_index] is None:
                self._del_point_btn.hide()
            else:
                self._del_point_btn.show()

        Path.draw(self, frame, frame_index)

    ######################################################################
    ### PROPERTIES #######################################################
    ######################################################################

    @property
    def mainwindow(self):    return self._object2d.mainwindow
    @property 
    def tree(self):          return self._object2d.tree
    @property 
    def video_capture(self): return self._object2d.video_capture

    @property 
    def parent_treenode(self):  return self._object2d.treenode

    @property
    def interpolation_mode(self): return None if self._interpolation_mode.value==-1 else self._interpolation_mode.value

    @property
    def mark_point_button(self):
        return self._mark_pto_btn

    @property
    def referencial(self): 
        return Path.referencial.fget(self)

    @referencial.setter
    def referencial(self, value):
        self._referencial_pt.value = str(value)[1:-1] if value else ''

    @property
    def apply_referencial(self):  
        return self._use_referencial.value

    @apply_referencial.setter
    def apply_referencial(self, value): 
        self._use_referencial.value = value

    @property
    def show_object_name(self):
        return self._show_object_name.value

    @show_object_name.setter
    def show_object_name(self, value):
        self._show_object_name.value = value

    @property
    def show_name(self):
        return self._show_name.value

    @show_name.setter
    def show_name(self, value):
        self._show_name.value = value
class UpdatePublication(BaseWidget):

    TITLE = 'Search publication'

    LAYOUT_POSITION = conf.ORQUESTRA_NEW_BIGWINDOW

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        authors = kwargs.get('authors')
        title = kwargs.get('title')
        journal_name = kwargs.get('journal_name')
        doi = kwargs.get('doi')
        pubdate = kwargs.get('pubdate')
        pubyear = kwargs.get('pubyear')

        self.pub_hash = str(
            (authors, title, journal_name, doi, pubdate, pubyear))

        text = f"""
            <table>
                <tr>
                    <th style='text-align: right' >Title</th>
                    <td style='padding:5px;padding-left:10px;' colspan='3' >{title}</th>
                <tr/>
                <tr>
                    <th style='text-align: right' >Authors</th>
                    <td style='padding:5px;padding-left:10px;' colspan='3' >{authors}</th>
                <tr/>
                <tr>
                    <th style='text-align: right' >Journal</th>
                    <td style='padding:5px;padding-left:10px;' >{journal_name}</th>
                    <th style='text-align: right' >Pub date</th>
                    <td style='padding:5px;padding-left:10px;' >{pubdate}</th>
                <tr/>
                <tr>
                    <th style='text-align: right' >Year</th>
                    <td style='padding:5px;padding-left:10px;' >{pubyear}</th>
                    <th style='text-align: right' >Doi</th>
                    <td style='padding:5px;padding-left:10px;' >{doi}</th>
                <tr/>
            </table>
        """

        self._person = ControlAutoComplete(
            'Author',
            queryset=Person.objects.all().order_by('full_name'),
            visible=False)
        self._authoralias = ControlText('Author alias', visible=False)
        self._addalias = ControlButton('Add alias',
                                       default=self.__add_author_alias_evt,
                                       visible=False)

        alias = AuthorAlias.objects.all()

        self._authors = ControlList(
            'Unknown authors',
            default=[[a] for a in authors.split(';')
                     if not alias.filter(name=a).exists()],
            horizontal_headers=['Authors alias'],
            item_selection_changed_event=self.__authors_selection_changed_evt)

        self._ignorebtn = ControlButton('Ignore this publication',
                                        css='red',
                                        default=self.__ignore_this_pub_evt,
                                        label_visible=False)
        self._info = ControlLabel(text)
        self._details = ControlEmptyWidget(parent=self,
                                           name='_details',
                                           default=PubsList(**kwargs))

        self.formset = [
            '_ignorebtn', '_info', ('_person', '_authoralias', '_addalias'),
            '_authors',
            segment('_details', css='secondary')
        ]

        if len(self._authors.value) == 0:
            self._authors.hide()

    def __authors_selection_changed_evt(self):
        if self._authors.selected_row_index >= 0:
            self._addalias.show()
            self._authoralias.show()
            self._person.show()
            self._authoralias.value = self._authors.value[
                self._authors.selected_row_index][0]
        else:
            self._addalias.hide()
            self._authoralias.hide()
            self._person.hide()

    def __add_author_alias_evt(self):

        if self._authoralias.value and self._person.value:
            a = AuthorAlias(name=self._authoralias.value,
                            person=Person.objects.get(pk=self._person.value))
            a.save()

            data = self._authors.value
            newdata = []
            for row in data:
                if row[0] == self._authoralias.value: continue
                newdata.append(row)
            self._authors.value = newdata

            self._addalias.hide()
            self._authoralias.hide()
            self._person.hide()

    def __ignore_this_pub_evt(self):

        filepath = os.path.join(settings.MEDIA_ROOT,
                                conf.APP_IMPORT_PUBLICATIONS_BLACKLIST_FILE)

        with open(filepath, 'a') as out:
            out.write(str(self.pub_hash) + '\n')

        self.close()

    @classmethod
    def has_permissions(cls, user):
        if user.is_superuser:
            return True

        return user.groups.filter(
            permissions__codename__in=['app_access_imp_pub']).exists()
Ejemplo n.º 10
0
class PubsList(PublicationsListWidget):

    UID = None

    EDITFORM_CLASS = PubForm
    LIST_FILTER = []
    USE_DETAILS_TO_EDIT = True
    LIST_ROWS_PER_PAGE = 5

    def __init__(self, *args, **kwargs):

        self.authors = kwargs.get('authors')
        self.pubtitle = kwargs.get('title')
        self.doi = kwargs.get('doi')
        self.pubdate = kwargs.get('pubdate')
        self.pubyear = kwargs.get('pubyear')
        self.journal_name = kwargs.get('journal_name')

        self._addbutton = ControlButton('Add button',
                                        label_visible=False,
                                        visible=False,
                                        default=self.__addbutton_evt)

        super().__init__(*args, **kwargs)

        self._list.filter_event = self.__list_changed_evt

        self.formset = ['_details', '_list', '_addbutton']

    def get_toolbar_buttons(self, *args, **kwargs):
        return []

    def get_queryset(self, request, qs):
        return ModelAdminWidget.get_queryset(self, request, qs)

    def __addbutton_evt(self):
        self.show_create_form()

        form = self._details.value
        form.publication_title.value = self.pubtitle
        form.publication_year.value = self.pubyear
        try:
            form.publication_publish.value = parse_date(self.pubdate)
        except:
            pass
        journals = Journal.objects.filter(
            Q(journal_name=self.journal_name)
            | Q(journalalias__name=self.journal_name))
        journal = journals[0]
        form.journal.value = journal.pk
        form.publication_doi.value = self.doi
        form.publication_authors.value = self.authors

        people = []
        authors = AuthorAlias.objects.filter(name__in=self.authors.split(';'))
        form.authors.value = [a.person.pk for a in authors]

        self._addbutton.hide()

    def __list_changed_evt(self):

        if self._list.value.count() == 0:
            self._addbutton.show()
        else:
            self._addbutton.hide()

    @classmethod
    def has_permissions(cls, user):
        if user.is_superuser:
            return True

        return user.groups.filter(
            permissions__codename__in=['app_access_imp_pub']).exists()
Ejemplo n.º 11
0
class SimpleExample1(BaseWidget):
    def __init__(self):
        super(SimpleExample1, self).__init__(' Thực Tập Cơ Sở ')

        #main menu
        self.mainmenu = [{
            'File': [{
                'Open Excel': self.__open,
                'icon': 'img/folder_open.png'
            }, '-', {
                'Import': self.__import,
                'icon': 'img/import_icon.png'
            }]
        }]

        #tkinler for messagebox
        root = tk.Tk()
        root.withdraw()

        #list
        self._list = ControlList('Danh sách')
        self._list.readonly = True

        #1.open file excel và heap sort
        self._file = ControlFile('Chọn file Excel')
        self._butheapsort = ControlButton('Heap Sort')
        self._butheapsort.icon = 'img/sort_icon.png'
        self._butheapsort.value = self.__heapsort
        self._butloadexcel = ControlButton('Load')
        self._butloadexcel.icon = 'img/load_icon.png'
        self._butloadexcel.value = self.__load
        self._butremoveloadexcel = ControlButton('Hủy bỏ')
        self._butremoveloadexcel.icon = 'img/remove_icon.png'
        self._butremoveloadexcel.value = self.__removeloadexcel

        #2.thêm thửa đất
        self._diachi = ControlText('Địa chỉ')
        self._dientich = ControlText('Diện tích')
        self._chusohuuhientai = ControlText('Chủ sở hữu hiện tại')
        self._loainha = ControlText('Loại nhà')
        self._mucdichsudung = ControlText('Mục đích Sử dụng')
        self._giatien = ControlText('Giá tiền')
        self._but1 = ControlButton('Thêm thửa đất')
        self._but1.value = self.__add
        self._but1.icon = 'img/add_icon.png'

        #3.tìm kiếm thử đất và xóa
        #tìm kiếm
        self._butsearch = ControlButton('Tìm kiếm')
        self._butsearch.icon = 'img/search_icon.png'
        self._butsearch.value = self.__search
        self._timkiem = ControlText('Tìm Kiếm')
        self._checklisttimkiem = ControlCheckBoxList('Chọn tiêu chí tìm kiếm:')
        self._checklisttimkiem.hide()
        self._buttonhideshowtimkiem = ControlButton('Hiển thị tiêu chí')
        self._buttonhideshowtimkiem.value = self._buthideshowtimkiem
        self._buttonhideshowtimkiem.icon = 'img/show.png'
        self._buthuybo = ControlButton('Hủy bỏ')
        self._buthuybo.icon = 'img/remove_icon.png'
        self._buthuybo.value = self._huybo
        #xóa
        self._textxoa = ControlText('Nhập nội dung cần xóa')
        self._butxoa = ControlButton('Xoá')
        self._butxoa.icon = 'img/delete_icon.png'
        self._butxoa.value = self.__xoa
        self._checklistxoa = ControlCheckBoxList('Chọn tiêu chí xóa:')
        self._checklistxoa.hide()
        self._buttonhideshowxoa = ControlButton('Hiển thị tiêu chí')
        self._buttonhideshowxoa.value = self._buthideshowxoa
        self._buttonhideshowxoa.icon = 'img/show.png'

        #4.xuất
        self._directory = ControlDir('Chọn chỗ xuất file excel')
        self._tenfilexuat = ControlText('Tên file xuất')
        self._butxuat = ControlButton('Xuất')
        self._butxuat.icon = 'img/export_icon.png'
        self._butxuat.value = self.__xuat

        #5.merge
        self._filemerge = ControlFile('Chọn file Excel cần merge')
        self._butimport = ControlButton('Import')
        self._butimport.icon = 'img/import2_icon.png'
        self._butimport.value = self._import
        self._butmerge = ControlButton('Gộp')
        self._butmerge.icon = 'img/merge_icon'
        self._butmerge.value = self._merge
        self._butmerge.hide()
        self._listmerge = ControlList('Danh sách import')
        self._listmerge.readonly = True
        self._buttonhideshow = ControlButton('Hiển thị tùy chọn')
        self._buttonhideshow.value = self._buthideshow
        self._buttonhideshow.hide()
        self._buttonhideshow.icon = 'img/show.png'
        self._checklist = ControlCheckBoxList(
            'Chọn tiêu chí giữ trong danh sách import:')
        self._checklist.hide()
        self._buttonremovemerge = ControlButton('Hủy bỏ')
        self._buttonremovemerge.value = self._remove
        self._buttonremovemerge.icon = 'img/remove_icon.png'
        self._buttonremovemerge.hide()

        #formset as layout
        self.formset = [{
            '1.Mở File và Heap Sort': [
                ' ', '_file', ' ',
                (' ', '_butloadexcel', '_butremoveloadexcel', '_butheapsort',
                 ' '), ' '
            ],
            '2.Thêm': [
                ' ', '_diachi', '_dientich', '_chusohuuhientai', '_loainha',
                '_mucdichsudung', '_giatien', ' ', (' ', '_but1', ' '), ' '
            ],
            '3.Tìm kiếm và Xóa': [
                ' ', '_textxoa', ' ',
                (' ', '_butxoa', '_buttonhideshowxoa', '_checklistxoa', ' '),
                ' ', '_timkiem', ' ',
                (' ', '_butsearch', '_buttonhideshowtimkiem',
                 '_checklisttimkiem', '_buthuybo', ' '), ' '
            ],
            '4.Xuất': [
                ' ', '_directory', ' ', '_tenfilexuat', ' ',
                (' ', '_butxuat', ' '), ' '
            ],
            '5.Merge danh sách': [
                '_filemerge',
                (' ', '_butimport', '_butmerge', '_buttonremovemerge',
                 '_buttonhideshow', '_checklist', ' '), '_listmerge'
            ],
        }, '', '', '_list']

#event for mainmenu

    def __open(self):
        self._file.click()

    def __import(self):
        self._filemerge.click()

#event tab 1
#event for _butremoveloadexcel

    def __removeloadexcel(self):
        if not values:
            messagebox.showwarning("Warning", "Không có thông tin cần loại bỏ")
        else:
            values.clear()
            fsqc.clear()
            self._refresh()

    #event for _butheapsort
    def __heapsort(self):
        if self._list.rows_count <= 1:
            messagebox.showwarning("Warning", "không có list để sort")
        else:
            heap_sort()
            self._refresh()

    #event for load button
    def __load(self):
        if not self._file.value:
            tk.messagebox.showwarning("Warning", "Đường dẫn trống")
        else:
            try:
                if self._file.value != '':
                    path = self._file.value
                    read(path)
                    self._list.value = [values_name]
                    n = 0
                    for i in range(int(len(values) / numberofcols[0])):
                        self._list.__add__(values[n:n + numberofcols[0]])
                        n = n + numberofcols[0]
                    if self._checklistxoa.count < 1:
                        for s in range(0, len(values_name)):
                            self._checklistxoa.__add__((values_name[s]))
                    if self._checklisttimkiem.count < 1:
                        for s in range(0, len(values_name)):
                            self._checklisttimkiem.__add__((values_name[s]))
            except:
                tk.messagebox.showwarning(
                    "Warning",
                    "Không thể đọc file khác excel hoặc đường dẫn không đúng")

#event tab 2
#event for thêm button

    def __add(self):
        var = str(self._diachi.value).strip().split(',')
        var2 = var[0].split('/')
        var3 = var2[0]
        if self._list.rows_count < 1:
            messagebox.showwarning("Warning", "Không có list để thêm vào")
        elif len(var3) == 0 \
                or (not var3[0].isdigit() and len(var3)  == 1 ) \
                or ( not var3[0:(len(var3) -1 )].isdigit() and len(var3) > 1 ) :
            messagebox.showwarning("Warning", "Địa chỉ không hợp lệ")
        elif not str(self._dientich.value).strip().isnumeric():
            messagebox.showwarning("Warning", "Diện tích không hợp lệ")
        elif not str(self._chusohuuhientai.value).strip():
            messagebox.showwarning("Warning", "Chủ sở hữu trống")
        elif not str(self._loainha.value).strip():
            messagebox.showwarning("Warning", "loại nhà trống")
        elif not str(self._mucdichsudung.value).strip():
            messagebox.showwarning("Warning", "mục đích sử dụng trống")
        elif not str(self._giatien.value).strip():
            messagebox.showwarning("Warning", "giá tiền trống")
        else:
            index = self._list.rows_count
            values.append(index)
            values.append(str(self._diachi.value))
            values.append(str(self._dientich.value))
            values.append(str(self._chusohuuhientai.value))
            values.append(str(self._loainha.value))
            values.append(str(self._mucdichsudung.value))
            values.append(str(self._giatien.value))
            if var3.isdigit():
                fsqc.append(int(var3[0:(len(var3))]))
            else:
                fsqc.append(int(var3[0:(len(var3) - 1)]))
            heap_sort()
            self._refresh()

#event tab 3
#search  :

    def __search(self):
        if self._list.rows_count <= 1:
            messagebox.showwarning("Warning", "Danh sách rỗng")
        elif not self._timkiem.value:
            messagebox.showwarning("Warning",
                                   "Vui lòng nhập nội dung tìm kiếm")
        elif self._checklisttimkiem.selected_row_index == -1:
            messagebox.showwarning("Warning", "Vui lòng chọn tiêu chí cần xóa")
            self._checklisttimkiem.show()
            self._buttonhideshowtimkiem.icon = 'img/hide_icon.png'
            self._buttonhideshowtimkiem.label = 'Ẩn tiêu chí'
        else:
            self._refresh()
            s = 1
            while s < self._list.rows_count:
                if not (str(self._timkiem.value).strip()) in str(
                        self._list.get_value(
                            self._checklisttimkiem.selected_row_index, s)):
                    self._list.__sub__(s)
                    s = s - 1
                s = s + 1

    def _huybo(self):
        self._refresh()

    def _buthideshowtimkiem(self):
        if not values_name:
            tk.messagebox.showwarning("Warning",
                                      "Không có list để chọn tiêu chí")
        elif str(self._buttonhideshowtimkiem.label) == 'Ẩn tiêu chí':
            self._checklisttimkiem.hide()
            self._buttonhideshowtimkiem.icon = 'img/show.png'
            self._buttonhideshowtimkiem.label = 'Hiển thị tiêu chí'
        elif str(self._buttonhideshowtimkiem.label) == 'Hiển thị tiêu chí':
            self._checklisttimkiem.show()
            self._buttonhideshowtimkiem.icon = 'img/hide_icon.png'
            self._buttonhideshowtimkiem.label = 'Ẩn tiêu chí'

    #delete
    def __xoa(self):
        if self._list.rows_count <= 1:
            messagebox.showwarning("Warning", "Danh sách rỗng")
        elif not self._textxoa.value:
            messagebox.showwarning("Warning", "Vui lòng nhập nội dung cần xóa")
        elif self._checklistxoa.selected_row_index == -1:
            messagebox.showwarning("Warning", "Vui lòng chọn tiêu chí cần xóa")
            self._checklistxoa.show()
            self._buttonhideshowxoa.icon = 'img/hide_icon.png'
            self._buttonhideshowxoa.label = 'Ẩn tiêu chí'
        else:
            result = messagebox.askokcancel('Warning', 'Bạn có chắc muốn xóa?')
            startvaluescount = len(values)
            if result == 1:
                s = 1
                while s < len(values):
                    if (str(self._textxoa.value).strip()) in str(
                            values[s + self._checklistxoa.selected_row_index -
                                   1]):
                        del fsqc[s // 7]
                        del values[(s - 1):(s + 6)]
                        s = s - 7
                    s = s + 7
                self._refresh()
            if startvaluescount > len(values):
                messagebox.showinfo("Sucess!!", "Đã xóa dữ liệu thành công")
                self._checklistxoa.hide()
                self._buttonhideshowxoa.icon = 'img/show.png'
                self._buttonhideshowxoa.label = 'Hiển thị tiêu chí'
            else:
                messagebox.showinfo(
                    "Opps",
                    "Nội dung cần xóa không có trong cột tiêu chí trong danh sách"
                )

    def _buthideshowxoa(self):
        if not values_name:
            tk.messagebox.showwarning("Warning",
                                      "Không có list để chọn tiêu chí")
        elif str(self._buttonhideshowxoa.label) == 'Ẩn tiêu chí':
            self._checklistxoa.hide()
            self._buttonhideshowxoa.icon = 'img/show.png'
            self._buttonhideshowxoa.label = 'Hiển thị tiêu chí'
        elif str(self._buttonhideshowxoa.label) == 'Hiển thị tiêu chí':
            self._checklistxoa.show()
            self._buttonhideshowxoa.icon = 'img/hide_icon.png'
            self._buttonhideshowxoa.label = 'Ẩn tiêu chí'
#event tab 4
#event _butxuat

    def __xuat(self):
        # kiểm tra đường dẫn
        if not os.path.isdir(self._directory.value):
            messagebox.showwarning("Warning", "đường dẫn ko có")
        elif not self._tenfilexuat.value:
            messagebox.showwarning("Warning", "tên file rỗng")
        elif not values and not values_name:
            messagebox.showwarning("Warning", "không có dữ liệu để xuất")
        else:
            try:
                os.makedirs(self._tenfilexuat.value)
                os.rmdir(self._tenfilexuat.value)
                if os.path.isfile(self._directory.value + '/' +
                                  self._tenfilexuat.value + '.xls'):
                    result = messagebox.askokcancel(
                        'Warning', 'File đã tồn tại bạn có muốn ghi đè lên  ?')
                    if result == 1:
                        write(self._directory.value, self._tenfilexuat.value)
                        myfile = Path(self._directory.value + '/' +
                                      self._tenfilexuat.value + '.xls')
                        if myfile.is_file():
                            messagebox.showinfo("Sucess!!",
                                                "Đã xuất file thành công")
                else:
                    result = messagebox.askokcancel('Warning',
                                                    'Bạn có chắc muốn xuất?')
                    if result == 1:
                        write(self._directory.value, self._tenfilexuat.value)
                        myfile = Path(self._directory.value + '/' +
                                      self._tenfilexuat.value + '.xls')
                        if myfile.is_file():
                            messagebox.showinfo("Sucess!!",
                                                "Đã xuất file thành công")
            except OSError:
                messagebox.showwarning(
                    "Warning",
                    "Tên file không hợp lệ hoặc đang được mở bởi ứng dụng khác"
                )

#event tab 5
#event _butmerge

    def _merge(self):
        if self._list.rows_count < 1:
            messagebox.showwarning("Warning", "Danh sách rỗng")
        else:
            result = messagebox.askokcancel('Warning', 'Bạn có chắc muốn gộp?')
            if result == 1:
                for i in range(1, len(valuesimport), 7):
                    n = False
                    for s in range(1, len(values), 7):
                        if valuesimport[i] == values[s]:
                            f = self._checklist.checked_indexes
                            for c in range(0, len(f), 1):
                                values[s + int(f[c]) -
                                       1] = valuesimport[i + int(f[c]) - 1]
                            n = True
                    if not n:
                        fsqc.append(fsqcimport[int(i / 7)])
                        for s in range(i - 1, i + 6):
                            values.append(valuesimport[s])
                self._refresh()
                for i in range(0, self._listmerge.rows_count):
                    self._listmerge.__sub__(i)
                    for j in range(0, self._listmerge.rows_count):
                        self._listmerge.__sub__(j)
                self._clearimportdata()
                self._checklist.hide()
                self._buttonhideshow.icon = 'img/show.png'
                self._buttonhideshow.label = 'Hiển thị tùy chọn'
                self._buttonremovemerge.hide()
                self._butmerge.hide()
                self._buttonhideshow.hide()
                tk.messagebox.showinfo("Success", "Đã merge thành công")

    #event _buttonremovemerge
    def _remove(self):
        if self._listmerge.rows_count < 1:
            tk.messagebox.showwarning("Warning", "Đã xóa hết!")
        else:
            for i in range(0, self._listmerge.rows_count):
                self._listmerge.__sub__(i)
                for j in range(0, self._listmerge.rows_count):
                    self._listmerge.__sub__(j)
            self._clearimportdata()
            self._checklist.clear()
            self._buttonremovemerge.hide()
            self._buttonhideshow.hide()
            self._checklist.hide()
            self._butmerge.hide()

    #event  _buttonhideshow
    def _buthideshow(self):
        if str(self._buttonhideshow.label) == 'Ẩn tùy chọn':
            self._checklist.hide()
            self._buttonhideshow.icon = 'img/show.png'
            self._buttonhideshow.label = 'Hiển thị tùy chọn'
        elif str(self._buttonhideshow.label) == 'Hiển thị tùy chọn':
            self._checklist.show()
            self._buttonhideshow.icon = 'img/hide_icon.png'
            self._buttonhideshow.label = 'Ẩn tùy chọn'

    #event _buttonimport
    def _import(self):
        if not self._filemerge.value:
            tk.messagebox.showwarning("Warning", "Đường dẫn trống")
        else:
            path = self._filemerge.value
            try:
                importexcel(path)
                self._listmerge.value = [values_nameimport]
                n = 0
                for i in range(int(len(valuesimport) / numberofcolsimport[0])):
                    self._listmerge.__add__(
                        valuesimport[n:n + numberofcolsimport[0]])
                    n = n + numberofcolsimport[0]
                if self._checklist.count < 1:
                    for s in range(0, len(values_nameimport)):
                        self._checklist.__add__((values_nameimport[s], True))
                if self._listmerge and not self._buttonhideshow.visible:
                    if str(self._buttonhideshow.label) == 'Ẩn tùy chọn':
                        self._buttonhideshow.icon = 'img/show.png'
                        self._buttonhideshow.label = 'Hiển thị tùy chọn'
                self._buttonhideshow.show()
                self._buttonremovemerge.show()
                self._butmerge.show()
            except:
                tk.messagebox.showwarning(
                    "Warning",
                    "Không thể đọc file khác excel hoặc đường dẫn không đúng")

#reusable function

    def _refresh(self):
        for i in range(1, self._list.rows_count):
            self._list.__sub__(i)
            for j in range(1, self._list.rows_count):
                self._list.__sub__(j)
        n = 0
        for i in range(int(len(values) / numberofcols[0])):
            self._list.__add__(values[n:n + numberofcols[0]])
            n = n + numberofcols[0]
        # update STT
        for s in range(1, self._list.rows_count):
            values[(s - 1) * 7] = s
            self._list.set_value(0, s, s)

    def _clearimportdata(self):
        fsqcimport.clear()
        valuesimport.clear()
        sqcimport.clear()
        numberofcolsimport.clear()
        values_nameimport.clear()
        self._checklist.clear()
Ejemplo n.º 12
0
class RequestReimbursementForm(ModelFormWidget):
    """
    """

    TITLE = "Request Reimbursement"

    MODEL = Reimbursement

    HAS_CANCEL_BTN_ON_ADD  = False
    HAS_CANCEL_BTN_ON_EDIT = False
    CLOSE_ON_REMOVE = True

    READ_ONLY = ["created", "modified", "status_changed", 'status']

    INLINES = [ExpenseInline]

    FIELDSETS = [
        no_columns('_previous', '_submit', "_print", '_printed', '_submit2approve','_reject', '_accept', 'bank_transfer_date', '_close', style="float:right"),
        "h3:Requester Information",
        segment(
            ("person", "iban")
        ),
        "h3:Expenses",
        segment("ExpenseInline"),
        ("created", "modified", "status", "status_changed")
    ]

    # Orquestra ===============================================================
    LAYOUT_POSITION = conf.ORQUESTRA_NEW_TAB
    # =========================================================================

    def __init__(self, *args, **kwargs):

        self._previous = ControlButton(
            '<i class="ui icon paper plane outline"></i>Previous status',
            css="basic gray",
            visible = False,
            label_visible=False,
            default = self.__previous_status_evt
        )

        self._submit = ControlButton(
            '<i class="ui icon paper plane outline"></i>Submit',
            css="blue",
            visible=False,
            label_visible=False,
            default = self.__submit_2_pending_evt
        )

        self._print = ControlButton(
            '<i class="ui icon print"></i>Print',
            visible=False,
            css="basic blue",
            label_visible=False
        )

        self._printed = ControlButton(
            '<i class="ui icon paper plane outline"></i>Set printed',
            visible=False,
            css="blue",
            label_visible=False,
            default=self.__set_printed_evt
        )

        self._submit2approve = ControlButton(
            '<i class="ui icon paper plane outline"></i>Submit to approval',
            visible=False,
            css="blue",
            label_visible=False,
            default=self.__submit_2_approve_evt
        )

        self._accept = ControlButton(
            '<i class="ui icon thumbs up"></i>Accept',
            visible=False,
            css="green",
            label_visible=False,
            default = self.__accept_evt
        )

        self._reject = ControlButton(
            '<i class="ui icon thumbs down"></i>Reject',
            visible=False,
            css="red",
            label_visible=False,
            default=self.__reject_evt
        )

        self._close = ControlButton(
            '<i class="ui icon thumbs up"></i>It was paid',
            visible=False,
            css="green basic",
            default=self.__set_closed_evt
        )

        super().__init__(*args, **kwargs)

        self.person.enabled = False

        if self.model_object is None:

            user   = PyFormsMiddleware.user()
            person = user.person_user.first()

            if person is not None:
                self.person.value = person.pk
                self.iban.value = person.privateinfo.iban
            else:
                self.warning(
                    'You need a Person profile associated to your account to be able to create reimbursements.'
                )

        self.update_fields_visibility()


    def update_fields_visibility(self):
        obj = self.model_object

        if obj:
            self._print.value = 'window.open("{0}", "_blank");'.format(
                reverse("print-reimbursement-form", args=[obj.pk])
            )
            self._print.show()
        else:
            self._print.hide()

        # show submit button only when is draft
        if obj is None or obj.status != 'draft':
            self._submit.hide()

        # show print button only when the reimbursement is pending
        if obj is None:
            self._print.hide()

        if obj and self.has_update_permissions():

            if obj.status == 'draft':

                self.bank_transfer_date.hide()
                self._submit.show()
                self._previous.hide()
                self._print.hide()
                self._printed.hide()
                self._submit2approve.hide()
                self._accept.hide()
                self._reject.hide()
                self._close.hide()
                self.iban.enabled = True

            elif obj.status == 'pending':

                self.bank_transfer_date.hide()
                self._previous.show()
                self._submit.hide()
                self._print.show()
                self._printed.show()
                self._submit2approve.hide()
                self._accept.hide()
                self._reject.hide()
                self._close.hide()
                self.iban.enabled = False

            elif obj.status == 'printed':

                self.bank_transfer_date.hide()
                self._previous.show()
                self._submit.hide()
                self._print.hide()
                self._printed.hide()
                self._submit2approve.show()
                self._accept.hide()
                self._reject.hide()
                self._close.hide()
                self.iban.enabled = False

            elif obj.status == 'submitted':

                self.bank_transfer_date.hide()
                self._previous.show()
                self._submit.hide()
                self._print.hide()
                self._printed.hide()
                self._submit2approve.hide()
                self._accept.show()
                self._reject.show()
                self._close.hide()
                self.iban.enabled = False

            elif obj.status in ['rejected', 'approved']:

                self._previous.hide()
                self._submit.hide()
                self._print.hide()
                self._printed.hide()
                self._submit2approve.hide()
                self._accept.hide()
                self._reject.hide()
                self.iban.enabled = False

                if obj.status == 'approved':
                    self.bank_transfer_date.show()
                    self._close.show()
                else:
                    self.bank_transfer_date.hide()
                    self._close.hide()

            elif obj.status == 'closed':

                self.bank_transfer_date.show()
                self.bank_transfer_date.readonly = True
                self._previous.hide()
                self._submit.hide()
                self._print.hide()
                self._printed.hide()
                self._submit2approve.hide()
                self._accept.hide()
                self._reject.hide()
                self._close.hide()
                self.iban.enabled = False

        else:

            self.bank_transfer_date.hide()
            self._submit.hide()
            self._previous.hide()
            self._print.hide()
            self._printed.hide()
            self._submit2approve.hide()
            self._accept.hide()
            self._reject.hide()
            self._close.hide()
            self.iban.enabled = True

        if obj.status == 'closed':
            self.bank_transfer_date.show()
            self.bank_transfer_date.readonly = True



    def save_btn_event(self):
        super().save_btn_event()
        self.update_fields_visibility()

    def __previous_status_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.previous_status()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __set_printed_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.set_printed()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __submit_2_pending_evt(self):
        """
        Notify the users with approval responsibility about the new reimbursement
        """
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.submit_to_pending()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __submit_2_approve_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.submit_for_approval()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __accept_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.accept()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __reject_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.reject()

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()

    def __set_closed_evt(self):
        if not self.has_update_permissions():
            raise Exception('No permission')

        obj = self.model_object
        obj.bank_transfer_date = self.bank_transfer_date.value
        obj.set_closed() # this function will save the object

        self.show_edit_form(self.object_pk)
        self.update_fields_visibility()


    def get_readonly(self, default):
        res  = super().get_readonly(default)
        obj  = self.model_object

        if obj and obj.status in ['rejected', 'approved']:
            return res + ['status']

        if obj and obj.has_approve_permissions(PyFormsMiddleware.user()):
            return res
        else:
            return res + ['status']


    def update_object_fields(self, obj):
        """
        Update the created by field.
        :param Reimbursement obj:
        :return: Return the updated reimbursement object.
        """
        obj = super().update_object_fields(obj)

        if obj.pk is None:
            obj.created_by = PyFormsMiddleware.user()

        return obj

    @property
    def title(self):
        obj = self.model_object
        if obj:
            name = obj.requester_name
            total = obj.total
            return f"({obj.pk}) {obj.person} ({obj.total})"
        else:
            return super().title
Ejemplo n.º 13
0
class AccessRequestFormWidget(ModelFormWidget):

    TITLE = "Access request"
    MODEL = AccessRequest

    LAYOUT_POSITION = conf.ORQUESTRA_NEW_TAB

    READ_ONLY = [
        'resource', 'requested_by', 'requested_on', 'reason', 'closed_by',
        'closed_on'
    ]

    FIELDSETS = [
        no_columns('resource', 'requested_by', 'requested_on'), 'reason',
        'comment',
        no_columns('_until', '_acceptbtn', '_rejectbtn', 'closed_by',
                   'closed_on')
    ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.resource.field_css = 'eleven wide'

        self._until = ControlDateTime('Access until', visible=False)
        self._acceptbtn = ControlButton('Accept',
                                        default=self.__accept_evt,
                                        css='basic green',
                                        visible=False)
        self._rejectbtn = ControlButton('Reject',
                                        default=self.__reject_evt,
                                        css='red',
                                        visible=False)

        req = self.model_object
        if req.is_approved() is None:
            self._acceptbtn.show()
            self._rejectbtn.show()
            self._until.show()
            self.closed_by.hide()
            self.closed_on.hide()
        else:
            self._until.hide()
            self.closed_by.show()
            self.closed_on.show()
            self.comment.readonly = True

    def has_remove_permissions(self):
        return False

    def has_add_permissions(self):
        return False

    def has_update_permissions(self):
        return False

    def __open_access_evt(self):
        pass

    def __accept_evt(self):
        req = self.model_object
        req.comment = self.comment.value
        req.accept(PyFormsMiddleware.user(),
                   until=self._until.value,
                   comment=self.comment.value)
        self._acceptbtn.hide()
        self._rejectbtn.hide()
        self._until.hide()
        self.success('The access request was accepted successfully.')
        self.closed_by.show()
        self.closed_on.show()
        self.closed_by.value = str(req.closed_by)
        self.closed_on.value = req.closed_on
        self.comment.readonly = True

    def __reject_evt(self):
        req = self.model_object
        req.comment = self.comment.value
        req.reject(PyFormsMiddleware.user(), comment=self.comment.value)

        self._acceptbtn.hide()
        self._rejectbtn.hide()
        self._until.hide()

        self.alert('The access request was rejected!')
        self.closed_by.show()
        self.closed_on.show()
        self.closed_by.value = str(req.closed_by)
        self.closed_on.value = req.closed_on
        self.comment.readonly = True

    @property
    def title(self):
        obj = self.model_object
        if obj is None:
            return ModelFormWidget.title.fget(self)
        else:
            return str(obj)

    @title.setter
    def title(self, value):
        ModelFormWidget.title.fset(self, value)