Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2730158
remarkupplugin.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Mar 13, 8:41 PM
Size
8 KB
Mime Type
text/x-c++
Expires
Sun, Mar 15, 8:41 PM (1 d, 15 h)
Engine
blob
Format
Raw Data
Handle
243372
Attached To
rXR Xreate
remarkupplugin.cpp
View Options
#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
Log In to Comment