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
25CompilerAutolinkWidget::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
34CompilerAutolinkWidget::~CompilerAutolinkWidget()
35{
36 delete ui;
37}
38
39void CompilerAutolinkWidget::doLoad()
40{
41 ui->grpAutolink->setChecked(pSettings->editor().enableAutolink());
42 mModel.setLinks(pAutolinkManager->links());
43}
44
45void 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
69AutolinkModel::AutolinkModel(CompilerAutolinkWidget* widget,QObject *parent):
70 QAbstractTableModel(parent),
71 mWidget(widget)
72{
73
74}
75
76int AutolinkModel::rowCount(const QModelIndex &) const
77{
78 return mLinks.count();
79}
80
81int AutolinkModel::columnCount(const QModelIndex &) const
82{
83 return 3;
84}
85
86QVariant AutolinkModel::headerData(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
101QVariant 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
128bool 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
179Qt::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
191bool 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
204bool 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
219const QList<PAutolink> &AutolinkModel::links() const
220{
221 return mLinks;
222}
223
224void AutolinkModel::setLinks(const QMap<QString, PAutolink> &newLinks)
225{
226 beginResetModel();
227 mLinks = newLinks.values();
228 endResetModel();
229}
230
231int AutolinkModel::findLink(const QString &header)
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
241void CompilerAutolinkWidget::on_btnAdd_pressed()
242{
243 mModel.insertRow(mModel.links().count());
244}
245
246
247void CompilerAutolinkWidget::on_btnRemove_pressed()
248{
249 QModelIndex index = ui->tblAutolinks->currentIndex();
250 mModel.removeRow(index.row(),index.parent());
251}
252
253void 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