]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/InsetParamsDialog.cpp
No need (any longer?) to create a new view for lyxfiles-open
[lyx.git] / src / frontends / qt / InsetParamsDialog.cpp
1 /**
2  * \file InsetParamsDialog.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Abdelrazak Younes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "InsetParamsDialog.h"
14
15 #include "GuiBox.h"
16 #include "GuiBranch.h"
17 #include "GuiBibitem.h"
18 #include "GuiCounter.h"
19 #include "GuiERT.h"
20 #include "GuiHSpace.h"
21 #include "GuiHyperlink.h"
22 #include "GuiInfo.h"
23 #include "GuiLabel.h"
24 #include "GuiLine.h"
25 #include "GuiNomenclature.h"
26 #include "GuiPrintNomencl.h"
27 #include "GuiTabular.h"
28 #include "GuiVSpace.h"
29 #include "FloatPlacement.h"
30
31 #include "InsetParamsWidget.h"
32 #include "qt_helpers.h"
33
34 #include "Buffer.h"
35 #include "buffer_funcs.h"
36 #include "BufferParams.h"
37 #include "BufferView.h"
38 #include "Cursor.h"
39 #include "FuncRequest.h"
40 #include "FuncStatus.h"
41 #include "LyX.h"
42
43 #include "support/debug.h"
44 #include "support/lstrings.h"
45
46 #include <QDialogButtonBox>
47
48 using namespace std;
49 using namespace lyx::support;
50
51 namespace lyx {
52 namespace frontend {
53
54 /////////////////////////////////////////////////////////////////
55 //
56 // InsetParamsDialog::Private
57 //
58 /////////////////////////////////////////////////////////////////
59
60 struct InsetParamsDialog::Private
61 {
62         Private() : widget_(nullptr), inset_(nullptr), changed_(false) {}
63         ///
64         InsetParamsWidget * widget_;
65         /// The inset that was used at last Restore or Apply operation.
66         Inset const * inset_;
67         /// Set to true whenever the dialog is changed and set back to
68         /// false when the dialog is applied or restored.
69         bool changed_;
70 };
71
72 /////////////////////////////////////////////////////////////////
73 //
74 // InsetParamsDialog
75 //
76 /////////////////////////////////////////////////////////////////
77
78 InsetParamsDialog::InsetParamsDialog(GuiView & lv, InsetParamsWidget * widget)
79         : DialogView(lv, toqstr(insetName(widget->insetCode())),
80         widget->dialogTitle()), d(new Private)
81 {
82         setupUi(this);
83         // Remove margins since the widget is embedded in dialog which provides them
84         widget->layout()->setContentsMargins(0, 0, 0, 0);
85         setInsetParamsWidget(widget);
86         immediateApplyCB->setChecked(false);
87         synchronizedCB->setChecked(true);
88         on_immediateApplyCB_stateChanged(false);
89         setFocusProxy(widget);
90         newPB = buttonBox->addButton(qt_("Ne&w Inset"),
91                              QDialogButtonBox::ActionRole);
92         // fix height to minimum
93         setFixedHeight(sizeHint().height());
94 }
95
96 InsetParamsDialog::~InsetParamsDialog()
97 {
98         delete d;
99 }
100
101
102 bool InsetParamsDialog::initialiseParams(std::string const & sdata)
103 {
104         if (!d->widget_->initialiseParams(sdata))
105                 resetDialog();
106         return true;
107 }
108
109
110 void InsetParamsDialog::setInsetParamsWidget(InsetParamsWidget * widget)
111 {
112         d->widget_ = widget;
113         stackedWidget->addWidget(widget);
114         stackedWidget->setCurrentWidget(widget);
115         connect(d->widget_, SIGNAL(changed()), this, SLOT(onWidget_changed()));
116 }
117
118
119 void InsetParamsDialog::on_buttonBox_clicked(QAbstractButton * button)
120 {
121         switch (buttonBox->buttonRole(button)) {
122         case QDialogButtonBox::AcceptRole: {// OK
123                 Inset const * i = inset(d->widget_->insetCode());
124                 if (i)
125                         applyView();
126                 else
127                         newInset();
128                 hide();
129                 break;
130         }
131         case QDialogButtonBox::ApplyRole:
132                 applyView();
133                 break;
134         case QDialogButtonBox::RejectRole:// Cancel or Close
135                 hide();
136                 break;
137         case QDialogButtonBox::ResetRole: {
138                 resetDialog();
139                 break;
140         }
141         case QDialogButtonBox::ActionRole:// New Inset
142                 newInset();
143                 break;
144         default:
145                 break;
146         }
147 }
148
149
150 void InsetParamsDialog::resetDialog()
151 {
152         updateView(true);
153         buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
154         d->changed_ = false;
155         d->inset_ = inset(d->widget_->insetCode());
156 }
157
158
159 void InsetParamsDialog::newInset()
160 {
161         docstring const argument = d->widget_->dialogToParams();
162         dispatch(FuncRequest(d->widget_->creationCode(), argument));
163 }
164
165
166 bool InsetParamsDialog::newInsetAllowed() const
167 {
168         docstring const argument = d->widget_->dialogToParams();
169         FuncRequest const fr = FuncRequest(d->widget_->creationCode(), argument);
170         FuncStatus const fs(getStatus(fr));
171         return fs.enabled();
172 }
173
174
175 void InsetParamsDialog::on_immediateApplyCB_stateChanged(int state)
176 {
177         checkWidgets(state == Qt::Checked);
178 }
179
180
181 void InsetParamsDialog::on_synchronizedCB_stateChanged(int)
182 {
183         checkWidgets(false);
184 }
185
186
187 docstring InsetParamsDialog::checkWidgets(bool immediate)
188 {
189         bool const read_only = buffer().isReadonly();
190         bool const widget_ok = d->widget_->checkWidgets(read_only);
191         Inset const * ins = inset(d->widget_->insetCode());
192         docstring const argument = d->widget_->dialogToParams();
193         bool valid_argument = !argument.empty();
194         if (ins)
195                 valid_argument &= ins->validateModifyArgument(argument);
196         FuncCode const code = immediate
197                 ? d->widget_->creationCode() : LFUN_INSET_MODIFY;
198         bool const lfun_ok = lyx::getStatus(FuncRequest(code, argument)).enabled();
199
200         bool const changed_inset = ins && (ins != d->inset_ || d->changed_);
201         buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!immediate && widget_ok
202                                                             && !read_only && valid_argument
203                                                             && (!ins || changed_inset));
204         bool const can_be_restored = !immediate && !read_only && changed_inset;
205         buttonBox->button(QDialogButtonBox::Reset)->setEnabled(can_be_restored);
206         buttonBox->button(QDialogButtonBox::Apply)->setEnabled(!immediate
207                                                                && lfun_ok && widget_ok
208                                                                && !read_only && valid_argument
209                                                                && changed_inset);
210         immediateApplyCB->setEnabled(ins && !read_only);
211         // This seems to be the only way to access custom buttons
212         QList<QAbstractButton*> buttons = buttonBox->buttons();
213         for (auto & button : buttons) {
214                 if (buttonBox->buttonRole(button) == QDialogButtonBox::ActionRole)
215                         button->setEnabled(widget_ok && !read_only
216                                                   && valid_argument
217                                                   && newInsetAllowed());
218         }
219         synchronizedCB->setEnabled(!immediate);
220         return argument;
221 }
222
223
224 void InsetParamsDialog::onWidget_changed()
225 {
226         d->changed_ = true;
227         docstring const argument = checkWidgets(immediateApplyCB->isChecked());
228         if (immediateApplyCB->isChecked()
229             && d->widget_->checkWidgets(buffer().isReadonly()))
230                 dispatch(FuncRequest(LFUN_INSET_MODIFY, argument));
231 }
232
233
234 void InsetParamsDialog::applyView()
235 {
236         docstring const argument = checkWidgets(immediateApplyCB->isChecked());
237         dispatch(FuncRequest(LFUN_INSET_MODIFY, argument));
238         d->changed_ = false;
239         d->inset_ = inset(d->widget_->insetCode());
240         updateView(true);
241 }
242
243
244 void InsetParamsDialog::updateView(bool update_widget)
245 {
246         if (update_widget) {
247                 Inset const * i = inset(d->widget_->insetCode());
248                 if (i) {
249                         d->widget_->blockSignals(true);
250                         d->widget_->paramsToDialog(i);
251                         d->widget_->blockSignals(false);
252                 }
253         }
254         checkWidgets(immediateApplyCB->isChecked());
255 }
256
257
258 void InsetParamsDialog::updateView()
259 {
260         bool const update_widget =
261                 (synchronizedCB->isChecked() || immediateApplyCB->isChecked());
262         updateView(update_widget);
263
264         // Somewhere in the chain this can lose default status (#11417)
265         buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
266 }
267
268 } // namespace frontend
269 } // namespace lyx
270
271 #include "moc_InsetParamsDialog.cpp"