| 1 | /* |
| 2 | * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) |
| 3 | * |
| 4 | * This program is free software: you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation, either version 3 of the License, or |
| 7 | * (at your option) any later version. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | #include "compilersetoptionwidget.h" |
| 18 | #include "ui_compilersetoptionwidget.h" |
| 19 | #include "../settings.h" |
| 20 | #include "../mainwindow.h" |
| 21 | #include "compilersetdirectorieswidget.h" |
| 22 | #include <QMessageBox> |
| 23 | #include "../utils.h" |
| 24 | #include "../iconsmanager.h" |
| 25 | #include <qt_utils/charsetinfo.h> |
| 26 | #include <QDebug> |
| 27 | #include <QFileDialog> |
| 28 | #include <QInputDialog> |
| 29 | |
| 30 | CompilerSetOptionWidget::CompilerSetOptionWidget(const QString& name, const QString& group, QWidget* parent) : |
| 31 | SettingsWidget(name,group,parent), |
| 32 | ui(new Ui::CompilerSetOptionWidget) |
| 33 | { |
| 34 | ui->setupUi(this); |
| 35 | |
| 36 | mBinDirWidget = new CompilerSetDirectoriesWidget(); |
| 37 | ui->dirTabs->addTab(mBinDirWidget,QObject::tr("Binaries" )); |
| 38 | mLibDirWidget = new CompilerSetDirectoriesWidget(); |
| 39 | ui->dirTabs->addTab(mLibDirWidget,QObject::tr("Libraries" )); |
| 40 | mCIncludeDirWidget = new CompilerSetDirectoriesWidget(); |
| 41 | ui->dirTabs->addTab(mCIncludeDirWidget,QObject::tr("C Includes" )); |
| 42 | mCppIncludeDirWidget = new CompilerSetDirectoriesWidget(); |
| 43 | ui->dirTabs->addTab(mCppIncludeDirWidget,QObject::tr("C++ Includes" )); |
| 44 | |
| 45 | connect(ui->chkUseCustomCompilerParams, &QCheckBox::stateChanged, |
| 46 | ui->txtCustomCompileParams, &QPlainTextEdit::setEnabled); |
| 47 | connect(ui->chkUseCustomLinkParams, &QCheckBox::stateChanged, |
| 48 | ui->txtCustomLinkParams, &QPlainTextEdit::setEnabled); |
| 49 | |
| 50 | connect(pIconsManager, &IconsManager::actionIconsUpdated, |
| 51 | this, &CompilerSetOptionWidget::updateIcons); |
| 52 | updateIcons(); |
| 53 | } |
| 54 | |
| 55 | CompilerSetOptionWidget::~CompilerSetOptionWidget() |
| 56 | { |
| 57 | delete ui; |
| 58 | } |
| 59 | |
| 60 | void CompilerSetOptionWidget::init() |
| 61 | { |
| 62 | ui->cbEncodingDetails->setVisible(false); |
| 63 | ui->cbEncoding->clear(); |
| 64 | ui->cbEncoding->addItem(tr("ANSI" ),ENCODING_SYSTEM_DEFAULT); |
| 65 | ui->cbEncoding->addItem(tr("UTF-8" ),ENCODING_UTF8); |
| 66 | foreach (const QString& langName, pCharsetInfoManager->languageNames()) { |
| 67 | ui->cbEncoding->addItem(langName,langName); |
| 68 | } |
| 69 | SettingsWidget::init(); |
| 70 | } |
| 71 | |
| 72 | |
| 73 | static void loadCompilerSetSettings(Settings::PCompilerSet pSet, Ui::CompilerSetOptionWidget* ui) { |
| 74 | ui->chkAutoAddCharset->setEnabled(pSet->compilerType() != COMPILER_CLANG); |
| 75 | ui->chkAutoAddCharset->setVisible(pSet->compilerType() != COMPILER_CLANG); |
| 76 | ui->cbEncoding->setEnabled(pSet->compilerType() != COMPILER_CLANG); |
| 77 | ui->cbEncoding->setVisible(pSet->compilerType() != COMPILER_CLANG); |
| 78 | ui->cbEncodingDetails->setEnabled(pSet->compilerType() != COMPILER_CLANG); |
| 79 | ui->cbEncodingDetails->setVisible(pSet->compilerType() != COMPILER_CLANG); |
| 80 | |
| 81 | ui->chkUseCustomCompilerParams->setChecked(pSet->useCustomCompileParams()); |
| 82 | ui->txtCustomCompileParams->setPlainText(pSet->customCompileParams()); |
| 83 | ui->txtCustomCompileParams->setEnabled(pSet->useCustomCompileParams()); |
| 84 | ui->chkUseCustomLinkParams->setChecked(pSet->useCustomLinkParams()); |
| 85 | ui->txtCustomLinkParams->setPlainText(pSet->customLinkParams()); |
| 86 | ui->txtCustomLinkParams->setEnabled(pSet->useCustomLinkParams()); |
| 87 | ui->chkAutoAddCharset->setChecked(pSet->autoAddCharsetParams()); |
| 88 | ui->chkStaticLink->setChecked(pSet->staticLink()); |
| 89 | //rest tabs in the options widget |
| 90 | |
| 91 | ui->optionTabs->resetUI(pSet,pSet->compileOptions()); |
| 92 | |
| 93 | ui->txtCCompiler->setText(pSet->CCompiler()); |
| 94 | ui->txtCppCompiler->setText(pSet->cppCompiler()); |
| 95 | ui->txtMake->setText(pSet->make()); |
| 96 | ui->txtDebugger->setText(pSet->debugger()); |
| 97 | ui->txtGDBServer->setText(pSet->debugServer()); |
| 98 | ui->txtResourceCompiler->setText(pSet->resourceCompiler()); |
| 99 | ui->txtProfiler->setText(pSet->profiler()); |
| 100 | |
| 101 | if (pSet->execCharset() == ENCODING_AUTO_DETECT |
| 102 | || pSet->execCharset() == ENCODING_SYSTEM_DEFAULT |
| 103 | || pSet->execCharset() == ENCODING_UTF8) { |
| 104 | int index =ui->cbEncoding->findData(pSet->execCharset()); |
| 105 | ui->cbEncoding->setCurrentIndex(index); |
| 106 | ui->cbEncodingDetails->clear(); |
| 107 | ui->cbEncodingDetails->setVisible(false); |
| 108 | } else { |
| 109 | QString encoding = pSet->execCharset(); |
| 110 | QString language = pCharsetInfoManager->findLanguageByCharsetName(encoding); |
| 111 | ui->cbEncoding->setCurrentText(language); |
| 112 | ui->cbEncodingDetails->setVisible(true); |
| 113 | ui->cbEncodingDetails->clear(); |
| 114 | QList<PCharsetInfo> infos = pCharsetInfoManager->findCharsetsByLanguageName(language); |
| 115 | foreach (const PCharsetInfo& info, infos) { |
| 116 | ui->cbEncodingDetails->addItem(info->name); |
| 117 | } |
| 118 | ui->cbEncodingDetails->setCurrentText(encoding); |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | void CompilerSetOptionWidget::doLoad() |
| 123 | { |
| 124 | disconnectInputs(); |
| 125 | ui->cbCompilerSet->clear(); |
| 126 | if (pSettings->compilerSets().size()<=0) { |
| 127 | ui->btnRenameCompilerSet->setEnabled(false); |
| 128 | ui->btnRemoveCompilerSet->setEnabled(false); |
| 129 | return; |
| 130 | } else { |
| 131 | ui->btnRenameCompilerSet->setEnabled(true); |
| 132 | ui->btnRemoveCompilerSet->setEnabled(true); |
| 133 | } |
| 134 | int index=pSettings->compilerSets().defaultIndex(); |
| 135 | for (size_t i=0;i<pSettings->compilerSets().size();i++) { |
| 136 | ui->cbCompilerSet->addItem(pSettings->compilerSets().getSet(i)->name()); |
| 137 | } |
| 138 | if (index < 0 || index>=ui->cbCompilerSet->count()) { |
| 139 | index = 0; |
| 140 | } |
| 141 | ui->cbCompilerSet->setCurrentIndex(index); |
| 142 | reloadCurrentCompilerSet(); |
| 143 | connectInputs(); |
| 144 | } |
| 145 | |
| 146 | void CompilerSetOptionWidget::doSave() |
| 147 | { |
| 148 | if (pSettings->compilerSets().size()>0) { |
| 149 | saveCurrentCompilerSet(); |
| 150 | } |
| 151 | pSettings->compilerSets().saveSets(); |
| 152 | pMainWindow->updateCompilerSet(); |
| 153 | } |
| 154 | |
| 155 | void CompilerSetOptionWidget::on_cbCompilerSet_currentIndexChanged(int index) |
| 156 | { |
| 157 | if (index<0) |
| 158 | return; |
| 159 | setSettingsChanged(); |
| 160 | pSettings->compilerSets().setDefaultIndex(index); |
| 161 | disconnectInputs(); |
| 162 | reloadCurrentCompilerSet(); |
| 163 | connectInputs(); |
| 164 | } |
| 165 | |
| 166 | void CompilerSetOptionWidget::reloadCurrentCompilerSet() |
| 167 | { |
| 168 | Settings::PCompilerSet pSet = pSettings->compilerSets().defaultSet(); |
| 169 | loadCompilerSetSettings(pSet, ui); |
| 170 | |
| 171 | mBinDirWidget->setDirList(pSet->binDirs()); |
| 172 | mLibDirWidget->setDirList(pSet->libDirs()); |
| 173 | mCIncludeDirWidget->setDirList(pSet->CIncludeDirs()); |
| 174 | mCppIncludeDirWidget->setDirList(pSet->CppIncludeDirs()); |
| 175 | } |
| 176 | |
| 177 | void CompilerSetOptionWidget::saveCurrentCompilerSet() |
| 178 | { |
| 179 | Settings::PCompilerSet pSet = pSettings->compilerSets().defaultSet(); |
| 180 | |
| 181 | pSet->setUseCustomCompileParams(ui->chkUseCustomCompilerParams->isChecked()); |
| 182 | pSet->setCustomCompileParams(ui->txtCustomCompileParams->toPlainText().trimmed()); |
| 183 | pSet->setUseCustomLinkParams(ui->chkUseCustomLinkParams->isChecked()); |
| 184 | pSet->setCustomLinkParams(ui->txtCustomLinkParams->toPlainText().trimmed()); |
| 185 | pSet->setAutoAddCharsetParams(ui->chkAutoAddCharset->isChecked()); |
| 186 | pSet->setStaticLink(ui->chkStaticLink->isChecked()); |
| 187 | |
| 188 | pSet->setCCompiler(ui->txtCCompiler->text().trimmed()); |
| 189 | pSet->setCppCompiler(ui->txtCppCompiler->text().trimmed()); |
| 190 | pSet->setMake(ui->txtMake->text().trimmed()); |
| 191 | pSet->setDebugger(ui->txtDebugger->text().trimmed()); |
| 192 | pSet->setDebugServer(ui->txtGDBServer->text().trimmed()); |
| 193 | pSet->setResourceCompiler(ui->txtResourceCompiler->text().trimmed()); |
| 194 | pSet->setProfiler(ui->txtProfiler->text().trimmed()); |
| 195 | |
| 196 | pSet->binDirs()=mBinDirWidget->dirList(); |
| 197 | |
| 198 | pSet->libDirs()=mLibDirWidget->dirList(); |
| 199 | pSet->CIncludeDirs()=mCIncludeDirWidget->dirList(); |
| 200 | pSet->CppIncludeDirs()=mCppIncludeDirWidget->dirList(); |
| 201 | |
| 202 | if (ui->cbEncodingDetails->isVisible()) { |
| 203 | pSet->setExecCharset(ui->cbEncodingDetails->currentText()); |
| 204 | } else { |
| 205 | pSet->setExecCharset(ui->cbEncoding->currentData().toString()); |
| 206 | } |
| 207 | |
| 208 | //read values in the options widget |
| 209 | pSet->setCompileOptions(ui->optionTabs->arguments(false)); |
| 210 | |
| 211 | } |
| 212 | |
| 213 | void CompilerSetOptionWidget::on_btnFindCompilers_pressed() |
| 214 | { |
| 215 | #ifdef Q_OS_WIN |
| 216 | QString msg = tr("Red Panda C++ will clear current compiler list and search" |
| 217 | " for compilers in the following locations:<br /> '%1'<br /> '%2'<br />Are you really want to continue?" ) |
| 218 | .arg(includeTrailingPathDelimiter(pSettings->dirs().appDir()) + "MinGW32" ) |
| 219 | .arg(includeTrailingPathDelimiter(pSettings->dirs().appDir()) + "MinGW64" ); |
| 220 | #else |
| 221 | QString msg = tr("Red Panda C++ will clear current compiler list and search" |
| 222 | " for compilers in the the PATH. <br />Are you really want to continue?" ); |
| 223 | #endif |
| 224 | if (QMessageBox::warning(this,tr("Confirm" ),msg, |
| 225 | QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok ) |
| 226 | return; |
| 227 | pSettings->compilerSets().clearSets(); |
| 228 | pSettings->compilerSets().findSets(); |
| 229 | doLoad(); |
| 230 | setSettingsChanged(); |
| 231 | if (pSettings->compilerSets().size()==0) { |
| 232 | QMessageBox::warning(this,tr("Failed" ),tr("Can't find any compiler." )); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | void CompilerSetOptionWidget::on_btnAddBlankCompilerSet_pressed() |
| 237 | { |
| 238 | QString name = QInputDialog::getText(this,tr("Compiler Set Name" ),tr("Name" )); |
| 239 | pSettings->compilerSets().addSet(); |
| 240 | pSettings->compilerSets().setDefaultIndex(pSettings->compilerSets().size()-1); |
| 241 | pSettings->compilerSets().defaultSet()->setName(name); |
| 242 | doLoad(); |
| 243 | } |
| 244 | |
| 245 | void CompilerSetOptionWidget::on_btnAddCompilerSetByFolder_pressed() |
| 246 | { |
| 247 | QString folder = QFileDialog::getExistingDirectory(this, tr("Compiler Set Folder" )); |
| 248 | int oldSize = pSettings->compilerSets().size(); |
| 249 | |
| 250 | if (!pSettings->compilerSets().addSets(folder)) { |
| 251 | pSettings->compilerSets().addSets(folder+QDir::separator()+"bin" ); |
| 252 | } |
| 253 | doLoad(); |
| 254 | int newSize = pSettings->compilerSets().size(); |
| 255 | if (oldSize == newSize) { |
| 256 | QMessageBox::warning(this,tr("Failed" ),tr("Can't find any compiler." )); |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | void CompilerSetOptionWidget::on_btnRenameCompilerSet_pressed() |
| 261 | { |
| 262 | QString name = QInputDialog::getText(this,tr("Compiler Set Name" ),tr("New name" ),QLineEdit::Normal, |
| 263 | pSettings->compilerSets().defaultSet()->name()); |
| 264 | if (!name.isEmpty()) |
| 265 | pSettings->compilerSets().defaultSet()->setName(name); |
| 266 | doLoad(); |
| 267 | } |
| 268 | |
| 269 | void CompilerSetOptionWidget::on_btnRemoveCompilerSet_pressed() |
| 270 | { |
| 271 | pSettings->compilerSets().deleteSet(ui->cbCompilerSet->currentIndex()); |
| 272 | doLoad(); |
| 273 | } |
| 274 | |
| 275 | void CompilerSetOptionWidget::updateIcons() |
| 276 | { |
| 277 | pIconsManager->setIcon(ui->btnFindCompilers, IconsManager::ACTION_EDIT_SEARCH); |
| 278 | pIconsManager->setIcon(ui->btnAddCompilerSetByFolder, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 279 | pIconsManager->setIcon(ui->btnAddBlankCompilerSet, IconsManager::ACTION_MISC_ADD); |
| 280 | pIconsManager->setIcon(ui->btnRemoveCompilerSet, IconsManager::ACTION_MISC_REMOVE); |
| 281 | pIconsManager->setIcon(ui->btnRenameCompilerSet, IconsManager::ACTION_MISC_RENAME); |
| 282 | |
| 283 | pIconsManager->setIcon(ui->btnChooseCCompiler, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 284 | pIconsManager->setIcon(ui->btnChooseCppCompiler, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 285 | pIconsManager->setIcon(ui->btnChooseGDB, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 286 | pIconsManager->setIcon(ui->btnChooseGDBServer, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 287 | pIconsManager->setIcon(ui->btnChooseMake, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 288 | pIconsManager->setIcon(ui->btnChooseProfiler, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 289 | pIconsManager->setIcon(ui->btnChooseResourceCompiler, IconsManager::ACTION_FILE_OPEN_FOLDER); |
| 290 | } |
| 291 | |
| 292 | void CompilerSetOptionWidget::on_cbEncoding_currentTextChanged(const QString &/*arg1*/) |
| 293 | { |
| 294 | QString userData = ui->cbEncoding->currentData().toString(); |
| 295 | if (userData == ENCODING_AUTO_DETECT |
| 296 | || userData == ENCODING_SYSTEM_DEFAULT |
| 297 | || userData == ENCODING_UTF8) { |
| 298 | ui->cbEncodingDetails->setVisible(false); |
| 299 | ui->cbEncodingDetails->clear(); |
| 300 | } else { |
| 301 | ui->cbEncodingDetails->setVisible(true); |
| 302 | ui->cbEncodingDetails->clear(); |
| 303 | QList<PCharsetInfo> infos = pCharsetInfoManager->findCharsetsByLanguageName(userData); |
| 304 | foreach (const PCharsetInfo& info, infos) { |
| 305 | ui->cbEncodingDetails->addItem(info->name); |
| 306 | } |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | |
| 311 | void CompilerSetOptionWidget::on_cbEncodingDetails_currentTextChanged(const QString &/*arg1*/) |
| 312 | { |
| 313 | |
| 314 | } |
| 315 | |
| 316 | |