示例#1
0
class PersonAdd(Frame):
    def __init__(self, parent, autofill, root, *args, **kwargs):
        Frame.__init__(self, parent, *args, **kwargs)

        self.parent = parent
        self.root = root
        self.autofill = autofill

        self.config(padx=24, pady=24)

        self.gender = 'unknown'

        self.new_person_id = None

        self.role_person_edited = False
        self.findings_roles_id = None

        self.rc_menu = RightClickMenu(self.root)
        self.make_widgets()

    def make_widgets(self):

        all_pics = self.get_all_pics()

        lab1 = Label(self, text='Gender:')
        self.gender_input = ClearableReadonlyCombobox(self, values=GENDER_TYPES)

        lab2 = Label(self, text='Main Image:')
        self.image_input = ClickAnywhereCombo(self, values=all_pics)

        lab3 = Label(self, text='Name Type:')
        self.name_type_input = ClearableReadonlyCombobox(self, values=self.get_name_types())

        lab4 = Label(self, text='Full Name')
        self.name_input = Entry(self, width=65)

        self.how = LabelH3(
            self, 
            text='Alphabetize name: after clicking auto-sort, tab into '
                  'auto-filled name fields to modify\nsort order with '
                  'arrow keys or if sort order is correct, just click ADD.')

        autosort = Button(
            self, text='AUTOSORT', command=self.show_sort_order)

        self.order_frm = Frame(self)

        s = 0
        for stg in range(20):
            mov = LabelMovable(self.order_frm)
            mov.grid(column=s, row=0, padx=3)
            s += 1 

        self.buttonbox = Frame(self)
        self.add_butt = Button(self.buttonbox, text='ADD', width=8)

        lab1.grid(column=0, row=3)
        self.gender_input.grid(
            column=1, row=3, padx=12, pady=12, sticky='e')
        lab2.grid(column=2, row=3)
        self.image_input.grid(column=3, row=3, padx=12, pady=12)
        lab3.grid(column=0, row=4)
        self.name_type_input.grid(
            column=1, row=4,  padx=12, pady=12, sticky='e')
        lab4.grid(column=2, row=4)
        self.name_input.grid(column=3, row=4, padx=12, pady=12)

        self.how.grid(column=0, row=5, padx=6, pady=6, columnspan=4)
        autosort.grid(column=0, row=6, padx=6, pady=6)
        self.order_frm.grid(column=1, row=6, columnspan=4, pady=24)
        self.buttonbox.grid(column=1, row=7, sticky='e')
        self.add_butt.grid(column=0, row=0, padx=6, pady=6, sticky='e')

        self.new_person_statusbar = StatusbarTooltips(self.parent, resizer=False)
        visited = (
            (self.gender_input, 
                "Gender Input", 
                "'Unknown' used if left blank."),
            (self.image_input, 
                "Image Input", 
                "Use an old photo of person's home town if no photo available."),
            (self.name_type_input, 
                "Name Type Input", 
                "Choose the name type."),
            (self.name_input, 
                "Name Input", 
                "Autofills but you can change it."),
            (autosort, 
                "Autosort Button", 
                "Click to auto-create a sortable name."),
            (self.order_frm, 
                "", 
                "Tab to focus name element. Arrow to change order.")
)        
        run_statusbar_tooltips(
            visited, 
            self.new_person_statusbar.status_label, 
            self.new_person_statusbar.tooltip_label)

        self.preset()

        rcm_widgets = (self.name_input, self.name_type_input)
        make_rc_menus(
            rcm_widgets, 
            self.rc_menu, 
            person_add_msg)

    def preset(self):

        self.gender_input.config(state='normal')
        self.gender_input.delete(0, 'end')
        self.gender_input.config(state='readonly')
        self.image_input.delete(0, 'end')
        self.image_input.insert(0, 'no_photo_001.gif')
        self.name_type_input.config(state='normal')
        self.name_type_input.delete(0, 'end')
        self.name_type_input.insert(0, 'birth name')
        self.name_type_input.config(state='readonly')

    def reset(self):
        self.preset()
        self.name_input.delete(0, 'end')
        for child in self.order_frm.winfo_children():
            child['text'] = ''
        self.dupe_check = True  

    def add_person(self, findings_roles_id=None):
        self.get_entered_values()
        self.findings_roles_id = findings_roles_id
        self.check_for_dupes()

    def get_entered_values(self):
        ''' 
        '''
        if len(self.gender_input.get()) != 0:
            self.gender = self.gender_input.get()
        self.full_name = self.name_input.get()
        self.selected_image = self.image_input.get()
        self.name_type = self.name_type_input.get()

    def check_for_dupes(self):
        ''' 
            If birth name already exists in database, open dialog. 
        '''
 
        conn = sqlite3.connect(current_file)
        cur = conn.cursor()
        cur.execute(select_all_person_ids)
        all_people = cur.fetchall()
        cur.close()
        conn.close()
        
        all_people = [[i[0]] for i in all_people]

        names_only = []

        for id in all_people:
            display_name = get_name_with_id(id[0]) 
            names_only.append(display_name)
            id.insert(0, display_name)

        people_vals = []
        for lst in all_people:
            if not lst[0]:
                lst[0] = ''
            people_vals.append(' #'.join([lst[0], str(lst[1])]))

        if self.full_name not in names_only:
            self.make_new_person()
            self.make_sort_order()
            self.save_new_name(self.new_person_id)  
            self.reset()
        else:
            self.dupe_check = msg.YesNoMessage(
                self,
                title='Duplicate Check',
                message="This birth name already exists. To create a "
                    "new person by the same name, click SUBMIT. The "
                    "two persons can be merged later if desired.",
                show_input=self.full_name).show()                
            if self.dupe_check is True:  
                self.make_new_person() 
                self.make_sort_order()
                self.save_new_name(self.new_person_id)  
                self.reset()
            else:
                self.reset() 

    def make_new_person(self): 
        conn = sqlite3.connect(current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()
        cur.execute(insert_person_null, (self.gender,))
        conn.commit()
        cur.execute("SELECT seq FROM SQLITE_SEQUENCE WHERE name = 'person' ")
        new_person_id = cur.fetchone()
        if new_person_id:
            self.new_person_id = new_person_id[0]

        if self.role_person_edited is True:
            cur.execute(
                update_findings_roles_person, 
                (self.new_person_id, self.findings_roles_id))
            conn.commit()
            self.role_person_edited = False 
        
        cur.close()
        conn.close()

    def make_sort_order(self): 

        self.order = []

        for child in self.order_frm.winfo_children():
            text = child['text']
            self.order.append(text)

        self.order = ' '.join(self.order)
        self.order = self.order.replace(' , ', ', ')
        self.order = self.order.strip(', ') 

    def save_new_name(self, subject_id):
        conn = sqlite3.connect(current_file)
        cur = conn.cursor()
        conn.execute('PRAGMA foreign_keys = 1')
        cur.execute(select_image_id, (self.selected_image,))
        img_id = cur.fetchone()[0]
        cur.execute(insert_images_entities, (img_id, subject_id))
        conn.commit()
        cur.execute(select_name_type_id, (self.name_type,))
        name_type_id = cur.fetchone()
        name_type_id = name_type_id[0]
        cur.execute(
            insert_name, 
            (subject_id, self.full_name, name_type_id, self.order))
        conn.commit()

        new_list = make_values_list_for_person_select()

        self.autofill.values = new_list
        
        cur.close()
        conn.close()

        self.image_input.delete(0, 'end')
        self.image_input.insert(0, 'no_photo_001.gif')

        for widg in (self.name_type_input, self.name_input):
            widg.config(state='normal')
            widg.delete(0, 'end')
        self.name_type_input.config(state='readonly')

        for child in self.order_frm.winfo_children():
            child.config(text='')
        self.gender_input.config(state='normal')
        self.gender_input.delete(0, 'end')
        self.gender_input.config(state='readonly')
        self.gender_input.focus_set()

    def show_sort_order(self):

        self.got = self.name_input.get()
        self.new_name = self.got
        self.got = self.got.split()
        if len(self.got) == 0:
            return
        else:
            length = len(self.got)-1
        word = self.got[length].lower()
        
        self.got.insert(0, ',')
        length += 1
        if word not in NAME_SUFFIXES:
            self.got.insert(0, self.got.pop())
        elif word in NAME_SUFFIXES and self.got[length].lower() == word:
            self.got.insert(0, self.got.pop())
            self.got.insert(0, self.got.pop())

        for child in self.order_frm.winfo_children():
            child.config(text='')

        v = 0
        for name in self.got:
            self.order_frm.winfo_children()[v].config(text=name)
            v += 1

    def get_name_types(self):

        conn = sqlite3.connect(current_file)
        cur = conn.cursor()
        cur.execute(select_all_name_types)
        name_types = cur.fetchall()
        cur.close()
        conn.close()
        name_types = [i[0] for i in name_types]

        return name_types

    def get_all_pics(self):

        conn = sqlite3.connect(current_file)
        cur = conn.cursor()
        picvals = cur.fetchall()
        cur.close()
        conn.close()
        return picvals
示例#2
0
class NotesDialog(Toplevel):
    def __init__(self,
                 master,
                 current_person,
                 finding_id=None,
                 header=None,
                 pressed=None,
                 *args,
                 **kwargs):
        Toplevel.__init__(self, master, *args, **kwargs)

        self.birth_name = get_name_with_id(current_person)
        self.title('{} ({})'.format('Notes for an Event', self.birth_name))

        self.current_person = current_person
        self.root = master
        self.finding_id = finding_id
        self.header = header
        self.pressed = pressed

        # self.self.new_index = None
        self.current_note_text = ''
        self.current_subtopic = ''
        self.current_note_id = None
        self.new_subtopic_label_text = 'New Note'
        self.current_subtopic_index = None
        self.new_subtopic_name = ''

        self.current_file = get_current_file()[0]

        self.bind('<Escape>', self.close_roles_dialog)
        self.subtopics = []

        self.privacy = tk.IntVar()

        self.refresh_notes_per_finding()
        self.rc_menu = RightClickMenu(self.root)
        self.make_widgets()
        self.protocol('WM_DELETE_WINDOW', self.close_roles_dialog)

    def make_widgets(self):

        self.title('{}{} ({})'.format('Notes for Conclusion #',
                                      self.finding_id, self.birth_name))

        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(1, weight=1)
        header = Frame(self)
        header.grid_columnconfigure(1, weight=1)
        header.grid_rowconfigure(0, weight=1)

        self.notes_dialog_header = Frame(header)

        content = Frame(self)

        left_panel = Frame(content)

        topiclab = Label(left_panel, text='Note Subtopics')

        self.toc = Listbox(left_panel,
                           self.sorted_subtopics,
                           view_height=424,
                           view_width=180,
                           scrollbar=False)

        self.new_index = len(self.subtopics)
        self.toc.insert(self.new_index, self.new_subtopic_label_text)
        self.toc.focus_set()
        self.toc.selection_set(0)

        self.toc.store_new_subtopic_name = self.store_new_subtopic_name
        self.toc.pass_ctrl_click = self.open_links_dialog
        self.toc.pass_delete_key = self.delete_note

        self.selected_subtopic = Label(content, text='New Note')

        self.note_input = ScrolledText(content)

        note_submit = Button(content,
                             text='Submit Changes',
                             command=self.save_changes)

        order = Button(content,
                       text='Change Order of Subtopics',
                       command=self.reorder_notes)

        radframe = LabelFrame(content, text='Make selected note...')

        self.public = Radiobutton(radframe,
                                  text='...public',
                                  anchor='w',
                                  variable=self.privacy,
                                  value=0,
                                  command=self.save_privacy_setting)

        self.private = Radiobutton(radframe,
                                   text='...private',
                                   anchor='w',
                                   variable=self.privacy,
                                   value=1,
                                   command=self.save_privacy_setting)

        close = Button(content, text='DONE', command=self.close_roles_dialog)

        # notes_statusbar = StatusbarTooltips(self)

        # visited = (
        # (above,
        # 'this is a notes_statusbar message',
        # 'this is a tooltip'),
        # (below,
        # 'this is also a notes_statusbar message',
        # 'this is another tooltip'))

        # run_statusbar_tooltips(
        # visited,
        # notes_statusbar.status_label,
        # notes_statusbar.tooltip_label)

        # grid in self
        header.grid(column=0, row=0, columnspan=2, pady=12, sticky='we')
        content.grid(column=0, row=1, sticky='news', padx=(0, 6))
        # notes_statusbar.grid(column=0, row=2, sticky='ew')

        # grid in header
        self.notes_dialog_header.grid(column=1, row=0, sticky='ew')
        self.notes_dialog_header.grid_columnconfigure(0, weight=1)

        # grid in content
        left_panel.grid(column=0, row=1, sticky='news', rowspan=2, pady=24)
        self.selected_subtopic.grid(column=1, row=1, sticky='w')
        self.note_input.grid(column=1,
                             row=2,
                             columnspan=3,
                             sticky='nsew',
                             padx=(0, 24),
                             pady=12)
        note_submit.grid(column=3, row=3, sticky='se')
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        content.grid_rowconfigure(1, weight=1)
        order.grid(column=1, row=4)
        radframe.grid(column=2, row=5, sticky='n', pady=24)
        close.grid(column=3, row=6, sticky='se', padx=24, pady=(0, 24))

        # grid in left_panel
        topiclab.grid(column=0, row=0)
        self.toc.grid(column=0, row=1)
        for child in self.toc.listbox_content.winfo_children():
            child.bind('<<ListboxSelected>>', self.switch_note)

        self.subtopic_widgets = self.toc.listbox_content.winfo_children()

        # grid in radframe
        self.public.grid(column=0, row=0, sticky='news', padx=24)
        self.private.grid(column=0, row=1, sticky='news', padx=24)

        # rcm_widgets = (self.subtopic_input, self.note_input.text)
        # make_rc_menus(
        # rcm_widgets,
        # self.rc_menu,
        # note_dlg_msg,
        # header_parent=self.notes_dialog_header,
        # header=self.header,
        # which_dlg='notes')

        config_generic(self)
        center_window(self)

    def open_links_dialog(self):
        links = Toplevel(self.root)
        links.title('Link Notes to Multiple Entities')
        instrux = LabelH3(
            links,
            text='The current note can be linked to any number of Entities\n'
            'such as Persons, Places, Assertions, Conclusions, or Sources.')
        instrux.grid(padx=24, pady=24)

    def save_changes(self):

        self.save_new_subtopic()

        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()

        new_note_text = self.note_input.text.get(1.0, 'end-1c')
        subtopic = self.current_subtopic
        cur.execute(update_note, (new_note_text, subtopic))
        conn.commit()
        cur.close()
        conn.close()

        self.master.current_note_text = new_note_text
        self.refresh()

    def save_new_subtopic(self):
        if self.selected_subtopic.cget('text') != self.new_subtopic_label_text:
            return
        self.subtopic_dialog = Toplevel(self.root)
        self.subtopic_dialog.title('New Note: Subtopic Input Dialog')
        headlab = LabelH3(self.subtopic_dialog,
                          text='Unique subtopic name for new note:')
        self.subtopic_input = Entry(self.subtopic_dialog, width=64)
        self.subtopic_input.focus_set()
        buttonbox = Frame(self.subtopic_dialog)
        self.subtopic_dialog.grid_columnconfigure(0, weight=1)
        new_note_ok = Button(buttonbox,
                             text='Submit Note and Subtitle',
                             command=self.submit_new_note)
        new_note_cancel = Button(buttonbox,
                                 text='Cancel',
                                 command=self.close_subtopic_dialog)

        headlab.grid(column=0, row=0, pady=(24, 0), columnspan=2)
        self.subtopic_input.grid(column=0,
                                 row=1,
                                 padx=24,
                                 pady=24,
                                 columnspan=2)
        buttonbox.grid(column=1, row=2, sticky='we', padx=24, pady=24)
        new_note_ok.grid(column=0, row=0, sticky='e', padx=12)
        new_note_cancel.grid(column=1, row=0, sticky='e', padx=12)

        self.subtopic_dialog.bind('<Escape>', self.close_subtopic_dialog)
        self.subtopic_dialog.protocol('WM_DELETE_WINDOW',
                                      self.close_subtopic_dialog)

    def submit_new_note(self):
        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()

        new_note_text = self.note_input.text.get(1.0, 'end-1c')
        new_subtopic = self.subtopic_input.get()
        cur.execute(select_count_subtopic, (new_subtopic, ))
        count = cur.fetchone()[0]
        if count > 0:
            non_unique_subtopic = ErrorMessage(
                self, message="Each subtopic can be\nused once in a tree.")
            non_unique_subtopic.title('Non-unique Note Title Error')
            self.subtopic_input.focus_set()
            return

        if len(new_subtopic) == 0:
            blank_subtopic = ErrorMessage(self,
                                          message="Blank notes are OK\n"
                                          "but not blank note titles.")
            blank_subtopic.title('Blank Note Title Error')
            self.subtopic_input.focus_set()
            return
        cur.execute(insert_note, (new_note_text, new_subtopic))
        conn.commit()
        cur.execute("SELECT seq FROM SQLITE_SEQUENCE WHERE name = 'note'")
        new_note_id = cur.fetchone()[0]

        cur.execute(insert_findings_notes,
                    (self.finding_id, new_note_id, self.new_index))
        conn.commit()
        cur.close()
        conn.close()

        self.master.current_note_text = new_note_text
        self.refresh_notes_per_finding()
        self.toc.insert(self.new_index, new_subtopic)
        items = self.toc.listbox_content.winfo_children()
        for child in items:
            child.bind('<<ListboxSelected>>', self.switch_note)
        self.toc.resize_scrollbar()
        self.toc.selection_set(self.new_index)
        self.switch_note()
        self.pressed.config(text=' ... ')
        self.new_index = len(self.subtopics)
        self.close_subtopic_dialog()
        self.refresh()

    def refresh_notes_per_finding(self):
        conn = sqlite3.connect(self.current_file)
        cur = conn.cursor()
        cur.execute(select_notes_refresh, (self.finding_id, ))
        notes = cur.fetchall()
        all_subtopics = []
        if len(notes) != 0:
            for tup in notes:
                all_subtopics.append([tup[1], tup[3]])
        all_subtopics.sort(key=lambda i: i[1])
        self.sorted_subtopics = []
        for lst in all_subtopics:
            self.sorted_subtopics.append(lst[0])

        self.subtopics = self.sorted_subtopics
        self.notesdict = {}
        for tup in notes:
            self.notesdict[tup[0]] = [tup[1], tup[2]]
        cur.close()
        conn.close()

    def close_roles_dialog(self, evt=None):
        self.destroy()
        self.master.focus_set()

    def close_subtopic_dialog(self, evt=None):
        self.subtopic_dialog.destroy()

    def save_privacy_setting(self):
        privacy_setting = self.privacy.get()
        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()
        cur.execute(update_note_private,
                    (privacy_setting, self.current_note_id))
        conn.commit()
        cur.close()
        conn.close()

    def get_selected_subtopic(self):
        # "is not None" has to be explicit here
        if self.toc.curselection() is not None:
            self.current_subtopic_index = self.toc.curselection()
        else:
            return
        self.current_subtopic = self.toc.get(self.current_subtopic_index)
        if len(self.notesdict) != 0:
            for k, v in self.notesdict.items():
                if v[0] == self.current_subtopic:
                    break
            self.current_note_id = k
            self.current_note_text = v[1]

    def store_new_subtopic_name(self):
        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()
        cur.execute(update_note_subtopic,
                    (self.toc.new_subtopic_name, self.current_note_id))
        conn.commit()
        cur.close()
        conn.close()

        self.subtopic_widgets = self.toc.listbox_content.winfo_children()
        for child in self.subtopic_widgets:
            child.bind('<<ListboxSelected>>', self.switch_note)
            if child.winfo_reqwidth() > self.toc.view_width:
                create_tooltip(child, self.toc.new_subtopic_name)

    def switch_note(self, evt=None):

        self.get_selected_subtopic()
        if len(self.current_subtopic) == 0:
            return
        self.selected_subtopic.config(text=self.current_subtopic)
        if self.current_subtopic == self.new_subtopic_label_text:
            self.note_input.text.delete(1.0, 'end')
            return
        self.note_input.text.delete(1.0, 'end')
        self.note_input.text.insert(1.0, self.current_note_text)

        conn = sqlite3.connect(self.current_file)
        cur = conn.cursor()
        cur.execute(select_private_note,
                    (self.current_subtopic, self.finding_id))
        privacy_setting = cur.fetchone()

        if privacy_setting:
            privacy_setting = privacy_setting[0]

        cur.close()
        conn.close()

        if privacy_setting is None:
            return
        elif privacy_setting == 0:
            self.public.select()
        elif privacy_setting == 1:
            self.private.select()

    def delete_note(self):
        '''
            Since any given note can be re-used more than once by linking it 
            to any number of findings, delete note from note table only if 
            the note_id no longer exists at all in the findings_notes table; 
            not every time a note_id is deleted from the findings_notes table. 
        '''
        def ok_delete():
            run_delete()
            cancel_delete()

        def cancel_delete():
            self.focus_set()
            deleter.destroy()

        def run_delete():

            note_count_per_finding = 0

            self.toc.delete(selected)
            self.note_input.text.delete(1.0, 'end')
            self.selected_subtopic.config(text='')
            cur.execute(delete_findings_notes, (deletable, self.finding_id))
            conn.commit()

            if delete_var.get() == 1:
                cur.execute(select_count_findings_notes_note_id, (deletable, ))
                linked_notes = cur.fetchone()[0]

                if linked_notes == 0:
                    cur.execute(delete_note, (deletable, ))
                    conn.commit()
                cur.execute(select_count_findings_notes_finding_id,
                            (self.finding_id, ))
                note_count_per_finding = cur.fetchone()[0]

            cur.close()
            conn.close()

            self.toc.selection_clear()

            if note_count_per_finding == 0:
                self.pressed.config(text='     ')

            self.refresh()

        selected = self.toc.curselection()
        subtopic = self.toc.get(selected)
        if subtopic is None:
            return

        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()
        cur.execute(select_note_id, (subtopic, ))
        deletable = cur.fetchone()
        if deletable is None:
            return
        elif deletable is not None:
            deletable = deletable[0]

        delete_var = tk.IntVar()

        deleter = Toplevel(self)
        deleter.title('Delete Note Dialog')

        instrux = LabelH3(
            deleter, text='Any note can be linked to any number of entities.')

        radio1 = Radiobutton(deleter,
                             text='Delete this instance of this note.',
                             value=0,
                             variable=delete_var)

        radio2 = Radiobutton(deleter,
                             text='Delete all instances of this note.',
                             value=1,
                             variable=delete_var)

        instrux.grid(column=0, row=0, columnspan=2, padx=24, pady=24)
        radio1.grid(column=0, row=1)
        radio2.grid(column=1, row=1)

        buttonbox = Frame(deleter)
        buttonbox.grid(column=1, row=2, sticky='e')
        b1 = Button(buttonbox, text='OK', command=ok_delete)
        b2 = Button(buttonbox, text='Cancel', command=cancel_delete)
        b1.grid(column=0, row=0)
        b2.grid(column=1, row=0)

    def refresh(self):

        self.refresh_notes_per_finding()
        self.toc.make_listbox_content()
        self.subtopic_widgets = self.toc.listbox_content.winfo_children()
        for child in self.subtopic_widgets:
            child.bind('<<ListboxSelected>>', self.switch_note)

    def reorder_notes(self):
        '''
        '''
        if self.toc.size() < 2:
            return

        self.order_dlg = Toplevel(self)
        self.order_dlg.grab_set()
        self.order_dlg.protocol('WM_DELETE_WINDOW', self.ignore_changes)
        self.order_dlg.bind('<Return>', self.save_close_reorder_dlg)
        self.order_dlg.bind('<Escape>', self.ignore_changes)
        self.order_dlg.grid_columnconfigure(0, weight=1)
        self.order_dlg.title('Reorder Subtopics')

        instrux = ('Tab or Ctrl+Tab selects movable subtopic.\n'
                   'Arrow keys change subtopic order up or down.')

        top = LabelH3(self.order_dlg, text=instrux, anchor='center')

        self.labels = Frame(self.order_dlg)

        e = 0
        for subtopic in self.subtopics:
            lab = LabelMovable(self.labels, text=subtopic, anchor='w')
            if e == 0:
                first = lab
            e += 1
            lab.grid(column=0, row=e, padx=3, sticky='ew')
        first.focus_set()

        close2 = Button(self.order_dlg,
                        text='OK',
                        command=self.save_close_reorder_dlg)

        top.grid(column=0, row=0, pady=(24, 0), padx=24, columnspan=2)
        self.labels.grid(column=0, row=1, columnspan=2, padx=24, pady=24)
        self.labels.grid_columnconfigure(0, weight=1)
        close2.grid(column=1, row=2, sticky='se', padx=12, pady=(0, 12))

        center_window(self.order_dlg)

    def ignore_changes(self, evt=None):
        self.order_dlg.grab_release()
        self.order_dlg.destroy()
        self.focus_set()

    def save_close_reorder_dlg(self, evt=None):
        '''
            Replace the values list.
        '''

        q = 0
        new_order = []
        save_order = []
        for child in self.labels.winfo_children():
            text = child.cget('text')
            new_order.append(text)
            save_order.append([text, q])
            q += 1

        conn = sqlite3.connect(self.current_file)
        conn.execute('PRAGMA foreign_keys = 1')
        cur = conn.cursor()

        for lst in save_order:
            cur.execute(select_note_id, (lst[0], ))
            note_id = cur.fetchone()[0]
            cur.execute(update_findings_notes,
                        (lst[1], self.finding_id, note_id))
            conn.commit()
        cur.close()
        conn.close()
        self.subtopics = self.toc.items = new_order
        self.refresh()
        self.order_dlg.grab_release()
        self.order_dlg.destroy()
        self.focus_set()