|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (developer.feedback@nokia.com) |
|
6 ** |
|
7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile. |
|
8 ** |
|
9 ** GNU Lesser General Public License Usage |
|
10 ** This file may be used under the terms of the GNU Lesser General Public |
|
11 ** License version 2.1 as published by the Free Software Foundation and |
|
12 ** appearing in the file LICENSE.LGPL included in the packaging of this file. |
|
13 ** Please review the following information to ensure the GNU Lesser General |
|
14 ** Public License version 2.1 requirements will be met: |
|
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
16 ** |
|
17 ** In addition, as a special exception, Nokia gives you certain additional |
|
18 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
20 ** |
|
21 ** If you have questions regarding the use of this file, please contact |
|
22 ** Nokia at developer.feedback@nokia.com. |
|
23 ** |
|
24 ****************************************************************************/ |
|
25 |
|
26 |
|
27 #include <hbinputdialog.h> |
|
28 #include "hbinputdialog_p.h" |
|
29 #include <hblineedit.h> |
|
30 #include <hbaction.h> |
|
31 #include "hbinputdialogcontent_p.h" |
|
32 #include <hbstyleoptioninputdialog.h> |
|
33 #include <hbvalidator.h> |
|
34 |
|
35 #include <QGraphicsScene> |
|
36 |
|
37 #ifdef HBINPUTDIALOG_DEBUG |
|
38 #include <QtDebug> |
|
39 #endif |
|
40 |
|
41 |
|
42 /*! |
|
43 @beta |
|
44 @hbwidgets |
|
45 \class HbInputDialog |
|
46 \brief Class used to get information from the user. |
|
47 |
|
48 input value can be a text, int, double or ip address. |
|
49 static API's can be used to quickly get an input from user. |
|
50 */ |
|
51 HbInputDialog::HbInputDialog(QGraphicsItem* parent) : |
|
52 HbDialog(*new HbInputDialogPrivate, parent) |
|
53 { |
|
54 Q_D(HbInputDialog); |
|
55 d->init(); |
|
56 } |
|
57 |
|
58 HbInputDialog::HbInputDialog(HbDialogPrivate &dd, QGraphicsItem *parent) : |
|
59 HbDialog(dd, parent) |
|
60 { |
|
61 Q_D(HbInputDialog); |
|
62 d->q_ptr = this; |
|
63 d->init(); |
|
64 } |
|
65 |
|
66 HbInputDialog::~HbInputDialog() |
|
67 { |
|
68 } |
|
69 |
|
70 |
|
71 /*! |
|
72 @beta |
|
73 Sets the input mode of the primary(Top/default)line edit in the query widget. |
|
74 this can be TextMode, IntMode, RealMode. each mode will affect how the line |
|
75 edit filters its input. |
|
76 */ |
|
77 void HbInputDialog::setInputMode(InputMode mode ,int row) |
|
78 { |
|
79 Q_D(HbInputDialog); |
|
80 d->setInputMode(mode,row); |
|
81 } |
|
82 |
|
83 |
|
84 /*! |
|
85 @beta |
|
86 Returns input mode for top/default line edit. |
|
87 */ |
|
88 HbInputDialog::InputMode HbInputDialog::inputMode(int row) const |
|
89 { |
|
90 Q_D(const HbInputDialog); |
|
91 if(row == 0) { |
|
92 return d->mPrimaryMode; |
|
93 } else { |
|
94 if (row ==1) { |
|
95 return d->mSecondaryMode; |
|
96 } else { |
|
97 return (HbInputDialog::InputMode)0; |
|
98 } |
|
99 } |
|
100 } |
|
101 |
|
102 |
|
103 /*! |
|
104 @beta |
|
105 Sets the prompt \a text for top/default line edit. |
|
106 */ |
|
107 void HbInputDialog::setPromptText(const QString &text, int row) |
|
108 { |
|
109 Q_D(HbInputDialog); |
|
110 d->setPromptText(text, row); |
|
111 } |
|
112 |
|
113 |
|
114 /*! |
|
115 @beta |
|
116 Returns prompt text for top/default line edit. |
|
117 */ |
|
118 QString HbInputDialog::promptText(int row) const |
|
119 { |
|
120 Q_D(const HbInputDialog); |
|
121 return d->promptText(row); |
|
122 } |
|
123 |
|
124 /*! |
|
125 @beta |
|
126 Sets the top/default line edit value in \a text format. |
|
127 */ |
|
128 void HbInputDialog::setValue(const QVariant &value,int row) |
|
129 { |
|
130 Q_D(HbInputDialog); |
|
131 d->setText(value.toString(),row); |
|
132 } |
|
133 |
|
134 /*! |
|
135 @beta |
|
136 Returns top/default line edit value as QVariant object. |
|
137 */ |
|
138 QVariant HbInputDialog::value(int row) const |
|
139 { |
|
140 Q_D(const HbInputDialog); |
|
141 return QVariant(d->text(row)); |
|
142 } |
|
143 |
|
144 /*! |
|
145 @beta |
|
146 Sets the visibility of bottom line edit and prompt text. |
|
147 */ |
|
148 void HbInputDialog::setAdditionalRowVisible(bool visible) |
|
149 { |
|
150 Q_D(HbInputDialog); |
|
151 d->setAdditionalRowVisible(visible); |
|
152 } |
|
153 |
|
154 /*! |
|
155 @beta |
|
156 Returns the visibility of secondary(bottom line edit and prompt text). |
|
157 */ |
|
158 bool HbInputDialog::isAdditionalRowVisible() |
|
159 { |
|
160 Q_D(HbInputDialog); |
|
161 return d->isAdditionalRowVisible(); |
|
162 } |
|
163 |
|
164 |
|
165 /*! |
|
166 @beta |
|
167 Validator is used to validate the content and cursor movements. |
|
168 |
|
169 \note Validator uses undo stack to back out invalid changes. Therefore undo |
|
170 is enabled when validator is set. |
|
171 \sa HbAbstractEdit::setValidator |
|
172 */ |
|
173 void HbInputDialog::setValidator(HbValidator *validator,int row) |
|
174 { |
|
175 Q_D(HbInputDialog); |
|
176 if( (row == 0) && (d->mContentWidget->mEdit1) ) { |
|
177 d->mContentWidget->mEdit1->setValidator(validator); |
|
178 } else if( (row == 1) && (d->mContentWidget->mEdit2) ) { |
|
179 d->mContentWidget->mEdit2->setValidator(validator); |
|
180 } |
|
181 } |
|
182 |
|
183 |
|
184 /*! |
|
185 @beta |
|
186 returns the validator of the inputDialog's line edit. |
|
187 */ |
|
188 HbValidator * HbInputDialog::validator(int row) const |
|
189 { |
|
190 Q_D(const HbInputDialog); |
|
191 if( (row == 0) && (d->mContentWidget->mEdit1) ) { |
|
192 return d->mContentWidget->mEdit1->validator(); |
|
193 } else if( (row == 1) && (d->mContentWidget->mEdit2) ) { |
|
194 return d->mContentWidget->mEdit2->validator(); |
|
195 } |
|
196 return NULL; |
|
197 } |
|
198 |
|
199 |
|
200 /*! |
|
201 @beta |
|
202 returns the lineEdit pointer. will return NULL if row is greater than 2. |
|
203 */ |
|
204 HbLineEdit* HbInputDialog::lineEdit(int row) const |
|
205 { |
|
206 Q_D(const HbInputDialog); |
|
207 if( (row == 0) && (d->mContentWidget->mEdit1) ) { |
|
208 return d->mContentWidget->mEdit1; |
|
209 } else if( (row == 1) && (d->mContentWidget->mEdit2) ) { |
|
210 return d->mContentWidget->mEdit2; |
|
211 } |
|
212 return NULL; |
|
213 } |
|
214 |
|
215 /*! |
|
216 @beta |
|
217 sets the echo mode for the given row. |
|
218 |
|
219 \sa HbLineEdit::setEchoMode |
|
220 */ |
|
221 void HbInputDialog::setEchoMode(HbLineEdit::EchoMode echoMode,int row) |
|
222 { |
|
223 Q_D(HbInputDialog); |
|
224 if( (row == 0) && (d->mContentWidget->mEdit1) ) { |
|
225 d->mContentWidget->mEdit1->setEchoMode(echoMode); |
|
226 } else if( (row == 1) ) { |
|
227 if(d->mContentWidget->mEdit2) { |
|
228 d->mContentWidget->mEdit2->setEchoMode(echoMode); |
|
229 } |
|
230 d->mEchoMode = echoMode; |
|
231 } |
|
232 }; |
|
233 |
|
234 |
|
235 /*! |
|
236 @beta |
|
237 Provides access to primitives of HbInputDialog. |
|
238 \param primitive is the type of the requested primitive. The available |
|
239 primitives are P_InputDialog_text, and P_InputDialog_additional_text. |
|
240 |
|
241 */ |
|
242 QGraphicsItem* HbInputDialog::primitive(HbStyle::Primitive primitive) const |
|
243 { |
|
244 Q_D(const HbInputDialog); |
|
245 switch (primitive) { |
|
246 case HbStyle::P_InputDialog_text: |
|
247 return d->mContentWidget->mLabel1; |
|
248 case HbStyle::P_InputDialog_additional_text: |
|
249 return d->mContentWidget->mLabel2; |
|
250 default: |
|
251 return 0; |
|
252 } |
|
253 } |
|
254 |
|
255 /*! |
|
256 @beta |
|
257 \reimp |
|
258 Initializes \a option with the values from this HbInputDialog. |
|
259 */ |
|
260 void HbInputDialog::initStyleOption(HbStyleOptionInputDialog *option) const |
|
261 { |
|
262 Q_D(const HbInputDialog); |
|
263 HbDialog::initStyleOption(option); |
|
264 option->text = d->mPromptText; |
|
265 option->additionalText = d->mPromptAdditionalText; |
|
266 } |
|
267 |
|
268 |
|
269 /*! |
|
270 @beta |
|
271 updatePrimitives. |
|
272 |
|
273 */ |
|
274 void HbInputDialog::updatePrimitives() |
|
275 { |
|
276 Q_D(HbInputDialog); |
|
277 HbDialog::updatePrimitives(); |
|
278 HbStyleOptionInputDialog option; |
|
279 initStyleOption(&option); |
|
280 if (d->mContentWidget->mLabel1) { |
|
281 style()->updatePrimitive(d->mContentWidget->mLabel1, HbStyle::P_InputDialog_text, &option); |
|
282 } |
|
283 |
|
284 if (d->mContentWidget->mLabel2 && d->mContentWidget->mAdditionalRowVisible) { |
|
285 style()->updatePrimitive(d->mContentWidget->mLabel2, HbStyle::P_InputDialog_additional_text, &option); |
|
286 } |
|
287 } |
|
288 |
|
289 |
|
290 /*! |
|
291 @beta |
|
292 returns the echoMode of line edit. returns -1 if row is more than 2. |
|
293 */ |
|
294 HbLineEdit::EchoMode HbInputDialog::echoMode(int row) const |
|
295 { |
|
296 Q_D(const HbInputDialog); |
|
297 if( (row == 0) && (d->mContentWidget->mEdit1) ) { |
|
298 return d->mContentWidget->mEdit1->echoMode(); |
|
299 } else if( (row == 1) ) { |
|
300 return d->mEchoMode; |
|
301 } |
|
302 return HbLineEdit::EchoMode(-1);// |
|
303 } |
|
304 |
|
305 |
|
306 /*! |
|
307 @beta |
|
308 Static convenience function to get a string from the user. \a |
|
309 label is the text which is shown to the user (it should |
|
310 say what should be entered). \a text is the default text which is |
|
311 placed in the line edit. If \a ok is non-null \e *\a ok will be |
|
312 set to true if the user pressed \gui OK and to false if the user pressed |
|
313 \gui Cancel. The dialog's parent is \a parent. The dialog will be |
|
314 modal. |
|
315 |
|
316 This function return data has to be queried in the finished(HbAction*) slot. |
|
317 |
|
318 \sa getInteger(), getDouble(), getIp() |
|
319 */ |
|
320 void HbInputDialog::getText(const QString &label, |
|
321 QObject *receiver, |
|
322 const char* member, |
|
323 const QString &text, |
|
324 QGraphicsScene *scene, |
|
325 QGraphicsItem *parent) |
|
326 { |
|
327 HbInputDialog *dlg = new HbInputDialog(parent); |
|
328 if (scene && !parent) { |
|
329 scene->addItem(dlg); |
|
330 } |
|
331 dlg->setPromptText(label); |
|
332 dlg->setInputMode(TextInput); |
|
333 dlg->setValue(text); |
|
334 dlg->setAttribute(Qt::WA_DeleteOnClose); |
|
335 dlg->open(receiver,member); |
|
336 } |
|
337 |
|
338 /*! |
|
339 @deprecated HbInputDialog::getText(const QString&,const QString&,bool*,QGraphicsScene*,QGraphicsItem*) |
|
340 Static convenience function to get a string from the user. \a |
|
341 label is the text which is shown to the user (it should |
|
342 say what should be entered). \a text is the default text which is |
|
343 placed in the line edit. If \a ok is non-null \e *\a ok will be |
|
344 set to true if the user pressed \gui OK and to false if the user pressed |
|
345 \gui Cancel. The dialog's parent is \a parent. The dialog will be |
|
346 modal. |
|
347 |
|
348 This function returns the text which has been entered in the line |
|
349 edit. It will not return an empty string. |
|
350 |
|
351 \sa getInteger(), getDouble(), getIp() |
|
352 */ |
|
353 QString HbInputDialog::getText(const QString &label,const QString &text, |
|
354 bool *ok, QGraphicsScene *scene, QGraphicsItem *parent) |
|
355 { |
|
356 Q_UNUSED(parent);//this is a bug in popup framework, cannot set parent will affect fading |
|
357 |
|
358 HbInputDialog *dlg = new HbInputDialog(); |
|
359 if (scene) { |
|
360 scene->addItem(dlg); |
|
361 } |
|
362 QString result; |
|
363 dlg->setPromptText(label); |
|
364 dlg->setInputMode(TextInput); |
|
365 dlg->setValue(text); |
|
366 HbAction* action = dlg->exec(); |
|
367 if(action == dlg->secondaryAction()) { //Cancel was pressed |
|
368 if(ok) { |
|
369 *ok = false; |
|
370 } |
|
371 } else { //OK was pressed |
|
372 if(ok) { |
|
373 *ok = true; |
|
374 } |
|
375 result = dlg->value().toString(); |
|
376 } |
|
377 delete dlg; |
|
378 return result; |
|
379 } |
|
380 |
|
381 |
|
382 /*! |
|
383 @beta |
|
384 Static convenience function to get an integer input from the |
|
385 user.\a label is the text which is shown to the user |
|
386 (it should say what should be entered). \a value is the default |
|
387 integer which the spinbox will be set to. |
|
388 If \a ok is non-null *\a ok will be set to true if the user |
|
389 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
390 dialog's parent is \a parent. The dialog will be modal. |
|
391 |
|
392 This function return data has to be queried in the finished(HbAction*) slot. |
|
393 |
|
394 \sa getText(), getDouble(), getIp() |
|
395 */ |
|
396 void HbInputDialog::getInteger(const QString &label, |
|
397 QObject *receiver, |
|
398 const char *member, |
|
399 int value, |
|
400 QGraphicsScene *scene, |
|
401 QGraphicsItem *parent) |
|
402 { |
|
403 HbInputDialog *dlg = new HbInputDialog(parent); |
|
404 if(scene && !parent) { |
|
405 scene->addItem(dlg); |
|
406 } |
|
407 dlg->setPromptText(label); |
|
408 dlg->setInputMode(IntInput); |
|
409 dlg->setValue(QString::number(value)); |
|
410 dlg->setAttribute(Qt::WA_DeleteOnClose); |
|
411 dlg->open(receiver,member); |
|
412 } |
|
413 /*! |
|
414 @deprecated HbInputDialog::getInteger(const QString&,int,bool*,QGraphicsScene*,QGraphicsItem*) |
|
415 Static convenience function to get an integer input from the |
|
416 user.\a label is the text which is shown to the user |
|
417 (it should say what should be entered). \a value is the default |
|
418 integer which the spinbox will be set to. |
|
419 If \a ok is non-null *\a ok will be set to true if the user |
|
420 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
421 dialog's parent is \a parent. The dialog will be modal. |
|
422 |
|
423 This function returns the integer which has been entered by the user. |
|
424 |
|
425 \sa getText(), getDouble(), getIp() |
|
426 */ |
|
427 int HbInputDialog::getInteger(const QString &label, int value, |
|
428 bool *ok,QGraphicsScene *scene,QGraphicsItem *parent) |
|
429 { |
|
430 Q_UNUSED(parent) |
|
431 |
|
432 HbInputDialog *dlg = new HbInputDialog(); |
|
433 QString result; |
|
434 dlg->setPromptText(label); |
|
435 dlg->setInputMode(IntInput); |
|
436 dlg->setValue(QString::number(value)); |
|
437 if(scene) { |
|
438 scene->addItem(dlg); |
|
439 } |
|
440 HbAction* action = dlg->exec(); |
|
441 if(action == dlg->secondaryAction()) { //Cancel was pressed |
|
442 if(ok) { |
|
443 *ok = false; |
|
444 } |
|
445 } else { //OK was pressed |
|
446 if(ok) { |
|
447 *ok = true; |
|
448 } |
|
449 result = dlg->value().toString(); |
|
450 } |
|
451 delete dlg; |
|
452 #ifdef HBINPUTDIALOG_DEBUG |
|
453 qDebug()<<"Value:"<<result; |
|
454 #endif |
|
455 return result.toInt(); |
|
456 } |
|
457 |
|
458 |
|
459 /*! |
|
460 @beta |
|
461 Static convenience function to get a floating point number from |
|
462 the user.\a label is the text which is shown to the user |
|
463 (it should say what should be entered). \a value is the default |
|
464 floating point number that the line edit will be set to. |
|
465 |
|
466 If \a ok is non-null, *\a ok will be set to true if the user |
|
467 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
468 dialog's parent is \a parent. The dialog will be modal. |
|
469 |
|
470 This function return data has to be queried in the finished(HbAction*) slot. |
|
471 |
|
472 \sa getText(), getInteger(), getIp() |
|
473 */ |
|
474 void HbInputDialog::getDouble(const QString &label, |
|
475 QObject *receiver, |
|
476 const char *member, |
|
477 double value, |
|
478 QGraphicsScene *scene, |
|
479 QGraphicsItem *parent) |
|
480 { |
|
481 HbInputDialog *dlg = new HbInputDialog(parent); |
|
482 if(scene && !parent) { |
|
483 scene->addItem(dlg); |
|
484 } |
|
485 dlg->setPromptText(label); |
|
486 dlg->setInputMode(RealInput); |
|
487 dlg->setValue(QString::number(value)); |
|
488 dlg->open(receiver,member); |
|
489 } |
|
490 |
|
491 |
|
492 /*! |
|
493 @deprecated HbInputDialog::getDouble(const QString &,double,bool*,QGraphicsScene*,QGraphicsItem*) |
|
494 Static convenience function to get a floating point number from |
|
495 the user.\a label is the text which is shown to the user |
|
496 (it should say what should be entered). \a value is the default |
|
497 floating point number that the line edit will be set to. |
|
498 |
|
499 If \a ok is non-null, *\a ok will be set to true if the user |
|
500 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
501 dialog's parent is \a parent. The dialog will be modal. |
|
502 |
|
503 This function returns the floating point number which has been |
|
504 entered by the user. |
|
505 |
|
506 \sa getText(), getInteger(), getIp() |
|
507 */ |
|
508 double HbInputDialog::getDouble(const QString &label, double value, |
|
509 bool *ok, QGraphicsScene *scene, QGraphicsItem *parent) |
|
510 { |
|
511 Q_UNUSED(parent) |
|
512 |
|
513 HbInputDialog *dlg = new HbInputDialog(); |
|
514 QString result; |
|
515 dlg->setPromptText(label); |
|
516 dlg->setInputMode(RealInput); |
|
517 dlg->setValue(QString::number(value)); |
|
518 if(scene) { |
|
519 scene->addItem(dlg); |
|
520 } |
|
521 HbAction* action = dlg->exec(); |
|
522 if(action == dlg->secondaryAction()){ //Cancel was pressed |
|
523 if(ok) { |
|
524 *ok = false; |
|
525 } |
|
526 } else { //OK was pressed |
|
527 if(ok) { |
|
528 *ok = true; |
|
529 } |
|
530 result = dlg->value().toString(); |
|
531 } |
|
532 delete dlg; |
|
533 #ifdef HBINPUTDIALOG_DEBUG |
|
534 qDebug()<<"Value:"<<result; |
|
535 #endif |
|
536 return result.toDouble(); |
|
537 } |
|
538 |
|
539 /*! |
|
540 @beta |
|
541 Static convenience function to get a ip address from |
|
542 the user.\a label is the text which is shown to the user |
|
543 (it should say what should be entered). \a address is the default |
|
544 QHostAddress that the line edit will be set to. |
|
545 |
|
546 If \a ok is non-null, *\a ok will be set to true if the user |
|
547 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
548 dialog's parent is \a parent. The dialog will be modal. |
|
549 |
|
550 This function return data has to be queried in the finished(HbAction*) slot. |
|
551 |
|
552 \sa getText(), getInteger(), getDouble() |
|
553 */ |
|
554 void HbInputDialog::getIp(const QString &label, |
|
555 QObject *receiver, |
|
556 const char *member, |
|
557 const QString &ipaddress, |
|
558 QGraphicsScene *scene, |
|
559 QGraphicsItem *parent) |
|
560 { |
|
561 HbInputDialog *dlg = new HbInputDialog(parent); |
|
562 if(scene && !parent) { |
|
563 scene->addItem(dlg); |
|
564 } |
|
565 dlg->setPromptText(label); |
|
566 dlg->setInputMode(IpInput); |
|
567 dlg->setValue(ipaddress); |
|
568 dlg->open(receiver,member); |
|
569 } |
|
570 |
|
571 |
|
572 /*! |
|
573 @deprecated HbInputDialog::getIp(const QString &,const QString&, bool *,QGraphicsScene*,QGraphicsItem*) |
|
574 Static convenience function to get a ip address from |
|
575 the user.\a label is the text which is shown to the user |
|
576 (it should say what should be entered). \a address is the default |
|
577 QHostAddress that the line edit will be set to. |
|
578 |
|
579 If \a ok is non-null, *\a ok will be set to true if the user |
|
580 pressed \gui OK and to false if the user pressed \gui Cancel. The |
|
581 dialog's parent is \a parent. The dialog will be modal. |
|
582 |
|
583 This function returns the ip address number which has been |
|
584 entered by the user. |
|
585 |
|
586 \sa getText(), getInteger(), getDouble() |
|
587 */ |
|
588 QString HbInputDialog::getIp(const QString &label, const QString &ipaddress, bool *ok, QGraphicsScene *scene, |
|
589 QGraphicsItem *parent) |
|
590 { |
|
591 Q_UNUSED(parent) |
|
592 |
|
593 HbInputDialog *dlg = new HbInputDialog(); |
|
594 QString result; |
|
595 dlg->setPromptText(label); |
|
596 dlg->setInputMode(IpInput); |
|
597 dlg->setValue(ipaddress); |
|
598 if(scene) { |
|
599 scene->addItem(dlg); |
|
600 } |
|
601 HbAction* action = dlg->exec(); |
|
602 if(action == dlg->secondaryAction()){ //Cancel was pressed |
|
603 if(ok) { |
|
604 *ok = false; |
|
605 } |
|
606 } else { //OK was pressed |
|
607 if(ok) { |
|
608 *ok = true; |
|
609 } |
|
610 result = dlg->value().toString(); |
|
611 } |
|
612 delete dlg; |
|
613 #ifdef HBINPUTDIALOG_DEBUG |
|
614 qDebug()<<"Value:"<<result; |
|
615 #endif |
|
616 return result; |
|
617 } |
|
618 #include "moc_hbinputdialog.cpp" |
|
619 |