Пример #1
0
class menuFile(Menu):
    def __init__(self, parent=None, values={}, position={}):
        self.menuFile = Menu(parent)

        self.state = dict()
        self.state["visible"] = True
        self.state["rendered"] = False

        self.values = values
        self.position = position

        self.createWidgets()

    def createWidgets(self):
        self.menuFile.add_command(label='New', command=self.newfile)
        self.menuFile.add_command(label='Open...', command=self.openfile)
        self.menuFile.add_command(label='Close', command=self.closefile)

    def newfile(self):
        print("new file")

    def openfile():
        fname = askopenfilename(filetypes=(("HDF5 files", "*.h5"),
                                           ("All files", "*.*"), ("jpeg files",
                                                                  "*.jpg")))
        if fname:
            try:
                print(fname)
            except:  # <- naked except is a bad idea
                showerror("Open Source File",
                          "Failed to read file\n'%s'" % fname)
        else:
            print("bad file")
        contents = self.readFile(fname)

    def closefile(self):
        print("close file")

    def getObject(self):
        return self.menuFile

    def set_state(self, state):
        self.state = state

    def get_state(self):
        return self.state

    def destroy(self):
        self.menuFile.destroy()
Пример #2
0
class MenuGui:

    def __init__(self, main_controller, window):
        self.__window = window
        self.__main_controller = main_controller
        self.__menu = None

    def show(self):
        if self.__menu is None:
            self.__menu = Menu(self.__window)
            self.__menu.add_command(label="save", command=self.__save)
            self.__menu.add_command(label="back to main menu", command=self.__back)
            self.__window.config(menu=self.__menu)


    def remove(self):
        if self.__menu is not None:
            self.__menu.destroy()
            self.__menu = None

    def disable(self):

        for i in range(3):
            self.__menu.entryconfig(i, state="disabled")

    def enable(self):
        for i in range(3):
            self.__menu.entryconfig(i, state="normal")



    def __save(self):
        self.__main_controller.show_save_menu()

    def __back(self):
        self.__main_controller.show_main_menu()
