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(autoUpdateCB, SIGNAL(toggled(bool)),
54 this, SLOT(updateView()));
55 connect(updatePB, SIGNAL(clicked()),
56 this, SLOT(updateView()));
58 // setting a document at this point trigger an assertion in Qt
59 // so we disable the signals here:
60 document_->blockSignals(true);
61 viewSourceTV->setDocument(document_);
62 document_->blockSignals(false);
63 viewSourceTV->setReadOnly(true);
64 ///dialog_->viewSourceTV->setAcceptRichText(false);
65 // this is personal. I think source code should be in fixed-size font
66 QFont font(guiApp->typewriterFontName());
67 font.setKerning(false);
68 font.setFixedPitch(true);
69 font.setStyleHint(QFont::TypeWriter);
70 viewSourceTV->setFont(font);
71 // again, personal taste
72 viewSourceTV->setWordWrapMode(QTextOption::NoWrap);
76 static size_t crcCheck(docstring const & s)
78 boost::crc_32_type crc;
79 crc.process_bytes(&s[0], sizeof(char_type) * s.size());
80 return crc.checksum();
84 /** get the source code of selected paragraphs, or the whole document
85 \param fullSource get full source code
86 \return true if the content has changed since last call.
88 static bool getContent(BufferView const * view, bool fullSource, QString & qstr)
90 // get the *top* level paragraphs that contain the cursor,
91 // or the selected text
95 if (!view->cursor().selection()) {
96 par_begin = view->cursor().bottom().pit();
99 par_begin = view->cursor().selectionBegin().bottom().pit();
100 par_end = view->cursor().selectionEnd().bottom().pit();
102 if (par_begin > par_end)
103 swap(par_begin, par_end);
104 odocstringstream ostr;
105 const_cast<BufferView *>(view)->buffer().getSourceCode(
106 ostr, par_begin, par_end + 1, fullSource);
107 docstring s = ostr.str();
108 static size_t crc = 0;
109 size_t newcrc = crcCheck(s);
118 void ViewSourceWidget::setBufferView(BufferView const * bv)
121 setEnabled(bv ? true : false);
125 void ViewSourceWidget::updateView()
128 document_->setPlainText(QString());
136 if (getContent(bv_, viewFullSourceCB->isChecked(), content))
137 document_->setPlainText(content);
139 CursorSlice beg = bv_->cursor().selectionBegin().bottom();
140 CursorSlice end = bv_->cursor().selectionEnd().bottom();
141 int const begrow = bv_->buffer().texrow().
142 getRowFromIdPos(beg.paragraph().id(), beg.pos());
143 int endrow = bv_->buffer().texrow().
144 getRowFromIdPos(end.paragraph().id(), end.pos());
145 int const nextendrow = bv_->buffer().texrow().
146 getRowFromIdPos(end.paragraph().id(), end.pos() + 1);
147 if (endrow != nextendrow)
148 endrow = nextendrow - 1;
150 QTextCursor c = QTextCursor(viewSourceTV->document());
151 c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, begrow);
152 c.select(QTextCursor::BlockUnderCursor);
153 c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor,
154 endrow - begrow + 1);
155 viewSourceTV->setTextCursor(c);
159 GuiViewSource::GuiViewSource(GuiView & parent,
160 Qt::DockWidgetArea area, Qt::WindowFlags flags)
161 : DockView(parent, "view-source", qt_("LaTeX Source"), area, flags)
163 widget_ = new ViewSourceWidget();
168 GuiViewSource::~GuiViewSource()
174 void GuiViewSource::updateView()
176 if (widget_->autoUpdateCB->isChecked()) {
177 widget_->setBufferView(bufferview());
178 widget_->updateView();
183 void GuiViewSource::enableView(bool enable)
185 widget_->setBufferView(bufferview());
187 // In the opposite case, updateView() will be called anyway.
188 widget_->updateView();
192 bool GuiViewSource::initialiseParams(string const & /*source*/)
194 setWindowTitle(title());
199 QString GuiViewSource::title() const
203 return qt_("LaTeX Source");
205 return qt_("DocBook Source");
207 return qt_("Literate Source");
209 LASSERT(false, /**/);
214 void GuiViewSource::saveSession() const
216 Dialog::saveSession();
219 sessionKey() + "/fullsource", widget_->viewFullSourceCB->isChecked());
221 sessionKey() + "/autoupdate", widget_->autoUpdateCB->isChecked());
225 void GuiViewSource::restoreSession()
227 DockView::restoreSession();
228 // FIXME: Full source updating is too slow to be done at startup.
229 //widget_->viewFullSourceCB->setChecked(
230 // settings.value(sessionKey() + "/fullsource", false).toBool());
231 widget_->viewFullSourceCB->setChecked(false);
233 widget_->autoUpdateCB->setChecked(
234 settings.value(sessionKey() + "/autoupdate", true).toBool());
235 widget_->updateView();
239 Dialog * createGuiViewSource(GuiView & lv)
241 return new GuiViewSource(lv);
245 } // namespace frontend
248 #include "moc_GuiViewSource.cpp"