File indexing completed on 2024-05-05 05:44:19

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 /*
0010  * Configuration Dialog for KCachegrind
0011  */
0012 
0013 #include "configdlg.h"
0014 
0015 #include <QCheckBox>
0016 #include <QCompleter>
0017 #include <QDir>
0018 #include <QFileDialog>
0019 #include <QMessageBox>
0020 
0021 #include <KColorButton>
0022 
0023 #include "tracedata.h"
0024 #include "globalguiconfig.h"
0025 
0026 
0027 ConfigDlg::ConfigDlg(GlobalGUIConfig* c, TraceData* data,
0028                      QWidget* parent)
0029     :ConfigDlgBase(parent)
0030 {
0031     _config = c;
0032     _data = data;
0033     _objectCS = nullptr;
0034     _classCS = nullptr;
0035     _fileCS = nullptr;
0036 
0037     connect(objectCombo, QOverload<int>::of(&QComboBox::activated),
0038             this, [this](int index) {
0039         objectActivated(objectCombo->itemText(index));
0040     });
0041     connect(objectCombo, &QComboBox::editTextChanged,
0042             this, &ConfigDlg::objectActivated);
0043     connect(objectCheck, &QAbstractButton::toggled,
0044             this, &ConfigDlg::objectCheckChanged);
0045     connect(objectColor, &KColorButton::changed,
0046             this, &ConfigDlg::objectColorChanged);
0047 
0048     connect(classCombo, QOverload<int>::of(&QComboBox::activated),
0049             this, [this](int index) {
0050         classActivated(classCombo->itemText(index));
0051     });
0052     connect(classCombo, &QComboBox::editTextChanged,
0053             this, &ConfigDlg::classActivated);
0054     connect(classCheck, &QAbstractButton::toggled,
0055             this, &ConfigDlg::classCheckChanged);
0056     connect(classColor, &KColorButton::changed,
0057             this, &ConfigDlg::classColorChanged);
0058 
0059     connect(fileCombo, QOverload<int>::of(&QComboBox::activated),
0060             this, [this](int index) {
0061         fileActivated(fileCombo->itemText(index));
0062     });
0063     connect(fileCombo, &QComboBox::editTextChanged,
0064             this, &ConfigDlg::fileActivated);
0065     connect(fileCheck, &QAbstractButton::toggled,
0066             this, &ConfigDlg::fileCheckChanged);
0067     connect(fileColor, &KColorButton::changed,
0068             this, &ConfigDlg::fileColorChanged);
0069 
0070     connect(buttonBox, &QDialogButtonBox::accepted,this, &QDialog::accept);
0071     connect(buttonBox, &QDialogButtonBox::rejected,this, &QDialog::reject);
0072     QString objectPrefix = ProfileContext::typeName(ProfileContext::Object);
0073     QString classPrefix = ProfileContext::typeName(ProfileContext::Class);
0074     QString filePrefix = ProfileContext::typeName(ProfileContext::File);
0075 
0076     objectCombo->setDuplicatesEnabled(false);
0077     classCombo->setDuplicatesEnabled(false);
0078     fileCombo->setDuplicatesEnabled(false);
0079     objectCombo->setCompleter(new QCompleter(objectCombo));
0080     classCombo->setCompleter(new QCompleter(classCombo));
0081     fileCombo->setCompleter(new QCompleter(fileCombo));
0082 
0083     // first unspecified cost items from data
0084     TraceObjectMap::Iterator oit;
0085     QStringList oList;
0086     if (data) {
0087         for ( oit = data->objectMap().begin();
0088               oit != data->objectMap().end(); ++oit )
0089             oList.append((*oit).prettyName());
0090     }
0091 
0092     TraceClassMap::Iterator cit;
0093     QStringList cList;
0094     if (data) {
0095         for ( cit = data->classMap().begin();
0096               cit != data->classMap().end(); ++cit )
0097             cList.append((*cit).prettyName());
0098     }
0099 
0100     TraceFileMap::Iterator fit;
0101     QStringList fList;
0102     if (data) {
0103         for ( fit = data->fileMap().begin();
0104               fit != data->fileMap().end(); ++fit )
0105             fList.append((*fit).prettyName());
0106     }
0107 
0108     // then already defined colors (have to check for duplicates!)
0109     foreach(ConfigColorSetting* cs, c->_colors) {
0110         if (cs->_automatic) continue;
0111 
0112         QString n = cs->_name;
0113         if (n.startsWith(objectPrefix)) {
0114             n.remove(0, objectPrefix.length()+1);
0115             if (oList.indexOf(n) == -1) oList.append(n);
0116         }
0117         else if (n.startsWith(classPrefix)) {
0118             n.remove(0, classPrefix.length()+1);
0119             if (cList.indexOf(n) == -1) cList.append(n);
0120         }
0121         else if (n.startsWith(filePrefix)) {
0122             n.remove(0, filePrefix.length()+1);
0123             if (fList.indexOf(n) == -1) fList.append(n);
0124         }
0125     }
0126 
0127     oList.sort();
0128     cList.sort();
0129     fList.sort();
0130     objectCombo->addItems(oList);
0131     classCombo->addItems(cList);
0132     fileCombo->addItems(fList);
0133 
0134     objectActivated(objectCombo->currentText());
0135     classActivated(classCombo->currentText());
0136     fileActivated(fileCombo->currentText());
0137 
0138     maxListEdit->setValue(c->_maxListCount);
0139 
0140     QTreeWidgetItem* i = new QTreeWidgetItem(dirList);
0141     i->setText(0, i18n("(always)"));
0142     i->setExpanded(true);
0143     QTreeWidgetItem* root = i;
0144     QStringList::const_iterator sit = c->_generalSourceDirs.constBegin();
0145     for(; sit != c->_generalSourceDirs.constEnd(); ++sit ) {
0146         QTreeWidgetItem *item = new QTreeWidgetItem(i);
0147         item->setText(0, sit->isEmpty() ? QDir::rootPath() : *sit);
0148     }
0149     if (data) {
0150         for ( oit = data->objectMap().begin();
0151               oit != data->objectMap().end(); ++oit ) {
0152             const QString n = (*oit).name();
0153             if (n.isEmpty()) continue;
0154             i = new QTreeWidgetItem(dirList);
0155             i->setText(0, n);
0156             i->setExpanded(true);
0157             const QStringList dirs = c->_objectSourceDirs[n];
0158 
0159             sit = dirs.constBegin();
0160             for(; sit != dirs.constEnd(); ++sit ) {
0161                 QTreeWidgetItem *item = new QTreeWidgetItem(i);
0162                 item->setText(0, sit->isEmpty() ? QDir::rootPath() : *sit);
0163             }
0164         }
0165     }
0166 
0167     connect(dirList, &QTreeWidget::itemSelectionChanged,
0168             this, &ConfigDlg::dirsItemChanged);
0169     connect(addDirButton, &QAbstractButton::clicked,
0170             this, &ConfigDlg::dirsAddPressed);
0171     connect(deleteDirButton, &QAbstractButton::clicked,
0172             this, &ConfigDlg::dirsDeletePressed);
0173     dirList->setCurrentItem(root);
0174 
0175     symbolCount->setValue(c->_maxSymbolCount);
0176     symbolLength->setValue(c->_maxSymbolLength);
0177     precisionEdit->setValue(c->_percentPrecision);
0178     contextEdit->setValue(c->_context);
0179 }
0180 
0181 ConfigDlg::~ConfigDlg()
0182 {
0183 }
0184 
0185 bool ConfigDlg::configure(GlobalGUIConfig* c, TraceData* d, QWidget* p)
0186 {
0187     ConfigDlg dlg(c, d, p);
0188 
0189     if (dlg.exec()) {
0190 
0191         // max 499 per definition
0192         c->_maxListCount = dlg.maxListEdit->value();
0193         c->_maxSymbolCount = dlg.symbolCount->value();
0194         c->_maxSymbolLength = dlg.symbolLength->value();
0195         c->_percentPrecision = dlg.precisionEdit->value();
0196         c->_context = dlg.contextEdit->value();
0197         return true;
0198     }
0199     return false;
0200 }
0201 
0202 void ConfigDlg::objectActivated(const QString & s)
0203 {
0204     //  qDebug("objectActivated: %s", s.ascii());
0205 
0206     if (s.isEmpty()) { _objectCS=nullptr; return; }
0207 
0208     QString n = ProfileContext::typeName(ProfileContext::Object) + '-' + s;
0209 
0210     ConfigColorSetting* cs = _config->_colors[n];
0211     if (!cs)
0212         cs = GlobalGUIConfig::colorSetting(n);
0213     //  else
0214     //    qDebug("found color %s", n.ascii());
0215 
0216     _objectCS = cs;
0217 
0218     objectCheck->setChecked(cs->_automatic);
0219     objectColor->setColor(cs->_color);
0220 
0221     /*
0222      qDebug("Found Color %s, automatic to %s",
0223             _objectCS->name.ascii(),
0224             _objectCS->automatic ? "true":"false");
0225     */
0226 }
0227 
0228 
0229 void ConfigDlg::objectCheckChanged(bool b)
0230 {
0231     if (_objectCS) {
0232         _objectCS->_automatic = b;
0233         /*
0234         qDebug("Set Color %s automatic to %s",
0235                _objectCS->name.ascii(),
0236                _objectCS->automatic ? "true":"false");
0237         */
0238     }
0239 }
0240 
0241 void ConfigDlg::objectColorChanged(const QColor & c)
0242 {
0243     if (_objectCS) _objectCS->_color = c;
0244 }
0245 
0246 void ConfigDlg::classActivated(const QString & s)
0247 {
0248     //  qDebug("classActivated: %s", s.ascii());
0249 
0250     if (s.isEmpty()) { _classCS=nullptr; return; }
0251 
0252     QString n = ProfileContext::typeName(ProfileContext::Class) + '-' + s;
0253 
0254     ConfigColorSetting* cs = _config->_colors[n];
0255     if (!cs)
0256         cs = GlobalGUIConfig::colorSetting(n);
0257 
0258     _classCS = cs;
0259 
0260     classCheck->setChecked(cs->_automatic);
0261     classColor->setColor(cs->_color);
0262 
0263 }
0264 
0265 
0266 void ConfigDlg::classCheckChanged(bool b)
0267 {
0268     if (_classCS) _classCS->_automatic = b;
0269 }
0270 
0271 void ConfigDlg::classColorChanged(const QColor & c)
0272 {
0273     if (_classCS) _classCS->_color = c;
0274 }
0275 
0276 
0277 void ConfigDlg::fileActivated(const QString & s)
0278 {
0279     //  qDebug("fileActivated: %s", s.ascii());
0280 
0281     if (s.isEmpty()) { _fileCS=nullptr; return; }
0282 
0283     QString n = ProfileContext::typeName(ProfileContext::File) + '-' + s;
0284 
0285     ConfigColorSetting* cs = _config->_colors[n];
0286     if (!cs)
0287         cs = GlobalGUIConfig::colorSetting(n);
0288 
0289     _fileCS = cs;
0290 
0291     fileCheck->setChecked(cs->_automatic);
0292     fileColor->setColor(cs->_color);
0293 }
0294 
0295 
0296 void ConfigDlg::fileCheckChanged(bool b)
0297 {
0298     if (_fileCS) _fileCS->_automatic = b;
0299 }
0300 
0301 void ConfigDlg::fileColorChanged(const QColor & c)
0302 {
0303     if (_fileCS) _fileCS->_color = c;
0304 }
0305 
0306 QTreeWidgetItem *ConfigDlg::getSelectedDirItem()
0307 {
0308     const QList<QTreeWidgetItem*> selectedItems = dirList->selectedItems();
0309     return selectedItems.count() ? selectedItems[0] : nullptr;
0310     }
0311 
0312     void ConfigDlg::dirsItemChanged()
0313     {
0314     QTreeWidgetItem *dirItem = getSelectedDirItem();
0315     deleteDirButton->setEnabled(dirItem && dirItem->parent() != nullptr);
0316     addDirButton->setEnabled(dirItem && dirItem->parent() == nullptr);
0317 }
0318 
0319 void ConfigDlg::dirsDeletePressed()
0320 {
0321     QTreeWidgetItem *dirItem = getSelectedDirItem();
0322     if (!dirItem || (dirItem->parent() == nullptr)) return;
0323     QTreeWidgetItem* p = dirItem->parent();
0324     if (!p) return;
0325 
0326     QString objName = p->text(0);
0327 
0328     QStringList* dirs;
0329     if (objName == i18n("(always)"))
0330         dirs = &(_config->_generalSourceDirs);
0331     else
0332         dirs = &(_config->_objectSourceDirs[objName]);
0333 
0334     dirs->removeAll(dirItem->text(0));
0335     delete dirItem;
0336 
0337     deleteDirButton->setEnabled(false);
0338 }
0339 
0340 void ConfigDlg::dirsAddPressed()
0341 {
0342     QTreeWidgetItem *dirItem = getSelectedDirItem();
0343     if (!dirItem || (dirItem->parent() != nullptr)) return;
0344 
0345     QString objName = dirItem->text(0);
0346 
0347     QStringList* dirs;
0348     if (objName == i18n("(always)"))
0349         dirs = &(_config->_generalSourceDirs);
0350     else
0351         dirs = &(_config->_objectSourceDirs[objName]);
0352 
0353     QString newDir;
0354     newDir = QFileDialog::getExistingDirectory(this,
0355                                                i18n("Choose Source Folder"));
0356     if (newDir.isEmpty()) return;
0357 
0358     // even for '/', we strip the tailing slash
0359     if (newDir.endsWith(QLatin1Char('/')))
0360         newDir = newDir.left(newDir.length()-1);
0361 
0362     if (dirs->indexOf(newDir)>=0) return;
0363 
0364     dirs->append(newDir);
0365     if (newDir.isEmpty()) newDir = QDir::rootPath();
0366     QTreeWidgetItem *item = new QTreeWidgetItem(dirItem);
0367     item->setText(0, newDir);
0368 }
0369 
0370 #include "moc_configdlg.cpp"