Unity 8
MessageMenuItemFactory.qml
1 /*
2  * Copyright 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors:
17  * Renato Araujo Oliveira Filho <renato@canonical.com>
18  * Olivier Tilloy <olivier.tilloy@canonical.com>
19  */
20 
21 import QtQuick 2.4
22 import Ubuntu.Components 1.3
23 import Ubuntu.Settings.Menus 0.1 as Menus
24 import QMenuModel 0.1 as QMenuModel
25 import Utils 0.1 as Utils
26 
27 Loader {
28  id: messageFactoryItem
29  objectName: "messageItem"
30  property var menuModel: null
31  property QtObject menuData: null
32  property int menuIndex: -1
33 
34  property bool selected: false
35  signal menuSelected
36  signal menuDeselected
37 
38  QtObject {
39  id: priv
40  property var extendedData: menuData && menuData.ext || undefined
41  property var actionsDescription: getExtendedProperty(extendedData, "xCanonicalMessageActions", undefined)
42  property date time: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 0) / 1000)
43  property string timeString: i18n.relativeDateTime(time)
44  }
45  LiveTimer {
46  frequency: LiveTimer.Relative
47  relativeTime: priv.time
48  onTrigger: priv.timeString = Qt.binding(function() { return i18n.relativeDateTime(priv.time); })
49  }
50 
51  onMenuModelChanged: {
52  loadAttributes();
53  }
54  onMenuIndexChanged: {
55  loadAttributes();
56  }
57 
58  sourceComponent: loadMessage(priv.actionsDescription)
59 
60  function loadMessage(actions)
61  {
62  var parameterType = ""
63  for (var actIndex in actions) {
64  var desc = actions[actIndex];
65  if (desc["parameter-type"] !== undefined) {
66  parameterType += desc["parameter-type"];
67  } else {
68  parameterType += "_";
69  }
70  }
71 
72  if (parameterType === "") {
73  return simpleMessage;
74  } else if (parameterType === "s") {
75  return textMessage;
76  } else if (parameterType === "_s") {
77  return snapDecision;
78  } else {
79  console.debug("Unknown paramater type: " + parameterType);
80  }
81  return undefined;
82  }
83 
84  function loadAttributes() {
85  if (!menuModel || menuIndex == -1) return;
86  menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
87  'x-canonical-text': 'string',
88  'x-canonical-message-actions': 'variant',
89  'icon': 'icon',
90  'x-canonical-app-icon': 'icon'});
91  }
92 
93  function getExtendedProperty(object, propertyName, defaultValue) {
94  if (object && object.hasOwnProperty(propertyName)) {
95  return object[propertyName];
96  }
97  return defaultValue;
98  }
99 
100  Component {
101  id: simpleMessage
102 
103  Menus.SimpleMessageMenu {
104  id: message
105  objectName: "simpleTextMessage"
106  // text
107  title: menuData && menuData.label || ""
108  time: priv.timeString
109  body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
110  // icons
111  avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
112  icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/message")
113  // actions
114  enabled: menuData && menuData.sensitive || false
115  removable: !selected
116  confirmRemoval: true
117  selected: messageFactoryItem.selected
118 
119  onIconActivated: {
120  menuModel.activate(menuIndex, true);
121  }
122  onDismissed: {
123  menuModel.activate(menuIndex, false);
124  }
125  onTriggered: {
126  if (selected) {
127  menuDeselected();
128  } else {
129  menuSelected();
130  }
131  }
132  }
133  }
134 
135  Component {
136  id: textMessage
137 
138  Menus.TextMessageMenu {
139  id: message
140  objectName: "textMessage"
141  property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
142  priv.actionsDescription[0] :
143  undefined
144 
145  property var replyAction: QMenuModel.UnityMenuAction {
146  model: menuModel
147  index: menuIndex
148  name: getExtendedProperty(replyActionDescription, "name", "")
149  }
150 
151  // text
152  title: menuData && menuData.label || ""
153  time: priv.timeString
154  body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
155  replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
156  replyHintText: i18n.ctr("Label: Hint in message indicator line edit", "Reply")
157  // icons
158  avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
159  icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/message")
160  // actions
161  replyEnabled: replyAction.valid && replyAction.enabled
162  enabled: menuData && menuData.sensitive || false
163  removable: !selected
164  confirmRemoval: true
165  selected: messageFactoryItem.selected
166  highlightWhenPressed: false
167 
168  onIconActivated: {
169  menuModel.activate(menuIndex, true);
170  }
171  onDismissed: {
172  menuModel.activate(menuIndex, false);
173  }
174  onReplied: {
175  replyAction.activate(value);
176  }
177  onTriggered: {
178  if (selected) {
179  menuDeselected();
180  } else {
181  menuSelected();
182  }
183  }
184  }
185  }
186 
187  Component {
188  id: snapDecision
189 
190  Menus.SnapDecisionMenu {
191  id: message
192  objectName: "snapDecision"
193  property var activateActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
194  priv.actionsDescription[0] : undefined
195  property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 1 ?
196  priv.actionsDescription[1] : undefined
197 
198  property var activateAction: QMenuModel.UnityMenuAction {
199  model: menuModel
200  index: menuIndex
201  name: getExtendedProperty(activateActionDescription, "name", "")
202  }
203  property var replyAction: QMenuModel.UnityMenuAction {
204  model: menuModel
205  index: menuIndex
206  name: getExtendedProperty(replyActionDescription, "name", "")
207  }
208 
209  // text
210  title: menuData && menuData.label || ""
211  time: priv.timeString
212  body: getExtendedProperty(priv.extendedData, "xCanonicalText", "")
213  actionButtonText: getExtendedProperty(activateActionDescription, "label", i18n.ctr("Button: Call back on phone", "Call back"))
214  replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
215  // icons
216  avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
217  icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "image://theme/missed-call")
218  // actions
219  actionEnabled: activateAction.valid && activateAction.enabled
220  replyEnabled: replyAction.valid && replyAction.enabled
221  enabled: menuData && menuData.sensitive || false
222  removable: !selected
223  confirmRemoval: true
224  selected: messageFactoryItem.selected
225  highlightWhenPressed: false
226 
227  onIconActivated: {
228  menuModel.activate(menuIndex, true);
229  }
230  onDismissed: {
231  menuModel.activate(menuIndex, false);
232  }
233  onActionActivated: {
234  activateAction.activate();
235  }
236  onReplied: {
237  replyAction.activate(value);
238  }
239  onTriggered: {
240  if (selected) {
241  menuDeselected();
242  } else {
243  menuSelected();
244  }
245  }
246  }
247  }
248 }