]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiViewSource.cpp
991877bea773f3118ad32525cff8f44a0631b369
[lyx.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 "GuiApplication.h"
16 #include "GuiViewSource.h"
17 #include "LaTeXHighlighter.h"
18 #include "qt_helpers.h"
19
20 #include "BufferView.h"
21 #include "Buffer.h"
22 #include "Cursor.h"
23 #include "Paragraph.h"
24 #include "TexRow.h"
25
26 #include "support/Debug.h"
27 #include "support/lassert.h"
28 #include "support/docstream.h"
29 #include "support/gettext.h"
30
31 #include <QSettings>
32 #include <QTextCursor>
33 #include <QTextDocument>
34 #include <QVariant>
35
36 using namespace std;
37
38 namespace lyx {
39 namespace frontend {
40
41 ViewSourceWidget::ViewSourceWidget()
42         :       bv_(0), document_(new QTextDocument(this)),
43                 highlighter_(new LaTeXHighlighter(document_))
44 {
45         setupUi(this);
46
47         connect(viewFullSourceCB, SIGNAL(clicked()),
48                 this, SLOT(updateView()));
49         connect(autoUpdateCB, SIGNAL(toggled(bool)),
50                 updatePB, SLOT(setDisabled(bool)));
51         connect(updatePB, SIGNAL(clicked()),
52                 this, SLOT(updateView()));
53
54         // setting a document at this point trigger an assertion in Qt
55         // so we disable the signals here:
56         document_->blockSignals(true);
57         viewSourceTV->setDocument(document_);
58         document_->blockSignals(false);
59         viewSourceTV->setReadOnly(true);
60         ///dialog_->viewSourceTV->setAcceptRichText(false);
61         // this is personal. I think source code should be in fixed-size font
62         QFont font(guiApp->typewriterFontName());
63         font.setKerning(false);
64         font.setFixedPitch(true);
65         font.setStyleHint(QFont::TypeWriter);
66         viewSourceTV->setFont(font);
67         // again, personal taste
68         viewSourceTV->setWordWrapMode(QTextOption::NoWrap);
69 }
70
71
72 /** get the source code of selected paragraphs, or the whole document
73         \param fullSource get full source code
74  */
75 static QString getContent(BufferView const * view, bool fullSource)
76 {
77         // get the *top* level paragraphs that contain the cursor,
78         // or the selected text
79         pit_type par_begin;
80         pit_type par_end;
81
82         if (!view->cursor().selection()) {
83                 par_begin = view->cursor().bottom().pit();
84                 par_end = par_begin;
85         } else {
86                 par_begin = view->cursor().selectionBegin().bottom().pit();
87                 par_end = view->cursor().selectionEnd().bottom().pit();
88         }
89         if (par_begin > par_end)
90                 swap(par_begin, par_end);
91         odocstringstream ostr;
92         view->buffer().getSourceCode(ostr, par_begin, par_end + 1, fullSource);
93         return toqstr(ostr.str());
94 }
95
96
97 void ViewSourceWidget::setBufferView(BufferView const * bv)
98 {
99         bv_ = bv;
100 }
101
102
103 void ViewSourceWidget::updateView()
104 {
105         if (!bv_) {
106                 document_->setPlainText(QString());
107                 setEnabled(false);
108                 return;
109         }
110
111         document_->setPlainText(getContent(bv_, viewFullSourceCB->isChecked()));
112
113         CursorSlice beg = bv_->cursor().selectionBegin().bottom();
114         CursorSlice end = bv_->cursor().selectionEnd().bottom();
115         int const begrow = bv_->buffer().texrow().
116                 getRowFromIdPos(beg.paragraph().id(), beg.pos());
117         int endrow = bv_->buffer().texrow().
118                 getRowFromIdPos(end.paragraph().id(), end.pos());
119         int const nextendrow = bv_->buffer().texrow().
120                 getRowFromIdPos(end.paragraph().id(), end.pos() + 1);
121         if (endrow != nextendrow)
122                 endrow = nextendrow - 1;
123
124         QTextCursor c = QTextCursor(viewSourceTV->document());
125         c.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, begrow);
126         c.select(QTextCursor::BlockUnderCursor);
127         c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor,
128                 endrow - begrow + 1);
129         viewSourceTV->setTextCursor(c);
130 }
131
132
133 GuiViewSource::GuiViewSource(GuiView & parent,
134                 Qt::DockWidgetArea area, Qt::WindowFlags flags)
135         : DockView(parent, "view-source", qt_("LaTeX Source"), area, flags)
136 {
137         widget_ = new ViewSourceWidget();
138         setWidget(widget_);
139 }
140
141
142 GuiViewSource::~GuiViewSource()
143 {
144         delete widget_;
145 }
146
147
148 void GuiViewSource::updateView()
149 {
150         if (widget_->autoUpdateCB->isChecked()) {
151                 widget_->setBufferView(bufferview());
152                 widget_->updateView();
153         }
154 }
155
156
157 void GuiViewSource::enableView(bool enable)
158 {
159         if (!enable) {
160                 // In the opposite case, updateView() will be called anyway.
161                 widget_->setBufferView(bufferview());
162                 widget_->updateView();
163         }
164         widget_->setEnabled(enable);
165 }
166
167
168 bool GuiViewSource::initialiseParams(string const & /*source*/)
169 {
170         setWindowTitle(title());
171         return true;
172 }
173
174
175 QString GuiViewSource::title() const
176 {
177         switch (docType()) {
178                 case LATEX:
179                         return qt_("LaTeX Source");
180                 case DOCBOOK:
181                         return qt_("DocBook Source");
182                 case LITERATE:
183                         return qt_("Literate Source");
184         }
185         LASSERT(false, /**/);
186         return QString();
187 }
188
189
190 void GuiViewSource::saveSession() const
191 {
192         Dialog::saveSession();
193         QSettings settings;
194         settings.setValue(
195                 sessionKey() + "/fullsource", widget_->viewFullSourceCB->isChecked());
196         settings.setValue(
197                 sessionKey() + "/autoupdate", widget_->autoUpdateCB->isChecked());
198 }
199
200
201 void GuiViewSource::restoreSession()
202 {
203         DockView::restoreSession();
204         // FIXME: Full source updating is too slow to be done at startup.
205         //widget_->viewFullSourceCB->setChecked(
206         //      settings.value(sessionKey() + "/fullsource", false).toBool());
207         widget_->viewFullSourceCB->setChecked(false);
208         QSettings settings;
209         widget_->autoUpdateCB->setChecked(
210                 settings.value(sessionKey() + "/autoupdate", true).toBool());
211 }
212
213
214 Dialog * createGuiViewSource(GuiView & lv)
215 {
216         return new GuiViewSource(lv);
217 }
218
219
220 } // namespace frontend
221 } // namespace lyx
222
223 #include "GuiViewSource_moc.cpp"