MauiKit File Browsing

TagsDialog.qml
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Layouts
4
5import org.mauikit.controls as Maui
6import org.mauikit.filebrowsing as FB
7
8/**
9 * @inherit org::mauikit::controls::PopupPage
10 * @brief A popup dialog for selecting between all the available tags to associate to a given set of file URLs.
11 *
12 * This popup page also allows to create new tags, edit existing ones and removing.
13 *
14 * To associate the set of file URLs, use the exposed property `composerList.urls`, which is an alias to TagsList::urls.
15 * @see composerList
16 * @see TagsList::urls
17 * The `composerList` property exposes most of the available properties for tweaking the behaviour, and also contains the methods to perform any modifications to the tags.
18 *
19 * @image html tagsdialog.png "Example using the TagsDialog control"
20 *
21 * @code
22 * Maui.Page
23 * {
24 * Maui.Controls.showCSD: true
25 * anchors.fill: parent
26 *
27 * title: "Add tags to a file"
28 *
29 * FB.FileBrowser
30 * {
31 * id: _fileBrowser
32 * anchors.fill: parent
33 * currentPath: StandardPaths.writableLocation(StandardPaths.DownloadLocation)
34 * settings.viewType: FB.FMList.LIST_VIEW
35 * onItemClicked: (index) =>
36 * {
37 * _tagsDialog.composerList.urls = [_fileBrowser.currentFMModel.get(index).url]
38 * _tagsDialog.open()
39 * }
40 * }
41 *
42 * FB.TagsDialog
43 * {
44 * id: _tagsDialog
45 * composerList.strict: false //Show all the associated tags to the file
46 * onTagsReady: (tags) => console.log(tags)
47 * }
48 * }
49 * @endcode
50 */
51Maui.PopupPage
52{
53 id: control
54
55 /**
56 * @brief An alias to the TagsList list/model controlling and listing all of the available tags.
57 * @see TagsListmodel
58 * @property TagsList TagsDialog::tagList
59 */
60 readonly property alias taglist : _tagsList
61
62 /**
63 * @brief An alias to the Mauikit ListBrowser element listing the tag elements.
64 * @property MauiKit::ListBrowser TagsDialog::listView
65 */
66 readonly property alias listView: _listView
67
68 /**
69 * @brief An alias to the TagsList controller and model.
70 * This property is exposed to set the file URLs to which perform any new assignment or removal of tags.
71 * Refer to its documentation for more details on the available actions.
72 * @property TagsList TagsDialog::composerList
73 */
74 readonly property alias composerList: tagListComposer.list
75
76 /**
77 * @brief Emitted once the assignment of the new set of tags has been done. This can include removal or additions.
78 * This won't actually write any changes to the file URLs, to write the changes refer to the `composerList.updateToUrls` function.
79 * @see TagsList::updateToUrls
80 * @param tags the list of the new tag names associated to the file URLs
81 */
82 signal tagsReady(var tags)
83
84 property string thumbnailSource
85
86 hint: 1
87
88 maxHeight: 500
89 maxWidth: 350
90
91 actions: [
92
93 Action
94 {
95 Maui.Controls.status: Maui.Controls.Positive
96 text: i18nd("mauikitfilebrowsing", "Save")
97 onTriggered: control.setTags()
98 },
99
100 Action
101 {
102 text: i18nd("mauikitfilebrowsing", "Cancel")
103 onTriggered: control.close()
104 }
105 ]
106 closeButtonVisible: false
107 headBar.visible: true
108 headBar.forceCenterMiddleContent: false
109 headBar.middleContent: Maui.TextField
110 {
111 id: tagText
112 Layout.fillWidth: true
113 Layout.maximumWidth: 500
114 placeholderText: i18nd("mauikitfilebrowsing", "Filter or add a new tag")
115 icon.source: "tag"
116 // validator: RegExpValidator { regExp: /[0-9A-F]+/ }
117 onAccepted: //here we append a new tag to the model but we do not insert it into the DB until the user saves the tag to an url
118 {
119 const tags = tagText.text.split(",")
120 for(var i in tags)
121 {
122 const myTag = tags[i].trim()
123 _tagsList.append(myTag)
124 tagListComposer.list.append(myTag)
125 }
126 clear()
127 // _tagsModel.filter = ""
128 }
129
130 onTextChanged:
131 {
132 _tagsModel.filter = text
133 }
134 }
135
136 Maui.InfoDialog
137 {
138 id: _deleteDialog
139
140 property string tag
141 title: i18nd("mauikitfilebrowsing", "Delete %1", tag)
142 message: i18nd("mauikitfilebrowsing", "Are you sure you want to delete this tag? This action can not be undone.")
143 template.iconSource: "tag"
144 onAccepted:
145 {
146 FB.Tagging.removeTag(tag)
147 _deleteDialog.close()
148 }
149
150 onRejected: _deleteDialog.close()
151 }
152
153 Maui.ContextualMenu
154 {
155 id: _menu
156
157 MenuItem
158 {
159 text: i18nd("mauikitfilebrowsing", "Edit")
160 icon.name: "document-edit"
161 }
162
163 MenuItem
164 {
165 text: i18nd("mauikitfilebrowsing", "Delete")
166 icon.name: "delete"
167 onTriggered:
168 {
169 _deleteDialog.tag = _tagsModel.get(_listView.currentIndex).tag
170 _deleteDialog.open()
171 }
172 }
173 }
174
175 stack: [
176
177 Maui.ListBrowser
178 {
179 id: _listView
180
181 Layout.fillHeight: true
182 Layout.fillWidth: true
183 clip: true
184 currentIndex: -1
185
186 holder.emoji: "qrc:/assets/tag.svg"
187 holder.visible: _listView.count === 0
188 holder.title : i18nd("mauikitfilebrowsing", "No Tags!")
189 holder.body: i18nd("mauikitfilebrowsing", "Create new tags to organize your files.")
190
191 header: Item
192 {
193 width: parent.width
194 height: 150
195
196 Pane
197 {
198 id: _pane
199 anchors.fill: parent
200 anchors.bottomMargin: Maui.Style.space.medium
201
202 background: Rectangle
203 {
204 color: Maui.Theme.alternateBackgroundColor
205 radius: Maui.Style.radiusV
206 }
207
208 contentItem: Maui.GridItemTemplate
209 {
210 readonly property var itemInfo : FB.FM.getFileInfo(tagListComposer.list.urls[0])
211
212 iconSizeHint: Maui.Style.iconSizes.huge
213 iconSource: itemInfo.icon
214 fillMode: Image.PreserveAspectCrop
215 imageSource: control.thumbnailSource || itemInfo.thumbnail
216 text1: i18np("1 item", "%1 items", tagListComposer.list.urls.length)
217 }
218 }
219 }
220
221 model: Maui.BaseModel
222 {
223 id: _tagsModel
224 sort: "tag"
225 sortOrder: Qt.AscendingOrder
226 recursiveFilteringEnabled: true
227 sortCaseSensitivity: Qt.CaseInsensitive
228 filterCaseSensitivity: Qt.CaseInsensitive
229 list: FB.TagsListModel
230 {
231 id: _tagsList
232 strict: false
233 }
234 }
235
236 delegate: Maui.ListBrowserDelegate
237 {
238 width: ListView.view.width
239 label1.text: model.tag
240 iconSource: model.icon
241 iconSizeHint: Maui.Style.iconSizes.small
242
243 template.content: Rectangle
244 {
245 color: model.color ? model.color : "transparent"
246 height: Maui.Style.iconSizes.small
247 radius: height/2
248 width: height
249 }
250
251 onClicked:
252 {
253 _listView.currentIndex = index
254 if(Maui.Handy.singleClick)
255 {
256 tagListComposer.list.appendItem(_tagsModel.get(_listView.currentIndex))
257 }
258 }
259
260 onDoubleClicked:
261 {
262 _listView.currentIndex = index
263 if(!Maui.Handy.singleClick)
264 {
265 tagListComposer.list.appendItem(_tagsModel.get(_listView.currentIndex))
266 }
267 }
268
269 onPressAndHold:
270 {
271 _listView.currentIndex = index
272 _menu.open()
273 }
274
275 onRightClicked:
276 {
277 _listView.currentIndex = index
278 _menu.open()
279 }
280 }
281 }
282 ]
283
284 page.footer: FB.TagList
285 {
286 id: tagListComposer
287 width: parent.width
288 visible: count > 0
289
290 onTagRemoved: (index) => list.remove(index)
291 placeholderText: i18nd("mauikitfilebrowsing", "No tags yet.")
292 }
293
294 onClosed:
295 {
296 composerList.urls = []
297 tagText.clear()
298 _tagsModel.filter = ""
299 }
300
301 onOpened: tagText.forceActiveFocus()
302
303 /**
304 * @brief Gathers the composed set of tags in the bottom composing TagsBar to the given file URLs, emits the `tagsReady` signal and then closes the dialog.
305 */
306 function setTags()
307 {
308 control.tagsReady(tagListComposer.list.newTags )
309 close()
310 }
311}
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
KGuiItem clear()
const QList< QKeySequence > & close()
void remove(qsizetype i, qsizetype n)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 11:55:53 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.