commit
2d76ec8c54
|
@ -58,10 +58,7 @@ def get_demo_path():
|
|||
|
||||
def get_editor():
|
||||
try: # in case running with old version of PySimpleGUI that doesn't have a global PSG settings path
|
||||
if sg.pysimplegui_user_settings:
|
||||
global_editor = sg.pysimplegui_user_settings.get('-editor program-')
|
||||
else:
|
||||
global_editor = ''
|
||||
global_editor = sg.pysimplegui_user_settings.get('-editor program-')
|
||||
except:
|
||||
global_editor = ''
|
||||
|
||||
|
@ -90,7 +87,7 @@ def find_in_file(string):
|
|||
for file in demo_files:
|
||||
filename = os.path.join(demo_path, file)
|
||||
try:
|
||||
with open(filename, 'r') as f:
|
||||
with open(filename, 'r', encoding="utf8") as f:
|
||||
for line in f.readlines():
|
||||
if string in line.lower():
|
||||
file_list.append(file)
|
||||
|
@ -125,7 +122,7 @@ def settings_window():
|
|||
event, values = window.read(close=True)
|
||||
if event == 'Ok':
|
||||
sg.user_settings_set_entry('-demos folder-', values['-DEMOS-'])
|
||||
new_editor = global_editor if not values['-EDITOR PROGRAM-'] else values['-EDITOR PROGRAM-']
|
||||
new_editor = editor_program if not values['-EDITOR PROGRAM-'] else values['-EDITOR PROGRAM-']
|
||||
sg.user_settings_set_entry('-editor program-', new_editor)
|
||||
new_theme = sg.theme_global() if values['-THEME-'] == '' else values['-THEME-']
|
||||
sg.user_settings_set_entry('-theme-', new_theme)
|
||||
|
@ -200,8 +197,8 @@ def main():
|
|||
for file in values['-DEMO LIST-']:
|
||||
sg.cprint(f'Editing using {editor_program}', text_color='white', background_color='red', end='')
|
||||
sg.cprint('')
|
||||
sg.cprint(f'{os.path.join(demo_path, file)}', text_color='white', background_color='purple')
|
||||
execute_command_subprocess(f'{editor_program}', os.path.join(demo_path, file))
|
||||
sg.cprint(f'{os.path.join(demo_path, file)}', t='white', b='purple')
|
||||
execute_command_subprocess(f'{editor_program}', f'"{os.path.join(demo_path, file)}"')
|
||||
elif event == 'Run':
|
||||
sg.cprint('Running....', c='white on green', end='')
|
||||
sg.cprint('')
|
||||
|
@ -209,8 +206,8 @@ def main():
|
|||
sg.cprint(os.path.join(demo_path, file),text_color='white', background_color='purple')
|
||||
run_py(os.path.join(demo_path, file))
|
||||
elif event.startswith('Edit Me'):
|
||||
sg.cprint(f'opening using {editor_program}\nThis file - {__file__}', text_color='white', background_color='green', end='')
|
||||
execute_command_subprocess(f'{editor_program}', __file__)
|
||||
sg.cprint(f'opening using {editor_program}\nThis file - {__file__}', t='white', b='green', end='')
|
||||
execute_command_subprocess(f'{editor_program}', f'"{__file__}"')
|
||||
elif event == '-FILTER-':
|
||||
new_list = [i for i in demo_files if values['-FILTER-'].lower() in i.lower()]
|
||||
window['-DEMO LIST-'].update(new_list)
|
||||
|
|
|
@ -72,7 +72,7 @@ def find_in_file(string):
|
|||
for file in demo_files:
|
||||
filename = os.path.join(demo_path, file)
|
||||
try:
|
||||
with open(filename, 'r') as f:
|
||||
with open(filename, 'r', encoding="utf8") as f:
|
||||
for line in f.readlines():
|
||||
if string in line.lower():
|
||||
file_list.append(file)
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
from idlelib import tooltip
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
PySimpleGUI Code Finder & Launcher
|
||||
|
||||
Use to filter and search your source code tree.
|
||||
Then run or edit your files
|
||||
|
||||
Filter the list of :
|
||||
* Search using filename
|
||||
* Searching within the demo program's source code (like grep)
|
||||
|
||||
The basic file operations are
|
||||
* Edit a file in your editor
|
||||
* Run a file
|
||||
* Filter file list
|
||||
* Search in files
|
||||
|
||||
Additional operations
|
||||
* Edit this file in editor
|
||||
|
||||
Copyright 2021 PySimpleGUI.org
|
||||
"""
|
||||
|
||||
|
||||
|
||||
def get_demo_git_files():
|
||||
"""
|
||||
Get the files in the demo and the GitHub folders
|
||||
Returns files as 2 lists
|
||||
|
||||
:return: two lists of files
|
||||
:rtype: Tuple[List[str], List[str]]
|
||||
"""
|
||||
|
||||
demo_path = get_demo_path()
|
||||
demo_files_dict = {}
|
||||
for dirname, dirnames, filenames in os.walk(demo_path):
|
||||
for filename in filenames:
|
||||
if filename.endswith('.py'):
|
||||
fname_full = os.path.join(dirname, filename)
|
||||
if filename not in demo_files_dict.keys():
|
||||
demo_files_dict[filename] = fname_full
|
||||
else:
|
||||
# print(f'duplicate filename found {filename} path {dirname}')
|
||||
demo_files_dict[f'{filename}_1'] = fname_full
|
||||
|
||||
return demo_files_dict
|
||||
|
||||
|
||||
def get_demo_path():
|
||||
demo_path = sg.user_settings_get_entry('-demos folder-', os.path.dirname(__file__))
|
||||
|
||||
return demo_path
|
||||
|
||||
|
||||
def get_editor():
|
||||
try: # in case running with old version of PySimpleGUI that doesn't have a global PSG settings path
|
||||
global_editor = sg.pysimplegui_user_settings.get('-editor program-')
|
||||
except:
|
||||
global_editor = ''
|
||||
|
||||
return sg.user_settings_get_entry('-editor program-', global_editor)
|
||||
|
||||
|
||||
def get_theme():
|
||||
try:
|
||||
global_theme = sg.theme_global()
|
||||
except:
|
||||
global_theme = sg.theme()
|
||||
|
||||
return sg.user_settings_get_entry('-theme-', global_theme)
|
||||
|
||||
def find_in_file(string):
|
||||
"""
|
||||
Search through the demo files for a string.
|
||||
The case of the string and the file contents are ignored
|
||||
|
||||
:param string: String to search for
|
||||
:return: List of files containing the string
|
||||
:rtype: List[str]
|
||||
"""
|
||||
|
||||
demo_files_dict = get_demo_git_files()
|
||||
string = string.lower()
|
||||
file_list = []
|
||||
for file in demo_files_dict:
|
||||
full_filename = demo_files_dict[file]
|
||||
try:
|
||||
with open(full_filename, 'r', encoding="utf8") as f:
|
||||
for line in f.readlines():
|
||||
if string in line.lower():
|
||||
file_list.append(file)
|
||||
# print(f'{os.path.basename(file)} -- {line}')
|
||||
except Exception as e:
|
||||
pass
|
||||
print(f'{file}',e)
|
||||
return list(set(file_list))
|
||||
|
||||
|
||||
def settings_window():
|
||||
"""
|
||||
Show the settings window.
|
||||
This is where the folder paths and program paths are set.
|
||||
Returns True if settings were changed
|
||||
|
||||
:return: True if settings were changed
|
||||
:rtype: (bool)
|
||||
"""
|
||||
|
||||
editor_program = get_editor()
|
||||
|
||||
layout = [[sg.T('Program Settings', font='DEFAIULT 18')],
|
||||
[sg.T('Path to Demos', size=(20,1)), sg.In(sg.user_settings_get_entry('-demos folder-', '.'), k='-DEMOS-'), sg.FolderBrowse()],
|
||||
[sg.T('Editor Program', size=(20,1)), sg.In(sg.user_settings_get_entry('-editor program-', editor_program),k='-EDITOR PROGRAM-'), sg.FileBrowse()],
|
||||
[sg.T(r"For PyCharm, Add this to your PyCharm main program's folder \bin\pycharm.bat")],
|
||||
[sg.Combo(['']+sg.theme_list(), sg.user_settings_get_entry('-theme-', None), k='-THEME-')],
|
||||
[sg.B('Ok', bind_return_key=True), sg.B('Cancel')],
|
||||
]
|
||||
|
||||
window = sg.Window('Settings', layout)
|
||||
event, values = window.read(close=True)
|
||||
if event == 'Ok':
|
||||
sg.user_settings_set_entry('-demos folder-', values['-DEMOS-'])
|
||||
new_editor = editor_program if not values['-EDITOR PROGRAM-'] else values['-EDITOR PROGRAM-']
|
||||
sg.user_settings_set_entry('-editor program-', new_editor)
|
||||
new_theme = sg.theme_global() if values['-THEME-'] == '' else values['-THEME-']
|
||||
sg.user_settings_set_entry('-theme-', new_theme)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
# --------------------------------- Create the window ---------------------------------
|
||||
def make_window():
|
||||
"""
|
||||
Creates the main window
|
||||
:return: The main window object
|
||||
:rtype: (Window)
|
||||
"""
|
||||
|
||||
theme = get_theme()
|
||||
editor = get_editor()
|
||||
demo_files_dict = get_demo_git_files()
|
||||
if not theme:
|
||||
theme = sg.OFFICIAL_PYSIMPLEGUI_THEME
|
||||
sg.theme(theme)
|
||||
# First the window layout...2 columns
|
||||
|
||||
find_tooltip = "Find in file\nEnter a string in box to search for string inside of the files.\nFile list will update with list of files string found inside."
|
||||
filter_tooltip = "Filter files\nEnter a string in box to narrow down the list of files.\nFile list will update with list of files with string in filename."
|
||||
|
||||
ML_KEY = '-ML-' # Multline's key
|
||||
|
||||
left_col = [
|
||||
[sg.Listbox(values=list(demo_files_dict.keys()), select_mode=sg.SELECT_MODE_EXTENDED, size=(40, 20), key='-DEMO LIST-')],
|
||||
[sg.Text('Filter:', tooltip=filter_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FILTER-', tooltip=filter_tooltip),
|
||||
sg.T(size=(20,1), k='-FILTER NUMBER-')],
|
||||
[sg.Button('Run'), sg.B('Edit'), sg.B('Clear')],
|
||||
[sg.Text('Find:', tooltip=find_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FIND-', tooltip=find_tooltip),
|
||||
sg.T(size=(20,1), k='-FIND NUMBER-')]]
|
||||
|
||||
right_col = [
|
||||
[sg.Multiline(size=(70, 21), write_only=True, key=ML_KEY, reroute_stdout=True, echo_stdout_stderr=True)],
|
||||
[sg.Button('Edit Me (this program)'), sg.B('Settings'), sg.Button('Exit')],
|
||||
[sg.T('PySimpleGUI ver ' + sg.version.split(' ')[0] + ' tkinter ver ' + sg.tclversion_detailed, font='Default 8', pad=(0,0))],
|
||||
]
|
||||
|
||||
# ----- Full layout -----
|
||||
|
||||
layout = [[sg.Text('PySimpleGUI Project File Searcher & Launcher', font='Any 20')],
|
||||
[sg.T('Click settings to set top of your tree')],
|
||||
sg.vtop([sg.Column(left_col, element_justification='c'), sg.Col(right_col, element_justification='c') ])]
|
||||
|
||||
# --------------------------------- Create Window ---------------------------------
|
||||
window = sg.Window('PSG Finder Launcher', layout)
|
||||
|
||||
sg.cprint_set_output_destination(window, ML_KEY)
|
||||
return window
|
||||
# --------------------------------- Main Program Layout ---------------------------------
|
||||
|
||||
def main():
|
||||
"""
|
||||
The main program that contains the event loop.
|
||||
It will call the make_window function to create the window.
|
||||
"""
|
||||
|
||||
editor_program = get_editor()
|
||||
demo_files_dict = get_demo_git_files()
|
||||
demo_files = demo_files_dict.keys()
|
||||
window = make_window()
|
||||
|
||||
while True:
|
||||
event, values = window.read()
|
||||
if event in (sg.WINDOW_CLOSED, 'Exit'):
|
||||
break
|
||||
if event == 'Edit':
|
||||
for file in values['-DEMO LIST-']:
|
||||
sg.cprint(f'Editing using {editor_program}', text_color='white', background_color='red', end='')
|
||||
sg.cprint('')
|
||||
sg.cprint(f'{demo_files_dict[file]}', text_color='white', background_color='purple')
|
||||
sg.execute_subprocess_nonblocking(f'{editor_program}', f'"{demo_files_dict[file]}"')
|
||||
elif event == 'Run':
|
||||
sg.cprint('Running....', c='white on green', end='')
|
||||
sg.cprint('')
|
||||
sg.cprint(f"Chose {values['-DEMO LIST-']}")
|
||||
for file in values['-DEMO LIST-']:
|
||||
file_to_run = str(demo_files_dict[file])
|
||||
sg.cprint(file_to_run,text_color='white', background_color='purple')
|
||||
sg.execute_subprocess_nonblocking('python' if sg._running_windows() else 'python3', f'"{file_to_run}"')
|
||||
# run_py(file_to_run)
|
||||
elif event.startswith('Edit Me'):
|
||||
sg.cprint(f'opening using {editor_program}\nThis file - {__file__}', text_color='white', background_color='green', end='')
|
||||
sg.execute_subprocess_nonblocking(f'{editor_program}', f'"{__file__}"')
|
||||
elif event == '-FILTER-':
|
||||
new_list = [i for i in demo_files if values['-FILTER-'].lower() in i.lower()]
|
||||
window['-DEMO LIST-'].update(new_list)
|
||||
window['-FILTER NUMBER-'].update(f'{len(new_list)} files')
|
||||
window['-FIND NUMBER-'].update('')
|
||||
window['-FIND-'].update('')
|
||||
elif event == '-FIND-':
|
||||
file_list = find_in_file(values['-FIND-'])
|
||||
window['-DEMO LIST-'].update(sorted(file_list))
|
||||
window['-FIND NUMBER-'].update(f'{len(file_list)} files')
|
||||
window['-FILTER NUMBER-'].update('')
|
||||
window['-FILTER-'].update('')
|
||||
elif event == 'Settings':
|
||||
if settings_window() is True:
|
||||
window.close()
|
||||
window = make_window()
|
||||
editor_program = get_editor()
|
||||
demo_files_dict = get_demo_git_files()
|
||||
demo_files = demo_files_dict.keys()
|
||||
elif event == 'Clear':
|
||||
window['-FILTER-'].update('')
|
||||
window['-FIND-'].update('')
|
||||
window['-DEMO LIST-'].update(demo_files)
|
||||
window['-FILTER NUMBER-'].update('')
|
||||
window['-FIND NUMBER-'].update('')
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
main()
|
Loading…
Reference in New Issue