File indexing completed on 2024-04-14 05:36:48

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "projectdlgs.h"
0012 #include "microlibrary.h"
0013 #include "microselectwidget.h"
0014 #include "projectmanager.h"
0015 
0016 #include <cassert>
0017 
0018 #include <KLocalizedString>
0019 #include <KUrlRequester>
0020 // #include <k3listview.h>
0021 
0022 #include <QCheckBox>
0023 #include <QComboBox>
0024 #include <QDialogButtonBox>
0025 #include <QLabel>
0026 #include <QPushButton>
0027 #include <QVBoxLayout>
0028 
0029 #include <ui_createsubprojectwidget.h>
0030 #include <ui_linkeroptionswidget.h>
0031 #include <ui_newprojectwidget.h>
0032 #include <ui_processingoptionswidget.h>
0033 #include <ktechlab_debug.h>
0034 
0035 class NewProjectWidget : public QWidget, public Ui::NewProjectWidget
0036 {
0037 public:
0038     NewProjectWidget(QWidget *parent)
0039         : QWidget(parent)
0040     {
0041         setupUi(this);
0042     }
0043 };
0044 
0045 // BEGIN class NewProjectDlg
0046 NewProjectDlg::NewProjectDlg(QWidget *parent)
0047     : QDialog(parent)
0048 {
0049     setObjectName("newprojectdlg");
0050     setModal(true);
0051     setWindowTitle(i18n("New Project"));
0052 
0053     QVBoxLayout *mainLayout = new QVBoxLayout;
0054     setLayout(mainLayout);
0055 
0056     m_pWidget = new NewProjectWidget(this);
0057     connect(m_pWidget->projectNameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(locationChanged(const QString &)));
0058     connect(m_pWidget->projectLocationURL, SIGNAL(textChanged(const QString &)), this, SLOT(locationChanged(const QString &)));
0059 
0060     mainLayout->addWidget(m_pWidget);
0061 
0062     m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0063     mainLayout->addWidget(m_buttonBox);
0064 
0065     QPushButton *okButton = m_buttonBox->button(QDialogButtonBox::Ok);
0066     okButton->setDefault(true);
0067     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0068     connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0069     connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0070 
0071     // Check if already valid dir
0072     locationChanged(QString());
0073 
0074     m_pWidget->projectLocationURL->setUrl(QUrl::fromLocalFile(QDir::homePath()));
0075     m_pWidget->projectLocationURL->setMode(KFile::Directory);
0076 }
0077 
0078 void NewProjectDlg::accept()
0079 {
0080     m_projectName = m_pWidget->projectNameEdit->text();
0081     m_projectLocation = m_pWidget->projectLocationURL->url().toLocalFile();
0082 
0083     QDialog::accept();
0084 }
0085 
0086 void NewProjectDlg::locationChanged(const QString &)
0087 {
0088     m_location = m_pWidget->projectLocationURL->url().toLocalFile();
0089     qCDebug(KTL_LOG) << "location changed to: " << m_location;
0090     QDir subDir(m_location);
0091 
0092     if (!m_location.endsWith("/"))
0093         m_location.append("/");
0094 
0095     if (!m_pWidget->projectNameEdit->text().isEmpty())
0096         m_location.append(m_pWidget->projectNameEdit->text().toLower() + "/");
0097 
0098     m_pWidget->locationLabel->setText(m_location);
0099 
0100     QDir dir(m_location);
0101 
0102     qCDebug(KTL_LOG) << "dir.exists: " << dir.exists() << " subdir.exists: " << subDir.exists();
0103 
0104     QPushButton *okButton = m_buttonBox->button(QDialogButtonBox::Ok);
0105     if (dir.exists() || !subDir.exists()) {
0106         okButton->setEnabled(false);
0107     } else {
0108         okButton->setEnabled(true);
0109     }
0110 }
0111 // END class NewProjectDlg
0112 
0113 class CreateSubprojectWidget : public QWidget, public Ui::CreateSubprojectWidget
0114 {
0115 public:
0116     CreateSubprojectWidget(QWidget *parent)
0117         : QWidget(parent)
0118     {
0119         setupUi(this);
0120     }
0121 };
0122 
0123 // BEGIN class CreateSubprojectDlg
0124 CreateSubprojectDlg::CreateSubprojectDlg(QWidget *parent)
0125     : QDialog(parent)
0126 {
0127     setObjectName("Create Subproject Dialog");
0128     setModal(true);
0129     setWindowTitle(i18n("Create Subproject"));
0130 
0131     QVBoxLayout *mainLayout = new QVBoxLayout;
0132     setLayout(mainLayout);
0133 
0134     m_pWidget = new CreateSubprojectWidget(this);
0135 
0136     if (ProjectManager::self()->currentProject())
0137         m_pWidget->m_targetFile->setUrl(ProjectManager::self()->currentProject()->url());
0138 
0139     m_type = ProgramType;
0140 
0141     mainLayout->addWidget(m_pWidget);
0142 
0143     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0144     mainLayout->addWidget(buttonBox);
0145 
0146     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0147     okButton->setDefault(true);
0148     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0149     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0150     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0151 }
0152 
0153 CreateSubprojectDlg::~CreateSubprojectDlg()
0154 {
0155 }
0156 
0157 void CreateSubprojectDlg::accept()
0158 {
0159     m_targetFile = m_pWidget->m_targetFile->url().toLocalFile();
0160     m_type = static_cast<Type>(m_pWidget->m_typeCombo->currentIndex());
0161 
0162     QDialog::accept();
0163 }
0164 // END class CreateSubprojectDlg
0165 
0166 class LinkerOptionsWidget : public QWidget, public Ui::LinkerOptionsWidget
0167 {
0168 public:
0169     LinkerOptionsWidget(QWidget *parent)
0170         : QWidget(parent)
0171     {
0172         setupUi(this);
0173     }
0174 };
0175 
0176 // BEGIN class LinkerOptionsDlg
0177 LinkerOptionsDlg::LinkerOptionsDlg(LinkerOptions *linkingOptions, QWidget *parent)
0178     : QDialog(parent)
0179 {
0180     setObjectName("Linker Options Dialog");
0181     setModal(true);
0182     setWindowTitle(i18n("Linker Options"));
0183 
0184     QVBoxLayout *mainLayout = new QVBoxLayout;
0185     setLayout(mainLayout);
0186 
0187     m_pLinkerOptions = linkingOptions;
0188     m_pWidget = new LinkerOptionsWidget(this);
0189 
0190     ProjectInfo *pi = ProjectManager::self()->currentProject();
0191     assert(pi);
0192 
0193     // BEGIN Update gplink options
0194     m_pWidget->m_pHexFormat->setCurrentIndex(m_pLinkerOptions->hexFormat());
0195     m_pWidget->m_pOutputMap->setChecked(m_pLinkerOptions->outputMapFile());
0196     m_pWidget->m_pLibraryDir->setText(m_pLinkerOptions->libraryDir());
0197     m_pWidget->m_pLinkerScript->setText(m_pLinkerOptions->linkerScript());
0198     m_pWidget->m_pOther->setText(m_pLinkerOptions->linkerOther());
0199     // END Update gplink options
0200 
0201     // BEGIN Update library widgets
0202     const QList<QUrl> availableInternal = pi->childOutputURLs(ProjectItem::LibraryType);
0203     const QStringList linkedInternal = m_pLinkerOptions->linkedInternal();
0204     const QUrl projectUrl = pi->url();
0205     const QDir projectDir(projectUrl.path()); // using QDir for relativeFilePath logic, not assuming local file
0206     for (const QUrl &internalUrl : availableInternal) {
0207         QString relativeURL;
0208         if (projectUrl.scheme() == internalUrl.scheme() && projectUrl.host() == internalUrl.host() && projectUrl.port() == internalUrl.port() && projectUrl.userInfo() == internalUrl.userInfo()) {
0209             relativeURL = projectDir.relativeFilePath(internalUrl.path());
0210         } else {
0211             relativeURL = internalUrl.toDisplayString(QUrl::PreferLocalFile);
0212         }
0213         // 2017.12.1 - convert to QListWidgetItem
0214         // Q3CheckListItem * item = new Q3CheckListItem( m_pWidget->m_pInternalLibraries, relativeURL, Q3CheckListItem::CheckBox );
0215         QListWidgetItem *item = new QListWidgetItem(relativeURL, m_pWidget->m_pInternalLibraries);
0216         item->setCheckState((linkedInternal.contains(relativeURL)) ? Qt::Checked : Qt::Unchecked);
0217         // item->setOn( linkedInternal.contains(relativeURL) ); // 2017.12.1 - convert to QListWidgetItem
0218     }
0219 
0220     m_pExternalLibraryRequester = new KUrlRequester(nullptr);
0221     m_pExternalLibraryRequester->setStartDir(QUrl::fromLocalFile("/usr/share/sdcc/lib"));
0222 
0223     // //   m_pWidget->m_pExternalLibraries = new KEditListBox(
0224     // //         i18n("Link libraries outside project"),
0225     // //         //m_pExternalLibraryRequester->customEditor(),
0226     // //         KEditListBox::CustomEditor(
0227     // //             m_pExternalLibraryRequester->comboBox(), m_pExternalLibraryRequester->lineEdit()),
0228     // //         m_pWidget );
0229     // //     m_pWidget->m_pExternalLibraries->setTitle(i18n("Link libraries outside project"));
0230     //  //m_pExternalLibraryRequester->fileDialog()->setUrl( KUrl( "/usr/share/sdcc/lib" ) );
0231     //     m_pExternalLibraryRequester->fileDialog()->setDirectoryUrl( KUrl( "/usr/share/sdcc/lib" ) );
0232     //
0233     //  delete m_pWidget->m_pExternalLibraries;
0234     //     KEditListBox b;
0235     //
0236     //  m_pWidget->m_pExternalLibraries = new KEditListBox(
0237     //         i18n("Link libraries outside project"),
0238     //         //m_pExternalLibraryRequester->customEditor(),
0239     //         KEditListBox::CustomEditor(
0240     //             m_pExternalLibraryRequester->comboBox(), m_pExternalLibraryRequester->lineEdit()),
0241     //         m_pWidget );
0242     //     m_pWidget->m_pExternalLibraries->setTitle(i18n("Link libraries outside project"));
0243     //  m_pExternalLibraryRequester->fileDialog()->selectUrl( KUrl( "/usr/share/sdcc/lib" ) );
0244     //
0245     delete m_pWidget->m_pExternalLibraries;
0246     m_pWidget->m_pExternalLibraries = new KEditListWidget(
0247         // i18n("Link libraries outside project"),
0248         m_pExternalLibraryRequester->customEditor(),
0249         m_pWidget);
0250     m_pWidget->m_pExternalLibraries->layout()->setMargin(11);
0251     {
0252         QGridLayout *grLayout = (dynamic_cast<QGridLayout *>(m_pWidget->layout()));
0253         // grLayout->addMultiCellWidget( m_pWidget->m_pExternalLibraries, 7, 7, 0, 1 ); // 2018.12.02
0254         grLayout->addWidget(m_pWidget->m_pExternalLibraries, 7, 0, 1, 2);
0255     }
0256 
0257     m_pWidget->m_pExternalLibraries->setButtons(KEditListWidget::Add | KEditListWidget::Remove);
0258     m_pWidget->m_pExternalLibraries->insertStringList(m_pLinkerOptions->linkedExternal());
0259     // END Update library widgets
0260 
0261     mainLayout->addWidget(m_pWidget);
0262 
0263     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0264     mainLayout->addWidget(buttonBox);
0265 
0266     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0267     okButton->setDefault(true);
0268     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0269     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0270     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0271 }
0272 
0273 LinkerOptionsDlg::~LinkerOptionsDlg()
0274 {
0275     delete m_pExternalLibraryRequester;
0276 }
0277 
0278 void LinkerOptionsDlg::accept()
0279 {
0280     QStringList linkedInternal;
0281     for (int itemNr = 0; itemNr < m_pWidget->m_pInternalLibraries->count(); ++itemNr) {
0282         QListWidgetItem *item = m_pWidget->m_pInternalLibraries->item(itemNr);
0283         if (item->checkState() == Qt::Checked) {
0284             linkedInternal << item->text();
0285         }
0286     }
0287     m_pLinkerOptions->setLinkedInternal(linkedInternal);
0288 
0289     m_pLinkerOptions->setLinkedExternal(m_pWidget->m_pExternalLibraries->items());
0290     m_pLinkerOptions->setHexFormat(static_cast<LinkerOptions::HexFormat::type>(m_pWidget->m_pHexFormat->currentIndex()));
0291     m_pLinkerOptions->setOutputMapFile(m_pWidget->m_pOutputMap->isChecked());
0292     m_pLinkerOptions->setLibraryDir(m_pWidget->m_pLibraryDir->text());
0293     m_pLinkerOptions->setLinkerScript(m_pWidget->m_pLinkerScript->text());
0294     m_pLinkerOptions->setLinkerOther(m_pWidget->m_pOther->text());
0295 
0296     QDialog::accept();
0297 }
0298 
0299 // END class LinkerOptionsDlg
0300 
0301 class ProcessingOptionsWidget : public QWidget, public Ui::ProcessingOptionsWidget
0302 {
0303 public:
0304     ProcessingOptionsWidget(QWidget *parent)
0305         : QWidget(parent)
0306     {
0307         setupUi(this);
0308     }
0309 };
0310 
0311 // BEGIN class ProcessingOptionsDlg
0312 ProcessingOptionsDlg::ProcessingOptionsDlg(ProjectItem *projectItem, QWidget *parent)
0313     : QDialog(parent)
0314 {
0315     setObjectName("Processing Options Dialog");
0316     setModal(true);
0317     setWindowTitle(i18n("Processing Options"));
0318 
0319     QVBoxLayout *mainLayout = new QVBoxLayout;
0320     setLayout(mainLayout);
0321 
0322     m_pProjectItem = projectItem;
0323     m_pWidget = new ProcessingOptionsWidget(this);
0324 
0325     m_pWidget->m_pMicroSelect->setEnabled(!projectItem->useParentMicroID());
0326 
0327     switch (projectItem->type()) {
0328     case ProjectItem::ProjectType:
0329         m_pWidget->m_pOutputURL->setEnabled(false);
0330         break;
0331 
0332     case ProjectItem::FileType:
0333         m_pWidget->m_pOutputURL->setEnabled(true);
0334         break;
0335 
0336     case ProjectItem::ProgramType:
0337     case ProjectItem::LibraryType:
0338         m_pWidget->m_pOutputURL->setEnabled(false);
0339         break;
0340     }
0341 
0342     m_pWidget->m_pOutputURL->setUrl(projectItem->outputURL());
0343     m_pWidget->m_pMicroSelect->setMicro(projectItem->microID());
0344 
0345     mainLayout->addWidget(m_pWidget);
0346 
0347     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0348     mainLayout->addWidget(buttonBox);
0349 
0350     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0351     okButton->setDefault(true);
0352     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0353     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0354     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0355 }
0356 
0357 ProcessingOptionsDlg::~ProcessingOptionsDlg()
0358 {
0359 }
0360 
0361 void ProcessingOptionsDlg::accept()
0362 {
0363     if (m_pWidget->m_pOutputURL->isEnabled())
0364         m_pProjectItem->setOutputURL(m_pWidget->m_pOutputURL->url());
0365 
0366     if (m_pWidget->m_pMicroSelect->isEnabled())
0367         m_pProjectItem->setMicroID(m_pWidget->m_pMicroSelect->micro());
0368 
0369     QDialog::accept();
0370 }
0371 
0372 // END class ProcessingOptionsDlg
0373 
0374 #include "moc_projectdlgs.cpp"