X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiViewSource.cpp;h=a5beae5da691e673c05fa55d77e9ae9274527128;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=ef34dc5500b3bab9c2396efab43e1e5435c1d358;hpb=58f5bed05d75d56973398dac28899078f6e1242c;p=lyx.git diff --git a/src/frontends/qt4/GuiViewSource.cpp b/src/frontends/qt4/GuiViewSource.cpp index ef34dc5500..a5beae5da6 100644 --- a/src/frontends/qt4/GuiViewSource.cpp +++ b/src/frontends/qt4/GuiViewSource.cpp @@ -12,49 +12,58 @@ #include +#include "GuiApplication.h" #include "GuiViewSource.h" +#include "LaTeXHighlighter.h" #include "qt_helpers.h" -#include "Application.h" #include "BufferView.h" #include "Buffer.h" #include "Cursor.h" -#include "gettext.h" #include "Paragraph.h" #include "TexRow.h" +#include "support/debug.h" +#include "support/lassert.h" +#include "support/docstream.h" +#include "support/gettext.h" + +#include + +#include #include #include -#include +#include -using std::string; +using namespace std; namespace lyx { namespace frontend { -GuiViewSourceDialog::GuiViewSourceDialog(ControlViewSource & controller) - : controller_(controller), document_(new QTextDocument(this)), +ViewSourceWidget::ViewSourceWidget() + : bv_(0), document_(new QTextDocument(this)), highlighter_(new LaTeXHighlighter(document_)) { setupUi(this); - setWindowTitle(qt_("LaTeX Source")); connect(viewFullSourceCB, SIGNAL(clicked()), this, SLOT(updateView())); connect(autoUpdateCB, SIGNAL(toggled(bool)), updatePB, SLOT(setDisabled(bool))); + connect(autoUpdateCB, SIGNAL(toggled(bool)), + this, SLOT(updateView())); connect(updatePB, SIGNAL(clicked()), this, SLOT(updateView())); // setting a document at this point trigger an assertion in Qt // so we disable the signals here: - document()->blockSignals(true); - viewSourceTV->setDocument(document()); - document()->blockSignals(false); + document_->blockSignals(true); + viewSourceTV->setDocument(document_); + document_->blockSignals(false); viewSourceTV->setReadOnly(true); ///dialog_->viewSourceTV->setAcceptRichText(false); // this is personal. I think source code should be in fixed-size font - QFont font(toqstr(theApp()->typewriterFontName())); + QFont font(guiApp->typewriterFontName()); font.setKerning(false); font.setFixedPitch(true); font.setStyleHint(QFont::TypeWriter); @@ -64,187 +73,175 @@ GuiViewSourceDialog::GuiViewSourceDialog(ControlViewSource & controller) } -void GuiViewSourceDialog::updateView() +static size_t crcCheck(docstring const & s) { - if (autoUpdateCB->isChecked()) - update(viewFullSourceCB->isChecked()); - - int beg, end; - boost::tie(beg, end) = controller_.getRows(); - QTextCursor c = QTextCursor(viewSourceTV->document()); - c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, beg); - c.select(QTextCursor::BlockUnderCursor); - c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, end - beg + 1); - viewSourceTV->setTextCursor(c); - QWidget::update(); + boost::crc_32_type crc; + crc.process_bytes(&s[0], sizeof(char_type) * s.size()); + return crc.checksum(); } -void GuiViewSourceDialog::update(bool full_source) +/** get the source code of selected paragraphs, or the whole document + \param fullSource get full source code + \return true if the content has changed since last call. + */ +static bool getContent(BufferView const * view, bool fullSource, QString & qstr) { - document_->setPlainText(toqstr(controller_.updateContent(full_source))); -} - - + // get the *top* level paragraphs that contain the cursor, + // or the selected text + pit_type par_begin; + pit_type par_end; -///////////////////////////////////////////////////////////////////// -// -// LaTeXHighlighter -// -///////////////////////////////////////////////////////////////////// + if (!view->cursor().selection()) { + par_begin = view->cursor().bottom().pit(); + par_end = par_begin; + } else { + par_begin = view->cursor().selectionBegin().bottom().pit(); + par_end = view->cursor().selectionEnd().bottom().pit(); + } + if (par_begin > par_end) + swap(par_begin, par_end); + odocstringstream ostr; + view->buffer().getSourceCode(ostr, par_begin, par_end + 1, fullSource); + docstring s = ostr.str(); + static size_t crc = 0; + size_t newcrc = crcCheck(s); + if (newcrc == crc) + return false; + crc = newcrc; + qstr = toqstr(s); + return true; +} -LaTeXHighlighter::LaTeXHighlighter(QTextDocument * parent) - : QSyntaxHighlighter(parent) +void ViewSourceWidget::setBufferView(BufferView const * bv) { - keywordFormat.setForeground(Qt::darkBlue); - keywordFormat.setFontWeight(QFont::Bold); - commentFormat.setForeground(Qt::darkGray); - mathFormat.setForeground(Qt::red); + bv_ = bv; + setEnabled(bv ? true : false); } -void LaTeXHighlighter::highlightBlock(QString const & text) +void ViewSourceWidget::updateView() { - // $ $ - QRegExp exprMath("\\$[^\\$]*\\$"); - int index = text.indexOf(exprMath); - while (index >= 0) { - int length = exprMath.matchedLength(); - setFormat(index, length, mathFormat); - index = text.indexOf(exprMath, index + length); - } - // [ ] - QRegExp exprStartDispMath("(\\\\\\[|" - "\\\\begin\\{equation\\**\\}|" - "\\\\begin\\{eqnarray\\**\\}|" - "\\\\begin\\{align(ed|at)*\\**\\}|" - "\\\\begin\\{flalign\\**\\}|" - "\\\\begin\\{gather\\**\\}|" - "\\\\begin\\{multline\\**\\}|" - "\\\\begin\\{array\\**\\}|" - "\\\\begin\\{cases\\**\\}" - ")"); - QRegExp exprEndDispMath("(\\\\\\]|" - "\\\\end\\{equation\\**\\}|" - "\\\\end\\{eqnarray\\**\\}|" - "\\\\end\\{align(ed|at)*\\**\\}|" - "\\\\end\\{flalign\\**\\}|" - "\\\\end\\{gather\\**\\}|" - "\\\\end\\{multline\\**\\}|" - "\\\\end\\{array\\**\\}|" - "\\\\end\\{cases\\**\\}" - ")"); - int startIndex = 0; - // if previous block was in 'disp math' - // start search from 0 (for end disp math) - // otherwise, start search from 'begin disp math' - if (previousBlockState() != 1) - startIndex = text.indexOf(exprStartDispMath); - while (startIndex >= 0) { - int endIndex = text.indexOf(exprEndDispMath, startIndex); - int length; - if (endIndex == -1) { - setCurrentBlockState(1); - length = text.length() - startIndex; - } else { - length = endIndex - startIndex + exprEndDispMath.matchedLength(); - } - setFormat(startIndex, length, mathFormat); - startIndex = text.indexOf(exprStartDispMath, startIndex + length); - } - // \whatever - QRegExp exprKeyword("\\\\[A-Za-z]+"); - index = text.indexOf(exprKeyword); - while (index >= 0) { - int length = exprKeyword.matchedLength(); - setFormat(index, length, keywordFormat); - index = text.indexOf(exprKeyword, index + length); + if (!bv_) { + document_->setPlainText(QString()); + setEnabled(false); + return; } - // comment - QRegExp exprComment("(^|[^\\\\])%.*$"); - index = text.indexOf(exprComment); - while (index >= 0) { - int const length = exprComment.matchedLength(); - setFormat(index, length, commentFormat); - index = text.indexOf(exprComment, index + length); - } -} + + setEnabled(true); + QString content; + if (getContent(bv_, viewFullSourceCB->isChecked(), content)) + document_->setPlainText(content); + + CursorSlice beg = bv_->cursor().selectionBegin().bottom(); + CursorSlice end = bv_->cursor().selectionEnd().bottom(); + int const begrow = bv_->buffer().texrow(). + getRowFromIdPos(beg.paragraph().id(), beg.pos()); + int endrow = bv_->buffer().texrow(). + getRowFromIdPos(end.paragraph().id(), end.pos()); + int const nextendrow = bv_->buffer().texrow(). + getRowFromIdPos(end.paragraph().id(), end.pos() + 1); + if (endrow != nextendrow) + endrow = nextendrow - 1; -ControlViewSource::ControlViewSource(Dialog & parent) - : Controller(parent) -{} + QTextCursor c = QTextCursor(viewSourceTV->document()); + c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, begrow); + c.select(QTextCursor::BlockUnderCursor); + c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, + endrow - begrow + 1); + viewSourceTV->setTextCursor(c); +} -bool ControlViewSource::initialiseParams(string const & /*source*/) +GuiViewSource::GuiViewSource(GuiView & parent, + Qt::DockWidgetArea area, Qt::WindowFlags flags) + : DockView(parent, "view-source", qt_("LaTeX Source"), area, flags) { - return true; + widget_ = new ViewSourceWidget(); + setWidget(widget_); } -docstring const ControlViewSource::updateContent(bool fullSource) +GuiViewSource::~GuiViewSource() { - // get the *top* level paragraphs that contain the cursor, - // or the selected text - pit_type par_begin; - pit_type par_end; + delete widget_; +} - BufferView * view = bufferview(); - if (!view->cursor().selection()) { - par_begin = view->cursor().bottom().pit(); - par_end = par_begin; - } else { - par_begin = view->cursor().selectionBegin().bottom().pit(); - par_end = view->cursor().selectionEnd().bottom().pit(); + +void GuiViewSource::updateView() +{ + if (widget_->autoUpdateCB->isChecked()) { + widget_->setBufferView(bufferview()); + widget_->updateView(); } - if (par_begin > par_end) - std::swap(par_begin, par_end); - odocstringstream ostr; - view->buffer().getSourceCode(ostr, par_begin, par_end + 1, fullSource); - return ostr.str(); } -std::pair ControlViewSource::getRows() const +void GuiViewSource::enableView(bool enable) { - BufferView const * view = bufferview(); - CursorSlice beg = view->cursor().selectionBegin().bottom(); - CursorSlice end = view->cursor().selectionEnd().bottom(); + widget_->setBufferView(bufferview()); + if (!enable) + // In the opposite case, updateView() will be called anyway. + widget_->updateView(); +} - int begrow = view->buffer().texrow(). - getRowFromIdPos(beg.paragraph().id(), beg.pos()); - int endrow = view->buffer().texrow(). - getRowFromIdPos(end.paragraph().id(), end.pos()); - int nextendrow = view->buffer().texrow(). - getRowFromIdPos(end.paragraph().id(), end.pos() + 1); - return std::make_pair(begrow, endrow == nextendrow ? endrow : (nextendrow - 1)); + +bool GuiViewSource::initialiseParams(string const & /*source*/) +{ + setWindowTitle(title()); + return true; } -docstring const ControlViewSource::title() const +QString GuiViewSource::title() const { switch (docType()) { case LATEX: - return _("LaTeX Source"); + return qt_("LaTeX Source"); case DOCBOOK: - return _("DocBook Source"); + return qt_("DocBook Source"); case LITERATE: - return _("Literate Source"); - default: - BOOST_ASSERT(false); - return docstring(); + return qt_("Literate Source"); } + LASSERT(false, /**/); + return QString(); +} + + +void GuiViewSource::saveSession() const +{ + Dialog::saveSession(); + QSettings settings; + settings.setValue( + sessionKey() + "/fullsource", widget_->viewFullSourceCB->isChecked()); + settings.setValue( + sessionKey() + "/autoupdate", widget_->autoUpdateCB->isChecked()); +} + + +void GuiViewSource::restoreSession() +{ + DockView::restoreSession(); + // FIXME: Full source updating is too slow to be done at startup. + //widget_->viewFullSourceCB->setChecked( + // settings.value(sessionKey() + "/fullsource", false).toBool()); + widget_->viewFullSourceCB->setChecked(false); + QSettings settings; + widget_->autoUpdateCB->setChecked( + settings.value(sessionKey() + "/autoupdate", true).toBool()); + widget_->updateView(); } -Dialog * createGuiViewSource(LyXView & lv) +Dialog * createGuiViewSource(GuiView & lv) { - return new GuiViewSource(static_cast(lv)); + return new GuiViewSource(lv); } } // namespace frontend } // namespace lyx -#include "GuiViewSource_moc.cpp" +#include "moc_GuiViewSource.cpp"