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"
24 #include "Paragraph.h"
27 #include "support/debug.h"
28 #include "support/lassert.h"
29 #include "support/docstream.h"
30 #include "support/gettext.h"
32 #include <boost/crc.hpp>
35 #include <QTextCursor>
36 #include <QTextDocument>
44 ViewSourceWidget::ViewSourceWidget()
45 : bv_(0), document_(new QTextDocument(this)),
46 highlighter_(new LaTeXHighlighter(document_))
50 connect(viewFullSourceCB, SIGNAL(clicked()),
51 this, SLOT(updateView()));
52 connect(autoUpdateCB, SIGNAL(toggled(bool)),
53 updatePB, SLOT(setDisabled(bool)));
54 connect(autoUpdateCB, SIGNAL(toggled(bool)),
55 this, SLOT(updateView()));
56 connect(updatePB, SIGNAL(clicked()),
57 this, SLOT(updateView()));
58 connect(outputFormatCO, SIGNAL(activated(int)),
59 this, SLOT(updateView()));
61 // setting a document at this point trigger an assertion in Qt
62 // so we disable the signals here:
63 document_->blockSignals(true);
64 viewSourceTV->setDocument(document_);
65 document_->blockSignals(false);
66 viewSourceTV->setReadOnly(true);
67 ///dialog_->viewSourceTV->setAcceptRichText(false);
68 // this is personal. I think source code should be in fixed-size font
69 QFont font(guiApp->typewriterFontName());
70 font.setKerning(false);
71 font.setFixedPitch(true);
72 font.setStyleHint(QFont::TypeWriter);
73 viewSourceTV->setFont(font);
74 // again, personal taste
75 viewSourceTV->setWordWrapMode(QTextOption::NoWrap);
79 static size_t crcCheck(docstring const & s)
81 boost::crc_32_type crc;
82 crc.process_bytes(&s[0], sizeof(char_type) * s.size());
83 return crc.checksum();
87 /** get the source code of selected paragraphs, or the whole document
88 \param fullSource get full source code
89 \return true if the content has changed since last call.
91 static bool getContent(BufferView const * view, bool fullSource,
92 QString & qstr, string const format)
94 // get the *top* level paragraphs that contain the cursor,
95 // or the selected text
99 if (!view->cursor().selection()) {
100 par_begin = view->cursor().bottom().pit();
103 par_begin = view->cursor().selectionBegin().bottom().pit();
104 par_end = view->cursor().selectionEnd().bottom().pit();
106 if (par_begin > par_end)
107 swap(par_begin, par_end);
108 odocstringstream ostr;
109 view->buffer().getSourceCode(ostr, format, par_begin, par_end + 1, fullSource);
110 docstring s = ostr.str();
111 static size_t crc = 0;
112 size_t newcrc = crcCheck(s);
121 void ViewSourceWidget::setBufferView(BufferView const * bv)
124 setEnabled(bv ? true : false);
128 void ViewSourceWidget::updateView()
131 document_->setPlainText(QString());
138 string const format = fromqstr(outputFormatCO->itemData(
139 outputFormatCO->currentIndex()).toString());
142 if (getContent(bv_, viewFullSourceCB->isChecked(), content, format))
143 document_->setPlainText(content);
145 CursorSlice beg = bv_->cursor().selectionBegin().bottom();
146 CursorSlice end = bv_->cursor().selectionEnd().bottom();
147 int const begrow = bv_->buffer().texrow().
148 getRowFromIdPos(beg.paragraph().id(), beg.pos());
149 int endrow = bv_->buffer().texrow().
150 getRowFromIdPos(end.paragraph().id(), end.pos());
151 int const nextendrow = bv_->buffer().texrow().
152 getRowFromIdPos(end.paragraph().id(), end.pos() + 1);
153 if (endrow != nextendrow)
154 endrow = nextendrow - 1;
156 QTextCursor c = QTextCursor(viewSourceTV->document());
157 c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, begrow);
158 c.select(QTextCursor::BlockUnderCursor);
159 c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor,
160 endrow - begrow + 1);
161 viewSourceTV->setTextCursor(c);
165 void ViewSourceWidget::updateDefaultFormat()
170 outputFormatCO->blockSignals(true);
171 outputFormatCO->clear();
172 outputFormatCO->addItem(qt_("Default"),
173 QVariant(QString("default")));
174 typedef vector<Format const *> Formats;
175 Formats formats = bv_->buffer().exportableFormats(true);
176 Formats::const_iterator cit = formats.begin();
177 Formats::const_iterator end = formats.end();
178 for (; cit != end; ++cit)
179 outputFormatCO->addItem(qt_((*cit)->prettyname()),
180 QVariant(toqstr((*cit)->name())));
181 outputFormatCO->blockSignals(false);
185 GuiViewSource::GuiViewSource(GuiView & parent,
186 Qt::DockWidgetArea area, Qt::WindowFlags flags)
187 : DockView(parent, "view-source", qt_("LaTeX Source"), area, flags)
189 widget_ = new ViewSourceWidget();
194 GuiViewSource::~GuiViewSource()
200 void GuiViewSource::updateView()
202 if (widget_->autoUpdateCB->isChecked()) {
203 widget_->setBufferView(bufferview());
204 widget_->updateView();
209 void GuiViewSource::enableView(bool enable)
211 widget_->setBufferView(bufferview());
212 widget_->updateDefaultFormat();
214 // In the opposite case, updateView() will be called anyway.
215 widget_->updateView();
219 bool GuiViewSource::initialiseParams(string const & /*source*/)
221 setWindowTitle(title());
226 QString GuiViewSource::title() const
230 return qt_("LaTeX Source");
232 return qt_("DocBook Source");
234 return qt_("Literate Source");
236 LASSERT(false, /**/);
241 void GuiViewSource::saveSession() const
243 Dialog::saveSession();
246 sessionKey() + "/fullsource", widget_->viewFullSourceCB->isChecked());
248 sessionKey() + "/autoupdate", widget_->autoUpdateCB->isChecked());
252 void GuiViewSource::restoreSession()
254 DockView::restoreSession();
255 // FIXME: Full source updating is too slow to be done at startup.
256 //widget_->viewFullSourceCB->setChecked(
257 // settings.value(sessionKey() + "/fullsource", false).toBool());
258 widget_->viewFullSourceCB->setChecked(false);
260 widget_->autoUpdateCB->setChecked(
261 settings.value(sessionKey() + "/autoupdate", true).toBool());
262 widget_->updateView();
266 Dialog * createGuiViewSource(GuiView & lv)
268 return new GuiViewSource(lv);
272 } // namespace frontend
275 #include "moc_GuiViewSource.cpp"