Esempio n. 1
0
class NotificationsWidget(Notifications, BaseWidget):
    def __init__(self, user = None, connection = None):
        Notifications.__init__(self)
        BaseWidget.__init__(self)
        self._user = user
        self._connection = connection
        self._refresh_button = ControlToolButton('Refresh', maxheight= 50, maxwidth= 100)

        self._notifCache=None
        self._notifList = ControlList('Notifications',
            select_entire_row = True)
        self._notifList.readonly = True
        self._notifList.cell_double_clicked_event = self.__onDouble
        #self._notifList.item_selection_changed_event = self.__softSelect
        self._notifList.horizontal_headers = [ 'Timestamp', 'Symbol', 'Price', 'Message']
        self._notifList.add_popup_menu_option('Edit', function_action= self.__popEdit)
        self._notifList.add_popup_menu_option('Delete', function_action= self.__deleteNotif)

        self._plusBtn = ControlButton('New Notification')
        self._plusBtn.value= self.__addNotifBtnAction
        if self._user!=None and self._connection!=None:
            self._refresh_button.value= self._refresh
            self._retreive_existing()



    def _refresh(self):
        self._notifList.clear()
        self._retreive_existing()
        if self.parent!=None: self.parent.persist_login()

    def _retreive_existing(self):
        try:
            pull_list = pull_notifications(self._user, self._connection)
            self._notifCache=pull_list
        except ValueError as err:
            err= ErrorWin(err)
            err.parent = self
            err.show()
            return
        if pull_list:
            for i in pull_list:
                ts = pull_list[i]['timestamp']
                datestring=datetime.fromtimestamp(ts/1e3).strftime('%Y-%m-%d %H:%M:%S')
                self._notifList.__add__([datestring, pull_list[i]['symbol'], pull_list[i]['price'], pull_list[i]['message']])


    def __addNotifBtnAction(self):
        if self.parent!=None: self.parent.persist_login()
        win = NotificationWidget(self._user, self._connection, '', '', '', '', 'new')
        win.parent = self
        win.show()



    def __rmNotifBtnAction(self):
        self.__deleteNotif(self)

    def __onDouble(self, row, column):
        if self.parent!=None: self.parent.persist_login()
        timestamp = self._notifList.get_value(0, row)
        symbol = self._notifList.get_value(1, row)
        index = self._notifList.get_value(2, row)
        message = self._notifList.get_value(3, row)
        win = NotificationWidget(self._user, self._connection, timestamp, symbol, index, message, 'view')
        win.parent = self
        win.show()

    def __popEdit(self):
        row = self._notifList.selected_row_index
        timestamp = self._notifList.get_value(0, row)
        symbol = self._notifList.get_value(1, row)
        index = self._notifList.get_value(2, row)
        message = self._notifList.get_value(3, row)
        for i in self._notifCache:
            if self._notifCache[i]['message']== message:
                key = i
                #print("popedit key found: " + key)
        win = NotificationWidget(self._user, self._connection, timestamp, symbol, index, message, "edit", key)
        win.parent = self
        win.show()


    def __softSelect(self, row, column):
        self._notifList.form.get_value(row, column)

    def __deleteNotif(self):
        row = self._notifList.selected_row_index
        message = self._notifList.get_value(3, row)
        for i in self._notifCache:
            if self._notifCache[i]['message']== message:
                key= i
        try:
            del_notification(self._user, self._connection, key)
            self._notifList.__sub__(row)
        except ValueError as error:
            err= ErrorWin(error)
            err.parent = self
            err.show()
            return
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 BoardTaskWindow(BoardTask, BaseWidget):
    """
    Define here which fields from the board_task model should appear on the setup configuration window.

    The model fields shall be defined as UI components like text fields, buttons, combo boxes, etc.

    You may also assign actions to these components.

    .. seealso::
        This class heavy relies on the corresponding API module.

        :py:class:`pybpodgui_api.models.setup.board_task.BoardTask`

    **Properties**

        states
            A list of task states associated with this BoardTask. States are defined on the task code.

        events
            A list of task events associated with this BoardTask. Events are defined on the task code.

        variables
            A list of task variables associated with this BoardTask. Variables are defined on the task code.

    **Private attributes**

        _states
            :class:`pyforms.controls.ControlList`

            UI list to show BoardTask states.

        _events
            :class:`pyforms.controls.ControlList`

            UI list to show BoardTask events.

        _vars
            :class:`pyforms.controls.ControlList`

            UI list to show BoardTask variables.

        _sync_btn
            :class:`pyforms.controls.ControlButton`

            Button to sync variables with board. Pressing the button fires the event :meth:`BoardTaskWindow.sync_variables`.

        _load_btn
            :class:`pyforms.controls.ControlButton`

            Button to read task variables from board. Pressing the button fires the event :meth:`BoardTaskWindow._BoardTaskWindow__load_task_details`.

        _formset
            Describe window fields organization to PyForms.

    **Methods**

    """
    def __init__(self, setup):
        BaseWidget.__init__(self,
                            "Variables config for {0}".format(setup.name))

        self._var_is_being_added = False

        self._updvars = ControlCheckBox('Update variables')
        self._vars = ControlList('Variables',
                                 add_function=self.__add_variable,
                                 remove_function=self.__remove_variable)

        BoardTask.__init__(self, setup)

        self._vars.horizontal_headers = ['NAME', 'TYPE', 'VALUE']
        self._vars.data_changed_event = self.__varslist_data_changed_evt

        self._formset = ['_updvars', '_vars']

        self._variable_rule = re.compile('^[A-Z0-9\_]+$')

    @property
    def update_variables(self):
        return self._updvars.value

    @update_variables.setter
    def update_variables(self, value):
        self._updvars.value = value

    def create_variable(self, name=None, value=None, datatype='string'):
        return TaskVariableWindow(self, name, value, datatype)

    def __varslist_data_changed_evt(self, row, col, item):

        # only verify if the list is being edited
        if self._var_is_being_added is True:
            return

        if col == 0 and item is not None:
            if not (self._variable_rule.match(item)
                    and item.startswith('VAR_')):
                self.critical(
                    "The name of the variable should start with VAR_, should be alphanumeric and upper case.",
                    "Error")

                self._vars.set_value(col, row,
                                     'VAR_{0}'.format(self._vars.rows_count))

        elif col == 2:
            datatype_combo = self._vars.get_value(1, row)
            datatype = datatype_combo.value if datatype_combo else None
            if datatype == 'number' and isinstance(
                    item, str) and not item.isnumeric():
                self.message("The value should be numeric.", "Error")
                self._vars.set_value(col, row, '0')

    def __add_variable(self):
        self._var_is_being_added = True
        var = self.create_variable('VAR_{0}'.format(self._vars.rows_count),
                                   '0')
        self._var_is_being_added = False

    def __remove_variable(self):
        if self._vars.selected_row_index is not None:
            var = self.variables[self._vars.selected_row_index]
            self.variables.remove(var)
            self._vars -= -1

    def before_close(self):
        return False
