remarkupplugin.cpp
No OneTemporary

File Metadata

Created
Fri, Mar 13, 8:41 PM

remarkupplugin.cpp

#include "remarkupplugin.h"
#include "remarkupparserthread.h"
#include "SciDoc.h"
#include "JuffScintilla.h"
#include <QDebug>
#include <QMap>
#include <QDomDocument>
#include "AppInfo.h"
#include "LexerStorage.h"
using namespace Juff;
//"PhutilRemarkupDefaultBlockRule",
//"PhutilRemarkupHeaderBlockRule",
//"PhutilRemarkupListBlockRule",
//"PhutilRemarkupNoteBlockRule",
//"PhutilRemarkupHorizontalRuleBlockRule",
//"PhutilRemarkupReplyBlockRule",
//"PhutilRemarkupCodeBlockRule",
//"PhutilRemarkupLiteralBlockRule",
//"PhutilRemarkupTableBlockRule",
//"PhutilRemarkupSimpleTableBlockRule",
//"PhutilRemarkupInterpreterBlockRule"
class BlocksHighlighter{
public:
BlocksHighlighter(){
}
QDomDocument loadScheme(){
QDomDocument doc("JuffScheme");
QString fileName = QString("remarkup.xml");
fileName = AppInfo::configDirPath() + "/hlschemes/" + fileName;
QFile file(fileName);
if ( !file.open(QIODevice::ReadOnly) ) {
qDebug()<<(QString("[BlocksScheme] No scheme found in '%1'. Using the standard one.").arg(fileName));
return doc;
}
QString err;
int errLine, errCol;
if ( !doc.setContent(&file, &err, &errLine, &errCol) ) {
qDebug() << QString("[BlocksScheme] File %1: XML reading error: '%2', line %3, column %4")
.arg(fileName).arg(err).arg(errLine).arg(errCol);
}
file.close();
return doc;
}
void init(){
const QDomDocument docScheme = loadScheme();
QDomElement root = docScheme.documentElement().firstChildElement("blockrules");
// while (!root.isNull() && root.tagName().compare("blockrules")){
// root = root.nextSiblingElement();
// }
if (root.isNull()){
qDebug()<<"[BlocksScheme] not found blocks section";
return;
}
int countRules=0;
QDomElement styleNode = root.firstChildElement("style");
while (!styleNode.isNull()){
QString rule = styleNode.attribute("name", "");
if (!rule.isEmpty()) {
QColor colorBg = QVariant(styleNode.attribute("color", "#FFFFFF")).value<QColor>();
QString markerType = styleNode.attribute("marker", "Background");
QsciScintilla::MarkerSymbol marker = QsciScintilla::Background;
if (markerType == "FullRectangle"){
marker = QsciScintilla::FullRectangle;
} else if (markerType == "LeftRectangle") {
marker = QsciScintilla::LeftRectangle;
} else if (markerType == "Underline") {
marker = QsciScintilla::Underline;
}
rules.insert(rule, countRules);
Style style;
style.color = colorBg;
style.marker = marker;
markerStyles.append(style);
++countRules;
}
styleNode = styleNode.nextSiblingElement("style");
}
}
void defineMarkersForDoc(JuffScintilla* doc){
doc->setMarginMarkerMask(0, 32767);
for (int i=0; i<markerStyles.size(); ++i){
doc->markerDefine(markerStyles[i].marker, markersCustomOffset + i);
doc->setMarkerBackgroundColor(markerStyles[i].color, markersCustomOffset + i);
}
}
void removeMarkers(JuffScintilla* doc){
for (int i=0; i<markerStyles.size(); ++i){
doc->markerDeleteAll(i + markersCustomOffset);
}
}
void highlightDoc(JuffScintilla* doc, const std::vector<Block>& blocks){
removeMarkers(doc);
for (size_t i=0; i<blocks.size(); ++i){
const Block& block = blocks.at(i);
QString debug__rulename = QString::fromStdString(block.rule);
int ruleId = rules.value(QString::fromStdString(block.rule), -1);
//unknown rule
if (ruleId == -1) continue;
int markerForRule = ruleId + markersCustomOffset;
for (int lineNo = block.start; lineNo<block.start + block.num_lines; ++lineNo){
doc->markerAdd(lineNo, markerForRule);
}
}
}
private:
struct Style {
QColor color;
QsciScintilla::MarkerSymbol marker;
};
QVector<Style> markerStyles;
QMap<QString, int> rules;
const int markersCustomOffset = 3;
} highlighterRemarkupBlocks;
QAction* createAction(const QString& title, const QKeySequence& key, const QObject* this_, const char* slot) {
QAction* act = new QAction(title, 0);
this_->connect(act, SIGNAL(triggered()), this_, slot);
act->setShortcut(key);
return act;
}
RemarkupPlugin::RemarkupPlugin(): QObject(), JuffPlugin()
{
threadRemarkupParser = new RemarkupParserThread();
connect(threadRemarkupParser, SIGNAL(updateDoc(Blocks, Juff::JuffScintilla*)), this, SLOT(onTextParsed(Blocks, Juff::JuffScintilla*)));
}
RemarkupPlugin::~RemarkupPlugin(){
threadRemarkupParser->exit();
threadRemarkupParser->wait();
delete threadRemarkupParser;
}
// info
QString RemarkupPlugin::name()const {return "Remarkup";}
QString RemarkupPlugin::title() const {return "Remarkup";}
QString RemarkupPlugin::description() const {return "Remarkup";}
QString RemarkupPlugin::targetEngine() const{
return "all";
}
void
RemarkupPlugin::init(){
connect(api(), SIGNAL(docOpened(Juff::Document*, Juff::PanelIndex)), SLOT(onDocOpened(Juff::Document*, Juff::PanelIndex)));
connect(api(), SIGNAL(docTextChanged(Juff::Document*)), this, SLOT(refresh(Juff::Document*)));
connect(api(), SIGNAL(docActivated(Juff::Document*)), this, SLOT(refresh(Juff::Document*)));
connect(api(), SIGNAL(docSyntaxChanged(Juff::Document*,QString)), this, SLOT(onDocSyntaxChanged(Juff::Document*,QString)));
connect(api(), SIGNAL(docClosed(Juff::Document*)), this, SLOT(onDocClosed(Juff::Document*)));
connect(api(), SIGNAL(docRenamed(Juff::Document*,QString)), this, SLOT(onDocRenamed(Juff::Document*,QString)));
highlighterRemarkupBlocks.init();
threadRemarkupParser->start();
// connect(api(), SIGNAL(docActivated(Juff::Document*)), this, SLOT(onDocActivated(Juff::Document*)));
}
void
RemarkupPlugin::onDocOpened(Juff::Document* doc, Juff::PanelIndex panel){
onDocSyntaxChanged(doc, doc->syntax());
}
void
RemarkupPlugin::onDocClosed(Juff::Document* doc){
if (doc->isNull()) {return;}
if (doc->syntax().compare("Remarkup") !=0){return;}
threadRemarkupParser->stop();
}
void
RemarkupPlugin::onDocSyntaxChanged(Juff::Document* doc, QString syntax){
if (syntax.compare("Remarkup") !=0){return;}
SciDoc* __doc = qobject_cast<SciDoc*> (doc);
JuffScintilla* scintilla = __doc->getCurrentEditor();
if (!scintilla) return;
highlighterRemarkupBlocks.defineMarkersForDoc(scintilla);
}
void
RemarkupPlugin::refresh(Juff::Document* doc){
if (doc->isNull()) {return;}
if (doc->syntax().compare("Remarkup") !=0){return;}
SciDoc* __doc = qobject_cast<SciDoc*> (api()->currentDocument());
JuffScintilla* scintilla = __doc->getCurrentEditor();
threadRemarkupParser->processDoc(scintilla);
}
void
RemarkupPlugin::onTextParsed(const Blocks& blocks, Juff::JuffScintilla* doc){
highlighterRemarkupBlocks.highlightDoc(doc, blocks);
}
Juff::ActionList
RemarkupPlugin::mainMenuActions(Juff::MenuID id) const {
Juff::ActionList list;
if ( id == Juff::MenuEdit ) {
list << createAction(tr("Bold"), QKeySequence("Ctrl+B"), this, SLOT(setSelectionBold()));
list << createAction(tr("Italic"), QKeySequence("Ctrl+I"), this, SLOT(setSelectionItalic()));
}
return list;
}
void
RemarkupPlugin::setSelectionItalic(){
Juff::Document* doc = this->api()->currentDocument();
if (doc->isNull()) {return;}
if (doc->syntax().compare("Remarkup") !=0){return;}
QString textInput;
doc->getSelectedText(textInput);
QString textItalic = QString("//%1//").arg(textInput);
doc->replaceSelectedText(textItalic);
}
void
RemarkupPlugin::setSelectionBold(){
Juff::Document* doc = this->api()->currentDocument();
if (doc->isNull()) {return;}
if (doc->syntax().compare("Remarkup") !=0){return;}
QString textInput;
doc->getSelectedText(textInput);
QString textBold = QString("**%1**").arg(textInput);
doc->replaceSelectedText(textBold);
}

Event Timeline