modernize: Pass arguments by value and move in constructors
[quassel.git] / src / qtui / settingspages / bufferviewsettingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #include "bufferviewsettingspage.h"
22
23 #include <QMessageBox>
24 #include <utility>
25
26 #include "buffermodel.h"
27 #include "bufferviewconfig.h"
28 #include "bufferviewfilter.h"
29 #include "client.h"
30 #include "clientbufferviewmanager.h"
31 #include "icon.h"
32 #include "network.h"
33 #include "networkmodel.h"
34 #include "util.h"
35
36 BufferViewSettingsPage::BufferViewSettingsPage(QWidget *parent)
37     : SettingsPage(tr("Interface"), tr("Custom Chat Lists"), parent),
38     _ignoreWidgetChanges(false),
39     _useBufferViewHint(false),
40     _bufferViewHint(0)
41 {
42     ui.setupUi(this);
43     //Hide the hide inactive networks feature on older cores (which won't save the setting)
44     if (!Client::isCoreFeatureEnabled(Quassel::Feature::HideInactiveNetworks))
45         ui.hideInactiveNetworks->hide();
46
47     ui.renameBufferView->setIcon(icon::get("edit-rename"));
48     ui.addBufferView->setIcon(icon::get("list-add"));
49     ui.deleteBufferView->setIcon(icon::get("edit-delete"));
50
51     reset();
52
53     ui.bufferViewList->setSortingEnabled(true);
54     ui.settingsGroupBox->setEnabled(false);
55     ui.bufferViewPreview->setEnabled(false);
56
57     coreConnectionStateChanged(Client::isConnected()); // need a core connection!
58     connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool)));
59     connect(ui.bufferViewList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
60         this, SLOT(bufferViewSelectionChanged(const QItemSelection &, const QItemSelection &)));
61
62     connect(ui.onlyStatusBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
63     connect(ui.onlyChannelBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
64     connect(ui.onlyQueryBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
65     connect(ui.addNewBuffersAutomatically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
66     connect(ui.sortAlphabetically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
67     connect(ui.hideInactiveBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
68     connect(ui.hideInactiveNetworks, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
69     connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
70     connect(ui.minimumActivitySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
71     connect(ui.showSearch, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
72
73     connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(enableStatusBuffers(int)));
74 }
75
76
77 BufferViewSettingsPage::~BufferViewSettingsPage()
78 {
79     reset();
80 }
81
82
83 void BufferViewSettingsPage::reset()
84 {
85     ui.bufferViewList->clear();
86     ui.deleteBufferView->setEnabled(false);
87
88     QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
89     QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
90     BufferViewConfig *config;
91     while (changedConfigIter != changedConfigIterEnd) {
92         config = changedConfigIter.value();
93         changedConfigIter = _changedBufferViews.erase(changedConfigIter);
94         config->deleteLater();
95     }
96
97     QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
98     QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
99     while (newConfigIter != newConfigIterEnd) {
100         config = *newConfigIter;
101         newConfigIter = _newBufferViews.erase(newConfigIter);
102         config->deleteLater();
103     }
104
105     _deleteBufferViews.clear();
106
107     _useBufferViewHint = false;
108
109     setChangedState(false);
110 }
111
112
113 void BufferViewSettingsPage::load()
114 {
115     bool useBufferViewHint = _useBufferViewHint;
116     int bufferViewHint = _bufferViewHint;
117     reset();
118
119     if (!Client::bufferViewManager())
120         return;
121
122     const QList<BufferViewConfig *> bufferViewConfigs = Client::bufferViewManager()->bufferViewConfigs();
123     foreach(BufferViewConfig *bufferViewConfig, bufferViewConfigs) {
124         addBufferView(bufferViewConfig);
125     }
126
127     _ignoreWidgetChanges = true;
128     // load network selector
129     ui.networkSelector->clear();
130     ui.networkSelector->addItem(tr("All"));
131     ui.networkSelector->setItemData(0, qVariantFromValue<NetworkId>(NetworkId()));
132     const Network *net;
133     foreach(NetworkId netId, Client::networkIds()) {
134         net = Client::network(netId);
135         ui.networkSelector->addItem(net->networkName());
136         ui.networkSelector->setItemData(ui.networkSelector->count() - 1, qVariantFromValue<NetworkId>(net->networkId()));
137     }
138     _ignoreWidgetChanges = false;
139
140     if (!useBufferViewHint || !selectBufferViewById(bufferViewHint))
141         ui.bufferViewList->setCurrentRow(0);
142 }
143
144
145 void BufferViewSettingsPage::save()
146 {
147     setEnabled(false);
148
149     BufferViewConfig *currentConfig = bufferView(ui.bufferViewList->currentRow());
150     if (currentConfig) {
151         _useBufferViewHint = true;
152         _bufferViewHint = currentConfig->bufferViewId();
153     }
154
155     QVariantList newConfigs;
156     QVariantList deleteConfigs;
157     QVariantList changedConfigs;
158
159     foreach(int bufferId, _deleteBufferViews) {
160         deleteConfigs << bufferId;
161     }
162     _deleteBufferViews.clear();
163     if (Client::bufferViewManager()) {
164         Client::bufferViewManager()->requestDeleteBufferViews(deleteConfigs);
165     }
166
167     QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
168     QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
169     BufferViewConfig *config, *changedConfig;
170     while (changedConfigIter != changedConfigIterEnd) {
171         config = changedConfigIter.key();
172         changedConfig = changedConfigIter.value();
173         changedConfigIter = _changedBufferViews.erase(changedConfigIter);
174         config->requestUpdate(changedConfig->toVariantMap());
175         changedConfig->deleteLater();
176     }
177
178     QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
179     QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
180     while (newConfigIter != newConfigIterEnd) {
181         config = *newConfigIter;
182         newConfigIter = _newBufferViews.erase(newConfigIter);
183         newConfigs << config->toVariantMap();
184         config->deleteLater();
185     }
186     if (Client::bufferViewManager()) {
187         Client::bufferViewManager()->requestCreateBufferViews(newConfigs);
188     }
189
190     load();
191     setEnabled(true);
192 }
193
194
195 void BufferViewSettingsPage::coreConnectionStateChanged(bool state)
196 {
197     setEnabled(state);
198     if (state) {
199         load();
200         connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int)));
201     }
202     else {
203         reset();
204     }
205 }
206
207
208 void BufferViewSettingsPage::addBufferView(BufferViewConfig *config)
209 {
210     QListWidgetItem *item = new QListWidgetItem(config->bufferViewName(), ui.bufferViewList);
211     item->setData(Qt::UserRole, qVariantFromValue<QObject *>(qobject_cast<QObject *>(config)));
212     connect(config, SIGNAL(updatedRemotely()), this, SLOT(updateBufferView()));
213     connect(config, SIGNAL(destroyed()), this, SLOT(bufferViewDeleted()));
214     ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
215 }
216
217
218 void BufferViewSettingsPage::addBufferView(int bufferViewId)
219 {
220     // we are informed about a new bufferview from Client::bufferViewManager()
221     Q_ASSERT(Client::bufferViewManager());
222     addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewId));
223     selectBufferViewById(bufferViewId);
224 }
225
226
227 void BufferViewSettingsPage::bufferViewDeleted()
228 {
229     BufferViewConfig *config = static_cast<BufferViewConfig *>(sender());
230     QObject *obj;
231     for (int i = 0; i < ui.bufferViewList->count(); i++) {
232         obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
233         if (config == static_cast<BufferViewConfig *>(obj)) {
234             QListWidgetItem *item = ui.bufferViewList->takeItem(i);
235             delete item;
236             break;
237         }
238     }
239     ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
240 }
241
242
243 void BufferViewSettingsPage::newBufferView(const QString &bufferViewName)
244 {
245     // id's of newly created bufferviews are negative (-1, -2... -n)
246     int fakeId = -1 * (_newBufferViews.count() + 1);
247     BufferViewConfig *config = new BufferViewConfig(fakeId);
248     config->setBufferViewName(bufferViewName);
249     config->setInitialized();
250     QList<BufferId> bufferIds;
251     if (config->addNewBuffersAutomatically()) {
252         if (config->sortAlphabetically()) {
253             bufferIds = Client::networkModel()->allBufferIdsSorted();
254         }
255         else {
256             bufferIds = Client::networkModel()->allBufferIds();
257             qSort(bufferIds);
258             config->setProperty("OriginalBufferList", toVariantList<BufferId>(bufferIds));
259         }
260     }
261     config->initSetBufferList(bufferIds);
262
263     _newBufferViews << config;
264     addBufferView(config);
265     ui.bufferViewList->setCurrentRow(listPos(config));
266 }
267
268
269 int BufferViewSettingsPage::listPos(BufferViewConfig *config)
270 {
271     QObject *obj;
272     for (int i = 0; i < ui.bufferViewList->count(); i++) {
273         obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
274         if (config == qobject_cast<BufferViewConfig *>(obj))
275             return i;
276     }
277     return -1;
278 }
279
280
281 BufferViewConfig *BufferViewSettingsPage::bufferView(int listPos)
282 {
283     if (listPos < ui.bufferViewList->count() && listPos >= 0) {
284         QObject *obj = ui.bufferViewList->item(listPos)->data(Qt::UserRole).value<QObject *>();
285         return qobject_cast<BufferViewConfig *>(obj);
286     }
287     else {
288         return nullptr;
289     }
290 }
291
292
293 bool BufferViewSettingsPage::selectBufferViewById(int bufferViewId)
294 {
295     BufferViewConfig *config;
296     for (int i = 0; i < ui.bufferViewList->count(); i++) {
297         config = qobject_cast<BufferViewConfig *>(ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>());
298         if (config && config->bufferViewId() == bufferViewId) {
299             ui.bufferViewList->setCurrentRow(i);
300             return true;
301         }
302     }
303     return false;
304 }
305
306
307 void BufferViewSettingsPage::updateBufferView()
308 {
309     BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
310     if (!config)
311         return;
312
313     int itemPos = listPos(config);
314     if (itemPos == -1) {
315         qWarning() << "BufferViewSettingsPage::updateBufferView(): view is unknown:" << config->bufferViewId();
316         return;
317     }
318     ui.bufferViewList->item(itemPos)->setText(config->bufferViewName());
319     if (itemPos == ui.bufferViewList->currentRow())
320         loadConfig(config);
321 }
322
323
324 void BufferViewSettingsPage::enableStatusBuffers(int networkIdx)
325 {
326     // we don't show a status buffer if we show multiple networks as selecting
327     // the network is the same as selecting the status buffer.
328     ui.onlyStatusBuffers->setEnabled(networkIdx != 0);
329 }
330
331
332 void BufferViewSettingsPage::on_addBufferView_clicked()
333 {
334     if (!Client::bufferViewManager())
335         return;
336
337     QStringList existing;
338     foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
339         existing << bufferConfig->bufferViewName();
340     }
341
342     BufferViewEditDlg dlg(QString(), existing, this);
343     if (dlg.exec() == QDialog::Accepted) {
344         newBufferView(dlg.bufferViewName());
345         changed();
346     }
347 }
348
349
350 void BufferViewSettingsPage::on_renameBufferView_clicked()
351 {
352     if (ui.bufferViewList->selectedItems().isEmpty())
353         return;
354
355     if (!Client::bufferViewManager())
356         return;
357
358     BufferViewConfig *config = bufferView(ui.bufferViewList->currentRow());
359     if (!config)
360         return;
361
362     QStringList existing;
363     foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
364         existing << bufferConfig->bufferViewName();
365     }
366
367     BufferViewEditDlg dlg(config->bufferViewName(), existing, this);
368     if (dlg.exec() == QDialog::Accepted) {
369         BufferViewConfig *changedConfig = cloneConfig(config);
370         changedConfig->setBufferViewName(dlg.bufferViewName());
371         ui.bufferViewList->item(listPos(config))->setText(dlg.bufferViewName());
372         changed();
373     }
374 }
375
376
377 void BufferViewSettingsPage::on_deleteBufferView_clicked()
378 {
379     if (ui.bufferViewList->selectedItems().isEmpty())
380         return;
381
382     QListWidgetItem *currentItem = ui.bufferViewList->item(ui.bufferViewList->currentRow());
383     QString viewName = currentItem->text();
384     int viewId = bufferView(ui.bufferViewList->currentRow())->bufferViewId();
385     int ret = QMessageBox::question(this, tr("Delete Chat List?"),
386         tr("Do you really want to delete the chat list \"%1\"?").arg(viewName),
387         QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
388
389     if (ret == QMessageBox::Yes) {
390         ui.bufferViewList->removeItemWidget(currentItem);
391         BufferViewConfig *config = qobject_cast<BufferViewConfig *>(currentItem->data(Qt::UserRole).value<QObject *>());
392         delete currentItem;
393         if (viewId >= 0) {
394             _deleteBufferViews << viewId;
395             changed();
396         }
397         else if (config) {
398             QList<BufferViewConfig *>::iterator iter = _newBufferViews.begin();
399             while (iter != _newBufferViews.end()) {
400                 if (*iter == config) {
401                     iter = _newBufferViews.erase(iter);
402                     break;
403                 }
404                 else {
405                     ++iter;
406                 }
407             }
408             delete config;
409             if (_deleteBufferViews.isEmpty() && _changedBufferViews.isEmpty() && _newBufferViews.isEmpty())
410                 setChangedState(false);
411         }
412     }
413 }
414
415
416 void BufferViewSettingsPage::bufferViewSelectionChanged(const QItemSelection &current, const QItemSelection &previous)
417 {
418     Q_UNUSED(previous)
419
420     if (!current.isEmpty()) {
421         ui.settingsGroupBox->setEnabled(true);
422         ui.bufferViewPreview->setEnabled(true);
423
424         loadConfig(configForDisplay(bufferView(ui.bufferViewList->currentRow())));
425     }
426     else {
427         ui.settingsGroupBox->setEnabled(false);
428         ui.bufferViewPreview->setEnabled(false);
429     }
430 }
431
432
433 void BufferViewSettingsPage::loadConfig(BufferViewConfig *config)
434 {
435     if (!config)
436         return;
437
438     _ignoreWidgetChanges = true;
439     ui.onlyStatusBuffers->setChecked(BufferInfo::StatusBuffer & config->allowedBufferTypes());
440     ui.onlyChannelBuffers->setChecked(BufferInfo::ChannelBuffer & config->allowedBufferTypes());
441     ui.onlyQueryBuffers->setChecked(BufferInfo::QueryBuffer & config->allowedBufferTypes());
442     ui.addNewBuffersAutomatically->setChecked(config->addNewBuffersAutomatically());
443     ui.sortAlphabetically->setChecked(config->sortAlphabetically());
444     ui.hideInactiveBuffers->setChecked(config->hideInactiveBuffers());
445     ui.hideInactiveNetworks->setChecked(config->hideInactiveNetworks());
446     ui.showSearch->setChecked(config->showSearch());
447
448     int networkIndex = 0;
449     for (int i = 0; i < ui.networkSelector->count(); i++) {
450         if (ui.networkSelector->itemData(i).value<NetworkId>() == config->networkId()) {
451             networkIndex = i;
452             break;
453         }
454     }
455     ui.networkSelector->setCurrentIndex(networkIndex);
456
457     int activityIndex = 0;
458     int minimumActivity = config->minimumActivity();
459     while (minimumActivity) {
460         activityIndex++;
461         minimumActivity = minimumActivity >> 1;
462     }
463     ui.minimumActivitySelector->setCurrentIndex(activityIndex);
464
465     ui.bufferViewPreview->setFilteredModel(Client::bufferModel(), config);
466
467     _ignoreWidgetChanges = false;
468 }
469
470
471 void BufferViewSettingsPage::saveConfig(BufferViewConfig *config)
472 {
473     if (!config)
474         return;
475
476     int allowedBufferTypes = 0;
477     if (ui.onlyStatusBuffers->isChecked())
478         allowedBufferTypes |= BufferInfo::StatusBuffer;
479     if (ui.onlyChannelBuffers->isChecked())
480         allowedBufferTypes |= BufferInfo::ChannelBuffer;
481     if (ui.onlyQueryBuffers->isChecked())
482         allowedBufferTypes |= BufferInfo::QueryBuffer;
483     config->setAllowedBufferTypes(allowedBufferTypes);
484
485     config->setAddNewBuffersAutomatically(ui.addNewBuffersAutomatically->isChecked());
486     config->setSortAlphabetically(ui.sortAlphabetically->isChecked());
487     config->setHideInactiveBuffers(ui.hideInactiveBuffers->isChecked());
488     config->setHideInactiveNetworks(ui.hideInactiveNetworks->isChecked());
489     config->setNetworkId(ui.networkSelector->itemData(ui.networkSelector->currentIndex()).value<NetworkId>());
490     config->setShowSearch(ui.showSearch->isChecked());
491
492     int minimumActivity = 0;
493     if (ui.minimumActivitySelector->currentIndex() > 0)
494         minimumActivity = 1 << (ui.minimumActivitySelector->currentIndex() - 1);
495     config->setMinimumActivity(minimumActivity);
496
497     QList<BufferId> bufferIds = fromVariantList<BufferId>(config->property("OriginalBufferList").toList());
498     if (config->sortAlphabetically())
499         Client::networkModel()->sortBufferIds(bufferIds);
500
501     if (!_newBufferViews.contains(config) || config->addNewBuffersAutomatically())
502         config->initSetBufferList(bufferIds);
503 }
504
505
506 void BufferViewSettingsPage::widgetHasChanged()
507 {
508     if (_ignoreWidgetChanges)
509         return;
510     setChangedState(testHasChanged());
511 }
512
513
514 bool BufferViewSettingsPage::testHasChanged()
515 {
516     saveConfig(cloneConfig(bufferView(ui.bufferViewList->currentRow())));
517
518     if (!_newBufferViews.isEmpty())
519         return true;
520
521     bool changed = false;
522     QHash<BufferViewConfig *, BufferViewConfig *>::iterator iter = _changedBufferViews.begin();
523     QHash<BufferViewConfig *, BufferViewConfig *>::iterator iterEnd = _changedBufferViews.end();
524     while (iter != iterEnd) {
525         if (&(iter.key()) == &(iter.value())) {
526             iter.value()->deleteLater();
527             iter = _changedBufferViews.erase(iter);
528         }
529         else {
530             changed = true;
531             ++iter;
532         }
533     }
534     return changed;
535 }
536
537
538 BufferViewConfig *BufferViewSettingsPage::cloneConfig(BufferViewConfig *config)
539 {
540     if (!config || config->bufferViewId() < 0)
541         return config;
542
543     if (_changedBufferViews.contains(config))
544         return _changedBufferViews[config];
545
546     BufferViewConfig *changedConfig = new BufferViewConfig(-1, this);
547     changedConfig->fromVariantMap(config->toVariantMap());
548     changedConfig->setInitialized();
549     _changedBufferViews[config] = changedConfig;
550     connect(config, SIGNAL(bufferAdded(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
551     connect(config, SIGNAL(bufferMoved(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
552     connect(config, SIGNAL(bufferRemoved(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
553 //   connect(config, SIGNAL(addBufferRequested(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
554 //   connect(config, SIGNAL(moveBufferRequested(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
555 //   connect(config, SIGNAL(removeBufferRequested(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
556
557     changedConfig->setProperty("OriginalBufferList", toVariantList<BufferId>(config->bufferList()));
558     // if this is the currently displayed view we have to change the config of the preview filter
559     BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(ui.bufferViewPreview->model());
560     if (filter && filter->config() == config)
561         filter->setConfig(changedConfig);
562     ui.bufferViewPreview->setConfig(changedConfig);
563
564     return changedConfig;
565 }
566
567
568 BufferViewConfig *BufferViewSettingsPage::configForDisplay(BufferViewConfig *config)
569 {
570     if (_changedBufferViews.contains(config))
571         return _changedBufferViews[config];
572     else
573         return config;
574 }
575
576
577 /**************************************************************************
578  * BufferViewEditDlg
579  *************************************************************************/
580 BufferViewEditDlg::BufferViewEditDlg(const QString &old, QStringList exist, QWidget *parent) : QDialog(parent), existing(std::move(exist))
581 {
582     ui.setupUi(this);
583
584     if (old.isEmpty()) {
585         // new buffer
586         setWindowTitle(tr("Add Chat List"));
587         on_bufferViewEdit_textChanged(""); // disable ok button
588     }
589     else {
590         ui.bufferViewEdit->setText(old);
591     }
592 }
593
594
595 void BufferViewEditDlg::on_bufferViewEdit_textChanged(const QString &text)
596 {
597     ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(text.isEmpty() || existing.contains(text));
598 }