Changeset View
Changeset View
Standalone View
Standalone View
src/qtquick/qml/QuestionAsker.qml
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright (C) 2019 Dan Leinir Turthra Jensen <admin@leinir.dk> | ||||
3 | * | ||||
4 | * This library is free software; you can redistribute it and/or | ||||
5 | * modify it under the terms of the GNU Lesser General Public | ||||
6 | * License as published by the Free Software Foundation; either | ||||
7 | * version 2.1 of the License, or (at your option) version 3, or any | ||||
8 | * later version accepted by the membership of KDE e.V. (or its | ||||
9 | * successor approved by the membership of KDE e.V.), which shall | ||||
10 | * act as a proxy defined in Section 6 of version 3 of the license. | ||||
11 | * | ||||
12 | * This library is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
15 | * Lesser General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU Lesser General Public | ||||
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | * | ||||
20 | */ | ||||
21 | | ||||
22 | /** | ||||
23 | * @brief A component used to forward questions from KNewStuff's engine to the UI | ||||
24 | * | ||||
25 | * This component is equivalent to the WidgetQuestionListener | ||||
26 | * @see KNewStuff::WidgetQuestionListener | ||||
27 | * @see KNewStuffCore::Question | ||||
28 | * @since 5.62 | ||||
29 | */ | ||||
30 | | ||||
31 | import QtQuick 2.11 | ||||
32 | import QtQuick.Controls 2.11 as QtControls | ||||
33 | import QtQuick.Layouts 1.11 as QtLayouts | ||||
34 | | ||||
35 | import org.kde.kirigami 2.7 as Kirigami | ||||
36 | | ||||
37 | import org.kde.newstuff.core 1.62 as NewStuffCore | ||||
38 | import org.kde.newstuff 1.62 as NewStuff | ||||
39 | | ||||
40 | QtControls.Dialog { | ||||
41 | id: dialog | ||||
42 | modal: true | ||||
43 | focus: true | ||||
44 | property int questionType | ||||
45 | anchors.centerIn: QtControls.Overlay.overlay | ||||
46 | margins: Kirigami.Units.largeSpacing | ||||
47 | padding: Kirigami.Units.largeSpacing | ||||
48 | standardButtons: { | ||||
49 | switch (questionType) { | ||||
50 | case NewStuffCore.Question.SelectFromListQuestion: | ||||
51 | case NewStuffCore.Question.InputTextQuestion: | ||||
52 | case NewStuffCore.Question.PasswordQuestion: | ||||
53 | case NewStuffCore.Question.ContinueCancelQuestion: | ||||
54 | // QtControls Dialog standardButtons does not have a Continue button... | ||||
55 | return QtControls.Dialog.Ok | QtControls.Dialog.Cancel; | ||||
56 | break; | ||||
57 | case NewStuffCore.Question.YesNoQuestion: | ||||
58 | return QtControls.Dialog.Yes | QtControls.Dialog.No; | ||||
59 | break; | ||||
60 | default: | ||||
61 | break; | ||||
62 | } | ||||
63 | } | ||||
64 | | ||||
65 | Connections { | ||||
66 | target: NewStuff.QuickQuestionListener | ||||
67 | onAskListQuestion: { | ||||
68 | dialog.questionType = NewStuffCore.Question.SelectFromListQuestion; | ||||
69 | dialog.title = title; | ||||
70 | questionLabel.text = question; | ||||
71 | for (var i = 0; i < list.length; i++) { | ||||
72 | listView.model.append({ text: list[i] }); | ||||
73 | } | ||||
74 | listView.currentIndex = 0; | ||||
75 | listView.visible = true; | ||||
76 | dialog.open(); | ||||
77 | } | ||||
78 | onAskContinueCancelQuestion: { | ||||
79 | dialog.questionType = NewStuffCore.Question.ContinueCancelQuestion; | ||||
80 | dialog.title = title; | ||||
81 | questionLabel.text = question; | ||||
82 | dialog.open(); | ||||
83 | } | ||||
84 | onAskTextInputQuestion: { | ||||
85 | dialog.questionType = NewStuffCore.Question.InputTextQuestion; | ||||
86 | dialog.title = title; | ||||
87 | questionLabel.text = question; | ||||
88 | textInput.visible = true; | ||||
89 | dialog.open(); | ||||
90 | } | ||||
91 | onAskPasswordQuestion: { | ||||
92 | dialog.questionType = NewStuffCore.Question.PasswordQuestion; | ||||
93 | dialog.title = title; | ||||
94 | questionLabel.text = question; | ||||
95 | textInput.echoMode = QtControls.TextInput.PasswordEchoOnEdit; | ||||
96 | textInput.visible = true; | ||||
97 | dialog.open(); | ||||
98 | } | ||||
99 | onAskYesNoQuestion: { | ||||
100 | dialog.questionType = NewStuffCore.Question.YesNoQuestion; | ||||
101 | dialog.title = title; | ||||
102 | questionLabel.text = question; | ||||
103 | dialog.open(); | ||||
104 | } | ||||
105 | } | ||||
106 | Connections { | ||||
107 | target: applicationWindow() | ||||
108 | // Since dialogs in QML don't automatically reject when the application is closed, | ||||
109 | // we just do that little job for it (and then we don't end up blocking everything | ||||
110 | // when the application is shut without the question being answered) | ||||
111 | onClosing: { | ||||
112 | if (dialog.opened === true) { | ||||
113 | passResponse(false); | ||||
114 | } | ||||
115 | } | ||||
116 | } | ||||
117 | function passResponse(responseIsContinue) { | ||||
118 | var input = ""; | ||||
119 | switch(dialog.questionType) { | ||||
120 | case NewStuffCore.Question.SelectFromListQuestion: | ||||
121 | input = listView.currentItem.text; | ||||
122 | listView.model.clear(); | ||||
123 | listView.visible = false; | ||||
124 | break; | ||||
125 | case NewStuffCore.Question.InputTextQuestion: | ||||
126 | input = textInput.text; | ||||
127 | textInput.text = ""; | ||||
128 | textInput.visible = false; | ||||
129 | break; | ||||
130 | case NewStuffCore.Question.PasswordQuestion: | ||||
131 | input = textInput.text; | ||||
132 | textInput.text = ""; | ||||
133 | textInput.visible = false; | ||||
134 | textInput.echoMode = QtControls.TextInput.Normal; | ||||
135 | break; | ||||
136 | case NewStuffCore.Question.ContinueCancelQuestion: | ||||
137 | case NewStuffCore.Question.YesNoQuestion: | ||||
138 | default: | ||||
139 | // Nothing special to do for these types of question, we just pass along the positive or negative response | ||||
140 | break; | ||||
141 | } | ||||
142 | NewStuff.QuickQuestionListener.passResponse(responseIsContinue, input); | ||||
143 | } | ||||
144 | | ||||
145 | QtLayouts.ColumnLayout { | ||||
146 | anchors.fill: parent | ||||
147 | property int maxWidth: applicationWindow().width - (dialog.leftPadding + dialog.leftMargin + dialog.rightMargin + dialog.rightPadding) | ||||
148 | QtControls.Label { | ||||
149 | id: questionLabel | ||||
150 | QtLayouts.Layout.maximumWidth: parent.maxWidth | ||||
151 | wrapMode: Text.Wrap | ||||
152 | } | ||||
153 | ListView { | ||||
154 | id: listView | ||||
155 | visible: false | ||||
156 | QtLayouts.Layout.maximumWidth: parent.maxWidth | ||||
157 | QtLayouts.Layout.fillWidth: true | ||||
158 | QtLayouts.Layout.minimumHeight: Kirigami.Units.gridUnit * 6 | ||||
159 | model: ListModel { } | ||||
160 | delegate: Kirigami.BasicListItem { | ||||
161 | reserveSpaceForIcon: false | ||||
162 | text: model.text | ||||
163 | } | ||||
164 | } | ||||
165 | QtControls.TextField { | ||||
166 | id: textInput | ||||
167 | visible: false | ||||
168 | QtLayouts.Layout.maximumWidth: parent.maxWidth | ||||
169 | QtLayouts.Layout.fillWidth: true | ||||
170 | } | ||||
171 | } | ||||
172 | onAccepted: { | ||||
173 | passResponse(true); | ||||
174 | } | ||||
175 | onRejected: { | ||||
176 | passResponse(false); | ||||
177 | } | ||||
178 | } |