17
17
QVBoxLayout ,
18
18
QWidget ,
19
19
)
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
21
22
from src .core .palette import ColorType , get_tag_color
22
23
from src .qt .translations import Translations
23
- from src .qt .widgets .panel import PanelWidget
24
+ from src .qt .widgets .panel import PanelModal , PanelWidget
24
25
from src .qt .widgets .tag import TagWidget
25
26
26
27
logger = structlog .get_logger (__name__ )
27
28
28
29
29
30
class TagSearchPanel (PanelWidget ):
30
31
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
+ ):
33
40
super ().__init__ ()
34
41
self .lib = library
35
42
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
+
38
45
self .setMinimumSize (300 , 400 )
39
46
self .root_layout = QVBoxLayout (self )
40
47
self .root_layout .setContentsMargins (6 , 0 , 6 , 0 )
@@ -44,9 +51,7 @@ def __init__(self, library: Library, exclude: list[int] | None = None):
44
51
self .search_field .setMinimumSize (QSize (0 , 32 ))
45
52
Translations .translate_with_setter (self .search_field .setPlaceholderText , "home.search_tags" )
46
53
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 ()))
50
55
51
56
self .scroll_contents = QWidget ()
52
57
self .scroll_layout = QVBoxLayout (self .scroll_contents )
@@ -63,17 +68,10 @@ def __init__(self, library: Library, exclude: list[int] | None = None):
63
68
self .root_layout .addWidget (self .search_field )
64
69
self .root_layout .addWidget (self .scroll_area )
65
70
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
-
75
71
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
77
75
while self .scroll_layout .count ():
78
76
self .scroll_layout .takeAt (0 ).widget ().deleteLater ()
79
77
@@ -87,45 +85,90 @@ def update_tags(self, query: str | None = None):
87
85
if self .exclude is not None and tag .id in self .exclude :
88
86
continue
89
87
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 )
120
92
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 )
124
131
125
132
self .search_field .setFocus ()
126
133
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
+
127
144
def showEvent (self , event : QShowEvent ) -> None : # noqa N802
128
145
if not self .is_initialized :
129
146
self .update_tags ()
130
147
self .is_initialized = True
131
148
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