Пример #3
0
class Dashboard:
    def __init__(self, master, username, role, token):
        # Frame.__init__(self, master)
        self.preferences_name = StringVar()
        self.contract_type = BooleanVar()
        self.requesting_department = StringVar()
        self.token = token
        self.accesses = ROLES_MAPPER[role]
        self.accesses_mapped = list()
        for bool_value in self.accesses:
            self.accesses_mapped.append(NORMAL if bool_value else DISABLED)
        self.master = master
        self.menu_bar = Menu(self.master)
        self.init_ui(self.menu_bar)
        self.cav = Canvas(master,
                          width=master.winfo_width(),
                          height=master.winfo_height() / 15,
                          bg="white")
        self.cav.create_text(.99 * master.winfo_width(),
                             int(master.winfo_height() / 30),
                             text="Logged as {}".format(username),
                             anchor=E,
                             font="Helvetica 10 bold")
        button1 = Button(self.cav,
                         text="Disconnect",
                         command=self.deconnect,
                         anchor=W,
                         bd=0)
        button1.configure(width=15,
                          background="white",
                          relief=FLAT,
                          height=int(master.winfo_height() / 30))
        button1.pack()
        self.cav.create_window(20,
                               int(master.winfo_height() / 30),
                               anchor=W,
                               window=button1)
        self.cav.pack()
        self.additional_fr = Frame(self.master)
        self.error_response = str()
        self.status_response = str()
        self.priority = StringVar()

    def deconnect(self):
        self.cav.destroy()
        self.menu_bar.destroy()
        self.additional_fr.destroy()
        from front.login import LoginPage
        _ = LoginPage(master=self.master)

    def init_ui(self, menu_bar):
        event_request_menu = Menu(menu_bar)
        event_request_menu.add_command(label="Create",
                                       state=self.accesses_mapped[0],
                                       command=self.create_event_request)
        event_request_menu.add_command(label="Retrieve & more",
                                       state=self.accesses_mapped[1],
                                       command=self.retrieve_event_request_ui)
        menu_bar.add_cascade(menu=event_request_menu, label="Event Creation")

        event_application = Menu(menu_bar)
        event_application.add_command(label="Create",
                                      state=self.accesses_mapped[2],
                                      command=self.create_application)
        event_application.add_command(label="Retrieve & more",
                                      state=self.accesses_mapped[3],
                                      command=self.retrieve_application_ui)
        menu_bar.add_cascade(menu=event_application, label="Application")

        event_tasks = Menu(menu_bar)
        event_tasks.add_command(label="Create",
                                state=self.accesses_mapped[4],
                                command=self.task_request)
        event_tasks.add_command(label="Retrieve & more",
                                state=self.accesses_mapped[5],
                                command=self.retrieve_task_ui)
        menu_bar.add_cascade(menu=event_tasks, label="Tasks")

        human_resource_request = Menu(menu_bar)
        human_resource_request.add_command(label="Create",
                                           state=self.accesses_mapped[6],
                                           command=self.hr_request)
        human_resource_request.add_command(label="Retrieve & more",
                                           state=self.accesses_mapped[7],
                                           command=self.retrieve_hr_ui)
        menu_bar.add_cascade(menu=human_resource_request, label="HR")

        financial_request = Menu(menu_bar)
        financial_request.add_command(label="Create",
                                      state=self.accesses_mapped[8],
                                      command=self.fm_request)
        financial_request.add_command(label="Retrieve & more",
                                      state=self.accesses_mapped[9],
                                      command=self.retrieve_fm_ui)
        menu_bar.add_cascade(menu=financial_request,
                             label="Financial Requests")

        self.master.config(menu=menu_bar)

    def create_event_request(self):
        token = self.token
        update_frame(self.additional_fr)
        sub_frame = Frame(self.additional_fr)
        sub_frame.grid(row=0, column=0)
        label_record_number = Label(sub_frame, text="Record Number (Client)")
        label_client_name = Label(sub_frame, text="Client Name")
        label_event_type = Label(sub_frame, text="Event Type")
        label_from_date = Label(sub_frame, text="From Date")
        label_to_date = Label(sub_frame, text="To Date")
        label_number_attendees = Label(sub_frame,
                                       text="Expected number of attendees")
        label_excepted_budget = Label(sub_frame, text="Expected Budget (SEK)")

        entry_number_attendees = Entry(sub_frame)
        entry_expected_budget = Entry(sub_frame)
        preferences_labelframe = LabelFrame(sub_frame,
                                            text='Preferences',
                                            relief=GROOVE,
                                            bd=2)
        preferences_name = self.preferences_name
        entry_to_date = Entry(sub_frame)
        entry_from_date = Entry(sub_frame)
        entry_event_type = Entry(sub_frame)
        entry_client_name = Entry(sub_frame)
        entry_record_number = Entry(sub_frame)
        entry_from_date.insert(END, "yyyy/mm/dd")
        entry_to_date.insert(END, "yyyy/mm/dd")
        button_submit = Button(sub_frame, text="Submit", width=10, height=1)
        label_error = Label(sub_frame,
                            text="",
                            fg="red",
                            font="Helvetica 9 bold")

        Radiobutton(preferences_labelframe,
                    variable=preferences_name,
                    value="decorations",
                    text="Decoration").grid(row=1, column=0, pady=20)
        Radiobutton(preferences_labelframe,
                    variable=preferences_name,
                    value="parties",
                    text="Parties").grid(row=2, column=0, pady=10)
        Radiobutton(preferences_labelframe,
                    variable=preferences_name,
                    value="photos_filming",
                    text="Photos/filming").grid(row=3, column=0, pady=10)
        Radiobutton(preferences_labelframe,
                    variable=preferences_name,
                    value="breakfast_launch_dinner",
                    text="Breakfast, launch, dinner").grid(row=1,
                                                           column=1,
                                                           pady=20,
                                                           padx=20)
        Radiobutton(preferences_labelframe,
                    variable=preferences_name,
                    value="drinks",
                    text="Soft/hot drinks").grid(row=2,
                                                 column=1,
                                                 pady=10,
                                                 padx=20)

        label_record_number.grid(row=1, column=0, pady=20)
        entry_record_number.grid(row=1, column=1, padx=10, pady=20)
        label_client_name.grid(row=2, column=0, pady=20)
        entry_client_name.grid(row=2, column=1, padx=10, pady=20)
        label_event_type.grid(row=3, column=0, pady=20)
        entry_event_type.grid(row=3, column=1, padx=10, pady=20)
        label_from_date.grid(row=4, column=0, pady=20)
        entry_from_date.grid(row=4, column=1, pady=20, padx=10)
        label_to_date.grid(row=4, column=4, pady=20)
        entry_to_date.grid(row=4, column=5, pady=20, padx=10)
        label_number_attendees.grid(row=5, column=0, pady=20)
        entry_number_attendees.grid(row=5, column=1, padx=10, pady=20)
        preferences_labelframe.grid(row=6, column=1, pady=20)
        label_excepted_budget.grid(row=7, column=0, pady=20)
        entry_expected_budget.grid(row=7, column=1, pady=20, padx=10)
        button_submit.grid(row=8, column=1, pady=20)
        label_error.grid(row=8, column=2)

        def send_form(*args):
            body = {
                "record_number": entry_record_number.get(),
                "client_name": entry_client_name.get(),
                "event_type": entry_event_type.get(),
                "from_date": entry_from_date.get(),
                "to_date": entry_to_date.get(),
                "expected_number_attendees": entry_number_attendees.get(),
                "preferences": preferences_name.get()
            }
            print(body)
            header = {'Authorization': 'Bearer {}'.format(token)}
            http_request.request("POST",
                                 "/event_creation/",
                                 headers=header,
                                 body=json.dumps(body))
            response = http_request.getresponse()
            if response.status > 200:
                sub_frame.config(highlightcolor="red",
                                 highlightbackground="red",
                                 highlightthickness=3,
                                 relief=SOLID,
                                 bd=0)
                label_error.config(text="Error click here to get details")
                sub_frame.after(3000, lambda: label_error.config(text=""))
                sub_frame.after(2000, lambda: sub_frame.config(relief=FLAT))
                try:
                    decoded_response = json.loads(response.read().decode())
                    self.error_response = decoded_response["error"]
                except (KeyError, json.decoder.JSONDecodeError):
                    self.status_response = "400 or 500"
                    self.error_response = "No information given by server, information were not properly given"
                label_error.bind("<Button-1>", self.display_error)
            else:
                self.display_validation()

        button_submit.bind("<Button-1>", send_form)
        self.additional_fr.bind("<Return>", send_form)
        self.additional_fr.pack()

    def display_error(self, event):
        messagebox.showerror(title="Error",
                             message="Status : {}, error: {}".format(
                                 self.status_response, self.error_response))

    def display_validation(self):
        messagebox.showinfo(
            title="Success",
            message="Information received and validated by server")

    def retrieve_event_request(self):
        header = {'Authorization': 'Bearer {}'.format(self.token)}
        http_request.request("GET", "/review_event_creation/", headers=header)
        response = http_request.getresponse()
        if response.status > 200:
            try:
                decoded_response = json.loads(response.read().decode())
                self.error_response = decoded_response["error"]
            except (KeyError, json.decoder.JSONDecodeError):
                self.status_response = "400 or 500"
                self.error_response = "No information given by server, unknown error"
            self.display_error(None)
            return []
        else:
            decoded_response = json.loads(response.read().decode())
            return decoded_response["events"]

    def retrieve_event_request_ui(self):
        update_frame(self.additional_fr)
        data = self.retrieve_event_request()
        headers = [
            "event_request_id", "client_name", "event_type", "from_date",
            "to_date", "preferences", "feedback_fm"
        ]
        canvas = Canvas(self.additional_fr)
        canvas.grid(column=0, row=0)
        for i in range(len(data)):
            for j, head in enumerate(headers):
                width = 15 if j > 0 else 45
                l = Label(canvas,
                          text="{}".format(data[i][head]),
                          width=width,
                          relief=SOLID,
                          bd=2,
                          font="Helevetica 9 bold")
                l.grid(row=i + 2, column=j)
        for j, head in enumerate(headers):
            width = 15 if j > 0 else 45
            Label(canvas,
                  text="{}".format(head),
                  width=width,
                  relief=SOLID,
                  bd=2,
                  pady=30,
                  font="Helevetica 9 bold").grid(row=1, column=j)
        Label(canvas,
              text="Event Request waiting for your approval",
              font="Helvetica 13 bold",
              underline=True).grid(row=0, column=0)
        self.additional_fr.pack_propagate(0)
        self.additional_fr.pack()

    def hr_request(self):
        token = self.token
        update_frame(self.additional_fr)
        frame_hr = Frame(self.additional_fr)
        frame_hr.grid(row=0, column=0)
        label_year = Label(frame_hr, text="Year(s) (Integer)")
        label_job_title = Label(frame_hr, text="Job title")
        label_job_description = Label(frame_hr, text="Job description")

        button_submit = Button(frame_hr, text="Submit", width=10, height=1)

        requesting_department_labelframe = LabelFrame(
            frame_hr, text='Requesting Department', relief=GROOVE, bd=2)
        contract_type_labelframe = LabelFrame(frame_hr,
                                              text='Contract Type',
                                              relief=GROOVE,
                                              bd=2)
        entry_years = Entry(frame_hr)
        entry_job_title = Entry(frame_hr)
        entry_job_description = Entry(frame_hr)
        entry_job_description.grid(ipady=50, ipadx=35)

        Radiobutton(contract_type_labelframe,
                    variable=self.contract_type,
                    value=True,
                    text="Full Time").grid(row=1, column=0, pady=20)
        Radiobutton(contract_type_labelframe,
                    variable=self.contract_type,
                    value=False,
                    text="Part Time").grid(row=1, column=1, pady=10)

        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="administration",
                    text="Administration").grid(row=2, column=0, pady=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="services",
                    text="Services").grid(row=2, column=1, pady=20, padx=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="production",
                    text="Production").grid(row=3, column=0, pady=10, padx=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="financial",
                    text="Financial").grid(row=3, column=1, pady=10, padx=20)

        contract_type_labelframe.grid(row=1, column=2, pady=20)
        requesting_department_labelframe.grid(row=2, column=2, pady=20)
        label_year.grid(row=3, column=1, pady=20)
        entry_years.grid(row=3, column=2, pady=20)
        label_job_title.grid(row=4, column=1, pady=20)
        entry_job_title.grid(row=4, column=2, pady=20)
        label_job_description.grid(row=5, column=1, pady=20)
        entry_job_description.grid(row=5, column=2, pady=20)
        button_submit.grid(row=6, column=1, pady=20)
        label_error = Label(frame_hr,
                            text="",
                            fg="red",
                            font="Helvetica 9 bold")
        contract_type = self.contract_type
        requesting_department = self.requesting_department

        def send_form(*args):
            body = {
                "is_full_time": contract_type.get(),
                "request_department": requesting_department.get(),
                "year_experience_min": int(entry_years.get()),
                'job_title': entry_job_title.get(),
                'job_description': entry_job_description.get()
            }
            header = {'Authorization': 'Bearer {}'.format(token)}
            http_request.request("POST",
                                 "/create_staff_request/",
                                 headers=header,
                                 body=json.dumps(body))
            response = http_request.getresponse()
            if response.status > 200:
                frame_hr.config(highlightcolor="red",
                                highlightbackground="red",
                                highlightthickness=3,
                                relief=SOLID,
                                bd=0)
                label_error.config(text="Error click here to get details")
                frame_hr.after(3000, lambda: label_error.config(text=""))
                frame_hr.after(2000, lambda: frame_hr.config(relief=FLAT))
                try:
                    decoded_response = json.loads(response.read().decode())
                    self.error_response = decoded_response["error"]
                except (KeyError, json.decoder.JSONDecodeError):
                    self.status_response = "400 or 500"
                    self.error_response = "No information given by server, information were not properly given"
                label_error.bind("<Button-1>", self.display_error)
            else:
                self.display_validation()

        button_submit.bind("<Button-1>", send_form)
        # self.additional_fr.bind("<Return>", self.send_form)
        frame_hr.bind("<Return>", send_form)
        self.additional_fr.pack()

    def fm_request(self):
        token = self.token
        update_frame(self.additional_fr)
        frame_hr = Frame(self.additional_fr)
        frame_hr.grid(row=0, column=0)
        label_project_reference = Label(frame_hr, text="Project Reference")
        label_required_amount = Label(frame_hr, text="Required Amount (SEK)")
        label_reason = Label(frame_hr, text="Reason")

        button_submit = Button(frame_hr, text="Submit", width=10, height=1)

        requesting_department_labelframe = LabelFrame(
            frame_hr, text='Requesting Department', relief=GROOVE, bd=2)
        entry_project_reference = Entry(frame_hr)
        entry_required_amount = Entry(frame_hr)
        entry_reason = Text(frame_hr, height=20, width=10)

        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="administration",
                    text="Administration").grid(row=2, column=0, pady=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="services",
                    text="Services").grid(row=2, column=1, pady=20, padx=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="production",
                    text="Production").grid(row=3, column=0, pady=10, padx=20)
        Radiobutton(requesting_department_labelframe,
                    variable=self.requesting_department,
                    value="financial",
                    text="Financial").grid(row=3, column=1, pady=10, padx=20)

        requesting_department_labelframe.grid(row=1, column=2, pady=20)
        label_project_reference.grid(row=3, column=1, pady=20)
        entry_project_reference.grid(row=3, column=2, pady=20)
        label_required_amount.grid(row=4, column=1, pady=20)
        entry_required_amount.grid(row=4, column=2, pady=20)
        label_reason.grid(row=5, column=1, pady=20)
        entry_reason.grid(row=5, column=2, pady=20, ipady=60, ipadx=35)

        button_submit.grid(row=6, column=1, pady=20)
        label_error = Label(frame_hr,
                            text="",
                            fg="red",
                            font="Helvetica 9 bold")
        requesting_department = self.requesting_department

        def send_form(*args):
            body = {
                "request_department": requesting_department.get(),
                "project_reference": entry_project_reference.get(),
                'required_amount': entry_required_amount.get(),
                'reason': entry_reason.get()
            }
            header = {'Authorization': 'Bearer {}'.format(token)}
            http_request.request("POST",
                                 "/create_financial_request/",
                                 headers=header,
                                 body=json.dumps(body))
            response = http_request.getresponse()
            if response.status > 200:
                frame_hr.config(highlightcolor="red",
                                highlightbackground="red",
                                highlightthickness=3,
                                relief=SOLID,
                                bd=0)
                label_error.config(text="Error click here to get details")
                frame_hr.after(3000, lambda: label_error.config(text=""))
                frame_hr.after(2000, lambda: frame_hr.config(relief=FLAT))
                try:
                    decoded_response = json.loads(response.read().decode())
                    self.error_response = decoded_response["error"]
                except (KeyError, json.decoder.JSONDecodeError):
                    self.status_response = "400 or 500"
                    self.error_response = "No information given by server, information were not properly given"
                label_error.bind("<Button-1>", self.display_error)
            else:
                self.display_validation()

        button_submit.bind("<Button-1>", send_form)
        # self.additional_fr.bind("<Return>", self.send_form)
        frame_hr.bind("<Return>", send_form)
        self.additional_fr.pack()

    def task_request(self):
        token = self.token
        update_frame(self.additional_fr)
        frame_hr = Frame(self.additional_fr)
        frame_hr.grid(row=0, column=0)
        label_project_reference = Label(frame_hr, text="Project Reference")
        label_assigned_to = Label(frame_hr, text="Assigned To")
        label_description = Label(frame_hr, text="Description")

        button_submit = Button(frame_hr, text="Submit", width=10, height=1)

        requesting_priority = LabelFrame(frame_hr,
                                         text='Priority',
                                         width=75,
                                         height=40,
                                         relief=GROOVE,
                                         bd=2)

        entry_project_reference = Entry(frame_hr)
        entry_assigned_to = Entry(frame_hr)
        entry_description = Entry(frame_hr)

        Radiobutton(requesting_priority,
                    variable=self.priority,
                    value="very_high",
                    text="Very High").grid(row=2, column=0, padx=20)
        Radiobutton(requesting_priority,
                    variable=self.priority,
                    value="high",
                    text="High").grid(row=3, column=0, padx=20)
        Radiobutton(requesting_priority,
                    variable=self.priority,
                    value="medium",
                    text="Medium").grid(row=4, column=0, padx=20)

        label_project_reference.grid(row=5, column=1, pady=20)
        entry_project_reference.grid(row=5, column=2, pady=20)
        label_description.grid(row=6, column=1, pady=20)
        entry_description.grid(row=6, column=2, pady=20)
        label_assigned_to.grid(row=7, column=1, pady=20)
        entry_assigned_to.grid(row=7, column=2, pady=20)
        requesting_priority.grid(row=8, column=1, pady=20, padx=20)

        button_submit.grid(row=9, column=1, pady=20)
        label_error = Label(frame_hr,
                            text="",
                            fg="red",
                            font="Helvetica 9 bold")
        label_error.grid(row=9, column=2, pady=20)

        def send_form(*args):
            body = {
                "project_reference": entry_project_reference.get(),
                'description': entry_description.get(),
                "user_assigned": entry_assigned_to.get(),
                "priority": self.priority.get()
            }
            header = {'Authorization': 'Bearer {}'.format(token)}
            http_request.request("POST",
                                 "/create_task/",
                                 headers=header,
                                 body=json.dumps(body))
            response = http_request.getresponse()
            if response.status > 200:
                frame_hr.config(highlightcolor="red",
                                highlightbackground="red",
                                highlightthickness=3,
                                relief=SOLID,
                                bd=0)
                label_error.config(text="Error click here to get details")
                frame_hr.after(3000, lambda: label_error.config(text=""))
                frame_hr.after(2000, lambda: frame_hr.config(relief=FLAT))
                try:
                    decoded_response = json.loads(response.read().decode())
                    self.error_response = decoded_response["error"]
                except (KeyError, json.decoder.JSONDecodeError):
                    self.status_response = "400 or 500"
                    self.error_response = "No information given by server, information were not properly given"
                label_error.bind("<Button-1>", self.display_error)
            else:
                self.display_validation()

        button_submit.bind("<Button-1>", send_form)
        # self.additional_fr.bind("<Return>", self.send_form)
        frame_hr.bind("<Return>", send_form)
        self.additional_fr.pack()

    def retrieve_financial_request(self):
        header = {'Authorization': 'Bearer {}'.format(self.token)}
        http_request.request("GET",
                             "/review_financial_request/",
                             headers=header,
                             body=json.dumps(dict()))
        response = http_request.getresponse()
        if response.status > 200:
            try:
                decoded_response = json.loads(response.read().decode())
                self.error_response = decoded_response["error"]
            except (KeyError, json.decoder.JSONDecodeError):
                self.status_response = "400 or 500"
                self.error_response = "No information given by server, unknown error"
            self.display_error(None)
            return []
        else:
            decoded_response = json.loads(response.read().decode())
            return decoded_response["financial_requests"]

    def retrieve_task_ui(self):
        update_frame(self.additional_fr)
        frame_hr = Frame(self.additional_fr)
        frame_hr.grid(row=0, column=0)
        Label(frame_hr, text="Project reference").grid(row=1, column=1)
        entry_project_reference = Entry(frame_hr)
        entry_project_reference.grid(row=1, column=2)

        def submit_data(*args):
            data = self.retrieve_task_request(entry_project_reference.get())
            headers = [
                "project_reference", "description", "assign_to_user",
                "priority", "status"
            ]
            canvas = Canvas(frame_hr)
            canvas.grid(column=0, row=5)
            for i in range(len(data)):
                for j, head in enumerate(headers):
                    width = 15 if j > 0 else 45
                    l = Label(canvas,
                              text="{}".format(data[i][head]),
                              width=width,
                              relief=SOLID,
                              bd=2,
                              font="Helevetica 9 bold")
                    l.grid(row=i + 2, column=j)
            for j, head in enumerate(headers):
                width = 15 if j > 0 else 45
                Label(canvas,
                      text="{}".format(head),
                      width=width,
                      relief=SOLID,
                      bd=2,
                      pady=30,
                      font="Helevetica 9 bold").grid(row=1, column=j)
            Label(canvas,
                  text="Tasks for your project id",
                  font="Helvetica 13 bold",
                  underline=True).grid(row=0, column=0)

        Button(frame_hr, text="Submit", command=submit_data).grid(row=1,
                                                                  column=3)
        frame_hr.pack()
        self.additional_fr.pack()

    def retrieve_task_request(self, project_reference):
        header = {'Authorization': 'Bearer {}'.format(self.token)}
        body = {"project_reference": project_reference}
        http_request.request("GET",
                             "/retrieve_task/",
                             headers=header,
                             body=json.dumps(body))
        response = http_request.getresponse()
        if response.status > 200:
            try:
                decoded_response = json.loads(response.read().decode())
                self.error_response = decoded_response["error"]
            except (KeyError, json.decoder.JSONDecodeError):
                self.status_response = "400 or 500"
                self.error_response = "No information given by server, unknown error"
            self.display_error(None)
            return []
        else:
            decoded_response = json.loads(response.read().decode())
            return decoded_response["tasks"]

    def retrieve_fm_ui(self):
        update_frame(self.additional_fr)
        data = self.retrieve_financial_request()
        headers = [
            "id", "department", "project_reference", "required_amount",
            "reason", "status"
        ]
        canvas = Canvas(self.additional_fr)
        canvas.grid(column=0, row=0)
        for i in range(len(data)):
            for j, head in enumerate(headers):
                width = 15 if j > 0 else 45
                l = Label(canvas,
                          text="{}".format(data[i][head]),
                          width=width,
                          relief=SOLID,
                          bd=2,
                          font="Helevetica 9 bold")
                l.grid(row=i + 2, column=j)
        for j, head in enumerate(headers):
            width = 15 if j > 0 else 45
            Label(canvas,
                  text="{}".format(head),
                  width=width,
                  relief=SOLID,
                  bd=2,
                  pady=30,
                  font="Helevetica 9 bold").grid(row=1, column=j)
        Label(canvas,
              text="Financial Requests",
              font="Helvetica 13 bold",
              underline=True).grid(row=0, column=0)
        self.additional_fr.pack_propagate(0)
        self.additional_fr.pack()

    def retrieve_hr_request(self):
        header = {'Authorization': 'Bearer {}'.format(self.token)}
        http_request.request('GET',
                             "/review_staff_request/",
                             headers=header,
                             body=json.dumps(dict()))
        response = http_request.getresponse()
        if response.status > 200:
            try:
                decoded_response = json.loads(response.read().decode())
                self.error_response = decoded_response["error"]
            except (KeyError, json.decoder.JSONDecodeError):
                self.status_response = "400 or 500"
                self.error_response = "No information given by server, unknown error"
            self.display_error(None)
            return []
        else:
            decoded_response = json.loads(response.read().decode())
            return decoded_response["hr"]

    def retrieve_hr_ui(self):
        update_frame(self.additional_fr)
        data = self.retrieve_hr_request()
        headers = [
            "staff_request_id", "is_full_time", "department", "year_min",
            "job_title", "job_description", "status"
        ]
        canvas = Canvas(self.additional_fr)
        canvas.grid(column=0, row=0)
        for i in range(len(data)):
            for j, head in enumerate(headers):
                width = 15 if j > 0 else 45
                l = Label(canvas,
                          text="{}".format(data[i][head]),
                          width=width,
                          relief=SOLID,
                          bd=2,
                          font="Helevetica 9 bold")
                l.grid(row=i + 2, column=j)
        for j, head in enumerate(headers):
            width = 15 if j > 0 else 45
            Label(canvas,
                  text="{}".format(head),
                  width=width,
                  relief=SOLID,
                  bd=2,
                  pady=30,
                  font="Helevetica 9 bold").grid(row=1, column=j)
        Label(canvas,
              text="HR Requests",
              font="Helvetica 13 bold",
              underline=True).grid(row=0, column=0)
        self.additional_fr.pack_propagate(0)
        self.additional_fr.pack()

    def create_application(self):
        token = self.token
        update_frame(self.additional_fr)
        sub_frame = Frame(self.additional_fr)
        sub_frame.grid(row=0, column=0)
        label_record_number = Label(sub_frame, text="Record Number (Client)")
        label_client_name = Label(sub_frame, text="Client Name")
        label_event_type = Label(sub_frame, text="Event Type")
        label_description = Label(sub_frame, text='Description')
        label_number_attendees = Label(sub_frame, text="Expected Number")
        label_excepted_budget = Label(sub_frame, text="Planned Budget (SEK)")
        label_from_date = Label(sub_frame, text="From")
        label_to_date = Label(sub_frame, text="To")
        label_decorations = Label(sub_frame, text="Decorations")
        label_food_drinks = Label(sub_frame, text="Food/Drinks")
        label_filming_photos = Label(sub_frame, text="Filming/Photos")
        label_music = Label(sub_frame, text="Music")
        label_posters_artwork = Label(sub_frame, text="Posters/Art Work")
        label_computer_related_issues = Label(sub_frame,
                                              text="Computer-Related Issues")
        label_other_needs = Label(sub_frame, text="Other Needs")

        entry_number_attendees = Entry(sub_frame)
        entry_expected_budget = Entry(sub_frame)
        entry_to_date = Entry(sub_frame)
        entry_from_date = Entry(sub_frame)
        entry_event_type = Entry(sub_frame)
        entry_client_name = Entry(sub_frame)
        entry_record_number = Entry(sub_frame)
        entry_description = Entry(sub_frame)
        entry_from_date.insert(END, "yyyy/mm/dd")
        entry_to_date.insert(END, "yyyy/mm/dd")
        text_decorations = Text(sub_frame, width=40, height=5)
        text_food_drinks = Text(sub_frame, width=40, height=5)
        text_filming_photos = Text(sub_frame, width=40, height=5)
        text_music = Text(sub_frame, width=40, height=5)
        text_poster_art_work = Text(sub_frame, width=40, height=5)
        text_computer = Text(sub_frame, width=40, height=5)
        text_other_needs = Text(sub_frame, width=80, height=2)

        button_submit = Button(sub_frame, text="Submit", width=10, height=1)
        label_error = Label(sub_frame,
                            text="",
                            fg="red",
                            font="Helvetica 9 bold")

        label_record_number.grid(row=1, column=0, pady=20, sticky='nsew')
        entry_record_number.grid(row=1, column=1, pady=20, sticky='nsew')
        label_client_name.grid(row=2, column=0)
        entry_client_name.grid(row=2, column=1)
        label_event_type.grid(row=3, column=0)
        entry_event_type.grid(row=3, column=1)
        label_description.grid(row=4, column=0)
        entry_description.grid(row=4, column=1)
        label_from_date.grid(row=5, column=0)
        entry_from_date.grid(row=5, column=1)
        label_to_date.grid(row=5, column=2)
        entry_to_date.grid(row=5, column=3)
        label_number_attendees.grid(row=2, column=2)
        entry_number_attendees.grid(row=2, column=3)
        label_excepted_budget.grid(row=3, column=2)
        entry_expected_budget.grid(row=3, column=3)

        label_decorations.grid(row=6, column=0, pady=20)
        text_decorations.grid(row=6, column=1, pady=20)
        label_food_drinks.grid(row=6, column=2, pady=20)
        text_food_drinks.grid(row=6, column=3, pady=20)

        label_filming_photos.grid(row=7, column=0, pady=20)
        text_filming_photos.grid(row=7, column=1, pady=20)
        label_music.grid(row=7, column=2, pady=20)
        text_music.grid(row=7, column=3, pady=20)

        label_posters_artwork.grid(row=8, column=0, pady=20)
        text_poster_art_work.grid(row=8, column=1, pady=20)
        label_computer_related_issues.grid(row=8, column=2, pady=20)
        text_computer.grid(row=8, column=3, pady=20)

        label_other_needs.grid(row=9, column=0, pady=20)
        text_other_needs.grid(row=9, column=0, pady=20, columnspan=4)

        button_submit.grid(row=11, column=1, pady=20)
        label_error.grid(row=10, column=2)

        def send_form(*args):
            body = {
                "record_number": entry_record_number.get(),
                'client_name': entry_client_name.get(),
                "event_type": entry_event_type.get(),
                "description": entry_description.get(),
                "from_date": entry_from_date.get(),
                "to_date": entry_to_date.get(),
                "expected_number_attendees": entry_number_attendees.get(),
                "planned_budget": entry_expected_budget.get(),
                "decorations": text_decorations.get("1.0", END),
                "food_drinks": text_food_drinks.get("1.0", END),
                "filming_photos": text_filming_photos.get("1.0", END),
                "music": text_music.get("1.0", END),
                "posters_art_work": text_poster_art_work.get("1.0", END),
                "computer_related_issues": text_computer.get("1.0", END),
                "other_needs": text_other_needs.get("1.0", END)
            }
            header = {'Authorization': 'Bearer {}'.format(token)}
            http_request.request("POST",
                                 "/event_application_creation",
                                 headers=header,
                                 body=json.dumps(body))
            response = http_request.getresponse()
            if response.status > 200:
                sub_frame.config(highlightcolor="red",
                                 highlightbackground="red",
                                 highlightthickness=3,
                                 relief=SOLID,
                                 bd=0)
                label_error.config(text="Error click here to get details")
                sub_frame.after(3000, lambda: label_error.config(text=""))
                sub_frame.after(2000, lambda: sub_frame.config(relief=FLAT))
                try:
                    decoded_response = json.loads(response.read().decode())
                    self.error_response = decoded_response["error"]
                except (KeyError, json.decoder.JSONDecodeError):
                    self.status_response = "400 or 500"
                    self.error_response = "No information given by server, information were not properly given"
                label_error.bind("<Button-1>", self.display_error)
            else:
                self.display_validation()

        button_submit.bind("<Button-1>", send_form)
        # self.additional_fr.bind("<Return>", self.send_form)
        sub_frame.bind("<Return>", send_form)
        self.additional_fr.pack()

    def retrieve_application_ui(self):
        update_frame(self.additional_fr)
        data = self.retrieve_application_request()
        headers = [
            "project_reference", "client_name", "event_type", "description",
            "from_date", "to_date", "number_attendees"
        ]
        canvas = Canvas(self.additional_fr)
        canvas.grid(column=0, row=0)
        for i in range(len(data)):
            for j, head in enumerate(headers):
                width = 15 if j > 0 else 45
                # if head == "details":
                #     text = str()
                #     for (key,value) in data[i]["details"].items():
                #         if len(value)>1:
                #             text += "{}: {}\n".format(key, value)
                #     l = Label(canvas, text=text, width=width, relief=SOLID, bd=2, font="Helevetica 9 bold")
                # else:
                l = Label(canvas,
                          text="{}".format(data[i][head]),
                          width=width,
                          relief=SOLID,
                          bd=2,
                          font="Helevetica 9 bold")
                l.grid(row=i + 2, column=j)
        for j, head in enumerate(headers):
            width = 15 if j > 0 else 45
            Label(canvas,
                  text="{}".format(head),
                  width=width,
                  relief=SOLID,
                  bd=2,
                  pady=30,
                  font="Helevetica 9 bold").grid(row=1, column=j)
        Label(canvas,
              text="Applications",
              font="Helvetica 13 bold",
              underline=True).grid(row=0, column=0)
        self.additional_fr.pack_propagate(0)
        self.additional_fr.pack()

    def retrieve_application_request(self):
        header = {'Authorization': 'Bearer {}'.format(self.token)}
        http_request.request("GET",
                             "/event_application_retrieve/",
                             headers=header,
                             body=json.dumps(dict()))
        response = http_request.getresponse()
        if response.status > 200:
            try:
                decoded_response = json.loads(response.read().decode())
                self.error_response = decoded_response["error"]
            except (KeyError, json.decoder.JSONDecodeError):
                self.status_response = "400 or 500"
                self.error_response = "No information given by server, unknown error"
            self.display_error(None)
            return []
        else:
            decoded_response = json.loads(response.read().decode())
            return decoded_response["applications"]
