1717 QVBoxLayout ,
1818 QWidget ,
1919)
20- from src .core .library import Library
20+ from src .core .constants import RESERVED_TAG_END , RESERVED_TAG_START
21+ from src .core .library import Library , Tag
2122from src .core .palette import ColorType , get_tag_color
2223from src .qt .translations import Translations
23- from src .qt .widgets .panel import PanelWidget
24+ from src .qt .widgets .panel import PanelModal , PanelWidget
2425from src .qt .widgets .tag import TagWidget
2526
2627logger = structlog .get_logger (__name__ )
2728
2829
2930class TagSearchPanel (PanelWidget ):
3031 tag_chosen = Signal (int )
31-
32- def __init__ (self , library : Library , exclude : list [int ] | None = None ):
32+ lib : Library
33+ is_initialized : bool = False
34+ first_tag_id : int = None
35+ is_tag_chooser : bool
36+
37+ def __init__ (
38+ self , library : Library , exclude : list [int ] | None = None , is_tag_chooser : bool = True
39+ ):
3340 super ().__init__ ()
3441 self .lib = library
3542 self .exclude = exclude
36- self .is_initialized : bool = False
37- self . first_tag_id : int = None
43+ self .is_tag_chooser = is_tag_chooser
44+
3845 self .setMinimumSize (300 , 400 )
3946 self .root_layout = QVBoxLayout (self )
4047 self .root_layout .setContentsMargins (6 , 0 , 6 , 0 )
@@ -44,9 +51,7 @@ def __init__(self, library: Library, exclude: list[int] | None = None):
4451 self .search_field .setMinimumSize (QSize (0 , 32 ))
4552 Translations .translate_with_setter (self .search_field .setPlaceholderText , "home.search_tags" )
4653 self .search_field .textEdited .connect (lambda : self .update_tags (self .search_field .text ()))
47- self .search_field .returnPressed .connect (
48- lambda checked = False : self .on_return (self .search_field .text ())
49- )
54+ self .search_field .returnPressed .connect (lambda : self .on_return (self .search_field .text ()))
5055
5156 self .scroll_contents = QWidget ()
5257 self .scroll_layout = QVBoxLayout (self .scroll_contents )
@@ -63,17 +68,10 @@ def __init__(self, library: Library, exclude: list[int] | None = None):
6368 self .root_layout .addWidget (self .search_field )
6469 self .root_layout .addWidget (self .scroll_area )
6570
66- def on_return (self , text : str ):
67- if text and self .first_tag_id is not None :
68- self .tag_chosen .emit (self .first_tag_id )
69- self .search_field .setText ("" )
70- self .update_tags ()
71- else :
72- self .search_field .setFocus ()
73- self .parentWidget ().hide ()
74-
7571 def update_tags (self , query : str | None = None ):
76- logger .info ("[Tag Search Modal] Updating Tags" )
72+ logger .info ("[Tag Search Super Class] Updating Tags" )
73+
74+ # TODO: Look at recycling rather than deleting and re-initializing
7775 while self .scroll_layout .count ():
7876 self .scroll_layout .takeAt (0 ).widget ().deleteLater ()
7977
@@ -87,45 +85,90 @@ def update_tags(self, query: str | None = None):
8785 if self .exclude is not None and tag .id in self .exclude :
8886 continue
8987
90- c = QWidget ()
91- layout = QHBoxLayout (c )
92- layout .setContentsMargins (0 , 0 , 0 , 0 )
93- layout .setSpacing (3 )
94- tw = TagWidget (tag , has_edit = False , has_remove = False )
95- ab = QPushButton ()
96- ab .setMinimumSize (23 , 23 )
97- ab .setMaximumSize (23 , 23 )
98- ab .setText ("+" )
99- ab .setStyleSheet (
100- f"QPushButton{{"
101- f"background: { get_tag_color (ColorType .PRIMARY , tag .color )} ;"
102- f"color: { get_tag_color (ColorType .TEXT , tag .color )} ;"
103- f"font-weight: 600;"
104- f"border-color:{ get_tag_color (ColorType .BORDER , tag .color )} ;"
105- f"border-radius: 6px;"
106- f"border-style:solid;"
107- f"border-width: { math .ceil (self .devicePixelRatio ())} px;"
108- f"padding-bottom: 5px;"
109- f"font-size: 20px;"
110- f"}}"
111- f"QPushButton::hover"
112- f"{{"
113- f"border-color:{ get_tag_color (ColorType .LIGHT_ACCENT , tag .color )} ;"
114- f"color: { get_tag_color (ColorType .DARK_ACCENT , tag .color )} ;"
115- f"background: { get_tag_color (ColorType .LIGHT_ACCENT , tag .color )} ;"
116- f"}}"
117- )
118-
119- ab .clicked .connect (lambda checked = False , x = tag .id : self .tag_chosen .emit (x ))
88+ container = QWidget ()
89+ row = QHBoxLayout (container )
90+ row .setContentsMargins (0 , 0 , 0 , 0 )
91+ row .setSpacing (3 )
12092
121- layout .addWidget (tw )
122- layout .addWidget (ab )
123- self .scroll_layout .addWidget (c )
93+ tag_widget = TagWidget (
94+ tag ,
95+ has_edit = True ,
96+ has_remove = (not self .is_tag_chooser )
97+ and (tag .id not in range (RESERVED_TAG_START , RESERVED_TAG_END )),
98+ )
99+ tag_widget .on_edit .connect (lambda t = tag : self .edit_tag (t ))
100+ tag_widget .on_remove .connect (lambda t = tag : self .remove_tag (t ))
101+ row .addWidget (tag_widget )
102+
103+ if self .is_tag_chooser :
104+ add_button = QPushButton ()
105+ add_button .setMinimumSize (23 , 23 )
106+ add_button .setMaximumSize (23 , 23 )
107+ add_button .setText ("+" )
108+ add_button .setStyleSheet (
109+ f"QPushButton{{"
110+ f"background: { get_tag_color (ColorType .PRIMARY , tag .color )} ;"
111+ f"color: { get_tag_color (ColorType .TEXT , tag .color )} ;"
112+ f"font-weight: 600;"
113+ f"border-color:{ get_tag_color (ColorType .BORDER , tag .color )} ;"
114+ f"border-radius: 6px;"
115+ f"border-style:solid;"
116+ f"border-width: { math .ceil (self .devicePixelRatio ())} px;"
117+ f"padding-bottom: 5px;"
118+ f"font-size: 20px;"
119+ f"}}"
120+ f"QPushButton::hover"
121+ f"{{"
122+ f"border-color:{ get_tag_color (ColorType .LIGHT_ACCENT , tag .color )} ;"
123+ f"color: { get_tag_color (ColorType .DARK_ACCENT , tag .color )} ;"
124+ f"background: { get_tag_color (ColorType .LIGHT_ACCENT , tag .color )} ;"
125+ f"}}"
126+ )
127+ add_button .clicked .connect (lambda x = tag .id : self .tag_chosen .emit (x ))
128+ row .addWidget (add_button )
129+
130+ self .scroll_layout .addWidget (container )
124131
125132 self .search_field .setFocus ()
126133
134+ def on_return (self , text : str ):
135+ if text and self .first_tag_id is not None :
136+ if self .is_tag_chooser :
137+ self .tag_chosen .emit (self .first_tag_id )
138+ self .search_field .setText ("" )
139+ self .update_tags ()
140+ else :
141+ self .search_field .setFocus ()
142+ self .parentWidget ().hide ()
143+
127144 def showEvent (self , event : QShowEvent ) -> None : # noqa N802
128145 if not self .is_initialized :
129146 self .update_tags ()
130147 self .is_initialized = True
131148 return super ().showEvent (event )
149+
150+ def remove_tag (self , tag : Tag ):
151+ raise NotImplementedError
152+
153+ def edit_tag (self , tag : Tag ):
154+ # only import here because of circular imports
155+ from src .qt .modals .build_tag import BuildTagPanel
156+
157+ def edit_tag_callback (btp : BuildTagPanel ):
158+ self .lib .update_tag (
159+ btp .build_tag (), set (btp .parent_ids ), set (btp .alias_names ), set (btp .alias_ids )
160+ )
161+ self .update_tags (self .search_field .text ())
162+
163+ build_tag_panel = BuildTagPanel (self .lib , tag = tag )
164+
165+ self .edit_modal = PanelModal (
166+ build_tag_panel ,
167+ tag .name ,
168+ done_callback = (self .update_tags (self .search_field .text ())),
169+ has_save = True ,
170+ )
171+ Translations .translate_with_setter (self .edit_modal .setWindowTitle , "tag.edit" )
172+
173+ self .edit_modal .saved .connect (lambda : edit_tag_callback (build_tag_panel ))
174+ self .edit_modal .show ()
0 commit comments