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 hint: 1
85
86 maxHeight: 500
87 maxWidth: 400
88
89 actions: [
90
91 Action
92 {
93 text: i18nd("mauikitfilebrowsing", "Save")
94 onTriggered: control.setTags()
95 },
96
97 Action
98 {
99 text: i18nd("mauikitfilebrowsing", "Cancel")
100 onTriggered: control.close()
101 }
102 ]
103
104 headBar.visible: true
105 headBar.forceCenterMiddleContent: false
106 headBar.middleContent: TextField
107 {
108 id: tagText
109 Layout.fillWidth: true
110 Layout.maximumWidth: 500
111 placeholderText: i18nd("mauikitfilebrowsing", "Filter or add a new tag")
112 // validator: RegExpValidator { regExp: /[0-9A-F]+/ }
113 onAccepted:
114 {
115 const tags = tagText.text.split(",")
116 for(var i in tags)
117 {
118 const myTag = tags[i].trim()
119 _tagsList.insert(myTag)
120 tagListComposer.list.append(myTag)
121 }
122 clear()
123 _tagsModel.filter = ""
124 }
125
126 onTextChanged:
127 {
128 _tagsModel.filter = text
129 }
130 }
131
132 Maui.InfoDialog
133 {
134 id: _deleteDialog
135
136 property string tag
137 title: i18nd("mauikitfilebrowsing", "Delete %1", tag)
138 message: i18nd("mauikitfilebrowsing", "Are you sure you want to delete this tag? This action can not be undone.")
139 template.iconSource: "tag"
140 onAccepted:
141 {
142 FB.Tagging.removeTag(tag)
143 _deleteDialog.close()
144 }
145
146 onRejected: _deleteDialog.close()
147 }
148
149 Maui.ContextualMenu
150 {
151 id: _menu
152
153 MenuItem
154 {
155 text: i18nd("mauikitfilebrowsing", "Edit")
156 icon.name: "document-edit"
157 }
158
159 MenuItem
160 {
161 text: i18nd("mauikitfilebrowsing", "Delete")
162 icon.name: "delete"
163 onTriggered:
164 {
165 _deleteDialog.tag = _tagsModel.get(_listView.currentIndex).tag
166 _deleteDialog.open()
167 }
168 }
169 }
170
171 stack: [
172
173 Maui.ListBrowser
174 {
175 id: _listView
176
177 Layout.fillHeight: true
178 Layout.fillWidth: true
179 clip: true
180 currentIndex: -1
181
182 holder.emoji: "qrc:/assets/tag.svg"
183 holder.visible: _listView.count === 0
184 holder.title : i18nd("mauikitfilebrowsing", "No Tags!")
185 holder.body: i18nd("mauikitfilebrowsing", "Create new tags to organize your files.")
186
187 model: Maui.BaseModel
188 {
189 id: _tagsModel
190 sort: "tag"
191 sortOrder: Qt.AscendingOrder
192 recursiveFilteringEnabled: true
193 sortCaseSensitivity: Qt.CaseInsensitive
194 filterCaseSensitivity: Qt.CaseInsensitive
195 list: FB.TagsListModel
196 {
197 id: _tagsList
198 strict: false
199 }
200 }
201
202 delegate: Maui.ListBrowserDelegate
203 {
204 width: ListView.view.width
205 label1.text: model.tag
206 iconSource: model.icon
207 iconSizeHint: Maui.Style.iconSizes.small
208
209 template.content: Rectangle
210 {
211 color: model.color ? model.color : "transparent"
212 height: Maui.Style.iconSizes.small
213 radius: height/2
214 width: height
215 }
216
217 onClicked:
218 {
219 _listView.currentIndex = index
220 if(Qt.styleHints.singleClickActivation)
221 {
222 tagListComposer.list.appendItem(_tagsModel.get(_listView.currentIndex))
223 }
224 }
225
226 onDoubleClicked:
227 {
228 _listView.currentIndex = index
229 if(!Qt.styleHints.singleClickActivation)
230 {
231 tagListComposer.list.appendItem(_tagsModel.get(_listView.currentIndex))
232 }
233 }
234
235 onPressAndHold:
236 {
237 _listView.currentIndex = index
238 _menu.open()
239 }
240
241 onRightClicked:
242 {
243 _listView.currentIndex = index
244 _menu.open()
245 }
246 }
247 },
248
249 Loader
250 {
251 asynchronous: true
252 active: tagListComposer.list.urls.length > 1
253 visible: active
254 Layout.fillWidth: true
255
256 sourceComponent: Maui.ListItemTemplate
257 {
258 id: _info
259
260 property var itemInfo : FB.FM.getFileInfo( tagListComposer.list.urls[0])
261 label1.text: i18nd("mauikitfilebrowsing", "Tagging %1 files", tagListComposer.list.urls.length)
262 label2.text: i18nd("mauikitfilebrowsing", "Add new tags for the selected files.")
263 label2.wrapMode: Text.WrapAtWordBoundaryOrAnywhere
264 iconSource : itemInfo.icon
265 imageSource: itemInfo.thumbnail
266 // iconSizeHint: Maui.Style.iconSizes.huge
267 // headerSizeHint: iconSizeHint + Maui.Style.space.big
268
269 iconComponent: Item
270 {
271 Item
272 {
273 anchors.fill: parent
274 layer.enabled: true
275
276 Rectangle
277 {
278 anchors.fill: parent
279 anchors.leftMargin: Maui.Style.space.small
280 anchors.rightMargin: Maui.Style.space.small
281 radius: Maui.Style.radiusV
282 color: Qt.tint(control.Maui.Theme.textColor, Qt.rgba(control.Maui.Theme.backgroundColor.r, control.Maui.Theme.backgroundColor.g, control.Maui.Theme.backgroundColor.b, 0.9))
283 border.color: Maui.Theme.backgroundColor
284 }
285
286 Rectangle
287 {
288 anchors.fill: parent
289 anchors.topMargin: Maui.Style.space.tiny
290 anchors.leftMargin: Maui.Style.space.tiny
291 anchors.rightMargin: Maui.Style.space.tiny
292 radius: Maui.Style.radiusV
293 color: Qt.tint(control.Maui.Theme.textColor, Qt.rgba(control.Maui.Theme.backgroundColor.r, control.Maui.Theme.backgroundColor.g, control.Maui.Theme.backgroundColor.b, 0.9))
294 border.color: Maui.Theme.backgroundColor
295 }
296
297 Rectangle
298 {
299 anchors.fill: parent
300 anchors.topMargin: Maui.Style.space.small
301 border.color: Maui.Theme.backgroundColor
302
303 radius: Maui.Style.radiusV
304 color: Qt.tint(control.Maui.Theme.textColor, Qt.rgba(control.Maui.Theme.backgroundColor.r, control.Maui.Theme.backgroundColor.g, control.Maui.Theme.backgroundColor.b, 0.9))
305
306 Maui.GridItemTemplate
307 {
308 anchors.fill: parent
309 anchors.margins: Maui.Style.space.tiny
310 iconSizeHint: _info.iconSizeHint
311
312 iconSource: _info.iconSource
313 imageSource: _info.imageSource
314 }
315 }
316 }
317 }
318 }
319 }
320 ]
321
322 page.footer: FB.TagList
323 {
324 id: tagListComposer
325 width: parent.width
326 visible: count > 0
327
328 onTagRemoved: list.remove(index)
329 placeholderText: i18nd("mauikitfilebrowsing", "No tags yet.")
330 }
331
332 onClosed:
333 {
334 composerList.urls = []
335 tagText.clear()
336 _tagsModel.filter = ""
337 }
338
339 onOpened: tagText.forceActiveFocus()
340
341 /**
342 * @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.
343 */
344 function setTags()
345 {
346 var tags = tagListComposer.list.tags
347 control.tagsReady(tags)
348 close()
349 }
350}
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
KGuiItem clear()
KGuiItem close()
void remove(qsizetype i, qsizetype n)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:32:33 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.