Squashed commit of the following:
commit 9d1667049d84a462c5e89b3df15a8b370323dcf8
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Wed Dec 7 23:09:58 2022 +0900
show what tags are "selected"
commit d2f385a5fb0073d2ba7809359b2ce29f1110ae64
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Wed Dec 7 22:52:37 2022 +0900
invert behavior in exclusive filter
commit ba6ff5e00f85fbdf074d073ccc7dbb7eb0258a89
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Wed Dec 7 22:46:47 2022 +0900
Update main.py
commit 76067e51a3fd0bca421a6b258cf872275c7f7b11
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Wed Dec 7 22:40:56 2022 +0900
logic filter, batch text search and replace
#11 #13 #15
commit f3688fa6aa3ec8e2b1e964a7d4291185ebd7f100
Merge: 05412b1 fddf4d9
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Wed Dec 7 00:26:23 2022 +0900
Merge branch 'main' into logic-filter
commit 05412b1afdda7ac32467298e407a1f83e2a70690
Merge: cfbeec2 3c5987e
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Tue Dec 6 01:06:37 2022 +0900
Merge branch 'main' into logic-filter
commit cfbeec208fa0645df7912f2bc43959ee704bdbcb
Merge: 88ecf79 d46f1a5
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Mon Dec 5 08:48:59 2022 +0900
Merge branch 'main' into logic-filter
commit 88ecf79d8dc11c6e5a686e0154fbd6d40d2474d2
Merge: a746882 c3d3a69
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Mon Dec 5 08:29:09 2022 +0900
Merge branch 'main' into logic-filter
commit a746882aab440396a3e24a6bd6f7eb022ec67cb8
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Mon Dec 5 00:58:57 2022 +0900
replace text( on the way)
#13
commit 9018e4c5754ef06caad733302cb7bfa3c9083188
Author: toshiaki1729 <116595002+toshiaki1729@users.noreply.github.com>
Date: Sun Dec 4 19:05:58 2022 +0900
separate tag replace feature from tag filter feature
pull/41/head
parent
fddf4d940d
commit
a3a2e4a8b3
|
|
@ -79,3 +79,6 @@ class Dataset:
|
|||
tags |= data.tagset
|
||||
return tags
|
||||
|
||||
def get_taglist(self):
|
||||
return [t for t in self.get_tagset()]
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class DatasetTagEditor:
|
|||
|
||||
def write_tags(self, tags: List[str]):
|
||||
if tags:
|
||||
return [f'{tag} [{self.tag_counts.get(tag)}]' for tag in tags if tag]
|
||||
return [f'{tag} [{self.tag_counts.get(tag) or 0}]' for tag in tags if tag]
|
||||
else:
|
||||
return []
|
||||
|
||||
|
|
@ -116,23 +116,42 @@ class DatasetTagEditor:
|
|||
return []
|
||||
|
||||
|
||||
def get_filtered_imgpath_and_tags(self, filters: List[Dataset.Filter] = [], filter_word: Optional[str] = None) -> Tuple[List[str], Set[str]]:
|
||||
def get_filtered_imgpaths(self, filters: List[Dataset.Filter] = []):
|
||||
filtered_set = self.dataset.copy()
|
||||
for filter in filters:
|
||||
filtered_set.filter(filter)
|
||||
|
||||
tag_set = filtered_set.get_tagset()
|
||||
img_paths = sorted(filtered_set.datas.keys())
|
||||
|
||||
if filter_word:
|
||||
# all tags with filter_word
|
||||
tag_set = {tag for tag in tag_set if filter_word in tag}
|
||||
|
||||
return (img_paths, tag_set)
|
||||
return img_paths
|
||||
|
||||
|
||||
def get_filtered_tags(self, filters: List[Dataset.Filter] = [], filter_word: str = '', filter_tags = True):
|
||||
if filter_tags:
|
||||
filtered_set = self.dataset.copy()
|
||||
for filter in filters:
|
||||
filtered_set.filter(filter)
|
||||
tags = filtered_set.get_tagset()
|
||||
else:
|
||||
tags = self.dataset.get_tagset()
|
||||
|
||||
return {tag for tag in tags if filter_word in tag}
|
||||
|
||||
|
||||
def get_common_tags(self, filters: List[Dataset.filter] = []):
|
||||
filtered_set = self.dataset.copy()
|
||||
for filter in filters:
|
||||
filtered_set.filter(filter)
|
||||
|
||||
result = filtered_set.get_tagset()
|
||||
for d in filtered_set.datas.values():
|
||||
result &= d.tagset
|
||||
|
||||
return sorted(result)
|
||||
|
||||
|
||||
def replace_tags(self, search_tags: List[str], replace_tags: List[str], filters: List[Dataset.Filter] = [], prepend: bool = False):
|
||||
img_paths, _ = self.get_filtered_imgpath_and_tags(filters=filters)
|
||||
img_paths = self.get_filtered_imgpaths(filters=filters)
|
||||
tags_to_append = replace_tags[len(search_tags):]
|
||||
tags_to_remove = search_tags[len(replace_tags):]
|
||||
tags_to_replace = {}
|
||||
|
|
@ -148,6 +167,42 @@ class DatasetTagEditor:
|
|||
|
||||
self.construct_tag_counts()
|
||||
|
||||
def get_replaced_tagset(self, tags: Set[str], search_tags: List[str], replace_tags: List[str]):
|
||||
tags_to_remove = search_tags[len(replace_tags):]
|
||||
tags_to_replace = {}
|
||||
for i in range(min(len(search_tags), len(replace_tags))):
|
||||
if replace_tags[i] is None or replace_tags[i] == '':
|
||||
tags_to_remove.append(search_tags[i])
|
||||
else:
|
||||
tags_to_replace[search_tags[i]] = replace_tags[i]
|
||||
tags_removed = {t for t in tags if t not in tags_to_remove}
|
||||
tags_replaced = {tags_to_replace.get(t) if t in tags_to_replace.keys() else t for t in tags_removed}
|
||||
return {t for t in tags_replaced if t}
|
||||
|
||||
|
||||
def search_and_replace_caption(self, search_text: str, replace_text: str, filters: List[Dataset.Filter] = []):
|
||||
img_paths = self.get_filtered_imgpaths(filters=filters)
|
||||
|
||||
for img_path in img_paths:
|
||||
caption = ', '.join(self.dataset.get_data_tags(img_path))
|
||||
caption = [t.strip() for t in caption.replace(search_text, replace_text).split(',')]
|
||||
self.set_tags_by_image_path(img_path, caption)
|
||||
|
||||
self.construct_tag_counts()
|
||||
|
||||
|
||||
def search_and_replace_selected_tags(self, search_text: str, replace_text: str, selected_tags = List[str], filters: List[Dataset.Filter] = []):
|
||||
img_paths = self.get_filtered_imgpaths(filters=filters)
|
||||
|
||||
selected_tags = set(selected_tags)
|
||||
|
||||
for img_path in img_paths:
|
||||
tags = self.dataset.get_data_tags(img_path)
|
||||
tags = [t.replace(search_text, replace_text) if t in selected_tags else t for t in tags]
|
||||
self.set_tags_by_image_path(img_path, tags)
|
||||
|
||||
self.construct_tag_counts()
|
||||
|
||||
|
||||
def get_img_path_list(self):
|
||||
return [k for k in self.dataset.datas.keys() if k]
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class TagFilter(Dataset.Filter):
|
|||
self.mode = mode
|
||||
|
||||
def apply(self, dataset: Dataset):
|
||||
if self.logic == TagFilter.Logic.NONE or self.mode == TagFilter.Logic.NONE:
|
||||
if not self.tags or self.logic == TagFilter.Logic.NONE or self.mode == TagFilter.Logic.NONE:
|
||||
return dataset
|
||||
|
||||
paths_remove = []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
from scripts.dataset_tag_editor.filters import TagFilter
|
||||
from scripts.dataset_tag_editor.dataset_tag_editor import DatasetTagEditor
|
||||
from scripts.dataset_tag_editor.dataset import Dataset
|
||||
from typing import List, Callable
|
||||
|
||||
class TagFilterUI:
|
||||
def __init__(self, dataset_tag_editor: DatasetTagEditor, tag_filter_mode: TagFilter.Mode = TagFilter.Mode.INCLUSIVE):
|
||||
self.logic = TagFilter.Logic.NONE
|
||||
self.filter_word = ''
|
||||
self.sort_by = 'Alphabetical Order'
|
||||
self.sort_order = 'Ascending'
|
||||
self.selected_tags = []
|
||||
self.filter_mode = tag_filter_mode
|
||||
self.filter = TagFilter({}, self.logic, self.filter_mode)
|
||||
self.dataset_tag_editor = dataset_tag_editor
|
||||
self.get_filters = lambda:[]
|
||||
|
||||
def get_filter(self):
|
||||
return self.filter
|
||||
|
||||
def create_ui(self, get_filters: Callable[[], List[Dataset.Filter]]):
|
||||
self.get_filters = get_filters
|
||||
|
||||
import gradio as gr
|
||||
self.tb_search_tags = gr.Textbox(label='Search Tags', interactive=True)
|
||||
with gr.Row():
|
||||
self.rd_sort_by = gr.Radio(choices=['Alphabetical Order', 'Frequency'], value='Alphabetical Order', interactive=True, label='Sort by')
|
||||
self.rd_sort_order = gr.Radio(choices=['Ascending', 'Descending'], value='Ascending', interactive=True, label='Sort Order')
|
||||
self.rd_logic = gr.Radio(choices=['NONE', 'AND', 'OR'], value='NONE', label='Filter Logic', interactive=True)
|
||||
self.cbg_tags = gr.CheckboxGroup(label='Filter Images by Tags', interactive=True)
|
||||
|
||||
|
||||
def set_callbacks(self, on_filter_update: Callable[[], List] = lambda:[], outputs=None):
|
||||
self.tb_search_tags.change(fn=self.tb_search_tags_changed, inputs=self.tb_search_tags, outputs=self.cbg_tags)
|
||||
self.rd_sort_by.change(fn=self.rd_sort_by_changed, inputs=self.rd_sort_by, outputs=self.cbg_tags)
|
||||
self.rd_sort_order.change(fn=self.rd_sort_order_changed, inputs=self.rd_sort_order, outputs=self.cbg_tags)
|
||||
self.rd_logic.change(fn=lambda a:[self.rd_logic_changed(a)] + on_filter_update(), inputs=self.rd_logic, outputs=[self.cbg_tags] + outputs)
|
||||
self.cbg_tags.change(fn=lambda a:[self.cbg_tags_changed(a)] + on_filter_update(), inputs=self.cbg_tags, outputs=[self.cbg_tags] + outputs)
|
||||
|
||||
|
||||
def tb_search_tags_changed(self, tb_search_tags: str):
|
||||
self.filter_word = tb_search_tags
|
||||
return self.cbg_tags_update()
|
||||
|
||||
|
||||
def rd_sort_by_changed(self, rb_sort_by: str):
|
||||
self.sort_by = rb_sort_by
|
||||
return self.cbg_tags_update()
|
||||
|
||||
|
||||
def rd_sort_order_changed(self, rd_sort_order: str):
|
||||
self.sort_order = rd_sort_order
|
||||
return self.cbg_tags_update()
|
||||
|
||||
|
||||
def rd_logic_changed(self, rd_logic: str):
|
||||
self.logic = TagFilter.Logic.AND if rd_logic == 'AND' else TagFilter.Logic.OR if rd_logic == 'OR' else TagFilter.Logic.NONE
|
||||
self.filter = TagFilter(set(self.selected_tags), self.logic, self.filter_mode)
|
||||
return self.cbg_tags_update()
|
||||
|
||||
|
||||
def cbg_tags_changed(self, cbg_tags: List[str]):
|
||||
self.selected_tags = self.dataset_tag_editor.read_tags(cbg_tags)
|
||||
self.filter = TagFilter(set(self.selected_tags), self.logic, self.filter_mode)
|
||||
return self.cbg_tags_update()
|
||||
|
||||
|
||||
def cbg_tags_update(self):
|
||||
if self.filter_mode == TagFilter.Mode.INCLUSIVE:
|
||||
filtered_tags = self.dataset_tag_editor.get_filtered_tags(self.get_filters(), self.filter_word, self.filter.logic == TagFilter.Logic.AND)
|
||||
else:
|
||||
filtered_tags = self.dataset_tag_editor.get_filtered_tags(self.get_filters(), self.filter_word, self.filter.logic == TagFilter.Logic.OR)
|
||||
tags = self.dataset_tag_editor.sort_tags(tags=filtered_tags, sort_by=self.sort_by, sort_order=self.sort_order)
|
||||
tags_in_filter = self.dataset_tag_editor.sort_tags(tags=list(self.filter.tags), sort_by=self.sort_by, sort_order=self.sort_order)
|
||||
tags = tags_in_filter + [tag for tag in tags if tag not in self.filter.tags]
|
||||
tags = self.dataset_tag_editor.write_tags(tags)
|
||||
tags_in_filter = self.dataset_tag_editor.write_tags(tags_in_filter)
|
||||
|
||||
import gradio as gr
|
||||
return gr.CheckboxGroup.update(value=tags_in_filter, choices=tags)
|
||||
|
||||
|
||||
def clear_filter(self):
|
||||
self.filter = TagFilter()
|
||||
self.filter_word = ''
|
||||
348
scripts/main.py
348
scripts/main.py
|
|
@ -1,38 +1,35 @@
|
|||
from typing import List
|
||||
from typing import List, Set
|
||||
from modules import shared, script_callbacks
|
||||
from modules.shared import opts, cmd_opts
|
||||
import gradio as gr
|
||||
from scripts.dataset_tag_editor.dataset_tag_editor import DatasetTagEditor, interrogate_image_clip, interrogate_image_booru, InterrogateMethod
|
||||
from scripts.dataset_tag_editor.filters import TagFilter, PathFilter
|
||||
from scripts.dataset_tag_editor.ui import TagFilterUI
|
||||
|
||||
dataset_tag_editor = DatasetTagEditor()
|
||||
tag_filter = TagFilter()
|
||||
tag_filter_neg = TagFilter()
|
||||
|
||||
path_filter = PathFilter()
|
||||
tag_filter_ui = TagFilterUI(dataset_tag_editor)
|
||||
tag_filter_ui_neg = TagFilterUI(dataset_tag_editor, TagFilter.Mode.EXCLUSIVE)
|
||||
|
||||
get_filters = lambda:[path_filter, tag_filter_ui.get_filter(), tag_filter_ui_neg.get_filter()]
|
||||
|
||||
total_image_num = 0
|
||||
displayed_image_num = 0
|
||||
current_selection = 0
|
||||
tmp_selection_img_path_set = set()
|
||||
gallery_selected_image_path = ''
|
||||
selection_selected_image_path = ''
|
||||
|
||||
|
||||
# ================================================================
|
||||
# Callbacks for "Filter and Edit Tags" tab
|
||||
# ================================================================
|
||||
|
||||
def arrange_tag_order(tags: List[str], sort_by: str, sort_order: str) -> List[str]:
|
||||
tags = dataset_tag_editor.sort_tags(tags=tags, sort_by=sort_by, sort_order=sort_order)
|
||||
tags_in_filter = [tag for tag in tags if tag in tag_filter.tags]
|
||||
tags = tags_in_filter + [tag for tag in tags if tag not in tag_filter.tags]
|
||||
return tags
|
||||
|
||||
|
||||
def get_current_txt_filter():
|
||||
def get_current_gallery_txt():
|
||||
return f"""
|
||||
Displayed Images : {displayed_image_num} / {total_image_num} total<br>
|
||||
Current Tag Filter : {tag_filter} {'' if not tag_filter_neg.tags else f'AND {tag_filter_neg}'}<br>
|
||||
Current Selection Filter : {current_selection} images<br>
|
||||
Current Tag Filter : {tag_filter_ui.get_filter()} {' AND ' if tag_filter_ui.get_filter().tags and tag_filter_ui_neg.get_filter().tags else ''} {tag_filter_ui_neg.get_filter()}<br>
|
||||
Current Selection Filter : {len(path_filter.paths)} images<br>
|
||||
Selected Image : {gallery_selected_image_path}
|
||||
"""
|
||||
|
||||
|
|
@ -41,8 +38,8 @@ def get_current_txt_selection():
|
|||
return f"""Selected Image : {selection_selected_image_path}"""
|
||||
|
||||
|
||||
def load_files_from_dir(dir: str, sort_by: str, sort_order: str, recursive: bool, load_caption_from_filename: bool, use_interrogator: str, use_clip: bool, use_booru: bool):
|
||||
global total_image_num, displayed_image_num, current_selection, tmp_selection_img_path_set, gallery_selected_image_path, selection_selected_image_path, tag_filter, tag_filter_neg, path_filter
|
||||
def load_files_from_dir(dir: str, recursive: bool, load_caption_from_filename: bool, use_interrogator: str, use_clip: bool, use_booru: bool):
|
||||
global total_image_num, displayed_image_num, tmp_selection_img_path_set, gallery_selected_image_path, selection_selected_image_path, path_filter
|
||||
|
||||
interrogate_method = InterrogateMethod.NONE
|
||||
if use_interrogator == 'If Empty':
|
||||
|
|
@ -55,87 +52,47 @@ def load_files_from_dir(dir: str, sort_by: str, sort_order: str, recursive: bool
|
|||
interrogate_method = InterrogateMethod.APPEND
|
||||
|
||||
dataset_tag_editor.load_dataset(img_dir=dir, recursive=recursive, load_caption_from_filename=load_caption_from_filename, interrogate_method=interrogate_method, use_clip=use_clip, use_booru=use_booru)
|
||||
img_paths, tags = dataset_tag_editor.get_filtered_imgpath_and_tags()
|
||||
tag_filter = TagFilter()
|
||||
tag_filter_neg = TagFilter()
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
path_filter = PathFilter()
|
||||
tags = arrange_tag_order(tags=tags, sort_by=sort_by, sort_order=sort_order)
|
||||
total_image_num = displayed_image_num = len(dataset_tag_editor.get_img_path_set())
|
||||
tmp_selection_img_path_set = set()
|
||||
current_selection = 0
|
||||
gallery_selected_image_path = ''
|
||||
selection_selected_image_path = ''
|
||||
return [
|
||||
img_paths,
|
||||
[],
|
||||
gr.CheckboxGroup.update(value=None, choices=dataset_tag_editor.write_tags(tags)),
|
||||
'',
|
||||
get_current_txt_filter(),
|
||||
get_current_gallery_txt(),
|
||||
get_current_txt_selection()
|
||||
]
|
||||
] + clear_tag_filters()
|
||||
|
||||
|
||||
def search_tags(filter_word: str, sort_by: str, sort_order: str):
|
||||
_, tags = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg], filter_word=filter_word)
|
||||
tags = arrange_tag_order(tags, sort_by=sort_by, sort_order=sort_order)
|
||||
return gr.CheckboxGroup.update(choices=dataset_tag_editor.write_tags(tags))
|
||||
|
||||
|
||||
def clear_tag_filters(sort_by, sort_order):
|
||||
global tag_filter
|
||||
tag_filter = TagFilter()
|
||||
return filter_gallery(filter_word='', sort_by=sort_by, sort_order=sort_order) + ['']
|
||||
|
||||
|
||||
def rearrange_tag_order(filter_word: str, sort_by: str, sort_order: str):
|
||||
_, tags = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg], filter_word=filter_word)
|
||||
tags = arrange_tag_order(tags=tags, sort_by=sort_by, sort_order=sort_order)
|
||||
return gr.CheckboxGroup.update(choices=dataset_tag_editor.write_tags(tags))
|
||||
|
||||
|
||||
def filter_gallery_by_checkbox(filter_tags: List[str], filter_word: str, sort_by: str, sort_order: str):
|
||||
global tag_filter
|
||||
filter_tags = dataset_tag_editor.read_tags(filter_tags)
|
||||
tag_filter = TagFilter(set(filter_tags), TagFilter.Logic.AND, TagFilter.Mode.INCLUSIVE)
|
||||
return filter_gallery(filter_word=filter_word, sort_by=sort_by, sort_order=sort_order)
|
||||
|
||||
|
||||
def filter_gallery(filter_word: str, sort_by: str, sort_order: str):
|
||||
global displayed_image_num, current_selection
|
||||
img_paths, tags = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg], filter_word=filter_word)
|
||||
|
||||
tags = arrange_tag_order(tags=tags, sort_by=sort_by, sort_order=sort_order)
|
||||
filter_tags = [tag for tag in tags if tag in tag_filter.tags]
|
||||
tags = dataset_tag_editor.write_tags(tags)
|
||||
filter_tags = dataset_tag_editor.write_tags(filter_tags)
|
||||
|
||||
def update_gallery():
|
||||
global displayed_image_num
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
displayed_image_num = len(img_paths)
|
||||
current_selection = len(tmp_selection_img_path_set)
|
||||
tag_txt = ', '.join(tag_filter.tags)
|
||||
|
||||
if filter_tags and len(filter_tags) == 0:
|
||||
filter_tags = None
|
||||
return [
|
||||
img_paths,
|
||||
gr.CheckboxGroup.update(value=filter_tags, choices=tags),
|
||||
tag_txt,
|
||||
tag_txt,
|
||||
-1,
|
||||
get_current_txt_filter()
|
||||
get_current_gallery_txt()
|
||||
]
|
||||
|
||||
|
||||
def apply_edit_tags(filter_tags: str, edit_tags: str, prepend: bool, filter_word: str, sort_by: str, sort_order: str):
|
||||
global tag_filter
|
||||
replace_tags = [t.strip() for t in edit_tags.split(',')]
|
||||
filter_tags = dataset_tag_editor.read_tags(filter_tags)
|
||||
tag_filter = TagFilter(set(filter_tags), TagFilter.Logic.AND, TagFilter.Mode.INCLUSIVE)
|
||||
dataset_tag_editor.replace_tags(search_tags = filter_tags, replace_tags = replace_tags, filters = [path_filter, tag_filter, tag_filter_neg], prepend = prepend)
|
||||
tag_filter = TagFilter({t for t in replace_tags if t}, TagFilter.Logic.AND, TagFilter.Mode.INCLUSIVE)
|
||||
return filter_gallery(filter_word = filter_word, sort_by=sort_by, sort_order=sort_order)
|
||||
def update_filter_and_gallery():
|
||||
return [tag_filter_ui.cbg_tags_update(), tag_filter_ui_neg.cbg_tags_update()] + update_gallery()
|
||||
|
||||
|
||||
def save_all_changes(backup: bool) -> str:
|
||||
def clear_tag_filters():
|
||||
tag_filter_ui.clear_filter()
|
||||
tag_filter_ui_neg.clear_filter()
|
||||
return update_filter_and_gallery() + update_common_tags()
|
||||
|
||||
|
||||
def update_common_tags():
|
||||
tags = ', '.join(dataset_tag_editor.get_common_tags(filters=get_filters()))
|
||||
return [tags, tags]
|
||||
|
||||
|
||||
def save_all_changes(backup: bool):
|
||||
saved, total, dir = dataset_tag_editor.save_dataset(backup=backup)
|
||||
return f'Saved text files : {saved}/{total} under {dir}' if total > 0 else ''
|
||||
|
||||
|
|
@ -144,7 +101,7 @@ def save_all_changes(backup: bool) -> str:
|
|||
# Callbacks for "Filter by Selection" tab
|
||||
# ================================================================
|
||||
|
||||
def arrange_selection_order(paths: List[str]) -> List[str]:
|
||||
def arrange_selection_order(paths: List[str]):
|
||||
return sorted(paths)
|
||||
|
||||
|
||||
|
|
@ -163,7 +120,7 @@ def selection_index_changed(idx: int):
|
|||
def add_image_selection(idx: int):
|
||||
global tmp_selection_img_path_set
|
||||
idx = int(idx)
|
||||
img_paths, _ = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg])
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
if idx < 0 or len(img_paths) <= idx:
|
||||
idx = -1
|
||||
else:
|
||||
|
|
@ -173,7 +130,7 @@ def add_image_selection(idx: int):
|
|||
|
||||
def add_all_displayed_image_selection():
|
||||
global tmp_selection_img_path_set
|
||||
img_paths, _ = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg])
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
tmp_selection_img_path_set |= set(img_paths)
|
||||
return arrange_selection_order(tmp_selection_img_path_set)
|
||||
|
||||
|
|
@ -214,13 +171,13 @@ def clear_image_selection():
|
|||
]
|
||||
|
||||
|
||||
def apply_image_selection_filter(filter_word: str, sort_by: str, sort_order: str):
|
||||
def apply_image_selection_filter():
|
||||
global path_filter
|
||||
if len(tmp_selection_img_path_set) > 0:
|
||||
path_filter = PathFilter(tmp_selection_img_path_set, PathFilter.Mode.INCLUSIVE)
|
||||
else:
|
||||
path_filter = PathFilter()
|
||||
return filter_gallery(filter_word=filter_word, sort_by=sort_by, sort_order=sort_order)
|
||||
return update_filter_and_gallery() + update_common_tags()
|
||||
|
||||
|
||||
# ================================================================
|
||||
|
|
@ -230,7 +187,7 @@ def apply_image_selection_filter(filter_word: str, sort_by: str, sort_order: str
|
|||
def gallery_index_changed(idx: int):
|
||||
global gallery_selected_image_path
|
||||
idx = int(idx)
|
||||
img_paths, _ = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg])
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
tags_txt = ''
|
||||
if 0 <= idx and idx < len(img_paths):
|
||||
gallery_selected_image_path = img_paths[idx]
|
||||
|
|
@ -241,38 +198,88 @@ def gallery_index_changed(idx: int):
|
|||
|
||||
return [
|
||||
tags_txt,
|
||||
get_current_txt_filter(),
|
||||
get_current_gallery_txt(),
|
||||
idx
|
||||
]
|
||||
|
||||
|
||||
def change_tags_selected_image(tags_text: str, filter_word:str, sort_by: str, sort_order: str, idx: int):
|
||||
def change_selected_image_caption(tags_text: str, idx: int):
|
||||
idx = int(idx)
|
||||
img_paths, _ = dataset_tag_editor.get_filtered_imgpath_and_tags(filters=[path_filter, tag_filter, tag_filter_neg])
|
||||
img_paths = dataset_tag_editor.get_filtered_imgpaths(filters=get_filters())
|
||||
|
||||
edited_tags = [t.strip() for t in tags_text.split(',')]
|
||||
edited_tags = [t for t in edited_tags if t]
|
||||
|
||||
if idx < 0 or len(img_paths) <= idx:
|
||||
idx = -1
|
||||
else:
|
||||
dataset_tag_editor.set_tags_by_image_path(imgpath=img_paths[idx], tags=edited_tags)
|
||||
return filter_gallery(filter_word=filter_word, sort_by=sort_by, sort_order=sort_order) + [idx]
|
||||
return update_filter_and_gallery() + update_common_tags() + [idx]
|
||||
|
||||
|
||||
def interrogate_selected_image_clip():
|
||||
global gallery_selected_image_path
|
||||
return interrogate_image_clip(gallery_selected_image_path)
|
||||
|
||||
|
||||
def interrogate_selected_image_booru():
|
||||
global gallery_selected_image_path
|
||||
return interrogate_image_booru(gallery_selected_image_path)
|
||||
|
||||
|
||||
# ================================================================
|
||||
# Callbacks for "Batch Edit Captions" tab
|
||||
# ================================================================
|
||||
|
||||
def apply_edit_tags(search_tags: str, replace_tags: str, prepend: bool):
|
||||
search_tags = [t.strip() for t in search_tags.split(',')]
|
||||
search_tags = [t for t in search_tags if t]
|
||||
replace_tags = [t.strip() for t in replace_tags.split(',')]
|
||||
replace_tags = [t for t in replace_tags if t]
|
||||
|
||||
dataset_tag_editor.replace_tags(search_tags = search_tags, replace_tags = replace_tags, filters=get_filters(), prepend = prepend)
|
||||
tag_filter_ui.get_filter().tags = dataset_tag_editor.get_replaced_tagset(tag_filter_ui.get_filter().tags, search_tags, replace_tags)
|
||||
tag_filter_ui_neg.get_filter().tags = dataset_tag_editor.get_replaced_tagset(tag_filter_ui_neg.get_filter().tags, search_tags, replace_tags)
|
||||
|
||||
return update_filter_and_gallery() + update_common_tags()
|
||||
|
||||
|
||||
def search_and_replace(search_text: str, replace_text: str, target_text: str):
|
||||
if target_text == 'Only Selected Tags':
|
||||
selected_tags = tag_filter_ui.selected_tags
|
||||
dataset_tag_editor.search_and_replace_selected_tags(search_text = search_text, replace_text=replace_text, selected_tags=selected_tags, filters=get_filters())
|
||||
tags = set()
|
||||
for t in tag_filter_ui.get_filter().tags:
|
||||
if t in selected_tags:
|
||||
tags.add(t.replace(search_text, replace_text))
|
||||
tag_filter_ui.get_filter().tags = {t for t in tags if t}
|
||||
|
||||
tags = set()
|
||||
for t in tag_filter_ui_neg.get_filter().tags:
|
||||
if t in selected_tags:
|
||||
tags.add(t.replace(search_text, replace_text))
|
||||
tag_filter_ui_neg.get_filter().tags = {t for t in tags if t}
|
||||
|
||||
elif target_text == 'Entire Caption':
|
||||
dataset_tag_editor.search_and_replace_caption(search_text=search_text, replace_text=replace_text, filters=get_filters())
|
||||
tags = set()
|
||||
for t in tag_filter_ui.get_filter().tags:
|
||||
tags.add(t.replace(search_text, replace_text))
|
||||
tag_filter_ui.get_filter().tags = {t for t in tags if t}
|
||||
|
||||
tags = set()
|
||||
for t in tag_filter_ui_neg.get_filter().tags:
|
||||
tags.add(t.replace(search_text, replace_text))
|
||||
tag_filter_ui_neg.get_filter().tags = {t for t in tags if t}
|
||||
|
||||
return update_filter_and_gallery() + update_common_tags()
|
||||
|
||||
|
||||
# ================================================================
|
||||
# Script Callbacks
|
||||
# ================================================================
|
||||
|
||||
def on_ui_tabs():
|
||||
global displayed_image_num, total_image_num, current_selection, gallery_selected_image_path, selection_selected_image_path
|
||||
with gr.Blocks(analytics_enabled=False) as dataset_tag_editor_interface:
|
||||
with gr.Row(visible=False):
|
||||
btn_hidden_set_index = gr.Button(elem_id="dataset_tag_editor_btn_hidden_set_index")
|
||||
|
|
@ -309,44 +316,22 @@ def on_ui_tabs():
|
|||
cb_use_booru_to_prefill = gr.Checkbox(value=False, label='Use DeepDanbooru')
|
||||
|
||||
gl_dataset_images = gr.Gallery(label='Dataset Images', elem_id="dataset_tag_editor_dataset_gallery").style(grid=opts.dataset_editor_image_columns)
|
||||
txt_filter = gr.HTML(value=get_current_txt_filter())
|
||||
txt_gallery = gr.HTML(value=get_current_gallery_txt())
|
||||
|
||||
with gr.Tab(label='Filter and Edit Tags'):
|
||||
with gr.Column():
|
||||
with gr.Row():
|
||||
with gr.Tab(label='Filter by Tags'):
|
||||
with gr.Row():
|
||||
btn_clear_tag_filters = gr.Button(value='Clear tag filters')
|
||||
btn_clear_all_filters = gr.Button(value='Clear ALL filters')
|
||||
with gr.Column(variant='panel'):
|
||||
gr.HTML(value='Edit tags in filtered images (=displayed images)')
|
||||
tb_selected_tags = gr.Textbox(label='Selected Tags', interactive=False)
|
||||
tb_edit_tags = gr.Textbox(label='Edit Tags', interactive=True)
|
||||
cb_prepend_tags = gr.Checkbox(value=False, label='Prepend additional tags')
|
||||
btn_apply_edit_tags = gr.Button(value='Apply changes to filtered images', variant='primary')
|
||||
with gr.Accordion(label='Show description of how to edit tags', open=False):
|
||||
gr.HTML(value="""
|
||||
1. The selected tags are displayed in comma separated style.<br>
|
||||
2. When changes are applied, all tags in each displayed images are replaced.<br>
|
||||
3. If you change some tags into blank, they will be erased.<br>
|
||||
4. If you add some tags to the end, they will be added to the end/beginning of the text file.<br>
|
||||
5. Changes are not applied to the text files until the "Save all changes" button is pressed.<br>
|
||||
<b>ex A.</b><br>
|
||||
 Original Text = "A, A, B, C" Selected Tags = "B, A" Edit Tags = "X, Y"<br>
|
||||
 Result = "Y, Y, X, C" (B->X, A->Y)<br>
|
||||
<b>ex B.</b><br>
|
||||
 Original Text = "A, B, C" Selected Tags = "(nothing)" Edit Tags = "X, Y"<br>
|
||||
 Result = "A, B, C, X, Y" (add X and Y to the end (default))<br>
|
||||
 Result = "X, Y, A, B, C" (add X and Y to the beginning ("Prepend additional tags" checked))<br>
|
||||
<b>ex C.</b><br>
|
||||
 Original Text = "A, B, C, D, E" Selected Tags = "A, B, D" Edit Tags = ", X, "<br>
|
||||
 Result = "X, C, E" (A->"", B->X, D->"")<br>
|
||||
""")
|
||||
|
||||
with gr.Tab(label='Positive Filter'):
|
||||
with gr.Column(variant='panel'):
|
||||
gr.HTML(value='Search tags / Filter images by tags')
|
||||
tb_search_tags = gr.Textbox(label='Search Tags', interactive=True)
|
||||
with gr.Row():
|
||||
rd_sort_by = gr.Radio(choices=['Alphabetical Order', 'Frequency'], value='Alphabetical Order', interactive=True, label='Sort by')
|
||||
rd_sort_order = gr.Radio(choices=['Ascending', 'Descending'], value='Ascending', interactive=True, label='Sort Order')
|
||||
cbg_tags = gr.CheckboxGroup(label='Filter Images by Tags', interactive=True)
|
||||
tag_filter_ui.create_ui(get_filters)
|
||||
|
||||
with gr.Tab(label='Negative Filter'):
|
||||
with gr.Column(variant='panel'):
|
||||
gr.HTML(value='Search tags / Filter images by tags')
|
||||
tag_filter_ui_neg.create_ui(get_filters)
|
||||
|
||||
with gr.Tab(label='Filter by Selection'):
|
||||
with gr.Row(visible=False):
|
||||
|
|
@ -357,7 +342,7 @@ def on_ui_tabs():
|
|||
with gr.Column(variant='panel'):
|
||||
with gr.Row():
|
||||
btn_add_image_selection = gr.Button(value='Add selection [Enter]', elem_id='dataset_tag_editor_btn_add_image_selection')
|
||||
btn_add_all_displayed_image_selection = gr.Button(value='Add ALL')
|
||||
btn_add_all_displayed_image_selection = gr.Button(value='Add ALL Displayed')
|
||||
|
||||
gl_selected_images = gr.Gallery(label='Filter Images', elem_id="dataset_tag_editor_selection_gallery").style(grid=opts.dataset_editor_image_columns)
|
||||
txt_selection = gr.HTML(value=get_current_txt_selection())
|
||||
|
|
@ -368,6 +353,39 @@ def on_ui_tabs():
|
|||
btn_clear_image_selection = gr.Button(value='Clear selection')
|
||||
|
||||
btn_apply_image_selection_filter = gr.Button(value='Apply selection filter', variant='primary')
|
||||
|
||||
with gr.Tab(label='Batch Edit Captions'):
|
||||
with gr.Column(variant='panel'):
|
||||
gr.HTML('Edit common tags.')
|
||||
tb_common_tags = gr.Textbox(label='Common Tags', interactive=False)
|
||||
tb_edit_tags = gr.Textbox(label='Edit Tags', interactive=True)
|
||||
cb_prepend_tags = gr.Checkbox(value=False, label='Prepend additional tags')
|
||||
btn_apply_edit_tags = gr.Button(value='Apply changes to filtered images', variant='primary')
|
||||
with gr.Accordion(label='Show description of how to edit tags', open=False):
|
||||
gr.HTML(value="""
|
||||
1. The tags common to all displayed images are shown in comma separated style.<br>
|
||||
2. When changes are applied, all tags in each displayed images are replaced.<br>
|
||||
3. If you change some tags into blank, they will be erased.<br>
|
||||
4. If you add some tags to the end, they will be added to the end/beginning of the text file.<br>
|
||||
5. Changes are not applied to the text files until the "Save all changes" button is pressed.<br>
|
||||
<b>ex A.</b><br>
|
||||
 Original Text = "A, A, B, C" Selected Tags = "B, A" Edit Tags = "X, Y"<br>
|
||||
 Result = "Y, Y, X, C" (B->X, A->Y)<br>
|
||||
<b>ex B.</b><br>
|
||||
 Original Text = "A, B, C" Selected Tags = "(nothing)" Edit Tags = "X, Y"<br>
|
||||
 Result = "A, B, C, X, Y" (add X and Y to the end (default))<br>
|
||||
 Result = "X, Y, A, B, C" (add X and Y to the beginning ("Prepend additional tags" checked))<br>
|
||||
<b>ex C.</b><br>
|
||||
 Original Text = "A, B, C, D, E" Selected Tags = "A, B, D" Edit Tags = ", X, "<br>
|
||||
 Result = "X, C, E" (A->"", B->X, D->"")<br>
|
||||
""")
|
||||
with gr.Column(variant='panel'):
|
||||
gr.HTML('Search and Replace for all images displayed.')
|
||||
tb_sr_search_tags = gr.Textbox(label='Search Text', interactive=True)
|
||||
tb_sr_replace_tags = gr.Textbox(label='Replace Text', interactive=True)
|
||||
rb_sr_replace_target = gr.Radio(['Only Selected Tags', 'Entire Caption'], value='Only Selected Tags', label='Search and Replace in', interactive=True)
|
||||
tb_sr_selected_tags = gr.Textbox(label='Selected Tags', interactive=False, lines=2)
|
||||
btn_apply_sr_tags = gr.Button(value='Search and Replace', variant='primary')
|
||||
|
||||
with gr.Tab(label='Edit Caption of Selected Image'):
|
||||
with gr.Tab(label='Read Caption from Selected Image'):
|
||||
|
|
@ -400,63 +418,31 @@ def on_ui_tabs():
|
|||
outputs=[txt_result]
|
||||
)
|
||||
|
||||
tag_filter_ui.set_callbacks(on_filter_update=lambda:update_gallery() + update_common_tags() + [', '.join(tag_filter_ui.filter.tags)], outputs=[gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags] + [tb_sr_selected_tags])
|
||||
tag_filter_ui_neg.set_callbacks(on_filter_update=lambda:update_gallery() + update_common_tags() + [', '.join(tag_filter_ui.filter.tags)], outputs=[gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags] + [tb_sr_selected_tags])
|
||||
|
||||
btn_load_datasets.click(
|
||||
fn=load_files_from_dir,
|
||||
inputs=[tb_img_directory, rd_sort_by, rd_sort_order, cb_load_recursive, cb_load_caption_from_filename, rb_use_interrogator, cb_use_clip_to_prefill, cb_use_booru_to_prefill],
|
||||
outputs=[gl_dataset_images, gl_selected_images, cbg_tags, tb_search_tags, txt_filter, txt_selection]
|
||||
inputs=[tb_img_directory, cb_load_recursive, cb_load_caption_from_filename, rb_use_interrogator, cb_use_clip_to_prefill, cb_use_booru_to_prefill],
|
||||
outputs=[gl_dataset_images, gl_selected_images, txt_gallery, txt_selection] + [tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
btn_load_datasets.click(
|
||||
fn=lambda:['', '', '', -1],
|
||||
inputs=None,
|
||||
outputs=[tb_selected_tags, tb_edit_tags, tb_caption_selected_image, nb_hidden_image_index]
|
||||
)
|
||||
|
||||
cbg_tags.change(
|
||||
fn=filter_gallery_by_checkbox,
|
||||
inputs=[cbg_tags, tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter]
|
||||
)
|
||||
|
||||
rd_sort_by.change(
|
||||
fn=rearrange_tag_order,
|
||||
inputs=[tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=cbg_tags
|
||||
)
|
||||
|
||||
rd_sort_order.change(
|
||||
fn=rearrange_tag_order,
|
||||
inputs=[tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=cbg_tags
|
||||
)
|
||||
|
||||
tb_search_tags.change(
|
||||
fn=search_tags,
|
||||
inputs=[tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=cbg_tags
|
||||
)
|
||||
|
||||
btn_apply_edit_tags.click(
|
||||
fn=apply_edit_tags,
|
||||
inputs=[cbg_tags, tb_edit_tags, cb_prepend_tags, tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter]
|
||||
fn=lambda:['', '', '', -1],
|
||||
outputs=[tb_common_tags, tb_edit_tags, tb_caption_selected_image, nb_hidden_image_index]
|
||||
)
|
||||
|
||||
btn_clear_tag_filters.click(
|
||||
fn=clear_tag_filters,
|
||||
inputs=[rd_sort_by, rd_sort_order],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter, tb_search_tags]
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
|
||||
btn_clear_all_filters.click(
|
||||
fn=clear_image_selection,
|
||||
inputs=None,
|
||||
outputs=[gl_selected_images, txt_selection, nb_hidden_selection_image_index]
|
||||
)
|
||||
|
||||
btn_clear_all_filters.click(
|
||||
fn=clear_tag_filters,
|
||||
inputs=[rd_sort_by, rd_sort_order],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter, tb_search_tags]
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
|
@ -477,32 +463,43 @@ def on_ui_tabs():
|
|||
|
||||
btn_add_all_displayed_image_selection.click(
|
||||
fn=add_all_displayed_image_selection,
|
||||
inputs=None,
|
||||
outputs=gl_selected_images
|
||||
)
|
||||
|
||||
btn_invert_image_selection.click(
|
||||
fn=invert_image_selection,
|
||||
inputs=None,
|
||||
outputs=gl_selected_images
|
||||
)
|
||||
|
||||
btn_remove_image_selection.click(
|
||||
fn=remove_image_selection,
|
||||
inputs=[nb_hidden_selection_image_index],
|
||||
outputs=[gl_selected_images,txt_selection,nb_hidden_selection_image_index]
|
||||
outputs=[gl_selected_images, txt_selection, nb_hidden_selection_image_index]
|
||||
)
|
||||
|
||||
btn_clear_image_selection.click(
|
||||
fn=clear_image_selection,
|
||||
inputs=None,
|
||||
outputs=[gl_selected_images,txt_selection,nb_hidden_selection_image_index]
|
||||
outputs=[gl_selected_images, txt_selection, nb_hidden_selection_image_index]
|
||||
)
|
||||
|
||||
btn_apply_image_selection_filter.click(
|
||||
fn=apply_image_selection_filter,
|
||||
inputs=[tb_search_tags, rd_sort_by, rd_sort_order],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter]
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Batch Edit Captions tab
|
||||
|
||||
btn_apply_edit_tags.click(
|
||||
fn=apply_edit_tags,
|
||||
inputs=[tb_common_tags, tb_edit_tags, cb_prepend_tags],
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
|
||||
btn_apply_sr_tags.click(
|
||||
fn=search_and_replace,
|
||||
inputs=[tb_sr_search_tags, tb_sr_replace_tags, rb_sr_replace_target],
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags]
|
||||
)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
|
@ -512,7 +509,7 @@ def on_ui_tabs():
|
|||
fn=gallery_index_changed,
|
||||
_js="(x) => [dataset_tag_editor_gl_dataset_images_selected_index()]",
|
||||
inputs=[nb_hidden_image_index],
|
||||
outputs=[tb_caption_selected_image, txt_filter, nb_hidden_image_index]
|
||||
outputs=[tb_caption_selected_image, txt_gallery, nb_hidden_image_index]
|
||||
)
|
||||
|
||||
btn_copy_caption.click(
|
||||
|
|
@ -535,13 +532,11 @@ def on_ui_tabs():
|
|||
|
||||
btn_interrogate_clip.click(
|
||||
fn=interrogate_selected_image_clip,
|
||||
inputs=None,
|
||||
outputs=[tb_interrogate_selected_image]
|
||||
)
|
||||
|
||||
btn_interrogate_booru.click(
|
||||
fn=interrogate_selected_image_booru,
|
||||
inputs=None,
|
||||
outputs=[tb_interrogate_selected_image]
|
||||
)
|
||||
|
||||
|
|
@ -563,11 +558,10 @@ def on_ui_tabs():
|
|||
outputs=[tb_edit_caption_selected_image]
|
||||
)
|
||||
|
||||
|
||||
btn_apply_changes_selected_image.click(
|
||||
fn=change_tags_selected_image,
|
||||
inputs=[tb_edit_caption_selected_image, tb_search_tags, rd_sort_by, rd_sort_order, nb_hidden_image_index],
|
||||
outputs=[gl_dataset_images, cbg_tags, tb_selected_tags, tb_edit_tags, nb_hidden_image_index, txt_filter, nb_hidden_image_index]
|
||||
fn=change_selected_image_caption,
|
||||
inputs=[tb_edit_caption_selected_image, nb_hidden_image_index],
|
||||
outputs=[tag_filter_ui.cbg_tags, tag_filter_ui_neg.cbg_tags, gl_dataset_images, nb_hidden_image_index, txt_gallery] + [tb_common_tags, tb_edit_tags] + [nb_hidden_image_index]
|
||||
)
|
||||
|
||||
btn_apply_changes_selected_image.click(
|
||||
|
|
|
|||
Loading…
Reference in New Issue