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 "compilerautolinkwidget.h" |
18 | #include "ui_compilerautolinkwidget.h" |
19 | #include "../mainwindow.h" |
20 | #include "../settings.h" |
21 | #include "../iconsmanager.h" |
22 | |
23 | #include <QMessageBox> |
24 | |
25 | CompilerAutolinkWidget::CompilerAutolinkWidget(const QString& name, const QString& group, QWidget* parent) : |
26 | SettingsWidget(name,group,parent), |
27 | mModel(this), |
28 | ui(new Ui::CompilerAutolinkWidget) |
29 | { |
30 | ui->setupUi(this); |
31 | ui->tblAutolinks->setModel(&mModel); |
32 | } |
33 | |
34 | CompilerAutolinkWidget::~CompilerAutolinkWidget() |
35 | { |
36 | delete ui; |
37 | } |
38 | |
39 | void CompilerAutolinkWidget::doLoad() |
40 | { |
41 | ui->grpAutolink->setChecked(pSettings->editor().enableAutolink()); |
42 | mModel.setLinks(pAutolinkManager->links()); |
43 | } |
44 | |
45 | void CompilerAutolinkWidget::doSave() |
46 | { |
47 | pSettings->editor().setEnableAutolink(ui->grpAutolink->isChecked()); |
48 | pSettings->editor().save(); |
49 | pAutolinkManager->clear(); |
50 | for (const PAutolink& link:mModel.links()) { |
51 | if (!link->header.isEmpty()) { |
52 | pAutolinkManager->setLink( |
53 | link->header, |
54 | link->linkOption, |
55 | link->execUseUTF8 |
56 | ); |
57 | } |
58 | } |
59 | try{ |
60 | pAutolinkManager->save(); |
61 | } catch (FileError e) { |
62 | QMessageBox::critical(this, |
63 | tr("Save failed." ), |
64 | e.reason(), |
65 | QMessageBox::Ok); |
66 | } |
67 | } |
68 | |
69 | AutolinkModel::AutolinkModel(CompilerAutolinkWidget* widget,QObject *parent): |
70 | QAbstractTableModel(parent), |
71 | mWidget(widget) |
72 | { |
73 | |
74 | } |
75 | |
76 | int AutolinkModel::rowCount(const QModelIndex &) const |
77 | { |
78 | return mLinks.count(); |
79 | } |
80 | |
81 | int AutolinkModel::columnCount(const QModelIndex &) const |
82 | { |
83 | return 3; |
84 | } |
85 | |
86 | QVariant AutolinkModel::(int section, Qt::Orientation orientation, int role) const |
87 | { |
88 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { |
89 | switch(section) { |
90 | case 0: |
91 | return tr("Header" ); |
92 | case 1: |
93 | return tr("UTF-8" ); |
94 | case 2: |
95 | return tr("Link options" ); |
96 | } |
97 | } |
98 | return QVariant(); |
99 | } |
100 | |
101 | QVariant AutolinkModel::data(const QModelIndex &index, int role) const |
102 | { |
103 | if (!index.isValid()) |
104 | return QVariant(); |
105 | if (role == Qt::DisplayRole || role == Qt::EditRole) { |
106 | int row = index.row(); |
107 | if (row<0 || row>=mLinks.count()) |
108 | return QVariant(); |
109 | PAutolink link = mLinks[row]; |
110 | switch(index.column()) { |
111 | case 0: |
112 | return link->header; |
113 | case 2: |
114 | return link->linkOption; |
115 | } |
116 | } else if (role == Qt::CheckStateRole && index.column()==1) { |
117 | int row = index.row(); |
118 | if (row<0 || row>=mLinks.count()) |
119 | return QVariant(); |
120 | PAutolink link = mLinks[row]; |
121 | return link->execUseUTF8 ? Qt::Checked : Qt::Unchecked; |
122 | } else if (role == Qt::TextAlignmentRole && index.column()==1) { |
123 | return Qt::AlignCenter; |
124 | } |
125 | return QVariant(); |
126 | } |
127 | |
128 | bool AutolinkModel::setData(const QModelIndex &index, const QVariant &value, int role) |
129 | { |
130 | if (!index.isValid()) |
131 | return false; |
132 | if (role == Qt::CheckStateRole && index.column()==1) { |
133 | int row = index.row(); |
134 | if (row<0 || row>=mLinks.count()) |
135 | return false; |
136 | PAutolink link = mLinks[row]; |
137 | link->execUseUTF8 = (value == Qt::Checked); |
138 | mWidget->setSettingsChanged(); |
139 | return true; |
140 | } |
141 | else if (role == Qt::EditRole) { |
142 | int row = index.row(); |
143 | if (row<0 || row>=mLinks.count()) |
144 | return false; |
145 | PAutolink link = mLinks[row]; |
146 | QString s=value.toString().trimmed(); |
147 | if (index.column() == 0) { |
148 | if (s.isEmpty()) |
149 | return false; |
150 | if (link->header == s) |
151 | return false; |
152 | if (findLink(s)>=0) { |
153 | QMessageBox::warning(pMainWindow, |
154 | tr("Header exists" ), |
155 | tr("Header already exists." ), |
156 | QMessageBox::Ok); |
157 | return false; |
158 | } |
159 | //we must create a new link, becasue mList may share link pointer with the autolink manger |
160 | PAutolink newLink = std::make_shared<Autolink>(); |
161 | newLink->header = s; |
162 | newLink->linkOption = link->linkOption; |
163 | mLinks[row]=newLink; |
164 | mWidget->setSettingsChanged(); |
165 | return true; |
166 | } else if (index.column() == 2) { |
167 | //we must create a new link, becasue mList may share link pointer with the autolink manger |
168 | PAutolink newLink = std::make_shared<Autolink>(); |
169 | newLink->header = link->header; |
170 | newLink->linkOption = s; |
171 | mLinks[row]=newLink; |
172 | mWidget->setSettingsChanged(); |
173 | return true; |
174 | } |
175 | } |
176 | return false; |
177 | } |
178 | |
179 | Qt::ItemFlags AutolinkModel::flags(const QModelIndex &index) const |
180 | { |
181 | Qt::ItemFlags flags = Qt::NoItemFlags; |
182 | if (index.isValid()) { |
183 | if (index.column()==1) |
184 | flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; |
185 | else |
186 | flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ; |
187 | } |
188 | return flags; |
189 | } |
190 | |
191 | bool AutolinkModel::insertRows(int row, int count, const QModelIndex &parent) |
192 | { |
193 | if (row<0 || row>mLinks.count()) |
194 | return false; |
195 | beginInsertRows(parent,row,row+count-1); |
196 | for (int i=row;i<row+count;i++) { |
197 | PAutolink link = std::make_shared<Autolink>(); |
198 | mLinks.insert(i,link); |
199 | } |
200 | endInsertRows(); |
201 | return true; |
202 | } |
203 | |
204 | bool AutolinkModel::removeRows(int row, int count, const QModelIndex &parent) |
205 | { |
206 | if (row<0 || row>=mLinks.count()) |
207 | return false; |
208 | beginRemoveRows(parent,row,row+count-1); |
209 | for (int i=row;i<row+count;i++) { |
210 | if (i>=mLinks.count()) |
211 | break; |
212 | mLinks.removeAt(i); |
213 | } |
214 | endRemoveRows(); |
215 | return true; |
216 | |
217 | } |
218 | |
219 | const QList<PAutolink> &AutolinkModel::links() const |
220 | { |
221 | return mLinks; |
222 | } |
223 | |
224 | void AutolinkModel::setLinks(const QMap<QString, PAutolink> &newLinks) |
225 | { |
226 | beginResetModel(); |
227 | mLinks = newLinks.values(); |
228 | endResetModel(); |
229 | } |
230 | |
231 | int AutolinkModel::findLink(const QString &) |
232 | { |
233 | for (int i=0;i<mLinks.count();i++) { |
234 | PAutolink link = mLinks[i]; |
235 | if (link->header == header) |
236 | return i; |
237 | } |
238 | return -1; |
239 | } |
240 | |
241 | void CompilerAutolinkWidget::on_btnAdd_pressed() |
242 | { |
243 | mModel.insertRow(mModel.links().count()); |
244 | } |
245 | |
246 | |
247 | void CompilerAutolinkWidget::on_btnRemove_pressed() |
248 | { |
249 | QModelIndex index = ui->tblAutolinks->currentIndex(); |
250 | mModel.removeRow(index.row(),index.parent()); |
251 | } |
252 | |
253 | void CompilerAutolinkWidget::updateIcons(const QSize &) |
254 | { |
255 | pIconsManager->setIcon(ui->btnAdd, IconsManager::ACTION_MISC_ADD); |
256 | pIconsManager->setIcon(ui->btnRemove, IconsManager::ACTION_MISC_REMOVE); |
257 | } |
258 | |
259 | |