Beispiel #1
0
def readme_popup(main_dir, icon):
    with open(f'{main_dir}/resources/README.txt', 'r',
              encoding='utf-8') as file:
        readme = file.read()
    layout = [[sg.Multiline(readme, size=(100, 50))],
              [sg.Button('Close', pad=(10, 10))]]
    popup = sg.Window('About', layout, icon=icon)
    popup.read()
    popup.close()
Beispiel #2
0
def get_graph_element():
    dot_exists = find_executable('dot')
    if dot_exists:
        graph_elem = sg.Image(filename=f'{main_dir}/resources/blank_graph.png',
                              key='-graph-',
                              enable_events=True)
    else:
        graph_elem = sg.Text('', key='-graph-')
    return [[graph_elem]], dot_exists
Beispiel #3
0
def okay_or_cancel(message: str, title: str):
    layout = [[sg.Text(message, pad=(10, 10))],
              [sg.Button('Okay'),
               sg.Stretch(),
               sg.Button('Cancel')]]
    popup = sg.Window(title, layout, icon=icon)
    response, _ = popup.read()
    popup.close()
    return response
Beispiel #4
0
def add_arc_main(arcs, values: dict, app, selected_app, ref, nodes, main_dir):
    if selected_app is None:
        return arcs, app
    if is_different(values['-stemma_from-'], values['-stemma_to-']) is False:
        return arcs, app
    new_arcs, app = xp.add_arc(app, values['-stemma_from-'],
                               values['-stemma_to-'])
    if new_arcs is not None:
        arcs = new_arcs
        pg.make_graph(arcs, selected_app, ref, nodes, main_dir,
                      graph_text_color, graph_text_color, line_color,
                      orientation)
        return arcs, app
    sg.popup_quick_message('Relationship already exists')
    return arcs, app
Beispiel #5
0
def initial_units_row():
    row = []
    for i in range(20):
        row.append(
            sg.Text('',
                    visible=False,
                    key=f'unit{i}',
                    justification='center',
                    pad=(2, 3)))
    return row
Beispiel #6
0
def initial_basetext_rows():
    row1 = []
    row2 = []
    row3 = []
    row4 = []
    key = 0
    for _ in range(20):
        row1.append(
            sg.Text('',
                    visible=False,
                    key=f'bt{key}',
                    justification='center',
                    pad=(2, 3)))
        row1.append(sg.Stretch())
        key += 1
    for _ in range(20):
        row2.append(
            sg.Text('',
                    visible=False,
                    key=f'bt{key}',
                    justification='center',
                    pad=(2, 3)))
        row2.append(sg.Stretch())
        key += 1
    for _ in range(20):
        row3.append(
            sg.Text('',
                    visible=False,
                    key=f'bt{key}',
                    justification='center',
                    pad=(2, 3)))
        row3.append(sg.Stretch())
        key += 1
    for _ in range(20):
        row4.append(
            sg.Text('',
                    visible=False,
                    key=f'bt{key}',
                    justification='center',
                    pad=(2, 3)))
        row4.append(sg.Stretch())
        key += 1
    return row1, row2, row3, row4
Beispiel #7
0
def okay_popup(message: str, title: str):
    layout = [[sg.Text(message, pad=(10, 10))], [sg.Button('Okay')]]
    popup = sg.Window(title, layout, icon=icon)
    popup.read()
    popup.close()