class AdminWidget(BaseWidget):
    def __init__(self, user=None, connection=None):
        BaseWidget.__init__(self)
        self._admin = user
        self._connection = connection
        self._add_user_button = ControlButton('New User')
        self._refresh_button = ControlButton('Refresh List')
        self._add_user_button.value= self.__add_User_btnAction
        self._refresh_button.value= self.__refresh
        self._userList = ControlList('Users',select_entire_row=True)
        self._userList.readonly=True
        self._userList.cell_double_clicked_event = self.__onSelect
        self._userList.horizontal_headers=['Admin', 'Name', 'Email']
        self._userList.add_popup_menu_option('Toggle Admin Status', function_action=self.__admin_power)
        self._userList.add_popup_menu_option('Edit', function_action=self.__popEdit)
        if self._admin!=None and self._connection!=None:
            self.__retreive_users()


    def __refresh(self):
        self._userList.clear()
        self.__retreive_users()
        if self.parent!=None: self.parent.persist_login()

    def __retreive_users(self):
        try:
            self._user_pull= pull_users(self._admin, self._connection)
        except ValueError as err:
            err=ErrorWin(err)
            err.parent=self
            err.show()
            return
        if self._user_pull!=None:
            admins = self._connection['Database'].child('admins').shallow().get(self._admin['idToken'])
            for user in self._user_pull:
                check = False
                if user in admins.val():
                    check = True
                self._userList.__add__([check, self._user_pull[user]['name'], self._user_pull[user]['email']])

    def __onSelect(self, row, column):
        if self.parent!=None: self.parent.persist_login()
        name = self._userList.get_value(1, row)
        email  = self._userList.get_value(2, row)
        for i in self._user_pull:
            if self._user_pull[i]['email'] == email:
                uid = i
                try:
                    services = self._user_pull[i]['services']
                except:
                    services = {"notifications" : False, "analysis": False, "newsletter" : False}
        win = UserWidget(self._admin, self._connection, 'edit', uid, email, name, services)
        win.parent = self
        win.show()

    def _refresh(self):
        self._userList.clear()
        self._user_pull= pull_users(self._admin, self._connection)
        if self._user_pull!=None:
            for user in self._user_pull:
                self._userList.__add__([self._user_pull[user]['name'], self._user_pull[user]['email']])

    def __popEdit(self):
        row = self._userList.selected_row_index
        name = self._userList.get_value(1, row)
        email  = self._userList.get_value(2, row)
        print(email)
        for i in self._user_pull:
            if self._user_pull[i]['email'] == email:
                uid = i
                try:
                    services = self._user_pull[i]['services']
                except:
                    services = {"notifications" : False, "analysis": False, "newsletter" : False}
        win = UserWidget(self._admin, self._connection,'edit', uid, email, name, services)
        win.parent = self
        win.show()

    def __add_User_btnAction(self):
        if self.parent!=None: self.parent.persist_login()
        win = UserWidget(self._admin, self._connection, 'new')
        win.parent = self
        win.show()
    def _add_User(self, user):
        pass

    def _update_user(self, account):
        self._connection['Database'].child("users").child(account._uid).update({"name": account.name, "email": account.email, "services": account.services})

    def __admin_power(self):
        if self.parent!=None: self.parent.persist_login()
        row = self._userList.selected_row_index
        email  = self._userList.get_value(2, row)
        for i in self._user_pull:
            if self._user_pull[i]['email'] == email:
                self._selected_uid = i
        if self._selected_uid == self._admin['localId']:
            err = ErrorWin('Action not allowed - Cannot remove self as admin.')
            err.parent= self
            err.show()
            return
        if self._userList.get_value(0, row)== 'true':#already admin
            conf= ConfirmWin('Are you sure you want to remove this admin?', self._userList.get_value(1, row))
            conf.parent = self
            conf.show()
            return
        else:
            conf= ConfirmWin('Are you sure you want to make this account admin?', self._userList.get_value(1, row))
            conf.parent = self
            conf.show()
            return

    def _admin_toggle(self):
        toggle_admin(self._admin, self._connection, self._selected_uid)
        self._selected_uid=''
        self.__refresh()
