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 "formattergeneralwidget.h" |
18 | #include "ui_formattergeneralwidget.h" |
19 | #include "../settings.h" |
20 | |
21 | FormatterGeneralWidget::FormatterGeneralWidget(const QString& name, const QString& group, QWidget *parent): |
22 | SettingsWidget(name,group,parent), |
23 | ui(new Ui::FormatterGeneralWidget) |
24 | { |
25 | ui->setupUi(this); |
26 | ui->cbBraceStyle->setModel(&mStylesModel); |
27 | connect(ui->cbBraceStyle, QOverload<int>::of(&QComboBox::currentIndexChanged), |
28 | this, &FormatterGeneralWidget::onBraceStyleChanged); |
29 | ui->editDemo->setReadOnly(true); |
30 | connect(this, &SettingsWidget::settingsChanged, |
31 | this, &FormatterGeneralWidget::updateDemo); |
32 | } |
33 | |
34 | FormatterGeneralWidget::~FormatterGeneralWidget() |
35 | { |
36 | delete ui; |
37 | } |
38 | |
39 | void FormatterGeneralWidget::onBraceStyleChanged() |
40 | { |
41 | PFormatterStyleItem item = mStylesModel.getStyle(ui->cbBraceStyle->currentIndex()); |
42 | if (item) { |
43 | ui->lblBraceStyle->setText(item->description); |
44 | } |
45 | } |
46 | |
47 | void FormatterGeneralWidget::doLoad() |
48 | { |
49 | Settings::CodeFormatter& format = pSettings->codeFormatter(); |
50 | for (int i=0;i<mStylesModel.rowCount(QModelIndex());i++) { |
51 | PFormatterStyleItem item = mStylesModel.getStyle(i); |
52 | if (item->style == format.braceStyle()) { |
53 | ui->cbBraceStyle->setCurrentIndex(i); |
54 | break; |
55 | } |
56 | } |
57 | if (format.indentStyle() == FormatterIndentType::fitSpace) { |
58 | ui->rbIndentSpaces->setChecked(true); |
59 | } else { |
60 | ui->rbIndentTabs->setChecked(true); |
61 | } |
62 | ui->spinTabSize->setValue(format.tabWidth()); |
63 | ui->chkAttachNamespaces->setChecked(format.attachNamespaces()); |
64 | ui->chkAttachClasses->setChecked(format.attachClasses()); |
65 | ui->chkAttachInline->setChecked(format.attachInlines()); |
66 | ui->chkAttachExternC->setChecked(format.attachExternC()); |
67 | ui->chkAttachClosingWhile->setChecked(format.attachClosingWhile()); |
68 | ui->chkIndentClasses->setChecked(format.indentClasses()); |
69 | ui->chkIndentModifiers->setChecked(format.indentModifiers()); |
70 | ui->chkIndentSwiches->setChecked(format.indentSwitches()); |
71 | ui->chkIndentCases->setChecked(format.indentCases()); |
72 | ui->chkIndentNamespaces->setChecked(format.indentNamespaces()); |
73 | ui->chkIndentAfterParens->setChecked(format.indentAfterParens()); |
74 | ui->spinIndentContinuation->setValue(format.indentContinuation()); |
75 | ui->chkIndentLabels->setChecked(format.indentLabels()); |
76 | ui->chkIndentPreprocBlock->setChecked(format.indentPreprocBlock()); |
77 | ui->chkIndentPreprocCond->setChecked(format.indentPreprocCond()); |
78 | ui->chkIndentPreprocDefine->setChecked(format.indentPreprocDefine()); |
79 | ui->chkIndentCol1Comments->setChecked(format.indentCol1Comments()); |
80 | ui->spinMinConditionalIndent->setValue(format.minConditionalIndent()); |
81 | ui->spinMaxContinuationIndent->setValue(format.maxContinuationIndent()); |
82 | ui->chkBreakBlocks->setChecked(format.breakBlocks()); |
83 | ui->chkBreakBlocksAll->setChecked(format.breakBlocksAll()); |
84 | ui->chkPadOper->setChecked(format.padOper()); |
85 | ui->chkPadComma->setChecked(format.padComma()); |
86 | ui->chkPadParen->setChecked(format.padParen()); |
87 | ui->chkPadParenOut->setChecked(format.padParenOut()); |
88 | ui->chkPadFirstParenOut->setChecked(format.padFirstParenOut()); |
89 | ui->chkPadParenIn->setChecked(format.padParenIn()); |
90 | ui->chkPadHeader->setChecked(format.padHeader()); |
91 | ui->chkUnpadParen->setChecked(format.unpadParen()); |
92 | ui->chkDeleteEmptyLines->setChecked(format.deleteEmptyLines()); |
93 | ui->chkDeleteMultipleEmptyLines->setChecked(format.deleteMultipleEmptyLines()); |
94 | ui->chkFillEmptyLines->setChecked(format.fillEmptyLines()); |
95 | switch(format.alignPointerStyle()) { |
96 | case FormatterOperatorAlign::foaNone: |
97 | ui->rbAlignPointNone->setChecked(true); |
98 | break; |
99 | case FormatterOperatorAlign::foaType: |
100 | ui->rbAlignPointType->setChecked(true); |
101 | break; |
102 | case FormatterOperatorAlign::foaMiddle: |
103 | ui->rbAlignPointerMiddle->setChecked(true); |
104 | break; |
105 | case FormatterOperatorAlign::foaName: |
106 | ui->rbAlignPointerName->setChecked(true); |
107 | break; |
108 | } |
109 | switch(format.alignReferenceStyle()) { |
110 | case FormatterOperatorAlign::foaNone: |
111 | ui->rbAlignReferenceNone->setChecked(true); |
112 | break; |
113 | case FormatterOperatorAlign::foaType: |
114 | ui->rbAlignReferenceType->setChecked(true); |
115 | break; |
116 | case FormatterOperatorAlign::foaMiddle: |
117 | ui->rbAlignReferenceMiddle->setChecked(true); |
118 | break; |
119 | case FormatterOperatorAlign::foaName: |
120 | ui->rbAlignReferenceName->setChecked(true); |
121 | break; |
122 | } |
123 | ui->chkBreakClosingBraces->setChecked(format.breakClosingBraces()); |
124 | ui->chkBreakElseIf->setChecked(format.breakElseIf()); |
125 | ui->chkBreakOneLineHeaders->setChecked(format.breakOneLineHeaders()); |
126 | ui->chkAddBraces->setChecked(format.addBraces()); |
127 | ui->chkAddOneLineBraces->setChecked(format.addOneLineBraces()); |
128 | ui->chkRemoveBraces->setChecked(format.removeBraces()); |
129 | ui->chkBreakReturnType->setChecked(format.breakReturnType()); |
130 | ui->chkBreakReturnTypeDecl->setChecked(format.breakReturnTypeDecl()); |
131 | ui->chkAttachReturnType->setChecked(format.attachReturnType()); |
132 | ui->chkAttachReturnTypeDecl->setChecked(format.attachReturnTypeDecl()); |
133 | ui->chkKeepOneLineBlocks->setChecked(format.keepOneLineBlocks()); |
134 | ui->chkKeepOneLineStatements->setChecked(format.keepOneLineStatements()); |
135 | ui->chkConvertTabs->setChecked(format.convertTabs()); |
136 | ui->chkCloseTemplates->setChecked(format.closeTemplates()); |
137 | ui->chkRemoveCommentPrefix->setChecked(format.removeCommentPrefix()); |
138 | ui->chkBreakMaxCodeLength->setChecked(format.breakMaxCodeLength()); |
139 | ui->spinMaxCodeLength->setValue(format.maxCodeLength()); |
140 | ui->chkBreakAfterLogical->setChecked(format.breakAfterLogical()); |
141 | updateDemo(); |
142 | } |
143 | |
144 | void FormatterGeneralWidget::doSave() |
145 | { |
146 | Settings::CodeFormatter& format = pSettings->codeFormatter(); |
147 | updateCodeFormatter(format); |
148 | format.save(); |
149 | } |
150 | |
151 | FormatterStyleModel::FormatterStyleModel(QObject *parent):QAbstractListModel(parent) |
152 | { |
153 | mStyles.append( |
154 | std::make_shared<FormatterStyleItem>( |
155 | tr("Default" ), |
156 | tr("The opening braces will not be changed and closing braces will be broken from the preceding line." ), |
157 | FormatterBraceStyle::fbsDefault) |
158 | ); |
159 | mStyles.append( |
160 | std::make_shared<FormatterStyleItem>( |
161 | tr("Allman" ), |
162 | tr("Broken braces." ), |
163 | FormatterBraceStyle::fbsAllman) |
164 | ); |
165 | mStyles.append( |
166 | std::make_shared<FormatterStyleItem>( |
167 | tr("Java" ), |
168 | tr("Attached braces." ), |
169 | FormatterBraceStyle::fbsJava) |
170 | ); |
171 | mStyles.append( |
172 | std::make_shared<FormatterStyleItem>( |
173 | tr("K&R" ), |
174 | tr("Linux braces." ), |
175 | FormatterBraceStyle::fbsKR) |
176 | ); |
177 | mStyles.append( |
178 | std::make_shared<FormatterStyleItem>( |
179 | tr("Stroustrup" ), |
180 | tr("Linux braces, with broken closing headers." ), |
181 | FormatterBraceStyle::fbsStroustrup) |
182 | ); |
183 | mStyles.append( |
184 | std::make_shared<FormatterStyleItem>( |
185 | tr("Whitesmith" ), |
186 | tr("Broken, indented braces." ) |
187 | + " " |
188 | +tr("Indented class blocks and switch blocks." ), |
189 | FormatterBraceStyle::fbsWitesmith) |
190 | ); |
191 | mStyles.append( |
192 | std::make_shared<FormatterStyleItem>( |
193 | tr("VTK" ), |
194 | tr("Broken, indented braces except for the opening braces." ), |
195 | FormatterBraceStyle::fbsVtk) |
196 | ); |
197 | mStyles.append( |
198 | std::make_shared<FormatterStyleItem>( |
199 | tr("Ratliff" ), |
200 | tr("Attached, indented braces." ), |
201 | FormatterBraceStyle::fbsRatliff) |
202 | ); |
203 | mStyles.append( |
204 | std::make_shared<FormatterStyleItem>( |
205 | tr("GNU" ), |
206 | tr("Broken braces, indented blocks." ), |
207 | FormatterBraceStyle::fbsGNU) |
208 | ); |
209 | mStyles.append( |
210 | std::make_shared<FormatterStyleItem>( |
211 | tr("Linux" ), |
212 | tr("Linux braces, minimum conditional indent is one-half indent." ), |
213 | FormatterBraceStyle::fbsLinux) |
214 | ); |
215 | mStyles.append( |
216 | std::make_shared<FormatterStyleItem>( |
217 | tr("Horstmann" ), |
218 | tr("Run-in braces, indented switches." ), |
219 | FormatterBraceStyle::fbsHorstmann) |
220 | ); |
221 | mStyles.append( |
222 | std::make_shared<FormatterStyleItem>( |
223 | tr("One True Brace" ), |
224 | tr("Linux braces, add braces to all conditionals." ), |
225 | FormatterBraceStyle::fbs1TBS) |
226 | ); |
227 | mStyles.append( |
228 | std::make_shared<FormatterStyleItem>( |
229 | tr("Google" ), |
230 | tr("Attached braces, indented class modifiers." ), |
231 | FormatterBraceStyle::fbsGoogle) |
232 | ); |
233 | mStyles.append( |
234 | std::make_shared<FormatterStyleItem>( |
235 | tr("Mozilla" ), |
236 | tr("Linux braces, with broken braces for structs and enums, and attached braces for namespaces." ), |
237 | FormatterBraceStyle::fbsMozilla) |
238 | ); |
239 | mStyles.append( |
240 | std::make_shared<FormatterStyleItem>( |
241 | tr("Webkit" ), |
242 | tr("Linux braces, with attached closing headers." ), |
243 | FormatterBraceStyle::fbsWebkit) |
244 | ); |
245 | mStyles.append( |
246 | std::make_shared<FormatterStyleItem>( |
247 | tr("Pico" ), |
248 | tr("Run-in opening braces and attached closing braces." ) |
249 | +" " + |
250 | tr("Uses keep one line blocks and keep one line statements." ), |
251 | FormatterBraceStyle::fbsPico) |
252 | ); |
253 | mStyles.append( |
254 | std::make_shared<FormatterStyleItem>( |
255 | tr("Lisp" ), |
256 | tr("Attached opening braces and attached closing braces." ) |
257 | +" " + |
258 | tr("Uses keep one line statements." ), |
259 | FormatterBraceStyle::fbsLisp) |
260 | ); |
261 | } |
262 | |
263 | int FormatterStyleModel::rowCount(const QModelIndex &) const |
264 | { |
265 | return mStyles.count(); |
266 | } |
267 | |
268 | QVariant FormatterStyleModel::data(const QModelIndex &index, int role) const |
269 | { |
270 | if (!index.isValid()) |
271 | return QVariant(); |
272 | int row = index.row(); |
273 | if (row<0 || row>=mStyles.count()) |
274 | return QVariant(); |
275 | PFormatterStyleItem item = mStyles[row]; |
276 | switch (role) { |
277 | case Qt::DisplayRole: |
278 | return item->name; |
279 | case Qt::ToolTipRole: |
280 | return item->description; |
281 | } |
282 | return QVariant(); |
283 | } |
284 | |
285 | PFormatterStyleItem FormatterStyleModel::getStyle(const QModelIndex &index) |
286 | { |
287 | if (index.isValid()) { |
288 | return getStyle(index.row()); |
289 | } else { |
290 | return PFormatterStyleItem(); |
291 | } |
292 | } |
293 | |
294 | PFormatterStyleItem FormatterStyleModel::getStyle(int index) |
295 | { |
296 | if (index<0 || index>=mStyles.count()) |
297 | return PFormatterStyleItem(); |
298 | return mStyles[index]; |
299 | } |
300 | |
301 | FormatterStyleItem::FormatterStyleItem(const QString &name, const QString &description, FormatterBraceStyle style) |
302 | { |
303 | this->name = name; |
304 | this->description = description; |
305 | this->style = style; |
306 | } |
307 | |
308 | void FormatterGeneralWidget::on_chkBreakMaxCodeLength_stateChanged(int) |
309 | { |
310 | ui->spinMaxCodeLength->setEnabled(ui->chkBreakMaxCodeLength->isChecked()); |
311 | ui->chkBreakAfterLogical->setEnabled(ui->chkBreakMaxCodeLength->isChecked()); |
312 | } |
313 | |
314 | void FormatterGeneralWidget::updateDemo() |
315 | { |
316 | QFile file(":/codes/formatdemo.cpp" ); |
317 | if (!file.open(QFile::ReadOnly)) |
318 | return; |
319 | QByteArray content = file.readAll(); |
320 | |
321 | Settings::CodeFormatter formatter(nullptr); |
322 | updateCodeFormatter(formatter); |
323 | |
324 | QByteArray newContent = runAndGetOutput("astyle.exe" , |
325 | pSettings->dirs().appDir(), |
326 | formatter.getArguments(), |
327 | content); |
328 | ui->editDemo->document()->setText(newContent); |
329 | } |
330 | |
331 | void FormatterGeneralWidget::updateCodeFormatter(Settings::CodeFormatter &format) |
332 | { |
333 | PFormatterStyleItem item = mStylesModel.getStyle(ui->cbBraceStyle->currentIndex()); |
334 | if (item) |
335 | format.setBraceStyle(item->style); |
336 | if (ui->rbIndentSpaces->isChecked()) { |
337 | format.setIndentStyle(FormatterIndentType::fitSpace); |
338 | } else { |
339 | format.setIndentStyle(FormatterIndentType::fitTab); |
340 | } |
341 | format.setTabWidth(ui->spinTabSize->value()); |
342 | format.setAttachNamespaces(ui->chkAttachNamespaces->isChecked()); |
343 | format.setAttachClasses(ui->chkAttachClasses->isChecked()); |
344 | format.setAttachInlines(ui->chkAttachInline->isChecked()); |
345 | format.setAttachExternC(ui->chkAttachExternC->isChecked()); |
346 | format.setAttachClosingWhile(ui->chkAttachClosingWhile->isChecked()); |
347 | format.setIndentClasses(ui->chkIndentClasses->isChecked()); |
348 | format.setIndentModifiers(ui->chkIndentModifiers->isChecked()); |
349 | format.setIndentSwitches(ui->chkIndentSwiches->isChecked()); |
350 | format.setIndentCases(ui->chkIndentCases->isChecked()); |
351 | format.setIndentNamespaces(ui->chkIndentNamespaces->isChecked()); |
352 | format.setIndentAfterParens(ui->chkIndentAfterParens->isChecked()); |
353 | format.setIndentContinuation(ui->spinIndentContinuation->value()); |
354 | format.setIndentLabels(ui->chkIndentLabels->isChecked()); |
355 | format.setIndentPreprocBlock(ui->chkIndentPreprocBlock->isChecked()); |
356 | format.setIndentPreprocCond(ui->chkIndentPreprocCond->isChecked()); |
357 | format.setIndentPreprocDefine(ui->chkIndentPreprocDefine->isChecked()); |
358 | format.setIndentCol1Comments(ui->chkIndentCol1Comments->isChecked()); |
359 | format.setMinConditionalIndent(ui->spinMinConditionalIndent->value()); |
360 | format.setMaxContinuationIndent(ui->spinMaxContinuationIndent->value()); |
361 | format.setBreakBlocks(ui->chkBreakBlocks->isChecked()); |
362 | format.setBreakBlocksAll(ui->chkBreakBlocksAll->isChecked()); |
363 | format.setPadOper(ui->chkPadOper->isChecked()); |
364 | format.setPadComma(ui->chkPadComma->isChecked()); |
365 | format.setPadParen(ui->chkPadParen->isChecked()); |
366 | format.setPadParenOut(ui->chkPadParenOut->isChecked()); |
367 | format.setPadFirstParenOut(ui->chkPadFirstParenOut->isChecked()); |
368 | format.setPadParenIn(ui->chkPadParenIn->isChecked()); |
369 | format.setPadHeader(ui->chkPadHeader->isChecked()); |
370 | format.setUnpadParen(ui->chkUnpadParen->isChecked()); |
371 | format.setDeleteEmptyLines(ui->chkDeleteEmptyLines->isChecked()); |
372 | format.setDeleteMultipleEmptyLines(ui->chkDeleteMultipleEmptyLines->isChecked()); |
373 | format.setFillEmptyLines(ui->chkFillEmptyLines->isChecked()); |
374 | if (ui->rbAlignPointNone->isChecked()) { |
375 | format.setAlignPointerStyle(FormatterOperatorAlign::foaNone); |
376 | } else if (ui->rbAlignPointType->isChecked()) { |
377 | format.setAlignPointerStyle(FormatterOperatorAlign::foaType); |
378 | } else if (ui->rbAlignPointerMiddle->isChecked()) { |
379 | format.setAlignPointerStyle(FormatterOperatorAlign::foaMiddle); |
380 | } else if (ui->rbAlignPointerName->isChecked()) { |
381 | format.setAlignPointerStyle(FormatterOperatorAlign::foaName); |
382 | } |
383 | if (ui->rbAlignReferenceNone->isChecked()) { |
384 | format.setAlignReferenceStyle(FormatterOperatorAlign::foaNone); |
385 | } else if (ui->rbAlignReferenceType->isChecked()) { |
386 | format.setAlignReferenceStyle(FormatterOperatorAlign::foaType); |
387 | } else if (ui->rbAlignReferenceMiddle->isChecked()) { |
388 | format.setAlignReferenceStyle(FormatterOperatorAlign::foaMiddle); |
389 | } else if (ui->rbAlignReferenceName->isChecked()) { |
390 | format.setAlignReferenceStyle(FormatterOperatorAlign::foaName); |
391 | } |
392 | format.setBreakClosingBraces(ui->chkBreakClosingBraces->isChecked()); |
393 | format.setBreakElseIf(ui->chkBreakElseIf->isChecked()); |
394 | format.setBreakOneLineHeaders(ui->chkBreakOneLineHeaders->isChecked()); |
395 | format.setAddBraces(ui->chkAddBraces->isChecked()); |
396 | format.setAddOneLineBraces(ui->chkAddOneLineBraces->isChecked()); |
397 | format.setRemoveBraces(ui->chkRemoveBraces->isChecked()); |
398 | format.setBreakReturnType(ui->chkBreakReturnType->isChecked()); |
399 | format.setBreakReturnTypeDecl(ui->chkBreakReturnTypeDecl->isChecked()); |
400 | format.setAttachReturnType(ui->chkAttachReturnType->isChecked()); |
401 | format.setAttachReturnTypeDecl(ui->chkAttachReturnTypeDecl->isChecked()); |
402 | format.setKeepOneLineBlocks(ui->chkKeepOneLineBlocks->isChecked()); |
403 | format.setKeepOneLineStatements(ui->chkKeepOneLineStatements->isChecked()); |
404 | format.setConvertTabs(ui->chkConvertTabs->isChecked()); |
405 | format.setCloseTemplates(ui->chkCloseTemplates->isChecked()); |
406 | format.setRemoveCommentPrefix(ui->chkRemoveCommentPrefix->isChecked()); |
407 | format.setBreakMaxCodeLength(ui->chkBreakMaxCodeLength->isChecked()); |
408 | format.setMaxCodeLength(ui->spinMaxCodeLength->value()); |
409 | format.setBreakAfterLogical(ui->chkBreakAfterLogical->isChecked()); |
410 | } |
411 | |
412 | |