Beispiel #8
0
def main():
    settings = get_settings(main_dir)
    layout, dot_exists = get_layout(settings)
    window = sg.Window('Apparatus Explorer v 0.9',
                       layout,
                       icon=icon,
                       size=(1800, 500))
    root = None
    ###########################################################
    '''Main Loop'''
    ###########################################################
    ref = basetext = all_apps = selected_app = rdgs = nodes = ab = tree = initial_fn = app = arcs = None
    while True:
        event, values = window.read()

        if event in [sg.WINDOW_CLOSED, None]:
            break

        elif event == 'Load File':
            if values['-xml_input-'] != '':
                xml_file = values['-xml_input-']
                if is_xml_reformatted(xml_file) is False:
                    sg.popup_quick_message('Reformatting XML file...')
                    xml_file = reformat_xml(xml_file)
                    xml_file = ds.differentiate_subreading_ids(xml_file)
                    window['-xml_input-'].update(value=xml_file)
                try:
                    tree, root, ab, ref, basetext, all_apps, selected_app, rdgs, arcs, nodes, app = xp.initialize_apparatus(
                        xml_file, settings['ignore'])
                    refresh_gui(window, ref, basetext, all_apps, selected_app,
                                rdgs, arcs, dot_exists, main_dir, nodes)
                    set_buttons(window, app, ab)
                    enable_editing_buttons(window)
                    initial_fn = values['-xml_input-']
                except:
                    okay_popup(
                        'Failed to load XML file.\n\
XML file must be the output of the ITSEE and INTF Collation Editor.',
                        'Failed to Parse XML')
            else:
                sg.popup_quick_message(
                    'Select a valid XML TEI encoded apparatus.')

        elif event == '-update_verse-':
            ref, basetext, all_apps, app, selected_app, rdgs, arcs, nodes, ab = xp.load_new_verse(
                root, values['-verse-'], settings['ignore'])
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)
            set_buttons(window, app, ab)

        elif event == '-next_verse-':
            ref, basetext, all_apps, app, selected_app, rdgs, arcs, nodes, ab = xp.verse_from_ab(
                ab.getnext(), settings['ignore'])
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)
            set_buttons(window, app, ab)

        elif event == '-prev_verse-':
            ref, basetext, all_apps, app, selected_app, rdgs, arcs, nodes, ab = xp.verse_from_ab(
                ab.getprevious(), settings['ignore'])
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)
            set_buttons(window, app, ab)

        elif event == '-next_app-':
            selected_app, rdgs, arcs, nodes, app = xp.load_app(app, 'next')
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)
            set_buttons(window, app, ab)

        elif event == '-prev_app-':
            selected_app, rdgs, arcs, nodes, app = xp.load_app(app, 'prev')
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)
            set_buttons(window, app, ab)

        elif event == '-save_xml-':
            response = okay_or_cancel(
                'Overwrite the original file?\n\
To save a copy, select "Save As" from the File menu.', 'Save Collation')
            if response == 'Okay':
                xp.save_xml(tree, initial_fn)
                settings['last_opened'] = initial_fn
                save_settings(settings, main_dir)

        elif event == '-update_reading-':
            if selected_app is None or values['-edit_rdg-'] in [
                    '', '        ', None
            ]:
                continue
            app, rdgs = xp.update_reading_type(app, values['-edit_type-'],
                                               values['-edit_rdg-'])
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)

        elif event == '-delete_reading-':
            if selected_app is None or values['-edit_rdg-'] in [
                    '', '        ', None
            ]:
                continue
            app, rdgs = xp.delete_rdg(app, values['-edit_rdg-'])
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)

        elif event == '-add_arc-':
            if selected_app is None:
                continue
            arcs, app = add_arc_main(arcs, values, app, selected_app, ref,
                                     nodes, main_dir)
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)

        elif event == '-delete_arc-':
            if selected_app is None:
                continue
            arcs, app = delete_arc_main(values, arcs, app, selected_app, ref,
                                        nodes, main_dir)
            refresh_gui(window, ref, basetext, all_apps, selected_app, rdgs,
                        arcs, dot_exists, main_dir, nodes)

        elif event == '-graph-':
            open_graph()

        elif event == 'Save As':
            new_fn = sg.popup_get_file('',
                                       no_window=True,
                                       file_types=(("XML Files", "*.xml"), ),
                                       save_as=True)
            if new_fn:
                fn = xp.save_xml(tree, new_fn)
                settings['last_opened'] = fn
                save_settings(settings, main_dir)
                okay_popup(f'Saved to\n{fn}', 'Saved!')

        elif event == 'Settings':
            settings = set_settings(settings, main_dir, icon)

        elif event == 'About':
            readme_popup(main_dir, icon)

        elif event == 'Combine XML Files':
            result = combine_xml_files_interface(settings, icon, main_dir)
            if result is not None:
                settings = result
                save_settings(settings, main_dir)

        # print(event, values)

    window.close()