Esempio n. 5
0
class UserWidget(User, BaseWidget):
    def __init__(self,
                 admin=None,
                 connection=None,
                 flag='',
                 uid='',
                 email='',
                 name='',
                 services={}):
        super(UserWidget, self).__init__(uid, email, name, services)
        BaseWidget.__init__(self, 'User')
        self._admin = admin
        self._connection = connection
        self._flag = flag
        self.changes = []  #0 is name change, 1 is services change
        if flag == 'edit':
            self._editBtn = ControlButton('Edit')
            self._editBtn.value = self._edit
        elif flag == 'new':
            self._editBtn = ControlButton('Save')
            self._editBtn.value = self._save
        else:
            self._closeBtn = ControlButton('Close')
            self._closeBtn.value = self._close

        if uid != '':
            self._uid_field = ControlText('User_Key')
            self._uid_field.value = uid
        self._email_field = ControlText('Email')
        self._email_field.readonly = True
        if email != '':
            self._email_field.value = email

        self._name_field = ControlText('Name')
        self._name_field.readonly = True
        if name != '':
            self._name_field.value = name

        self._services = services
        self._services_field = ControlList('Services')
        self._services_field.readonly = True
        self._services_field.horizontal_headers = ['Service', 'Value']
        #self._services_field.cell_double_clicked_event = None
        if services != {}:
            for i in services:
                self._services_field.__add__([i, services[i]])

    def _edit(self):
        self._editBtn.label = 'Save'
        self._editBtn.value = self._save
        self._email_field.readonly = False
        self._name_field.readonly = False
        self._services_field.readonly = False
        self._services_field.cell_double_clicked_event = self._toggle

    def _save(self):
        if self.parent != None:
            self.name = self._name_field.value
            self.email = self._email_field.value
            self.services = self._services
            self.uid = self._uid_field.value
            if self._flag == 'edit':
                self.parent._update_user(self)
            elif self._flag == 'new':
                self.parent._add_User(self)
        self._close()

    def _toggle(self, row, column):
        val = self._services_field.get_value(column, row)
        if val == True:
            self._services_field.set_value(column, row, False)
            self._services[self._services_field.get_value(0, row)] = False
        else:
            self._services_field.set_value(column, row, True)
            self._services[self._services_field.get_value(0, row)] = True

    def _close(self):
        close_win(self)
Esempio n. 6
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()