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
30CompilerSetOptionWidget::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
55CompilerSetOptionWidget::~CompilerSetOptionWidget()
56{
57 delete ui;
58}
59
60void 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
73static 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
122void 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
146void CompilerSetOptionWidget::doSave()
147{
148 if (pSettings->compilerSets().size()>0) {
149 saveCurrentCompilerSet();
150 }
151 pSettings->compilerSets().saveSets();
152 pMainWindow->updateCompilerSet();
153}
154
155void 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
166void 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
177void 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
213void 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
236void 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
245void 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
260void 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
269void CompilerSetOptionWidget::on_btnRemoveCompilerSet_pressed()
270{
271 pSettings->compilerSets().deleteSet(ui->cbCompilerSet->currentIndex());
272 doLoad();
273}
274
275void 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
292void 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
311void CompilerSetOptionWidget::on_cbEncodingDetails_currentTextChanged(const QString &/*arg1*/)
312{
313
314}
315
316