1 /** @file libshell/src/inputdialog.cpp Dialog for querying text from the user.
2 *
3 * @authors Copyright © 2013-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4 *
5 * @par License
6 * LGPL: http://www.gnu.org/licenses/lgpl.html
7 *
8 * <small>This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or (at your
11 * option) any later version. This program is distributed in the hope that it
12 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
14 * General Public License for more details. You should have received a copy of
15 * the GNU Lesser General Public License along with this program; if not, see:
16 * http://www.gnu.org/licenses</small>
17 */
18
19 #include "de/shell/InputDialog"
20 #include "de/shell/LabelWidget"
21 #include "de/shell/LineEditWidget"
22 #include "de/shell/MenuWidget"
23 #include "de/shell/TextRootWidget"
24
25 namespace de { namespace shell {
26
DENG2_PIMPL_NOREF(InputDialog)27 DENG2_PIMPL_NOREF(InputDialog)
28 {
29 LabelWidget * label;
30 LineEditWidget *edit;
31 MenuWidget * menu;
32 String userText;
33 int result;
34
35 Impl() : label(0), edit(0), menu(0), result(0)
36 {}
37
38 ~Impl()
39 {}
40 };
41
InputDialog(String const & name)42 InputDialog::InputDialog(String const &name)
43 : DialogWidget(name), d(new Impl)
44 {
45 RuleRectangle &rect = rule();
46
47 // Label.
48 d->label = new LabelWidget;
49 d->label->setExpandsToFitLines(true); // determines height independently
50
51 d->label->rule()
52 .setInput(Rule::Width, rect.width())
53 .setInput(Rule::Top, rect.top())
54 .setInput(Rule::Left, rect.left());
55
56 // Address editor.
57 d->edit = new LineEditWidget;
58 d->edit->setName(d->edit->uniqueName("edit"));
59
60 d->edit->rule()
61 .setInput(Rule::Width, rect.width())
62 .setInput(Rule::Left, rect.left())
63 .setInput(Rule::Top, d->label->rule().bottom() + 1);
64
65 // Menu for actions.
66 d->menu = new MenuWidget(MenuWidget::AlwaysOpen);
67 d->menu->setName(d->menu->uniqueName("menu"));
68 d->menu->setBorder(MenuWidget::NoBorder);
69 d->menu->setBackgroundAttribs(TextCanvas::Char::DefaultAttributes);
70 d->menu->setSelectionAttribs(TextCanvas::Char::Reverse);
71 d->menu->appendItem(new Action(tr("OK"), this, SLOT(accept())));
72 d->menu->appendItem(new Action(tr("Cancel"), KeyEvent(Qt::Key_C, KeyEvent::Control),
73 this, SLOT(reject())), "Ctrl-C");
74
75 d->menu->rule()
76 .setInput(Rule::Width, rect.width())
77 .setInput(Rule::Left, rect.left())
78 .setInput(Rule::Bottom, rect.bottom());
79
80 add(d->label);
81 add(d->edit);
82 add(d->menu);
83
84 setFocusCycle(WidgetList() << d->edit << d->menu);
85
86 // Outer dimensions.
87 rect.setInput(Rule::Width, Const(50));
88 rect.setInput(Rule::Height,
89 d->menu->rule().height() +
90 d->edit->rule().height() +
91 d->label->rule().height() + 2);
92 }
93
label()94 LabelWidget &InputDialog::label()
95 {
96 return *d->label;
97 }
98
lineEdit()99 LineEditWidget &InputDialog::lineEdit()
100 {
101 return *d->edit;
102 }
103
menu()104 MenuWidget &InputDialog::menu()
105 {
106 return *d->menu;
107 }
108
setWidth(int width)109 void InputDialog::setWidth(int width)
110 {
111 rule().setInput(Rule::Width, Const(width));
112 }
113
setDescription(String const & desc)114 void InputDialog::setDescription(String const &desc)
115 {
116 d->label->setLabel(desc);
117 }
118
setPrompt(String const & prompt)119 void InputDialog::setPrompt(String const &prompt)
120 {
121 d->edit->setPrompt(prompt);
122 }
123
setText(String const & text)124 void InputDialog::setText(String const &text)
125 {
126 d->edit->setText(text);
127 }
128
setAcceptLabel(String const & label)129 void InputDialog::setAcceptLabel(String const &label)
130 {
131 d->menu->itemAction(0).setLabel(label);
132 redraw();
133 }
134
setRejectLabel(String const & label)135 void InputDialog::setRejectLabel(String const &label)
136 {
137 d->menu->itemAction(1).setLabel(label);
138 redraw();
139 }
140
prepare()141 void InputDialog::prepare()
142 {
143 DialogWidget::prepare();
144
145 d->userText.clear();
146 d->result = 0;
147
148 root().setFocus(d->edit);
149 }
150
finish(int result)151 void InputDialog::finish(int result)
152 {
153 d->result = result;
154 d->userText.clear();
155 if (result) d->userText = d->edit->text();
156
157 DialogWidget::finish(result);
158 }
159
text() const160 String InputDialog::text() const
161 {
162 return d->userText;
163 }
164
result() const165 int InputDialog::result() const
166 {
167 return d->result;
168 }
169
170 }} // namespace de::shell
171