Lea Laux 5daa99193a Update missing keywords
Update the keyword list in the lexer, because PostgreSQL uses a lof of
keywords, which were not part of the keyword list.
2021-03-15 12:27:42 +01:00

142 lines
6.5 KiB
Python

import logging
from PyQt5.Qsci import QsciLexerSQL, QsciLexerCustom
from PyQt5.QtGui import QColor
from pygadmin.configurator import global_app_configurator
class SQLLexer(QsciLexerSQL, QsciLexerCustom):
"""
Create a custom lexer class for style customization. The background color of the lexer, the font color, the color of
specific keywords are configurable.
"""
def __init__(self, scintilla):
super().__init__(scintilla)
self.init_colors()
def keywords(self, p_int):
"""
Reimplement the function for getting all keywords, because the SQL lexer does not contain all relevant keywords
for PostgreSQL.
"""
# Define a list of missing keywords. Note: This list does not necessarily contain all missing keywords, but a
# lot of them are common among tasks for PostgreSQL.
missing_keywords = ["analyze", "analyse" "explain", "count", "sum", "avg", "min", "max", "serial",
"materialized", "text", "replace", "exists", "plpgsql", "raise", "while", "loop", "void",
"truncate", "notice", "others", "instead", "do", "verbose", "costs", "settings", "buffers",
"wal", "summary", "format", "json", "xml", "yaml", "immutable"]
# Get the existing SQL keywords in the lexer.
keywords = super().keywords(p_int)
# Add the missing keywords to the keyword string.
for keyword in missing_keywords:
keywords = "{} {}".format(keywords, keyword)
# Return the result.
return keywords
def init_colors(self):
"""
Initialize the colors of the lexer.
"""
self.color_parameters_dictionary = {}
default_style = global_app_configurator.get_default_color_theme_style()
if default_style:
self.style_name = default_style[0]
for color_description, color_string in default_style[1].items():
self.color_parameters_dictionary[color_description] = QColor(color_string)
if not default_style:
self.style_name = "Default"
self.color_parameters_dictionary = {
"default_color": QColor("ff000000"),
"default_paper_color": QColor("#ffffffff"),
"keyword_color": QColor("#ff00007f"),
"number_color": QColor("#ff007f7f"),
"other_keyword_color": QColor("#ff7f7f00"),
"apostrophe_color": QColor("#ff7f007f")
}
self.save_dictionary_with_style_information()
self.set_lexer_colors(self.color_parameters_dictionary)
def set_lexer_colors(self, color_dictionary):
"""
Set the different colors of the lexer, which are given in a color dictionary. Check every item in the dictionary
for a potential match in the key. This procedure allows to check for the existence of the key and the further
usage after a match. Check also the color for a QColor, so only a color of the right type is used. Specific
integers are used in setColor for specifying the component for the color.
"""
# Check every key and value pair in the dictionary with the colors.
for color_description, color_value in color_dictionary.items():
# Check the given color for its instance/type. Proceed for a QColor.
if isinstance(color_value, QColor):
# Set the color for the default color.
if color_description == "default_color":
self.setDefaultColor(color_value)
# Set the default paper color.
elif color_description == "default_paper_color":
self.setDefaultPaper(color_value)
# Use the function setColor() with the value 0 for using the given color for the paper for special
# words like keywords.
self.setColor(color_value, 0)
# Set the color for keywords.
elif color_description == "keyword_color":
# The integer value 5 is used for the color of keywords.
self.setColor(color_value, 5)
# Set the color for numbers.
elif color_description == "number_color":
# The integer value 4 is used for the color of numbers.
self.setColor(color_value, 4)
# Set the color for other keywords, which are not a part of "normal" keywords.
elif color_description == "other_keyword_color":
# The integer value 8 is used for the color of those other keywords.
self.setColor(color_value, 8)
# Set the color for the apostrophes and the text inside.
elif color_description == "apostrophe_color":
# The integer value 7 is used for the color of apostrophes and the text inside.
self.setColor(color_value, 7)
# Use this else-branch, if the given color value is not a QColor.
else:
# Warn in the log about a missing QColor.
logging.warning("The given color {} for the color description/color key {} is not a QColor. Potential "
"changes in the lexer's and editor's color will not be "
"applied.".format(color_value, color_description))
def save_dictionary_with_style_information(self):
"""
Save the current style information for further usage with the global app configurator.
"""
# Create an empty dictionary for the information.
style_information_dictionary = {}
# Change every value of the dictionary with its key to a usable value for saving in a .yaml file.
for color_description, color_q_color in self.color_parameters_dictionary.items():
# Use the name of the color as string for saving.
style_information_dictionary[color_description] = color_q_color.name()
# Add the configuration to the app configurator.
global_app_configurator.add_style_configuration(self.style_name, style_information_dictionary)
# Add the configuration name as default configuration to all configurations.
global_app_configurator.set_single_configuration("color_theme", self.style_name)
# Save the style configuration.
global_app_configurator.save_style_configuration_data()
# Save the configuration data.
global_app_configurator.save_configuration_data()