|
@@ -1,5 +1,7 @@
|
|
|
# TODO Lot of hardcoded shizzle
|
|
# TODO Lot of hardcoded shizzle
|
|
|
|
|
+import enum
|
|
|
import logging
|
|
import logging
|
|
|
|
|
+import sys
|
|
|
from itertools import groupby
|
|
from itertools import groupby
|
|
|
from typing import Optional, List, Union
|
|
from typing import Optional, List, Union
|
|
|
from urllib.error import URLError
|
|
from urllib.error import URLError
|
|
@@ -13,22 +15,47 @@ from graph_exploring_tool.query import QueryTemplate
|
|
|
|
|
|
|
|
arklog.set_config_logging()
|
|
arklog.set_config_logging()
|
|
|
|
|
|
|
|
-# TODO Add color coding
|
|
|
|
|
-def set_status_text(message: str):
|
|
|
|
|
|
|
+class StatusMessageType(enum.Enum):
|
|
|
|
|
+ DEFAULT = 0
|
|
|
|
|
+ WARNING = 1
|
|
|
|
|
+ ERROR = 2
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+STATUS_CONSOLE_TAG = "__status_console"
|
|
|
|
|
+QUERY_FILTER_TAG = "__query_filter"
|
|
|
|
|
+ENDPOINT_TEXTINPUT_TAG = "__endpoint_input"
|
|
|
|
|
+POST_METHOD_CHECKBOX_TAG = "__use_post_method"
|
|
|
|
|
+
|
|
|
|
|
+RADIO_BUTTON_TYPE = "mvAppItemType::mvRadioButton"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def set_status_text(message: str, message_type: StatusMessageType = StatusMessageType.DEFAULT):
|
|
|
"""Set the text displayed on the status bar."""
|
|
"""Set the text displayed on the status bar."""
|
|
|
- dpg.set_value("__status_console", message)
|
|
|
|
|
|
|
+ dpg.set_value(STATUS_CONSOLE_TAG, message)
|
|
|
|
|
+ with dpg.theme() as default_theme:
|
|
|
|
|
+ with dpg.theme_component(dpg.mvAll):
|
|
|
|
|
+ dpg.add_theme_color(dpg.mvThemeCol_Text, (255, 255, 255), category=dpg.mvThemeCat_Core)
|
|
|
|
|
+ with dpg.theme() as warning_theme:
|
|
|
|
|
+ with dpg.theme_component(dpg.mvAll):
|
|
|
|
|
+ dpg.add_theme_color(dpg.mvThemeCol_Text, (50, 200, 50), category=dpg.mvThemeCat_Core)
|
|
|
|
|
+ with dpg.theme() as error_theme:
|
|
|
|
|
+ with dpg.theme_component(dpg.mvAll):
|
|
|
|
|
+ dpg.add_theme_color(dpg.mvThemeCol_Text, (200, 50, 50), category=dpg.mvThemeCat_Core)
|
|
|
|
|
+ if message_type == StatusMessageType.DEFAULT:
|
|
|
|
|
+ dpg.bind_item_theme(STATUS_CONSOLE_TAG, default_theme)
|
|
|
|
|
+ elif message_type == StatusMessageType.WARNING:
|
|
|
|
|
+ dpg.bind_item_theme(STATUS_CONSOLE_TAG, warning_theme)
|
|
|
|
|
+ elif message_type == StatusMessageType.ERROR:
|
|
|
|
|
+ dpg.bind_item_theme(STATUS_CONSOLE_TAG, error_theme)
|
|
|
|
|
|
|
|
def _config(sender, keyword, user_data):
|
|
def _config(sender, keyword, user_data):
|
|
|
widget_type = dpg.get_item_type(sender)
|
|
widget_type = dpg.get_item_type(sender)
|
|
|
items = user_data
|
|
items = user_data
|
|
|
-
|
|
|
|
|
- if widget_type == "mvAppItemType::mvRadioButton":
|
|
|
|
|
|
|
+ if widget_type == RADIO_BUTTON_TYPE:
|
|
|
value = True
|
|
value = True
|
|
|
-
|
|
|
|
|
else:
|
|
else:
|
|
|
keyword = dpg.get_item_label(sender)
|
|
keyword = dpg.get_item_label(sender)
|
|
|
value = dpg.get_value(sender)
|
|
value = dpg.get_value(sender)
|
|
|
-
|
|
|
|
|
if isinstance(user_data, list):
|
|
if isinstance(user_data, list):
|
|
|
for item in items:
|
|
for item in items:
|
|
|
dpg.configure_item(item, **{keyword: value})
|
|
dpg.configure_item(item, **{keyword: value})
|
|
@@ -38,23 +65,22 @@ def _config(sender, keyword, user_data):
|
|
|
def add_main_menu():
|
|
def add_main_menu():
|
|
|
with dpg.menu_bar():
|
|
with dpg.menu_bar():
|
|
|
with dpg.menu(label="Menu"):
|
|
with dpg.menu(label="Menu"):
|
|
|
- dpg.add_menu_item(label="New")
|
|
|
|
|
- dpg.add_menu_item(label="Open")
|
|
|
|
|
- with dpg.menu(label="Open Recent"):
|
|
|
|
|
- dpg.add_menu_item(label="patty.h")
|
|
|
|
|
- dpg.add_menu_item(label="nick.py")
|
|
|
|
|
- dpg.add_menu_item(label="Save")
|
|
|
|
|
- dpg.add_menu_item(label="Exit")
|
|
|
|
|
|
|
+ # dpg.add_menu_item(label="New")
|
|
|
|
|
+ # dpg.add_menu_item(label="Open")
|
|
|
|
|
+ # with dpg.menu(label="Open Recent"):
|
|
|
|
|
+ # dpg.add_menu_item(label="patty.h")
|
|
|
|
|
+ # dpg.add_menu_item(label="nick.py")
|
|
|
|
|
+ # dpg.add_menu_item(label="Save")
|
|
|
|
|
+ dpg.add_menu_item(label="Exit", callback=lambda _: sys.exit())
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO Add tab for prefixes
|
|
# TODO Add tab for prefixes
|
|
|
def create_query_palette(query_palette: List[QueryTemplate]):
|
|
def create_query_palette(query_palette: List[QueryTemplate]):
|
|
|
- demo_layout_child = dpg.generate_uuid()
|
|
|
|
|
- with dpg.child_window(tag=demo_layout_child, label="Query Palette", width=220, menubar=True):
|
|
|
|
|
|
|
+ with dpg.child_window(label="Query Palette", width=220, menubar=True):
|
|
|
with dpg.menu_bar():
|
|
with dpg.menu_bar():
|
|
|
dpg.add_menu(label="Query Palette", enabled=False)
|
|
dpg.add_menu(label="Query Palette", enabled=False)
|
|
|
- dpg.add_input_text(label="Filter", callback=lambda s, a: dpg.set_value("__query_filter", a))
|
|
|
|
|
- with dpg.filter_set(tag="__query_filter"):
|
|
|
|
|
|
|
+ dpg.add_input_text(label="Filter", callback=lambda s, a: dpg.set_value(QUERY_FILTER_TAG, a))
|
|
|
|
|
+ with dpg.filter_set(tag=QUERY_FILTER_TAG):
|
|
|
# TODO Populate from onto/base
|
|
# TODO Populate from onto/base
|
|
|
# TODO Bug fix this; actually figure out groups
|
|
# TODO Bug fix this; actually figure out groups
|
|
|
# TODO Fix filtering
|
|
# TODO Fix filtering
|
|
@@ -84,7 +110,7 @@ def create_query_palette(query_palette: List[QueryTemplate]):
|
|
|
def create_query_options(endpoint: str):
|
|
def create_query_options(endpoint: str):
|
|
|
with dpg.group(horizontal=True):
|
|
with dpg.group(horizontal=True):
|
|
|
dpg.add_combo(("Visual", "Textual"), default_value="Visual", callback=_mode_select, width=100, tag="__editor_selector")
|
|
dpg.add_combo(("Visual", "Textual"), default_value="Visual", callback=_mode_select, width=100, tag="__editor_selector")
|
|
|
- dpg.add_input_text(default_value=endpoint, width=300, enabled=False, tag="__endpoint_input")
|
|
|
|
|
|
|
+ dpg.add_input_text(default_value=endpoint, width=300, enabled=False, tag=ENDPOINT_TEXTINPUT_TAG)
|
|
|
dpg.add_checkbox(label="debug", callback=_config)
|
|
dpg.add_checkbox(label="debug", callback=_config)
|
|
|
dpg.add_checkbox(label="annotate", default_value=False, callback=_config) # TODO Actually make this annotate the result data with its type
|
|
dpg.add_checkbox(label="annotate", default_value=False, callback=_config) # TODO Actually make this annotate the result data with its type
|
|
|
|
|
|
|
@@ -100,7 +126,7 @@ def create_query_editor_visual(example_prefix:str, example_query:str, show: bool
|
|
|
with dpg.tab(label="Prefix", tag="__prefix_tab"):
|
|
with dpg.tab(label="Prefix", tag="__prefix_tab"):
|
|
|
dpg.add_input_text(default_value=example_prefix, callback=_log, multiline=True, on_enter=True, height=300, width=-1, tag="__prefix_editor_visual_input")
|
|
dpg.add_input_text(default_value=example_prefix, callback=_log, multiline=True, on_enter=True, height=300, width=-1, tag="__prefix_editor_visual_input")
|
|
|
with dpg.tab(label="Advanced", tag="__advanced_tab"):
|
|
with dpg.tab(label="Advanced", tag="__advanced_tab"):
|
|
|
- dpg.add_checkbox(label="Use post method", default_value=False, tag="__use_post_method")
|
|
|
|
|
|
|
+ dpg.add_checkbox(label="Use post method", default_value=False, tag=POST_METHOD_CHECKBOX_TAG)
|
|
|
with dpg.group(tag="__visual_editor_fields"):
|
|
with dpg.group(tag="__visual_editor_fields"):
|
|
|
# TODO Make more clear which placeholder is getting replaced (Maybe do it interactively, replace as user changes)
|
|
# TODO Make more clear which placeholder is getting replaced (Maybe do it interactively, replace as user changes)
|
|
|
pass
|
|
pass
|
|
@@ -129,7 +155,7 @@ def create_query_editor_textual(example_prefix:str, example_query:str, show: boo
|
|
|
def create_status_console():
|
|
def create_status_console():
|
|
|
with dpg.child_window(autosize_x=True, height=35):
|
|
with dpg.child_window(autosize_x=True, height=35):
|
|
|
with dpg.group(horizontal=True):
|
|
with dpg.group(horizontal=True):
|
|
|
- dpg.add_text(default_value="Ready.", tag="__status_console")
|
|
|
|
|
|
|
+ dpg.add_text(default_value="Ready.", tag=STATUS_CONSOLE_TAG)
|
|
|
|
|
|
|
|
def set_copy(element: Union[int, str], text_data:str):
|
|
def set_copy(element: Union[int, str], text_data:str):
|
|
|
dpg.set_value(element, shorten(text_data))
|
|
dpg.set_value(element, shorten(text_data))
|
|
@@ -183,12 +209,12 @@ def _query_palette_click(sender: int, mode: str, user_data: Optional[QueryTempla
|
|
|
mode = dpg.get_value("__editor_selector").lower().strip()
|
|
mode = dpg.get_value("__editor_selector").lower().strip()
|
|
|
if mode == "visual" and not user_data.visual_support:
|
|
if mode == "visual" and not user_data.visual_support:
|
|
|
logging.warning(f"Visual mode for template '{user_data.name}' not implemented yet!")
|
|
logging.warning(f"Visual mode for template '{user_data.name}' not implemented yet!")
|
|
|
- set_status_text(f"Visual mode for template '{user_data.name}' not implemented yet!")
|
|
|
|
|
|
|
+ set_status_text(f"Visual mode for template '{user_data.name}' not implemented yet!", StatusMessageType.WARNING)
|
|
|
return
|
|
return
|
|
|
set_status_text(f"Using {mode} template '{user_data.name}'.")
|
|
set_status_text(f"Using {mode} template '{user_data.name}'.")
|
|
|
dpg.set_value(f"__prefix_editor_{mode}_input", user_data.prefix)
|
|
dpg.set_value(f"__prefix_editor_{mode}_input", user_data.prefix)
|
|
|
dpg.set_value(f"__query_editor_{mode}_input", user_data.query)
|
|
dpg.set_value(f"__query_editor_{mode}_input", user_data.query)
|
|
|
- dpg.set_value(f"__use_post_method", user_data.modifies)
|
|
|
|
|
|
|
+ dpg.set_value(POST_METHOD_CHECKBOX_TAG, user_data.modifies)
|
|
|
dpg.delete_item("__visual_editor_fields", children_only=True)
|
|
dpg.delete_item("__visual_editor_fields", children_only=True)
|
|
|
if mode == "visual" and user_data.visual_support:
|
|
if mode == "visual" and user_data.visual_support:
|
|
|
for replacement in user_data.replacements:
|
|
for replacement in user_data.replacements:
|
|
@@ -199,8 +225,8 @@ def _perform_query(sender: int, mode: str, user_data: Optional[dict]):
|
|
|
mode = dpg.get_value("__editor_selector").lower().strip()
|
|
mode = dpg.get_value("__editor_selector").lower().strip()
|
|
|
prefix_text = dpg.get_value(f"__prefix_editor_{mode}_input")
|
|
prefix_text = dpg.get_value(f"__prefix_editor_{mode}_input")
|
|
|
query_text = dpg.get_value(f"__query_editor_{mode}_input")
|
|
query_text = dpg.get_value(f"__query_editor_{mode}_input")
|
|
|
- endpoint = dpg.get_value("__endpoint_input")
|
|
|
|
|
- use_post_method = dpg.get_value("__use_post_method")
|
|
|
|
|
|
|
+ endpoint = dpg.get_value(ENDPOINT_TEXTINPUT_TAG)
|
|
|
|
|
+ use_post_method = dpg.get_value(POST_METHOD_CHECKBOX_TAG)
|
|
|
try:
|
|
try:
|
|
|
if mode=="visual":
|
|
if mode=="visual":
|
|
|
for replacement_field in dpg.get_item_children("__visual_editor_fields", 1):
|
|
for replacement_field in dpg.get_item_children("__visual_editor_fields", 1):
|
|
@@ -210,7 +236,7 @@ def _perform_query(sender: int, mode: str, user_data: Optional[dict]):
|
|
|
query_result = query.perform_query(endpoint, prefix_text + "\n" + query_text, use_post_method)
|
|
query_result = query.perform_query(endpoint, prefix_text + "\n" + query_text, use_post_method)
|
|
|
except URLError as e:
|
|
except URLError as e:
|
|
|
logging.error(f"Connection to '{endpoint}' failed.")
|
|
logging.error(f"Connection to '{endpoint}' failed.")
|
|
|
- set_status_text(f"Connection to '{endpoint}' failed.")
|
|
|
|
|
|
|
+ set_status_text(f"Connection to '{endpoint}' failed.", StatusMessageType.ERROR)
|
|
|
return
|
|
return
|
|
|
if use_post_method:
|
|
if use_post_method:
|
|
|
logging.debug(f"{query_result}")
|
|
logging.debug(f"{query_result}")
|
|
@@ -258,6 +284,7 @@ def _select_file(sender: int, app_data: str, user_data: Optional[dict]):
|
|
|
dpg.set_value("file_info_n", "file :" + selected_file)
|
|
dpg.set_value("file_info_n", "file :" + selected_file)
|
|
|
|
|
|
|
|
def interface(example_prefix: str, example_query: str, palette: List[QueryTemplate], endpoint: str, width=1200, height=900):
|
|
def interface(example_prefix: str, example_query: str, palette: List[QueryTemplate], endpoint: str, width=1200, height=900):
|
|
|
|
|
+ """Show the full user interface."""
|
|
|
dpg.create_context()
|
|
dpg.create_context()
|
|
|
dpg.create_viewport(title="Graph Exploring Tool", width=width, height=height)
|
|
dpg.create_viewport(title="Graph Exploring Tool", width=width, height=height)
|
|
|
with dpg.window(tag="primary", label="Graph Exploring Tool", menubar=True):
|
|
with dpg.window(tag="primary", label="Graph Exploring Tool", menubar=True):
|