Пример #4
0
class Interface(Frame):
    def __init__(self, master=None, *_):
        Frame.__init__(self, master)
        self.master = master

        # settings variables
        self.word_wrap = BooleanVar()
        self.word_wrap.set(True)
        self.__show_status_bar = BooleanVar()
        self.__show_status_bar.set(True)
        self.fnt = font.Font(family="Courier New", size=10)
        self.find_open = False
        self.replace_open = False
        self.goto_open = False
        self.prior_search = ''
        self.prior_goto = ''

        # init methods
        self.__init_main_window()
        self.__build_status_bar()
        self.__build_menu_bar()
        self.__bind_shortcuts()
        self.toggle_word_wrap()
        self.context_menu = Menu(self.master, tearoff=0)

        self.last_hash = get_signature(self.text_area.get(1.0, END))

    def __init_main_window(self):
        self.text_area = Text(self.master, undo=True)
        self.text_area.config(font=self.fnt, wrap=WORD)

        # To add scrollbar
        self.scroll_bar_x = Scrollbar(self.master, orient=HORIZONTAL)
        self.scroll_bar_y = Scrollbar(self.master, orient=VERTICAL)
        __file = None

        try:
            self.master.wm_iconbitmap('notepad.ico')
        except TclError:
            log.error("unable to set icon to notepad.ico")
            pass

        # Set the window text
        self.master.title('Untitled - Notepad')

        # To make the text area auto resizable
        self.master.grid_rowconfigure(0, weight=1)
        self.master.grid_columnconfigure(0, weight=1)

        self.text_area.grid(column=0, row=0, sticky='nsew')

        self.scroll_bar_y.grid(column=1, row=0, sticky='nsew')
        self.scroll_bar_x.grid(column=0, row=1, stic='nsew')

        # Scrollbar will adjust automatically according to the content
        self.scroll_bar_x.config(command=self.text_area.xview)
        self.scroll_bar_y.config(command=self.text_area.yview)
        self.text_area.config(xscrollcommand=self.scroll_bar_x.set,
                              yscrollcommand=self.scroll_bar_y.set)

        self.text_area.focus()

    def __build_menu_bar(self):
        # main and submenus
        self.menu_bar = Menu(self.master)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.edit_menu = Menu(self.menu_bar, tearoff=0)
        self.format_menu = Menu(self.menu_bar, tearoff=0)
        self.thisViewMenu = Menu(self.menu_bar, tearoff=0)
        self.help_menu = Menu(self.menu_bar, tearoff=0)

        # File Menu
        self.menu_bar.add_cascade(label='File',
                                  underline=0,
                                  menu=self.file_menu)
        self.file_menu.add_command(label='New',
                                   underline=0,
                                   accelerator='Ctrl+N',
                                   command=new_file)
        self.file_menu.add_command(label='Open...',
                                   underline=0,
                                   accelerator='Ctrl+O',
                                   command=open_file)
        self.file_menu.add_command(label='Save',
                                   underline=0,
                                   accelerator='Ctrl+S',
                                   command=save_file)
        self.file_menu.add_command(label='Save As...',
                                   underline=5,
                                   command=save_file_as)
        self.file_menu.add_separator()
        self.file_menu.add_command(label='Page Setup...',
                                   underline=5,
                                   accelerator='Ctrl+S',
                                   command=save_file)
        self.file_menu.add_command(label='Print',
                                   underline=0,
                                   accelerator='Ctrl+P',
                                   command=save_file)
        self.file_menu.add_separator()
        self.file_menu.add_command(label='Exit',
                                   underline=1,
                                   command=self.quit_application)

        # Edit Menu
        self.menu_bar.add_cascade(label='Edit',
                                  underline=0,
                                  menu=self.edit_menu)
        self.edit_menu.add_command(label='Undo',
                                   underline=0,
                                   accelerator='Ctrl+Z',
                                   command=self.undo)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label='Cut',
                                   underline=2,
                                   accelerator='Ctrl+X',
                                   command=self.cut)
        self.edit_menu.add_command(label='Copy',
                                   underline=0,
                                   accelerator='Ctrl+C',
                                   command=self.copy)
        self.edit_menu.add_command(label='Paste',
                                   underline=0,
                                   accelerator='Ctrl+V',
                                   command=self.paste)
        self.edit_menu.add_command(label='Delete',
                                   underline=2,
                                   accelerator='Del',
                                   command=self.delete)
        self.edit_menu.add_command(label='Search with Bing... ',
                                   underline=0,
                                   accelerator='Ctrl+B',
                                   command=self.search_selected_text)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label='Find...',
                                   underline=0,
                                   accelerator='Ctrl+F',
                                   command=self.show_find)
        self.edit_menu.add_command(label='Find Next',
                                   underline=5,
                                   accelerator='F3',
                                   command=self.find_next)
        self.edit_menu.add_command(label='Replace...',
                                   underline=0,
                                   accelerator='Ctrl+H',
                                   command=self.show_find_replace)
        self.edit_menu.add_command(label='Go To...',
                                   underline=0,
                                   accelerator='Ctrl+G',
                                   command=self.show_goto)
        self.edit_menu.add_separator()
        self.edit_menu.add_command(label='Select All',
                                   underline=7,
                                   accelerator='Ctrl+A',
                                   command=lambda: self.select_all())
        self.edit_menu.add_command(label='Time/Date',
                                   underline=5,
                                   accelerator='F5',
                                   command=self.time_date)

        # Format Menu
        self.menu_bar.add_cascade(label='Format',
                                  underline=0,
                                  menu=self.format_menu)
        self.format_menu.add_checkbutton(label='Word Wrap',
                                         underline=0,
                                         variable=self.word_wrap,
                                         command=self.toggle_word_wrap)
        self.format_menu.add_command(label='Font...',
                                     underline=0,
                                     command=self.set_font)

        # View Menu
        self.menu_bar.add_cascade(label='View',
                                  underline=1,
                                  menu=self.thisViewMenu)
        self.thisViewMenu.add_checkbutton(label='Status Bar',
                                          underline=0,
                                          variable=self.__show_status_bar,
                                          command=self.toggle_status_bar)

        # Help Menu
        self.menu_bar.add_cascade(label='Help',
                                  underline=0,
                                  menu=self.help_menu)
        self.help_menu.add_command(label='View Help',
                                   underline=5,
                                   command=self.get_help)
        self.help_menu.add_separator()
        self.help_menu.add_command(label='About Notepad',
                                   underline=0,
                                   command=show_about)

        self.master.config(menu=self.menu_bar)

    def show_context_menu(self, event):
        try:
            self.context_menu = Menu(self.master, tearoff=0)
            self.context_menu.add_command(label='Undo',
                                          underline=2,
                                          accelerator='Ctrl+Z',
                                          command=self.undo)
            self.context_menu.add_separator()
            self.context_menu.add_command(label='Cut',
                                          underline=2,
                                          accelerator='Ctrl+X',
                                          command=self.cut)
            self.context_menu.add_command(label='Copy',
                                          underline=0,
                                          accelerator='Ctrl+C',
                                          command=self.copy)
            self.context_menu.add_command(label='Paste',
                                          underline=0,
                                          accelerator='Ctrl+V',
                                          command=self.paste)
            self.context_menu.add_command(label='Delete',
                                          underline=2,
                                          accelerator='Del',
                                          command=self.delete)
            self.context_menu.add_separator()
            self.context_menu.add_command(label='Select All',
                                          underline=2,
                                          accelerator='Ctrl+A',
                                          command=self.select_all)
            self.context_menu.add_separator()
            self.context_menu.add_command(label='Search with Bing... ',
                                          underline=0,
                                          accelerator='Ctrl+B',
                                          command=self.search_selected_text)
            self.context_menu.tk_popup(event.x_root, event.y_root)

        finally:
            self.context_menu.grab_release()

    def set_font(self):
        fnt = fontpicker.ask_font(family=self.fnt.actual(option='family'),
                                  size=self.fnt.actual(option='size'),
                                  weight=self.fnt.actual(option='weight'),
                                  slant=self.fnt.actual(option='slant'))

        if fnt:
            self.fnt = font.Font(family=fnt['family'],
                                 size=int(fnt['size']),
                                 weight=fnt['weight'],
                                 slant=fnt['slant'])

            self.text_area.config(font=self.fnt)

    def __build_status_bar(self):
        self.status_bar = Label(self.master,
                                text="Ln 1, Col 1\t",
                                bd=1,
                                relief=SUNKEN,
                                anchor='e')
        self.toggle_status_bar()

    def toggle_status_bar(self):
        if self.__show_status_bar.get():
            self.status_bar.grid(sticky='sew')
        else:
            self.status_bar.grid_forget()

    def toggle_word_wrap(self):
        if self.word_wrap.get():
            self.text_area.config(wrap=WORD)
            self.scroll_bar_x.grid_forget()
            log.info("word wrap on, scroll bar off")
        else:
            self.text_area.config(wrap=NONE)
            self.scroll_bar_x.grid(column=0, row=1, sticky='nsew')
            log.info("word wrap off, scroll bar on")

    def __bind_shortcuts(self):
        self.master.bind_class('Text', '<Control-a>', self.select_all)
        self.master.bind_class('Text', '<Control-A>', self.select_all)
        self.master.bind_class('Text', '<Control-s>', save_file)
        self.master.bind_class('Text', '<Control-S>', save_file)
        self.master.bind_class('Text', '<Control-n>', new_file)
        self.master.bind_class('Text', '<Control-N>', new_file)
        self.master.bind_class('Text', '<Control-b>',
                               self.search_selected_text)
        self.master.bind_class('Text', '<Control-B>',
                               self.search_selected_text)
        self.master.bind_class('Text', '<Control-f>', self.show_find)
        self.master.bind_class('Text', '<Control-F>', self.show_find)
        self.master.bind_class('Text', '<Control-h>', self.show_find_replace)
        self.master.bind_class('Text', '<Control-H>', self.show_find_replace)
        self.master.bind_class('Text', '<Control-g>', self.show_goto)
        self.master.bind_class('Text', '<Control-G>', self.show_goto)
        self.master.bind_class('Text', '<F5>', self.time_date)
        self.master.bind_class('Text', '<F3>', self.find_next)
        self.text_area.bind_class(self.text_area, '<Any-KeyPress>',
                                  self.on_key)
        self.text_area.bind_class(self.text_area, '<Button-1>', self.on_click)
        self.text_area.bind_class(self.text_area, '<Button-3>',
                                  self.show_context_menu)

    def quit_application(self):
        if notepad.has_changed():
            save_box = messagebox.askquestion(
                'Confirm save',
                'Do you want to save before closing this file?',
                icon='warning')
            if save_box == 'yes':
                save_file()
        self.master.destroy()
        exit()

    def undo(self, *_):
        self.text_area.event_generate('<<Undo>>')

    def on_key(self, *_):
        self.update_status_bar(INSERT)

    def on_click(self, *_):
        self.update_status_bar(CURRENT)

        try:
            self.context_menu.destroy()
        except AttributeError:
            log.warning(
                'error occurred while trying to exit context menu, probably not instansiated'
            )

    def update_status_bar(self, obj):
        row, col = self.text_area.index(obj).split('.')
        self.status_bar.config(text=str('Ln ' + row + ', Col ' + col + ' \t'))

    def cut(self, *_):
        self.text_area.event_generate('<<Cut>>')

    def copy(self, *_):
        self.text_area.event_generate('<<Copy>>')

    def paste(self, *_):
        self.text_area.event_generate('<<Paste>>')

    def select_all(self, *_):
        self.text_area.tag_add('sel', '1.0', 'end')

    def delete(self, *_):
        self.text_area.event_generate('<Delete>')

    def search_selected_text(self, *_):
        try:
            s = self.text_area.selection_get()
            if s is not None:
                search_with_bing(s)
            else:
                log.debug('selection was empty, not searching with bing')
        except TclError:
            print('TclError - Probably because nothing was selected ')

    def time_date(self, *_):
        now = datetime.now()
        s = now.strftime("%I:%M %p %m/%d/%Y")
        self.text_area.insert(INSERT, s)

    def show_find(self, *_):
        if not self.find_open:
            self.find_open = True
            FindWindow(master=self)

    def show_find_replace(self, *_):
        if not self.replace_open:
            self.replace_open = True
            FindReplaceWindow(master=self)

    def show_goto(self, *_):
        if not self.goto_open:
            self.goto_open = True
            GotoWindow(master=self)

    @staticmethod
    def get_help():
        search_with_bing("get+help+with+notepad+in+windows+10")

    def run(self):
        # Run main application
        self.master.mainloop()

    def set_title(self, string):
        self.master.title(string + ' - Notepad')

    def clear_text(self):
        self.text_area.delete(1.0, END)

    def get_text(self):
        return self.text_area.get(1.0, END)

    def write_text(self, text, start_index=1.0):
        self.text_area.insert(start_index, text)

    def find_next(self, _):
        search_string = self.prior_search

        location = self.text_area.search(search_string,
                                         self.text_area.index(INSERT),
                                         nocase=True)
        log.info('searching next -- forwards')

        if location != '':
            log.info('found ' + search_string + ' at position ' + location)

            row, col = get_index(location)
            end_col = str(col + len(search_string))
            end_location = str(str(row) + '.' + end_col)

            self.text_area.mark_set("insert", end_location)
            self.text_area.see("insert")
            self.text_area.tag_remove('sel', "1.0", END)
            self.text_area.tag_raise("sel")
            self.text_area.tag_add('sel', location, end_location)
            self.text_area.focus()
        else:
            log.warning(search_string + 'string not found')

    def has_changed(self):
        if get_signature(self.text_area.get(1.0, END)) == self.last_hash:
            log.info('file has changed')
            return False
        else:
            log.info('file has not changed')
            return True