]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiViewSource.cpp
the fun begins....
[features.git] / src / frontends / qt4 / GuiViewSource.cpp
1 /**
2  * \file GuiViewSource.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Bo Peng
8  * \author Abdelrazak Younes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiViewSource.h"
16 #include "qt_helpers.h"
17
18 #include <boost/tuple/tuple.hpp>
19
20 #include <QTextCursor>
21 #include <QTextDocument>
22
23
24 namespace lyx {
25 namespace frontend {
26
27 GuiViewSourceDialog::GuiViewSourceDialog(LyXView & lv)
28         : GuiDialog(lv, "view-source"),
29                 document_(new QTextDocument(this)),
30                 highlighter_(new LaTeXHighlighter(document_))
31 {
32         setupUi(this);
33         setController(new ControlViewSource(*this));
34
35         //      GuiViewBase & gui_view = static_cast<GuiViewBase &>(lyxview_);
36         //              *dialog, qvs, &gui_view, _("LaTeX Source"), Qt::BottomDockWidgetArea));
37
38         connect(viewFullSourceCB, SIGNAL(clicked()),
39                 this, SLOT(update()));
40         connect(autoUpdateCB, SIGNAL(toggled(bool)),
41                 updatePB, SLOT(setDisabled(bool)));
42         connect(updatePB, SIGNAL(clicked()),
43                 this, SLOT(update()));
44
45         // setting a document at this point trigger an assertion in Qt
46         // so we disable the signals here:
47         document()->blockSignals(true);
48         viewSourceTV->setDocument(document());
49         document()->blockSignals(false);
50         viewSourceTV->setReadOnly(true);
51         ///dialog_->viewSourceTV->setAcceptRichText(false);
52         // this is personal. I think source code should be in fixed-size font
53         QFont font(toqstr(theApp()->typewriterFontName()));
54         font.setKerning(false);
55         font.setFixedPitch(true);
56         font.setStyleHint(QFont::TypeWriter);
57         viewSourceTV->setFont(font);
58         // again, personal taste
59         viewSourceTV->setWordWrapMode(QTextOption::NoWrap);
60
61         bc().setPolicy(ButtonPolicy::OkCancelPolicy);
62 }
63
64
65 ControlViewSource & GuiViewSourceDialog::controller() const
66 {
67         return static_cast<ControlViewSource &>(Dialog::controller());
68 }
69
70
71 void GuiViewSourceDialog::updateView()
72 {
73         if (autoUpdateCB->isChecked())
74                 update(viewFullSourceCB->isChecked());
75
76         int beg, end;
77         boost::tie(beg, end) = controller().getRows();
78         QTextCursor c = QTextCursor(viewSourceTV->document());
79         c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, beg);
80         c.select(QTextCursor::BlockUnderCursor);
81         c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, end - beg + 1);
82         viewSourceTV->setTextCursor(c);
83         QWidget::update();
84 }
85
86
87 void GuiViewSourceDialog::update(bool full_source)
88 {
89         document_->setPlainText(toqstr(controller().updateContent(full_source)));
90 }
91
92
93
94 /////////////////////////////////////////////////////////////////////
95 //
96 // LaTeXHighlighter
97 //
98 /////////////////////////////////////////////////////////////////////
99
100
101 LaTeXHighlighter::LaTeXHighlighter(QTextDocument * parent)
102         : QSyntaxHighlighter(parent)
103 {
104         keywordFormat.setForeground(Qt::darkBlue);
105         keywordFormat.setFontWeight(QFont::Bold);
106         commentFormat.setForeground(Qt::darkGray);
107         mathFormat.setForeground(Qt::red);
108 }
109
110
111 void LaTeXHighlighter::highlightBlock(QString const & text)
112 {
113         // $ $
114         QRegExp exprMath("\\$[^\\$]*\\$");
115         int index = text.indexOf(exprMath);
116         while (index >= 0) {
117                 int length = exprMath.matchedLength();
118                 setFormat(index, length, mathFormat);
119                 index = text.indexOf(exprMath, index + length);
120         }
121         // [ ]
122         QRegExp exprStartDispMath("(\\\\\\[|"
123                 "\\\\begin\\{equation\\**\\}|"
124                 "\\\\begin\\{eqnarray\\**\\}|"
125                 "\\\\begin\\{align(ed|at)*\\**\\}|"
126                 "\\\\begin\\{flalign\\**\\}|"
127                 "\\\\begin\\{gather\\**\\}|"
128                 "\\\\begin\\{multline\\**\\}|"
129                 "\\\\begin\\{array\\**\\}|"
130                 "\\\\begin\\{cases\\**\\}"
131                 ")");
132         QRegExp exprEndDispMath("(\\\\\\]|"
133                 "\\\\end\\{equation\\**\\}|"
134                 "\\\\end\\{eqnarray\\**\\}|"
135                 "\\\\end\\{align(ed|at)*\\**\\}|"
136                 "\\\\end\\{flalign\\**\\}|"
137                 "\\\\end\\{gather\\**\\}|"
138                 "\\\\end\\{multline\\**\\}|"
139                 "\\\\end\\{array\\**\\}|"
140                 "\\\\end\\{cases\\**\\}"
141                 ")");
142         int startIndex = 0;
143         // if previous block was in 'disp math'
144         // start search from 0 (for end disp math)
145         // otherwise, start search from 'begin disp math'
146         if (previousBlockState() != 1)
147                 startIndex = text.indexOf(exprStartDispMath);
148         while (startIndex >= 0) {
149                 int endIndex = text.indexOf(exprEndDispMath, startIndex);
150                 int length;
151                 if (endIndex == -1) {
152                         setCurrentBlockState(1);
153                         length = text.length() - startIndex;
154                 } else {
155                         length = endIndex - startIndex + exprEndDispMath.matchedLength();
156                 }
157                 setFormat(startIndex, length, mathFormat);
158                 startIndex = text.indexOf(exprStartDispMath, startIndex + length);
159         }
160         // \whatever
161         QRegExp exprKeyword("\\\\[A-Za-z]+");
162         index = text.indexOf(exprKeyword);
163         while (index >= 0) {
164                 int length = exprKeyword.matchedLength();
165                 setFormat(index, length, keywordFormat);
166                 index = text.indexOf(exprKeyword, index + length);
167         }
168         // comment
169         QRegExp exprComment("(^|[^\\\\])%.*$");
170         index = text.indexOf(exprComment);
171         while (index >= 0) {
172                 int const length = exprComment.matchedLength();
173                 setFormat(index, length, commentFormat);
174                 index = text.indexOf(exprComment, index + length);
175         }
176 }
177
178
179 } // namespace frontend
180 } // namespace lyx
181
182 #include "GuiViewSource_moc.cpp"