2021-09-30 11:20:43 +08:00
|
|
|
#include "codesnippetsmanager.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "systemconsts.h"
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
|
|
#include <QFile>
|
|
|
|
#include <QJsonArray>
|
|
|
|
#include <QJsonDocument>
|
|
|
|
#include <QJsonObject>
|
|
|
|
|
|
|
|
CodeSnippetsManager::CodeSnippetsManager(QObject *parent) : QObject(parent)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSnippetsManager::load()
|
|
|
|
{
|
2021-09-30 20:10:48 +08:00
|
|
|
//if config file not exists, copy it from data
|
|
|
|
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_CODESNIPPET_FILE;
|
|
|
|
if (!fileExists(filename)) {
|
|
|
|
QString defaultFilename = ":/config/codesnippets.json";
|
|
|
|
if (!QFile::copy(
|
|
|
|
defaultFilename,
|
|
|
|
filename)) {
|
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Load default code snippets failed"),
|
|
|
|
tr("Can't copy default code snippets '%1' to '%2'.")
|
|
|
|
.arg(defaultFilename)
|
|
|
|
.arg(filename));
|
|
|
|
}
|
|
|
|
}
|
2021-09-30 11:20:43 +08:00
|
|
|
//read config file
|
2021-09-30 20:10:48 +08:00
|
|
|
QFile file(filename);
|
|
|
|
if (!file.open(QFile::ReadOnly)) {
|
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Read code snippets failed"),
|
|
|
|
tr("Can't open code snippet file '%1' for read.")
|
|
|
|
.arg(filename));
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray json = file.readAll();
|
|
|
|
QJsonParseError error;
|
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(json,&error);
|
|
|
|
if (error.error != QJsonParseError::NoError) {
|
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Read code snippets failed"),
|
|
|
|
tr("Read code snippet file '%1' failed:%2")
|
|
|
|
.arg(filename)
|
|
|
|
.arg(error.errorString()));
|
|
|
|
}
|
|
|
|
mSnippets.clear();
|
|
|
|
QJsonArray array = doc.array();
|
|
|
|
foreach (const QJsonValue& value,array) {
|
|
|
|
QJsonObject object = value.toObject();
|
|
|
|
PCodeSnippet snippet = std::make_shared<CodeSnippet>();
|
|
|
|
snippet->caption = object["caption"].toString();
|
|
|
|
snippet->prefix = object["prefix"].toString();
|
|
|
|
snippet->code = object["code"].toString();
|
|
|
|
snippet->desc = object["description"].toString();
|
|
|
|
snippet->section = object["section"].toInt();
|
|
|
|
mSnippets.append(snippet);
|
|
|
|
}
|
2021-09-30 11:20:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSnippetsManager::save()
|
|
|
|
{
|
2021-09-30 20:10:48 +08:00
|
|
|
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_CODESNIPPET_FILE;
|
2021-09-30 11:20:43 +08:00
|
|
|
QFile file(filename);
|
|
|
|
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
|
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Save code snippets failed"),
|
|
|
|
tr("Can't open code snippet file '%1' for write.")
|
|
|
|
.arg(filename));
|
|
|
|
}
|
|
|
|
QJsonArray array;
|
|
|
|
foreach (const PCodeSnippet& snippet,mSnippets) {
|
|
|
|
QJsonObject object;
|
|
|
|
object["caption"]=snippet->caption;
|
|
|
|
object["prefix"]=snippet->prefix;
|
|
|
|
object["code"]=snippet->code;
|
|
|
|
object["description"]=snippet->desc;
|
|
|
|
object["section"]=snippet->section;
|
|
|
|
array.append(object);
|
|
|
|
}
|
|
|
|
QJsonDocument doc;
|
|
|
|
doc.setArray(array);
|
|
|
|
if (file.write(doc.toJson())<0) {
|
|
|
|
QMessageBox::critical(nullptr,
|
|
|
|
tr("Save code snippets failed"),
|
|
|
|
tr("Write to code snippet file '%1' failed.")
|
|
|
|
.arg(filename));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-30 12:52:22 +08:00
|
|
|
const QList<PCodeSnippet> &CodeSnippetsManager::snippets() const
|
|
|
|
{
|
|
|
|
return mSnippets;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSnippetsManager::setSnippets(const QList<PCodeSnippet> &newSnippets)
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
2021-09-30 12:52:22 +08:00
|
|
|
mSnippets = newSnippets;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSnippetsModel::addSnippet(const QString &caption, const QString &prefix, const QString &code, const QString &description, int menuSection)
|
|
|
|
{
|
|
|
|
beginInsertRows(QModelIndex(),mSnippets.count(),mSnippets.count());
|
2021-09-30 11:20:43 +08:00
|
|
|
PCodeSnippet snippet = std::make_shared<CodeSnippet>();
|
|
|
|
snippet->caption = caption;
|
|
|
|
snippet->prefix = prefix;
|
|
|
|
snippet->code = code;
|
|
|
|
snippet->desc = description;
|
|
|
|
snippet->section = menuSection;
|
|
|
|
mSnippets.append(snippet);
|
2021-09-30 12:52:22 +08:00
|
|
|
endInsertRows();
|
2021-09-30 11:20:43 +08:00
|
|
|
}
|
|
|
|
|
2021-09-30 12:52:22 +08:00
|
|
|
void CodeSnippetsModel::remove(int index)
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
|
|
|
Q_ASSERT(index>=0 && index<mSnippets.count());
|
2021-09-30 12:52:22 +08:00
|
|
|
beginRemoveRows(QModelIndex(),index,index);
|
2021-09-30 11:20:43 +08:00
|
|
|
mSnippets.removeAt(index);
|
2021-09-30 12:52:22 +08:00
|
|
|
endRemoveRows();
|
2021-09-30 11:20:43 +08:00
|
|
|
}
|
|
|
|
|
2021-09-30 12:52:22 +08:00
|
|
|
void CodeSnippetsModel::clear()
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
2021-09-30 12:52:22 +08:00
|
|
|
beginRemoveRows(QModelIndex(),0,mSnippets.count()-1);
|
2021-09-30 11:20:43 +08:00
|
|
|
mSnippets.clear();
|
2021-09-30 12:52:22 +08:00
|
|
|
endRemoveRows();
|
2021-09-30 11:20:43 +08:00
|
|
|
}
|
|
|
|
|
2021-09-30 20:10:48 +08:00
|
|
|
QModelIndex CodeSnippetsModel::lastSnippetCaption()
|
|
|
|
{
|
|
|
|
Q_ASSERT(mSnippets.count()>0);
|
|
|
|
return createIndex(mSnippets.count()-1,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CodeSnippetsModel::rowCount(const QModelIndex &) const
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
|
|
|
return mSnippets.count();
|
|
|
|
}
|
|
|
|
|
2021-09-30 20:10:48 +08:00
|
|
|
int CodeSnippetsModel::columnCount(const QModelIndex &) const
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
2021-09-30 12:52:22 +08:00
|
|
|
QVariant CodeSnippetsModel::data(const QModelIndex &index, int role) const
|
2021-09-30 11:20:43 +08:00
|
|
|
{
|
2021-09-30 12:52:22 +08:00
|
|
|
if (!index.isValid()) {
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
if (role==Qt::DisplayRole) {
|
|
|
|
int row = index.row();
|
|
|
|
PCodeSnippet snippet = mSnippets[row];
|
|
|
|
switch(index.column()) {
|
|
|
|
case 0:
|
|
|
|
return snippet->caption;
|
|
|
|
case 1:
|
|
|
|
return snippet->prefix;
|
|
|
|
case 2:
|
|
|
|
return snippet->desc;
|
|
|
|
case 3:
|
|
|
|
return snippet->section;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
2021-09-30 11:20:43 +08:00
|
|
|
|
2021-09-30 12:52:22 +08:00
|
|
|
bool CodeSnippetsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
|
|
{
|
|
|
|
if (!index.isValid()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (role==Qt::EditRole) {
|
|
|
|
int row = index.row();
|
|
|
|
PCodeSnippet snippet = mSnippets[row];
|
|
|
|
switch(index.column()) {
|
|
|
|
case 0:
|
|
|
|
snippet->caption = value.toString();
|
|
|
|
return true;
|
|
|
|
case 1:
|
|
|
|
snippet->prefix = value.toString();
|
|
|
|
return true;
|
|
|
|
case 2:
|
|
|
|
snippet->desc = value.toString();
|
|
|
|
return true;
|
|
|
|
case 3:
|
|
|
|
snippet->section = value.toInt();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
2021-09-30 11:20:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
QVariant CodeSnippetsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
|
|
{
|
|
|
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
|
|
|
switch(section) {
|
|
|
|
case 0:
|
|
|
|
return tr("Caption");
|
|
|
|
case 1:
|
|
|
|
return tr("Completion Prefix");
|
|
|
|
case 2:
|
|
|
|
return tr("Description");
|
|
|
|
case 3:
|
|
|
|
return tr("Menu Section");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
2021-09-30 12:52:22 +08:00
|
|
|
|
|
|
|
Qt::ItemFlags CodeSnippetsModel::flags(const QModelIndex &) const
|
|
|
|
{
|
|
|
|
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QList<PCodeSnippet> &CodeSnippetsModel::snippets() const
|
|
|
|
{
|
|
|
|
return mSnippets;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSnippetsModel::updateSnippets(const QList<PCodeSnippet> &snippets)
|
|
|
|
{
|
|
|
|
beginResetModel();
|
|
|
|
mSnippets = snippets;
|
|
|
|
endResetModel();
|
|
|
|
}
|