diff --git a/src/airunner/aihandler/auto_pipeline.py b/src/airunner/aihandler/auto_pipeline.py index 3ff9a6b13..14eac87ef 100644 --- a/src/airunner/aihandler/auto_pipeline.py +++ b/src/airunner/aihandler/auto_pipeline.py @@ -1,5 +1,5 @@ from airunner.aihandler.logger import Logger as logger -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager class AutoImport: diff --git a/src/airunner/aihandler/engine.py b/src/airunner/aihandler/engine.py index ea0f1ccdb..aed93b0c2 100644 --- a/src/airunner/aihandler/engine.py +++ b/src/airunner/aihandler/engine.py @@ -6,7 +6,7 @@ from airunner.aihandler.llm import LLM from airunner.aihandler.logger import Logger as logger from airunner.aihandler.runner import SDRunner -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.aihandler.tts import TTS diff --git a/src/airunner/aihandler/runner.py b/src/airunner/aihandler/runner.py index 4ef0107d7..546bba83a 100644 --- a/src/airunner/aihandler/runner.py +++ b/src/airunner/aihandler/runner.py @@ -28,7 +28,7 @@ from airunner.aihandler.mixins.scheduler_mixin import SchedulerMixin from airunner.aihandler.mixins.txttovideo_mixin import TexttovideoMixin from airunner.aihandler.settings import LOG_LEVEL, AIRUNNER_ENVIRONMENT -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.prompt_builder.prompt_data import PromptData from airunner.scripts.realesrgan.main import RealESRGAN from airunner.aihandler.logger import Logger diff --git a/src/airunner/aihandler/settings_manager.py b/src/airunner/aihandler/settings_manager.py index 5a5a311ea..6dc272a54 100644 --- a/src/airunner/aihandler/settings_manager.py +++ b/src/airunner/aihandler/settings_manager.py @@ -3,9 +3,10 @@ from airunner.aihandler.qtvar import StringVar, IntVar, BooleanVar, FloatVar, DictVar from airunner.data.models import LLMGenerator, Settings, GeneratorSetting, AIModel, Pipeline, ControlnetModel, ImageFilter, \ SavedPrompt, StandardImageWidgetSettings -from airunner.utils import save_session, get_session from airunner.aihandler.logger import Logger as logger from airunner.data.models import Document +from airunner.data.session_scope import session_scope, path_settings_scope + document = None _app = None @@ -17,7 +18,6 @@ "FLOAT": FloatVar, "JSON": DictVar, } -session = get_session() class SettingsSignal(QObject): @@ -40,7 +40,8 @@ def prompts(self): Return Prompt objects from the database :return: """ - return session.query(SavedPrompt).all() + with session_scope() as session: + return session.query(SavedPrompt).all() def create_saved_prompt(self, prompt, negative_prompt): if prompt == "" and negative_prompt == "": @@ -50,102 +51,110 @@ def create_saved_prompt(self, prompt, negative_prompt): prompt=prompt, negative_prompt=negative_prompt ) - session.add(saved_prompt) - if save_session(session): + with session_scope() as session: + session.add(saved_prompt) self.changed_signal.emit("saved_prompt", saved_prompt, self) def delete_prompt(self, saved_prompt): - session.delete(saved_prompt) - session.commit() + with session_scope() as session: + session.delete(saved_prompt) self.save_and_emit("saved_prompt", saved_prompt) self.changed_signal.emit("saved_prompt", saved_prompt, self) def save_and_emit(self, key, value): - self.save() self.changed_signal.emit(key, value, self) def available_models_by_category(self, category): categories = [category] if category in ["img2img", "txt2vid"]: categories.append("txt2img") - return session.query(AIModel).filter( - AIModel.category.in_(categories), - AIModel.enabled.is_(True) - ).all() + with session_scope() as session: + return session.query(AIModel).filter( + AIModel.category.in_(categories), + AIModel.enabled.is_(True) + ).all() def set_model_enabled(self, key, model, enabled): - session.query(AIModel).filter_by( - name=model["name"], - path=model["path"], - branch=model["branch"], - version=model["version"], - category=model["category"] - ).update({"enabled": enabled == 2}) + with session_scope() as session: + session.query(AIModel).filter_by( + name=model["name"], + path=model["path"], + branch=model["branch"], + version=model["version"], + category=model["category"] + ).update({"enabled": enabled == 2}) self.save_settings() def available_pipeline_by_section(self, pipeline_action, version, category): - return session.query(Pipeline).filter_by( - category=category, - pipeline_action=pipeline_action, - version=version - ).first() + with session_scope() as session: + return session.query(Pipeline).filter_by( + category=category, + pipeline_action=pipeline_action, + version=version + ).first() def available_model_names(self, pipeline_action, category): # returns a list of names of models # that match the pipeline_action and category - names = [] - models = session.query(AIModel).filter_by( - pipeline_action=pipeline_action, - category=category, - enabled=True - ).all() - for model in models: - if model.name not in names: - names.append(model.name) - return names + with session_scope() as session: + names = [] + models = session.query(AIModel).filter_by( + pipeline_action=pipeline_action, + category=category, + enabled=True + ).all() + for model in models: + if model.name not in names: + names.append(model.name) + return names def add_model(self, model_data): - model = AIModel(**model_data) - session.add(model) - session.commit() + with session_scope() as session: + model = AIModel(**model_data) + session.add(model) def delete_model(self, model): - session.delete(model) - session.commit() + with session_scope() as session: + session.delete(model) def update_model(self, model): - session.add(model) - session.commit() + with session_scope() as session: + session.add(model) def get_image_filter(self, name): - return session.query(ImageFilter).filter_by(name=name).first() + with session_scope() as session: + return session.query(ImageFilter).filter_by(name=name).first() def get_image_filters(self): - return session.query(ImageFilter).all() + with session_scope() as session: + return session.query(ImageFilter).all() @property def standard_image_widget_settings(self): - standard_image_widget_settings = session.query(StandardImageWidgetSettings).first() - if standard_image_widget_settings is None: - standard_image_widget_settings = StandardImageWidgetSettings() - session.add(standard_image_widget_settings) - session.commit() - return standard_image_widget_settings + with session_scope() as session: + standard_image_widget_settings = session.query(StandardImageWidgetSettings).first() + if standard_image_widget_settings is None: + standard_image_widget_settings = StandardImageWidgetSettings() + session.add(standard_image_widget_settings) + return standard_image_widget_settings @property def pipelines(self): - return session.query(Settings).all() + with session_scope() as session: + return session.query(Settings).all() @property def models(self): - return session.query(AIModel).filter_by(enabled=True) + with session_scope() as session: + return session.query(AIModel).filter_by(enabled=True) def models_by_pipeline_action(self, pipeline_action): return self.models.filter_by(pipeline_action=pipeline_action).all() @property def controlnet_models(self): - return session.query(ControlnetModel).filter_by(enabled=True) + with session_scope() as session: + return session.query(ControlnetModel).filter_by(enabled=True) def controlnet_model_by_name(self, name): return self.controlnet_models.filter_by(name=name).first() @@ -169,11 +178,12 @@ def model_categories(self): def get_pipeline_classname(self, pipeline_action, version, category): try: - return session.query(Pipeline).filter_by( - category=category, - pipeline_action=pipeline_action, - version=version - ).first().classname + with session_scope() as session: + return session.query(Pipeline).filter_by( + category=category, + pipeline_action=pipeline_action, + version=version + ).first().classname except AttributeError: logger.error(f"Unable to find pipeline classname for {pipeline_action} {version} {category}") return None @@ -200,8 +210,9 @@ def generator(self): @property def llm_generator_setting(self): - llm_generator = session.query(LLMGenerator).filter(LLMGenerator.name == self.current_llm_generator).first() - return llm_generator.generator_settings[0] + with session_scope() as session: + llm_generator = session.query(LLMGenerator).filter(LLMGenerator.name == self.current_llm_generator).first() + return llm_generator.generator_settings[0] _generator = None @@ -209,25 +220,25 @@ def find_generator(self, generator_section, generator_name): # using sqlalchemy, query the document.settings.generator_settings column # and find any with GeneratorSettings.section == self.generator_section and GeneratorSettings.generator_name == self.generator_name # return the first result - if self.generator_settings_override_id: - generator_settings = session.query(GeneratorSetting).filter_by( - id=self.generator_settings_override_id - ).first() - else: - generator_settings = session.query(GeneratorSetting).filter_by( - is_preset=0 - ).first() - if generator_settings is None: - if not generator_section or generator_section == "" or not generator_name or generator_name == "": - return None - # generator_settings = GeneratorSetting( - # section=generator_section, - # generator_name=generator_name, - # is_preset=False - # ) - # session.add(generator_settings) - # session.commit() - return generator_settings + with session_scope() as session: + if self.generator_settings_override_id: + generator_settings = session.query(GeneratorSetting).filter_by( + id=self.generator_settings_override_id + ).first() + else: + generator_settings = session.query(GeneratorSetting).filter_by( + is_preset=0 + ).first() + if generator_settings is None: + if not generator_section or generator_section == "" or not generator_name or generator_name == "": + return None + # generator_settings = GeneratorSetting( + # section=generator_section, + # generator_name=generator_name, + # is_preset=False + # ) + # session.add(generator_settings) + return generator_settings def __init__(self, app=None, *args, **kwargs): global _app, document @@ -237,8 +248,8 @@ def __init__(self, app=None, *args, **kwargs): _app = app document = _app.document else: - session = get_session() - document = session.query(Document).first() + with session_scope() as session: + document = session.query(Document).first() super().__init__(*args, **kwargs) @@ -273,8 +284,11 @@ def get_database_value(self, name): return getattr(document.settings, name) def __getattr__(self, name): - if document and hasattr(document.settings, name): - return getattr(document.settings, name) + with session_scope() as session: + session.add(document) + session.add(document.settings) + if document and hasattr(document.settings, name): + return getattr(document.settings, name) return None def __setattr__(self, name, value): @@ -311,4 +325,4 @@ def current_tab_action(self): return self.current_section_stablediffusion def save(self): - session.commit() + pass diff --git a/src/airunner/aihandler/transformer_runner.py b/src/airunner/aihandler/transformer_runner.py index 7cc21e808..747064335 100644 --- a/src/airunner/aihandler/transformer_runner.py +++ b/src/airunner/aihandler/transformer_runner.py @@ -10,9 +10,9 @@ from transformers import InstructBlipForConditionalGeneration from transformers import InstructBlipProcessor -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.data.models import LLMGenerator -from airunner.utils import get_session +from airunner.data.session_scope import session_scope from airunner.aihandler.logger import Logger @@ -66,10 +66,10 @@ class TransformerRunner(QObject): @property def generator(self): try: - session = get_session() if not self._generator or self.current_generator_name != self.requested_generator_name: self.current_generator_name = self.requested_generator_name - self._generator = session.query(LLMGenerator).filter_by(name=self.current_generator_name).first() + with session_scope() as session: + self._generator = session.query(LLMGenerator).filter_by(name=self.current_generator_name).first() return self._generator except Exception as e: Logger.error(e) diff --git a/src/airunner/alembic/versions/1aa0b181a56e_renamed_gridsettings_size_to_cell_size.py b/src/airunner/alembic/versions/1aa0b181a56e_renamed_gridsettings_size_to_cell_size.py new file mode 100644 index 000000000..0455c0d83 --- /dev/null +++ b/src/airunner/alembic/versions/1aa0b181a56e_renamed_gridsettings_size_to_cell_size.py @@ -0,0 +1,32 @@ +"""Renamed GridSettings size to cell_size + +Revision ID: 1aa0b181a56e +Revises: 77bcb51efb33 +Create Date: 2024-01-10 12:27:35.247277 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '1aa0b181a56e' +down_revision: Union[str, None] = '77bcb51efb33' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('grid_settings', sa.Column('cell_size', sa.Integer(), nullable=True)) + op.drop_column('grid_settings', 'size') + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('grid_settings', sa.Column('size', sa.INTEGER(), nullable=True)) + op.drop_column('grid_settings', 'cell_size') + # ### end Alembic commands ### diff --git a/src/airunner/alembic/versions/77bcb51efb33_adds_prompt_weights_to_.py b/src/airunner/alembic/versions/77bcb51efb33_adds_prompt_weights_to_.py new file mode 100644 index 000000000..a5796784c --- /dev/null +++ b/src/airunner/alembic/versions/77bcb51efb33_adds_prompt_weights_to_.py @@ -0,0 +1,36 @@ +"""Adds prompt weights to PromptGeneratorSetting + +Revision ID: 77bcb51efb33 +Revises: 6d98d892995f +Create Date: 2024-01-10 12:19:51.811669 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '77bcb51efb33' +down_revision: Union[str, None] = '6d98d892995f' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('prompt_generator_settings', sa.Column('auto_prompt_weight', sa.Float(), nullable=True)) + op.add_column('prompt_generator_settings', sa.Column('text_prompt_weight', sa.Float(), nullable=True)) + op.add_column('prompt_generator_settings', sa.Column('negative_auto_prompt_weight', sa.Float(), nullable=True)) + op.add_column('prompt_generator_settings', sa.Column('negative_text_prompt_weight', sa.Float(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('prompt_generator_settings', 'negative_text_prompt_weight') + op.drop_column('prompt_generator_settings', 'negative_auto_prompt_weight') + op.drop_column('prompt_generator_settings', 'text_prompt_weight') + op.drop_column('prompt_generator_settings', 'auto_prompt_weight') + # ### end Alembic commands ### diff --git a/src/airunner/alembic/versions/bc6ff97b7e60_removes_prompt_generator.py b/src/airunner/alembic/versions/bc6ff97b7e60_removes_prompt_generator.py new file mode 100644 index 000000000..14a91bbcd --- /dev/null +++ b/src/airunner/alembic/versions/bc6ff97b7e60_removes_prompt_generator.py @@ -0,0 +1,66 @@ +"""Removes prompt generator + +Revision ID: bc6ff97b7e60 +Revises: 1aa0b181a56e +Create Date: 2024-01-10 12:55:01.403042 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import sqlite + +# revision identifiers, used by Alembic. +revision: str = 'bc6ff97b7e60' +down_revision: Union[str, None] = '1aa0b181a56e' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('prompt_generator_settings') + op.drop_table('prompt_builder') + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('prompt_builder', + sa.Column('id', sa.INTEGER(), nullable=False), + sa.Column('name', sa.VARCHAR(), nullable=True), + sa.Column('active', sa.BOOLEAN(), nullable=True), + sa.Column('auto_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('text_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('negative_auto_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('negative_text_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('created_at', sa.DATETIME(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('prompt_generator_settings', + sa.Column('id', sa.INTEGER(), nullable=False), + sa.Column('settings_id', sa.INTEGER(), nullable=True), + sa.Column('name', sa.VARCHAR(), nullable=True), + sa.Column('advanced_mode', sa.BOOLEAN(), nullable=True), + sa.Column('category', sa.VARCHAR(), nullable=True), + sa.Column('prompt_blend_type', sa.INTEGER(), nullable=True), + sa.Column('prompt', sa.VARCHAR(), nullable=True), + sa.Column('weighted_values', sqlite.JSON(), nullable=True), + sa.Column('prompt_genre', sa.VARCHAR(), nullable=True), + sa.Column('prompt_color', sa.VARCHAR(), nullable=True), + sa.Column('prompt_style', sa.VARCHAR(), nullable=True), + sa.Column('prefix', sa.VARCHAR(), nullable=True), + sa.Column('suffix', sa.VARCHAR(), nullable=True), + sa.Column('negative_prefix', sa.VARCHAR(), nullable=True), + sa.Column('negative_suffix', sa.VARCHAR(), nullable=True), + sa.Column('active', sa.BOOLEAN(), nullable=True), + sa.Column('auto_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('text_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('negative_auto_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('negative_text_prompt_weight', sa.FLOAT(), nullable=True), + sa.Column('created_at', sa.DATETIME(), nullable=True), + sa.ForeignKeyConstraint(['settings_id'], ['settings.id'], ), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### diff --git a/src/airunner/data/db.py b/src/airunner/data/db.py index 5b07d1609..b25a1d81d 100644 --- a/src/airunner/data/db.py +++ b/src/airunner/data/db.py @@ -5,13 +5,13 @@ from airunner.data.bootstrap.pipeline_bootstrap_data import pipeline_bootstrap_data from airunner.data.bootstrap.prompt_bootstrap_data import prompt_bootstrap_data, style_bootstrap_data, \ variable_bootstrap_data -from airunner.data.models import ControlnetModel, LLMPromptTemplate, Pipeline, Document, Settings, PromptGeneratorSetting, \ +from airunner.data.models import ControlnetModel, LLMPromptTemplate, Pipeline, Document, Settings, \ GeneratorSetting, SplitterSection, GridSettings, MetadataSettings, PathSettings, MemorySettings, AIModel, \ ImageFilter, ImageFilterValue, BrushSettings, Prompt, PromptVariable, PromptCategory, PromptOption, \ PromptVariableCategory, PromptVariableCategoryWeight, PromptStyleCategory, PromptStyle, Scheduler, ActionScheduler, \ - DeterministicSettings, ActiveGridSettings, TabSection, PromptBuilder, CanvasSettings, \ - LLMGeneratorSetting, LLMGenerator, LLMModelVersion -from airunner.utils import get_session + DeterministicSettings, ActiveGridSettings, TabSection, CanvasSettings, \ + LLMGeneratorSetting, LLMGenerator, LLMModelVersion, StandardImageWidgetSettings +from airunner.data.session_scope import session_scope, engine from alembic.config import Config from alembic import command import os @@ -19,419 +19,402 @@ def prepare_database(): - my_session = get_session() - do_stamp_alembic = False - - # check if database is blank: - if not my_session.query(Prompt).first(): - do_stamp_alembic = True - - # Add Prompt objects - for prompt_option, data in prompt_bootstrap_data.items(): - category = PromptCategory(name=prompt_option, negative_prompt=data["negative_prompt"]) - prompt = Prompt( - name=f"Standard {prompt_option} prompt", - category=category - ) - my_session.add(prompt) - my_session.commit() - prompt_id = prompt.id - - prompt_variables = [] - for category_name, variable_values in data["variables"].items(): - # add prompt category - cat = my_session.query(PromptVariableCategory).filter_by(name=category_name).first() - if not cat: - cat = PromptVariableCategory(name=category_name) - my_session.add(cat) - my_session.commit() - - # add prompt variable category weight - weight = my_session.query(PromptVariableCategoryWeight).filter_by( - prompt_category=category, - variable_category=cat - ).first() - if not weight: - try: - weight_value = data["weights"][category_name] - except KeyError: - weight_value = 1.0 - weight = PromptVariableCategoryWeight( - prompt_category=category, - variable_category=cat, - weight=weight_value - ) - my_session.add(weight) - my_session.commit() + from airunner.data.models import Base + Base.metadata.create_all(engine) - # add prompt variables - for var in variable_values: - my_session.add(PromptVariable( - value=var, + with session_scope() as my_session: + do_stamp_alembic = False + + # check if database is blank: + if not my_session.query(Prompt).first(): + do_stamp_alembic = True + + standard_image_widget = StandardImageWidgetSettings() + my_session.add(standard_image_widget) + + # Add Prompt objects + for prompt_option, data in prompt_bootstrap_data.items(): + category = PromptCategory(name=prompt_option, negative_prompt=data["negative_prompt"]) + prompt = Prompt( + name=f"Standard {prompt_option} prompt", + category=category + ) + my_session.add(prompt) + + prompt_id = prompt.id + + prompt_variables = [] + for category_name, variable_values in data["variables"].items(): + # add prompt category + cat = my_session.query(PromptVariableCategory).filter_by(name=category_name).first() + if not cat: + cat = PromptVariableCategory(name=category_name) + my_session.add(cat) + + + # add prompt variable category weight + weight = my_session.query(PromptVariableCategoryWeight).filter_by( prompt_category=category, variable_category=cat - )) - my_session.commit() - - def insert_variables(variables, prev_object=None): - for option in variables: - text = option.get("text", None) - cond = option.get("cond", "") - else_cond = option.get("else", "") - next_cond = option.get("next", None) - or_cond = option.get("or_cond", None) - prompt_option = PromptOption( - text=text, - cond=cond, - else_cond=else_cond, - or_cond=or_cond, - prompt_id=prompt_id - ) - if prev_object: - my_session.add(prompt_option) - my_session.commit() - prev_object.next_cond_id = prompt_option.id - my_session.add(prev_object) - my_session.commit() - prev_object = prompt_option - else: - my_session.add(prompt_option) - my_session.commit() - prev_object = prompt_option - if next_cond: - prev_object = insert_variables( - variables=next_cond, - prev_object=prev_object, + ).first() + if not weight: + try: + weight_value = data["weights"][category_name] + except KeyError: + weight_value = 1.0 + weight = PromptVariableCategoryWeight( + prompt_category=category, + variable_category=cat, + weight=weight_value ) - return prev_object - - insert_variables(data["builder"]) - - my_session.commit() + my_session.add(weight) + + + # add prompt variables + for var in variable_values: + my_session.add(PromptVariable( + value=var, + prompt_category=category, + variable_category=cat + )) + + + def insert_variables(variables, prev_object=None): + for option in variables: + text = option.get("text", None) + cond = option.get("cond", "") + else_cond = option.get("else", "") + next_cond = option.get("next", None) + or_cond = option.get("or_cond", None) + prompt_option = PromptOption( + text=text, + cond=cond, + else_cond=else_cond, + or_cond=or_cond, + prompt_id=prompt_id + ) + if prev_object: + my_session.add(prompt_option) + + prev_object.next_cond_id = prompt_option.id + my_session.add(prev_object) + + prev_object = prompt_option + else: + my_session.add(prompt_option) + + prev_object = prompt_option + if next_cond: + prev_object = insert_variables( + variables=next_cond, + prev_object=prev_object, + ) + return prev_object + + insert_variables(data["builder"]) + + + + for variable_category, data in variable_bootstrap_data.items(): + category = my_session.query(PromptVariableCategory).filter_by(name=variable_category).first() + if not category: + category = PromptVariableCategory(name=variable_category) + my_session.add(category) + + for variable in data: + my_session.add(PromptVariable( + value=variable, + variable_category=category + )) + - for variable_category, data in variable_bootstrap_data.items(): - category = my_session.query(PromptVariableCategory).filter_by(name=variable_category).first() - if not category: - category = PromptVariableCategory(name=variable_category) + # Add PromptStyle objects + for style_category, data in style_bootstrap_data.items(): + category = PromptStyleCategory(name=style_category, negative_prompt=data["negative_prompt"]) my_session.add(category) - my_session.commit() - for variable in data: - my_session.add(PromptVariable( - value=variable, - variable_category=category - )) - my_session.commit() - - # Add PromptStyle objects - for style_category, data in style_bootstrap_data.items(): - category = PromptStyleCategory(name=style_category, negative_prompt=data["negative_prompt"]) - my_session.add(category) - my_session.commit() - for style in data["styles"]: - my_session.add(PromptStyle( - name=style, - style_category=category - )) - my_session.commit() - - # Add ControlnetModel objects - for name, path in controlnet_bootstrap_data.items(): - my_session.add(ControlnetModel(name=name, path=path)) - my_session.commit() - - - # Add AIModel objects - for model_data in model_bootstrap_data: - my_session.add(AIModel(**model_data)) - my_session.commit() - - - # Add Pipeline objects - for pipeline_data in pipeline_bootstrap_data: - my_session.add(Pipeline(**pipeline_data)) - my_session.commit() - - - # Add PathSettings objects - my_session.add(PathSettings()) - my_session.commit() - - - # Add BrushSettings objects - my_session.add(BrushSettings()) - my_session.commit() - - - # Add GridSettings objects - my_session.add(GridSettings()) - my_session.commit() - - my_session.add(DeterministicSettings()) - my_session.commit() - - - # Add MetadataSettings objects - my_session.add(MetadataSettings()) - my_session.commit() - - - # Add MemorySettings objects - my_session.add(MemorySettings()) - my_session.commit() - - # Add ActiveGridSettings object - my_session.add(ActiveGridSettings()) - my_session.commit() - - # Add ImageFilter objects - for filter in imagefilter_bootstrap_data: - image_filter = ImageFilter( - display_name=filter[0], - name=filter[1], - filter_class=filter[2] - ) - for filter_value in filter[3]: - image_filter.image_filter_values.append(ImageFilterValue( - name=filter_value[0], - value=filter_value[1], - value_type=filter_value[2], - min_value=filter_value[3] if len(filter_value) > 3 else None, - max_value=filter_value[4] if len(filter_value) > 4 else None - )) - my_session.add(image_filter) - my_session.commit() - - image_filter = my_session.query(ImageFilter).filter_by(name='color_balance').first() - - # Access its image_filter_values - filter_values = image_filter.image_filter_values - - # Add Document object - settings = Settings(nsfw_filter=True) - settings.prompt_generator_settings.append( - PromptGeneratorSetting( - name="Prompt A", - active=True, - settings_id=settings.id - ) - ) - settings.prompt_generator_settings.append( - PromptGeneratorSetting( - name="Prompt B", - settings_id=settings.id - ) - ) - settings.splitter_sizes.append(SplitterSection( - name="content_splitter", - order=0, - size=390 - )) - settings.splitter_sizes.append(SplitterSection( - name="content_splitter", - order=1, - size=512 - )) - settings.splitter_sizes.append(SplitterSection( - name="content_splitter", - order=2, - size=200 - )) - settings.splitter_sizes.append(SplitterSection( - name="content_splitter", - order=3, - size=64 - )) - settings.splitter_sizes.append(SplitterSection( - name="main_splitter", - order=0, - size=520 - )) - settings.splitter_sizes.append(SplitterSection( - name="main_splitter", - order=1, - size=-1 - )) - settings.splitter_sizes.append(SplitterSection( - name="canvas_splitter", - order=0, - size=520 - )) - settings.splitter_sizes.append(SplitterSection( - name="canvas_splitter", - order=1, - size=-1 - )) - my_session.add(settings) - - settings.brush_settings = my_session.query(BrushSettings).first() - settings.path_settings = my_session.query(PathSettings).first() - settings.grid_settings = my_session.query(GridSettings).first() - settings.deterministic_settings = my_session.query(DeterministicSettings).first() - settings.metadata_settings = my_session.query(MetadataSettings).first() - settings.memory_settings = my_session.query(MemorySettings).first() - settings.active_grid_settings = my_session.query(ActiveGridSettings).first() - - active_grid_colors = { - "stablediffusion": { - "border": { - "txt2img": "#00FF00", - "outpaint": "#00FFFF", - "depth2img": "#0000FF", - "pix2pix": "#FFFF00", - "upscale": "#00FFFF", - "superresolution": "#FF00FF", - "txt2vid": "#999999", - }, - # choose complimentary colors for the fill - "fill": { - "txt2img": "#FF0000", - "outpaint": "#FF00FF", - "depth2img": "#FF8000", - "pix2pix": "#8000FF", - "upscale": "#00FF80", - "superresolution": "#00FF00", - "txt2vid": "#000000", - - } - }, - } - - generator_section = "txt2img" - generator_name = "stablediffusion" - my_session.add(GeneratorSetting( - section=generator_section, - generator_name=generator_name, - active_grid_border_color=active_grid_colors[generator_name]["border"][generator_section], - active_grid_fill_color=active_grid_colors[generator_name]["fill"][generator_section] - )) - - my_session.add(Document( - name="Untitled", - settings=settings, - active=True - )) - my_session.commit() - - - available_schedulers = {} - for scheduler_data in [ - ("Euler a", "EULER_ANCESTRAL"), - ("Euler", "EULER"), - ("LMS", "LMS"), - ("Heun", "HEUN"), - ("DPM2", "DPM2"), - ("DPM++ 2M", "DPM_PP_2M"), - ("DPM2 Karras", "DPM2_K"), - ("DPM2 a Karras", "DPM2_A_K"), - ("DPM++ 2M Karras", "DPM_PP_2M_K"), - ("DPM++ 2M SDE Karras", "DPM_PP_2M_SDE_K"), - ("DDIM", "DDIM"), - ("UniPC", "UNIPC"), - ("DDPM", "DDPM"), - ("DEIS", "DEIS"), - ("DPM 2M SDE Karras", "DPM_2M_SDE_K"), - ("PLMS", "PLMS"), - ]: - obj = Scheduler( - name=scheduler_data[1], - display_name=scheduler_data[0] - ) - my_session.add(obj) - available_schedulers[scheduler_data[1]] = obj - my_session.commit() - - generator_sections = { - "stablediffusion": { - "upscale": ["EULER"], - "superresolution": ["DDIM", "LMS", "PLMS"], - }, - } - - # add all of the schedulers for the defined generator sections - for generator, sections in generator_sections.items(): - for section, schedulers in sections.items(): - for scheduler in schedulers: - my_session.add(ActionScheduler( - section=section, - generator_name=generator, - scheduler_id=my_session.query(Scheduler).filter_by(name=scheduler).first().id + + for style in data["styles"]: + my_session.add(PromptStyle( + name=style, + style_category=category )) - my_session.commit() + + + # Add ControlnetModel objects + for name, path in controlnet_bootstrap_data.items(): + my_session.add(ControlnetModel(name=name, path=path)) + + + + # Add AIModel objects + for model_data in model_bootstrap_data: + my_session.add(AIModel(**model_data)) + + + + # Add Pipeline objects + for pipeline_data in pipeline_bootstrap_data: + my_session.add(Pipeline(**pipeline_data)) + - # add the rest of the stable diffusion schedulers - for k, v in available_schedulers.items(): - for section in [ - "txt2img", "depth2img", "pix2pix", "vid2vid", - "outpaint", "controlnet", "txt2vid" + + # Add PathSettings objects + my_session.add(PathSettings()) + + + + # Add BrushSettings objects + my_session.add(BrushSettings()) + + + + # Add GridSettings objects + my_session.add(GridSettings()) + + + my_session.add(DeterministicSettings()) + + + + # Add MetadataSettings objects + my_session.add(MetadataSettings()) + + + + # Add MemorySettings objects + my_session.add(MemorySettings()) + + + # Add ActiveGridSettings object + my_session.add(ActiveGridSettings()) + + + # Add ImageFilter objects + for filter in imagefilter_bootstrap_data: + image_filter = ImageFilter( + display_name=filter[0], + name=filter[1], + filter_class=filter[2] + ) + for filter_value in filter[3]: + image_filter.image_filter_values.append(ImageFilterValue( + name=filter_value[0], + value=filter_value[1], + value_type=filter_value[2], + min_value=filter_value[3] if len(filter_value) > 3 else None, + max_value=filter_value[4] if len(filter_value) > 4 else None + )) + my_session.add(image_filter) + + + image_filter = my_session.query(ImageFilter).filter_by(name='color_balance').first() + + # Access its image_filter_values + filter_values = image_filter.image_filter_values + + # Add Document object + settings = Settings(nsfw_filter=True) + settings.splitter_sizes.append(SplitterSection( + name="content_splitter", + order=0, + size=390 + )) + settings.splitter_sizes.append(SplitterSection( + name="content_splitter", + order=1, + size=512 + )) + settings.splitter_sizes.append(SplitterSection( + name="content_splitter", + order=2, + size=200 + )) + settings.splitter_sizes.append(SplitterSection( + name="content_splitter", + order=3, + size=64 + )) + settings.splitter_sizes.append(SplitterSection( + name="main_splitter", + order=0, + size=520 + )) + settings.splitter_sizes.append(SplitterSection( + name="main_splitter", + order=1, + size=-1 + )) + settings.splitter_sizes.append(SplitterSection( + name="canvas_splitter", + order=0, + size=520 + )) + settings.splitter_sizes.append(SplitterSection( + name="canvas_splitter", + order=1, + size=-1 + )) + my_session.add(settings) + + settings.brush_settings = my_session.query(BrushSettings).first() + settings.path_settings = my_session.query(PathSettings).first() + settings.grid_settings = my_session.query(GridSettings).first() + settings.deterministic_settings = my_session.query(DeterministicSettings).first() + settings.metadata_settings = my_session.query(MetadataSettings).first() + settings.memory_settings = my_session.query(MemorySettings).first() + settings.active_grid_settings = my_session.query(ActiveGridSettings).first() + + active_grid_colors = { + "stablediffusion": { + "border": { + "txt2img": "#00FF00", + "outpaint": "#00FFFF", + "depth2img": "#0000FF", + "pix2pix": "#FFFF00", + "upscale": "#00FFFF", + "superresolution": "#FF00FF", + "txt2vid": "#999999", + }, + # choose complimentary colors for the fill + "fill": { + "txt2img": "#FF0000", + "outpaint": "#FF00FF", + "depth2img": "#FF8000", + "pix2pix": "#8000FF", + "upscale": "#00FF80", + "superresolution": "#00FF00", + "txt2vid": "#000000", + + } + }, + } + + generator_section = "txt2img" + generator_name = "stablediffusion" + my_session.add(GeneratorSetting( + section=generator_section, + generator_name=generator_name, + active_grid_border_color=active_grid_colors[generator_name]["border"][generator_section], + active_grid_fill_color=active_grid_colors[generator_name]["fill"][generator_section] + )) + + my_session.add(Document( + name="Untitled", + settings=settings, + active=True + )) + + + + available_schedulers = {} + for scheduler_data in [ + ("Euler a", "EULER_ANCESTRAL"), + ("Euler", "EULER"), + ("LMS", "LMS"), + ("Heun", "HEUN"), + ("DPM2", "DPM2"), + ("DPM++ 2M", "DPM_PP_2M"), + ("DPM2 Karras", "DPM2_K"), + ("DPM2 a Karras", "DPM2_A_K"), + ("DPM++ 2M Karras", "DPM_PP_2M_K"), + ("DPM++ 2M SDE Karras", "DPM_PP_2M_SDE_K"), + ("DDIM", "DDIM"), + ("UniPC", "UNIPC"), + ("DDPM", "DDPM"), + ("DEIS", "DEIS"), + ("DPM 2M SDE Karras", "DPM_2M_SDE_K"), + ("PLMS", "PLMS"), ]: - obj = ActionScheduler( - section=section, - generator_name="stablediffusion", - scheduler_id=v.id + obj = Scheduler( + name=scheduler_data[1], + display_name=scheduler_data[0] ) my_session.add(obj) - my_session.commit() - - # create tab sections - my_session.add(TabSection( - panel="center_tab", - active_tab="Canvas" - )) - my_session.add(TabSection( - panel="tool_tab_widget", - active_tab="Embeddings" - )) - my_session.add(TabSection( - panel="prompt_builder.ui.tabs", - active_tab="0" - )) - my_session.commit() - - my_session.add(PromptBuilder( - name="Prompt A", - active=True - )) - my_session.add(PromptBuilder( - name="Prompt B", - active=True - )) - my_session.commit() - - my_session.add(CanvasSettings()) - my_session.commit() - - - for generator_name, generator_data in seed_data.items(): - generator = LLMGenerator(name=generator_name) - my_session.add(generator) - - # create GeneratorSetting with property, value and property_type based on value type - setting = LLMGeneratorSetting() - setting.generator = generator - for k, v in generator_data["generator_settings"].items(): - setting.__setattr__(k, v) - my_session.add(setting) - - if "model_versions" in generator_data: - model_versions = [] - for name in generator_data["model_versions"]: - print("Name", name) - model_versions.append(LLMModelVersion(name=name)) - - for version in model_versions: - generator.model_versions.append(version) - - my_session.add(generator) - my_session.commit() - - from airunner.data.bootstrap.prompt_templates import prompt_template_seed_data - for data in prompt_template_seed_data: - prompt_template = LLMPromptTemplate( - name=data["name"], - template=data["template"] - ) - my_session.add(prompt_template) - my_session.commit() + available_schedulers[scheduler_data[1]] = obj + + + generator_sections = { + "stablediffusion": { + "upscale": ["EULER"], + "superresolution": ["DDIM", "LMS", "PLMS"], + }, + } + + # add all of the schedulers for the defined generator sections + for generator, sections in generator_sections.items(): + for section, schedulers in sections.items(): + for scheduler in schedulers: + my_session.add(ActionScheduler( + section=section, + generator_name=generator, + scheduler_id=my_session.query(Scheduler).filter_by(name=scheduler).first().id + )) + + + # add the rest of the stable diffusion schedulers + for k, v in available_schedulers.items(): + for section in [ + "txt2img", "depth2img", "pix2pix", "vid2vid", + "outpaint", "controlnet", "txt2vid" + ]: + obj = ActionScheduler( + section=section, + generator_name="stablediffusion", + scheduler_id=v.id + ) + my_session.add(obj) + + + # create tab sections + my_session.add(TabSection( + panel="center_tab", + active_tab="Canvas" + )) + my_session.add(TabSection( + panel="tool_tab_widget", + active_tab="Embeddings" + )) + my_session.add(TabSection( + panel="prompt_builder.ui.tabs", + active_tab="0" + )) + + + my_session.add(CanvasSettings()) + + + + for generator_name, generator_data in seed_data.items(): + generator = LLMGenerator(name=generator_name) + my_session.add(generator) + + # create GeneratorSetting with property, value and property_type based on value type + setting = LLMGeneratorSetting() + setting.generator = generator + for k, v in generator_data["generator_settings"].items(): + setting.__setattr__(k, v) + my_session.add(setting) + + if "model_versions" in generator_data: + model_versions = [] + for name in generator_data["model_versions"]: + print("Name", name) + model_versions.append(LLMModelVersion(name=name)) + + for version in model_versions: + generator.model_versions.append(version) + + my_session.add(generator) + + + from airunner.data.bootstrap.prompt_templates import prompt_template_seed_data + for data in prompt_template_seed_data: + prompt_template = LLMPromptTemplate( + name=data["name"], + template=data["template"] + ) + my_session.add(prompt_template) + HERE = os.path.abspath(os.path.dirname(__file__)) alembic_ini_path = os.path.join(HERE, "../alembic.ini") diff --git a/src/airunner/data/managers.py b/src/airunner/data/managers.py new file mode 100644 index 000000000..0da848ce3 --- /dev/null +++ b/src/airunner/data/managers.py @@ -0,0 +1,189 @@ +from contextlib import contextmanager +from typing import Any, Iterator +from sqlalchemy.orm import joinedload +from PyQt6.QtCore import QObject, pyqtSignal +from airunner.utils import Logger + +from airunner.data.session_scope import ( + active_grid_settings_scope, + generator_scope, + settings_scope, + path_settings_scope, + grid_settings_scope, + standard_image_widget_settings_scope, + generator_settings_scope, + models_scope, + session_scope, + brush_settings_scope, + image_filters_scope, + llm_generator_scope, + llm_generator_settings_scope, + canvas_settings_scope, + memory_settings_scope +) + + +class Modelmanager: + def __init__(self, scope_function): + self.scope_function = scope_function + + def get_property(self, name: str) -> str: + try: + with self.scope_function() as object: + try: + value = getattr(object, name) + except AttributeError: + import traceback + traceback.print_exc() + #value = object.default # Use the default value of the object in scope + value = None + except Exception as e: + import traceback + traceback.print_exc() + print(f"Error while getting property {name}: {e}") + value = None # Return None if there's an error + return value + + def get_properties(self, name: str = None) -> Iterator[str]: + try: + print(f"Scope function: {self.scope_function}") + with self.scope_function() as objects: + for object in objects: + print(f"Object: {object}, attributes: {dir(object)}") + if name is None: + yield object + else: + try: + value = getattr(object, name) + except AttributeError: + value = object.default # Use the default value of the object in scope + yield value + except Exception as e: + import traceback + traceback.print_exc() + print(f"Error while getting property {name}: {e}") + yield None # Yield None if there's an error + + def __getattr__(self, name): + return self.get_property(name) + + +class SettingsManager(QObject): + _instance = None # Keep instance reference + changed_signal = pyqtSignal(str, object) + + scopes = { + "active_grid_settings": active_grid_settings_scope, + "grid_settings": grid_settings_scope, + "generator": generator_scope, + "settings": settings_scope, + "path_settings": path_settings_scope, + "standard_image_settings": standard_image_widget_settings_scope, + "generator_settings": generator_settings_scope, + "models": models_scope, + "brush_settings": brush_settings_scope, + "image_filters": image_filters_scope, + "llm_generator": llm_generator_scope, + "llm_generator_settings": llm_generator_settings_scope, + "canvas_settings": canvas_settings_scope, + "memory_settings": memory_settings_scope, + } + + def __new__(cls, *args, **kwargs): + if not isinstance(cls._instance, cls): + cls._instance = super(SettingsManager, cls).__new__(cls, *args, **kwargs) + return cls._instance + + # todo: handle changed_signalgrid_settings + def __init__(self): + super().__init__() + self.active_grid_settings = Modelmanager(active_grid_settings_scope) + self.grid_settings = Modelmanager(grid_settings_scope) + self.generator = Modelmanager(generator_scope) + self.settings = Modelmanager(settings_scope) + self.path_settings = Modelmanager(path_settings_scope) + self.standard_image_settings = Modelmanager(standard_image_widget_settings_scope) + self.generator_settings = Modelmanager(generator_settings_scope) + self.models = Modelmanager(models_scope) + self.brush_settings = Modelmanager(brush_settings_scope) + self.image_filters = Modelmanager(image_filters_scope) + self.llm_generator = Modelmanager(llm_generator_scope) + self.llm_generator_settings = Modelmanager(llm_generator_settings_scope) + self.canvas_settings = Modelmanager(canvas_settings_scope) + self.memory_settings = Modelmanager(memory_settings_scope) + + @contextmanager + def brushes(self): + from airunner.data.models import Brush + with session_scope() as session: + brushes = session.query(Brush).options(joinedload('*')).all() + yield brushes + + @contextmanager + def loras(self, search_filter=None): + from airunner.data.models import Lora + with session_scope() as session: + if search_filter: + loras = session.query(Lora).options(joinedload('*')).filter( + Lora.name.like(f"%{self.search_filter}%") if self.search_filter != "" else True).all() + else: + loras = session.query(Lora).options(joinedload('*')).all() + yield loras + + @contextmanager + def layers(self): + from airunner.data.models import Layer + with session_scope() as session: + layers = session.query(Layer).options(joinedload('*')).all() + yield layers + + @contextmanager + def document(self): + from airunner.data.models import Document + with session_scope() as session: + document = session.query(Document).options(joinedload('*')).first() + yield document + + @contextmanager + def models_by_pipeline_action(self, pipeline_action): + with session_scope() as session: + from airunner.data.models import AIModel + models = session.query(AIModel).options(joinedload('*')).all() + models.filter_by(pipeline_action=pipeline_action).all() + yield models + + def get_pipeline_classname(self, pipeline_action, version, category): + from airunner.data.models import Pipeline + try: + with session_scope() as session: + return session.query(Pipeline).filter_by( + category=category, + pipeline_action=pipeline_action, + version=version + ).first().classname + except AttributeError: + Logger.error(f"Unable to find pipeline classname for {pipeline_action} {version} {category}") + return None + + def get_value(self, key): + keys = key.split('.') + obj = self + for k in keys: + try: + obj = getattr(obj, k) + except AttributeError: + Logger.error(f"Unable to find key {key}") + return obj + + def set_value(self, key, value): + print(f"Setting value {key} to {value}") + keys = key.split('.') + obj = self + for k in keys[:-1]: # Traverse till second last key + if k in self.scopes: + with self.scopes[k]() as object: + obj = object + setattr(obj, keys[-1], value) + + self.changed_signal.emit(key, value) + print(f"Emitted changed_signal with {key}, {value}") # Debug print statement \ No newline at end of file diff --git a/src/airunner/data/models.py b/src/airunner/data/models.py index 5ac73cdd0..273c63510 100644 --- a/src/airunner/data/models.py +++ b/src/airunner/data/models.py @@ -372,35 +372,13 @@ class Brush(BaseModel): generator_setting = relationship('GeneratorSetting', back_populates='brushes') # modified line - -class PromptGeneratorSetting(BaseModel): - __tablename__ = 'prompt_generator_settings' - - id = Column(Integer, primary_key=True) - settings_id = Column(Integer, ForeignKey('settings.id')) - name = Column(String, default="") - advanced_mode = Column(Boolean, default=False) - category = Column(String, default="") - prompt_blend_type = Column(Integer, default=0) - prompt = Column(String, default="") - weighted_values = Column(JSON, default={}) - prompt_genre = Column(String, default="") - prompt_color = Column(String, default="") - prompt_style = Column(String, default="") - prefix = Column(String, default="") - suffix = Column(String, default="") - negative_prefix = Column(String, default="") - negative_suffix = Column(String, default="") - active = Column(Boolean, default=False) - - class GridSettings(BaseModel): __tablename__ = 'grid_settings' id = Column(Integer, primary_key=True) show_grid = Column(Boolean, default=True) snap_to_grid = Column(Boolean, default=True) - size = Column(Integer, default=64) + cell_size = Column(Integer, default=64) line_width = Column(Integer, default=1) canvas_color = Column(String, default="#000000") line_color = Column(String, default="#121212") @@ -530,8 +508,6 @@ def reset_paths(self): self.llm_casuallm_model_path = DEFAULT_PATHS["text"]["models"]["casuallm"] self.llm_seq2seq_model_path = DEFAULT_PATHS["text"]["models"]["seq2seq"] self.llm_visualqa_model_path = DEFAULT_PATHS["text"]["models"]["visualqa"] - from airunner.utils import save_session - save_session() class BrushSettings(BaseModel): @@ -638,8 +614,7 @@ class Settings(BaseModel): use_interpolation = Column(Boolean, default=False) is_maximized = Column(Boolean, default=False) splitter_sizes = relationship("SplitterSection", backref="settings") - prompt_generator_settings = relationship("PromptGeneratorSetting", backref="settings") - + # generator tab sections current_tab = Column(String, default="stablediffusion") current_section_stablediffusion = Column(String, default="txt2img") @@ -735,20 +710,6 @@ class TabSection(BaseModel): active_tab = Column(String) -class PromptBuilder(BaseModel): - __tablename__ = 'prompt_builder' - - id = Column(Integer, primary_key=True) - # document_id = Column(Integer, ForeignKey('documents.id')) - # document = relationship("Document", backref="prompt_builder") - name = Column(String, default="") - active = Column(Boolean, default=False) - auto_prompt_weight = Column(Float, default=0.5) - text_prompt_weight = Column(Float, default=0.5) - negative_auto_prompt_weight = Column(Float, default=0.5) - negative_text_prompt_weight = Column(Float, default=0.5) - - class CanvasSettings(BaseModel): __tablename__ = "canvas_settings" @@ -831,4 +792,3 @@ class Message(BaseModel): conversation_id = Column(Integer, ForeignKey('conversation.id')) conversation = relationship('Conversation', back_populates='messages') - diff --git a/src/airunner/data/session_scope.py b/src/airunner/data/session_scope.py new file mode 100644 index 000000000..ea719443b --- /dev/null +++ b/src/airunner/data/session_scope.py @@ -0,0 +1,134 @@ +from contextlib import contextmanager +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import joinedload +from sqlalchemy.exc import IntegrityError + +from airunner.settings import SQLITE_DB_PATH + +engine = create_engine(f'sqlite:///{SQLITE_DB_PATH}') +Session = sessionmaker(bind=engine) + +@contextmanager +def session_scope(): + """Provide a transactional scope around a series of operations.""" + session = Session() + try: + yield session + session.commit() + except IntegrityError as e: + if 'UNIQUE constraint failed' in str(e): + session.rollback() + pass # skip unique constraint errors + else: + session.rollback() + raise # re-raise other IntegrityErrors + except: + session.rollback() + raise + finally: + session.close() + + +@contextmanager +def settings_scope(): + from airunner.data.models import Settings + with session_scope() as session: + settings = session.query(Settings).options(joinedload('*')).first() + yield settings + + +@contextmanager +def generator_scope(): + from airunner.data.models import GeneratorSetting + with session_scope() as session: + generator = session.query(GeneratorSetting).options(joinedload('*')).first() + yield generator + +@contextmanager +def active_grid_settings_scope(): + from airunner.data.models import ActiveGridSettings + with session_scope() as session: + active_grid_settings = session.query(ActiveGridSettings).options(joinedload('*')).first() + yield active_grid_settings + +@contextmanager +def path_settings_scope(): + from airunner.data.models import PathSettings + with session_scope() as session: + path_settings = session.query(PathSettings).options(joinedload('*')).first() + yield path_settings + + +@contextmanager +def grid_settings_scope(): + from airunner.data.models import GridSettings + with session_scope() as session: + grid_settings = session.query(GridSettings).options(joinedload('*')).first() + yield grid_settings + + +@contextmanager +def standard_image_widget_settings_scope(): + from airunner.data.models import StandardImageWidgetSettings + with session_scope() as session: + standard_image_widget_settings = session.query(StandardImageWidgetSettings).options(joinedload('*')).first() + yield standard_image_widget_settings + +@contextmanager +def generator_settings_scope(): + from airunner.data.models import GeneratorSetting + with session_scope() as session: + generator_settings = session.query(GeneratorSetting).options(joinedload('*')).first() + yield generator_settings + + +@contextmanager +def models_scope(): + from airunner.data.models import AIModel + with session_scope() as session: + models = session.query(AIModel).all() + yield models + +@contextmanager +def brush_settings_scope(): + from airunner.data.models import BrushSettings + with session_scope() as session: + brush_settings = session.query(BrushSettings).options(joinedload('*')).first() + yield brush_settings + + +@contextmanager +def image_filters_scope(): + from airunner.data.models import ImageFilter + with session_scope() as session: + image_filters = session.query(ImageFilter).options(joinedload('*')).all() + yield image_filters + +@contextmanager +def llm_generator_scope(): + from airunner.data.models import LLMGenerator + with session_scope() as session: + llm_generator = session.query(LLMGenerator).options(joinedload('*')).first() + yield llm_generator + +@contextmanager +def llm_generator_settings_scope(): + from airunner.data.models import LLMGeneratorSetting + with session_scope() as session: + llm_generator = session.query(LLMGeneratorSetting).options(joinedload('*')).first() + yield llm_generator + +@contextmanager +def canvas_settings_scope(): + from airunner.data.models import CanvasSettings + with session_scope() as session: + canvas_settings = session.query(CanvasSettings).options(joinedload('*')).first() + yield canvas_settings + +@contextmanager +def memory_settings_scope(): + from airunner.data.models import MemorySettings + with session_scope() as session: + memory_settings = session.query(MemorySettings).options(joinedload('*')).first() + yield memory_settings \ No newline at end of file diff --git a/src/airunner/filters/windows/filter_base.py b/src/airunner/filters/windows/filter_base.py index 3f6aaab44..dda1f4d82 100644 --- a/src/airunner/filters/windows/filter_base.py +++ b/src/airunner/filters/windows/filter_base.py @@ -5,7 +5,6 @@ from PyQt6 import uic from airunner.widgets.slider.slider_widget import SliderWidget -from airunner.aihandler.settings_manager import SettingsManager class FilterBase: @@ -37,7 +36,7 @@ def __getattr__(self, item): def __setattr__(self, key, value): if key in self._filter_values: self._filter_values[key].value = str(value) - self.settings_manager.save() + self.app.settings_manager.save() else: super().__setattr__(key, value) @@ -58,7 +57,6 @@ def __init__(self, parent, model_name): # filter_values are the names of the ImageFilterValue objects in the database. # when the filter is shown, the values are loaded from the database # and stored in this dictionary. - self.settings_manager = SettingsManager(app=parent) self._filter_values = {} @@ -69,13 +67,13 @@ def __init__(self, parent, model_name): def update_value(self, name, value): self._filter_values[name].value = str(value) - self.settings_manager.save() + self.app.settings_manager.save() def update_canvas(self): pass def load_image_filter_data(self): - self.image_filter_data = self.settings_manager.get_image_filter(self.image_filter_model_name) + self.image_filter_data = self.app.settings_manager.get_image_filter(self.image_filter_model_name) for filter_value in self.image_filter_data.image_filter_values: self._filter_values[filter_value.name] = filter_value @@ -135,7 +133,7 @@ def show(self): def handle_auto_apply_toggle(self): self.image_filter_data.auto_apply = self.filter_window.auto_apply.isChecked() - self.settings_manager.save() + self.app.settings_manager.save() def handle_slider_change(self, settings_property, val): self.update_value(settings_property, val) diff --git a/src/airunner/main.py b/src/airunner/main.py index e3bf7f1bc..1c94a84ef 100644 --- a/src/airunner/main.py +++ b/src/airunner/main.py @@ -8,7 +8,7 @@ import os from airunner.data.db import prepare_database prepare_database() -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager settings_manager = SettingsManager() hf_cache_path = settings_manager.path_settings.hf_cache_path if hf_cache_path != "": @@ -79,7 +79,7 @@ def display_splash_screen(app): def show_main_application(app, splash, watch_files=False): try: - window = MainWindow() + window = MainWindow(settings_manager=settings_manager) if watch_files: print("Watching style files for changes...") # get existing app diff --git a/src/airunner/mixins/canvas_active_grid_area_mixin.py b/src/airunner/mixins/canvas_active_grid_area_mixin.py index 132ab1828..04e730c7f 100644 --- a/src/airunner/mixins/canvas_active_grid_area_mixin.py +++ b/src/airunner/mixins/canvas_active_grid_area_mixin.py @@ -7,9 +7,9 @@ class CanvasActiveGridAreaMixin: @property def active_grid_area_color(self): - current_tab = self.settings_manager.current_tab + current_tab = self.app.settings_manager.current_tab if current_tab == "stablediffusion": - current_section = self.settings_manager.current_section_stablediffusion + current_section = self.app.settings_manager.current_section_stablediffusion if current_section == "txt2img": brush_color = QColor(0, 255, 0) @@ -35,8 +35,8 @@ def active_grid_area_color(self): @property def active_grid_area_rect(self): - width = self.settings_manager.working_width - height = self.settings_manager.working_height + width = self.app.settings_manager.working_width + height = self.app.settings_manager.working_height rect = QRect( self.active_grid_area_pivot_point.x(), @@ -67,14 +67,14 @@ def draw_active_grid_area_container(self, painter): painter.setBrush(QBrush(QColor(0, 0, 0, 0))) pen = QPen( self.active_grid_area_color, - self.settings_manager.grid_settings.line_width + self.app.settings_manager.grid_settings.line_width ) painter.setPen(pen) rect = QRect( self.active_grid_area_rect.x(), self.active_grid_area_rect.y(), - self.settings_manager.working_width, - self.settings_manager.working_height + self.app.settings_manager.working_width, + self.app.settings_manager.working_height ) painter.drawRect(rect) @@ -82,33 +82,33 @@ def draw_active_grid_area_container(self, painter): # to make it more visible pen = QPen( self.active_grid_area_color, - self.settings_manager.grid_settings.line_width + 1 + self.app.settings_manager.grid_settings.line_width + 1 ) painter.setPen(pen) size = 4 rect = QRect( self.active_grid_area_rect.x() + size, self.active_grid_area_rect.y() + size, - self.settings_manager.working_width - (size * 2), - self.settings_manager.working_height - (size * 2) + self.app.settings_manager.working_width - (size * 2), + self.app.settings_manager.working_height - (size * 2) ) painter.drawRect(rect) # draw a third black border in the center of the two rectangles pen = QPen( QColor(0, 0, 0), - self.settings_manager.grid_settings.line_width + 1 + self.app.settings_manager.grid_settings.line_width + 1 ) painter.setPen(pen) size = 2 rect = QRect( self.active_grid_area_rect.x() + size, self.active_grid_area_rect.y() + size, - self.settings_manager.working_width - (size * 2), - self.settings_manager.working_height - (size * 2) + self.app.settings_manager.working_width - (size * 2), + self.app.settings_manager.working_height - (size * 2) ) painter.drawRect(rect) def reset_settings(self): - self.width_slider.setValue(self.settings_manager.working_width) - self.height_slider.setValue(self.settings_manager.working_height) + self.width_slider.setValue(self.app.settings_manager.working_width) + self.height_slider.setValue(self.app.settings_manager.working_height) diff --git a/src/airunner/mixins/canvas_brushes_mixin.py b/src/airunner/mixins/canvas_brushes_mixin.py index 219122813..64dd8a13b 100644 --- a/src/airunner/mixins/canvas_brushes_mixin.py +++ b/src/airunner/mixins/canvas_brushes_mixin.py @@ -208,7 +208,7 @@ def handle_erase(self, event): self.is_erasing = True if len(self.current_layer.lines) > 0: self.rasterize_lines(final=True) - brush_size = int(self.settings_manager.brush_settings.size / 2) + brush_size = int(self.app.settings_manager.brush_settings.size / 2) image = self.current_layer.image_data.image if self.current_layer.image_data.image is not None else None image_pos = self.current_layer.image_data.position if self.current_layer.image_data.image is not None else None if image is None: @@ -240,7 +240,7 @@ def handle_erase(self, event): def pen(self, event): brush_color = "#ffffff" if event.button() == Qt.MouseButton.LeftButton or Qt.MouseButton.LeftButton in event.buttons(): - brush_color = self.settings_manager.brush_settings.primary_color + brush_color = self.app.settings_manager.brush_settings.primary_color brush_color = QColor(brush_color) # brush_color = QColor( # brush_color.red(), @@ -250,7 +250,7 @@ def pen(self, event): # ) pen = QPen( brush_color, - self.settings_manager.brush_settings.size + self.app.settings_manager.brush_settings.size ) return pen @@ -273,7 +273,7 @@ def get_line_extremities(self, lines): end_x = line.end_point.x() end_y = line.end_point.y() - brush_size = int(self.settings_manager.brush_settings.size / 2) + brush_size = int(self.app.settings_manager.brush_settings.size / 2) min_x = min(start_x, end_x) - brush_size min_y = min(start_y, end_y) - brush_size max_x = max(start_x, end_x) + brush_size @@ -303,7 +303,7 @@ def rasterize_lines(self, final=False): lines = self.current_layer.lines[:max_lines] top, left, bottom, right = self.get_line_extremities(lines) - brush_size = self.settings_manager.brush_settings.size + brush_size = self.app.settings_manager.brush_settings.size if brush_size > 1: brush_size = int(brush_size / 2) diff --git a/src/airunner/mixins/canvas_grid_mixin.py b/src/airunner/mixins/canvas_grid_mixin.py index fcb50363d..d2e6d48d6 100644 --- a/src/airunner/mixins/canvas_grid_mixin.py +++ b/src/airunner/mixins/canvas_grid_mixin.py @@ -8,7 +8,7 @@ def active_grid_area_selected(self): @property def grid_size(self): - return self.settings_manager.grid_settings.size + return self.settings_manager.grid_settings.cell_size def initialize(self): # Set the grid line color and thickness diff --git a/src/airunner/mixins/canvas_image_mixin.py b/src/airunner/mixins/canvas_image_mixin.py index df82e7eb6..9b9eb714c 100644 --- a/src/airunner/mixins/canvas_image_mixin.py +++ b/src/airunner/mixins/canvas_image_mixin.py @@ -11,7 +11,8 @@ from airunner.data.models import LayerImage from airunner.models.imagedata import ImageData from airunner.models.layerdata import LayerData -from airunner.utils import apply_opacity_to_image, save_session, get_session +from airunner.utils import apply_opacity_to_image +from airunner.data.session_scope import session_scope class CanvasImageMixin: @@ -188,8 +189,8 @@ def paste_image_from_clipboard(self): return if self.app.settings_manager.resize_on_paste: - image.thumbnail((self.settings_manager.working_width, - self.settings_manager.working_height), Image.ANTIALIAS) + image.thumbnail((self.app.settings_manager.working_width, + self.app.settings_manager.working_height), Image.ANTIALIAS) self.create_image(image) def create_image(self, image): @@ -197,8 +198,8 @@ def create_image(self, image): Create a new image object and add it to the current layer """ location = QPoint( - self.settings_manager.active_grid_settings.pos_x, - self.settings_manager.active_grid_settings.pos_y + self.app.settings_manager.active_grid_settings.pos_x, + self.app.settings_manager.active_grid_settings.pos_y ) # convert image to RGBA image = image.convert("RGBA") @@ -210,14 +211,13 @@ def create_image(self, image): self.current_layer.position_x = location.x() self.current_layer.position_y = location.y() - session = get_session() - layer_image = LayerImage( - layer_id=self.current_layer.id, - order=len(self.current_layer.layer_images), - ) - layer_image.image = image - session.add(layer_image) - save_session() + with session_scope() as session: + layer_image = LayerImage( + layer_id=self.current_layer.id, + order=len(self.current_layer.layer_images), + ) + layer_image.image = image + session.add(layer_image) self.current_layer.layer_widget.set_thumbnail() # self.set_image_opacity(self.get_layer_opacity(self.current_layer_index)) @@ -266,8 +266,8 @@ def load_image(self, image_path): # if settings_manager.resize_on_paste, resize the image to working width and height while mainting its aspect ratio if self.app.settings_manager.resize_on_paste: - image.thumbnail((self.settings_manager.working_width, - self.settings_manager.working_height), Image.ANTIALIAS) + image.thumbnail((self.app.settings_manager.working_width, + self.app.settings_manager.working_height), Image.ANTIALIAS) self.create_image(image) diff --git a/src/airunner/prompt_builder/prompt_data.py b/src/airunner/prompt_builder/prompt_data.py index 2ded44b0b..707105800 100644 --- a/src/airunner/prompt_builder/prompt_data.py +++ b/src/airunner/prompt_builder/prompt_data.py @@ -3,8 +3,8 @@ from airunner.prompt_builder.prompt_parser import PromptParser from airunner.build_prompt import BuildPrompt -from airunner.utils import get_session from airunner.data.models import PromptVariableCategory, PromptCategory, PromptVariableCategoryWeight, PromptVariable, PromptOption, PromptStyleCategory, PromptStyle +from airunner.data.session_scope import session_scope class PromptData: @@ -314,10 +314,10 @@ def build_prompt_options(self, prompt_id, builder=None, prompt_options=None, nex if builder is None: builder = [] if prompt_options is None: - session = get_session() - prompt_options = session.query(PromptOption).filter_by( - prompt_id=prompt_id - ).all() + with session_scope() as session: + prompt_options = session.query(PromptOption).filter_by( + prompt_id=prompt_id + ).all() for prompt_option in prompt_options: if next_id and next_id != prompt_option.id: continue @@ -341,48 +341,51 @@ def build_prompt_options(self, prompt_id, builder=None, prompt_options=None, nex return builder def prepare_data(self, prompt_id): - session = get_session() - data = dict( categories=dict(), styles=dict(), extra_variables=dict(), ) - style_categories = session.query(PromptStyleCategory).all() - for cat in style_categories: - styles = session.query(PromptStyle).filter_by( - style_category_id=cat.id - ).all() - data["styles"][cat.name] = dict( - styles=[style.name for style in styles], - negative_prompt=cat.negative_prompt - ) - prompt_categories = session.query(PromptCategory).all() - variable_categories = session.query(PromptVariableCategory).all() - prompt_options = self.build_prompt_options(prompt_id) - for prompt_category in prompt_categories: - data["categories"][prompt_category.name] = dict( - weights=dict(), - variables=dict(), - builder=prompt_options, - negative_prompt=prompt_category.negative_prompt - ) - for variable_category in variable_categories: - variables = session.query(PromptVariable).filter_by( - prompt_category_id=prompt_category.id + with session_scope() as session: + style_categories = session.query(PromptStyleCategory).all() + + for cat in style_categories: + styles = session.query(PromptStyle).filter_by( + style_category_id=cat.id ).all() - weights = session.query(PromptVariableCategoryWeight).filter_by( - prompt_category_id=prompt_category.id - ).all() - for variable in variables: - if variable.variable_category_id == variable_category.id: - if variable_category.name not in data["categories"][prompt_category.name]["variables"]: - data["categories"][prompt_category.name]["variables"][variable_category.name] = [] - data["categories"][prompt_category.name]["variables"][variable_category.name].append(variable.value) - for variable_weight in weights: - if variable_weight.variable_category_id == variable_category.id: - data["categories"][prompt_category.name]["weights"][variable_category.name] = variable_weight.weight + data["styles"][cat.name] = dict( + styles=[style.name for style in styles], + negative_prompt=cat.negative_prompt + ) + + prompt_categories = session.query(PromptCategory).all() + + variable_categories = session.query(PromptVariableCategory).all() + + prompt_options = self.build_prompt_options(prompt_id) + for prompt_category in prompt_categories: + data["categories"][prompt_category.name] = dict( + weights=dict(), + variables=dict(), + builder=prompt_options, + negative_prompt=prompt_category.negative_prompt + ) + for variable_category in variable_categories: + variables = session.query(PromptVariable).filter_by( + prompt_category_id=prompt_category.id + ).all() + weights = session.query(PromptVariableCategoryWeight).filter_by( + prompt_category_id=prompt_category.id + ).all() + for variable in variables: + if variable.variable_category_id == variable_category.id: + if variable_category.name not in data["categories"][prompt_category.name]["variables"]: + data["categories"][prompt_category.name]["variables"][variable_category.name] = [] + data["categories"][prompt_category.name]["variables"][variable_category.name].append(variable.value) + for variable_weight in weights: + if variable_weight.variable_category_id == variable_category.id: + data["categories"][prompt_category.name]["weights"][variable_category.name] = variable_weight.weight self.data = data @@ -403,9 +406,10 @@ def prepare_data(self, prompt_id): json.dump(self.data, f) def set_variables_by_name(self, name): - session = get_session() - composition_genre = session.query(PromptVariableCategory).filter_by(name=name).first() - variables = session.query(PromptVariable).filter_by(variable_category_id=composition_genre.id).all() - values = [variable.value for variable in variables] - values.sort() - self.prompt_variables[name] = ["Random"] + values + with session_scope() as session: + composition_genre = session.query(PromptVariableCategory).filter_by(name=name).first() + variables = session.query(PromptVariable).filter_by(variable_category_id=composition_genre.id).all() + + values = [variable.value for variable in variables] + values.sort() + self.prompt_variables[name] = ["Random"] + values diff --git a/src/airunner/tests/test_canvas_brushes_mixin.py b/src/airunner/tests/test_canvas_brushes_mixin.py index 2d9883433..6b5c37c6d 100644 --- a/src/airunner/tests/test_canvas_brushes_mixin.py +++ b/src/airunner/tests/test_canvas_brushes_mixin.py @@ -4,7 +4,7 @@ from PyQt6.QtGui import QPen from airunner.mixins.canvas_brushes_mixin import CanvasBrushesMixin -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.models.layerdata import LayerData from airunner.models.linedata import LineData @@ -15,7 +15,7 @@ def setUp(self): self.cbm.pos_x = 0 self.cbm.pos_y = 0 self.cbm.settings_manager = SettingsManager() - self.cbm.settings_manager.set_value("mask_brush_size", 10) + self.cbm.settings_manager.set_value("settings.mask_brush_size", 10) self.cbm.current_layer = LayerData(0, "Untitled", True, 1.0, QPoint(0, 0)) def test_get_line_extremities(self): diff --git a/src/airunner/utils.py b/src/airunner/utils.py index 561bdf193..32734eb12 100644 --- a/src/airunner/utils.py +++ b/src/airunner/utils.py @@ -8,6 +8,7 @@ from airunner.aihandler.logger import Logger from airunner.settings import SQLITE_DB_PATH from PIL import PngImagePlugin +from airunner.data.session_scope import session_scope SESSION = None @@ -50,7 +51,7 @@ def get_venv_python_executable(): def initialize_os_environment(): - from airunner.aihandler.settings_manager import SettingsManager + from airunner.data.managers import SettingsManager settings_manager = SettingsManager() hf_cache_path = settings_manager.path_settings.hf_cache_path if hf_cache_path != "": @@ -253,7 +254,7 @@ def get_version(): # return models def prepare_metadata(data, index=0): - from airunner.aihandler.settings_manager import SettingsManager + from airunner.data.managers import SettingsManager settings_manager = SettingsManager() if not settings_manager.metadata_settings.export_metadata or \ settings_manager.image_export_type != "png": @@ -297,7 +298,7 @@ def prepare_metadata(data, index=0): return metadata def prepare_controlnet_metadata(data): - from airunner.aihandler.settings_manager import SettingsManager + from airunner.data.managers import SettingsManager from PIL import PngImagePlugin settings_manager = SettingsManager() metadata = PngImagePlugin.PngInfo() @@ -310,7 +311,7 @@ def auto_export_image( latents_seed=None, type="image", ): - from airunner.aihandler.settings_manager import SettingsManager + from airunner.data.managers import SettingsManager if seed is None: raise Exception("Seed must be set when auto exporting an image") @@ -413,54 +414,29 @@ def get_main_window(): return widget -def get_session(): - global SESSION - if not SESSION: - from sqlalchemy import create_engine - from sqlalchemy.orm import sessionmaker - from airunner.data.models import Base - - engine = create_engine(f"sqlite:///{SQLITE_DB_PATH}") - Base.metadata.create_all(engine) - Session = sessionmaker(bind=engine) - SESSION = Session() - return SESSION - - -def save_session(session=None): - session = get_session() if not session else session - try: - session.commit() - return True - except Exception as e: - Logger.error("Failed to save session") - session.rollback() - return False - - def create_airunner_paths(): from airunner.data.models import PathSettings import os - session = get_session() - path_settings = session.query(PathSettings).first() - if path_settings: - paths = [ - path_settings.base_path, - path_settings.txt2img_model_path, - path_settings.depth2img_model_path, - path_settings.pix2pix_model_path, - path_settings.outpaint_model_path, - path_settings.upscale_model_path, - path_settings.txt2vid_model_path, - path_settings.embeddings_path, - path_settings.lora_path, - path_settings.image_path, - path_settings.video_path - ] - for index, path in enumerate(paths): - if not os.path.exists(path): - print("cerating path", index, path) - os.makedirs(path) + with session_scope() as session: + path_settings = session.query(PathSettings).first() + if path_settings: + paths = [ + path_settings.base_path, + path_settings.txt2img_model_path, + path_settings.depth2img_model_path, + path_settings.pix2pix_model_path, + path_settings.outpaint_model_path, + path_settings.upscale_model_path, + path_settings.txt2vid_model_path, + path_settings.embeddings_path, + path_settings.lora_path, + path_settings.image_path, + path_settings.video_path + ] + for index, path in enumerate(paths): + if not os.path.exists(path): + print("cerating path", index, path) + os.makedirs(path) def apply_opacity_to_image(image, target_opacity): diff --git a/src/airunner/widgets/active_grid_settings/active_grid_settings_widget.py b/src/airunner/widgets/active_grid_settings/active_grid_settings_widget.py index 221a0e05b..7ce550c6f 100644 --- a/src/airunner/widgets/active_grid_settings/active_grid_settings_widget.py +++ b/src/airunner/widgets/active_grid_settings/active_grid_settings_widget.py @@ -7,23 +7,23 @@ class ActiveGridSettingsWidget(BaseWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.ui.width_slider_widget.setProperty("current_value", self.settings_manager.working_width) - self.ui.height_slider_widget.setProperty("current_value", self.settings_manager.working_height) + self.ui.width_slider_widget.setProperty("current_value", self.app.settings_manager.settings.working_width) + self.ui.height_slider_widget.setProperty("current_value", self.app.settings_manager.settings.working_height) self.ui.width_slider_widget.initialize() self.ui.height_slider_widget.initialize() - self.ui.border_opacity_slider_widget.setProperty("current_value", self.settings_manager.active_grid_settings.border_opacity) - self.ui.fill_opacity_slider_widget.setProperty("current_value", self.settings_manager.active_grid_settings.fill_opacity) + self.ui.border_opacity_slider_widget.setProperty("current_value", self.app.settings_manager.active_grid_settings.border_opacity) + self.ui.fill_opacity_slider_widget.setProperty("current_value", self.app.settings_manager.active_grid_settings.fill_opacity) self.ui.border_opacity_slider_widget.initialize() self.ui.fill_opacity_slider_widget.initialize() - self.ui.active_grid_area_groupbox.setChecked(self.settings_manager.active_grid_settings.enabled) - self.ui.active_grid_border_groupbox.setChecked(self.settings_manager.active_grid_settings.render_border) - self.ui.active_grid_fill_groupbox.setChecked(self.settings_manager.active_grid_settings.render_fill) + self.ui.active_grid_area_groupbox.setChecked(self.app.settings_manager.active_grid_settings.enabled) + self.ui.active_grid_border_groupbox.setChecked(self.app.settings_manager.active_grid_settings.render_border) + self.ui.active_grid_fill_groupbox.setChecked(self.app.settings_manager.active_grid_settings.render_fill) def action_clicked_checkbox_toggle_active_grid_border(self, checked): - self.settings_manager.set_value("active_grid_settings.render_border", checked) + self.app.settings_manager.set_value("active_grid_settings.render_border", checked) def action_clicked_checkbox_toggle_active_grid_fill(self, checked): - self.settings_manager.set_value("active_grid_settings.render_fill", checked) + self.app.settings_manager.set_value("active_grid_settings.render_fill", checked) def action_clicked_checkbox_toggle_active_grid_area(self, checked): - self.settings_manager.set_value("active_grid_settings.render_active_grid_area", checked) + self.app.settings_manager.set_value("active_grid_settings.render_active_grid_area", checked) diff --git a/src/airunner/widgets/active_grid_settings/templates/active_grid_settings.ui b/src/airunner/widgets/active_grid_settings/templates/active_grid_settings.ui index 204890610..731370ec2 100644 --- a/src/airunner/widgets/active_grid_settings/templates/active_grid_settings.ui +++ b/src/airunner/widgets/active_grid_settings/templates/active_grid_settings.ui @@ -198,7 +198,7 @@ action_slider_changed - working_width + settings.working_width false @@ -241,7 +241,7 @@ action_slider_changed - working_height + settings.working_height false diff --git a/src/airunner/widgets/active_grid_settings/templates/active_grid_settings_ui.py b/src/airunner/widgets/active_grid_settings/templates/active_grid_settings_ui.py index 36f4afc36..022798dd6 100644 --- a/src/airunner/widgets/active_grid_settings/templates/active_grid_settings_ui.py +++ b/src/airunner/widgets/active_grid_settings/templates/active_grid_settings_ui.py @@ -82,7 +82,7 @@ def setupUi(self, active_grid_settings_widget): self.width_slider_widget.setProperty("spinbox_single_step", 64) self.width_slider_widget.setProperty("spinbox_page_step", 64) self.width_slider_widget.setProperty("slider_callback", "action_slider_changed") - self.width_slider_widget.setProperty("settings_property", "working_width") + self.width_slider_widget.setProperty("settings_property", "settings.working_width") self.width_slider_widget.setProperty("display_as_float", False) self.width_slider_widget.setObjectName("width_slider_widget") self.verticalLayout.addWidget(self.width_slider_widget) @@ -128,5 +128,5 @@ def retranslateUi(self, active_grid_settings_widget): self.groupBox_3.setTitle(_translate("active_grid_settings_widget", "Size")) self.width_slider_widget.setProperty("label_text", _translate("active_grid_settings_widget", "Active Grid Width")) self.height_slider_widget.setProperty("label_text", _translate("active_grid_settings_widget", "Active Grid Height")) - self.height_slider_widget.setProperty("settings_property", _translate("active_grid_settings_widget", "working_height")) + self.height_slider_widget.setProperty("settings_property", _translate("active_grid_settings_widget", "settings.working_height")) from airunner.widgets.slider.slider_widget import SliderWidget diff --git a/src/airunner/widgets/api_token/api_token_widget.py b/src/airunner/widgets/api_token/api_token_widget.py index 593a7cbe9..4a23c2f34 100644 --- a/src/airunner/widgets/api_token/api_token_widget.py +++ b/src/airunner/widgets/api_token/api_token_widget.py @@ -11,17 +11,17 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.ui.hf_api_key_text_generation.blockSignals(True) self.ui.hf_api_key_text_generation.setEchoMode(QLineEdit.EchoMode.Password) - self.ui.hf_api_key_text_generation.setText(self.settings_manager.hf_api_key_read_key) + self.ui.hf_api_key_text_generation.setText(self.app.settings_manager.hf_api_key_read_key) self.ui.hf_api_key_writetoken.blockSignals(True) self.ui.hf_api_key_writetoken.setEchoMode(QLineEdit.EchoMode.Password) - self.ui.hf_api_key_writetoken.setText(self.settings_manager.hf_api_key_write_key) + self.ui.hf_api_key_writetoken.setText(self.app.settings_manager.hf_api_key_write_key) self.ui.hf_api_key_text_generation.blockSignals(False) self.ui.hf_api_key_writetoken.blockSignals(False) def action_text_edited_api_key(self, value): - self.settings_manager.set_value("hf_api_key_read_key", value) + self.app.settings_manager.set_value("settings.hf_api_key_read_key", value) def action_text_edited_writekey(self, value): - self.settings_manager.set_value("hf_api_key_write_key", value) + self.app.settings_manager.set_value("settings.hf_api_key_write_key", value) diff --git a/src/airunner/widgets/base_widget.py b/src/airunner/widgets/base_widget.py index cd314ef85..cbab42769 100644 --- a/src/airunner/widgets/base_widget.py +++ b/src/airunner/widgets/base_widget.py @@ -2,7 +2,7 @@ from PyQt6 import QtGui from PyQt6.QtWidgets import QWidget -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.utils import get_main_window @@ -14,7 +14,7 @@ class BaseWidget(QWidget): @property def is_dark(self): - return self.settings_manager.dark_mode_enabled + return self.app.settings_manager.settings.dark_mode_enabled @property def canvas(self): @@ -27,7 +27,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.app = get_main_window() self.app.loaded.connect(self.initialize) - self.settings_manager = SettingsManager() if self.widget_class_: self.ui = self.widget_class_() if self.ui: @@ -40,6 +39,21 @@ def __init__(self, *args, **kwargs): # self.setStyleSheet(stylesheet) self.set_icons() + def handle_settings_manager_changed(self, key, val, settings_manager): + """ + Handle the change in settings manager. + + Args: + key (str): The key of the changed setting. + val: The new value of the changed setting. + settings_manager: The settings manager object. + + Returns: + None + """ + print("handle_settings_manager_changed") + pass + def initialize(self): """ Triggered when the app is loaded. @@ -138,7 +152,7 @@ def set_form_value(self, element, settings_key_name): val = self.get_value(element) if val is None: val = self.get_is_checked(element) - target_val = self.settings_manager.get_value(settings_key_name) + target_val = self.app.settings_manager.get_value(settings_key_name) if val != target_val: if not self.set_plain_text(element, target_val): @@ -150,7 +164,7 @@ def set_form_value(self, element, settings_key_name): def set_form_property(self, element, property_name, settings_key_name=None, settings=None): val = self.get_form_element(element).property(property_name) if settings_key_name: - target_val = self.settings_manager.get_value(settings_key_name) + target_val = self.app.settings_manager.get_value(settings_key_name) elif settings: target_val = getattr(settings, property_name) diff --git a/src/airunner/widgets/brush/brush_container_widget.py b/src/airunner/widgets/brush/brush_container_widget.py index 37a4c8700..71db50996 100644 --- a/src/airunner/widgets/brush/brush_container_widget.py +++ b/src/airunner/widgets/brush/brush_container_widget.py @@ -1,11 +1,20 @@ +from contextlib import contextmanager from airunner.widgets.base_widget import BaseWidget from airunner.widgets.brush.templates.brush_widget_ui import Ui_brush_widget +from airunner.data.session_scope import session_scope class BrushContainerWidget(BaseWidget): widget_class_ = Ui_brush_widget + _brush = None + + @contextmanager + def brush(self): + with session_scope() as session: + session.add(self._brush) + yield self._brush def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.ui.brush_size_slider.setProperty("current_value", self.settings_manager.brush_settings.size) + self.ui.brush_size_slider.setProperty("current_value", self.app.settings_manager.brush_settings.size) self.ui.brush_size_slider.initialize() diff --git a/src/airunner/widgets/brushes/brushes_container.py b/src/airunner/widgets/brushes/brushes_container.py index bc3b24e0d..2c4e065e5 100644 --- a/src/airunner/widgets/brushes/brushes_container.py +++ b/src/airunner/widgets/brushes/brushes_container.py @@ -1,19 +1,21 @@ import io +from io import BytesIO import json -from airunner.widgets.base_widget import BaseWidget -from airunner.widgets.image.image_widget import BrushImageWidget -from airunner.widgets.qflowlayout.q_flow_layout import QFlowLayout +import base64 +from PIL import Image + from PyQt6.QtWidgets import QInputDialog from PyQt6.QtGui import QPixmap from PyQt6.QtCore import Qt -from airunner.utils import get_session -from airunner.data.models import Brush, GeneratorSetting -import base64 -from PIL import Image -from io import BytesIO from PyQt6.QtCore import QBuffer from PyQt6.QtWidgets import QMenu +from airunner.widgets.base_widget import BaseWidget +from airunner.widgets.image.image_widget import BrushImageWidget +from airunner.widgets.qflowlayout.q_flow_layout import QFlowLayout +from airunner.data.models import Brush, GeneratorSetting +from airunner.data.session_scope import session_scope + class BrushesContainer(BaseWidget): def __init__(self, *args, **kwargs): @@ -60,60 +62,56 @@ def save_brush(self, brush_name, thumbnail: QPixmap, meta_data): # Convert the bytes to base64 img_base64 = base64.b64encode(img_bytes).decode() - session = get_session() - - # Create a new GeneratorSetting entry with the metadata - generator_setting = GeneratorSetting( - section=meta_data.get("section", getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}")), - generator_name=meta_data.get("generator_name", self.settings_manager.current_image_generator), - prompt=meta_data.get("prompt", ""), - negative_prompt=meta_data.get("negative_prompt", ""), - steps=meta_data.get("steps", 20), - ddim_eta=meta_data.get("ddim_eta", 0.5), - height=meta_data.get("height", 512), - width=meta_data.get("width", 512), - scale=meta_data.get("scale", 750), - seed=meta_data.get("seed", 42), - latents_seed=meta_data.get("latents_seed", 84), - random_seed=meta_data.get("random_seed", True), - random_latents_seed=meta_data.get("random_latents_seed", True), - model=meta_data.get("model", ""), - scheduler=meta_data.get("scheduler", "DPM++ 2M Karras"), - prompt_triggers=meta_data.get("prompt_triggers", ""), - strength=meta_data.get("strength", 50), - image_guidance_scale=meta_data.get("image_guidance_scale", 150), - n_samples=meta_data.get("n_samples", 1), - controlnet=meta_data.get("controlnet", ""), - enable_controlnet=meta_data.get("enable_controlnet", False), - enable_input_image=meta_data.get("enable_input_image", False), - controlnet_guidance_scale=meta_data.get("controlnet_guidance_scale", 50), - clip_skip=meta_data.get("clip_skip", 0), - variation=meta_data.get("variation", False), - input_image_use_imported_image=meta_data.get("input_image_use_imported_image", False), - input_image_use_grid_image=meta_data.get("input_image_use_grid_image", True), - input_image_recycle_grid_image=meta_data.get("input_image_recycle_grid_image", True), - input_image_mask_use_input_image=meta_data.get("input_image_mask_use_input_image", True), - input_image_mask_use_imported_image=meta_data.get("input_image_mask_use_imported_image", False), - controlnet_input_image_link_to_input_image=meta_data.get("controlnet_input_image_link_to_input_image", True), - controlnet_input_image_use_imported_image=meta_data.get("controlnet_input_image_use_imported_image", False), - controlnet_use_grid_image=meta_data.get("controlnet_use_grid_image", False), - controlnet_recycle_grid_image=meta_data.get("controlnet_recycle_grid_image", False), - controlnet_mask_link_input_image=meta_data.get("controlnet_mask_link_input_image", False), - controlnet_mask_use_imported_image=meta_data.get("controlnet_mask_use_imported_image", False), - use_prompt_builder=meta_data.get("use_prompt_builder", False), - active_grid_border_color=meta_data.get("active_grid_border_color", "#00FF00"), - active_grid_fill_color=meta_data.get("active_grid_fill_color", "#FF0000") - ) - - session.add(generator_setting) - session.commit() - - # Create a new Brush entry associated with the GeneratorSetting entry - brush = Brush(name=brush_name, thumbnail=img_base64, generator_setting_id=generator_setting.id) - session.add(brush) - - session.commit() - + with session_scope() as session: + + # Create a new GeneratorSetting entry with the metadata + generator_setting = GeneratorSetting( + section=meta_data.get("section", self.app.settings_manager.settings.current_section_stablediffusion), + generator_name=meta_data.get("generator_name", self.app.settings_manager.settings.current_image_generator), + prompt=meta_data.get("prompt", ""), + negative_prompt=meta_data.get("negative_prompt", ""), + steps=meta_data.get("steps", 20), + ddim_eta=meta_data.get("ddim_eta", 0.5), + height=meta_data.get("height", 512), + width=meta_data.get("width", 512), + scale=meta_data.get("scale", 750), + seed=meta_data.get("seed", 42), + latents_seed=meta_data.get("latents_seed", 84), + random_seed=meta_data.get("random_seed", True), + random_latents_seed=meta_data.get("random_latents_seed", True), + model=meta_data.get("model", ""), + scheduler=meta_data.get("scheduler", "DPM++ 2M Karras"), + prompt_triggers=meta_data.get("prompt_triggers", ""), + strength=meta_data.get("strength", 50), + image_guidance_scale=meta_data.get("image_guidance_scale", 150), + n_samples=meta_data.get("n_samples", 1), + controlnet=meta_data.get("controlnet", ""), + enable_controlnet=meta_data.get("enable_controlnet", False), + enable_input_image=meta_data.get("enable_input_image", False), + controlnet_guidance_scale=meta_data.get("controlnet_guidance_scale", 50), + clip_skip=meta_data.get("clip_skip", 0), + variation=meta_data.get("variation", False), + input_image_use_imported_image=meta_data.get("input_image_use_imported_image", False), + input_image_use_grid_image=meta_data.get("input_image_use_grid_image", True), + input_image_recycle_grid_image=meta_data.get("input_image_recycle_grid_image", True), + input_image_mask_use_input_image=meta_data.get("input_image_mask_use_input_image", True), + input_image_mask_use_imported_image=meta_data.get("input_image_mask_use_imported_image", False), + controlnet_input_image_link_to_input_image=meta_data.get("controlnet_input_image_link_to_input_image", True), + controlnet_input_image_use_imported_image=meta_data.get("controlnet_input_image_use_imported_image", False), + controlnet_use_grid_image=meta_data.get("controlnet_use_grid_image", False), + controlnet_recycle_grid_image=meta_data.get("controlnet_recycle_grid_image", False), + controlnet_mask_link_input_image=meta_data.get("controlnet_mask_link_input_image", False), + controlnet_mask_use_imported_image=meta_data.get("controlnet_mask_use_imported_image", False), + use_prompt_builder=meta_data.get("use_prompt_builder", False), + active_grid_border_color=meta_data.get("active_grid_border_color", "#00FF00"), + active_grid_fill_color=meta_data.get("active_grid_fill_color", "#FF0000") + ) + + session.add(generator_setting) + + # Create a new Brush entry associated with the GeneratorSetting entry + brush = Brush(name=brush_name, thumbnail=img_base64, generator_setting_id=generator_setting.id) + session.add(brush) return brush selected_brushes = [] @@ -133,7 +131,7 @@ def activate_brush(self, clicked_widget, brush, multiple): else: self.selected_brushes.remove(widget) widget.setStyleSheet("") - self.settings_manager.set_value("generator_settings_override_id", None) + self.app.settings_manager.set_value("settings.generator_settings_override_id", None) return for widget in self.selected_brushes: @@ -154,7 +152,8 @@ def activate_brush(self, clicked_widget, brush, multiple): widget.setStyleSheet(f""" border: 2px solid #ff0000; """) - self.settings_manager.set_value("generator_settings_override_id", widget.brush.generator_setting_id) + with widget.brush() as brush: + self.app.settings_manager.set_value("settings.generator_settings_override_id", brush.generator_setting_id) def display_brush_menu(self, event, widget, brush): context_menu = QMenu(self) @@ -165,18 +164,18 @@ def display_brush_menu(self, event, widget, brush): global_position = self.mapToGlobal(event.pos()) context_menu.exec(global_position) - def delete_brush(self, widget, brush): - session = get_session() - brush = session.query(Brush).filter(Brush.id == brush.id).first() - generator_setting = session.query(GeneratorSetting).filter(GeneratorSetting.id == brush.generator_setting_id).first() - - if generator_setting is not None: - session.delete(generator_setting) - - if brush is not None: - session.delete(brush) - - session.commit() + def delete_brush(self, widget, _brush): + with widget.brush() as brush: + with session_scope() as session: + brush = session.query(Brush).filter(Brush.id == brush.id).first() + generator_setting = session.query(GeneratorSetting).filter(GeneratorSetting.id == brush.generator_setting_id).first() + + if generator_setting is not None: + session.delete(generator_setting) + + if brush is not None: + session.delete(brush) + widget.deleteLater() def create_and_add_widget(self, image_source, is_base64=False, brush=None): @@ -224,14 +223,12 @@ def dropEvent(self, event): widget.deleteLater() else: # Save the brush name, thumbnail, and metadata to the database - widget.brush = self.save_brush(brush_name, widget.thumbnail(), meta_data) + widget._brush = self.save_brush(brush_name, widget.pixmap, meta_data) event.acceptProposedAction() def load_brushes(self): - session = get_session() - brushes = session.query(Brush).all() - - for brush in brushes: - self.create_and_add_widget(brush.thumbnail, is_base64=True, brush=brush) + with self.app.settings_manager.brushes() as brushes: + for brush in brushes: + self.create_and_add_widget(brush.thumbnail, is_base64=True, brush=brush) diff --git a/src/airunner/widgets/canvas_plus/canvas_plus_widget.py b/src/airunner/widgets/canvas_plus/canvas_plus_widget.py index 24dd9156e..3271dd71f 100644 --- a/src/airunner/widgets/canvas_plus/canvas_plus_widget.py +++ b/src/airunner/widgets/canvas_plus/canvas_plus_widget.py @@ -13,13 +13,13 @@ from PyQt6.QtCore import QLineF from airunner.aihandler.logger import Logger -from airunner.aihandler.settings_manager import SettingsManager from airunner.cursors.circle_brush import CircleCursor -from airunner.data.models import Layer, CanvasSettings, ActiveGridSettings -from airunner.utils import save_session, get_session +from airunner.data.models import Layer, CanvasSettings from airunner.widgets.canvas_plus.canvas_base_widget import CanvasBaseWidget from airunner.widgets.canvas_plus.templates.canvas_plus_ui import Ui_canvas from airunner.utils import apply_opacity_to_image +from airunner.data.session_scope import session_scope +from airunner.data.managers import SettingsManager class ImageAdder(QThread): @@ -33,32 +33,29 @@ def __init__(self, widget, image, is_outpaint, image_root_point): self.image_root_point = image_root_point def run(self): - session = get_session() - self.widget.current_active_image = self.image - if self.image_root_point is not None: - self.widget.current_layer.pos_x = self.image_root_point.x() - self.widget.current_layer.pos_y = self.image_root_point.y() - elif not self.is_outpaint: - self.widget.current_layer.pos_x = self.widget.active_grid_area_rect.x() - self.widget.current_layer.pos_y = self.widget.active_grid_area_rect.y() - session.add(self.widget.current_layer) - save_session() - self.widget.do_draw() - self.finished.emit() + with session_scope() as session: + self.widget.current_active_image = self.image + if self.image_root_point is not None: + self.widget.current_layer.pos_x = self.image_root_point.x() + self.widget.current_layer.pos_y = self.image_root_point.y() + elif not self.is_outpaint: + self.widget.current_layer.pos_x = self.widget.active_grid_area_rect.x() + self.widget.current_layer.pos_y = self.widget.active_grid_area_rect.y() + session.add(self.widget.current_layer) + self.widget.do_draw() + self.finished.emit() class DraggablePixmap(QGraphicsPixmapItem): def __init__(self, parent, pixmap): self.parent = parent - self.settings_manager = SettingsManager() super().__init__(pixmap) self.pixmap = pixmap self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True) - def snap_to_grid(self): - grid_size = self.settings_manager.grid_settings.size + grid_size = self.parent.settings_manager.grid_settings.cell_size x = round(self.x() / grid_size) * grid_size y = round(self.y() / grid_size) * grid_size x += self.parent.last_pos.x() @@ -85,10 +82,11 @@ def __init__(self, parent, pixmap, layer_image_data): def mouseReleaseEvent(self, event): super().mouseReleaseEvent(event) - pos = self.pos() - self.layer_image_data.pos_x = pos.x() - self.layer_image_data.pos_y = pos.y() - save_session() + with session_scope() as session: + pos = self.pos() + self.layer_image_data.pos_x = pos.x() + self.layer_image_data.pos_y = pos.y() + session.add(self.layer_image_data) class ActiveGridArea(DraggablePixmap): @@ -96,27 +94,27 @@ class ActiveGridArea(DraggablePixmap): image = None def __init__(self, parent, rect): - self.settings_manager = SettingsManager() + self.app = parent.app self.update_settings() super().__init__(parent, self.pixmap) self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True) - self.settings_manager.changed_signal.connect(self.handle_changed_signal) + self.app.settings_manager.changed_signal.connect(self.handle_changed_signal) @property def active_grid_area_rect(self): return QRect( - self.settings_manager.active_grid_settings.pos_x, - self.settings_manager.active_grid_settings.pos_y, - self.settings_manager.working_width, - self.settings_manager.working_height + self.app.settings_manager.active_grid_settings.pos_x, + self.app.settings_manager.active_grid_settings.pos_y, + self.app.settings_manager.settings.working_width, + self.app.settings_manager.settings.working_height ) def update_settings(self): - border_color = self.settings_manager.generator.active_grid_border_color + border_color = self.app.settings_manager.generator.active_grid_border_color border_color = QColor(border_color) - border_opacity = self.settings_manager.active_grid_settings.border_opacity + border_opacity = self.app.settings_manager.active_grid_settings.border_opacity border_color.setAlpha(border_opacity) fill_color = self.get_fill_color() @@ -138,6 +136,7 @@ def update_settings(self): self.pixmap = QPixmap.fromImage(self.image) def handle_changed_signal(self, key, value): + print("active_grid_area: handle_changed_signal", key, value) if key == "active_grid_settings.fill_opacity": self.change_fill_opacity(value) self.redraw() @@ -152,9 +151,9 @@ def handle_changed_signal(self, key, value): self.redraw() elif key in [ "active_grid_settings.enabled", - "current_tab", - "working_width", - "working_height", + "settings.current_tab", + "settings.working_width", + "settings.working_height", ]: self.redraw() @@ -163,33 +162,33 @@ def redraw(self): scene = self.scene() if scene: scene.removeItem(self) - if self.settings_manager.active_grid_settings.enabled: + if self.app.settings_manager.active_grid_settings.enabled: scene.addItem(self) def get_fill_color(self): - fill_color = self.settings_manager.generator.active_grid_fill_color + fill_color = self.app.settings_manager.generator.active_grid_fill_color fill_color = QColor(fill_color) - fill_opacity = self.settings_manager.active_grid_settings.fill_opacity + fill_opacity = self.app.settings_manager.active_grid_settings.fill_opacity fill_opacity = max(1, fill_opacity) fill_color.setAlpha(fill_opacity) return fill_color def paint(self, painter: QPainter, option, widget=None): - if not self.settings_manager.active_grid_settings.render_fill: + if not self.app.settings_manager.active_grid_settings.render_fill: self.pixmap.fill(QColor(0, 0, 0, 1)) - if self.settings_manager.active_grid_settings.render_border: + if self.app.settings_manager.active_grid_settings.render_border: print(self.active_grid_area_rect) size = 4 painter.setPen(QPen( self.active_grid_area_color, - self.settings_manager.grid_settings.line_width + self.app.settings_manager.grid_settings.line_width )) painter.setBrush(QBrush(QColor(0, 0, 0, 0))) painter.drawRect(self.active_grid_area_rect) painter.setPen(QPen( self.active_grid_area_color, - self.settings_manager.grid_settings.line_width + 1 + self.app.settings_manager.grid_settings.line_width + 1 )) painter.drawRect(QRect( self.active_grid_area_rect.x(), @@ -282,36 +281,34 @@ def image_pivot_point(self): @image_pivot_point.setter def image_pivot_point(self, value): - try: + with session_scope() as session: + session.add(self.current_layer) self.current_layer.pivot_x = value.x() self.current_layer.pivot_y = value.y() - save_session() - except Exception as e: - pass @property def active_grid_area_selected(self): - return self.settings_manager.current_tool == "active_grid_area" + return self.app.settings_manager.settings.current_tool == "active_grid_area" @property def select_selected(self): - return self.settings_manager.current_tool == "select" + return self.app.settings_manager.settings.current_tool == "select" @property def eraser_selected(self): - return self.settings_manager.current_tool == "eraser" + return self.app.settings_manager.settings.current_tool == "eraser" @property def brush_selected(self): - return self.settings_manager.current_tool == "brush" + return self.app.settings_manager.settings.current_tool == "brush" @property def move_selected(self): - return self.settings_manager.current_tool == "move" + return self.app.settings_manager.settings.current_tool == "move" @property def brush_size(self): - return self.settings_manager.brush_settings.size + return self.app.settings_manager.settings.brush_settings.size @property def active_grid_area_rect(self): @@ -323,7 +320,7 @@ def active_grid_area_rect(self): ) # apply self.pos_x and self.pox_y to the rect - rect.translate(self.canvas_settings.pos_x, self.canvas_settings.pos_y) + rect.translate(self.app.settings_manager.canvas_settings.pos_x, self.app.settings_manager.canvas_settings.pos_y) return rect @@ -353,7 +350,7 @@ def layer_container_widget(self): @property def active_grid_settings(self): - return self.settings_manager.active_grid_settings + return self.app.settings_manager.active_grid_settings @property def canvas_container(self): @@ -361,52 +358,44 @@ def canvas_container(self): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - session = get_session() - self.canvas_settings = session.query(CanvasSettings).first() - self.ui.central_widget.resizeEvent = self.resizeEvent - self.app.add_image_to_canvas_signal.connect(self.handle_add_image_to_canvas) - self.app.image_data.connect(self.handle_image_data) - self.app.load_image.connect(self.load_image_from_path) - self.app.load_image_object.connect(self.add_image_to_scene) - self.layer_data = session.query( - Layer - ).filter( - Layer.document_id == self.app.document.id, - ).order_by( - Layer.position.asc() - ).all() - self.initialize() - self.settings_manager.changed_signal.connect(self.handle_changed_signal) + self.app.settings_manager.changed_signal.connect(self.handle_changed_signal) + with session_scope() as session: + self.ui.central_widget.resizeEvent = self.resizeEvent + self.app.add_image_to_canvas_signal.connect(self.handle_add_image_to_canvas) + self.app.image_data.connect(self.handle_image_data) + self.app.load_image.connect(self.load_image_from_path) + self.app.load_image_object.connect(self.add_image_to_scene) + self.initialize() self.app.loaded.connect(self.handle_loaded) def increase_active_grid_height(self, amount): - height = self.settings_manager.working_height + self.settings_manager.grid_settings.size * amount + height = self.app.settings_manager.settings.working_height + self.app.settings_manager.grid_settings.cell_size * amount if height > 4096: height = 4096 - self.settings_manager.set_value("working_height", height) + self.app.settings_manager.settings.set_value("working_height", height) self.do_draw() def decrease_active_grid_height(self, amount): - height = self.settings_manager.working_height - self.settings_manager.grid_settings.size * amount + height = self.app.settings_manager.settings.working_height - self.app.settings_manager.grid_settings.cell_size * amount if height < 512: height = 512 - self.settings_manager.set_value("working_height", height) + self.app.settings_manager.settings.set_value("working_height", height) self.do_draw() def increase_active_grid_width(self, amount): - width = self.settings_manager.working_width + self.settings_manager.grid_settings.size * amount + width = self.app.settings_manager.settings.working_width + self.app.settings_manager.grid_settings.cell_size * amount if width > 4096: width = 4096 - self.settings_manager.set_value("working_width", width) + self.app.settings_manager.settings.set_value("working_width", width) self.do_draw() def decrease_active_grid_width(self, amount): - width = self.settings_manager.working_width - self.settings_manager.grid_settings.size * amount + width = self.app.settings_manager.settings.working_width - self.app.settings_manager.grid_settings.cell_size * amount if width < 512: width = 512 - self.settings_manager.set_value("working_width", width) + self.app.settings_manager.settings.set_value("working_width", width) self.do_draw() def wheelEvent(self, event): @@ -432,15 +421,16 @@ def wheelEvent(self, event): super().wheelEvent(event) # Propagate the event to the base class if no modifier keys are pressed def handle_changed_signal(self, key, value): - if key == "current_tab": + print("canvas_plus_widget: handle_changed_signal", key, value) + if key == "settings.current_tab": self.do_draw() - elif key == "current_section_stablediffusion": + elif key == "settings.current_section_stablediffusion": self.do_draw() elif key == "layer_image_data.visible": self.do_draw() elif key == "layer_data.hidden": self.do_draw() - elif key == "active_image_editor_section": + elif key == "settings.active_image_editor_section": self.do_draw() elif key == "grid_settings.show_grid": # remove lines from scene @@ -479,10 +469,10 @@ def initialize(self): self.view_size = self.view.viewport().size() # # initialize variables - self.cell_size = self.settings_manager.grid_settings.size - self.line_width = self.settings_manager.grid_settings.line_width - self.line_color = QColor(self.settings_manager.grid_settings.line_color) - self.canvas_color = QColor(self.settings_manager.grid_settings.canvas_color) + self.cell_size = self.app.settings_manager.grid_settings.cell_size + self.line_width = self.app.settings_manager.grid_settings.line_width + self.line_color = QColor(self.app.settings_manager.grid_settings.line_color) + self.canvas_color = QColor(self.app.settings_manager.grid_settings.canvas_color) # # Set the margins of the QGraphicsView object to 0 self.view.setContentsMargins(0, 0, 0, 0) @@ -493,7 +483,7 @@ def initialize(self): self.do_draw() def draw_layers(self): - for layer in self.layer_data: + for layer in self.layers: image = layer.image if image is None: continue @@ -528,8 +518,8 @@ def draw_layers(self): pos = QPoint(layer.pos_x, layer.pos_y) draggable_pixmap.setPos(QPointF( - self.canvas_settings.pos_x + pos.x(), - self.canvas_settings.pos_y + pos.y() + self.app.settings_manager.canvas_settings.pos_x + pos.x(), + self.app.settings_manager.canvas_settings.pos_y + pos.y() )) def set_scene_rect(self): @@ -545,19 +535,19 @@ def draw_lines(self): Qt.PenStyle.SolidLine ) - if self.settings_manager.grid_settings.show_grid: + if self.app.settings_manager.grid_settings.show_grid: # vertical lines - h = self.view_size.height() + abs(self.canvas_settings.pos_y) % self.cell_size + h = self.view_size.height() + abs(self.app.settings_manager.canvas_settings.pos_y) % self.cell_size y = 0 for i in range(width_cells): - x = i * self.cell_size + self.canvas_settings.pos_x % self.cell_size + x = i * self.cell_size + self.app.settings_manager.canvas_settings.pos_x % self.cell_size self.scene.addLine(x, y, x, h, pen) # # horizontal lines - w = self.view_size.width() + abs(self.canvas_settings.pos_x) % self.cell_size + w = self.view_size.width() + abs(self.app.settings_manager.canvas_settings.pos_x) % self.cell_size x = 0 for i in range(height_cells): - y = i * self.cell_size + self.canvas_settings.pos_y % self.cell_size + y = i * self.cell_size + self.app.settings_manager.canvas_settings.pos_y % self.cell_size self.scene.addLine(x, y, w, y, pen) def draw_active_grid_area_container(self): @@ -591,7 +581,7 @@ def do_draw(self): self.draw_layers() self.draw_active_grid_area_container() self.ui.canvas_position.setText( - f"X {-self.canvas_settings.pos_x: 05d} Y {self.canvas_settings.pos_y: 05d}" + f"X {-self.app.settings_manager.canvas_settings.pos_x: 05d} Y {self.app.settings_manager.canvas_settings.pos_y: 05d}" ) self.scene.update() self.drawing = False @@ -694,9 +684,9 @@ def load_image_from_object(self, image, is_outpaint=False, image_root_point=None def load_image(self, image_path): image = Image.open(image_path) - if self.settings_manager.resize_on_paste: - image.thumbnail((self.settings_manager.working_width, - self.settings_manager.working_height), Image.ANTIALIAS) + if self.app.settings_manager.settings.resize_on_paste: + image.thumbnail((self.app.settings_manager.settings.working_width, + self.app.settings_manager.settings.working_height), Image.ANTIALIAS) self.add_image_to_scene(image) def current_draggable_pixmap(self): @@ -765,15 +755,15 @@ def image_to_system_clipboard_linux(self, pixmap): Logger.error("xclip not found. Please install xclip to copy image to clipboard.") def create_image(self, image): - if self.settings_manager.resize_on_paste: + if self.app.settings_manager.settings.resize_on_paste: image = self.resize_image(image) self.add_image_to_scene(image) def resize_image(self, image): image.thumbnail( ( - self.settings_manager.working_width, - self.settings_manager.working_height + self.app.settings_manager.settings.working_width, + self.app.settings_manager.settings.working_height ), Image.ANTIALIAS ) @@ -791,16 +781,6 @@ def switch_to_layer(self, layer_index): self.current_layer_index = layer_index def add_image_to_scene(self, image, is_outpaint=False, image_root_point=None): - # self.current_active_image = image - # if image_root_point is not None: - # self.current_layer.pos_x = image_root_point.x() - # self.current_layer.pos_y = image_root_point.y() - # elif not is_outpaint: - # self.current_layer.pos_x = self.active_grid_area_rect.x() - # self.current_layer.pos_y = self.active_grid_area_rect.y() - # session.add(self.current_layer) - # save_session() - # self.do_draw() self.image_adder = ImageAdder(self, image, is_outpaint, image_root_point) self.image_adder.finished.connect(self.on_image_adder_finished) self.image_adder.start() diff --git a/src/airunner/widgets/canvas_plus/standard_image_widget.py b/src/airunner/widgets/canvas_plus/standard_image_widget.py index 0182f1c5a..74289e359 100644 --- a/src/airunner/widgets/canvas_plus/standard_image_widget.py +++ b/src/airunner/widgets/canvas_plus/standard_image_widget.py @@ -7,13 +7,13 @@ from PIL import Image -from airunner.utils import get_session from airunner.data.models import AIModel from airunner.widgets.canvas_plus.standard_base_widget import StandardBaseWidget from airunner.widgets.canvas_plus.templates.standard_image_widget_ui import Ui_standard_image_widget from airunner.utils import load_metadata_from_image, prepare_metadata from airunner.widgets.slider.slider_widget import SliderWidget from airunner.data.models import ActionScheduler, Pipeline +from airunner.data.session_scope import session_scope class StandardImageWidget(StandardBaseWidget): @@ -50,7 +50,6 @@ def __init__(self, *args, **kwargs): self.set_input_image_widget_properties() self.ui.ddim_eta_slider_widget.hide() self.ui.frames_slider_widget.hide() - self.initialize() def set_controlnet_settings_properties(self): self.ui.controlnet_settings.initialize() @@ -80,7 +79,7 @@ def handle_advanced_settings_checkbox(self, val): def load_upscale_options(self): self.ui.upscale_model.blockSignals(True) - model = self.settings_manager.standard_image_widget_settings.upscale_model + model = self.app.settings_manager.standard_image_settings.upscale_model index = self.ui.upscale_model.findText(model) if index == -1: index = 0 @@ -88,17 +87,17 @@ def load_upscale_options(self): self.ui.upscale_model.blockSignals(False) self.ui.face_enhance.blockSignals(True) - self.ui.face_enhance.setChecked(self.settings_manager.standard_image_widget_settings.face_enhance) + self.ui.face_enhance.setChecked(self.app.settings_manager.standard_image_settings.face_enhance) self.ui.face_enhance.blockSignals(False) def upscale_model_changed(self, model): - self.settings_manager.set_value("standard_image_widget_settings.upscale_model", model) + self.app.settings_manager.set_value("standard_image_settings.upscale_model", model) def face_enhance_toggled(self, val): - self.settings_manager.set_value("standard_image_widget_settings.face_enhance", val) + self.app.settings_manager.set_value("standard_image_settings.face_enhance", val) def handle_controlnet_changed(self, val): - self.settings_manager.set_value("standard_image_widget_settings.controlnet", val) + self.app.settings_manager.set_value("standard_image_settings.controlnet", val) def handle_image_data(self, data): images = data["images"] @@ -249,10 +248,10 @@ def generate_similar_image(self, batch_size=1): meta_data["width"] = self.image.width meta_data["height"] = self.image.height meta_data["enable_controlnet"] = True - meta_data["controlnet"] = self.settings_manager.standard_image_widget_settings.controlnet.lower() - meta_data["controlnet_conditioning_scale"] = self.settings_manager.standard_image_widget_settings.image_similarity / 100.0 - #meta_data["image_guidance_scale"] = 100 * (100 - self.settings_manager.image_similarity) / 100.0 - meta_data["strength"] = 1.1 - (self.settings_manager.standard_image_widget_settings.image_similarity / 100.0) + meta_data["controlnet"] = self.app.settings_manager.standard_image_widget_settings.controlnet.lower() + meta_data["controlnet_conditioning_scale"] = self.app.settings_manager.standard_image_widget_settings.image_similarity / 100.0 + #meta_data["image_guidance_scale"] = 100 * (100 - self.app.settings_manager.image_similarity) / 100.0 + meta_data["strength"] = 1.1 - (self.app.settings_manager.standard_image_widget_settings.image_similarity / 100.0) print(meta_data["controlnet_conditioning_scale"], meta_data["strength"]) meta_data["enable_input_image"] = True meta_data["use_cropped_image"] = False @@ -284,8 +283,8 @@ def upscale_2x_clicked(self): meta_data.pop("seed", None) meta_data.pop("latents_seed", None) - meta_data["model_data_path"] = self.settings_manager.standard_image_widget_settings.upscale_model - meta_data["face_enhance"] = self.settings_manager.standard_image_widget_settings.face_enhance + meta_data["model_data_path"] = self.app.settings_manager.standard_image_widget_settings.upscale_model + meta_data["face_enhance"] = self.app.settings_manager.standard_image_widget_settings.face_enhance meta_data["denoise_strength"] = 0.5 meta_data["action"] = "upscale" meta_data["width"] = self.ui.canvas_widget.current_layer.image.width @@ -307,7 +306,7 @@ def load_pipelines(self): self.ui.pipeline.clear() pipeline_names = ["txt2img / img2img", "inpaint / outpaint", "depth2img", "pix2pix", "upscale", "superresolution", "txt2vid"] self.ui.pipeline.addItems(pipeline_names) - current_pipeline = getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}") + current_pipeline = self.app.settings_manager.settings.current_section_stablediffusion if current_pipeline != "": if current_pipeline == "txt2img": current_pipeline = "txt2img / img2img" @@ -317,76 +316,76 @@ def load_pipelines(self): self.ui.pipeline.blockSignals(False) def load_versions(self): - session = get_session() - self.ui.version.blockSignals(True) - self.ui.version.clear() - pipelines = session.query(Pipeline).filter(Pipeline.category == self.settings_manager.current_image_generator).all() - version_names = set([pipeline.version for pipeline in pipelines]) - self.ui.version.addItems(version_names) - current_version = getattr(self.settings_manager, f"current_version_{self.settings_manager.current_image_generator}") - if current_version != "": - self.ui.version.setCurrentText(current_version) - self.ui.version.blockSignals(False) + with session_scope() as session: + self.ui.version.blockSignals(True) + self.ui.version.clear() + pipelines = session.query(Pipeline).filter(Pipeline.category == "stablediffusion").all() + version_names = set([pipeline.version for pipeline in pipelines]) + self.ui.version.addItems(version_names) + current_version = self.app.settings_manager.settings.current_version_stablediffusion + if current_version != "": + self.ui.version.setCurrentText(current_version) + self.ui.version.blockSignals(False) def load_models(self): - session = get_session() - self.ui.model.blockSignals(True) - self.clear_models() - - image_generator = self.settings_manager.current_image_generator - pipeline = getattr(self.settings_manager, f"current_section_{image_generator}") - version = getattr(self.settings_manager, f"current_version_{image_generator}") - - models = session.query(AIModel).filter( - AIModel.category == image_generator, - AIModel.pipeline_action == pipeline, - AIModel.version == version, - AIModel.enabled == True - ).all() - model_names = [model.name for model in models] - self.ui.model.addItems(model_names) - current_model = self.settings_manager.generator.model - if current_model != "": - self.ui.model.setCurrentText(current_model) - self.settings_manager.set_value("generator.model", self.ui.model.currentText()) - self.ui.model.blockSignals(False) + with session_scope() as session: + self.ui.model.blockSignals(True) + self.clear_models() + + image_generator = "stablediffusion" + pipeline = self.app.settings_manager.settings.current_section_stablediffusion + version = self.app.settings_manager.settings.current_version_stablediffusion + + models = session.query(AIModel).filter( + AIModel.category == image_generator, + AIModel.pipeline_action == pipeline, + AIModel.version == version, + AIModel.enabled == True + ).all() + model_names = [model.name for model in models] + self.ui.model.addItems(model_names) + current_model = self.app.settings_manager.generator.model + if current_model != "": + self.ui.model.setCurrentText(current_model) + self.app.settings_manager.generator.model = self.ui.model.currentText() + self.ui.model.blockSignals(False) def load_schedulers(self): - self.ui.scheduler.blockSignals(True) - session = get_session() - schedulers = session.query(ActionScheduler).filter( - ActionScheduler.section == getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}"), - ActionScheduler.generator_name == self.settings_manager.current_image_generator - ).all() - scheduler_names = [s.scheduler.display_name for s in schedulers] - self.ui.scheduler.clear() - self.ui.scheduler.addItems(scheduler_names) - - current_scheduler = self.settings_manager.generator.scheduler - if current_scheduler != "": - self.ui.scheduler.setCurrentText(current_scheduler) - else: - self.settings_manager.set_value("generator.scheduler", self.ui.scheduler.currentText()) - self.ui.scheduler.blockSignals(False) + with session_scope() as session: + self.ui.scheduler.blockSignals(True) + schedulers = session.query(ActionScheduler).filter( + ActionScheduler.section == self.app.settings_manager.settings.current_section_stablediffusion, + ActionScheduler.generator_name == "stablediffusion" + ).all() + scheduler_names = [s.scheduler.display_name for s in schedulers] + self.ui.scheduler.clear() + self.ui.scheduler.addItems(scheduler_names) + + current_scheduler = self.app.settings_manager.generator.scheduler + if current_scheduler != "": + self.ui.scheduler.setCurrentText(current_scheduler) + else: + self.app.settings_manager.set_value("generator.scheduler", self.ui.scheduler.currentText()) + self.ui.scheduler.blockSignals(False) def clear_models(self): self.ui.model.clear() def initialize_generator_form(self, override_id=None): if override_id: - self.ui.steps_widget.set_slider_and_spinbox_values(self.settings_manager.generator.steps) - self.ui.scale_widget.set_slider_and_spinbox_values(self.settings_manager.generator.scale * 100) - self.ui.clip_skip_slider_widget.set_slider_and_spinbox_values(self.settings_manager.generator.clip_skip) + self.ui.steps_widget.set_slider_and_spinbox_values(self.app.settings_manager.generator.steps) + self.ui.scale_widget.set_slider_and_spinbox_values(self.app.settings_manager.generator.scale * 100) + self.ui.clip_skip_slider_widget.set_slider_and_spinbox_values(self.app.settings_manager.generator.clip_skip) self.ui.pipeline.blockSignals(True) self.ui.version.blockSignals(True) self.ui.model.blockSignals(True) self.ui.scheduler.blockSignals(True) - self.ui.pipeline.setCurrentText(self.settings_manager.generator.section) - self.ui.version.setCurrentText(self.settings_manager.generator.version) - self.ui.model.setCurrentText(self.settings_manager.generator.model) - self.ui.scheduler.setCurrentText(self.settings_manager.generator.scheduler) + self.ui.pipeline.setCurrentText(self.app.settings_manager.generator.section) + self.ui.version.setCurrentText(self.app.settings_manager.generator.version) + self.ui.model.setCurrentText(self.app.settings_manager.generator.model) + self.ui.scheduler.setCurrentText(self.app.settings_manager.generator.scheduler) self.ui.pipeline.blockSignals(False) self.ui.version.blockSignals(False) @@ -399,11 +398,13 @@ def initialize_generator_form(self, override_id=None): self.load_models() self.load_schedulers() - def handle_settings_manager_changed(self, key, val, settings_manager): - if key == "generator_settings_override_id": + def handle_changed_signal(self, key, val): + print("standard_image_widget handle_settings_manager_changed handle_settings_manager_changed handle_settings_manager_changed handle_settings_manager_changed handle_settings_manager_changed") + if key == "settings.generator_settings_override_id": self.initialize_generator_form(val) - elif key == "ai_mode": - self.ui.settings_tab_widget.setCurrentIndex(1 if self.settings_manager.ai_mode else 0) + elif key == "settings.ai_mode": + print("HANDLE SETTINGS MANAGER CHANGED") + self.ui.settings_tab_widget.setCurrentIndex(1 if self.app.settings_manager.settings.ai_mode else 0) def initialize(self): self.set_form_values() @@ -411,9 +412,7 @@ def initialize(self): self.load_versions() self.load_models() self.load_schedulers() - - # listen to emitted signal from self.settings_manager.changed_signal - self.settings_manager.changed_signal.connect(self.handle_settings_manager_changed) + self.app.settings_manager.changed_signal.connect(self.handle_changed_signal) # find all SliderWidget widgets in the template and call initialize for widget in self.findChildren(SliderWidget): @@ -428,15 +427,15 @@ def initialize(self): widget.setProperty("current_value", current_value) widget.initialize() - self.ui.seed_widget.setProperty("generator_section", getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}")) - self.ui.seed_widget.setProperty("generator_name", self.settings_manager.current_image_generator) + self.ui.seed_widget.setProperty("generator_section", self.app.settings_manager.settings.current_section_stablediffusion) + self.ui.seed_widget.setProperty("generator_name", "stablediffusion") # self.ui.seed_widget.initialize( # self.generator_section, # self.generator_name # ) - self.ui.seed_widget_latents.setProperty("generator_section", getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}")) - self.ui.seed_widget_latents.setProperty("generator_name", self.settings_manager.current_image_generator) + self.ui.seed_widget_latents.setProperty("generator_section", self.app.settings_manager.settings.current_section_stablediffusion) + self.ui.seed_widget_latents.setProperty("generator_name", "stablediffusion") # self.ui.seed_widget_latents.initialize( # self.generator_section, # self.generator_name @@ -446,23 +445,23 @@ def initialize(self): def handle_model_changed(self, name): if not self.initialized: return - self.settings_manager.set_value("generator.model", name) + self.app.settings_manager.set_value("generator.model", name) def handle_scheduler_changed(self, name): if not self.initialized: return - self.settings_manager.set_value("generator.scheduler", name) + self.app.settings_manager.set_value("generator.scheduler", name) def handle_pipeline_changed(self, val): if val == "txt2img / img2img": val = "txt2img" elif val == "inpaint / outpaint": val = "outpaint" - self.settings_manager.set_value(f"current_section_{self.settings_manager.current_image_generator}", val) + self.app.settings_manager.set_value("settings.current_section_stablediffusion", val) self.load_versions() self.load_models() def handle_version_changed(self, val): print("VERSION CHANGED", val) - self.settings_manager.set_value(f"current_version_{self.settings_manager.current_image_generator}", val) + self.app.settings_manager.set_value(f"settings.current_version_stablediffusion", val) self.load_models() \ No newline at end of file diff --git a/src/airunner/widgets/canvas_plus/templates/standard_image_widget.ui b/src/airunner/widgets/canvas_plus/templates/standard_image_widget.ui index 521be74d9..d1f9a30d2 100644 --- a/src/airunner/widgets/canvas_plus/templates/standard_image_widget.ui +++ b/src/airunner/widgets/canvas_plus/templates/standard_image_widget.ui @@ -80,7 +80,7 @@ Qt::LeftToRight - 5 + 3 @@ -166,7 +166,7 @@ 0 - standard_image_widget_settings.image_similarity + standard_image_settings.image_similarity diff --git a/src/airunner/widgets/canvas_plus/templates/standard_image_widget_ui.py b/src/airunner/widgets/canvas_plus/templates/standard_image_widget_ui.py index 2bfee2847..19e621c83 100644 --- a/src/airunner/widgets/canvas_plus/templates/standard_image_widget_ui.py +++ b/src/airunner/widgets/canvas_plus/templates/standard_image_widget_ui.py @@ -358,7 +358,7 @@ def setupUi(self, standard_image_widget): self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1) self.retranslateUi(standard_image_widget) - self.tabWidget.setCurrentIndex(5) + self.tabWidget.setCurrentIndex(3) self.settings_tab_widget.setCurrentIndex(0) self.upscale_model.currentTextChanged['QString'].connect(standard_image_widget.upscale_model_changed) # type: ignore self.face_enhance.clicked['bool'].connect(standard_image_widget.face_enhance_toggled) # type: ignore @@ -381,7 +381,7 @@ def retranslateUi(self, standard_image_widget): self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("standard_image_widget", "LoRA")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("standard_image_widget", "Embeddings")) self.samples_widget.setProperty("label_text", _translate("standard_image_widget", "Similarity")) - self.samples_widget.setProperty("settings_property", _translate("standard_image_widget", "standard_image_widget_settings.image_similarity")) + self.samples_widget.setProperty("settings_property", _translate("standard_image_widget", "standard_image_settings.image_similarity")) self.generate_single_simillar_button.setToolTip(_translate("standard_image_widget", "Generate one variation")) self.generate_single_simillar_button.setText(_translate("standard_image_widget", "Single")) self.generate_batch_similar_button.setToolTip(_translate("standard_image_widget", "Generate a batch of four variations")) diff --git a/src/airunner/widgets/controlnet_settings/controlnet_settings_widget.py b/src/airunner/widgets/controlnet_settings/controlnet_settings_widget.py index cab521dfd..1c542af3c 100644 --- a/src/airunner/widgets/controlnet_settings/controlnet_settings_widget.py +++ b/src/airunner/widgets/controlnet_settings/controlnet_settings_widget.py @@ -20,16 +20,16 @@ class ControlNetSettingsWidget(InputImageSettingsWidget): @property def current_controlnet_image(self): - if self.settings_manager.generator.controlnet_mask_link_input_image: + if self.app.settings_manager.generator_settings.controlnet_mask_link_input_image: return self.controlnet_image - elif self.settings_manager.generator.controlnet_mask_use_imported_image: + elif self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image: return self.imported_controlnet_image @current_controlnet_image.setter def current_controlnet_image(self, value): - if self.settings_manager.generator.controlnet_mask_link_input_image: + if self.app.settings_manager.generator_settings.controlnet_mask_link_input_image: self.controlnet_image = value - elif self.settings_manager.generator.controlnet_mask_use_imported_image: + elif self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image: self.imported_controlnet_image = value self.toggle_mask_export_button(value is not None) self.set_mask_thumbnail() @@ -45,46 +45,45 @@ def active_grid_area_image(self): @property def current_image(self): - if not self.settings_manager.generator.enable_controlnet: + if not self.app.settings_manager.generator_settings.enable_controlnet: return None - if self.settings_manager.generator.controlnet_input_image_link_to_input_image: + if self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image: return self.app.generator_tab_widget.current_input_image - elif self.settings_manager.generator.controlnet_input_image_use_imported_image: + elif self.app.settings_manager.generator_settings.controlnet_input_image_use_imported_image: return self.input_image - elif self.settings_manager.generator.controlnet_use_grid_image: + elif self.app.settings_manager.generator_settings.controlnet_use_grid_image: return self.active_grid_area_image else: return None @property def cached_image(self): - if self.settings_manager.generator.controlnet_input_image_link_to_input_image: + if self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image: return self._current_input_image - elif self.settings_manager.generator.controlnet_input_image_use_imported_image: + elif self.app.settings_manager.generator_settings.controlnet_input_image_use_imported_image: return self._current_imported_image - elif self.settings_manager.generator.controlnet_use_grid_image: + elif self.app.settings_manager.generator_settings.controlnet_use_grid_image: return self._current_active_grid_area_image else: return None @cached_image.setter def cached_image(self, value): - if self.settings_manager.generator.controlnet_input_image_link_to_input_image: + if self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image: self._current_input_image = value - elif self.settings_manager.generator.controlnet_input_image_use_imported_image: + elif self.app.settings_manager.generator_settings.controlnet_input_image_use_imported_image: self._current_imported_image = value - elif self.settings_manager.generator.controlnet_use_grid_image: + elif self.app.settings_manager.generator_settings.controlnet_use_grid_image: self._current_active_grid_area_image = value def initialize_groupbox(self): - if self.settings_manager.generator: - self.ui.groupBox.setChecked(self.settings_manager.generator.enable_controlnet) + self.ui.groupBox.setChecked(self.app.settings_manager.generator_settings.enable_controlnet is True) def handle_toggle_controlnet(self, value): - if self.settings_manager.current_tab != "stablediffusion": + if self.app.settings_manager.current_tab != "stablediffusion": value = False - self.settings_manager.set_value("generator.enable_controlnet", value) + self.app.settings_manager.set_value("generator.enable_controlnet", value) self.set_thumbnail() # self.set_stylesheet() @@ -120,12 +119,12 @@ def send_active_mask_to_canvas(self): return self.app.canvas.update_image_canvas( - self.settings_manager.current_tab, + self.app.settings_manager.current_tab, { - "action": self.settings_manager.current_tab, + "action": self.app.settings_manager.current_tab, "options": { "outpaint_box_rect": self.app.canvas.active_grid_area_rect, - "generator_section": self.settings_manager.current_generator_section + "generator_section": self.app.settings_manager.current_generator_section } }, self.current_controlnet_image @@ -133,14 +132,14 @@ def send_active_mask_to_canvas(self): self.app.canvas.update() def toggle_mask_link(self, value): - self.settings_manager.generator.controlnet_mask_use_imported_image = not value - self.settings_manager.generator.controlnet_mask_link_input_image = value + self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image = not value + self.app.settings_manager.generator_settings.controlnet_mask_link_input_image = value self.set_mask_thumbnail() self.toggle_buttons() def toggle_mask_use_imported_image(self, value): - self.settings_manager.generator.controlnet_mask_use_imported_image = value - self.settings_manager.generator.controlnet_mask_link_input_image = not value + self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image = value + self.app.settings_manager.generator_settings.controlnet_mask_link_input_image = not value self.set_mask_thumbnail() self.toggle_buttons() @@ -149,10 +148,10 @@ def handle_link_settings_clicked(self, value): Use the same setting as input image :return: """ - self.settings_manager.generator.controlnet_input_image_link_to_input_image = value + self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image = value if value: - self.settings_manager.generator.controlnet_input_image_use_imported_image = False - self.settings_manager.generator.controlnet_use_grid_image = False + self.app.settings_manager.generator_settings.controlnet_input_image_use_imported_image = False + self.app.settings_manager.generator_settings.controlnet_use_grid_image = False self.toggle_buttons() self.set_thumbnail() @@ -161,9 +160,9 @@ def export_generated_controlnet_image(self): image=self.current_controlnet_image, type="controlnet", data={ - "controlnet": self.settings_manager.generator.controlnet + "controlnet": self.app.settings_manager.generator_settings.controlnet }, - seed=self.settings_manager.generator.seed + seed=self.app.settings_manager.generator_settings.seed ) if path is not None: self.app.set_status_label(f"Mask exported to {path}") @@ -178,7 +177,7 @@ def toggle_buttons(self): self.toggle_link_input_image_button() self.toggle_use_grid_image() self.toggle_mask_buttons() - use_grid = self.settings_manager.generator.controlnet_use_grid_image + use_grid = self.app.settings_manager.generator_settings.controlnet_use_grid_image if use_grid: self.ui.refresh_input_image_button.show() self.ui.clear_image_button.hide() @@ -191,25 +190,25 @@ def toggle_buttons(self): self.ui.recycle_grid_image_button.setEnabled(False) def toggle_mask_buttons(self): - self.ui.mask_import_button.setEnabled(self.settings_manager.generator.controlnet_mask_use_imported_image) - self.ui.mask_link_to_input_image_button.setChecked(self.settings_manager.generator.controlnet_mask_link_input_image) - self.ui.mask_use_imported_image_button.setChecked(self.settings_manager.generator.controlnet_mask_use_imported_image) + self.ui.mask_import_button.setEnabled(self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image) + self.ui.mask_link_to_input_image_button.setChecked(self.app.settings_manager.generator_settings.controlnet_mask_link_input_image) + self.ui.mask_use_imported_image_button.setChecked(self.app.settings_manager.generator_settings.controlnet_mask_use_imported_image) def toggle_link_input_image_button(self): - use_input_image = self.settings_manager.generator.controlnet_input_image_link_to_input_image - self.settings_manager.generator.controlnet_input_image_link_to_input_image = use_input_image + use_input_image = self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image + self.app.settings_manager.generator_settings.controlnet_input_image_link_to_input_image = use_input_image self.ui.link_settings_button.setChecked(use_input_image) def toggle_import_image_button(self): - use_import_image = self.settings_manager.generator.controlnet_input_image_use_imported_image + use_import_image = self.app.settings_manager.generator_settings.controlnet_input_image_use_imported_image self.ui.import_image_button.setEnabled(use_import_image) self.ui.use_imported_image_button.setChecked(use_import_image) def toggle_use_grid_image(self): - use_grid_image = self.settings_manager.generator.controlnet_use_grid_image + use_grid_image = self.app.settings_manager.generator_settings.controlnet_use_grid_image self.ui.recycle_grid_image_button.setEnabled(use_grid_image) self.ui.use_grid_image_button.setChecked(use_grid_image) - self.ui.recycle_grid_image_button.setChecked(use_grid_image and self.settings_manager.generator.controlnet_recycle_grid_image) + self.ui.recycle_grid_image_button.setChecked(use_grid_image and self.app.settings_manager.generator_settings.controlnet_recycle_grid_image) def clear_controlnet_input_image(self): self.current_controlnet_image = None @@ -220,7 +219,7 @@ def import_controlnet_image(self): it into the application for use with controlnet during image generation. :return: """ - controlnet_image_mask_path = os.path.join(self.settings_manager.path_settings.image_path, "controlnet_masks") + controlnet_image_mask_path = os.path.join(self.app.settings_manager.path_settings.image_path, "controlnet_masks") file_path, _ = open_file_path( label="Import Mask", directory=controlnet_image_mask_path @@ -231,7 +230,7 @@ def import_controlnet_image(self): self.set_mask_thumbnail() def handle_image_generated(self): - if self.settings_manager.generator.controlnet_use_grid_image: + if self.app.settings_manager.generator_settings.controlnet_use_grid_image: self.set_thumbnail() def set_mask_thumbnail(self): @@ -253,20 +252,20 @@ def initialize_combobox(self): self.ui.controlnet_dropdown.addItems(controlnet_options) current_index = 0 for index, controlnet_name in enumerate(controlnet_options): - if controlnet_name.lower() == self.settings_manager.generator.controlnet: + if controlnet_name.lower() == self.app.settings_manager.generator_settings.controlnet: current_index = index break self.ui.controlnet_dropdown.setCurrentIndex(current_index) self.ui.controlnet_dropdown.blockSignals(False) def handle_controlnet_scale_slider_change(self, value): - self.settings_manager.set_value( + self.app.settings_manager.set_value( "generator.controlnet_guidance_scale", value ) def handle_controlnet_change(self, attr_name, value=None, widget=None): - self.settings_manager.set_value(attr_name, value) + self.app.settings_manager.set_value(attr_name, value) def action_controlnet_model_text_changed(self, model_value): - self.settings_manager.set_value("generator.controlnet_model", model_value) \ No newline at end of file + self.app.settings_manager.set_value("generator.controlnet_model", model_value) \ No newline at end of file diff --git a/src/airunner/widgets/embeddings/embedding_widget.py b/src/airunner/widgets/embeddings/embedding_widget.py index 194777915..0d66756e9 100644 --- a/src/airunner/widgets/embeddings/embedding_widget.py +++ b/src/airunner/widgets/embeddings/embedding_widget.py @@ -1,35 +1,47 @@ -from airunner.utils import save_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.embeddings.templates.embedding_ui import Ui_embedding from PyQt6.QtWidgets import QApplication - +from contextlib import contextmanager +from sqlalchemy.exc import InvalidRequestError class EmbeddingWidget(BaseWidget): widget_class_ = Ui_embedding - embedding = None + + @contextmanager + def embedding(self): + with session_scope() as session: + try: + session.add(self._embedding) + except InvalidRequestError: + pass + yield self._embedding def __init__(self, *args, **kwargs): - self.embedding = kwargs.pop("embedding") + self._embedding = kwargs.pop("embedding") super().__init__(*args, **kwargs) - self.ui.enabledCheckbox.setChecked(self.embedding.active) - self.ui.enabledCheckbox.setTitle(self.embedding.name) - if self.embedding.tags: - self.ui.tags.show() - self.ui.tags.setText(self.embedding.tags) - else: - self.ui.tags.hide() + with self.embedding() as embedding: + self.ui.enabledCheckbox.setChecked(embedding.active) + self.ui.enabledCheckbox.setTitle(embedding.name) + if embedding.tags: + self.ui.tags.show() + self.ui.tags.setText(embedding.tags) + else: + self.ui.tags.hide() def action_clicked_button_to_prompt(self): - val = f"{self.settings_manager.generator.prompt} {self.embedding.name}" - self.settings_manager.set_value("generator.prompt", val) + with self.embedding() as embedding: + val = f"{self.app.settings_manager.generator.prompt} {embedding.name}" + self.app.settings_manager.set_value("generator.prompt", val) def action_clicked_button_to_negative_prompt(self): - val = f"{self.settings_manager.generator.negative_prompt} {self.embedding.name}" - self.settings_manager.set_value("generator.negative_prompt", val) + with self.embedding() as embedding: + val = f"{self.app.settings_manager.generator.negative_prompt} {embedding.name}" + self.app.settings_manager.set_value("generator.negative_prompt", val) def action_toggled_embedding(self, val): - self.embedding.active = val - save_session() + with self.embedding() as embedding: + embedding.active = val def action_clicked_copy(self): # copy embedding name to clipboard diff --git a/src/airunner/widgets/embeddings/embeddings_container_widget.py b/src/airunner/widgets/embeddings/embeddings_container_widget.py index 3d9b5f8fc..7ba99c6e6 100644 --- a/src/airunner/widgets/embeddings/embeddings_container_widget.py +++ b/src/airunner/widgets/embeddings/embeddings_container_widget.py @@ -4,8 +4,9 @@ from PyQt6.QtWidgets import QWidget, QSizePolicy from airunner.aihandler.enums import MessageCode +from airunner.data.managers import SettingsManager from airunner.data.models import Embedding -from airunner.utils import get_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.embeddings.embedding_widget import EmbeddingWidget from airunner.widgets.embeddings.templates.embeddings_container_ui import Ui_embeddings_container @@ -23,7 +24,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.app.generator_tab_changed_signal.connect(self.handle_generator_tab_changed) self.app.tab_section_changed_signal.connect(self.handle_tab_section_changed) - self.settings_manager.changed_signal.connect(self.handle_changed_signal) self.app.message_var.my_signal.connect(self.message_handler) self.scan_for_embeddings() @@ -73,7 +73,8 @@ def handle_tab_section_changed(self): self.enable_embeddings() def handle_changed_signal(self, key): - if key == "embeddings_path": + print("embeddings_container_widget: handle_changed_signal", key, value) + if key == "path_settings.embeddings_path": self.update_embedding_names() elif key == "generator.model": self.enable_embeddings() @@ -88,9 +89,10 @@ def message_handler(self, response: dict): def load_embeddings(self): self.clear_embedding_widgets() - session = get_session() - embeddings = session.query(Embedding).filter( - Embedding.name.like(f"%{self.search_filter}%") if self.search_filter != "" else True).all() + with session_scope() as session: + embeddings = session.query(Embedding).filter( + Embedding.name.like(f"%{self.search_filter}%") if self.search_filter != "" else True).all() + for embedding in embeddings: self.add_embedding(embedding) @@ -100,19 +102,21 @@ def load_embeddings(self): self.ui.scrollAreaWidgetContents.layout().addWidget(self.spacer) def add_embedding(self, embedding): - embedding_widget = EmbeddingWidget(embedding=embedding) - self.register_embedding_widget(embedding.name, embedding_widget) + with session_scope() as session: + embedding_widget = EmbeddingWidget(embedding=embedding) + session.add(embedding) + self.register_embedding_widget(embedding.name, embedding_widget) self.ui.scrollAreaWidgetContents.layout().addWidget(embedding_widget) def action_clicked_button_scan_for_embeddings(self): self.scan_for_embeddings() def check_saved_embeddings(self): - session = get_session() - embeddings = session.query(Embedding).all() - for embedding in embeddings: - if not os.path.exists(embedding.path): - session.delete(embedding) + with session_scope() as session: + embeddings = session.query(Embedding).all() + for embedding in embeddings: + if not os.path.exists(embedding.path): + session.delete(embedding) def scan_for_embeddings(self): # recursively scan for embedding model files in the embeddings path @@ -121,22 +125,21 @@ def scan_for_embeddings(self): # add the Embedding model to the UI self.check_saved_embeddings() - session = get_session() - embeddings_path = self.settings_manager.path_settings.embeddings_path - - if os.path.exists(embeddings_path): - for root, dirs, _ in os.walk(embeddings_path): - for dir in dirs: - version = dir.split("/")[-1] - path = os.path.join(root, dir) - for entry in os.scandir(path): - if entry.is_file() and entry.name.endswith((".ckpt", ".safetensors", ".pt")): - name = os.path.splitext(entry.name)[0] - embedding = session.query(Embedding).filter_by(name=name).first() - if not embedding: - embedding = Embedding(name=name, path=entry.path, version=version) - session.add(embedding) - session.commit() + with session_scope() as session: + embeddings_path = self.app.settings_manager.path_settings.embeddings_path + + if os.path.exists(embeddings_path): + for root, dirs, _ in os.walk(embeddings_path): + for dir in dirs: + version = dir.split("/")[-1] + path = os.path.join(root, dir) + for entry in os.scandir(path): + if entry.is_file() and entry.name.endswith((".ckpt", ".safetensors", ".pt")): + name = os.path.splitext(entry.name)[0] + embedding = session.query(Embedding).filter_by(name=name).first() + if not embedding: + embedding = Embedding(name=name, path=entry.path, version=version) + session.add(embedding) self.load_embeddings() def toggle_all_toggled(self, checked): diff --git a/src/airunner/widgets/export_preferences/export_preferences_widget.py b/src/airunner/widgets/export_preferences/export_preferences_widget.py index 8de5c8001..5fa5793e5 100644 --- a/src/airunner/widgets/export_preferences/export_preferences_widget.py +++ b/src/airunner/widgets/export_preferences/export_preferences_widget.py @@ -26,21 +26,21 @@ def __init__(self, **kwargs): self.ui.image_type_dropdown.blockSignals(True) self.ui.image_path.blockSignals(True) # initialize values: - self.ui.metadata_prompt.setChecked(self.settings_manager.metadata_settings.image_export_metadata_prompt is True) - self.ui.metadata_negative_prompt.setChecked(self.settings_manager.metadata_settings.image_export_metadata_negative_prompt is True) - self.ui.metadata_scale.setChecked(self.settings_manager.metadata_settings.image_export_metadata_scale is True) - self.ui.metadata_seed.setChecked(self.settings_manager.metadata_settings.image_export_metadata_seed is True) - self.ui.metadata_steps.setChecked(self.settings_manager.metadata_settings.image_export_metadata_steps is True) - self.ui.metadata_ddim_eta.setChecked(self.settings_manager.metadata_settings.image_export_metadata_ddim_eta is True) - self.ui.metadata_iterations.setChecked(self.settings_manager.metadata_settings.image_export_metadata_iterations is True) - self.ui.metadata_samples.setChecked(self.settings_manager.metadata_settings.image_export_metadata_samples is True) - self.ui.metadata_model.setChecked(self.settings_manager.metadata_settings.image_export_metadata_model is True) - self.ui.metadata_model_branch.setChecked(self.settings_manager.metadata_settings.image_export_metadata_model_branch is True) - self.ui.metadata_scheduler.setChecked(self.settings_manager.metadata_settings.image_export_metadata_scheduler is True) - self.ui.export_metadata.setChecked(self.settings_manager.metadata_settings.export_metadata is True) - self.ui.actionAuto_export_images.setChecked(self.settings_manager.auto_export_images is True) - self.ui.image_type_dropdown.setCurrentText(self.settings_manager.image_export_type) - self.ui.image_path.setText(self.settings_manager.image_path) + self.ui.metadata_prompt.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_prompt is True) + self.ui.metadata_negative_prompt.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_negative_prompt is True) + self.ui.metadata_scale.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_scale is True) + self.ui.metadata_seed.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_seed is True) + self.ui.metadata_steps.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_steps is True) + self.ui.metadata_ddim_eta.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_ddim_eta is True) + self.ui.metadata_iterations.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_iterations is True) + self.ui.metadata_samples.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_samples is True) + self.ui.metadata_model.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_model is True) + self.ui.metadata_model_branch.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_model_branch is True) + self.ui.metadata_scheduler.setChecked(self.app.settings_manager.metadata_settings.image_export_metadata_scheduler is True) + self.ui.export_metadata.setChecked(self.app.settings_manager.metadata_settings.export_metadata is True) + self.ui.actionAuto_export_images.setChecked(self.app.settings_manager.auto_export_images is True) + self.ui.image_type_dropdown.setCurrentText(self.app.settings_manager.image_export_type) + self.ui.image_path.setText(self.app.settings_manager.image_path) image_types = [ "png", "jpg", @@ -49,7 +49,7 @@ def __init__(self, **kwargs): "tiff", ] self.ui.image_type_dropdown.addItems(image_types) - self.ui.image_type_dropdown.setCurrentText(self.settings_manager.image_export_type) + self.ui.image_type_dropdown.setCurrentText(self.app.settings_manager.image_export_type) self.ui.metadata_prompt.blockSignals(False) self.ui.metadata_negative_prompt.blockSignals(False) @@ -68,56 +68,56 @@ def __init__(self, **kwargs): self.ui.image_path.blockSignals(False) def action_toggled_steps(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_steps", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_steps", val) def action_toggled_seed(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_seed", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_seed", val) def action_toggled_latents_seed(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_latents_seed", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_latents_seed", val) def action_toggled_scheduler(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_scheduler", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_scheduler", val) def action_toggled_scale(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_scale", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_scale", val) def action_toggled_samples(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_samples", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_samples", val) def action_toggled_prompt(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_prompt", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_prompt", val) def action_toggled_negative_prompt(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_negative_prompt", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_negative_prompt", val) def action_toggled_model_branch(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_model_branch", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_model_branch", val) def action_toggled_model(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_model", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_model", val) def action_toggled_iterations(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_iterations", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_iterations", val) def action_toggled_ddim(self, val): - self.settings_manager.set_value(f"metadata_settings.image_export_metadata_ddim_eta", val) + self.app.settings_manager.set_value(f"metadata_settings.image_export_metadata_ddim_eta", val) def action_toggled_export_metadata(self, val): - self.settings_manager.set_value(f"metadata_settings.export_metadata", val) + self.app.settings_manager.set_value(f"metadata_settings.export_metadata", val) def action_toggle_automatically_export_images(self, val): - self.settings_manager.set_value(f"auto_export_images", val) + self.app.settings_manager.set_value(f"auto_export_images", val) def action_image_type_text_changed(self, val): - self.settings_manager.set_value(f"image_export_type", val) + self.app.settings_manager.set_value(f"image_export_type", val) def image_export_path_text_edited(self, val): - self.settings_manager.set_value(f"image_path", val) + self.app.settings_manager.set_value(f"image_path", val) def action_clicked_button_browse(self): path = QFileDialog.getExistingDirectory(None, "Select Directory") if path: self.ui.image_path.setText(path) - self.settings_manager.set_value("image_path", path) + self.app.settings_manager.set_value("path_settings.image_path", path) diff --git a/src/airunner/widgets/generator_form/generator_form_widget.py b/src/airunner/widgets/generator_form/generator_form_widget.py index 3a85adb89..ed89e717f 100644 --- a/src/airunner/widgets/generator_form/generator_form_widget.py +++ b/src/airunner/widgets/generator_form/generator_form_widget.py @@ -7,7 +7,7 @@ from airunner.data.models import ActiveGridSettings, CanvasSettings from airunner.widgets.base_widget import BaseWidget from airunner.widgets.generator_form.templates.generatorform_ui import Ui_generator_form -from airunner.utils import get_session +from airunner.data.session_scope import session_scope class GeneratorForm(BaseWidget): @@ -54,48 +54,48 @@ def is_txt2vid(self): @property def generator_section(self): - return getattr(self.settings_manager, f"current_section_{self.settings_manager.current_image_generator}") + return getattr(self.app.settings_manager, f"current_section_{self.app.settings_manager.current_image_generator}") @property def generator_name(self): - return self.settings_manager.current_image_generator + return self.app.settings_manager.current_image_generator @property def generator_settings(self): - return self.settings_manager.find_generator( + return self.app.settings_manager.find_generator( self.generator_section, self.generator_name ) @property def random_seed(self): - return self.settings_manager.generator.random_seed + return self.app.settings_manager.generator.random_seed @property def random_latents_seed(self): - return self.settings_manager.generator.random_latents_seed + return self.app.settings_manager.generator.random_latents_seed @property def latents_seed(self): - return self.settings_manager.generator.latents_seed + return self.app.settings_manager.generator.latents_seed @latents_seed.setter def latents_seed(self, val): - self.settings_manager.set_value("generator.latents_seed", val) + self.app.settings_manager.set_value("generator.latents_seed", val) self.app.standard_image_panel.ui.seed_widget_latents.ui.lineEdit.setText(str(val)) @property def seed(self): - return self.settings_manager.generator.seed + return self.app.settings_manager.generator.seed @seed.setter def seed(self, val): - self.settings_manager.set_value("generator.seed", val) + self.app.settings_manager.set_value("generator.seed", val) self.app.standard_image_panel.ui.seed_widget.ui.lineEdit.setText(str(val)) @property def image_scale(self): - return self.settings_manager.generator.image_guidance_scale + return self.app.settings_manager.generator.image_guidance_scale @property def active_rect(self): @@ -111,26 +111,25 @@ def active_rect(self): @property def enable_controlnet(self): - return self.settings_manager.generator.enable_controlnet + return self.app.settings_manager.generator.enable_controlnet @property def controlnet_image(self): return self.app.standard_image_panel.ui.controlnet_settings.current_controlnet_image def __init__(self, *args, **kwargs): - session = get_session() super().__init__(*args, **kwargs) self.ui.generator_form_tabs.tabBar().hide() - self.active_grid_settings = session.query(ActiveGridSettings).first() - self.canvas_settings = session.query(CanvasSettings).first() - self.settings_manager.changed_signal.connect(self.handle_changed_signal) + with session_scope() as session: + self.active_grid_settings = session.query(ActiveGridSettings).first() + self.canvas_settings = session.query(CanvasSettings).first() self.activate_ai_mode() def activate_ai_mode(self): - self.ui.generator_form_tabs.setCurrentIndex(1 if self.settings_manager.ai_mode is True else 0) + self.ui.generator_form_tabs.setCurrentIndex(1 if self.app.settings_manager.settings.ai_mode is True else 0) def toggle_advanced_generation(self): - advanced_mode = self.settings_manager.enable_advanced_mode + advanced_mode = self.app.settings_manager.settings.enable_advanced_mode # set the splitter sizes splitter_sizes = [1, 1, 0 if not advanced_mode else 1] @@ -138,6 +137,7 @@ def toggle_advanced_generation(self): self.ui.advanced_splitter.setSizes(splitter_sizes) def handle_changed_signal(self, key, value): + print("generator_form: handle_changed_signal", key, value) if key == "generator.random_seed": self.set_primary_seed() self.ui.seed_widget.seed = self.seed @@ -146,9 +146,9 @@ def handle_changed_signal(self, key, value): self.set_latents_seed() self.ui.seed_widget_latents.latents_seed = self.latents_seed self.ui.seed_widget_latents.update_seed() - elif key == "enable_advanced_mode": + elif key == "settings.enable_advanced_mode": self.toggle_advanced_generation() - elif key == "ai_mode": + elif key == "settings.ai_mode": self.activate_ai_mode() """ @@ -158,20 +158,21 @@ def handle_changed_signal(self, key, value): signals in the corresponding ui file. """ def action_clicked_button_save_prompts(self): - self.settings_manager.create_saved_prompt( - self.settings_manager.generator.prompt, - self.settings_manager.generator.negative_prompt + self.app.settings_manager.create_saved_prompt( + self.app.settings_manager.generator.prompt, + self.app.settings_manager.generator.negative_prompt ) def handle_prompt_changed(self): + print("PROMPT CHANGED") if not self.initialized: return - self.settings_manager.set_value("generator.prompt", self.ui.prompt.toPlainText()) + self.app.settings_manager.set_value("generator.prompt", self.ui.prompt.toPlainText()) def handle_negative_prompt_changed(self): if not self.initialized: return - self.settings_manager.set_value("generator.negative_prompt", self.ui.negative_prompt.toPlainText()) + self.app.settings_manager.set_value("generator.negative_prompt", self.ui.negative_prompt.toPlainText()) def toggle_prompt_builder_checkbox(self, toggled): pass @@ -191,9 +192,9 @@ def generate(self, image=None, seed=None): seed = self.app.standard_image_panel.ui.seed_widget.seed if self.app.standard_image_panel.ui.samples_widget.current_value > 1: self.app.client.do_process_queue = False - total_samples = self.settings_manager.generator.n_samples + total_samples = self.app.settings_manager.generator.n_samples for n in range(total_samples): - if self.settings_manager.generator.use_prompt_builder and n > 0: + if self.app.settings_manager.generator.use_prompt_builder and n > 0: seed = int(seed) + n self.call_generate(image, seed=seed) self.seed_override = None @@ -216,7 +217,7 @@ def call_generate(self, image=None, seed=None, override_data=None): # Get input image from input image enable_input_image = override_data.get( "enable_input_image", - self.settings_manager.generator.enable_input_image + self.app.settings_manager.generator.enable_input_image ) if enable_input_image: input_image = self.app.standard_image_panel.ui.input_image_widget.current_input_image @@ -236,8 +237,8 @@ def call_generate(self, image=None, seed=None, override_data=None): if self.is_txt2img: return self.do_generate(seed=seed, override_data=override_data) # Create a transparent image the size of self.app.canvas_widget.active_grid_area_rect - width = self.settings_manager.working_width - height = self.settings_manager.working_height + width = self.app.settings_manager.working_width + height = self.app.settings_manager.working_height image = Image.new("RGBA", (int(width), int(height)), (0, 0, 0, 0)) use_cropped_image = override_data.get("use_cropped_image", True) @@ -252,8 +253,8 @@ def call_generate(self, image=None, seed=None, override_data=None): new_image = Image.new( "RGBA", ( - self.settings_manager.working_width, - self.settings_manager.working_height + self.app.settings_manager.working_width, + self.app.settings_manager.working_height ), (255, 255, 255, 0) ) @@ -298,7 +299,7 @@ def call_generate(self, image=None, seed=None, override_data=None): "mask": mask, "image": image, "original_image": original_image, - "location": QRect(0, 0, self.settings_manager.working_width, self.settings_manager.working_height) + "location": QRect(0, 0, self.app.settings_manager.working_width, self.app.settings_manager.working_height) }, seed=seed, override_data=override_data) elif self.generator_section == "vid2vid": images = self.prep_video() @@ -329,36 +330,36 @@ def do_generate(self, extra_options=None, seed=None, latents_seed=None, do_deter override_data = {} action = override_data.get("action", action) - prompt = override_data.get("prompt", self.settings_manager.generator.prompt) - negative_prompt = override_data.get("negative_prompt", self.settings_manager.generator.negative_prompt) - steps = int(override_data.get("steps", self.settings_manager.generator.steps)) - strength = float(override_data.get("strength", self.settings_manager.generator.strength / 100.0)) - image_guidance_scale = float(override_data.get("image_guidance_scale", self.settings_manager.generator.image_guidance_scale / 10000.0 * 100.0)) - scale = float(override_data.get("scale", self.settings_manager.generator.scale / 100)) - seed = int(override_data.get("seed", self.settings_manager.generator.seed)) - latents_seed = int(override_data.get("latents_seed", self.settings_manager.generator.latents_seed)) - ddim_eta = float(override_data.get("ddim_eta", self.settings_manager.generator.ddim_eta)) + prompt = override_data.get("prompt", self.app.settings_manager.generator.prompt) + negative_prompt = override_data.get("negative_prompt", self.app.settings_manager.generator.negative_prompt) + steps = int(override_data.get("steps", self.app.settings_manager.generator.steps)) + strength = float(override_data.get("strength", self.app.settings_manager.generator.strength / 100.0)) + image_guidance_scale = float(override_data.get("image_guidance_scale", self.app.settings_manager.generator.image_guidance_scale / 10000.0 * 100.0)) + scale = float(override_data.get("scale", self.app.settings_manager.generator.scale / 100)) + seed = int(override_data.get("seed", self.app.settings_manager.generator.seed)) + latents_seed = int(override_data.get("latents_seed", self.app.settings_manager.generator.latents_seed)) + ddim_eta = float(override_data.get("ddim_eta", self.app.settings_manager.generator.ddim_eta)) n_iter = int(override_data.get("n_iter", 1)) - n_samples = int(override_data.get("n_samples", self.settings_manager.generator.n_samples)) + n_samples = int(override_data.get("n_samples", self.app.settings_manager.generator.n_samples)) # iterate over all keys in model_data model_data = {} for k,v in override_data.items(): if k.startswith("model_data_"): model_data[k.replace("model_data_", "")] = v - scheduler = override_data.get("scheduler", self.settings_manager.generator.scheduler) - enable_controlnet = bool(override_data.get("enable_controlnet", self.settings_manager.generator.enable_controlnet)) - controlnet = override_data.get("controlnet", self.settings_manager.generator.controlnet) - controlnet_conditioning_scale = float(override_data.get("controlnet_conditioning_scale", self.settings_manager.generator.controlnet_guidance_scale)) - width = int(override_data.get("width", self.settings_manager.working_width)) - height = int(override_data.get("height", self.settings_manager.working_height)) - clip_skip = int(override_data.get("clip_skip", self.settings_manager.generator.clip_skip)) + scheduler = override_data.get("scheduler", self.app.settings_manager.generator.scheduler) + enable_controlnet = bool(override_data.get("enable_controlnet", self.app.settings_manager.generator.enable_controlnet)) + controlnet = override_data.get("controlnet", self.app.settings_manager.generator.controlnet) + controlnet_conditioning_scale = float(override_data.get("controlnet_conditioning_scale", self.app.settings_manager.generator.controlnet_guidance_scale)) + width = int(override_data.get("width", self.app.settings_manager.working_width)) + height = int(override_data.get("height", self.app.settings_manager.working_height)) + clip_skip = int(override_data.get("clip_skip", self.app.settings_manager.generator.clip_skip)) batch_size = int(override_data.get("batch_size", 1)) # get the model from the database - model = self.settings_manager.models.filter_by( + model = self.app.settings_manager.models.filter_by( name=model_data["name"] if "name" in model_data \ - else self.settings_manager.generator.model + else self.app.settings_manager.generator.model ).first() if model: # set the model data, first using model_data pulled from the override_data @@ -422,23 +423,23 @@ def do_generate(self, extra_options=None, seed=None, latents_seed=None, do_deter generator_section=self.generator_section, width=width, height=height, - do_nsfw_filter=self.settings_manager.nsfw_filter, + do_nsfw_filter=self.app.settings_manager.settings.nsfw_filter, pos_x=0, pos_y=0, outpaint_box_rect=self.active_rect, - hf_token=self.settings_manager.hf_api_key, - model_base_path=self.settings_manager.path_settings.model_base_path, - outpaint_model_path=self.settings_manager.path_settings.outpaint_model_path, - pix2pix_model_path=self.settings_manager.path_settings.pix2pix_model_path, - depth2img_model_path=self.settings_manager.path_settings.depth2img_model_path, - upscale_model_path=self.settings_manager.path_settings.upscale_model_path, - image_path=self.settings_manager.path_settings.image_path, - lora_path=self.settings_manager.lora_path, - embeddings_path=self.settings_manager.path_settings.embeddings_path, - video_path=self.settings_manager.path_settings.video_path, + hf_token=self.app.settings_manager.hf_api_key, + model_base_path=self.app.settings_manager.path_settings.model_base_path, + outpaint_model_path=self.app.settings_manager.path_settings.outpaint_model_path, + pix2pix_model_path=self.app.settings_manager.path_settings.pix2pix_model_path, + depth2img_model_path=self.app.settings_manager.path_settings.depth2img_model_path, + upscale_model_path=self.app.settings_manager.path_settings.upscale_model_path, + image_path=self.app.settings_manager.path_settings.image_path, + lora_path=self.app.settings_manager.lora_path, + embeddings_path=self.app.settings_manager.path_settings.embeddings_path, + video_path=self.app.settings_manager.path_settings.video_path, clip_skip=clip_skip, batch_size=batch_size, - variation=self.settings_manager.generator.variation, + variation=self.app.settings_manager.generator.variation, deterministic_generation=False, input_image=input_image, enable_controlnet=enable_controlnet, @@ -478,18 +479,18 @@ def do_generate(self, extra_options=None, seed=None, latents_seed=None, do_deter def get_memory_options(self): return { - "use_last_channels": self.settings_manager.memory_settings.use_last_channels, - "use_enable_sequential_cpu_offload": self.settings_manager.memory_settings.use_enable_sequential_cpu_offload, - "enable_model_cpu_offload": self.settings_manager.memory_settings.enable_model_cpu_offload, - "use_attention_slicing": self.settings_manager.memory_settings.use_attention_slicing, - "use_tf32": self.settings_manager.memory_settings.use_tf32, - "use_cudnn_benchmark": self.settings_manager.memory_settings.use_cudnn_benchmark, - "use_enable_vae_slicing": self.settings_manager.memory_settings.use_enable_vae_slicing, - "use_accelerated_transformers": self.settings_manager.memory_settings.use_accelerated_transformers, - "use_torch_compile": self.settings_manager.memory_settings.use_torch_compile, - "use_tiled_vae": self.settings_manager.memory_settings.use_tiled_vae, - "use_tome_sd": self.settings_manager.memory_settings.use_tome_sd, - "tome_sd_ratio": self.settings_manager.memory_settings.tome_sd_ratio, + "use_last_channels": self.app.settings_manager.memory_settings.use_last_channels, + "use_enable_sequential_cpu_offload": self.app.settings_manager.memory_settings.use_enable_sequential_cpu_offload, + "enable_model_cpu_offload": self.app.settings_manager.memory_settings.enable_model_cpu_offload, + "use_attention_slicing": self.app.settings_manager.memory_settings.use_attention_slicing, + "use_tf32": self.app.settings_manager.memory_settings.use_tf32, + "use_cudnn_benchmark": self.app.settings_manager.memory_settings.use_cudnn_benchmark, + "use_enable_vae_slicing": self.app.settings_manager.memory_settings.use_enable_vae_slicing, + "use_accelerated_transformers": self.app.settings_manager.memory_settings.use_accelerated_transformers, + "use_torch_compile": self.app.settings_manager.memory_settings.use_torch_compile, + "use_tiled_vae": self.app.settings_manager.memory_settings.use_tiled_vae, + "use_tome_sd": self.app.settings_manager.memory_settings.use_tome_sd, + "tome_sd_ratio": self.app.settings_manager.memory_settings.tome_sd_ratio, } def set_seed(self, seed=None, latents_seed=None): @@ -535,10 +536,6 @@ def start_progress_bar(self): # "code": MessageCode.PROGRESS # }) - def save_db_session(self): - from airunner.utils import save_session - save_session() - def handle_checkbox_change(self, key, widget_name): widget = getattr(self.ui, widget_name) value = widget.isChecked() @@ -547,15 +544,13 @@ def handle_checkbox_change(self, key, widget_name): self.changed_signal.emit(key, value) def initialize(self): - self.settings_manager.generator_section = self.generator_section - self.settings_manager.generator_name = self.generator_name self.set_form_values() - self.settings_manager.changed_signal.connect(self.handle_settings_manager_changed) self.initialized = True + self.app.settings_manager.changed_signal.connect(self.handle_changed_signal) def handle_settings_manager_changed(self, key, val, settings_manager): - if settings_manager.generator_section == self.settings_manager.generator_section and settings_manager.generator_name == self.settings_manager.generator_name: - self.set_form_values() + print("generator_form_widget handle_settings_manager_changed") + self.set_form_values() def clear_prompts(self): self.ui.prompt.setPlainText("") diff --git a/src/airunner/widgets/generator_form/generator_tab_widget.py b/src/airunner/widgets/generator_form/generator_tab_widget.py index 6fb82ac9e..7d644005d 100644 --- a/src/airunner/widgets/generator_form/generator_tab_widget.py +++ b/src/airunner/widgets/generator_form/generator_tab_widget.py @@ -30,7 +30,7 @@ def current_input_image_widget(self): @property def current_input_image(self): - if self.settings_manager.settings.enable_input_image: + if self.app.settings_manager.settings.enable_input_image: return self.current_input_image_widget.current_input_image return None @@ -108,7 +108,7 @@ def handle_generator_tab_changed(self, val): :return: """ print("handle_generator_tab_changed") - self.settings_manager.set_value("current_tab", self.current_generator) + self.app.settings_manager.set_value("settings.current_tab", self.current_generator) self.set_current_section_tab() self.app.handle_generator_tab_changed() @@ -118,12 +118,12 @@ def handle_tab_section_changed(self, val): Tab sections are txt2img, depth2img etc. :return: """ - self.settings_manager.set_value(f"current_section_{self.current_generator}", "txt2img") + self.app.settings_manager.set_value(f"settings.current_section_{self.current_generator}", "txt2img") self.app.handle_tab_section_changed() def set_current_section_tab(self): - current_tab = self.settings_manager.current_tab - current_section = getattr(self.settings_manager, f"current_section_{current_tab}") + current_tab = self.app.settings_manager.current_tab + current_section = getattr(self.app.settings_manager, f"current_section_{current_tab}") tab_object = self.ui.generator_tabs.findChild(QWidget, f"tab_{current_tab}") tab_index = self.ui.generator_tabs.indexOf(tab_object) @@ -158,7 +158,7 @@ def update_available_models(self): self.load_model_by_section(section, tab) def toggle_variation(self, val): - self.settings_manager.set_value("generator.variation", val) + self.app.settings_manager.set_value("generator.variation", val) def set_progress_bar_value(self, tab_section, section, value): progressbar = self.find_widget("progress_bar", tab_section, section) diff --git a/src/airunner/widgets/grid_preferences/grid_preferences_widget.py b/src/airunner/widgets/grid_preferences/grid_preferences_widget.py index 93bda366c..1b9218d07 100644 --- a/src/airunner/widgets/grid_preferences/grid_preferences_widget.py +++ b/src/airunner/widgets/grid_preferences/grid_preferences_widget.py @@ -15,10 +15,10 @@ def __init__(self, *args, **kwargs): self.ui.show_grid_checkbox.blockSignals(True) self.ui.snap_to_grid_checkbox.blockSignals(True) - self.ui.grid_line_width_spinbox.setValue(self.settings_manager.grid_settings.line_width) - self.ui.grid_size_spinbox.setValue(self.settings_manager.grid_settings.size) - self.ui.show_grid_checkbox.setChecked(self.settings_manager.grid_settings.show_grid is True) - self.ui.snap_to_grid_checkbox.setChecked(self.settings_manager.grid_settings.snap_to_grid is True) + self.ui.grid_line_width_spinbox.setValue(self.app.settings_manager.grid_settings.line_width) + self.ui.grid_size_spinbox.setValue(self.app.settings_manager.grid_settings.cell_size) + self.ui.show_grid_checkbox.setChecked(self.app.settings_manager.grid_settings.show_grid is True) + self.ui.snap_to_grid_checkbox.setChecked(self.app.settings_manager.grid_settings.snap_to_grid is True) self.ui.grid_line_width_spinbox.blockSignals(False) self.ui.grid_size_spinbox.blockSignals(False) @@ -26,25 +26,25 @@ def __init__(self, *args, **kwargs): self.ui.snap_to_grid_checkbox.blockSignals(False) def action_toggled_snap_to_grid(self, val): - self.settings_manager.set_value("grid_settings.snap_to_grid", val) + self.app.settings_manager.set_value("grid_settings.snap_to_grid", val) def action_toggled_show_grid(self, val): - self.settings_manager.set_value("grid_settings.show_grid", val) + self.app.settings_manager.set_value("grid_settings.show_grid", val) def action_button_clicked_grid_line_color(self): color = QColorDialog.getColor() if color.isValid(): - self.settings_manager.set_value("grid_settings.line_color", color.name()) + self.app.settings_manager.set_value("grid_settings.line_color", color.name()) self.app.canvas.update_grid_pen() def action_button_clicked_canvas_color(self): color = QColorDialog.getColor() if color.isValid(): - self.settings_manager.set_value("grid_settings.canvas_color", color.name()) + self.app.settings_manager.set_value("grid_settings.canvas_color", color.name()) self.app.canvas.update_canvas_color(color.name()) def grid_size_changed(self, val): - self.settings_manager.set_value("grid_settings.size", val) + self.app.settings_manager.set_value("grid_settings.cell_size", val) def line_width_changed(self, val): - self.settings_manager.set_value("grid_settings.line_width", val) + self.app.settings_manager.set_value("grid_settings.line_width", val) diff --git a/src/airunner/widgets/image/image_panel_widget.py b/src/airunner/widgets/image/image_panel_widget.py index 5a576fbad..3f17b3cbd 100644 --- a/src/airunner/widgets/image/image_panel_widget.py +++ b/src/airunner/widgets/image/image_panel_widget.py @@ -35,7 +35,7 @@ def __init__(self, *args, **kwargs): self.ui.scrollArea.verticalScrollBar().valueChanged.connect(self.handle_scroll) flowLayout = QFlowLayout() self.ui.scrollAreaWidgetContents.setLayout(flowLayout) - if self.settings_manager.path_settings.image_path != "": + if self.app.settings_manager.path_settings.image_path != "": self.show_files() self.load_files() @@ -89,12 +89,12 @@ def load_files(self): Returns: None """ - files_in_image_path = os.listdir(self.settings_manager.path_settings.image_path) + files_in_image_path = os.listdir(self.app.settings_manager.path_settings.image_path) sorted_files = {} for file in files_in_image_path: - if os.path.isdir(os.path.join(self.settings_manager.path_settings.image_path, file)): + if os.path.isdir(os.path.join(self.app.settings_manager.path_settings.image_path, file)): sorted_files[file] = [] - for root, dirs, files_in_dir in os.walk(os.path.join(self.settings_manager.path_settings.image_path, file)): + for root, dirs, files_in_dir in os.walk(os.path.join(self.app.settings_manager.path_settings.image_path, file)): files = [] for f in files_in_dir: if ".png.thumbnail.png" not in f: @@ -117,7 +117,7 @@ def display_thumbnails(self): for file in self.sorted_files[self.start:self.end]: if file.endswith(".png"): image_widget = ImageWidget(self, is_thumbnail=True) - image_widget.set_image(os.path.join(self.settings_manager.path_settings.image_path, file)) + image_widget.set_image(os.path.join(self.app.settings_manager.path_settings.image_path, file)) self.ui.scrollAreaWidgetContents.layout().addWidget(image_widget) def handle_folder_clicked(self, path): diff --git a/src/airunner/widgets/image/image_widget.py b/src/airunner/widgets/image/image_widget.py index 5aaf18ca2..4afc51916 100644 --- a/src/airunner/widgets/image/image_widget.py +++ b/src/airunner/widgets/image/image_widget.py @@ -1,3 +1,4 @@ +from contextlib import contextmanager import os import json @@ -19,6 +20,7 @@ from PyQt6.QtGui import QDrag from PyQt6.QtCore import QMimeData from PyQt6.QtCore import QByteArray +from airunner.data.session_scope import session_scope class ImageWidget(BaseWidget): @@ -251,9 +253,17 @@ def generate_variant(self): class BrushImageWidget(ImageWidget): + _brush = None + + @contextmanager + def brush(self): + with session_scope() as session: + session.add(self._brush) + yield self._brush + def __init__(self, *args, **kwargs): self.container = kwargs.pop("container", None) - self.brush = kwargs.pop("brush", None) + self._brush = kwargs.pop("brush", None) super().__init__(*args, **kwargs) def handle_label_clicked(self, event): diff --git a/src/airunner/widgets/image_generator_preferences/image_generator_preferences_widget.py b/src/airunner/widgets/image_generator_preferences/image_generator_preferences_widget.py index 4ccc755d4..6e9ca3251 100644 --- a/src/airunner/widgets/image_generator_preferences/image_generator_preferences_widget.py +++ b/src/airunner/widgets/image_generator_preferences/image_generator_preferences_widget.py @@ -7,12 +7,12 @@ class ImageGeneratorPreferencesWidget(BaseWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.ui.stablediffusion.setChecked(self.settings_manager.current_image_generator == "stablediffusion") + self.ui.stablediffusion.setChecked(self.app.settings_manager.current_image_generator == "stablediffusion") def stablediffusion_toggled(self, val): if val: - self.settings_manager.set_value("current_image_generator", "stablediffusion") - self.settings_manager.set_value("current_tab", "stablediffusion") - self.settings_manager.set_value("current_section_stablediffusion", "txt2img") + self.app.settings_manager.set_value("settings.current_image_generator", "stablediffusion") + self.app.settings_manager.set_value("settings.current_tab", "stablediffusion") + self.app.settings_manager.set_value("settings.current_section_stablediffusion", "txt2img") self.app.generator_tab_widget.set_current_section_tab() - self.settings_manager.set_value("generator_section", "txt2img") \ No newline at end of file + self.app.settings_manager.set_value("settings.generator_section", "txt2img") \ No newline at end of file diff --git a/src/airunner/widgets/input_image/input_image_settings_widget.py b/src/airunner/widgets/input_image/input_image_settings_widget.py index 48f41cfd2..1fad003ee 100644 --- a/src/airunner/widgets/input_image/input_image_settings_widget.py +++ b/src/airunner/widgets/input_image/input_image_settings_widget.py @@ -22,7 +22,7 @@ def generator_name(self): return self.property("generator_name") def active_grid_area_image(self): - if not self.settings_manager.generator.input_image_recycle_grid_image or not self._active_grid_area_image: + if not self.app.settings_manager.generator_settings.input_image_recycle_grid_image or not self._active_grid_area_image: layer_image = self.app.canvas.current_layer.image if layer_image.image: self._active_grid_area_image = layer_image.image.copy() @@ -31,11 +31,11 @@ def active_grid_area_image(self): @property def current_input_image(self): try: - if not self.settings_manager.generator: + if not self.app.settings_manager.generator_settings: return None - if self.settings_manager.generator.input_image_use_imported_image: + if self.app.settings_manager.generator_settings.input_image_use_imported_image: return self.input_image - elif self.settings_manager.generator.input_image_use_grid_image: + elif self.app.settings_manager.generator_settings.input_image_use_grid_image: return self.active_grid_area_image() except AttributeError: return None @@ -51,11 +51,11 @@ def initialize_combobox(self): def initialize_groupbox(self): self.ui.groupBox.blockSignals(True) - self.ui.groupBox.setChecked(self.settings_manager.generator.enable_input_image) + self.ui.groupBox.setChecked(self.app.settings_manager.generator_settings.enable_input_image) self.ui.groupBox.blockSignals(False) def action_toggled_use_input_image(self, val): - self.settings_manager.set_value("generator.enable_input_image", val) + self.app.settings_manager.set_value("generator.enable_input_image", val) def action_toggled_button_use_imported_image(self, val): self.toggle_use_imported_image(val) @@ -68,7 +68,7 @@ def action_toggled_button_use_grid_image(self, val): self.update_buttons() def toggle_use_imported_image(self, value): - self.settings_manager.set_value("generator.input_image_use_imported_image", value) + self.app.settings_manager.set_value("generator.input_image_use_imported_image", value) self.set_thumbnail(self.input_image) def action_toggled_button_lock_grid_image(self, val): @@ -78,8 +78,8 @@ def action_toggled_button_refresh_input_image(self, val): self.toggle_keep_refreshed(val) def toggle_keep_refreshed(self, value): - if self.settings_manager.generator.input_image_use_grid_image: - self.settings_manager.set_value("generator.input_image_recycle_grid_image", value) + if self.app.settings_manager.generator_settings.input_image_use_grid_image: + self.app.settings_manager.set_value("generator.input_image_recycle_grid_image", value) self.set_thumbnail() def action_clicked_button_refresh_grid_image(self): @@ -101,14 +101,14 @@ def action_clicked_button_clear_input_image(self): grid_layout.addWidget(slider) def handle_image_strength_changed(self, val): - self.settings_manager.set_value("generator.strength", val) + self.app.settings_manager.set_value("generator.strength", val) def handle_image_scale_changed(self, val): - self.settings_manager.set_value("generator.image_scale", val) + self.app.settings_manager.set_value("generator.image_scale", val) def import_input_image(self): file_path, _ = self.app.display_import_image_dialog( - directory=self.settings_manager.path_settings.image_path, + directory=self.app.settings_manager.path_settings.image_path, ) if file_path == "": return @@ -118,33 +118,33 @@ def import_input_image(self): self.set_thumbnail(image) def clear_input_image(self): - if self.settings_manager.generator.input_image_use_grid_image: + if self.app.settings_manager.generator_settings.input_image_use_grid_image: self._active_grid_area_image = None - elif self.settings_manager.generator.input_image_use_imported_image: + elif self.app.settings_manager.generator_settings.input_image_use_imported_image: self.input_image = None self.set_thumbnail() def toggle_use_active_grid_area(self, value): - self.settings_manager.set_value("generator.input_image_use_grid_image", value) + self.app.settings_manager.set_value("generator.input_image_use_grid_image", value) self.set_thumbnail(self.current_input_image) def update_buttons(self): - if not self.settings_manager.generator: + if not self.app.settings_manager.generator_settings: return self.ui.use_imported_image_button.blockSignals(True) self.ui.use_grid_image_button.blockSignals(True) self.ui.recycle_grid_image_button.blockSignals(True) - if self.settings_manager.generator.input_image_use_grid_image: + if self.app.settings_manager.generator_settings.input_image_use_grid_image: self.ui.import_image_button.setEnabled(False) self.ui.recycle_grid_image_button.setEnabled(True) # hide the self.ui.refresh_input_image_button button widget self.ui.clear_image_button.hide() self.ui.refresh_input_image_button.show() self.ui.use_imported_image_button.setChecked(False) - self.ui.use_grid_image_button.setChecked(self.settings_manager.generator.input_image_use_grid_image) - self.ui.recycle_grid_image_button.setChecked(self.settings_manager.generator.input_image_recycle_grid_image) + self.ui.use_grid_image_button.setChecked(self.app.settings_manager.generator_settings.input_image_use_grid_image) + self.ui.recycle_grid_image_button.setChecked(self.app.settings_manager.generator_settings.input_image_recycle_grid_image) else: self.ui.import_image_button.setEnabled(True) self.ui.recycle_grid_image_button.setEnabled(False) @@ -165,7 +165,7 @@ def clear_input_image_mask(self): print("clear input image mask") def handle_new_image(self, data): - if not self.settings_manager.generator.input_image_recycle_grid_image or not self._active_grid_area_image: + if not self.app.settings_manager.generator_settings.input_image_recycle_grid_image or not self._active_grid_area_image: self._active_grid_area_image = data["processed_image"].copy() self.set_thumbnail() diff --git a/src/airunner/widgets/layers/layer_container_widget.py b/src/airunner/widgets/layers/layer_container_widget.py index 39e5f154c..0cefab86d 100644 --- a/src/airunner/widgets/layers/layer_container_widget.py +++ b/src/airunner/widgets/layers/layer_container_widget.py @@ -1,44 +1,39 @@ from PIL import Image from PyQt6.QtCore import QRect, QPoint, Qt from PyQt6.QtWidgets import QSpacerItem, QSizePolicy -from airunner.aihandler.logger import Logger +from contextlib import contextmanager +from airunner.aihandler.logger import Logger from airunner.data.models import Layer from airunner.models.layerdata import LayerData -from airunner.utils import get_session, save_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.layers.layer_widget import LayerWidget from airunner.widgets.layers.templates.layer_container_ui import Ui_layer_container - class LayerContainerWidget(BaseWidget): widget_class_ = Ui_layer_container current_layer_index = 0 layers = [] selected_layers = {} - @property + @contextmanager def current_layer(self): - if len(self.layers) == 0: - return None - try: - return self.layers[self.current_layer_index] - except IndexError: - Logger.error(f"No current layer for index {self.current_layer_index}") + with self.app.settings_manager.layers() as layers: + if len(layers) == 0: + self.add_layer() + try: + yield layers[self.current_layer_index] + except IndexError: + Logger.error(f"No current layer for index {self.current_layer_index}") def initialize(self): - self.ui.scrollAreaWidgetContents.layout().addSpacerItem( - QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)) - session = get_session() - self.layers = session.query(Layer).filter_by(document=self.app.document).all() - if len(self.layers) == 0: - self.create_layer() - else: - self.add_layers() - # set the current_value property of the slider - self.ui.opacity_slider_widget.set_slider_and_spinbox_values(self.current_layer.opacity) - self.ui.opacity_slider_widget.initialize_properties() - self.set_layer_opacity(self.current_layer.opacity) + with self.current_layer() as current_layer: + self.ui.scrollAreaWidgetContents.layout().addSpacerItem(QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)) + # set the current_value property of the slider + self.ui.opacity_slider_widget.set_slider_and_spinbox_values(current_layer.opacity) + self.ui.opacity_slider_widget.initialize_properties() + self.set_layer_opacity(current_layer.opacity) def action_clicked_button_add_new_layer(self): self.add_layer() @@ -57,8 +52,9 @@ def action_clicked_button_delete_selected_layers(self): self.delete_layer() def add_layers(self): - for layer in self.layers: - self.add_layer_widget(layer, layer.position) + with self.app.settings_manager.layers() as layers: + for layer in layers: + self.add_layer_widget(layer, layer.position) def add_layer(self): self.app.history.add_event({ @@ -69,21 +65,24 @@ def add_layer(self): return self.create_layer() def create_layer(self): - session = get_session() - layer_data = Layer( - name=f"Layer {len(self.layers) + 1}", - document=self.app.document, - position=len(self.layers) + 1, - visible=True - ) - session.add(layer_data) - save_session(session) + with self.app.settings_manager.document() as document: + with self.app.settings_manager.layers() as layers: + layer_data = Layer( + name=f"Layer {len(layers) + 1}", + document=document, + position=len(layers) + 1, + visible=True + ) + + with session_scope() as session: + session.add(layer_data) - layer_name = f"Layer {len(self.layers) + 1}" + # layer_name = f"Layer {len(self.layers) + 1}" index = 0 - self.layers.insert(index, layer_data) - self.set_current_layer(index) - self.add_layer_widget(layer_data, index) + with self.app.settings_manager.layers() as layers: + layers.insert(index, layer_data) + self.set_current_layer(index) + self.add_layer_widget(layer_data, index) return index def add_layer_widget(self, layer_data, index): @@ -96,87 +95,93 @@ def add_layer_widget(self, layer_data, index): layer_widget.reset_position() def move_layer_up(self): - layer = self.current_layer - index = self.layers.index(layer) - if index == 0: - return - # track the current layer order - self.app.canvas.track_layer_move_history() - self.layers.remove(layer) - self.layers.insert(index - 1, layer) - self.current_layer_index = index - 1 - self.show_layers() - self.app.canvas.update() + with self.app.settings_manager.layers() as layers: + with self.current_layer() as current_layer: + layer = current_layer + index = layers.index(layer) + if index == 0: + return + # track the current layer order + self.app.canvas.track_layer_move_history() + layers.remove(layer) + layers.insert(index - 1, layer) + self.current_layer_index = index - 1 + self.show_layers() + self.app.canvas.update() def move_layer_down(self): - layer = self.current_layer - index = self.layers.index(layer) - if index == len(self.layers) - 1: - return - self.app.canvas.track_layer_move_history() - self.layers.remove(layer) - self.layers.insert(index + 1, layer) - self.current_layer_index = index + 1 - self.show_layers() - self.app.canvas.update() + with self.app.settings_manager.layers() as layers: + with self.current_layer() as layer: + index = layers.index(layer) + if index == len(layers) - 1: + return + self.app.canvas.track_layer_move_history() + layers.remove(layer) + layers.insert(index + 1, layer) + self.current_layer_index = index + 1 + self.show_layers() + self.app.canvas.update() def merge_selected_layers(self): - if self.current_layer_index not in self.selected_layers: - self.selected_layers[self.current_layer_index] = self.current_layer - - selected_layer = self.current_layer - - # get the rect of the new image based on the existing images extremities - # (left, top, width and height) - rect = QRect() - for layer in self.selected_layers.values(): - image = layer.image_data.image - if image: - if (image.width+layer.image_data.position.x()) > rect.width(): - rect.setWidth(image.width+abs(layer.image_data.position.x())) - if (image.height+layer.image_data.position.y()) > rect.height(): - rect.setHeight(image.height+abs(layer.image_data.position.y())) - if layer.image_data.position.x() < rect.x(): - rect.setX(layer.image_data.position.x()) - if layer.image_data.position.y() < rect.y(): - rect.setY(layer.image_data.position.y()) - - new_image = Image.new("RGBA", (rect.width(), rect.height()), (0, 0, 0, 0)) - - for index, layer in self.selected_layers.items(): - # get an image object and merge it into the new image if it exists - image = layer.image_data.image - if image: - x = layer.image_data.position.x() - if x < 0: - x = 0 - y = layer.image_data.position.y() - if y < 0: - y = 0 - new_image.alpha_composite( - image, - (x, y) - ) - - # delete any layers which are not the current layer index - if index != self.current_layer_index: - self.app.canvas.delete_layer(layer=layer) - - # if we have a new image object, set it as the current layer image - layer_index = self.app.canvas.get_index_by_layer(selected_layer) - Logger.info("Setting current_layer_index={layer_index}") - self.current_layer_index = layer_index - if new_image: - self.layers[self.current_layer_index].image_data.image = new_image - self.layers[self.current_layer_index].image_data.position = QPoint(rect.x(), rect.y()) - - # reset the selected layers dictionary and refresh the canvas - self.selected_layers = {} - self.show_layers() - self.app.canvas.update() + with self.current_layer() as current_layer: + if self.current_layer_index not in self.selected_layers: + self.selected_layers[self.current_layer_index] = current_layer + + selected_layer = self.current_layer + + # get the rect of the new image based on the existing images extremities + # (left, top, width and height) + rect = QRect() + for layer in self.selected_layers.values(): + image = layer.image_data.image + if image: + if (image.width+layer.image_data.position.x()) > rect.width(): + rect.setWidth(image.width+abs(layer.image_data.position.x())) + if (image.height+layer.image_data.position.y()) > rect.height(): + rect.setHeight(image.height+abs(layer.image_data.position.y())) + if layer.image_data.position.x() < rect.x(): + rect.setX(layer.image_data.position.x()) + if layer.image_data.position.y() < rect.y(): + rect.setY(layer.image_data.position.y()) + + new_image = Image.new("RGBA", (rect.width(), rect.height()), (0, 0, 0, 0)) + + for index, layer in self.selected_layers.items(): + # get an image object and merge it into the new image if it exists + image = layer.image_data.image + if image: + x = layer.image_data.position.x() + if x < 0: + x = 0 + y = layer.image_data.position.y() + if y < 0: + y = 0 + new_image.alpha_composite( + image, + (x, y) + ) + + # delete any layers which are not the current layer index + if index != self.current_layer_index: + self.app.canvas.delete_layer(layer=layer) + + # if we have a new image object, set it as the current layer image + layer_index = self.app.canvas.get_index_by_layer(selected_layer) + Logger.info("Setting current_layer_index={layer_index}") + self.current_layer_index = layer_index + with self.app.settings_manager.layers() as layers: + if new_image: + layers[self.current_layer_index].image_data.image = new_image + layers[self.current_layer_index].image_data.position = QPoint(rect.x(), rect.y()) + + # reset the selected layers dictionary and refresh the canvas + self.selected_layers = {} + self.show_layers() + self.app.canvas.update() def get_layers_copy(self): - return [layer for layer in self.layers] + with self.app.settings_manager.layers() as layers: + return [layer for layer in layers] selected_layers = {} @@ -195,42 +200,44 @@ def delete_selected_layers(self): def delete_layer(self, _value=False, index=None, layer=None): Logger.info(f"delete_layer requested index {index}") - current_index = index - if layer and current_index is None: - for layer_index, layer_object in enumerate(self.layers): - if layer_object is layer: - current_index = layer_index - Logger.info(f"current_index={current_index}") - if current_index is None: - current_index = self.current_layer_index - Logger.info(f"Deleting layer {current_index}") - self.app.standard_image_panel.canvas_widget.delete_image() - self.app.history.add_event({ - "event": "delete_layer", - "layers": self.get_layers_copy(), - "layer_index": current_index - }) - try: - session = get_session() - session.delete(self.layers[current_index]) - save_session(session) - layer = self.layers.pop(current_index) - layer.layer_widget.deleteLater() - except IndexError as e: - Logger.error(f"Could not delete layer {current_index}. Error: {e}") - if len(self.layers) == 0: - self.layers = [LayerData(0, "Layer 1")] - self.show_layers() - self.update() + with self.app.settings_manager.layers() as layers: + current_index = index + if layer and current_index is None: + for layer_index, layer_object in enumerate(layers): + if layer_object is layer: + current_index = layer_index + Logger.info(f"current_index={current_index}") + if current_index is None: + current_index = self.current_layer_index + Logger.info(f"Deleting layer {current_index}") + self.app.standard_image_panel.canvas_widget.delete_image() + self.app.history.add_event({ + "event": "delete_layer", + "layers": self.get_layers_copy(), + "layer_index": current_index + }) + try: + with session_scope() as session: + session.delete(layers[current_index]) + with self.app.settings_manager.layers() as layers: + layer = layers.pop(current_index) + layer.layer_widget.deleteLater() + except IndexError as e: + Logger.error(f"Could not delete layer {current_index}. Error: {e}") + if len(layers) == 0: + layers = [LayerData(0, "Layer 1")] + self.show_layers() + self.update() def clear_layers(self): # delete all widgets from self.container.layout() - for index, layer in enumerate(self.layers): - if not layer.layer_widget: - continue - layer.layer_widget.deleteLater() - self.layers = [LayerData(0, "Layer 1")] - self.current_layer_index = 0 + with self.app.settings_manager.layers() as layers: + for index, layer in enumerate(layers): + if not layer.layer_widget: + continue + layer.layer_widget.deleteLater() + layers = [LayerData(0, "Layer 1")] + self.current_layer_index = 0 def handle_layer_click(self, layer, index, event): Logger.info(f"handle_layer_click index={index}") @@ -275,23 +282,26 @@ def set_current_layer(self, index): # ) def track_layer_move_history(self): - layer_order = [] - for layer in self.layers: - layer_order.append(layer.uuid) - self.app.history.add_event({ - "event": "move_layer", - "layer_order": layer_order, - "layer_index": self.current_layer_index - }) + with self.app.settings_manager.layers() as layers: + layer_order = [] + for layer in layers: + layer_order.append(layer.uuid) + self.app.history.add_event({ + "event": "move_layer", + "layer_order": layer_order, + "layer_index": self.current_layer_index + }) def get_layers_copy(self): - return [layer for layer in self.layers] + with self.app.settings_manager.layers() as layers: + return [layer for layer in layers] def get_index_by_layer(self, layer): - for index, layer_object in enumerate(self.layers): - if layer is layer_object: - return index - return 0 + with self.app.settings_manager.layers() as layers: + for index, layer_object in enumerate(layers): + if layer is layer_object: + return index + return 0 def toggle_layer_visibility(self, layer, layer_obj): # change the eye icon of the visible_button on the layer @@ -306,7 +316,7 @@ def handle_move_layer(self, event): event.pos().y() if self.app.canvas.drag_pos is not None else 0 ) # snap to grid - grid_size = self.settings_manager.grid_settings.size + grid_size = self.app.settings_manager.grid_settings.cell_size point.setX(point.x() - (point.x() % grid_size)) point.setY(point.y() - (point.y() % grid_size)) @@ -316,35 +326,36 @@ def handle_move_layer(self, event): # establish a rect based on line points - we need the area that is being moved # so that we can center the point on it - rect = QRect() - for line in self.current_layer.lines: - rect = rect.united(QRect(line.start_point, line.end_point)) - - try: - rect = rect.united(QRect( - self.current_layer.image_data.position.x(), - self.current_layer.image_data.position.y(), - self.current_layer.image_data.image.size[0], - self.current_layer.image_data.image.size[1] - )) - except IndexError: - pass + with self.current_layer() as current_layer: + rect = QRect() + for line in current_layer.lines: + rect = rect.united(QRect(line.start_point, line.end_point)) + + try: + rect = rect.united(QRect( + current_layer.image_data.position.x(), + current_layer.image_data.position.y(), + current_layer.image_data.image.size[0], + current_layer.image_data.image.size[1] + )) + except IndexError: + pass # center the point on the rect point.setX(int(point.x() - int(rect.width() / 2))) point.setY(int(point.y() - int(rect.height() / 2))) - self.layers[self.current_layer_index].offset = point + with self.app.settings_manager.layers() as layers: + layers[self.current_layer_index].offset = point self.app.canvas.update() def get_layer_opacity(self, index): - return self.layers[index].opacity + with self.app.settings_manager.layers() as layers: + return layers[index].opacity def set_layer_opacity(self, opacity: int): - self.current_layer.opacity = opacity - session = get_session() - session.add(self.current_layer) - save_session(session) + with self.current_layer() as current_layer: + current_layer.opacity = opacity def show_layers(self): pass \ No newline at end of file diff --git a/src/airunner/widgets/layers/layer_image_widget.py b/src/airunner/widgets/layers/layer_image_widget.py index 625ff3a8c..61d89aa63 100644 --- a/src/airunner/widgets/layers/layer_image_widget.py +++ b/src/airunner/widgets/layers/layer_image_widget.py @@ -1,8 +1,9 @@ from PyQt6.uic.properties import QtGui -from airunner.utils import save_session, image_to_pixmap +from airunner.utils import image_to_pixmap from airunner.widgets.base_widget import BaseWidget from airunner.widgets.layers.templates.layer_image_widget_ui import Ui_layer_image_widget +from airunner.data.session_scope import session_scope class LayerImageWidget(BaseWidget): @@ -15,12 +16,13 @@ def __init__(self, layer_image_data): self.set_thumbnail() def action_clicked_button_toggle_image_visibility(self, value): - self.layer_image_data.visible = value - self.settings_manager.save_and_emit( - "layer_image_data.visible", - value - ) - save_session() + with session_scope() as session: + session.add(self.layer_image_data) + self.layer_image_data.visible = value + self.app.settings_manager.save_and_emit( + "layer_image_data.visible", + value + ) def set_thumbnail(self): image = self.layer_image_data.image diff --git a/src/airunner/widgets/layers/layer_widget.py b/src/airunner/widgets/layers/layer_widget.py index b648fb5fd..266f44f22 100644 --- a/src/airunner/widgets/layers/layer_widget.py +++ b/src/airunner/widgets/layers/layer_widget.py @@ -5,18 +5,24 @@ from airunner.widgets.base_widget import BaseWidget from airunner.widgets.layers.templates.layer_ui import Ui_LayerWidget -from airunner.utils import get_session, image_to_pixmap +from airunner.utils import image_to_pixmap +from airunner.data.session_scope import session_scope class LayerWidget(BaseWidget): widget_class_ = Ui_LayerWidget - layer_data = None offset = QPoint(0, 0) _previous_pos = None + @property + def layer_data(self): + with session_scope() as session: + session.add(self._layer_data) + return self._layer_data + def __init__(self, *args, **kwargs): self.layer_container = kwargs.pop("layer_container", None) - self.layer_data = kwargs.pop("layer_data", None) + self._layer_data = kwargs.pop("layer_data", None) self.layer_index = kwargs.pop("layer_index", None) self.layer_data.layer_widget = self super().__init__(*args, **kwargs) @@ -60,9 +66,9 @@ def set_visible_button_icon(self, val): def action_clicked_button_toggle_layer_visibility(self, val): self.set_visible_button_icon(val) - self.layer_data.visible = val - session = get_session() - session.commit() + with session_scope() as session: + session.add(self.layer_data) + self.layer_data.visible = val self.app.canvas_widget.do_draw() def set_thumbnail(self): diff --git a/src/airunner/widgets/llm/chat_prompt_widget.py b/src/airunner/widgets/llm/chat_prompt_widget.py index 96a908902..e6214c630 100644 --- a/src/airunner/widgets/llm/chat_prompt_widget.py +++ b/src/airunner/widgets/llm/chat_prompt_widget.py @@ -6,7 +6,7 @@ from airunner.widgets.base_widget import BaseWidget from airunner.widgets.llm.templates.chat_prompt_ui import Ui_chat_prompt from airunner.widgets.llm.message_widget import MessageWidget -from airunner.utils import save_session, get_session +from airunner.data.session_scope import session_scope from airunner.aihandler.logger import Logger @@ -24,7 +24,7 @@ class ChatPromptWidget(BaseWidget): @property def generator(self): try: - return self.app.generator + return self.app.settings_manager.llm_generator except Exception as e: Logger.error(e) import traceback @@ -43,19 +43,18 @@ def instructions(self): @property def current_generator(self): - return self.settings_manager.current_llm_generator + return self.app.settings_manager.current_llm_generator @property def instructions(self): return f"{self.generator.botname} loves {self.generator.username}. {self.generator.botname} is very nice. {self.generator.botname} uses compliments, kind responses, and nice words. Everything {self.generator.botname} says is nice. {self.generator.botname} is kind." def load_data(self): - session = get_session() - self.conversation = session.query(Conversation).first() - if self.conversation is None: - self.conversation = Conversation() - session.add(self.conversation) - session.commit() + with session_scope() as session: + self.conversation = session.query(Conversation).first() + if self.conversation is None: + self.conversation = Conversation() + session.add(self.conversation) def initialize(self): self.load_data() @@ -122,11 +121,10 @@ def handle_text_generated(self, message): message=message, conversation=self.conversation ) - session = get_session() - session.add(message_object) - session.commit() + with session_scope() as session: + session.add(message_object) - if self.settings_manager.enable_tts: + if self.app.settings_manager.enable_tts: # split on sentence enders sentence_enders = [".", "?", "!", "\n"] text = message_object.message @@ -209,61 +207,60 @@ def action_button_clicked_send(self, image_override=None, prompt_override=None, Logger.warning("Prompt is empty") return - session = get_session() - prompt_template = session.query(LLMPromptTemplate).filter( - LLMPromptTemplate.name == self.generator.prompt_template - ).first() - - data = { - "llm_request": True, - "request_data": { - "generator_name": generator_name, - "model_path": self.generator_settings.model_version, - "stream": True, - "prompt": prompt, - "do_summary": False, - "is_bot_alive": True, - "conversation_history": self.conversation_history, - "generator": self.generator, - "prefix": self.prefix, - "suffix": self.suffix, - "dtype": self.generator_settings.dtype, - "use_gpu": self.generator_settings.use_gpu, - "request_type": "image_caption_generator", - "username": self.generator.username, - "botname": self.generator.botname, - "prompt_template": prompt_template.template, - "parameters": { - "override_parameters": self.generator.override_parameters, - "top_p": self.generator_settings.top_p / 100.0, - "max_length": self.generator_settings.max_length, - "repetition_penalty": self.generator_settings.repetition_penalty / 100.0, - "min_length": self.generator_settings.min_length, - "length_penalty": self.generator_settings.length_penalty / 100, - "num_beams": self.generator_settings.num_beams, - "ngram_size": self.generator_settings.ngram_size, - "temperature": self.generator_settings.temperature / 10000.0, - "sequences": self.generator_settings.sequences, - "top_k": self.generator_settings.top_k, - "eta_cutoff": self.generator_settings.eta_cutoff / 100.0, - "seed": self.generator_settings.do_sample, - "early_stopping": self.generator_settings.early_stopping, - }, - "image": image, - "callback": callback + with session_scope() as session: + prompt_template = session.query(LLMPromptTemplate).filter( + LLMPromptTemplate.name == self.generator.prompt_template + ).first() + + data = { + "llm_request": True, + "request_data": { + "generator_name": generator_name, + "model_path": self.generator_settings.model_version, + "stream": True, + "prompt": prompt, + "do_summary": False, + "is_bot_alive": True, + "conversation_history": self.conversation_history, + "generator": self.generator, + "prefix": self.prefix, + "suffix": self.suffix, + "dtype": self.generator_settings.dtype, + "use_gpu": self.generator_settings.use_gpu, + "request_type": "image_caption_generator", + "username": self.generator.username, + "botname": self.generator.botname, + "prompt_template": prompt_template.template, + "parameters": { + "override_parameters": self.generator.override_parameters, + "top_p": self.generator_settings.top_p / 100.0, + "max_length": self.generator_settings.max_length, + "repetition_penalty": self.generator_settings.repetition_penalty / 100.0, + "min_length": self.generator_settings.min_length, + "length_penalty": self.generator_settings.length_penalty / 100, + "num_beams": self.generator_settings.num_beams, + "ngram_size": self.generator_settings.ngram_size, + "temperature": self.generator_settings.temperature / 10000.0, + "sequences": self.generator_settings.sequences, + "top_k": self.generator_settings.top_k, + "eta_cutoff": self.generator_settings.eta_cutoff / 100.0, + "seed": self.generator_settings.do_sample, + "early_stopping": self.generator_settings.early_stopping, + }, + "image": image, + "callback": callback + } } - } - message_object = Message( - name=self.generator.username, - message=self.prompt, - conversation=self.conversation - ) - session.add(message_object) - session.commit() - self.app.client.message = data - self.add_message_to_conversation(message_object=message_object, is_bot=False) - self.clear_prompt() - self.start_progress_bar() + message_object = Message( + name=self.generator.username, + message=self.prompt, + conversation=self.conversation + ) + session.add(message_object) + self.app.client.message = data + self.add_message_to_conversation(message_object=message_object, is_bot=False) + self.clear_prompt() + self.start_progress_bar() def describe_image(self, image, callback): self.action_button_clicked_send( @@ -311,24 +308,29 @@ def action_button_clicked_clear_conversation(self): } def message_type_text_changed(self, val): - self.generator.message_type = val - save_session() + with session_scope() as session: + session.add(self.generator) + self.generator.message_type = val def action_button_clicked_generate_characters(self): pass def prefix_text_changed(self): - self.generator.prefix = self.ui.prefix.toPlainText() - save_session() + with session_scope() as session: + session.add(self.generator) + self.generator.prefix = self.ui.prefix.toPlainText() def suffix_text_changed(self): - self.generator.suffix = self.ui.suffix.toPlainText() - save_session() + with session_scope() as session: + session.add(self.generator) + self.generator.suffix = self.ui.suffix.toPlainText() def username_text_changed(self, val): - self.generator.username = val - save_session() - + with session_scope() as session: + session.add(self.generator) + self.settings_manager.set_value("generator.username", val) + def botname_text_changed(self, val): - self.generator.botname = val - save_session() \ No newline at end of file + with session_scope() as session: + session.add(self.generator) + self.settings_manager.set_value("generator.botname", val) diff --git a/src/airunner/widgets/llm/llm_settings_widget.py b/src/airunner/widgets/llm/llm_settings_widget.py index 64aeb2095..f7fb50f13 100644 --- a/src/airunner/widgets/llm/llm_settings_widget.py +++ b/src/airunner/widgets/llm/llm_settings_widget.py @@ -5,9 +5,9 @@ from airunner.widgets.base_widget import BaseWidget from airunner.widgets.llm.templates.llm_settings_ui import Ui_llm_settings_widget -from airunner.utils import save_session, get_session from airunner.data.models import LLMGeneratorSetting, LLMGenerator, AIModel, LLMPromptTemplate from airunner.aihandler.logger import Logger +from airunner.data.session_scope import session_scope class LLMSettingsWidget(BaseWidget): @@ -24,7 +24,7 @@ class LLMSettingsWidget(BaseWidget): @property def generator(self): try: - return self.app.generator + return self.app.settings_manager.llm_generator except Exception as e: Logger.error(e) import traceback @@ -33,32 +33,33 @@ def generator(self): @property def generator_settings(self): try: - return self.app.generator_settings + return self.app.settings_manager.generator_settings except Exception as e: Logger.error(e) @property def current_generator(self): - return self.settings_manager.get_value("current_llm_generator") + return self.app.settings_manager.settings.current_llm_generator def initialize(self): self.initialize_form() def early_stopping_toggled(self, val): - self.generator.generator_settings[0].early_stopping = val - save_session() + with session_scope() as session: + session.add(self.app.settings_manager.llm_generator_settings) + self.app.settings_manager.llm_generator_settings.early_stopping = val def do_sample_toggled(self, val): - self.generator.generator_settings[0].do_sample = val - save_session() + with session_scope() as session: + session.add(self.generator) + self.app.settings_manager.llm_generator_settings.do_sample = val def toggle_leave_model_in_vram(self, val): if val: - self.settings_manager.set_value("unload_unused_model", False) - self.settings_manager.set_value("move_unused_model_to_cpu", False) + self.app.settings_manager.set_value("settings.unload_unused_model", False) + self.app.settings_manager.set_value("settings.move_unused_model_to_cpu", False) def initialize_form(self): - session = get_session() self.ui.prompt_template.blockSignals(True) self.ui.model.blockSignals(True) self.ui.model_version.blockSignals(True) @@ -87,36 +88,38 @@ def initialize_form(self): self.ui.sequences.initialize_properties() self.ui.top_k.initialize_properties() - prompt_templates = [template.name for template in session.query(LLMPromptTemplate).all()] + with session_scope() as session: + prompt_templates = [template.name for template in session.query(LLMPromptTemplate).all()] + model_names = [model.name for model in session.query(LLMGenerator).all()] + self.ui.prompt_template.clear() self.ui.prompt_template.addItems(prompt_templates) - self.ui.leave_in_vram.setChecked(not self.settings_manager.unload_unused_model and not self.settings_manager.move_unused_model_to_cpu) - self.ui.move_to_cpu.setChecked(self.settings_manager.move_unused_model_to_cpu) - self.ui.unload_model.setChecked(self.settings_manager.unload_unused_model) + self.ui.leave_in_vram.setChecked(not self.app.settings_manager.settings.unload_unused_model and not self.app.settings_manager.settings.move_unused_model_to_cpu) + self.ui.move_to_cpu.setChecked(self.app.settings_manager.settings.move_unused_model_to_cpu) + self.ui.unload_model.setChecked(self.app.settings_manager.settings.unload_unused_model) if self.generator: - self.ui.radio_button_2bit.setChecked(self.generator.generator_settings[0].dtype == "2bit") - self.ui.radio_button_4bit.setChecked(self.generator.generator_settings[0].dtype == "4bit") - self.ui.radio_button_8bit.setChecked(self.generator.generator_settings[0].dtype == "8bit") - self.ui.radio_button_16bit.setChecked(self.generator.generator_settings[0].dtype == "16bit") - self.ui.radio_button_32bit.setChecked(self.generator.generator_settings[0].dtype == "32bit") - self.set_dtype_by_gpu( self.generator.generator_settings[0].use_gpu) - self.set_dtype(self.generator.generator_settings[0].dtype) + self.ui.radio_button_2bit.setChecked(self.app.settings_manager.llm_generator_settings.dtype == "2bit") + self.ui.radio_button_4bit.setChecked(self.app.settings_manager.llm_generator_settings.dtype == "4bit") + self.ui.radio_button_8bit.setChecked(self.app.settings_manager.llm_generator_settings.dtype == "8bit") + self.ui.radio_button_16bit.setChecked(self.app.settings_manager.llm_generator_settings.dtype == "16bit") + self.ui.radio_button_32bit.setChecked(self.app.settings_manager.llm_generator_settings.dtype == "32bit") + self.set_dtype_by_gpu( self.app.settings_manager.llm_generator_settings.use_gpu) + self.set_dtype(self.app.settings_manager.llm_generator_settings.dtype) # get unique model names - model_names = [model.name for model in session.query(LLMGenerator).all()] model_names = list(set(model_names)) self.ui.model.clear() self.ui.model.addItems(model_names) self.ui.model.setCurrentText(self.current_generator) self.update_model_version_combobox() if self.generator: - self.ui.model_version.setCurrentText(self.generator.generator_settings[0].model_version) - self.ui.random_seed.setChecked(self.generator.generator_settings[0].random_seed) - self.ui.do_sample.setChecked(self.generator.generator_settings[0].do_sample) - self.ui.early_stopping.setChecked(self.generator.generator_settings[0].early_stopping) - self.ui.use_gpu_checkbox.setChecked(self.generator.generator_settings[0].use_gpu) + self.ui.model_version.setCurrentText(self.app.settings_manager.llm_generator_settings.model_version) + self.ui.random_seed.setChecked(self.app.settings_manager.llm_generator_settings.random_seed) + self.ui.do_sample.setChecked(self.app.settings_manager.llm_generator_settings.do_sample) + self.ui.early_stopping.setChecked(self.app.settings_manager.llm_generator_settings.early_stopping) + self.ui.use_gpu_checkbox.setChecked(self.app.settings_manager.llm_generator_settings.use_gpu) self.ui.override_parameters.setChecked(self.generator.override_parameters) self.ui.model.blockSignals(False) @@ -138,28 +141,31 @@ def initialize_form(self): def model_text_changed(self, val): print("model_text_changed", val) - self.settings_manager.set_value("current_llm_generator", val) + self.app.settings_manager.set_value("settings.current_llm_generator", val) self.update_model_version_combobox() self.model_version_changed(self.ui.model_version.currentText()) self.initialize_form() def model_version_changed(self, val): - self.generator.generator_settings[0].model_version = val - save_session() + with session_scope() as session: + session.add(self.generator) + self.app.settings_manager.llm_generator_settings.model_version = val def toggle_move_model_to_cpu(self, val): - self.settings_manager.set_value("move_unused_model_to_cpu", val) + self.app.settings_manager.set_value("settings.move_unused_model_to_cpu", val) if val: - self.settings_manager.set_value("unload_unused_model", False) + self.app.settings_manager.set_value("settings.unload_unused_model", False) def override_parameters_toggled(self, val): - self.generator.override_parameters = val - save_session() - + with session_scope() as session: + session.add(self.generator) + self.generator.override_parameters = val + def prompt_template_text_changed(self, value): - self.generator.prompt_template = value - save_session() - + with session_scope() as session: + session.add(self.generator) + self.generator.prompt_template = value + def toggled_2bit(self, val): if val: self.set_dtype("2bit") @@ -181,27 +187,30 @@ def toggled_32bit(self, val): self.set_dtype("32bit") def random_seed_toggled(self, val): - self.generator.generator_settings[0].random_seed = val - save_session() - + with session_scope() as session: + session.add(self.generator) + self.app.settings_manager.llm_generator_settings.random_seed = val + def seed_changed(self, val): - self.generator.generator_settings[0].seed = val - save_session() - + with session_scope() as session: + session.add(self.generator) + self.app.settings_manager.llm_generator_settings.seed = val + def toggle_unload_model(self, val): - self.settings_manager.set_value("unload_unused_model", val) + self.app.settings_manager.set_value("settings.unload_unused_model", val) if val: - self.settings_manager.set_value("move_unused_model_to_cpu", False) + self.app.settings_manager.set_value("settings.move_unused_model_to_cpu", False) def use_gpu_toggled(self, val): - self.generator.generator_settings[0].use_gpu = val - # toggle the 16bit radio button and disable 4bit and 8bit radio buttons - self.set_dtype_by_gpu(val) - save_session() + with session_scope() as session: + session.add(self.generator) + self.app.settings_manager.llm_generator_settings.use_gpu = val + # toggle the 16bit radio button and disable 4bit and 8bit radio buttons + self.set_dtype_by_gpu(val) def set_dtype_by_gpu(self, use_gpu): if not use_gpu: - if self.generator.generator_settings[0].dtype in ["2bit","4bit", "8bit"]: + if self.app.settings_manager.llm_generator_settings.dtype in ["2bit","4bit", "8bit"]: self.ui.radio_button_16bit.setChecked(True) self.ui.radio_button_2bit.setEnabled(False) self.ui.radio_button_4bit.setEnabled(False) @@ -212,58 +221,63 @@ def set_dtype_by_gpu(self, use_gpu): self.ui.radio_button_4bit.setEnabled(True) self.ui.radio_button_8bit.setEnabled(True) self.ui.radio_button_32bit.setEnabled(False) - if self.generator.generator_settings[0].dtype == "32bit": + if self.app.settings_manager.llm_generator_settings.dtype == "32bit": self.ui.radio_button_16bit.setChecked(True) def reset_settings_to_default_clicked(self): - self.generator.generator_settings[0].top_p = LLMGeneratorSetting.top_p.default.arg - self.generator.generator_settings[0].max_length = LLMGeneratorSetting.max_length.default.arg - self.generator.generator_settings[0].repetition_penalty = LLMGeneratorSetting.repetition_penalty.default.arg - self.generator.generator_settings[0].min_length = LLMGeneratorSetting.min_length.default.arg - self.generator.generator_settings[0].length_penalty = LLMGeneratorSetting.length_penalty.default.arg - self.generator.generator_settings[0].num_beams = LLMGeneratorSetting.num_beams.default.arg - self.generator.generator_settings[0].ngram_size = LLMGeneratorSetting.ngram_size.default.arg - self.generator.generator_settings[0].temperature = LLMGeneratorSetting.temperature.default.arg - self.generator.generator_settings[0].sequences = LLMGeneratorSetting.sequences.default.arg - self.generator.generator_settings[0].top_k = LLMGeneratorSetting.top_k.default.arg - self.generator.generator_settings[0].eta_cutoff = LLMGeneratorSetting.eta_cutoff.default.arg - self.generator.generator_settings[0].seed = LLMGeneratorSetting.seed.default.arg - self.generator.generator_settings[0].do_sample = LLMGeneratorSetting.do_sample.default.arg - self.generator.generator_settings[0].early_stopping = LLMGeneratorSetting.early_stopping.default.arg - self.generator.generator_settings[0].random_seed = LLMGeneratorSetting.random_seed.default.arg - self.generator.generator_settings[0].model_version = LLMGeneratorSetting.model_version.default.arg - self.generator.generator_settings[0].dtype = LLMGeneratorSetting.dtype.default.arg - self.generator.generator_settings[0].use_gpu = LLMGeneratorSetting.use_gpu.default.arg - save_session() + with session_scope() as session: + session.add(self.app.settings_manager.llm_generator_settings) + session.add(self.generator) + + self.app.settings_manager.llm_generator_settings.top_p = LLMGeneratorSetting.top_p.default.arg + self.app.settings_manager.llm_generator_settings.max_length = LLMGeneratorSetting.max_length.default.arg + self.app.settings_manager.llm_generator_settings.repetition_penalty = LLMGeneratorSetting.repetition_penalty.default.arg + self.app.settings_manager.llm_generator_settings.min_length = LLMGeneratorSetting.min_length.default.arg + self.app.settings_manager.llm_generator_settings.length_penalty = LLMGeneratorSetting.length_penalty.default.arg + self.app.settings_manager.llm_generator_settings.num_beams = LLMGeneratorSetting.num_beams.default.arg + self.app.settings_manager.llm_generator_settings.ngram_size = LLMGeneratorSetting.ngram_size.default.arg + self.app.settings_manager.llm_generator_settings.temperature = LLMGeneratorSetting.temperature.default.arg + self.app.settings_manager.llm_generator_settings.sequences = LLMGeneratorSetting.sequences.default.arg + self.app.settings_manager.llm_generator_settings.top_k = LLMGeneratorSetting.top_k.default.arg + self.app.settings_manager.llm_generator_settings.eta_cutoff = LLMGeneratorSetting.eta_cutoff.default.arg + self.app.settings_manager.llm_generator_settings.seed = LLMGeneratorSetting.seed.default.arg + self.app.settings_manager.llm_generator_settings.do_sample = LLMGeneratorSetting.do_sample.default.arg + self.app.settings_manager.llm_generator_settings.early_stopping = LLMGeneratorSetting.early_stopping.default.arg + self.app.settings_manager.llm_generator_settings.random_seed = LLMGeneratorSetting.random_seed.default.arg + self.app.settings_manager.llm_generator_settings.model_version = LLMGeneratorSetting.model_version.default.arg + self.app.settings_manager.llm_generator_settings.dtype = LLMGeneratorSetting.dtype.default.arg + self.app.settings_manager.llm_generator_settings.use_gpu = LLMGeneratorSetting.use_gpu.default.arg + self.initialize_form() - self.ui.top_p.set_slider_and_spinbox_values(self.generator.generator_settings[0].top_p) - self.ui.max_length.set_slider_and_spinbox_values(self.generator.generator_settings[0].max_length) - self.ui.repetition_penalty.set_slider_and_spinbox_values(self.generator.generator_settings[0].repetition_penalty) - self.ui.min_length.set_slider_and_spinbox_values(self.generator.generator_settings[0].min_length) - self.ui.length_penalty.set_slider_and_spinbox_values(self.generator.generator_settings[0].length_penalty) - self.ui.num_beams.set_slider_and_spinbox_values(self.generator.generator_settings[0].num_beams) - self.ui.ngram_size.set_slider_and_spinbox_values(self.generator.generator_settings[0].ngram_size) - self.ui.temperature.set_slider_and_spinbox_values(self.generator.generator_settings[0].temperature) - self.ui.sequences.set_slider_and_spinbox_values(self.generator.generator_settings[0].sequences) - self.ui.top_k.set_slider_and_spinbox_values(self.generator.generator_settings[0].top_k) - self.ui.eta_cutoff.set_slider_and_spinbox_values(self.generator.generator_settings[0].eta_cutoff) - self.ui.random_seed.setChecked(self.generator.generator_settings[0].random_seed) + self.ui.top_p.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.top_p) + self.ui.max_length.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.max_length) + self.ui.repetition_penalty.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.repetition_penalty) + self.ui.min_length.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.min_length) + self.ui.length_penalty.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.length_penalty) + self.ui.num_beams.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.num_beams) + self.ui.ngram_size.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.ngram_size) + self.ui.temperature.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.temperature) + self.ui.sequences.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.sequences) + self.ui.top_k.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.top_k) + self.ui.eta_cutoff.set_slider_and_spinbox_values(self.app.settings_manager.llm_generator_settings.eta_cutoff) + self.ui.random_seed.setChecked(self.app.settings_manager.llm_generator_settings.random_seed) def set_dtype(self, dtype): - self.generator.generator_settings[0].dtype = dtype - save_session() + with session_scope() as session: + session.add(self.app.settings_manager.llm_generator_settings) + self.app.settings_manager.llm_generator_settings.dtype = dtype self.set_dtype_description(dtype) def set_dtype_description(self, dtype): self.ui.dtype_description.setText(self.dtype_descriptions[dtype]) def update_model_version_combobox(self): - session = get_session() self.ui.model_version.blockSignals(True) self.ui.model_version.clear() - ai_model_paths = [model.path for model in session.query(AIModel).filter( - AIModel.pipeline_action == self.current_generator - )] + with session_scope() as session: + ai_model_paths = [model.path for model in session.query(AIModel).filter( + AIModel.pipeline_action == self.current_generator + )] self.ui.model_version.addItems(ai_model_paths) self.ui.model_version.blockSignals(False) diff --git a/src/airunner/widgets/llm/templates/llm_settings.ui b/src/airunner/widgets/llm/templates/llm_settings.ui index e7129ede0..3e2dacf4d 100644 --- a/src/airunner/widgets/llm/templates/llm_settings.ui +++ b/src/airunner/widgets/llm/templates/llm_settings.ui @@ -216,7 +216,7 @@ true - llm_generator_setting.repetition_penalty + llm_generator.repetition_penalty 0 @@ -262,7 +262,7 @@ false - llm_generator_setting.min_length + llm_generator.min_length 1 @@ -312,7 +312,7 @@ true - llm_generator_setting.top_p + llm_generator.top_p 1 @@ -358,7 +358,7 @@ false - llm_generator_setting.max_length + llm_generator.max_length 1 @@ -445,7 +445,7 @@ false - llm_generator_setting.ngram_size + llm_generator.ngram_size 1 @@ -491,7 +491,7 @@ true - llm_generator_setting.temperature + llm_generator.temperature 1 @@ -541,7 +541,7 @@ true - llm_generator_setting.length_penalty + llm_generator.length_penalty 1 @@ -587,7 +587,7 @@ false - llm_generator_setting.num_beams + llm_generator.num_beams 1 @@ -644,7 +644,7 @@ false - llm_generator_setting.sequences + llm_generator.sequences 1 @@ -690,7 +690,7 @@ false - llm_generator_setting.top_k + llm_generator.top_k 1 diff --git a/src/airunner/widgets/llm/templates/llm_settings_ui.py b/src/airunner/widgets/llm/templates/llm_settings_ui.py index bfb93997b..d16ea205f 100644 --- a/src/airunner/widgets/llm/templates/llm_settings_ui.py +++ b/src/airunner/widgets/llm/templates/llm_settings_ui.py @@ -371,38 +371,38 @@ def retranslateUi(self, llm_settings_widget): self.early_stopping.setText(_translate("llm_settings_widget", "Early stopping")) self.do_sample.setText(_translate("llm_settings_widget", "Do sample")) self.groupBox_11.setTitle(_translate("llm_settings_widget", "Repetition penalty")) - self.repetition_penalty.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.repetition_penalty")) + self.repetition_penalty.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.repetition_penalty")) self.repetition_penalty.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_16.setTitle(_translate("llm_settings_widget", "Min length")) - self.min_length.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.min_length")) + self.min_length.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.min_length")) self.min_length.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_20.setTitle(_translate("llm_settings_widget", "Top P")) - self.top_p.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.top_p")) + self.top_p.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.top_p")) self.top_p.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_21.setTitle(_translate("llm_settings_widget", "Max length")) - self.max_length.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.max_length")) + self.max_length.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.max_length")) self.max_length.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.leave_in_vram.setText(_translate("llm_settings_widget", "Leave in VRAM")) self.move_to_cpu.setText(_translate("llm_settings_widget", "Move to CPU")) self.unload_model.setText(_translate("llm_settings_widget", "Unload model")) self.label_3.setText(_translate("llm_settings_widget", "Model management")) self.groupBox_17.setTitle(_translate("llm_settings_widget", "No repeat ngram size")) - self.ngram_size.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.ngram_size")) + self.ngram_size.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.ngram_size")) self.ngram_size.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_18.setTitle(_translate("llm_settings_widget", "Temperature")) - self.temperature.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.temperature")) + self.temperature.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.temperature")) self.temperature.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_24.setTitle(_translate("llm_settings_widget", "Length penalty")) - self.length_penalty.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.length_penalty")) + self.length_penalty.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.length_penalty")) self.length_penalty.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_25.setTitle(_translate("llm_settings_widget", "Num beams")) - self.num_beams.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.num_beams")) + self.num_beams.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.num_beams")) self.num_beams.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_22.setTitle(_translate("llm_settings_widget", "Sequences to generate")) - self.sequences.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.sequences")) + self.sequences.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.sequences")) self.sequences.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.groupBox_23.setTitle(_translate("llm_settings_widget", "Top k")) - self.top_k.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator_setting.top_k")) + self.top_k.setProperty("settings_property", _translate("llm_settings_widget", "llm_generator.top_k")) self.top_k.setProperty("slider_callback", _translate("llm_settings_widget", "handle_value_change")) self.label_4.setText(_translate("llm_settings_widget", "How to treat model when not in use")) from airunner.widgets.slider.slider_widget import SliderWidget diff --git a/src/airunner/widgets/lora/lora_container_widget.py b/src/airunner/widgets/lora/lora_container_widget.py index 6d8e0fc4d..e344f68ea 100644 --- a/src/airunner/widgets/lora/lora_container_widget.py +++ b/src/airunner/widgets/lora/lora_container_widget.py @@ -3,7 +3,7 @@ from PyQt6.QtWidgets import QWidget, QSizePolicy from airunner.data.models import Lora -from airunner.utils import get_session, save_session +from airunner.data.session_scope import session_scope, path_settings_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.lora.lora_widget import LoraWidget from airunner.widgets.lora.templates.lora_container_ui import Ui_lora_container @@ -23,12 +23,10 @@ def toggle_all(self, val): @property def loras(self): - session = get_session() - available_loras = session.query(Lora).filter( - Lora.name.like(f"%{self.search_filter}%") if self.search_filter != "" else True).all() - if not available_loras or isinstance(available_loras, dict): - return [] - return available_loras + with self.app.settings_manager.loras(self.search_filter) as available_loras: + if not available_loras or isinstance(available_loras, dict): + return [] + return available_loras def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -37,12 +35,9 @@ def __init__(self, *args, **kwargs): self.load_lora() def load_lora(self): - session = get_session() - loras = session.query(Lora).filter( - Lora.name.like(f"%{self.search_filter}%") if self.search_filter != "" else True).all() - - for lora in loras: - self.add_lora(lora) + with self.app.settings_manager.loras(self.search_filter) as loras: + for lora in loras: + self.add_lora(lora) # add spacer to end of self.ui.scrollAreaWidgetContents.layout() if not self.spacer: @@ -55,17 +50,16 @@ def add_lora(self, lora): self.ui.scrollAreaWidgetContents.layout().addWidget(lora_widget) def scan_for_lora(self): - session = get_session() - lora_path = self.settings_manager.path_settings.lora_path - for dirpath, dirnames, filenames in os.walk(lora_path): - # get version from dirpath - version = dirpath.split("/")[-1] - for file in filenames: - if file.endswith(".ckpt") or file.endswith(".safetensors") or file.endswith(".pt"): - name = file.replace(".ckpt", "").replace(".safetensors", "").replace(".pt", "") - lora = Lora(name=name, path=os.path.join(dirpath, file), enabled=True, scale=100.0, version=version) - session.add(lora) - save_session(session) + with session_scope() as session: + lora_path = self.app.settings_manager.path_settings.lora_path + for dirpath, dirnames, filenames in os.walk(lora_path): + # get version from dirpath + version = dirpath.split("/")[-1] + for file in filenames: + if file.endswith(".ckpt") or file.endswith(".safetensors") or file.endswith(".pt"): + name = file.replace(".ckpt", "").replace(".safetensors", "").replace(".pt", "") + lora = Lora(name=name, path=os.path.join(dirpath, file), enabled=True, scale=100.0, version=version) + session.add(lora) def toggle_all_lora(self, checked): for i in range(self.ui.lora_scroll_area.widget().layout().count()): @@ -84,8 +78,8 @@ def available_lora(self, action): return available_lora def get_available_loras(self, tab_name): - base_path = self.settings_manager.path_settings.model_base_path - lora_path = self.settings_manager.lora_path or "lora" + base_path = self.app.settings_manager.path_settings.model_base_path + lora_path = self.app.settings_manager.lora_path or "lora" if lora_path == "lora": lora_path = os.path.join(base_path, lora_path) if not os.path.exists(lora_path): @@ -93,7 +87,7 @@ def get_available_loras(self, tab_name): available_lora = self.loras available_lora = self.get_list_of_available_loras(tab_name, lora_path, lora_names=available_lora) self.loras = available_lora - self.settings_manager.save_settings() + self.app.settings_manager.save_settings() return available_lora def get_list_of_available_loras(self, tab_name, lora_path, lora_names=None): @@ -183,7 +177,7 @@ def handle_lora_trigger_word(self, lora, lora_widget, value): if available_loras[n]["name"] == lora["name"]: available_loras[n]["trigger_word"] = value self.loras = available_loras - self.settings_manager.save_settings() + self.app.settings_manager.save_settings() def toggle_lora(self, lora, value, tab_name): available_loras = self.loras @@ -196,7 +190,7 @@ def toggle_lora(self, lora, value, tab_name): self.total_lora_by_section["enabled"] -= 1 self.update_lora_tab_name(tab_name) self.loras = available_loras - self.settings_manager.save_settings() + self.app.settings_manager.save_settings() def update_lora_tab_name(self, tab_name): # if tab_name not in self.total_lora_by_section: @@ -215,7 +209,7 @@ def handle_lora_slider(self, lora, lora_widget, value, tab_name): available_loras[n]["scale"] = float_val lora_widget.scaleSpinBox.setValue(float_val) self.loras = available_loras - self.settings_manager.save_settings() + self.app.settings_manager.save_settings() def handle_lora_spinbox(self, lora, lora_widget, value, tab_name): available_loras = self.loras @@ -224,7 +218,7 @@ def handle_lora_spinbox(self, lora, lora_widget, value, tab_name): available_loras[n]["scale"] = value lora_widget.scaleSlider.setValue(int(value * 100)) self.loars = available_loras - self.settings_manager.save_settings() + self.app.settings_manager.save_settings() def search_text_changed(self, val): print("search text changed", val) diff --git a/src/airunner/widgets/lora/lora_trigger_word_widget.py b/src/airunner/widgets/lora/lora_trigger_word_widget.py index 91d70b912..265df17b4 100644 --- a/src/airunner/widgets/lora/lora_trigger_word_widget.py +++ b/src/airunner/widgets/lora/lora_trigger_word_widget.py @@ -13,15 +13,15 @@ def __init__(self, *args, **kwargs): self.ui.trigger_word.setText(self.trigger_word) def action_click_button_to_prompt(self): - self.settings_manager.set_value( + self.app.settings_manager.set_value( "generator.prompt", - f"{self.settings_manager.generator.prompt} {self.trigger_word}" + f"{self.app.settings_manager.generator.prompt} {self.trigger_word}" ) def action_click_button_to_negative_prompt(self): - self.settings_manager.set_value( + self.app.settings_manager.set_value( "generator.negative_prompt", - f"{self.settings_manager.generator.negative_prompt} {self.trigger_word}" + f"{self.app.settings_manager.generator.negative_prompt} {self.trigger_word}" ) def action_click_button_copy(self): diff --git a/src/airunner/widgets/lora/lora_widget.py b/src/airunner/widgets/lora/lora_widget.py index 4ddacf116..816207c2c 100644 --- a/src/airunner/widgets/lora/lora_widget.py +++ b/src/airunner/widgets/lora/lora_widget.py @@ -1,47 +1,56 @@ -from airunner.utils import save_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.lora.lora_trigger_word_widget import LoraTriggerWordWidget +from airunner.data.models import Lora from airunner.widgets.lora.templates.lora_ui import Ui_lora +from contextlib import contextmanager class LoraWidget(BaseWidget): widget_class_ = Ui_lora + @contextmanager + def lora(self): + with session_scope() as session: + lora = session.query(Lora).first() + yield lora + def __init__(self, *args, **kwargs): - self.lora = kwargs.pop("lora", None) + self._lora = kwargs.pop("lora", None) super().__init__(*args, **kwargs) - name = self.lora.name - enabled = self.lora.enabled - self.ui.enabledCheckbox.setTitle(name) - self.ui.enabledCheckbox.setChecked(enabled) - self.ui.trigger_word_edit.setText(self.lora.trigger_word) - self.create_trigger_word_widgets() + with self.lora() as lora: + name = lora.name + enabled = lora.enabled + self.ui.enabledCheckbox.setTitle(name) + self.ui.enabledCheckbox.setChecked(enabled) + self.ui.trigger_word_edit.setText(lora.trigger_word) + self.create_trigger_word_widgets(lora) def action_text_changed_trigger_word(self, val): - self.lora.trigger_word = val - save_session() - - def create_trigger_word_widgets(self): + with self.lora() as lora: + lora.trigger_word = val + + def create_trigger_word_widgets(self, lora): for i in reversed(range(self.ui.enabledCheckbox.layout().count())): widget = self.ui.enabledCheckbox.layout().itemAt(i).widget() if isinstance(widget, LoraTriggerWordWidget): widget.deleteLater() - for word in self.lora.trigger_word.split(","): + for word in lora.trigger_word.split(","): if word.strip() == "": continue widget = LoraTriggerWordWidget(trigger_word=word) self.ui.enabledCheckbox.layout().addWidget(widget) def action_changed_trigger_words(self, val): - self.lora.trigger_word = val - save_session() - self.create_trigger_word_widgets() + with self.lora() as lora: + lora.trigger_word = val + self.create_trigger_word_widgets(lora) def action_toggled_lora_enabled(self, val): - self.lora.enabled = val - save_session() - + with self.lora() as lora: + lora.enabled = val + def set_enabled(self, val): - self.ui.enabledCheckbox.setChecked(val) - self.lora.enabled = val - save_session() \ No newline at end of file + with self.lora() as lora: + self.ui.enabledCheckbox.setChecked(val) + lora.enabled = val \ No newline at end of file diff --git a/src/airunner/widgets/memory_preferences/memory_preferences_widget.py b/src/airunner/widgets/memory_preferences/memory_preferences_widget.py index 36f5e2f0e..e860294f9 100644 --- a/src/airunner/widgets/memory_preferences/memory_preferences_widget.py +++ b/src/airunner/widgets/memory_preferences/memory_preferences_widget.py @@ -18,18 +18,18 @@ def __init__(self, **kwargs): self.ui.use_enable_vae_slicing.blockSignals(True) self.ui.use_tome.blockSignals(True) - self.ui.use_accelerated_transformers.setChecked(self.settings_manager.memory_settings.use_accelerated_transformers is True) - self.ui.use_attention_slicing.setChecked(self.settings_manager.memory_settings.use_attention_slicing is True) + self.ui.use_accelerated_transformers.setChecked(self.app.settings_manager.memory_settings.use_accelerated_transformers is True) + self.ui.use_attention_slicing.setChecked(self.app.settings_manager.memory_settings.use_attention_slicing is True) self.ui.use_enable_sequential_cpu_offload.setChecked( - self.settings_manager.memory_settings.use_enable_sequential_cpu_offload is True) + self.app.settings_manager.memory_settings.use_enable_sequential_cpu_offload is True) self.ui.enable_model_cpu_offload.setChecked( - self.settings_manager.memory_settings.enable_model_cpu_offload is True + self.app.settings_manager.memory_settings.enable_model_cpu_offload is True ) - self.ui.use_lastchannels.setChecked(self.settings_manager.memory_settings.use_last_channels is True) - self.ui.use_tf32.setChecked(self.settings_manager.memory_settings.use_tf32 is True) - self.ui.use_tiled_vae.setChecked(self.settings_manager.memory_settings.use_tiled_vae is True) - self.ui.use_enable_vae_slicing.setChecked(self.settings_manager.memory_settings.use_enable_vae_slicing is True) - self.ui.use_tome.setChecked(self.settings_manager.memory_settings.use_tome_sd is True) + self.ui.use_lastchannels.setChecked(self.app.settings_manager.memory_settings.use_last_channels is True) + self.ui.use_tf32.setChecked(self.app.settings_manager.memory_settings.use_tf32 is True) + self.ui.use_tiled_vae.setChecked(self.app.settings_manager.memory_settings.use_tiled_vae is True) + self.ui.use_enable_vae_slicing.setChecked(self.app.settings_manager.memory_settings.use_enable_vae_slicing is True) + self.ui.use_tome.setChecked(self.app.settings_manager.memory_settings.use_tome_sd is True) self.ui.use_accelerated_transformers.blockSignals(False) self.ui.use_attention_slicing.blockSignals(False) @@ -45,31 +45,31 @@ def __init__(self, **kwargs): def action_toggled_tome(self, val): - self.settings_manager.set_value("memory_settings.use_tome_sd", val) + self.app.settings_manager.set_value("memory_settings.use_tome_sd", val) def action_toggled_tile_vae(self, val): - self.settings_manager.set_value("memory_settings.use_tiled_vae", val) + self.app.settings_manager.set_value("memory_settings.use_tiled_vae", val) def action_toggled_tf32(self, val): - self.settings_manager.set_value("memory_settings.use_tf32", val) + self.app.settings_manager.set_value("memory_settings.use_tf32", val) def action_toggled_last_memory(self, val): - self.settings_manager.set_value("memory_settings.use_last_channels", val) + self.app.settings_manager.set_value("memory_settings.use_last_channels", val) def action_toggled_vae_slicing(self, val): - self.settings_manager.set_value("memory_settings.use_enable_vae_slicing", val) + self.app.settings_manager.set_value("memory_settings.use_enable_vae_slicing", val) def action_toggled_sequential_cpu_offload(self, val): - self.settings_manager.set_value("memory_settings.use_enable_sequential_cpu_offload", val) + self.app.settings_manager.set_value("memory_settings.use_enable_sequential_cpu_offload", val) def action_toggled_model_cpu_offload(self, val): - self.settings_manager.set_value("memory_settings.enable_model_cpu_offload", val) + self.app.settings_manager.set_value("memory_settings.enable_model_cpu_offload", val) def action_toggled_attention_slicing(self, val): - self.settings_manager.set_value("memory_settings.use_attention_slicing", val) + self.app.settings_manager.set_value("memory_settings.use_attention_slicing", val) def action_toggled_accelerated_transformers(self, val): - self.settings_manager.set_value("memory_settings.use_accelerated_transformers", val) + self.app.settings_manager.set_value("memory_settings.use_accelerated_transformers", val) def action_button_clicked_optimize_memory_settings(self): self.ui.use_accelerated_transformers.setChecked(True) diff --git a/src/airunner/widgets/model_manager/custom_widget.py b/src/airunner/widgets/model_manager/custom_widget.py index 16c6b0c8f..45bbc861a 100644 --- a/src/airunner/widgets/model_manager/custom_widget.py +++ b/src/airunner/widgets/model_manager/custom_widget.py @@ -2,7 +2,7 @@ from airunner.data.models import AIModel from airunner.models.modeldata import ModelData -from airunner.utils import get_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.model_manager.model_widget import ModelWidget from airunner.widgets.model_manager.templates.custom_ui import Ui_custom_model_widget @@ -26,14 +26,14 @@ def action_button_clicked_scan_for_models(self): def scan_for_models(self): # look at model path and determine if we can import existing local models # first look at all files and folders inside of the model paths - base_model_path = self.settings_manager.path_settings.model_base_path - depth2img_model_path = self.settings_manager.path_settings.depth2img_model_path - pix2pix_model_path = self.settings_manager.path_settings.pix2pix_model_path - outpaint_model_path = self.settings_manager.path_settings.outpaint_model_path - upscale_model_path = self.settings_manager.path_settings.upscale_model_path - txt2vid_model_path = self.settings_manager.path_settings.txt2vid_model_path - llm_casuallm_model_path = self.settings_manager.path_settings.llm_casuallm_model_path - llm_seq2seq_model_path = self.settings_manager.path_settings.llm_seq2seq_model_path + base_model_path = self.app.settings_manager.path_settings.model_base_path + depth2img_model_path = self.app.settings_manager.path_settings.depth2img_model_path + pix2pix_model_path = self.app.settings_manager.path_settings.pix2pix_model_path + outpaint_model_path = self.app.settings_manager.path_settings.outpaint_model_path + upscale_model_path = self.app.settings_manager.path_settings.upscale_model_path + txt2vid_model_path = self.app.settings_manager.path_settings.txt2vid_model_path + llm_casuallm_model_path = self.app.settings_manager.path_settings.llm_casuallm_model_path + llm_seq2seq_model_path = self.app.settings_manager.path_settings.llm_seq2seq_model_path diffusers_folders = ["scheduler", "text_encoder", "tokenizer", "unet", "vae"] for key, model_path in { "txt2img": base_model_path, @@ -62,7 +62,7 @@ def scan_for_models(self): model.category = "stablediffusion" model.enabled = True model.pipeline_action = key - model.pipeline_class = self.settings_manager.get_pipeline_classname( + model.pipeline_class = self.app.settings_manager.get_pipeline_classname( model.pipeline_action, model.version, model.category) if entry.is_file(): # ckpt or safetensors file @@ -87,68 +87,67 @@ def scan_for_models(self): self.update_generator_model_dropdown() def save_model(self, model): - session = get_session() - model_exists = session.query(AIModel).filter_by( - name=model.name, - path=model.path, - branch=model.branch, - version=model.version, - category=model.category, - pipeline_action=model.pipeline_action - ).first() - if not model_exists: - new_model = AIModel( + with session_scope() as session: + model_exists = session.query(AIModel).filter_by( name=model.name, path=model.path, branch=model.branch, version=model.version, category=model.category, - pipeline_action=model.pipeline_action, - enabled=model.enabled, - is_default=False - ) - session.add(new_model) - session.commit() + pipeline_action=model.pipeline_action + ).first() + if not model_exists: + new_model = AIModel( + name=model.name, + path=model.path, + branch=model.branch, + version=model.version, + category=model.category, + pipeline_action=model.pipeline_action, + enabled=model.enabled, + is_default=False + ) + session.add(new_model) spacer = None def show_items_in_scrollarea(self, search=None): if self.spacer: self.ui.scrollAreaWidgetContents.layout().removeItem(self.spacer) - session = get_session() for child in self.ui.scrollAreaWidgetContents.children(): if isinstance(child, ModelWidget): child.deleteLater() - if search: - models = session.query(AIModel).filter_by(is_default=False).filter(AIModel.name.like(f"%{search}%")).all() - else: - models = session.query(AIModel).filter_by(is_default=False).all() - for model_widget in self.model_widgets: - model_widget.deleteLater() - self.model_widgets = [] - for index, model in enumerate(models): - version = model.version - category = model.category - pipeline_action = model.pipeline_action - pipeline_class = self.settings_manager.get_pipeline_classname( - pipeline_action, version, category) - - model_widget = ModelWidget( - path=model.path, - branch=model.branch, - version=version, - category=category, - pipeline_action=pipeline_action, - pipeline_class=pipeline_class, - # prompts=model.prompts, - ) - - model_widget.ui.name.setChecked(model.enabled) - - self.ui.scrollAreaWidgetContents.layout().addWidget( - model_widget) - - self.model_widgets.append(model_widget) + with session_scope() as session: + if search: + models = session.query(AIModel).filter_by(is_default=False).filter(AIModel.name.like(f"%{search}%")).all() + else: + models = session.query(AIModel).filter_by(is_default=False).all() + for model_widget in self.model_widgets: + model_widget.deleteLater() + self.model_widgets = [] + for index, model in enumerate(models): + version = model.version + category = model.category + pipeline_action = model.pipeline_action + pipeline_class = self.app.settings_manager.get_pipeline_classname( + pipeline_action, version, category) + + model_widget = ModelWidget( + path=model.path, + branch=model.branch, + version=version, + category=category, + pipeline_action=pipeline_action, + pipeline_class=pipeline_class, + # prompts=model.prompts, + ) + + model_widget.ui.name.setChecked(model.enabled) + + self.ui.scrollAreaWidgetContents.layout().addWidget( + model_widget) + + self.model_widgets.append(model_widget) if not self.spacer: self.spacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) @@ -156,11 +155,11 @@ def show_items_in_scrollarea(self, search=None): def models_changed(self, key, model, value): model.enabled = True - self.settings_manager.update_model(model) + self.app.settings_manager.update_model(model) self.update_generator_model_dropdown() def handle_delete_model(self, model): - self.settings_manager.delete_model(model) + self.app.settings_manager.delete_model(model) self.show_items_in_scrollarea() self.update_generator_model_dropdown() @@ -177,19 +176,19 @@ def handle_edit_model(self, model, index): self.ui.model_form.category.addItems(categories) self.ui.model_form.category.setCurrentText(model.category) - actions = self.settings_manager.pipeline_actions + actions = self.app.settings_manager.pipeline_actions self.ui.model_form.pipeline_action.clear() self.ui.model_form.pipeline_action.addItems(actions) self.ui.model_form.pipeline_action.setCurrentText(model.pipeline_action) self.ui.model_form.model_name.setText(model.name) - pipeline_class = self.settings_manager.get_pipeline_classname( + pipeline_class = self.app.settings_manager.get_pipeline_classname( model.pipeline_action, model.version, model.category) self.ui.model_form.pipeline_class_line_edit.setText(pipeline_class) self.ui.model_form.enabled.setChecked(True) self.ui.model_form.path_line_edit.setText(model.path) - versions = self.settings_manager.versions + versions = self.app.settings_manager.versions self.ui.model_form.versions.clear() self.ui.model_form.versions.addItems(versions) self.ui.model_form.versions.setCurrentText(model.version) diff --git a/src/airunner/widgets/model_manager/default_widget.py b/src/airunner/widgets/model_manager/default_widget.py index 8455915b6..e6399b4f4 100644 --- a/src/airunner/widgets/model_manager/default_widget.py +++ b/src/airunner/widgets/model_manager/default_widget.py @@ -1,15 +1,13 @@ from PyQt6 import QtCore from airunner.data.models import AIModel -from airunner.utils import get_session, save_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.model_manager.model_widget import ModelWidget from airunner.widgets.model_manager.templates.default_ui import Ui_default_model_widget from PyQt6 import QtWidgets -session = get_session() - class DefaultModelWidget(BaseWidget): widget_class_ = Ui_default_model_widget @@ -20,13 +18,14 @@ def __init__(self, *args, **kwargs): self.show_items_in_scrollarea() # find how many models are set to enabled = FAlse self.ui.toggle_all.blockSignals(True) - disabled_models = session.query(AIModel).filter_by(is_default=True).filter_by(enabled=False).all() - if len(disabled_models) == 0: - self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.Checked) - elif len(disabled_models) < len(session.query(AIModel).filter_by(is_default=True).all()): - self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.PartiallyChecked) - else: - self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.Unchecked) + with session_scope() as session: + disabled_models = session.query(AIModel).filter_by(is_default=True).filter_by(enabled=False).all() + if len(disabled_models) == 0: + self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.Checked) + elif len(disabled_models) < len(session.query(AIModel).filter_by(is_default=True).all()): + self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.PartiallyChecked) + else: + self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.Unchecked) self.ui.toggle_all.blockSignals(False) spacer = None @@ -37,32 +36,33 @@ def show_items_in_scrollarea(self, search=None): for child in self.ui.scrollAreaWidgetContents.children(): if isinstance(child, ModelWidget): child.deleteLater() - if search: - # search by name - models = session.query(AIModel).filter_by(is_default=True).filter(AIModel.name.like(f"%{search}%")).all() - else: - models = session.query(AIModel).filter_by(is_default=True).all() - for model_widget in self.model_widgets: - model_widget.deleteLater() - self.model_widgets = [] - for index, model in enumerate(models): - version = model.version - category = model.category - pipeline_action = model.pipeline_action - pipeline_class = self.settings_manager.get_pipeline_classname(pipeline_action, version, category) - model_widget = ModelWidget( - path=model.path, - branch=model.branch, - version=version, - category=category, - pipeline_action=pipeline_action, - pipeline_class=pipeline_class, - ) - model_widget.ui.delete_button.hide() - model_widget.ui.edit_button.deleteLater() - model_widget.ui.name.setChecked(model.enabled) - self.ui.scrollAreaWidgetContents.layout().addWidget(model_widget) - self.model_widgets.append(model_widget) + with session_scope() as session: + if search: + # search by name + models = session.query(AIModel).filter_by(is_default=True).filter(AIModel.name.like(f"%{search}%")).all() + else: + models = session.query(AIModel).filter_by(is_default=True).all() + for model_widget in self.model_widgets: + model_widget.deleteLater() + self.model_widgets = [] + for index, model in enumerate(models): + version = model.version + category = model.category + pipeline_action = model.pipeline_action + pipeline_class = self.app.settings_manager.get_pipeline_classname(pipeline_action, version, category) + model_widget = ModelWidget( + path=model.path, + branch=model.branch, + version=version, + category=category, + pipeline_action=pipeline_action, + pipeline_class=pipeline_class, + ) + model_widget.ui.delete_button.hide() + model_widget.ui.edit_button.deleteLater() + model_widget.ui.name.setChecked(model.enabled) + self.ui.scrollAreaWidgetContents.layout().addWidget(model_widget) + self.model_widgets.append(model_widget) if not self.spacer: self.spacer = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.ui.scrollAreaWidgetContents.layout().addItem(self.spacer) @@ -73,15 +73,15 @@ def mode_type_changed(self, val): def toggle_all_state_change(self, val: int): if val == 0: # disable all by setting AIModel.enabled to False where is_default=True - session.query(AIModel).filter_by(is_default=True).update({"enabled": False}) - save_session() + with session_scope() as session: + session.query(AIModel).filter_by(is_default=True).update({"enabled": False}) self.show_items_in_scrollarea() elif val == 1: # self.ui.toggle_all is a checkbox with tri-state enabled, how can we set it to checked? self.ui.toggle_all.setCheckState(QtCore.Qt.CheckState.Checked) elif val == 2: - session.query(AIModel).filter_by(is_default=True).update({"enabled": True}) - save_session() + with session_scope() as session: + session.query(AIModel).filter_by(is_default=True).update({"enabled": True}) self.show_items_in_scrollarea() diff --git a/src/airunner/widgets/model_manager/import_widget.py b/src/airunner/widgets/model_manager/import_widget.py index ec72846f3..bc3b60502 100644 --- a/src/airunner/widgets/model_manager/import_widget.py +++ b/src/airunner/widgets/model_manager/import_widget.py @@ -1,7 +1,7 @@ import threading from airunner.data.models import AIModel, Lora, Embedding -from airunner.utils import get_session +from airunner.data.session_scope import session_scope from airunner.widgets.base_widget import BaseWidget from airunner.widgets.model_manager.templates.import_ui import Ui_import_model_widget from airunner.aihandler.download_civitai import DownloadCivitAI @@ -54,92 +54,82 @@ def download_model(self): name = model_data["name"] + " " + model_version["name"] model_version_name = model_version["name"] - categories = self.settings_manager.model_categories - actions = self.settings_manager.pipeline_actions + categories = self.app.settings_manager.model_categories + actions = self.app.settings_manager.pipeline_actions category = "stablediffusion" pipeline_action = "txt2img" if "inpaint" in model_version_name: pipeline_action = "outpaint" diffuser_model_version = model_version["baseModel"] - pipeline_class = self.settings_manager.get_pipeline_classname(pipeline_action, diffuser_model_version, category) - diffuser_model_versions = self.settings_manager.model_versions + pipeline_class = self.app.settings_manager.get_pipeline_classname(pipeline_action, diffuser_model_version, category) + diffuser_model_versions = self.app.settings_manager.model_versions model_type = model_data["type"] file_path = self.download_path(file, diffuser_model_version, pipeline_action, model_type) # path is the download path of the model - print("Name", name) - print("Path", file_path) - print("Branch", "main") - print("Version", diffuser_model_version) - print("Category", category) - print("Pipeline Action", pipeline_action) trained_words = model_version.get("trainedWords", []) if isinstance(trained_words, str): trained_words = [trained_words] trained_words = ",".join(trained_words) - - session = get_session() - if model_type == "Checkpoint": - model_exists = session.query(AIModel).filter_by( - name=name, - path=file_path, - branch="main", - version=diffuser_model_version, - category=category, - pipeline_action=pipeline_action, - ).first() - if not model_exists: - new_model = AIModel( + with session_scope() as session: + if model_type == "Checkpoint": + model_exists = session.query(AIModel).filter_by( name=name, path=file_path, branch="main", version=diffuser_model_version, category=category, pipeline_action=pipeline_action, - enabled=True, - is_default=False - ) - session.add(new_model) - session.commit() - elif model_type == "LORA": - lora_exists = session.query(Lora).filter_by( - name=name, - path=file_path, - ).first() - if not lora_exists: - new_lora = Lora( + ).first() + if not model_exists: + new_model = AIModel( + name=name, + path=file_path, + branch="main", + version=diffuser_model_version, + category=category, + pipeline_action=pipeline_action, + enabled=True, + is_default=False + ) + session.add(new_model) + elif model_type == "LORA": + lora_exists = session.query(Lora).filter_by( name=name, path=file_path, - scale=1, - enabled=True, - loaded=False, - trigger_word=trained_words, - ) - session.add(new_lora) - session.commit() - elif model_type == "TextualInversion": - name = file_path.split("/")[-1].split(".")[0] - embedding_exists = session.query(Embedding).filter_by( - name=name, - path=file_path, - ).first() - if not embedding_exists: - new_embedding = Embedding( + ).first() + if not lora_exists: + new_lora = Lora( + name=name, + path=file_path, + scale=1, + enabled=True, + loaded=False, + trigger_word=trained_words, + ) + session.add(new_lora) + elif model_type == "TextualInversion": + name = file_path.split("/")[-1].split(".")[0] + embedding_exists = session.query(Embedding).filter_by( name=name, path=file_path, - active=True, - tags=trained_words, - ) - session.add(new_embedding) - session.commit() - elif model_type == "VAE": - # todo save vae here - pass - elif model_type == "Controlnet": - # todo save controlnet here - pass - elif model_type == "Poses": - # todo save poses here - pass + ).first() + if not embedding_exists: + new_embedding = Embedding( + name=name, + path=file_path, + active=True, + tags=trained_words, + ) + session.add(new_embedding) + elif model_type == "VAE": + # todo save vae here + pass + elif model_type == "Controlnet": + # todo save controlnet here + pass + elif model_type == "Poses": + # todo save poses here + pass print("starting download") self.download_model_thread(download_url, file_path, size_kb) @@ -154,7 +144,7 @@ def download_callback(self, current_size, total_size): self.ui.download_progress_bar.setValue(current_size) if current_size >= total_size: self.reset_form() - self.settings_manager.add_model(self.current_model_data) + self.app.settings_manager.add_model(self.current_model_data) self.show_items_in_scrollarea() def import_models(self): @@ -215,20 +205,20 @@ def model_version_changed(self, index): def download_path(self, file, version, pipeline_action, model_type): if model_type == "LORA": - path = self.settings_manager.path_settings.lora_model_path + path = self.app.settings_manager.path_settings.lora_model_path elif model_type == "Checkpoint": if pipeline_action == "txt2img": - path = self.settings_manager.path_settings.txt2img_model_path + path = self.app.settings_manager.path_settings.txt2img_model_path elif pipeline_action == "outpaint": - path = self.settings_manager.path_settings.outpaint_model_path + path = self.app.settings_manager.path_settings.outpaint_model_path elif pipeline_action == "upscale": - path = self.settings_manager.path_settings.upscale_model_path + path = self.app.settings_manager.path_settings.upscale_model_path elif pipeline_action == "depth2img": - path = self.settings_manager.path_settings.depth2img_model_path + path = self.app.settings_manager.path_settings.depth2img_model_path elif pipeline_action == "pix2pix": - path = self.settings_manager.path_settings.pix2pix_model_path + path = self.app.settings_manager.path_settings.pix2pix_model_path elif model_type == "TextualInversion": - path = self.settings_manager.path_settings.embeddings_model_path + path = self.app.settings_manager.path_settings.embeddings_model_path elif model_type == "VAE": # todo save vae here pass @@ -249,15 +239,15 @@ def set_model_form_data(self): return model_version_name = model_version["name"] - categories = self.settings_manager.model_categories - actions = self.settings_manager.pipeline_actions + categories = self.app.settings_manager.model_categories + actions = self.app.settings_manager.pipeline_actions category = "stablediffusion" pipeline_action = "txt2img" if "inpaint" in model_version_name: pipeline_action = "outpaint" diffuser_model_version = model_version["baseModel"] - pipeline_class = self.settings_manager.get_pipeline_classname(pipeline_action, diffuser_model_version, category) - diffuser_model_versions = self.settings_manager.model_versions + pipeline_class = self.app.settings_manager.get_pipeline_classname(pipeline_action, diffuser_model_version, category) + diffuser_model_versions = self.app.settings_manager.model_versions path = self.download_path(file, diffuser_model_version, pipeline_action, self.current_model_data["type"]) # path is the download path of the model self.ui.model_form.set_model_form_data( diff --git a/src/airunner/widgets/paths/path_widget.py b/src/airunner/widgets/paths/path_widget.py index e6e5b5a03..ea4b66ee2 100644 --- a/src/airunner/widgets/paths/path_widget.py +++ b/src/airunner/widgets/paths/path_widget.py @@ -25,7 +25,7 @@ def path_name(self): @property def path(self): return getattr( - self.settings_manager.path_settings, f"{self.path_name}") + self.app.settings_manager.path_settings, f"{self.path_name}") def initialize(self): self.ui.title_label.setText(self.title) @@ -42,7 +42,7 @@ def action_path_changed(self, text): def action_button_clicked(self): path = self.path if not os.path.exists(path): - path = self.settings_manager.path_settings.model_base_path + path = self.app.settings_manager.path_settings.model_base_path if not os.path.exists(path): path = os.path.expanduser("~") path = QFileDialog.getExistingDirectory( @@ -56,7 +56,7 @@ def auto_discover(self): home = os.path.expanduser("~") - base_path = self.settings_manager.path_settings.base_path + base_path = self.app.settings_manager.path_settings.base_path if base_path == "": base_path = os.path.join(home, "airunner") @@ -67,5 +67,5 @@ def auto_discover(self): def set_path(self, path): self.ui.path.setText(path) - self.settings_manager.set_value( + self.app.settings_manager.set_value( f"path_settings.{self.path_name}", path) diff --git a/src/airunner/widgets/paths/paths_widget.py b/src/airunner/widgets/paths/paths_widget.py index 15a56c48a..8b6296324 100644 --- a/src/airunner/widgets/paths/paths_widget.py +++ b/src/airunner/widgets/paths/paths_widget.py @@ -11,7 +11,7 @@ def __init__(self, **kwargs): self.initialize_widgets() def action_button_clicked_reset(self): - self.settings_manager.path_settings.reset_paths() + self.app.settings_manager.path_settings.reset_paths() self.initialize_widgets() def initialize_widgets(self): diff --git a/src/airunner/widgets/prompt_builder/__init__.py b/src/airunner/widgets/prompt_builder/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/airunner/widgets/prompt_builder/prompt_builder_form_widget.py b/src/airunner/widgets/prompt_builder/prompt_builder_form_widget.py deleted file mode 100644 index 2959d6638..000000000 --- a/src/airunner/widgets/prompt_builder/prompt_builder_form_widget.py +++ /dev/null @@ -1,369 +0,0 @@ -import json -import random -from functools import partial -from PyQt6 import uic -from PyQt6.QtWidgets import QGridLayout, QSpacerItem, QSizePolicy - -from airunner.widgets.base_widget import BaseWidget -from airunner.widgets.prompt_builder.templates.prompt_builder_form_ui import Ui_prompt_builder_form -from airunner.data.models import PromptVariableCategory, PromptCategory, PromptVariable, Prompt -from airunner.utils import get_session - -class PromptBuilderForm(BaseWidget): - widget_class_ = Ui_prompt_builder_form - prompt_types = None - unprocessed_prompts = {} - - # this is the parent tab widget which initializes this widget - prompt_builder_widget = None - - @property - def prompt_data(self): - return self.prompt_builder_widget.prompt_data - - def process_prompt(self): - """ - A pass-through function for the prompt builder widget to call - :return: - """ - self.parent.process_prompt() - - def __init__(self, *args, **kwargs): - self.prompt_builder_widget = kwargs.pop("prompt_builder_widget") - super().__init__(*args, **kwargs) - self.parent = kwargs.get("parent") - self.scroll_layout = QGridLayout(self.ui.scrollArea.widget()) - self.initialize_category_dropdowns() - self.initialize_genre_dropdowns() - self.initialize_color_dropdowns() - self.initialize_style_dropdowns() - self.initialize_dropdown_values() - self.initialize_prefix_suffix_inputs() - self.initialize_buttons() - self.ui.scrollArea.show() - - def variables_by_category(self, name, prompt_category_name=None): - session = get_session() - #prompt_category = session.query(PromptCategory).filter_by(name=prompt_category_name).first() - variable_category = session.query(PromptVariableCategory).filter_by(name=name).first() - variable_objects = session.query(PromptVariable).filter_by( - #prompt_category=prompt_category, - variable_category=variable_category - ).all() - return list(filter(None, [v.value for v in variable_objects])) - - def prompts_by_category(self, name): - session = get_session() - category = session.query(PromptCategory).filter_by(name=name).first() - prompt_objects = session.query(Prompt).filter_by(category=category).all() - return list(filter(None, [p.name for p in prompt_objects])) - - def category_text_changed(self, val): - session = get_session() - prompt_category = session.query(PromptCategory).filter_by(name=val).first() - if prompt_category: - self.prompt_data.change_prompt(prompt_category.id) - self.prompt_generator_category = val - self.set_prompts("advanced") - - def style_text_changed(self, val): - self.set_style() - - def genre_text_changed(self, val): - self.set_genre() - - def color_text_changed(self, val): - self.set_color() - - def initialize_category_dropdowns(self): - # initialize category dropdowns - self.prompt_category_current_index = 0 - self.ui.prompt_category.blockSignals(True) - self.ui.prompt_category.addItems(self.variables_by_category("composition_category")) - self.ui.prompt_category.lineEdit().setReadOnly(True) - self.ui.prompt_category.blockSignals(False) - - def initialize_genre_dropdowns(self): - # initialize genre dropdowns - self.ui.prompt_genre.blockSignals(True) - self.ui.prompt_genre.addItems(self.variables_by_category("composition_genre")) - self.ui.prompt_genre.lineEdit().setReadOnly(True) - self.ui.prompt_genre.blockSignals(False) - - def initialize_color_dropdowns(self): - # initialize color dropdowns - self.ui.prompt_color.blockSignals(True) - self.ui.prompt_color.addItems(self.variables_by_category("composition_color")) - self.ui.prompt_color.lineEdit().setReadOnly(True) - self.ui.prompt_color.blockSignals(False) - - def initialize_style_dropdowns(self): - # initialize style dropdowns - self.ui.prompt_style.blockSignals(True) - self.ui.prompt_style.addItems(self.variables_by_category("composition_style")) - self.ui.prompt_style.lineEdit().setReadOnly(True) - self.ui.prompt_style.blockSignals(False) - - def initialize_dropdown_values(self): - # check for index in - prompt_category = self.settings_manager.current_prompt_generator_settings.category - prompt_genre = self.settings_manager.current_prompt_generator_settings.prompt_genre - prompt_color = self.settings_manager.current_prompt_generator_settings.prompt_color - prompt_style = self.settings_manager.current_prompt_generator_settings.prompt_style - - # initialize dropdown values - prompt_category_index = self.ui.prompt_category.findText(prompt_category) - prompt_genre_index = self.ui.prompt_genre.findText(prompt_genre) - prompt_color_index = self.ui.prompt_color.findText(prompt_color) - prompt_style_index = self.ui.prompt_style.findText(prompt_style) - self.ui.prompt_category.setCurrentIndex(prompt_category_index) - self.ui.prompt_genre.setCurrentIndex(prompt_genre_index) - self.ui.prompt_color.setCurrentIndex(prompt_color_index) - self.ui.prompt_style.setCurrentIndex(prompt_style_index) - - def initialize_prefix_suffix_inputs(self): - self.ui.prompt_prefix.setText(self.settings_manager.current_prompt_generator_settings.prefix) - self.ui.prompt_suffix.setText(self.settings_manager.current_prompt_generator_settings.suffix) - self.ui.prompt_prefix.textChanged.connect(self.handle_prompt_prefix_change) - self.ui.prompt_suffix.textChanged.connect(self.handle_prompt_suffix_change) - - self.ui.negative_prompt_prefix.setText(self.settings_manager.current_prompt_generator_settings.negative_prefix) - self.ui.negative_prompt_suffix.setText(self.settings_manager.current_prompt_generator_settings.negative_suffix) - self.ui.negative_prompt_prefix.textChanged.connect(self.handle_negative_prompt_prefix_change) - self.ui.negative_prompt_suffix.textChanged.connect(self.handle_negative_prompt_suffix_change) - - def handle_prompt_prefix_change(self, text): - self.settings_manager.set_value("current_prompt_generator_settings.prefix", text) - self.process_prompt() - - def handle_prompt_suffix_change(self, text): - self.settings_manager.set_value("current_prompt_generator_settings.suffix", text) - self.process_prompt() - - def handle_negative_prompt_prefix_change(self, text): - self.settings_manager.set_value("current_prompt_generator_settings.negative_prompt_generator_prefix", text) - self.process_prompt() - - def handle_negative_prompt_suffix_change(self, text): - self.settings_manager.set_value("current_prompt_generator_settings.negative_prompt_generator_suffix", text) - self.process_prompt() - - def initialize_buttons(self): - # initialize buttons - self.ui.randomize_values_button.clicked.connect(self.randomize_values) - self.ui.values_to_random_button.clicked.connect(self.values_to_random) - self.ui.reset_weights_button.clicked.connect(self.reset_weights) - self.ui.clear_values_button.clicked.connect(self.clear_values) - self.set_prompts("advanced") - - def randomize_values(self): - for i in reversed(range(self.scroll_layout.count())): - widget = self.scroll_layout.itemAt(i).widget() - if widget is not None: - widget.combobox.setCurrentIndex(random.randrange(0, widget.combobox.count())) - - def values_to_random(self): - for i in reversed(range(self.scroll_layout.count())): - widget = self.scroll_layout.itemAt(i).widget() - if widget is not None: - widget.combobox.setCurrentIndex(1) - - def clear_values(self): - for i in reversed(range(self.scroll_layout.count())): - widget = self.scroll_layout.itemAt(i).widget() - if widget is not None: - widget.combobox.setCurrentIndex(0) - - def reset_weights(self): - category = self.ui.prompt_category.currentText() - for i in reversed(range(self.scroll_layout.count())): - widget = self.scroll_layout.itemAt(i).widget() - if widget is not None: - variable = widget.label.text().lower() - try: - weight = self.prompt_data.variable_weights_by_category(category, variable) - widget.spinbox.setValue(weight) - except Exception as e: - print(e) - - def clear_scroll_grid(self): - for i in reversed(range(self.scroll_layout.count())): - widget = self.scroll_layout.itemAt(i).widget() - if widget: - widget.setParent(None) - - def populate_prompt_widgets(self, category): - if category == "": - return - # clear items from self.scroll_grid - self.clear_scroll_grid() - index = 0 - for variable_category, weight in self.prompt_data.data["categories"][category]["weights"].items(): - self.create_prompt_widget(category, variable_category, weight, index) - index+=1 - spacer = QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) - total_rows = self.scroll_layout.layout().rowCount() - self.scroll_layout.layout().addItem(spacer, total_rows+1, 0) - - # session = get_session() - - # print("*"*80) - # print("populate_prompt_widgets") - - # prompt_category = session.query(PromptCategory).filter_by(name=category).first() - - # # select unique ids - # prompt_variable_category_ids = session.query(PromptVariable.variable_category_id).filter_by( - # prompt_category_id=prompt_category.id - # ).distinct().all() - # prompt_variable_category_ids = [i[0] for i in prompt_variable_category_ids] - - - # prompt_variable_categories = session.query(PromptVariableCategory).filter( - # PromptVariableCategory.id.in_(prompt_variable_category_ids) - # ).all() - - # prompt_variable_category = None - # for index, prompt_variable_category in enumerate(prompt_variable_categories): - # weights = session.query(PromptVariableCategoryWeight).filter_by( - # prompt_category_id=prompt_category.id, - # variable_category_id=prompt_variable_category.id - # ).all() - # # for index, variable in enumerate(prompt_variables): - # # # weighted_value = { - # # # "value": "", - # # # "weight": self.settings_manager.variable_weights_by_category(category, variable).weight - # # # } - # weighted_value = dict( - # value="", - # weight=1.0 - # ) - # # for w in weights: - # # if w.prompt_category_id == variable.prompt_category_id and w.variable_category_id == variable.variable_category_id: - # # weighted_value["weight"] = w.weight - # # break - # self.create_prompt_widget(prompt_variable_category.name, prompt_variable_category.name, weighted_value, index) - - - # print("*"*80) - - # # try: - # # vars = {} - # # category_name = "" - # # for index, variable in enumerate(self.settings_manager.variables_by_prompt_category(category)): - # # if variable.prompt_category_id not in vars: - # # vars[variable.prompt_category_id] = [] - # # for cat in prompt_variable_categories: - # # if cat.id == variable.prompt_category_id: - # # category_name = cat.name - # # if category in data and variable in data[category]: - # # weighted_value = data[category][variable] - # # else: - # # weighted_value = { - # # "value": "", - # # "weight": self.settings_manager.variable_weights_by_category(category, variable).weight - # # } - # # vars[variable.prompt_category_id].append(dict( - # # weighted_value=weighted_value, - # # category_name=category_name, - # # )) - # # self.create_prompt_widget(category_name, variable, weighted_value, index) - # # except KeyError: - # # pass - # spacer = QSpacerItem(0, 0, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding) - # total_rows = self.scroll_layout.layout().rowCount() - # self.scroll_layout.layout().addItem(spacer, total_rows+1, 0) - - def create_prompt_widget(self, category, variable_category, weight, index): - widget = uic.loadUi(f"widgets/prompt_builder/templates/prompt_builder_variable_widget.ui") - widget.label.setText(variable_category.capitalize()) - - # set default weights - widget.spinbox.setValue(weight) - widget.spinbox.valueChanged.connect(partial( - self.handle_weight_spinbox_change, category, variable_category, widget)) - items = self.prompt_data.data["categories"][category]["variables"][variable_category] - if isinstance(items, dict): - if items["type"] == "range": - items = [str(n) for n in range(items["min"], items["max"] + 1)] - self.prompt_data.set_variable_values_by_category(category, variable_category, items) - else: - items.sort() - # do not scroll the slider on mouse wheel, instead scroll the scroll area - widget.combobox.addItems(["", "Random"] + items) - try: - widget.combobox.setCurrentText(weight["value"]) - except Exception as e: - pass - widget.combobox.currentIndexChanged.connect(partial( - self.handle_combobox_change, category, variable_category, widget)) - # prevent widget.combobox from being edited, but leave it editable - widget.combobox.lineEdit().setReadOnly(True) - self.scroll_layout.layout().addWidget(widget, index // 2, index % 2, 1, 1) - - def weighted_values(self, category, variable): - data = json.loads(self.settings_manager.current_prompt_generator_settings.weighted_values) if not isinstance(self.settings_manager.current_prompt_generator_settings.weighted_values, dict) else self.settings_manager.current_prompt_generator_settings.weighted_values - if category not in data: - data[category] = {} - if variable not in data[category]: - data[category][variable] = {} - return data - - def handle_combobox_change(self, category, variable, widget): - data = self.weighted_values(category, variable) - value = widget.combobox.currentText() - data[category][variable]["value"] = value - data[category][variable]["weight"] = self.prompt_data.variable_weights_by_category(category, variable) - print("setting current_prompt_generator_settings.weighted_values", data) - # convert data to json string - data = json.dumps(data) - self.settings_manager.set_value("current_prompt_generator_settings.weighted_values", data) - self.process_prompt() - - def handle_weight_spinbox_change(self, category, variable, widget, value): - data = self.weighted_values(category, variable) - value = round(value, 2) - data[category][variable]["weight"] = value - self.settings_manager.set_value("current_prompt_generator_settings.weighted_values", data) - self.process_prompt() - - def update_weight_spinbox(self, category, variable, widget): - data = self.weighted_values(category, variable) - widget.spinbox.setValue(data[category][variable]["weight"]) - self.process_prompt() - - def set_prompts(self, prompt_type): - category = self.ui.prompt_category.currentText() - try: - prompts = list(self.prompts_by_category(category)) - except KeyError: - prompts = [] - self.prompt_types = prompts - self.settings_manager.set_value("current_prompt_generator_settings.category", category) - - try: - self.settings_manager.set_value("current_prompt_generator_settings.prompt", prompts[0]) - - except IndexError: - pass - if prompt_type == "advanced": - self.populate_prompt_widgets(category) - self.process_prompt() - - def set_style(self): - self.settings_manager.set_value( - "current_prompt_generator_settings.prompt_style", - self.ui.prompt_style.currentText()) - self.process_prompt() - - def set_color(self): - self.settings_manager.set_value( - "current_prompt_generator_settings.prompt_color", - self.ui.prompt_color.currentText()) - self.process_prompt() - - def set_genre(self): - self.settings_manager.set_value( - "current_prompt_generator_settings.prompt_genre", - self.ui.prompt_genre.currentText()) - self.process_prompt() diff --git a/src/airunner/widgets/prompt_builder/prompt_builder_widget.py b/src/airunner/widgets/prompt_builder/prompt_builder_widget.py deleted file mode 100644 index 58326ad8f..000000000 --- a/src/airunner/widgets/prompt_builder/prompt_builder_widget.py +++ /dev/null @@ -1,327 +0,0 @@ -import random - -from airunner.aihandler.settings import MAX_SEED -from airunner.data.models import TabSection, PromptBuilder -from airunner.utils import save_session, get_session -from airunner.widgets.base_widget import BaseWidget -from airunner.widgets.prompt_builder.prompt_builder_form_widget import PromptBuilderForm -from airunner.widgets.prompt_builder.templates.prompt_builder_ui import Ui_prompt_builder -from airunner.prompt_builder.prompt_data import PromptData - - -class PromptBuilderWidget(BaseWidget): - widget_class_ = Ui_prompt_builder - prompt_data = None - prompt_types = None - unprocessed_prompts = {} - current_tab = "a" - current_tab_index = 0 - - prompt_generator_settings = [] - - @property - def prompt_generator_setting(self): - return self.prompt_generator_settings[self.current_tab_index] - - @property - def auto_prompt_weight(self): - return self.prompt_generator_setting.auto_prompt_weight - - @auto_prompt_weight.setter - def auto_prompt_weight(self, val): - self.prompt_generator_setting.auto_prompt_weight = val - save_session() - - @property - def text_prompt_weight(self): - return self.prompt_generator_setting.text_prompt_weight - - @text_prompt_weight.setter - def text_prompt_weight(self, val): - self.prompt_generator_setting.text_prompt_weight = val - save_session() - - @property - def negative_auto_prompt_weight(self): - return self.prompt_generator_setting.negative_auto_prompt_weight - - @negative_auto_prompt_weight.setter - def negative_auto_prompt_weight(self, val): - self.prompt_generator_setting.negative_auto_prompt_weight = val - save_session() - - @property - def negative_text_prompt_weight(self): - return self.prompt_generator_setting.negative_text_prompt_weight - - @negative_text_prompt_weight.setter - def negative_text_prompt_weight(self, val): - self.prompt_generator_setting.negative_text_prompt_weight = val - save_session() - - @property - def prompt_generator_category(self): - return self.settings_manager.current_prompt_generator_settings.category - - @prompt_generator_category.setter - def prompt_generator_category(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.category", value) - - @property - def prompt_generator_prompt(self): - return self.settings_manager.current_prompt_generator_settings.prompt - - @prompt_generator_prompt.setter - def prompt_generator_prompt(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.prompt", value) - - @property - def prompt_generator_weighted_values(self): - return self.settings_manager.current_prompt_generator_settings.weighted_values - - @prompt_generator_weighted_values.setter - def prompt_generator_weighted_values(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.weighted_values", value) - - @property - def prompt_generator_prompt_genre(self): - return self.settings_manager.current_prompt_generator_settings.prompt_genre - - @prompt_generator_prompt_genre.setter - def prompt_generator_prompt_genre(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.prompt_genre", value) - - @property - def prompt_generator_prompt_color(self): - return self.settings_manager.current_prompt_generator_settings.prompt_color - - @prompt_generator_prompt_color.setter - def prompt_generator_prompt_color(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.prompt_color", value) - - @property - def prompt_generator_prompt_style(self): - return self.settings_manager.current_prompt_generator_settings.prompt_style - - @prompt_generator_prompt_style.setter - def prompt_generator_prompt_style(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.prompt_style", value) - - @property - def prompt_generator_prefix(self): - return self.settings_manager.current_prompt_generator_settings.prefix - - @prompt_generator_prefix.setter - def prompt_generator_prefix(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.prefix", value) - - @property - def prompt_generator_suffix(self): - return self.settings_manager.current_prompt_generator_settings.suffix - - @prompt_generator_suffix.setter - def prompt_generator_suffix(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.suffix", value) - - @property - def negative_prompt_generator_prefix(self): - return self.settings_manager.current_prompt_generator_settings.negative_prefix - - @negative_prompt_generator_prefix.setter - def negative_prompt_generator_prefix(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.negative_prefix", value) - - @property - def negative_prompt_generator_suffix(self): - return self.settings_manager.current_prompt_generator_settings.negative_suffix - - @negative_prompt_generator_suffix.setter - def negative_prompt_generator_suffix(self, value): - self.settings_manager.set_value("current_prompt_generator_settings.negative_suffix", value) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - session = get_session() - self.prompt_generator_settings = session.query(PromptBuilder).all() - ts = session.query(TabSection).filter(TabSection.panel == "prompt_builder.ui.tabs").first() - self.ui.tabs.blockSignals(True) - self.prompt_data = PromptData(prompt_id=1, use_prompt_builder=True)#session.query(Prompt).all() - # print self.prompt_data as a dict - self.initialize_tab_forms() - self.ui.tabs.setCurrentIndex(int(ts.active_tab)) - self.ui.tabs.blockSignals(False) - - prompt_builder_forms = [] - - def initialize_tab_forms(self): - """ - Prompt blender allows multiple generated prompts to be blended together. - This function initializes the tab forms for each prompt blender tab. - :return: - """ - for prompt_builder_settings in self.settings_manager.prompt_generator_settings: - form = PromptBuilderForm( - parent=self, - prompt_builder_widget=self) - form.initialize_dropdown_values() - form.ui.prompt_blend_type.setCurrentIndex( - self.settings_manager.current_prompt_generator_settings.prompt_blend_type) - form.ui.prompt_blend_type.currentIndexChanged.connect( - self.handle_prompt_blend_type_change) - self.prompt_builder_forms.append(form) - self.ui.tabs.addTab(form, prompt_builder_settings.name) - - # on self.tabs change, update the prompt builder form - self.ui.tabs.currentChanged.connect(self.handle_tab_changed) - - self.initialize_weight_sliders() - self.initialize_weights() - - self.update_blend_sliders() - - def handle_tab_changed(self): - self.current_tab = "a" if self.ui.tabs.currentIndex() == 0 else "b" - self.process_prompt() - - def handle_prompt_blend_type_change(self, index): - self.settings_manager.set_value("current_prompt_generator_settings.prompt_blend_type", index) - self.update_blend_sliders() - self.process_prompt() - - def update_blend_sliders(self): - for form in self.prompt_builder_forms: - form.ui.prompt_weight_distribution_slider.setEnabled(self.settings_manager.prompt_blend_type != 0) - form.ui.negative_prompt_weight_distribution_slider.setEnabled(self.settings_manager.prompt_blend_type != 0) - - def initialize_weights(self): - auto_prompt_weight = self.auto_prompt_weight - auto_negative_prompt_weight = self.settings_manager.negative_auto_prompt_weight - auto_prompt_weight = 0.0 if auto_prompt_weight is None else auto_prompt_weight - auto_negative_prompt_weight = 0.0 if auto_negative_prompt_weight is None else auto_negative_prompt_weight - - for form in self.prompt_builder_forms: - form.ui.prompt_weight_distribution_slider.setValue(int(auto_prompt_weight * 100)) - form.ui.negative_prompt_weight_distribution_slider.setValue(int(auto_negative_prompt_weight * 100)) - - def initialize_weight_sliders(self): - for form in self.prompt_builder_forms: - - form.ui.prompt_weight_distribution_slider.valueChanged.connect( - self.handle_weight_distribution_slider_change) - form.ui.negative_prompt_weight_distribution_slider.valueChanged.connect( - self.handle_negative_weight_distribution_slider_change) - - def handle_weight_distribution_slider_change(self, value): - self.auto_prompt_weight = 0.0 + (value / 100.0) - self.text_prompt_weight = 1.0 - self.auto_prompt_weight - self.auto_prompt_weight = round(self.auto_prompt_weight, 2) - self.text_prompt_weight = round(self.text_prompt_weight, 2) - - for form in self.prompt_builder_forms: - form.ui.auto_prompt_weight_label.setText(f"{self.auto_prompt_weight:.2f}") - form.ui.text_prompt_weight_label.setText(f"{self.text_prompt_weight:.2f}") - form.ui.prompt_weight_distribution_slider.setValue(int(self.auto_prompt_weight * 100)) - - self.settings_manager.set_value("auto_prompt_weight", self.auto_prompt_weight) - self.process_prompt() - - def handle_negative_weight_distribution_slider_change(self, value): - self.negative_auto_prompt_weight = 0.0 + (value / 100.0) - self.negative_text_prompt_weight = 1.0 - self.negative_auto_prompt_weight - self.negative_auto_prompt_weight = round(self.negative_auto_prompt_weight, 2) - self.negative_text_prompt_weight = round(self.negative_text_prompt_weight, 2) - for form in self.prompt_builder_forms: - form.ui.negative_auto_prompt_weight_label.setText(f"{self.negative_auto_prompt_weight:.2f}") - form.ui.negative_text_prompt_weight_label.setText(f"{self.negative_text_prompt_weight:.2f}") - form.ui.negative_prompt_weight_distribution_slider.setValue(int(self.negative_auto_prompt_weight * 100)) - form.ui.negative_prompt_weight_distribution_slider.setValue(int(self.negative_auto_prompt_weight * 100)) - self.settings_manager.set_value("negative_auto_prompt_weight", self.negative_auto_prompt_weight) - self.process_prompt() - - def process_prompt(self): - # if not self.settings_manager.generator.use_prompt_builder: - # # self.prompt_text.setPlainText("") - # # self.negative_prompt_text.setPlainText("") - # return - - # get composition values from dropdowns in current tab - # get widget from current tab - current_tab = self.ui.tabs.currentWidget() - if current_tab is None: - return - - #seed = self.app.seed if not self.app.seed_override else self.app.seed_override - seed = random.randint(0, MAX_SEED) - # if self.settings_manager.prompt_blend_type == 1: - # prompt_a = self.app.prompt - # negative_prompt_a = self.app.negative_prompt - # elif self.settings_manager.prompt_blend_type == 2: - # prev_tab = self.current_tab - # self.current_tab = "b" if prev_tab == "a" else "a" - # prompt_a, negative_prompt_a = self.build_prompts("", "", seed) - # self.current_tab = prev_tab - prev_tab = self.current_tab - self.current_tab = "b" if prev_tab == "a" else "a" - self.current_tab = prev_tab - - prompt, negative_prompt = self.build_prompts(self.settings_manager.generator.prompt, self.settings_manager.generator.negative_prompt, seed) - - # save processed prompts - current_tab.ui.prompt_text.setPlainText(prompt) - current_tab.ui.negative_prompt_text.setPlainText(negative_prompt) - - def build_prompts(self, prompt_a="", negative_prompt_a="", seed=None): - # if seed is None: - # seed = self.app.seed if not self.app.seed_override else self.app.seed_override - category = self.prompt_generator_category - image_genre = self.prompt_generator_prompt_genre - image_color = self.prompt_generator_prompt_color - image_style = self.prompt_generator_prompt_style - if category == "" or category is None: - category = "Random" - prompt_prefix = self.prompt_generator_prefix - prompt_suffix = self.prompt_generator_suffix - negative_prompt_prefix = self.negative_prompt_generator_prefix - negative_prompt_suffix = self.negative_prompt_generator_suffix - weighted_variables = self.prompt_generator_weighted_values - - return self.prompt_data.build_prompts( - prompt=prompt_a, - negative_prompt=negative_prompt_a, - text_prompt_weight=self.text_prompt_weight, - auto_prompt_weight=self.auto_prompt_weight, - prompt_prefix=prompt_prefix, - prompt_suffix=prompt_suffix, - negative_prompt_prefix=negative_prompt_prefix, - negative_prompt_suffix=negative_prompt_suffix, - negative_text_prompt_weight=self.negative_text_prompt_weight, - negative_auto_prompt_weight=self.negative_auto_prompt_weight, - weighted_variables=weighted_variables, - seed=seed, - category=category, - image_genre=image_genre, - image_color=image_color, - image_style=image_style, - advanced=True#self.settings_manager.prompt_generator_advanced - ) - - def inject_prompt(self, options): - """ - Injects the prompts into the options dictionary which is - passed to the runner. - :param options: - :return: - """ - self.process_prompt() - current_tab = self.tabs.currentWidget() - if self.settings_manager.generator.use_prompt_builder: - options[f"prompt"] = current_tab.prompt_text.toPlainText() - options[f"negative_prompt"] = current_tab.negative_prompt_text.toPlainText() - options[f"prompt_data"] = self.prompt_data - - def tab_changed(self, val): - print("tab_changed", val) - session = get_session() - ts = session.query(TabSection).filter(TabSection.panel == "prompt_builder.ui.tabs").first() - ts.active_tab = str(val) - save_session() diff --git a/src/airunner/widgets/prompt_builder/templates/__init__.py b/src/airunner/widgets/prompt_builder/templates/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder.ui b/src/airunner/widgets/prompt_builder/templates/prompt_builder.ui deleted file mode 100644 index 43adeb502..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder.ui +++ /dev/null @@ -1,97 +0,0 @@ - - - prompt_builder - - - - 0 - 0 - 300 - 317 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 9 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 9 - - - - - - - -1 - - - false - - - false - - - - - - - - - tabs - currentChanged(int) - prompt_builder - tab_changed(int) - - - 216 - 96 - - - 232 - -20 - - - - - - tab_changed(int) - - diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder_form.ui b/src/airunner/widgets/prompt_builder/templates/prompt_builder_form.ui deleted file mode 100644 index 334024a32..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder_form.ui +++ /dev/null @@ -1,1038 +0,0 @@ - - - prompt_builder_form - - - - 0 - 0 - 680 - 415 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - QFrame::Plain - - - true - - - - - 0 - 0 - 680 - 415 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 8 - - - - 0 - - - - Prompt Settings - - - - 11 - - - 19 - - - 11 - - - 9 - - - 6 - - - - - - 0 - 0 - - - - - 8 - true - - - - Style - - - - - - - - 0 - 0 - - - - - 80 - 22 - - - - - 8 - - - - true - - - QComboBox::InsertAlphabetically - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 8 - true - - - - Genre - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 8 - true - - - - Color - - - - - - - - 0 - 0 - - - - - 80 - 22 - - - - - 16777215 - 16777215 - - - - - 8 - - - - true - - - QComboBox::InsertAlphabetically - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 80 - 22 - - - - - 16777215 - 16777215 - - - - - 8 - - - - true - - - QComboBox::InsertAlphabetically - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 80 - 22 - - - - - 8 - - - - true - - - QComboBox::InsertAlphabetically - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 8 - true - - - - Category - - - - - - - - Variables - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - Randomize - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - To Random - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - Reset Weights - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - Clear - - - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOn - - - true - - - - - 0 - 0 - 660 - 364 - - - - - - - - - - - - Generated Prompts - - - - 11 - - - 19 - - - 11 - - - 9 - - - - - true - - - - - 0 - 0 - 652 - 359 - - - - - - - 6 - - - - - - 0 - 0 - - - - - 200 - 16777215 - - - - - 8 - true - - - - Prompt - - - - - - - 6 - - - - - - 8 - - - - Prompt prefix - - - - - - - - 8 - - - - Prompt suffix - - - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - false - - - - - - - - 0 - 0 - - - - - 200 - 16777215 - - - - - 8 - true - - - - Negative Prompt - - - - - - - 6 - - - - - - 8 - - - - Negative prefix - - - - - - - - 8 - - - - Negative suffix - - - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - - - - false - - - - - - - - - - - - 8 - false - - - - Auto Neg Prompt - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 8 - false - - - - Text Prompt - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 8 - false - - - - Auto Prompt - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - 100 - - - 1 - - - 50 - - - Qt::Horizontal - - - QSlider::NoTicks - - - 1 - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 10 - - - - 100 - - - 1 - - - 50 - - - Qt::Horizontal - - - QSlider::NoTicks - - - 1 - - - - - - - - 8 - true - - - - 0.50 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 8 - true - - - - 0.5 - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 8 - false - - - - Negative Prompt - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 8 - true - - - - 0.5 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 8 - true - - - - 0.50 - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 8 - - - - Blend mode - - - - Blend Disabled - - - - - Main Prompt - - - - - Prompt Builder - - - - - - - - - 8 - true - - - - Prompt blend weight distribution - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - - - - - - - - - - - - - prompt_category - currentTextChanged(QString) - prompt_builder_form - category_text_changed(QString) - - - 154 - 72 - - - 329 - -12 - - - - - prompt_style - currentTextChanged(QString) - prompt_builder_form - style_text_changed(QString) - - - 533 - 116 - - - 576 - -6 - - - - - prompt_genre - currentTextChanged(QString) - prompt_builder_form - genre_text_changed(QString) - - - 622 - 76 - - - 8 - -15 - - - - - prompt_color - currentTextChanged(QString) - prompt_builder_form - color_text_changed(QString) - - - 201 - 124 - - - 39 - -8 - - - - - - tab_changed(int) - category_text_changed(QString) - style_text_changed(QString) - genre_text_changed(QString) - color_text_changed(QString) - - diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder_form_ui.py b/src/airunner/widgets/prompt_builder/templates/prompt_builder_form_ui.py deleted file mode 100644 index feb036eb0..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder_form_ui.py +++ /dev/null @@ -1,493 +0,0 @@ -# Form implementation generated from reading ui file '/home/joe/Projects/imagetopixel/airunner/src/airunner/../../src/airunner/widgets/prompt_builder/templates/prompt_builder_form.ui' -# -# Created by: PyQt6 UI code generator 6.4.2 -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class Ui_prompt_builder_form(object): - def setupUi(self, prompt_builder_form): - prompt_builder_form.setObjectName("prompt_builder_form") - prompt_builder_form.resize(680, 415) - self.gridLayout = QtWidgets.QGridLayout(prompt_builder_form) - self.gridLayout.setContentsMargins(0, 0, 0, 0) - self.gridLayout.setObjectName("gridLayout") - self.scrollArea_2 = QtWidgets.QScrollArea(parent=prompt_builder_form) - self.scrollArea_2.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) - self.scrollArea_2.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) - self.scrollArea_2.setWidgetResizable(True) - self.scrollArea_2.setObjectName("scrollArea_2") - self.scrollAreaWidgetContents_2 = QtWidgets.QWidget() - self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 680, 415)) - self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2") - self.gridLayout_5 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents_2) - self.gridLayout_5.setContentsMargins(0, 0, 0, 0) - self.gridLayout_5.setObjectName("gridLayout_5") - self.tabWidget = QtWidgets.QTabWidget(parent=self.scrollAreaWidgetContents_2) - font = QtGui.QFont() - font.setPointSize(8) - self.tabWidget.setFont(font) - self.tabWidget.setObjectName("tabWidget") - self.prompt_settings = QtWidgets.QWidget() - self.prompt_settings.setObjectName("prompt_settings") - self.gridLayout_4 = QtWidgets.QGridLayout(self.prompt_settings) - self.gridLayout_4.setContentsMargins(11, 19, 11, 9) - self.gridLayout_4.setVerticalSpacing(6) - self.gridLayout_4.setObjectName("gridLayout_4") - self.label_11 = QtWidgets.QLabel(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_11.sizePolicy().hasHeightForWidth()) - self.label_11.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_11.setFont(font) - self.label_11.setObjectName("label_11") - self.gridLayout_4.addWidget(self.label_11, 2, 2, 1, 1) - self.prompt_color = QtWidgets.QComboBox(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_color.sizePolicy().hasHeightForWidth()) - self.prompt_color.setSizePolicy(sizePolicy) - self.prompt_color.setMinimumSize(QtCore.QSize(80, 22)) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_color.setFont(font) - self.prompt_color.setEditable(True) - self.prompt_color.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) - self.prompt_color.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow) - self.prompt_color.setObjectName("prompt_color") - self.gridLayout_4.addWidget(self.prompt_color, 3, 0, 1, 1) - self.label = QtWidgets.QLabel(parent=self.prompt_settings) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label.setFont(font) - self.label.setObjectName("label") - self.gridLayout_4.addWidget(self.label, 0, 2, 1, 1) - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - self.gridLayout_4.addItem(spacerItem, 6, 0, 1, 1) - self.label_8 = QtWidgets.QLabel(parent=self.prompt_settings) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_8.setFont(font) - self.label_8.setObjectName("label_8") - self.gridLayout_4.addWidget(self.label_8, 2, 0, 1, 2) - self.prompt_category = QtWidgets.QComboBox(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_category.sizePolicy().hasHeightForWidth()) - self.prompt_category.setSizePolicy(sizePolicy) - self.prompt_category.setMinimumSize(QtCore.QSize(80, 22)) - self.prompt_category.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_category.setFont(font) - self.prompt_category.setEditable(True) - self.prompt_category.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) - self.prompt_category.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow) - self.prompt_category.setObjectName("prompt_category") - self.gridLayout_4.addWidget(self.prompt_category, 1, 0, 1, 1) - self.prompt_style = QtWidgets.QComboBox(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_style.sizePolicy().hasHeightForWidth()) - self.prompt_style.setSizePolicy(sizePolicy) - self.prompt_style.setMinimumSize(QtCore.QSize(80, 22)) - self.prompt_style.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_style.setFont(font) - self.prompt_style.setEditable(True) - self.prompt_style.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) - self.prompt_style.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow) - self.prompt_style.setObjectName("prompt_style") - self.gridLayout_4.addWidget(self.prompt_style, 3, 2, 1, 1) - self.prompt_genre = QtWidgets.QComboBox(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_genre.sizePolicy().hasHeightForWidth()) - self.prompt_genre.setSizePolicy(sizePolicy) - self.prompt_genre.setMinimumSize(QtCore.QSize(80, 22)) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_genre.setFont(font) - self.prompt_genre.setEditable(True) - self.prompt_genre.setInsertPolicy(QtWidgets.QComboBox.InsertPolicy.InsertAlphabetically) - self.prompt_genre.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow) - self.prompt_genre.setObjectName("prompt_genre") - self.gridLayout_4.addWidget(self.prompt_genre, 1, 2, 1, 1) - self.label_2 = QtWidgets.QLabel(parent=self.prompt_settings) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Maximum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) - self.label_2.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_2.setFont(font) - self.label_2.setObjectName("label_2") - self.gridLayout_4.addWidget(self.label_2, 0, 0, 1, 1) - self.tabWidget.addTab(self.prompt_settings, "") - self.variables = QtWidgets.QWidget() - self.variables.setObjectName("variables") - self.gridLayout_2 = QtWidgets.QGridLayout(self.variables) - self.gridLayout_2.setContentsMargins(0, 0, 0, 0) - self.gridLayout_2.setObjectName("gridLayout_2") - self.gridLayout_9 = QtWidgets.QGridLayout() - self.gridLayout_9.setSpacing(0) - self.gridLayout_9.setObjectName("gridLayout_9") - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() - self.horizontalLayout_3.setObjectName("horizontalLayout_3") - self.randomize_values_button = QtWidgets.QPushButton(parent=self.variables) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.randomize_values_button.sizePolicy().hasHeightForWidth()) - self.randomize_values_button.setSizePolicy(sizePolicy) - self.randomize_values_button.setMinimumSize(QtCore.QSize(20, 0)) - self.randomize_values_button.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.randomize_values_button.setFont(font) - self.randomize_values_button.setObjectName("randomize_values_button") - self.horizontalLayout_3.addWidget(self.randomize_values_button) - self.values_to_random_button = QtWidgets.QPushButton(parent=self.variables) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Minimum) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.values_to_random_button.sizePolicy().hasHeightForWidth()) - self.values_to_random_button.setSizePolicy(sizePolicy) - self.values_to_random_button.setMinimumSize(QtCore.QSize(20, 0)) - self.values_to_random_button.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.values_to_random_button.setFont(font) - self.values_to_random_button.setObjectName("values_to_random_button") - self.horizontalLayout_3.addWidget(self.values_to_random_button) - self.reset_weights_button = QtWidgets.QPushButton(parent=self.variables) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.reset_weights_button.sizePolicy().hasHeightForWidth()) - self.reset_weights_button.setSizePolicy(sizePolicy) - self.reset_weights_button.setMinimumSize(QtCore.QSize(20, 0)) - self.reset_weights_button.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.reset_weights_button.setFont(font) - self.reset_weights_button.setObjectName("reset_weights_button") - self.horizontalLayout_3.addWidget(self.reset_weights_button) - self.clear_values_button = QtWidgets.QPushButton(parent=self.variables) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.clear_values_button.sizePolicy().hasHeightForWidth()) - self.clear_values_button.setSizePolicy(sizePolicy) - self.clear_values_button.setMinimumSize(QtCore.QSize(20, 0)) - self.clear_values_button.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.clear_values_button.setFont(font) - self.clear_values_button.setObjectName("clear_values_button") - self.horizontalLayout_3.addWidget(self.clear_values_button) - self.gridLayout_9.addLayout(self.horizontalLayout_3, 1, 1, 1, 1) - self.scrollArea = QtWidgets.QScrollArea(parent=self.variables) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth()) - self.scrollArea.setSizePolicy(sizePolicy) - self.scrollArea.setMinimumSize(QtCore.QSize(200, 0)) - self.scrollArea.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) - self.scrollArea.setFrameShadow(QtWidgets.QFrame.Shadow.Plain) - self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOn) - self.scrollArea.setWidgetResizable(True) - self.scrollArea.setObjectName("scrollArea") - self.scroll_grid = QtWidgets.QWidget() - self.scroll_grid.setGeometry(QtCore.QRect(0, 0, 660, 364)) - self.scroll_grid.setObjectName("scroll_grid") - self.scrollArea.setWidget(self.scroll_grid) - self.gridLayout_9.addWidget(self.scrollArea, 0, 1, 1, 1) - self.gridLayout_2.addLayout(self.gridLayout_9, 0, 0, 1, 1) - self.tabWidget.addTab(self.variables, "") - self.generated_prompts = QtWidgets.QWidget() - self.generated_prompts.setObjectName("generated_prompts") - self.gridLayout_3 = QtWidgets.QGridLayout(self.generated_prompts) - self.gridLayout_3.setContentsMargins(11, 19, 11, 9) - self.gridLayout_3.setObjectName("gridLayout_3") - self.scrollArea_3 = QtWidgets.QScrollArea(parent=self.generated_prompts) - self.scrollArea_3.setWidgetResizable(True) - self.scrollArea_3.setObjectName("scrollArea_3") - self.scrollAreaWidgetContents = QtWidgets.QWidget() - self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 652, 359)) - self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") - self.gridLayout_6 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) - self.gridLayout_6.setObjectName("gridLayout_6") - self.verticalLayout_3 = QtWidgets.QVBoxLayout() - self.verticalLayout_3.setSpacing(6) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.label_16 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth()) - self.label_16.setSizePolicy(sizePolicy) - self.label_16.setMaximumSize(QtCore.QSize(200, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_16.setFont(font) - self.label_16.setObjectName("label_16") - self.verticalLayout_3.addWidget(self.label_16) - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setSpacing(6) - self.horizontalLayout.setObjectName("horizontalLayout") - self.prompt_prefix = QtWidgets.QLineEdit(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_prefix.setFont(font) - self.prompt_prefix.setObjectName("prompt_prefix") - self.horizontalLayout.addWidget(self.prompt_prefix) - self.prompt_suffix = QtWidgets.QLineEdit(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_suffix.setFont(font) - self.prompt_suffix.setObjectName("prompt_suffix") - self.horizontalLayout.addWidget(self.prompt_suffix) - self.verticalLayout_3.addLayout(self.horizontalLayout) - self.prompt_text = QtWidgets.QTextBrowser(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_text.sizePolicy().hasHeightForWidth()) - self.prompt_text.setSizePolicy(sizePolicy) - self.prompt_text.setMinimumSize(QtCore.QSize(200, 0)) - self.prompt_text.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_text.setFont(font) - self.prompt_text.setReadOnly(False) - self.prompt_text.setObjectName("prompt_text") - self.verticalLayout_3.addWidget(self.prompt_text) - self.label_17 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Maximum, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_17.sizePolicy().hasHeightForWidth()) - self.label_17.setSizePolicy(sizePolicy) - self.label_17.setMaximumSize(QtCore.QSize(200, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_17.setFont(font) - self.label_17.setObjectName("label_17") - self.verticalLayout_3.addWidget(self.label_17) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() - self.horizontalLayout_2.setSpacing(6) - self.horizontalLayout_2.setObjectName("horizontalLayout_2") - self.negative_prompt_prefix = QtWidgets.QLineEdit(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - self.negative_prompt_prefix.setFont(font) - self.negative_prompt_prefix.setObjectName("negative_prompt_prefix") - self.horizontalLayout_2.addWidget(self.negative_prompt_prefix) - self.negative_prompt_suffix = QtWidgets.QLineEdit(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - self.negative_prompt_suffix.setFont(font) - self.negative_prompt_suffix.setObjectName("negative_prompt_suffix") - self.horizontalLayout_2.addWidget(self.negative_prompt_suffix) - self.verticalLayout_3.addLayout(self.horizontalLayout_2) - self.negative_prompt_text = QtWidgets.QTextBrowser(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.negative_prompt_text.sizePolicy().hasHeightForWidth()) - self.negative_prompt_text.setSizePolicy(sizePolicy) - self.negative_prompt_text.setMinimumSize(QtCore.QSize(200, 0)) - self.negative_prompt_text.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - self.negative_prompt_text.setFont(font) - self.negative_prompt_text.setReadOnly(False) - self.negative_prompt_text.setObjectName("negative_prompt_text") - self.verticalLayout_3.addWidget(self.negative_prompt_text) - self.gridLayout_6.addLayout(self.verticalLayout_3, 0, 0, 1, 1) - self.weights = QtWidgets.QGridLayout() - self.weights.setObjectName("weights") - self.label_5 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.label_5.setFont(font) - self.label_5.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.label_5.setObjectName("label_5") - self.weights.addWidget(self.label_5, 2, 4, 1, 1) - self.label_4 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.label_4.setFont(font) - self.label_4.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.label_4.setObjectName("label_4") - self.weights.addWidget(self.label_4, 1, 0, 1, 1) - self.label_3 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.label_3.setFont(font) - self.label_3.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.label_3.setObjectName("label_3") - self.weights.addWidget(self.label_3, 1, 4, 1, 1) - self.negative_prompt_weight_distribution_slider = QtWidgets.QSlider(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.negative_prompt_weight_distribution_slider.sizePolicy().hasHeightForWidth()) - self.negative_prompt_weight_distribution_slider.setSizePolicy(sizePolicy) - self.negative_prompt_weight_distribution_slider.setMinimumSize(QtCore.QSize(50, 0)) - self.negative_prompt_weight_distribution_slider.setMaximum(100) - self.negative_prompt_weight_distribution_slider.setPageStep(1) - self.negative_prompt_weight_distribution_slider.setProperty("value", 50) - self.negative_prompt_weight_distribution_slider.setOrientation(QtCore.Qt.Orientation.Horizontal) - self.negative_prompt_weight_distribution_slider.setTickPosition(QtWidgets.QSlider.TickPosition.NoTicks) - self.negative_prompt_weight_distribution_slider.setTickInterval(1) - self.negative_prompt_weight_distribution_slider.setObjectName("negative_prompt_weight_distribution_slider") - self.weights.addWidget(self.negative_prompt_weight_distribution_slider, 2, 2, 1, 1) - self.prompt_weight_distribution_slider = QtWidgets.QSlider(parent=self.scrollAreaWidgetContents) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.prompt_weight_distribution_slider.sizePolicy().hasHeightForWidth()) - self.prompt_weight_distribution_slider.setSizePolicy(sizePolicy) - self.prompt_weight_distribution_slider.setMinimumSize(QtCore.QSize(50, 0)) - font = QtGui.QFont() - font.setPointSize(10) - self.prompt_weight_distribution_slider.setFont(font) - self.prompt_weight_distribution_slider.setMaximum(100) - self.prompt_weight_distribution_slider.setPageStep(1) - self.prompt_weight_distribution_slider.setProperty("value", 50) - self.prompt_weight_distribution_slider.setOrientation(QtCore.Qt.Orientation.Horizontal) - self.prompt_weight_distribution_slider.setTickPosition(QtWidgets.QSlider.TickPosition.NoTicks) - self.prompt_weight_distribution_slider.setTickInterval(1) - self.prompt_weight_distribution_slider.setObjectName("prompt_weight_distribution_slider") - self.weights.addWidget(self.prompt_weight_distribution_slider, 1, 2, 1, 1) - self.auto_prompt_weight_label = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.auto_prompt_weight_label.setFont(font) - self.auto_prompt_weight_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.auto_prompt_weight_label.setObjectName("auto_prompt_weight_label") - self.weights.addWidget(self.auto_prompt_weight_label, 1, 3, 1, 1) - self.negative_text_prompt_weight_label = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.negative_text_prompt_weight_label.setFont(font) - self.negative_text_prompt_weight_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.negative_text_prompt_weight_label.setObjectName("negative_text_prompt_weight_label") - self.weights.addWidget(self.negative_text_prompt_weight_label, 2, 1, 1, 1) - self.label_6 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.label_6.setFont(font) - self.label_6.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.label_6.setObjectName("label_6") - self.weights.addWidget(self.label_6, 2, 0, 1, 1) - self.negative_auto_prompt_weight_label = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.negative_auto_prompt_weight_label.setFont(font) - self.negative_auto_prompt_weight_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.negative_auto_prompt_weight_label.setObjectName("negative_auto_prompt_weight_label") - self.weights.addWidget(self.negative_auto_prompt_weight_label, 2, 3, 1, 1) - self.text_prompt_weight_label = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.text_prompt_weight_label.setFont(font) - self.text_prompt_weight_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.text_prompt_weight_label.setObjectName("text_prompt_weight_label") - self.weights.addWidget(self.text_prompt_weight_label, 1, 1, 1, 1) - self.prompt_blend_type = QtWidgets.QComboBox(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - self.prompt_blend_type.setFont(font) - self.prompt_blend_type.setObjectName("prompt_blend_type") - self.prompt_blend_type.addItem("") - self.prompt_blend_type.addItem("") - self.prompt_blend_type.addItem("") - self.weights.addWidget(self.prompt_blend_type, 0, 3, 1, 2) - self.label_7 = QtWidgets.QLabel(parent=self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label_7.setFont(font) - self.label_7.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeading|QtCore.Qt.AlignmentFlag.AlignLeft|QtCore.Qt.AlignmentFlag.AlignVCenter) - self.label_7.setObjectName("label_7") - self.weights.addWidget(self.label_7, 0, 0, 1, 3) - self.gridLayout_6.addLayout(self.weights, 1, 0, 1, 1) - self.scrollArea_3.setWidget(self.scrollAreaWidgetContents) - self.gridLayout_3.addWidget(self.scrollArea_3, 0, 0, 1, 1) - self.tabWidget.addTab(self.generated_prompts, "") - self.gridLayout_5.addWidget(self.tabWidget, 0, 0, 1, 1) - self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) - self.gridLayout.addWidget(self.scrollArea_2, 0, 0, 1, 1) - - self.retranslateUi(prompt_builder_form) - self.tabWidget.setCurrentIndex(0) - self.prompt_category.currentTextChanged['QString'].connect(prompt_builder_form.category_text_changed) # type: ignore - self.prompt_style.currentTextChanged['QString'].connect(prompt_builder_form.style_text_changed) # type: ignore - self.prompt_genre.currentTextChanged['QString'].connect(prompt_builder_form.genre_text_changed) # type: ignore - self.prompt_color.currentTextChanged['QString'].connect(prompt_builder_form.color_text_changed) # type: ignore - QtCore.QMetaObject.connectSlotsByName(prompt_builder_form) - - def retranslateUi(self, prompt_builder_form): - _translate = QtCore.QCoreApplication.translate - prompt_builder_form.setWindowTitle(_translate("prompt_builder_form", "Form")) - self.label_11.setText(_translate("prompt_builder_form", "Style")) - self.label.setText(_translate("prompt_builder_form", "Genre")) - self.label_8.setText(_translate("prompt_builder_form", "Color")) - self.label_2.setText(_translate("prompt_builder_form", "Category")) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.prompt_settings), _translate("prompt_builder_form", "Prompt Settings")) - self.randomize_values_button.setText(_translate("prompt_builder_form", "Randomize")) - self.values_to_random_button.setText(_translate("prompt_builder_form", "To Random")) - self.reset_weights_button.setText(_translate("prompt_builder_form", "Reset Weights")) - self.clear_values_button.setText(_translate("prompt_builder_form", "Clear")) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.variables), _translate("prompt_builder_form", "Variables")) - self.label_16.setText(_translate("prompt_builder_form", "Prompt")) - self.prompt_prefix.setPlaceholderText(_translate("prompt_builder_form", "Prompt prefix")) - self.prompt_suffix.setPlaceholderText(_translate("prompt_builder_form", "Prompt suffix")) - self.label_17.setText(_translate("prompt_builder_form", "Negative Prompt")) - self.negative_prompt_prefix.setPlaceholderText(_translate("prompt_builder_form", "Negative prefix")) - self.negative_prompt_suffix.setPlaceholderText(_translate("prompt_builder_form", "Negative suffix")) - self.label_5.setText(_translate("prompt_builder_form", "Auto Neg Prompt")) - self.label_4.setText(_translate("prompt_builder_form", "Text Prompt")) - self.label_3.setText(_translate("prompt_builder_form", "Auto Prompt")) - self.auto_prompt_weight_label.setText(_translate("prompt_builder_form", "0.50")) - self.negative_text_prompt_weight_label.setText(_translate("prompt_builder_form", "0.5")) - self.label_6.setText(_translate("prompt_builder_form", "Negative Prompt")) - self.negative_auto_prompt_weight_label.setText(_translate("prompt_builder_form", "0.5")) - self.text_prompt_weight_label.setText(_translate("prompt_builder_form", "0.50")) - self.prompt_blend_type.setToolTip(_translate("prompt_builder_form", "Blend mode")) - self.prompt_blend_type.setItemText(0, _translate("prompt_builder_form", "Blend Disabled")) - self.prompt_blend_type.setItemText(1, _translate("prompt_builder_form", "Main Prompt")) - self.prompt_blend_type.setItemText(2, _translate("prompt_builder_form", "Prompt Builder")) - self.label_7.setText(_translate("prompt_builder_form", "Prompt blend weight distribution")) - self.tabWidget.setTabText(self.tabWidget.indexOf(self.generated_prompts), _translate("prompt_builder_form", "Generated Prompts")) diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder_ui.py b/src/airunner/widgets/prompt_builder/templates/prompt_builder_ui.py deleted file mode 100644 index 21184a6e8..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder_ui.py +++ /dev/null @@ -1,50 +0,0 @@ -# Form implementation generated from reading ui file '/home/joe/Projects/imagetopixel/airunner/src/airunner/../../src/airunner/widgets/prompt_builder/templates/prompt_builder.ui' -# -# Created by: PyQt6 UI code generator 6.4.2 -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class Ui_prompt_builder(object): - def setupUi(self, prompt_builder): - prompt_builder.setObjectName("prompt_builder") - prompt_builder.resize(300, 317) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(prompt_builder.sizePolicy().hasHeightForWidth()) - prompt_builder.setSizePolicy(sizePolicy) - prompt_builder.setMinimumSize(QtCore.QSize(0, 0)) - font = QtGui.QFont() - font.setPointSize(9) - prompt_builder.setFont(font) - self.gridLayout = QtWidgets.QGridLayout(prompt_builder) - self.gridLayout.setContentsMargins(0, 0, 0, 0) - self.gridLayout.setObjectName("gridLayout") - self.tabs = QtWidgets.QTabWidget(parent=prompt_builder) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tabs.sizePolicy().hasHeightForWidth()) - self.tabs.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(9) - self.tabs.setFont(font) - self.tabs.setStyleSheet("") - self.tabs.setTabsClosable(False) - self.tabs.setTabBarAutoHide(False) - self.tabs.setObjectName("tabs") - self.gridLayout.addWidget(self.tabs, 0, 0, 1, 1) - - self.retranslateUi(prompt_builder) - self.tabs.setCurrentIndex(-1) - self.tabs.currentChanged['int'].connect(prompt_builder.tab_changed) # type: ignore - QtCore.QMetaObject.connectSlotsByName(prompt_builder) - - def retranslateUi(self, prompt_builder): - _translate = QtCore.QCoreApplication.translate - prompt_builder.setWindowTitle(_translate("prompt_builder", "Form")) diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget.ui b/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget.ui deleted file mode 100644 index d9ed16e1b..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget.ui +++ /dev/null @@ -1,141 +0,0 @@ - - - Form - - - - 0 - 0 - 200 - 57 - - - - - 0 - 0 - - - - - 200 - 57 - - - - - 16777215 - 57 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - 0 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 8 - false - - - - true - - - QComboBox::AdjustToMinimumContentsLengthWithIcon - - - 10 - - - - - - - - 0 - 0 - - - - - 20 - 0 - - - - - 8 - false - - - - Weight - - - 2.000000000000000 - - - 0.010000000000000 - - - 1.000000000000000 - - - - - - - - 8 - true - - - - TextLabel - - - - - - - - diff --git a/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget_ui.py b/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget_ui.py deleted file mode 100644 index fcbeccfee..000000000 --- a/src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget_ui.py +++ /dev/null @@ -1,76 +0,0 @@ -# Form implementation generated from reading ui file '/home/joe/Projects/imagetopixel/airunner/src/airunner/../../src/airunner/widgets/prompt_builder/templates/prompt_builder_variable_widget.ui' -# -# Created by: PyQt6 UI code generator 6.4.2 -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class Ui_Form(object): - def setupUi(self, Form): - Form.setObjectName("Form") - Form.resize(200, 57) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth()) - Form.setSizePolicy(sizePolicy) - Form.setMinimumSize(QtCore.QSize(200, 57)) - Form.setMaximumSize(QtCore.QSize(16777215, 57)) - self.gridLayout = QtWidgets.QGridLayout(Form) - self.gridLayout.setContentsMargins(0, 0, 0, 0) - self.gridLayout.setHorizontalSpacing(6) - self.gridLayout.setVerticalSpacing(0) - self.gridLayout.setObjectName("gridLayout") - self.combobox = QtWidgets.QComboBox(parent=Form) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.combobox.sizePolicy().hasHeightForWidth()) - self.combobox.setSizePolicy(sizePolicy) - self.combobox.setMinimumSize(QtCore.QSize(0, 0)) - self.combobox.setMaximumSize(QtCore.QSize(16777215, 16777215)) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.combobox.setFont(font) - self.combobox.setEditable(True) - self.combobox.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) - self.combobox.setMinimumContentsLength(10) - self.combobox.setObjectName("combobox") - self.gridLayout.addWidget(self.combobox, 1, 1, 1, 1) - self.spinbox = QtWidgets.QDoubleSpinBox(parent=Form) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.spinbox.sizePolicy().hasHeightForWidth()) - self.spinbox.setSizePolicy(sizePolicy) - self.spinbox.setMinimumSize(QtCore.QSize(20, 0)) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(False) - self.spinbox.setFont(font) - self.spinbox.setMaximum(2.0) - self.spinbox.setSingleStep(0.01) - self.spinbox.setProperty("value", 1.0) - self.spinbox.setObjectName("spinbox") - self.gridLayout.addWidget(self.spinbox, 1, 2, 1, 1) - self.label = QtWidgets.QLabel(parent=Form) - font = QtGui.QFont() - font.setPointSize(8) - font.setBold(True) - self.label.setFont(font) - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 0, 1, 1, 1) - - self.retranslateUi(Form) - QtCore.QMetaObject.connectSlotsByName(Form) - - def retranslateUi(self, Form): - _translate = QtCore.QCoreApplication.translate - Form.setWindowTitle(_translate("Form", "Form")) - self.spinbox.setToolTip(_translate("Form", "Weight")) - self.label.setText(_translate("Form", "TextLabel")) diff --git a/src/airunner/widgets/seed/seed_widget.py b/src/airunner/widgets/seed/seed_widget.py index 42da4bf23..221a2117f 100644 --- a/src/airunner/widgets/seed/seed_widget.py +++ b/src/airunner/widgets/seed/seed_widget.py @@ -9,17 +9,17 @@ class SeedWidget(BaseWidget): # def initialize(self, generator_section, generator_name): # self.ui.lineEdit.setText(str(self.seed)) - # self.settings_manager.generator_section = generator_section - # self.settings_manager.generator_name = generator_name - # self.ui.random_button.setChecked(self.settings_manager.generator.random_seed) - # self.ui.lineEdit.setEnabled(not self.settings_manager.generator.random_seed) + # self.app.settings_manager.generator_section = generator_section + # self.app.settings_manager.generator_name = generator_name + # self.ui.random_button.setChecked(self.app.settings_manager.generator.random_seed) + # self.ui.lineEdit.setEnabled(not self.app.settings_manager.generator.random_seed) def update_seed(self): self.ui.lineEdit.setText(str(self.seed)) def action_clicked_button_random_seed(self, value): property_name = self.property("property_name") - self.settings_manager.set_value(property_name, value) + self.app.settings_manager.set_value(property_name, value) self.ui.lineEdit.setEnabled(not value) def action_value_changed_seed(self, value): @@ -30,9 +30,9 @@ class LatentsSeedWidget(SeedWidget): setting_name = "generator.random_latents_seed" # def initialize(self, generator_section, generator_name): - # self.settings_manager.generator_section = generator_section - # self.settings_manager.generator_name = generator_name + # self.app.settings_manager.generator_section = generator_section + # self.app.settings_manager.generator_name = generator_name # self.ui.label.setText("Image Seed") # self.update_seed() - # self.ui.random_button.setChecked(self.settings_manager.generator.random_latents_seed) - # self.ui.lineEdit.setEnabled(not self.settings_manager.generator.random_latents_seed) + # self.ui.random_button.setChecked(self.app.settings_manager.generator.random_latents_seed) + # self.ui.lineEdit.setEnabled(not self.app.settings_manager.generator.random_latents_seed) diff --git a/src/airunner/widgets/slider/slider_widget.py b/src/airunner/widgets/slider/slider_widget.py index dcd7c9b1f..d46fe0fa4 100644 --- a/src/airunner/widgets/slider/slider_widget.py +++ b/src/airunner/widgets/slider/slider_widget.py @@ -123,7 +123,8 @@ def initialize_properties(self, **kwargs): self.divide_by = self.property("divide_by") or 1.0 if settings_property is not None: - current_value = self.settings_manager.get_value(settings_property) or 0 + print("GET SETTINGS PROPERTY", settings_property) + current_value = self.app.settings_manager.get_value(settings_property) or 0 # check if slider_callback is str if isinstance(slider_callback, str): @@ -168,6 +169,7 @@ def initialize_properties(self, **kwargs): self.ui.slider_spinbox.setDecimals(2 if decimals < 2 else decimals) def set_slider_and_spinbox_values(self, val): + print("VAL", val) self.ui.slider.blockSignals(True) self.ui.slider_spinbox.blockSignals(True) diff --git a/src/airunner/widgets/status/status_widget.py b/src/airunner/widgets/status/status_widget.py index c7a4a52b6..b2804a7e7 100644 --- a/src/airunner/widgets/status/status_widget.py +++ b/src/airunner/widgets/status/status_widget.py @@ -10,7 +10,7 @@ class StatusWidget(BaseWidget): def update_system_stats(self, queue_size): has_cuda = torch.cuda.is_available() - nsfw_status = f"NSFW Filter {'On' if self.settings_manager.nsfw_filter else 'Off'}" + nsfw_status = f"NSFW Filter {'On' if self.app.settings_manager.settings.nsfw_filter else 'Off'}" queue_stats = f"Queued items: {queue_size}" cuda_status = f"Using {'GPU' if has_cuda else 'CPU'}" vram_stats = f"VRAM allocated {torch.cuda.memory_allocated() / 1024 ** 3:.1f}GB cached {torch.cuda.memory_cached() / 1024 ** 3:.1f}GB" @@ -24,7 +24,7 @@ def update_system_stats(self, queue_size): enabled_css = "QLabel { color: #00ff00; }" disabled_css = "QLabel { color: #ff0000; }" - self.ui.nsfw_status.setStyleSheet(enabled_css if self.settings_manager.nsfw_filter else disabled_css) + self.ui.nsfw_status.setStyleSheet(enabled_css if self.app.settings_manager.settings.nsfw_filter else disabled_css) self.ui.cuda_status.setStyleSheet(enabled_css if has_cuda else disabled_css) def set_system_status(self, txt, error): diff --git a/src/airunner/windows/base_window.py b/src/airunner/windows/base_window.py index 704cd9bb3..40f58c188 100644 --- a/src/airunner/windows/base_window.py +++ b/src/airunner/windows/base_window.py @@ -1,7 +1,7 @@ import os from PyQt6.QtCore import Qt from PyQt6.QtWidgets import QDialog -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.utils import get_main_window @@ -15,7 +15,6 @@ def __init__(self, **kwargs): super().__init__() self.app = get_main_window() self.do_exec = kwargs.get("exec", True) - self.settings_manager = SettingsManager() self.set_stylesheet() @@ -35,7 +34,7 @@ def set_stylesheet(self): """ Sets the stylesheet for the application based on the current theme """ - theme_name = "dark_theme" if self.settings_manager.dark_mode_enabled else "light_theme" + theme_name = "dark_theme" if self.app.settings_manager.dark_mode_enabled else "light_theme" here = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(here, "..", "styles", theme_name, "styles.qss"), "r") as f: stylesheet = f.read() diff --git a/src/airunner/windows/main/main_window.py b/src/airunner/windows/main/main_window.py index 064a8a923..998573a82 100644 --- a/src/airunner/windows/main/main_window.py +++ b/src/airunner/windows/main/main_window.py @@ -12,6 +12,7 @@ from PyQt6.QtGui import QGuiApplication from PyQt6.QtWidgets import QApplication, QFileDialog, QMainWindow, QWidget from PyQt6 import QtGui +from airunner import settings from airunner.resources_light_rc import * from airunner.resources_dark_rc import * @@ -20,14 +21,14 @@ from airunner.aihandler.pyqt_client import OfflineClient from airunner.aihandler.qtvar import MessageHandlerVar from airunner.aihandler.settings import LOG_LEVEL -from airunner.aihandler.settings_manager import SettingsManager +from airunner.data.managers import SettingsManager from airunner.airunner_api import AIRunnerAPI -from airunner.data.models import SplitterSection, Prompt, TabSection, LLMGenerator +from airunner.data.models import Prompt, TabSection, LLMGenerator from airunner.filters.windows.filter_base import FilterBase from airunner.input_event_manager import InputEventManager from airunner.mixins.history_mixin import HistoryMixin from airunner.settings import BASE_PATH -from airunner.utils import get_version, auto_export_image, save_session, get_session, \ +from airunner.utils import get_version, auto_export_image, \ create_airunner_paths, default_hf_cache_dir from airunner.widgets.status.status_widget import StatusWidget from airunner.windows.about.about import AboutWindow @@ -40,6 +41,7 @@ from airunner.data.models import TabSection from airunner.widgets.brushes.brushes_container import BrushesContainer from airunner.data.models import Document +from airunner.data.session_scope import session_scope, path_settings_scope class ImageDataWorker(QObject): @@ -69,7 +71,7 @@ def process_image_data(self, message): self.stop_progress_bar.emit() print("process_image_data 4") path = "" - if self.parent.settings_manager.auto_export_images: + if self.parent.settings_manager.settings.auto_export_images: procesed_images = [] for image in images: path, image = auto_export_image( @@ -82,7 +84,7 @@ def process_image_data(self, message): self.parent.set_status_label(f"Image exported to {path}") procesed_images.append(image) images = procesed_images - if nsfw_content_detected and self.parent.settings_manager.nsfw_filter: + if nsfw_content_detected and self.parent.settings_manager.settings.nsfw_filter: self.parent.message_handler({ "message": "Explicit content detected, try again.", "code": MessageCode.ERROR @@ -99,6 +101,7 @@ def process_image_data(self, message): self.parent.image_generated.emit(True) + class MainWindow( QMainWindow, HistoryMixin @@ -130,7 +133,6 @@ class MainWindow( _themes = None button_clicked_signal = pyqtSignal(dict) status_widget = None - splitters = None header_widget_spacer = None deterministic_window = None @@ -160,17 +162,17 @@ class MainWindow( @property def generator(self): - if self._generator is None: - session = get_session() - try: - self._generator = session.query(LLMGenerator).filter( - LLMGenerator.name == self.ui.standard_image_widget.ui.llm_settings_widget.current_generator - ).first() - if self._generator is None: - logger.error("Unable to locate generator by name " + self.ui.standard_image_widget.ui.llm_settings_widget.current_generator if self.ui.llm_settings_widget.current_generator else "None") - except Exception as e: - logger.error(e) - return self._generator + with session_scope() as session: + if self._generator is None: + try: + self._generator = session.query(LLMGenerator).filter( + LLMGenerator.name == self.ui.standard_image_widget.ui.llm_settings_widget.current_generator + ).first() + if self._generator is None: + logger.error("Unable to locate generator by name " + self.ui.standard_image_widget.ui.llm_settings_widget.current_generator if self.ui.llm_settings_widget.current_generator else "None") + except Exception as e: + logger.error(e) + return self._generator @property def generator_settings(self): @@ -184,19 +186,13 @@ def generator_settings(self): def generate_signal(self): return self.generator_tab_widget.generate_signal - @property - def settings_manager(self): - if self._settings_manager is None: - self._settings_manager = SettingsManager(app=self) - return self._settings_manager - @property def is_dark(self): - return self.settings_manager.dark_mode_enabled + return self.settings_manager.settings.dark_mode_enabled @property def grid_size(self): - return self.settings_manager.grid_settings.size + return self.settings_manager.grid_settings.cell_size @property def standard_image_panel(self): @@ -260,11 +256,11 @@ def image_path(self): @property def is_maximized(self): - return self.settings_manager.is_maximized + return self.settings_manager.settings.is_maximized @is_maximized.setter def is_maximized(self, val): - self.settings_manager.set_value("is_maximized", val) + self.settings_manager.set_value("settings.is_maximized", val) @property def current_layer(self): @@ -293,17 +289,45 @@ def send_message(self, code, message): }) def available_model_names_by_section(self, section): - for model in self.settings_manager.available_models_by_category(section): + for model in self.settings_manager.settings.available_models_by_category(section): yield model["name"] loaded = pyqtSignal() window_opened = pyqtSignal() - def __init__(self, *args, **kwargs): + def handle_changed_signal(self, key, value): + print("main_window: handle_changed_signal", key, value) + if key == "settings.ai_mode": + # Handle the settings.ai_mode key here + print(f"settings.ai_mode changed to {value}") + elif key == "grid_settings.cell_size": + self.set_size_form_element_step_values() + elif key == "grid_settings.line_width": + self.set_size_form_element_step_values() + elif key == "grid_settings.show_grid": + self.canvas_widget.update() + elif key == "grid_settings.snap_to_grid": + self.canvas_widget.update() + elif key == "settings.line_color": + self.canvas_widget.update_grid_pen() + elif key == "path_settings.lora_path": + self.refresh_lora() + elif key == "path_settings.model_base_path": + self.generator_tab_widget.refresh_model_list() + elif key == "generator.seed": + self.prompt_builder.process_prompt() + # elif key == "use_prompt_builder_checkbox": + # self.generator_tab_widget.toggle_all_prompt_builder_checkboxes(value) + elif key == "models": + self.model_manager.models_changed(key, value) + + def __init__(self, settings_manager, *args, **kwargs): logger.info("Starting AI Runnner") self.ui = Ui_MainWindow() # qdarktheme.enable_hi_dpi() + self.settings_manager = settings_manager + # set the api self.api = AIRunnerAPI(window=self) @@ -311,8 +335,8 @@ def __init__(self, *args, **kwargs): self.testing = kwargs.pop("testing", False) # initialize the document - session = get_session() - self.document = session.query(Document).first() + with session_scope() as session: + self.document = session.query(Document).first() super().__init__(*args, **kwargs) @@ -362,17 +386,20 @@ def __init__(self, *args, **kwargs): self.initialize_panel_tabs() self.initialize_tool_section_buttons() - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.image_generation_toggled() - elif self.settings_manager.mode == Mode.LANGUAGE_PROCESSOR.value: + elif self.settings_manager.settings.mode == Mode.LANGUAGE_PROCESSOR.value: self.language_processing_toggled() else: self.model_manager_toggled(True) - - # This is used to check the state of the window and save splitter sizes if they have changed - self.start_splitter_timer() self.initialize_image_worker() + + # TODO + #self.settings = settings("Capsize Games", "AI Runner") + self.restore_state() + + self.settings_manager.changed_signal.connect(self.handle_changed_signal) self.loaded.emit() @@ -402,27 +429,27 @@ def initialize_panel_tabs(self): :return: """ self.ui.mode_tab_widget.currentChanged.connect(self.mode_tab_index_changed) - session = get_session() - tabsections = session.query(TabSection).filter( - TabSection.panel != "generator_tabs" - ).all() - for ts in tabsections: - if ts.panel == "prompt_builder.ui.tabs": - widget = self.ui.prompt_builder.ui.tabs - else: - widget = getattr(self.ui, ts.panel) - for i in range(widget.count()): - if widget.tabText(i) == ts.active_tab: - widget.setCurrentIndex(i) + with session_scope() as session: + tabsections = session.query(TabSection).filter( + TabSection.panel != "generator_tabs" + ).all() + for ts in tabsections: + if ts.panel == "prompt_builder.ui.tabs": + print(f"Setting prompt builder tab to {ts.active_tab}") + else: + widget = getattr(self.ui, ts.panel) + for i in range(widget.count()): + if widget.tabText(i) == ts.active_tab: + widget.setCurrentIndex(i) + break + + for i in range(self.ui.mode_tab_widget.count()): + if self.ui.mode_tab_widget.tabText(i) == self.settings_manager.settings.mode: + self.ui.mode_tab_widget.setCurrentIndex(i) break - for i in range(self.ui.mode_tab_widget.count()): - if self.ui.mode_tab_widget.tabText(i) == self.settings_manager.mode: - self.ui.mode_tab_widget.setCurrentIndex(i) - break - def mode_tab_index_changed(self, index): - self.settings_manager.set_value("mode", self.ui.mode_tab_widget.tabText(index)) + self.settings_manager.set_value("settings.mode", self.ui.mode_tab_widget.tabText(index)) def on_show(self): pass @@ -472,23 +499,23 @@ def action_redo_triggered(self): self.redo() def action_paste_image_triggered(self): - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.canvas_widget.paste_image_from_clipboard() def action_copy_image_triggered(self): - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.canvas_widget.copy_image(self.current_active_image()) def action_cut_image_triggered(self): - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.canvas_widget.cut_image() def action_rotate_90_clockwise_triggered(self): - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.canvas_widget.rotate_90_clockwise() def action_rotate_90_counterclockwise_triggered(self): - if self.settings_manager.mode == Mode.IMAGE.value: + if self.settings_manager.settings.mode == Mode.IMAGE.value: self.canvas_widget.rotate_90_counterclockwise() def action_show_prompt_browser_triggered(self): @@ -605,7 +632,7 @@ def action_toggle_active_grid_area(self, active): self.ui.toggle_eraser_button.setChecked(False) def action_toggle_nsfw_filter_triggered(self, bool): - self.settings_manager.set_value("nsfw_filter", bool) + self.settings_manager.set_value("settings.nsfw_filter", bool) self.toggle_nsfw_filter() def action_toggle_grid(self, active): @@ -643,38 +670,25 @@ def action_open_discord(self): webbrowser.open("https://discord.gg/ukcgjEpc5f") def tool_tab_index_changed(self, index): - session = get_session() - tab_section = session.query(TabSection).filter_by( - panel="tool_tab_widget" - ).first() - tab_section.active_tab = self.ui.tool_tab_widget.tabText(index) - session.commit() + with session_scope() as session: + tab_section = session.query(TabSection).filter_by( + panel="tool_tab_widget" + ).first() + tab_section.active_tab = self.ui.tool_tab_widget.tabText(index) def center_panel_tab_index_changed(self, val): - session = get_session() - tab_section = session.query(TabSection).filter_by( - panel="center_tab" - ).first() - tab_section.active_tab = self.ui.center_tab.tabText(val) - - session.commit() + with session_scope() as session: + tab_section = session.query(TabSection).filter_by( + panel="center_tab" + ).first() + tab_section.active_tab = self.ui.center_tab.tabText(val) def bottom_panel_tab_index_changed(self, index): - session = get_session() - tab_section = session.query(TabSection).filter_by( - panel="bottom_panel_tab_widget" - ).first() - tab_section.active_tab = self.ui.bottom_panel_tab_widget.tabText(index) - session.commit() - - def right_splitter_moved(self, size, index): - print("right_splitter_moved") - - def main_splitter_moved(self, size, index): - print("main_splitter_moved") - - def content_splitter_moved(self, size, index): - print("content_splitter_moved") + with session_scope() as session: + tab_section = session.query(TabSection).filter_by( + panel="bottom_panel_tab_widget" + ).first() + tab_section.active_tab = self.ui.bottom_panel_tab_widget.tabText(index) """ End slot functions @@ -695,27 +709,11 @@ def toggle_nsfw_filter(self): self.set_nsfw_filter_tooltip() def set_nsfw_filter_tooltip(self): - nsfw_filter = self.settings_manager.nsfw_filter + nsfw_filter = self.settings_manager.settings.nsfw_filter self.ui.safety_checker_button.setToolTip( f"Click to {'enable' if not nsfw_filter else 'disable'} NSFW filter" ) - # def resizeEvent(self, event): - # if not self.is_started: - # return - # state = self.windowState() - # if state == Qt.WindowState.WindowMaximized: - # timer = QTimer(self) - # timer.setSingleShot(True) - # timer.timeout.connect(self.checkWindowState) - # timer.start(100) - # else: - # self.checkWindowState() - - # def checkWindowState(self): - # state = self.windowState() - # self.is_maximized = state == Qt.WindowState.WindowMaximized - def dragmode_pressed(self): # self.canvas_widget.is_canvas_drag_mode = True pass @@ -747,9 +745,32 @@ def toggle_fullscreen(self): def quit(self): self.close() + ##### Window properties ##### + # Use this to set and restore window properties + # Such as splitter positions, window size, etc + # TODO: complete this def closeEvent(self, event): logger.info("Quitting") + self.save_state() + event.accept() QApplication.quit() + + def save_state(self): + # TODO: + # self.settings.setValue("splitterSizes", self.splitter.saveState()) + # self.settings.setValue("currentTabIndex", self.tabWidget.currentIndex()) + pass + + def restore_state(self): + # TODO: + # splitter_sizes = self.settings.value("splitterSizes") + # if splitter_sizes is not None: + # self.splitter.restoreState(splitter_sizes) + # current_tab_index = self.settings.value("currentTabIndex", 0, type=int) + # self.tabWidget.setCurrentIndex(current_tab_index) + pass + ##### End window properties ##### + ################################# def timerEvent(self, event): # self.canvas_widget.timerEvent(event) @@ -802,20 +823,17 @@ def initialize(self): # self.automatic_filter_manager.register_filter(PixelFilter, base_size=256) self.input_event_manager = InputEventManager(app=self) - self.initialize_splitter_sizes() - self.initialize_settings_manager() self.initialize_window() self.initialize_handlers() - self.connect_splitter_handlers() self.initialize_mixins() self.generate_signal.connect(self.handle_generate) # self.header_widget.initialize() # self.header_widget.set_size_increment_levels() self.initialize_shortcuts() self.initialize_stable_diffusion() - if self.settings_manager.force_reset: + if self.settings_manager.settings.force_reset: self.reset_settings() - self.settings_manager.set_value("force_reset", False) + self.settings_manager.set_value("settingsforce_reset", False) # self.actionShow_Active_Image_Area.setChecked( # self.settings_manager.show_active_image_area == True # ) @@ -829,7 +847,7 @@ def initialize(self): def initialize_filter_actions(self): # add more filters: - for filter in self.settings_manager.get_image_filters(): + for filter in self.settings_manager.image_filters.get_properties(): action = self.ui.menuFilters.addAction(filter.display_name) action.triggered.connect(partial(self.display_filter_window, filter)) @@ -846,11 +864,11 @@ def initialize_default_buttons(self): self.ui.toggle_eraser_button.blockSignals(True) self.ui.toggle_grid_button.blockSignals(True) self.ui.ai_button.blockSignals(True) - self.ui.toggle_active_grid_area_button.setChecked(self.settings_manager.current_tool == "active_grid_area") - self.ui.toggle_brush_button.setChecked(self.settings_manager.current_tool == "brush") - self.ui.toggle_eraser_button.setChecked(self.settings_manager.current_tool == "eraser") + self.ui.toggle_active_grid_area_button.setChecked(self.settings_manager.settings.current_tool == "active_grid_area") + self.ui.toggle_brush_button.setChecked(self.settings_manager.settings.current_tool == "brush") + self.ui.toggle_eraser_button.setChecked(self.settings_manager.settings.current_tool == "eraser") self.ui.toggle_grid_button.setChecked(self.settings_manager.grid_settings.show_grid is True) - self.ui.ai_button.setChecked(self.settings_manager.ai_mode is True) + self.ui.ai_button.setChecked(self.settings_manager.settings.ai_mode is True) self.ui.toggle_active_grid_area_button.blockSignals(False) self.ui.toggle_brush_button.blockSignals(False) self.ui.toggle_eraser_button.blockSignals(False) @@ -864,7 +882,7 @@ def handle_button_clicked(self, kwargs): self.toggle_tool(kwargs["tool"]) def toggle_tool(self, tool): - self.settings_manager.set_value("current_tool", tool) + self.settings_manager.set_value("settings.current_tool", tool) def initialize_mixins(self): HistoryMixin.initialize(self) @@ -879,100 +897,6 @@ def connect_signals(self): self.button_clicked_signal.connect(self.handle_button_clicked) - def initialize_splitter_sizes(self): - self.splitters = dict( - main=dict( - moved=False, - sizes=None, - ), - content=dict( - moved=False, - sizes=None, - ), - canvas=dict( - moved=False, - sizes=None - ) - ) - splitter_names = ["main", "content", "canvas"] - session = get_session() - for name in splitter_names: - self.splitters[name]["sizes"] = session.query(SplitterSection).filter( - SplitterSection.name == f"{name}_splitter" - ).order_by( - SplitterSection.order - ).all() - - def start_splitter_timer(self): - self.timer = QTimer() - self.timer.timeout.connect(self.save_splitters_sizes) - self.timer.start(1000) - - def connect_splitter_handlers(self): - splitter_names = ["content", "main", "canvas"] - for name in splitter_names: - getattr(self.ui, f"{name}_splitter").splitterMoved.connect(partial(self.splitter_moved, name)) - - def splitter_moved(self, key, pos, index): - self.splitters[key]["moved"] = True - sizes = self.splitters[key]["sizes"] - updated_sizes = [] - if key == "content": - col_a_width = self.ui.content_splitter.widget(0).width() - col_b_width = self.ui.content_splitter.widget(1).width() - col_c_width = self.ui.content_splitter.widget(2).width() - window_width = self.width() - - if index == 2 and window_width - pos == 60: - col_c_width = 0 - if index == 1 and pos == 1: - col_a_width = 0 - if index == 1: - col_c_width = sizes[2].size - if index == 2: - col_a_width = sizes[0].size - updated_sizes = [col_a_width, col_b_width, col_c_width] - elif key == "main": - updated_sizes = [ - self.ui.main_splitter.widget(0).height(), - self.ui.main_splitter.widget(1).height() - ] - elif key == "canvas": - updated_sizes = [ - self.ui.canvas_splitter.widget(0).width(), - self.ui.canvas_splitter.widget(1).width() - ] - for i, size in enumerate(updated_sizes): - self.splitters[key]["sizes"][i].size = size - - def save_splitters_sizes(self): - do_save = False - session = get_session() - for key, val in self.splitters.items(): - if val["moved"] is True: - val["moved"] = False - do_save = True - for size in val["sizes"]: - session.add(size) - if do_save: - save_session() - - def set_splitter_sizes(self): - """ - Splitters are used to divide the window into sections. This function - intializes the sizes of each splitter section. The sizes are stored - in the database and are loaded when the application starts. - - The SplitterSection model is used to store the sizes. - The name field for each SplitterSection is set to the name of its - corresponding widget. - """ - splitter_names = ["main", "content", "canvas"] - for name in splitter_names: - splitter_sections = self.splitters[name]["sizes"] - splitter_sizes = [obj.size for obj in splitter_sections] - getattr(self.ui, f"{name}_splitter").setSizes(splitter_sizes) - def show_section(self, section): section_lists = { "center": [self.ui.center_tab.tabText(i) for i in range(self.ui.center_tab.count())], @@ -1021,31 +945,6 @@ def handle_value_change(self, attr_name, value=None, widget=None): def handle_similar_slider_change(self, attr_name, value=None, widget=None): self.standard_image_panel.handle_similar_slider_change(value) - def initialize_settings_manager(self): - self.settings_manager.changed_signal.connect(self.handle_changed_signal) - - def handle_changed_signal(self, key, value): - if key == "size": - self.set_size_form_element_step_values() - elif key == "line_width": - self.set_size_form_element_step_values() - elif key == "show_grid": - self.canvas_widget.update() - elif key == "snap_to_grid": - self.canvas_widget.update() - elif key == "line_color": - self.canvas_widget.update_grid_pen() - elif key == "lora_path": - self.refresh_lora() - elif key == "model_base_path": - self.generator_tab_widget.refresh_model_list() - elif key == "generator.seed": - self.prompt_builder.process_prompt() - # elif key == "use_prompt_builder_checkbox": - # self.generator_tab_widget.toggle_all_prompt_builder_checkboxes(value) - elif key == "models": - self.model_manager.models_changed(key, value) - def initialize_shortcuts(self): event_callbacks = { "wheelEvent": self.handle_wheel_event, @@ -1091,7 +990,6 @@ def set_window_state(self): self.showMaximized() else: self.showNormal() - self.set_splitter_sizes() def set_log_levels(self): uic.properties.logger.setLevel(LOG_LEVEL) @@ -1111,8 +1009,8 @@ def handle_wheel_event(self, event): if QtCore.Qt.KeyboardModifier.ShiftModifier in event.modifiers(): delta = event.angleDelta().y() increment = grid_size if delta > 0 else -grid_size - val = self.settings_manager.working_width + increment - self.settings_manager.set_value("working_width", val) + val = self.settings_manager.settings.working_width + increment + self.settings_manager.set_value("settings.working_width", val) except TypeError: pass @@ -1121,8 +1019,8 @@ def handle_wheel_event(self, event): if QtCore.Qt.KeyboardModifier.ControlModifier in event.modifiers(): delta = event.angleDelta().y() increment = grid_size if delta > 0 else -grid_size - val = self.settings_manager.working_height + increment - self.settings_manager.set_value("working_height", val) + val = self.settings_manager.settings.working_height + increment + self.settings_manager.set_value("settings.working_height", val) except TypeError: pass @@ -1283,24 +1181,24 @@ def insert_into_prompt(self, text, negative_prompt=False): prompt_widget.setPlainText(text) def change_content_widget(self): - session = get_session() - active_tab_obj = session.query(TabSection).filter( - TabSection.panel == "center_tab" - ).first() - active_tab = active_tab_obj.active_tab - self.ui.center_tab.blockSignals(True) - if active_tab == "Prompt Builder": - tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, f"tab_prompt_builder")) - print("switching to tab_index", tab_index) - self.ui.center_tab.setCurrentIndex(tab_index) - elif self.settings_manager.generator_section == "txt2vid": - # get tab by name Video - tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, "tab_txt2vid")) - self.ui.center_tab.setCurrentIndex(tab_index) - else: - tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, f"tab_image")) - self.ui.center_tab.setCurrentIndex(tab_index) - self.ui.center_tab.blockSignals(False) + with session_scope() as session: + active_tab_obj = session.query(TabSection).filter( + TabSection.panel == "center_tab" + ).first() + active_tab = active_tab_obj.active_tab + self.ui.center_tab.blockSignals(True) + if active_tab == "Prompt Builder": + tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, f"tab_prompt_builder")) + print("switching to tab_index", tab_index) + self.ui.center_tab.setCurrentIndex(tab_index) + elif self.settings_manager.settings.generator_section == "txt2vid": + # get tab by name Video + tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, "tab_txt2vid")) + self.ui.center_tab.setCurrentIndex(tab_index) + else: + tab_index = self.ui.center_tab.indexOf(self.ui.center_tab.findChild(QWidget, f"tab_image")) + self.ui.center_tab.setCurrentIndex(tab_index) + self.ui.center_tab.blockSignals(False) def clear_all_prompts(self): self.prompt = "" @@ -1326,7 +1224,7 @@ def choose_image_export_path(self): path = QFileDialog.getExistingDirectory(None, "Select Directory") if path == "": return - self.settings_manager.set_value("image_path", path) + self.settings_manager.set_value("path_settings.image_path", path) def display_file_export_dialog(self): return QFileDialog.getSaveFileName( @@ -1363,12 +1261,12 @@ def new_batch(self, index, image, data): self.generator_tab_widget.new_batch(index, image, data) def image_generation_toggled(self): - self.settings_manager.set_value("mode", Mode.IMAGE.value) + self.settings_manager.set_value("settings.mode", Mode.IMAGE.value) self.activate_image_generation_section() self.set_all_section_buttons() def language_processing_toggled(self): - self.settings_manager.set_value("mode", Mode.LANGUAGE_PROCESSOR.value) + self.settings_manager.set_value("settings.mode", Mode.LANGUAGE_PROCESSOR.value) self.activate_language_processing_section() self.set_all_section_buttons() @@ -1376,7 +1274,7 @@ def model_manager_toggled(self, val): if not val: self.image_generators_toggled() else: - self.settings_manager.set_value("mode", Mode.MODEL_MANAGER.value) + self.settings_manager.set_value("settings.mode", Mode.MODEL_MANAGER.value) self.activate_model_manager_section() self.set_all_section_buttons() @@ -1389,7 +1287,7 @@ def set_button_checked(self, name, val=True, block_signals=True): widget.blockSignals(False) def set_all_section_buttons(self): - self.set_button_checked("model_manager", self.settings_manager.mode == Mode.MODEL_MANAGER.value) + self.set_button_checked("model_manager", self.settings_manager.settings.mode == Mode.MODEL_MANAGER.value) def activate_image_generation_section(self): self.ui.mode_tab_widget.setCurrentIndex(0) @@ -1404,45 +1302,42 @@ def initialize_tool_section_buttons(self): pass def set_all_image_generator_buttons(self): - is_image_generators = self.settings_manager.generator_section == GeneratorSection.TXT2IMG.value - is_txt2vid = self.settings_manager.generator_section == GeneratorSection.TXT2VID.value - is_prompt_builder = self.settings_manager.generator_section == GeneratorSection.PROMPT_BUILDER.value + is_image_generators = self.settings_manager.settings.generator_section == GeneratorSection.TXT2IMG.value + is_txt2vid = self.settings_manager.settings.generator_section == GeneratorSection.TXT2VID.value + is_prompt_builder = self.settings_manager.settings.generator_section == GeneratorSection.PROMPT_BUILDER.value def image_generators_toggled(self): - session = get_session() - self.image_generation_toggled() - self.settings_manager.set_value("mode", Mode.IMAGE.value) - self.settings_manager.set_value("generator_section", GeneratorSection.TXT2IMG.value) - active_tab_obj = session.query(TabSection).filter(TabSection.panel == "center_tab").first() - active_tab_obj.active_tab = "Canvas" - save_session() - self.set_all_image_generator_buttons() - self.change_content_widget() + with session_scope() as session: + self.image_generation_toggled() + self.settings_manager.set_value("settings.mode", Mode.IMAGE.value) + self.settings_manager.set_value("settings.generator_section", GeneratorSection.TXT2IMG.value) + active_tab_obj = session.query(TabSection).filter(TabSection.panel == "center_tab").first() + active_tab_obj.active_tab = "Canvas" + self.set_all_image_generator_buttons() + self.change_content_widget() def text_to_video_toggled(self): - session = get_session() - self.image_generation_toggled() - self.settings_manager.set_value("mode", Mode.IMAGE.value) - self.settings_manager.set_value("generator_section", GeneratorSection.TXT2VID.value) - active_tab_obj = session.query(TabSection).filter(TabSection.panel == "center_tab").first() - active_tab_obj.active_tab = "Video" - save_session() - self.set_all_image_generator_buttons() - self.change_content_widget() - - def toggle_prompt_builder(self, val): - session = get_session() - if not val: - self.image_generators_toggled() - else: + with session_scope() as session: self.image_generation_toggled() - self.settings_manager.set_value(f"generator_section", GeneratorSection.PROMPT_BUILDER.value) + self.settings_manager.set_value("settings.mode", Mode.IMAGE.value) + self.settings_manager.set_value("settings.generator_section", GeneratorSection.TXT2VID.value) active_tab_obj = session.query(TabSection).filter(TabSection.panel == "center_tab").first() - active_tab_obj.active_tab = "Prompt Builder" - save_session() + active_tab_obj.active_tab = "Video" self.set_all_image_generator_buttons() self.change_content_widget() + def toggle_prompt_builder(self, val): + with session_scope() as session: + if not val: + self.image_generators_toggled() + else: + self.image_generation_toggled() + self.settings_manager.set_value(f"generator_section", GeneratorSection.PROMPT_BUILDER.value) + active_tab_obj = session.query(TabSection).filter(TabSection.panel == "center_tab").first() + active_tab_obj.active_tab = "Prompt Builder" + self.set_all_image_generator_buttons() + self.change_content_widget() + def redraw(self): self.set_stylesheet() @@ -1453,4 +1348,5 @@ def action_center_clicked(self): print("center clicked") def action_ai_toggled(self, val): - self.settings_manager.set_value("ai_mode", val) + print("ACTION AI TOGGLED") + self.settings_manager.set_value("settings.ai_mode", val) diff --git a/src/airunner/windows/main/templates/main_window.ui b/src/airunner/windows/main/templates/main_window.ui index b675e7222..a92a4af44 100644 --- a/src/airunner/windows/main/templates/main_window.ui +++ b/src/airunner/windows/main/templates/main_window.ui @@ -615,28 +615,6 @@ - - - Prompt Builder - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - Model Manager @@ -1922,12 +1900,6 @@
airunner/widgets/generator_form/generator_form_widget
1 - - PromptBuilderWidget - QWidget -
airunner/widgets/prompt_builder/prompt_builder_widget
- 1 -
ModelManagerWidget QWidget @@ -2562,22 +2534,6 @@ - - center_tab - currentChanged(int) - MainWindow - center_panel_tab_index_changed(int) - - - 536 - 392 - - - 1002 - 0 - - - settings_button clicked() @@ -2818,6 +2774,22 @@ + + center_tab + currentChanged(int) + MainWindow + center_panel_tab_index_changed(int) + + + 536 + 392 + + + 1002 + 0 + + + diff --git a/src/airunner/windows/main/templates/main_window_ui.py b/src/airunner/windows/main/templates/main_window_ui.py index 303aa659c..eeb58aea7 100644 --- a/src/airunner/windows/main/templates/main_window_ui.py +++ b/src/airunner/windows/main/templates/main_window_ui.py @@ -230,15 +230,6 @@ def setupUi(self, MainWindow): self.image_browser.setObjectName("image_browser") self.gridLayout_10.addWidget(self.canvas_splitter, 0, 0, 1, 1) self.center_tab.addTab(self.tab_image, "") - self.tab_prompt_builder = QtWidgets.QWidget() - self.tab_prompt_builder.setObjectName("tab_prompt_builder") - self.gridLayout_16 = QtWidgets.QGridLayout(self.tab_prompt_builder) - self.gridLayout_16.setContentsMargins(0, 0, 0, 0) - self.gridLayout_16.setObjectName("gridLayout_16") - self.prompt_builder = PromptBuilderWidget(parent=self.tab_prompt_builder) - self.prompt_builder.setObjectName("prompt_builder") - self.gridLayout_16.addWidget(self.prompt_builder, 0, 0, 1, 1) - self.center_tab.addTab(self.tab_prompt_builder, "") self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") self.gridLayout_7 = QtWidgets.QGridLayout(self.tab) @@ -801,7 +792,6 @@ def setupUi(self, MainWindow): self.actionDeterministic_Batches.triggered.connect(MainWindow.action_show_deterministic_batches) # type: ignore self.actionStandard_Batches.triggered.connect(MainWindow.action_show_standard_batches) # type: ignore self.actionLLM_beta.triggered.connect(MainWindow.action_show_llm) # type: ignore - self.center_tab.currentChanged['int'].connect(MainWindow.center_panel_tab_index_changed) # type: ignore self.settings_button.clicked.connect(MainWindow.action_show_settings) # type: ignore self.toggle_grid_button.toggled['bool'].connect(MainWindow.action_toggle_grid) # type: ignore self.toggle_active_grid_area_button.toggled['bool'].connect(MainWindow.action_toggle_active_grid_area) # type: ignore @@ -817,6 +807,7 @@ def setupUi(self, MainWindow): self.undo_button.clicked.connect(MainWindow.action_undo_triggered) # type: ignore self.redo_button.clicked.connect(MainWindow.action_redo_triggered) # type: ignore self.model_manager_button.toggled['bool'].connect(MainWindow.model_manager_toggled) # type: ignore + self.center_tab.currentChanged['int'].connect(MainWindow.center_panel_tab_index_changed) # type: ignore QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): @@ -829,7 +820,6 @@ def retranslateUi(self, MainWindow): self.undo_button.setToolTip(_translate("MainWindow", "Undo")) self.redo_button.setToolTip(_translate("MainWindow", "Redo")) self.center_tab.setTabText(self.center_tab.indexOf(self.tab_image), _translate("MainWindow", "Canvas")) - self.center_tab.setTabText(self.center_tab.indexOf(self.tab_prompt_builder), _translate("MainWindow", "Prompt Builder")) self.center_tab.setTabText(self.center_tab.indexOf(self.tab), _translate("MainWindow", "Model Manager")) self.tool_tab_widget.setTabText(self.tool_tab_widget.indexOf(self.tab_pen), _translate("MainWindow", "Pen")) self.tool_tab_widget.setTabText(self.tool_tab_widget.indexOf(self.tab_active_grid), _translate("MainWindow", "Active Grid")) @@ -974,4 +964,3 @@ def retranslateUi(self, MainWindow): from airunner.widgets.image.image_panel_widget import ImagePanelWidget from airunner.widgets.layers.layer_container_widget import LayerContainerWidget from airunner.widgets.model_manager.model_manager_widget import ModelManagerWidget -from airunner.widgets.prompt_builder.prompt_builder_widget import PromptBuilderWidget diff --git a/src/airunner/windows/model_merger.py b/src/airunner/windows/model_merger.py index 935fb6b5a..7f146da09 100644 --- a/src/airunner/windows/model_merger.py +++ b/src/airunner/windows/model_merger.py @@ -43,15 +43,15 @@ def section(self): def output_path(self): output_path = None if self.section == "outpaint": - output_path = self.settings_manager.path_settings.outpaint_model_path + output_path = self.app.settings_manager.path_settings.outpaint_model_path elif self.section == "depth2img": - output_path = self.settings_manager.path_settings.depth2img_model_path + output_path = self.app.settings_manager.path_settings.depth2img_model_path elif self.section == "pix2pix": - output_path = self.settings_manager.path_settings.pix2pix_model_path + output_path = self.app.settings_manager.path_settings.pix2pix_model_path elif self.section == "upscale": - output_path = self.settings_manager.path_settings.upscale_model_path + output_path = self.app.settings_manager.path_settings.upscale_model_path if not output_path or output_path == "": - output_path = self.settings_manager.path_settings.model_base_path + output_path = self.app.settings_manager.path_settings.model_base_path return output_path def change_model_type(self, index): @@ -143,7 +143,7 @@ def finalize_merge(self): def do_model_merge(self): models = [] weights = [] - path = self.settings_manager.path_settings.model_base_path + path = self.app.settings_manager.path_settings.model_base_path for widget in self.widgets: if widget.models.currentText() != "": diff --git a/src/airunner/windows/prompt_browser/prompt_browser.py b/src/airunner/windows/prompt_browser/prompt_browser.py index 96e4f4ef7..ad1d9b12c 100644 --- a/src/airunner/windows/prompt_browser/prompt_browser.py +++ b/src/airunner/windows/prompt_browser/prompt_browser.py @@ -7,6 +7,6 @@ class PromptBrowser(BaseWindow): template_class_ = Ui_prompt_browser def initialize_window(self): - for index, prompt_data in enumerate(self.settings_manager.prompts): + for index, prompt_data in enumerate(self.app.settings_manager.prompts): widget = PromptWidget(prompt_data=prompt_data) self.ui.scrollAreaWidgetContents.layout().addWidget(widget) \ No newline at end of file diff --git a/src/airunner/windows/prompt_browser/prompt_widget.py b/src/airunner/windows/prompt_browser/prompt_widget.py index 28be14f29..3fdaea9b4 100644 --- a/src/airunner/windows/prompt_browser/prompt_widget.py +++ b/src/airunner/windows/prompt_browser/prompt_widget.py @@ -1,6 +1,6 @@ -from airunner.utils import save_session, get_session from airunner.widgets.base_widget import BaseWidget from airunner.windows.prompt_browser.templates.prompt_browser_prompt_widget_ui import Ui_prompt_widget +from airunner.data.session_scope import session_scope class PromptWidget(BaseWidget): @@ -22,12 +22,12 @@ def action_clicked_button_load(self): self.app.load_prompt(self.prompt_data) def action_clicked_button_delete(self): - session = get_session() - session.delete(self.prompt_data) - save_session() + with session_scope() as session: + session.delete(self.prompt_data) self.deleteLater() def save_prompt(self): - self.prompt_data.prompt = self.ui.prompt.toPlainText() - self.prompt_data.negative_prompt = self.ui.negative_prompt.toPlainText() - save_session() + with session_scope() as session: + session.add(self.prompt_data) + self.prompt_data.prompt = self.ui.prompt.toPlainText() + self.prompt_data.negative_prompt = self.ui.negative_prompt.toPlainText() diff --git a/src/airunner/windows/settings/airunner_settings.py b/src/airunner/windows/settings/airunner_settings.py index 13f6c8261..af5ad674e 100644 --- a/src/airunner/windows/settings/airunner_settings.py +++ b/src/airunner/windows/settings/airunner_settings.py @@ -228,22 +228,22 @@ def on_item_clicked(self, index): if name == "resize_on_import": checked = item.checkState() == Qt.CheckState.Checked - self.app.settings_manager.set_value("resize_on_paste", checked) + self.app.settings_manager.set_value("settings.resize_on_paste", checked) elif name == "image_to_new_layer": checked = item.checkState() == Qt.CheckState.Checked - self.app.settings_manager.set_value("image_to_new_layer", checked) + self.app.settings_manager.set_value("settings.image_to_new_layer", checked) elif name == "dark_mode": checked = item.checkState() == Qt.CheckState.Checked - self.app.settings_manager.set_value("dark_mode_enabled", checked) + self.app.settings_manager.set_value("settings.dark_mode_enabled", checked) elif name == "check_for_updates": checked = item.checkState() == Qt.CheckState.Checked - self.app.settings_manager.set_value("latest_version_check", checked) + self.app.settings_manager.set_value("settings.latest_version_check", checked) elif name == "enable_tts": checked = item.checkState() == Qt.CheckState.Checked - self.app.settings_manager.set_value("enable_tts", checked) + self.app.settings_manager.set_value("settings.enable_tts", checked) elif name == "allow_online_mode": checked = item.checkState() == Qt.CheckState.Checked - self.settings_manager.set_value("allow_online_mode", checked) + self.settings_manager.set_value("settings.allow_online_mode", checked) elif name == "reset_settings": self.app.reset_settings() self.show_content(section, display_name, name, description)