File indexing completed on 2024-04-28 05:41:41

0001 /*
0002     This file is part of KCachegrind.
0003 
0004     SPDX-FileCopyrightText: 2009-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only
0007 */
0008 
0009 /*
0010  * Source annotation directory settings config page
0011  */
0012 
0013 #include "sourcesettings.h"
0014 
0015 #include <QTreeWidgetItem>
0016 #include <QFileDialog>
0017 
0018 #include "tracedata.h"
0019 #include "globalconfig.h"
0020 
0021 //
0022 // SourceSettings
0023 //
0024 
0025 SourceSettings::SourceSettings(TraceData* data, QWidget* parent)
0026     : ConfigPage(parent,
0027                  QObject::tr("Source Annotation"),
0028                  QObject::tr("Directory Settings for Source Annotation"))
0029 {
0030     ui.setupUi(this);
0031 
0032     ui.dirList->setRootIsDecorated(false);
0033 
0034     GlobalConfig* c = GlobalConfig::config();
0035     _always = tr("(always)");
0036 
0037     QTreeWidgetItem* i;
0038     QStringList::const_iterator sit = c->generalSourceDirs().constBegin();
0039     for(; sit != c->generalSourceDirs().constEnd(); ++sit ) {
0040         QString d = (*sit);
0041         if (d.isEmpty()) d = QStringLiteral("/");
0042         i = new QTreeWidgetItem();
0043         i->setText(0, _always);
0044         i->setText(1, d);
0045         ui.dirList->addTopLevelItem(i);
0046     }
0047 
0048     QStringList objItems(_always);
0049     if (data) {
0050         TraceObjectMap::Iterator oit;
0051         for ( oit = data->objectMap().begin();
0052               oit != data->objectMap().end(); ++oit ) {
0053             QString n = (*oit).name();
0054             if (n.isEmpty()) continue;
0055             objItems << n;
0056 
0057             const QStringList& dirs = c->objectSourceDirs(n);
0058             sit = dirs.constBegin();
0059             for(; sit != dirs.constEnd(); ++sit ) {
0060                 QString d = (*sit);
0061                 if (d.isEmpty()) d = QStringLiteral("/");
0062                 i = new QTreeWidgetItem();
0063                 i->setText(0, n);
0064                 i->setText(1, d);
0065                 ui.dirList->addTopLevelItem(i);
0066             }
0067         }
0068     }
0069 
0070     ui.objectBox->addItems(objItems);
0071     ui.objectBox->setCurrentIndex(0);
0072 
0073     connect(ui.addDirButton, &QAbstractButton::clicked,
0074             this, &SourceSettings::addClicked);
0075     connect(ui.deleteDirButton, &QAbstractButton::clicked,
0076             this, &SourceSettings::deleteClicked);
0077     connect(ui.browseDirButton, &QAbstractButton::clicked,
0078             this, &SourceSettings::browseClicked);
0079     connect(ui.dirList,
0080             &QTreeWidget::currentItemChanged,
0081             this,
0082             &SourceSettings::dirListItemChanged);
0083     connect(ui.objectBox,
0084             SIGNAL(currentIndexChanged(QString)),
0085             this, SLOT(objectChanged(QString)));
0086     connect(ui.dirEdit, SIGNAL(textChanged(QString)),
0087             this, SLOT(dirEditChanged(QString)));
0088 
0089     _current = nullptr;
0090     update();
0091 }
0092 
0093 void SourceSettings::activate(QString s)
0094 {
0095     int idx = s.toInt();
0096     if ((idx==0) || (idx>ui.dirList->topLevelItemCount())) return;
0097 
0098     ui.dirList->setCurrentItem(ui.dirList->topLevelItem(idx-1));
0099     ui.dirEdit->setFocus();
0100 }
0101 
0102 void SourceSettings::update()
0103 {
0104     if (!_current) {
0105         ui.deleteDirButton->setEnabled(false);
0106         ui.objectBox->setEnabled(false);
0107         ui.dirEdit->setEnabled(false);
0108         ui.browseDirButton->setEnabled(false);
0109         return;
0110     }
0111     ui.deleteDirButton->setEnabled(true);
0112     ui.objectBox->setEnabled(true);
0113     ui.objectBox->setCurrentIndex(ui.objectBox->findText(_current->text(0)));
0114     ui.dirEdit->setEnabled(true);
0115     ui.dirEdit->setText(_current->text(1));
0116     ui.browseDirButton->setEnabled(true);
0117 }
0118 
0119 void SourceSettings::addClicked()
0120 {
0121     int prevItemCount = ui.dirList->topLevelItemCount();
0122     QTreeWidgetItem* i = new QTreeWidgetItem();
0123     i->setText(0, ui.objectBox->currentText());
0124     i->setText(1, tr("<insert valid directory>"));
0125     ui.dirList->addTopLevelItem(i);
0126     ui.dirList->setCurrentItem(i);
0127     if (prevItemCount == 0 && ui.objectBox->currentText() == _always) {
0128         // it's not obvious that you have to click browse after adding an item,
0129         // but handle the case where we have no items and are looking for the
0130         // default. give users an oppurtunity to select for multiple ELF objects
0131         browseClicked();
0132     }
0133 }
0134 
0135 void SourceSettings::deleteClicked()
0136 {
0137     if (!_current) return;
0138 
0139     QTreeWidgetItem* i = _current;
0140     // the deletion removes the item
0141     delete _current;
0142     // deletion can trigger a call to dirListItemChanged() !
0143     if (_current == i) {
0144         _current = nullptr;
0145         update();
0146     }
0147 }
0148 
0149 void SourceSettings::browseClicked()
0150 {
0151     QString d;
0152     d = QFileDialog::getExistingDirectory(this,
0153                                           tr("Choose Source Directory"),
0154                                           ui.dirEdit->text());
0155     if (!d.isEmpty())
0156         ui.dirEdit->setText(d);
0157 }
0158 
0159 void SourceSettings::dirListItemChanged(QTreeWidgetItem* current,
0160                                         QTreeWidgetItem*)
0161 {
0162     _current = current;
0163     update();
0164 }
0165 
0166 void SourceSettings::objectChanged(QString obj)
0167 {
0168     if (!_current) return;
0169 
0170     _current->setText(0, obj);
0171 }
0172 
0173 void SourceSettings::dirEditChanged(QString dir)
0174 {
0175     if (!_current) return;
0176 
0177     _current->setText(1, dir);
0178 }
0179 
0180 bool SourceSettings::check(QString& errorMsg, QString& errorItem)
0181 {
0182     for(int idx=0; idx< ui.dirList->topLevelItemCount(); idx++) {
0183         QTreeWidgetItem* item = ui.dirList->topLevelItem(idx);
0184         QString dir = item->text(1);
0185         if (QDir(dir).exists()) continue;
0186         errorMsg = tr("Directory does not exist");
0187         errorItem = QStringLiteral("%1").arg(idx+1);
0188         return false;
0189     }
0190     return true;
0191 }
0192 
0193 void SourceSettings::accept()
0194 {
0195     GlobalConfig* c = GlobalConfig::config();
0196 
0197     QHash<QString, QStringList> dirs;
0198     for(int idx=0; idx< ui.dirList->topLevelItemCount(); idx++) {
0199         QTreeWidgetItem* item = ui.dirList->topLevelItem(idx);
0200         dirs[item->text(0)] << item->text(1);
0201     }
0202 
0203     c->setGeneralSourceDirs(QStringList());
0204     c->clearObjectSourceDirs();
0205 
0206     QHash<QString, QStringList>::const_iterator oit = dirs.constBegin();
0207     for(;oit != dirs.constEnd(); ++oit) {
0208         if (oit.key() == _always)
0209             c->setGeneralSourceDirs(oit.value());
0210         else
0211             c->setObjectSourceDirs(oit.key(), oit.value());
0212     }
0213 }
0214 
0215 #include "moc_sourcesettings.cpp"