Beispiel #9
0
def get_layout(settings):
    units_row = initial_units_row()
    bt1, bt2, bt3, bt4 = initial_basetext_rows()
    menu = [[
        'File',
        ['!Save As', '---', 'Combine XML Files', '---', 'Settings', 'About']
    ]]
    verse_frame = [[
        sg.Stretch(),
        sg.Button('<Prev', key='-prev_verse-', disabled=True),
        sg.Input('', key='-verse-'),
        sg.Button('Next>', key='-next_verse-', disabled=True),
        sg.Stretch()
    ],
                   [
                       sg.Stretch(),
                       sg.Button('Update', key='-update_verse-',
                                 disabled=True),
                       sg.Stretch()
                   ]]
    units_frame = [[sg.Button(' <Prev ', key='-prev_app-', disabled=True)] +
                   units_row +
                   [sg.Button(' Next> ', key='-next_app-', disabled=True)]]

    basetext_frame = [bt1, bt2, bt3, bt4]

    edit_readings_frame = [
        [sg.Text('')],
        [
            sg.Text('Reading:'),
            sg.Combo(['        '], readonly=True, key='-edit_rdg-')
        ],
        [
            sg.Text('Type:'),
            sg.Combo(['Defective', 'Orthographic', 'Lacunose', 'Subreading'],
                     readonly=True,
                     key='-edit_type-')
        ], [sg.Text('')], [sg.Text('')], [sg.Text('')],
        [sg.Button('Update', key='-update_reading-', disabled=True)],
        [sg.Button('Delete', key='-delete_reading-', disabled=True)]
    ]
    edit_stemma_frame = [
        [sg.Text('')],
        [
            sg.Combo(['        '], readonly=True, key='-stemma_from-'),
            sg.Text('➜', justification='center'),
            sg.Combo(['        '], readonly=True, key='-stemma_to-')
        ], [sg.Text('')], [sg.Text('')], [sg.Text('')], [sg.Text('')],
        [sg.Button('Add Relationship', key='-add_arc-', disabled=True)],
        [sg.Button('Delete Relationship', key='-delete_arc-', disabled=True)]
    ]
    stemma_frame, dot_exists = get_graph_element()

    xml_input_frame = [[
        sg.Text('TEI XML Collation File:'),
        sg.Input(settings['last_opened'], key='-xml_input-'),
        sg.FileBrowse('Browse', file_types=(("XML Files", "*.xml"), )),
        sg.Button('Load File'),
        sg.Button('Save', key='-save_xml-', disabled=True)
    ]]

    layout = [[sg.Menu(menu, key='-menu-')],
              [
                  sg.Text('XML TEI Apparatus Explorer and Editor',
                          justification='center')
              ], [sg.Frame('', verse_frame, border_width=3)],
              [sg.Frame('Variation Units', units_frame)],
              [sg.Frame('Basetext', basetext_frame)],
              [sg.MultilineOutput('', key='-rdgs-')],
              [
                  sg.Frame('Local Stemma', stemma_frame),
                  sg.Frame('Edit Readings', edit_readings_frame),
                  sg.Frame('Edit Local Stemma', edit_stemma_frame)
              ], [sg.Frame('', xml_input_frame)]]

    return layout, dot_exists
Beispiel #10
0
def is_different(value_a, value_b):
    if value_a != value_b:
        return True
    sg.popup_quick_message('"From" and "To" cannot be equal')
    return False
Beispiel #11
0
            'last_opened': '',
            'last_opened_dir': '',
            'graph_bg_color': '#ffffff00',
            'ignore': {
                'lac': False,
                'subr': False
            }
        }
        with open(f'{main_dir}/resources/settings.json', 'w') as file:
            json.dump(settings, file, indent=4)
    return settings


main_dir = pathlib.Path(__file__).parent.as_posix()
settings = get_settings(main_dir)
orientation = settings[
    'graph_orientation']  # rankdir="LR" for horizontal, empty str for vertical
graph_bg_color = settings['graph_bg_color']
graph_text_color, selected_app_color, color_theme, line_color = get_theme(
    settings['theme'])
sg.theme(color_theme)
icon = f'{main_dir}/resources/apparatusexplorer.ico'
sg.set_options(font=('Cambria', 12), element_padding=(3, 5))

try:
    ctypes.windll.shcore.SetProcessDpiAwareness(
        settings['dpi']
    )  # High resolution Windows machines have scaling issues
except:
    pass
def combine_xml_files_interface(settings, icon, main_dir):
    layout = [
        [sg.Text('Select the folder that contains the individual XML files to be combined')],
        [sg.Text('Folder:'), sg.Input('', key='output_dir'), sg.FolderBrowse(initial_folder=settings['last_opened_dir'])],
        [sg.Text('Combine all files that start with:'), sg.Stretch(), sg.Input('', key='starts_with')],
        [sg.Button('Combine XML Files'), sg.Button('Cancel')]
    ]
    window = sg.Window('Combine XML Files', layout, icon=icon)
    while True:
        event, values = window.read()
        if event in [sg.WINDOW_CLOSED, 'Cancel']:
            window.close()
            return None
        elif event == 'Combine XML Files':
            if values['output_dir'] == '' or values['starts_with'] == '':
                sg.popup_quick_message('First select a folder and at least one "starts with" character')
                continue
            try:
                tree = combine_verses(values['starts_with'], values['output_dir'], main_dir)
            except:
                okay_popup('Failed to combine files.\n\
Double-check that the selected folder contains XML files and that\n\
these match the given "starts with" characters', 'Bummer', icon)
                continue
            saved_name = sg.popup_get_file('', no_window=True, file_types=(("XML Files", "*.xml"),), save_as=True, initial_folder=values['output_dir'])
            tree.write(saved_name, encoding='utf-8', xml_declaration=True)
            settings['last_opened_dir'] = values['output_dir']
            okay_popup(f'Files have been combined and saved to {saved_name}', 'Combined!', icon)
            window.close()
            return settings