2 * \file GuiViewSource.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * \author Abdelrazak Younes
10 * Full author contact details are available in file CREDITS.
15 #include "GuiApplication.h"
16 #include "GuiViewSource.h"
17 #include "LaTeXHighlighter.h"
18 #include "qt_helpers.h"
20 #include "BufferView.h"
23 #include "Paragraph.h"
26 #include "support/debug.h"
27 #include "support/lassert.h"
28 #include "support/docstream.h"
29 #include "support/gettext.h"
31 #include <boost/crc.hpp>
34 #include <QTextCursor>
35 #include <QTextDocument>
43 ViewSourceWidget::ViewSourceWidget()
44 : bv_(0), document_(new QTextDocument(this)),
45 highlighter_(new LaTeXHighlighter(document_))
49 connect(viewFullSourceCB, SIGNAL(clicked()),
50 this, SLOT(updateView()));
51 connect(autoUpdateCB, SIGNAL(toggled(bool)),
52 updatePB, SLOT(setDisabled(bool)));
53 connect(updatePB, SIGNAL(clicked()),
54 this, SLOT(updateView()));
56 // setting a document at this point trigger an assertion in Qt
57 // so we disable the signals here:
58 document_->blockSignals(true);
59 viewSourceTV->setDocument(document_);
60 document_->blockSignals(false);
61 viewSourceTV->setReadOnly(true);
62 ///dialog_->viewSourceTV->setAcceptRichText(false);
63 // this is personal. I think source code should be in fixed-size font
64 QFont font(guiApp->typewriterFontName());
65 font.setKerning(false);
66 font.setFixedPitch(true);
67 font.setStyleHint(QFont::TypeWriter);
68 viewSourceTV->setFont(font);
69 // again, personal taste
70 viewSourceTV->setWordWrapMode(QTextOption::NoWrap);
74 static size_t crcCheck(docstring const & s)
76 boost::crc_32_type crc;
77 crc.process_bytes(&s[0], sizeof(char_type) * s.size());
78 return crc.checksum();
82 /** get the source code of selected paragraphs, or the whole document
83 \param fullSource get full source code
84 \return true if the content has changed since last call.
86 static bool getContent(BufferView const * view, bool fullSource, QString & qstr)
88 // get the *top* level paragraphs that contain the cursor,
89 // or the selected text
93 if (!view->cursor().selection()) {
94 par_begin = view->cursor().bottom().pit();
97 par_begin = view->cursor().selectionBegin().bottom().pit();
98 par_end = view->cursor().selectionEnd().bottom().pit();
100 if (par_begin > par_end)
101 swap(par_begin, par_end);
102 odocstringstream ostr;
103 view->buffer().getSourceCode(ostr, par_begin, par_end + 1, fullSource);
104 docstring s = ostr.str();
105 static size_t crc = 0;
106 size_t newcrc = crcCheck(s);
115 void ViewSourceWidget::setBufferView(BufferView const * bv)
121 void ViewSourceWidget::updateView()
124 document_->setPlainText(QString());
130 if (getContent(bv_, viewFullSourceCB->isChecked(), content))
131 document_->setPlainText(content);
133 CursorSlice beg = bv_->cursor().selectionBegin().bottom();
134 CursorSlice end = bv_->cursor().selectionEnd().bottom();
135 int const begrow = bv_->buffer().texrow().
136 getRowFromIdPos(beg.paragraph().id(), beg.pos());
137 int endrow = bv_->buffer().texrow().
138 getRowFromIdPos(end.paragraph().id(), end.pos());
139 int const nextendrow = bv_->buffer().texrow().
140 getRowFromIdPos(end.paragraph().id(), end.pos() + 1);
141 if (endrow != nextendrow)
142 endrow = nextendrow - 1;
144 QTextCursor c = QTextCursor(viewSourceTV->document());
145 c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, begrow);
146 c.select(QTextCursor::BlockUnderCursor);
147 c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor,
148 endrow - begrow + 1);
149 viewSourceTV->setTextCursor(c);
153 GuiViewSource::GuiViewSource(GuiView & parent,
154 Qt::DockWidgetArea area, Qt::WindowFlags flags)
155 : DockView(parent, "view-source", qt_("LaTeX Source"), area, flags)
157 widget_ = new ViewSourceWidget();
162 GuiViewSource::~GuiViewSource()
168 void GuiViewSource::updateView()
170 if (widget_->autoUpdateCB->isChecked()) {
171 widget_->setBufferView(bufferview());
172 widget_->updateView();
177 void GuiViewSource::enableView(bool enable)
180 // In the opposite case, updateView() will be called anyway.
181 widget_->setBufferView(bufferview());
182 widget_->updateView();
184 widget_->setEnabled(enable);
188 bool GuiViewSource::initialiseParams(string const & /*source*/)
190 setWindowTitle(title());
195 QString GuiViewSource::title() const
199 return qt_("LaTeX Source");
201 return qt_("DocBook Source");
203 return qt_("Literate Source");
205 LASSERT(false, /**/);
210 void GuiViewSource::saveSession() const
212 Dialog::saveSession();
215 sessionKey() + "/fullsource", widget_->viewFullSourceCB->isChecked());
217 sessionKey() + "/autoupdate", widget_->autoUpdateCB->isChecked());
221 void GuiViewSource::restoreSession()
223 DockView::restoreSession();
224 // FIXME: Full source updating is too slow to be done at startup.
225 //widget_->viewFullSourceCB->setChecked(
226 // settings.value(sessionKey() + "/fullsource", false).toBool());
227 widget_->viewFullSourceCB->setChecked(false);
229 widget_->autoUpdateCB->setChecked(
230 settings.value(sessionKey() + "/autoupdate", true).toBool());
234 Dialog * createGuiViewSource(GuiView & lv)
236 return new GuiViewSource(lv);
240 } // namespace frontend
243 #include "GuiViewSource_moc.cpp"