2 Description: file viewer window
4 Author: Marco Costalba (C) 2005-2007
6 Copyright: See COPYING file that comes with this distribution
14 #include "filecontent.h"
17 #define MAX_LINE_NUM 5
19 FileView::FileView(MainImpl
* mi
, Git
* g
) : Domain(mi
, g
, false) {
21 fileTab
= new Ui_TabFile();
22 fileTab
->setupUi(container
);
23 fileTab
->histListView
->setup(this, git
);
24 fileTab
->textEditFile
->setup(this, git
, fileTab
->listWidgetAnn
);
26 // an empty string turn off the special-value text display
27 fileTab
->spinBoxRevision
->setSpecialValueText(" ");
29 // Add GNU source-highlight version to tooltip, or add a message that it's not installed.
30 QToolButton
* highlight
= fileTab
->toolButtonHighlightText
;
31 highlight
->setToolTip(highlight
->toolTip().arg(git
->textHighlighterVersion()));
33 clear(true); // init some stuff
35 fileTab
->listWidgetAnn
->installEventFilter(this);
37 connect(git
, SIGNAL(loadCompleted(const FileHistory
*, const QString
&)),
38 this, SLOT(on_loadCompleted(const FileHistory
*, const QString
&)));
40 connect(m(), SIGNAL(changeFont(const QFont
&)),
41 fileTab
->histListView
, SLOT(on_changeFont(const QFont
&)));
43 connect(fileTab
->histListView
, SIGNAL(contextMenu(const QString
&, int)),
44 this, SLOT(on_contextMenu(const QString
&, int)));
46 connect(fileTab
->textEditFile
, SIGNAL(annotationAvailable(bool)),
47 this, SLOT(on_annotationAvailable(bool)));
49 connect(fileTab
->textEditFile
, SIGNAL(fileAvailable(bool)),
50 this, SLOT(on_fileAvailable(bool)));
52 connect(fileTab
->textEditFile
, SIGNAL(revIdSelected(int)),
53 this, SLOT(on_revIdSelected(int)));
55 connect(fileTab
->toolButtonCopy
, SIGNAL(clicked()),
56 this, SLOT(on_toolButtonCopy_clicked()));
58 connect(fileTab
->toolButtonShowAnnotate
, SIGNAL(toggled(bool)),
59 this, SLOT(on_toolButtonShowAnnotate_toggled(bool)));
61 connect(fileTab
->toolButtonFindAnnotate
, SIGNAL(toggled(bool)),
62 this, SLOT(on_toolButtonFindAnnotate_toggled(bool)));
64 connect(fileTab
->toolButtonGoNext
, SIGNAL(clicked()),
65 this, SLOT(on_toolButtonGoNext_clicked()));
67 connect(fileTab
->toolButtonGoPrev
, SIGNAL(clicked()),
68 this, SLOT(on_toolButtonGoPrev_clicked()));
70 connect(fileTab
->toolButtonRangeFilter
, SIGNAL(toggled(bool)),
71 this, SLOT(on_toolButtonRangeFilter_toggled(bool)));
73 connect(fileTab
->toolButtonPin
, SIGNAL(toggled(bool)),
74 this, SLOT(on_toolButtonPin_toggled(bool)));
76 connect(fileTab
->toolButtonHighlightText
, SIGNAL(toggled(bool)),
77 this, SLOT(on_toolButtonHighlightText_toggled(bool)));
79 connect(fileTab
->spinBoxRevision
, SIGNAL(valueChanged(int)),
80 this, SLOT(on_spinBoxRevision_valueChanged(int)));
83 FileView::~FileView() {
88 delete fileTab
->textEditFile
; // must be deleted before fileTab
90 showStatusBarMessage(""); // cleanup any pending progress info
91 QApplication::restoreOverrideCursor();
94 bool FileView::eventFilter(QObject
* obj
, QEvent
* e
) {
96 QListWidget
* lw
= fileTab
->listWidgetAnn
;
97 if (e
->type() == QEvent::ToolTip
&& obj
== lw
) {
98 QHelpEvent
* h
= static_cast<QHelpEvent
*>(e
);
99 int id
= fileTab
->textEditFile
->itemAnnId(lw
->itemAt(h
->pos()));
101 SCRef
sha(fileTab
->histListView
->shaFromAnnId(id
));
102 SCRef
d(git
->getDesc(sha
, re
, re
, false, model()));
105 return QObject::eventFilter(obj
, e
);
108 void FileView::clear(bool complete
) {
110 Domain::clear(complete
);
113 setTabCaption("File");
114 fileTab
->toolButtonCopy
->setEnabled(false);
116 fileTab
->textEditFile
->clearAll(); // emits file/ann available signals
118 fileTab
->toolButtonPin
->setEnabled(false);
119 fileTab
->toolButtonPin
->setChecked(false); // TODO signals pressed() and clicked() are not emitted
120 fileTab
->spinBoxRevision
->setEnabled(false);
121 fileTab
->spinBoxRevision
->setValue(fileTab
->spinBoxRevision
->minimum()); // clears the box
124 bool FileView::goToCurrentAnnotation(int direction
) {
126 SCRef ids
= fileTab
->histListView
->currentText(QGit::ANN_ID_COL
);
127 int id
= (!ids
.isEmpty() ? ids
.toInt() : 0);
128 fileTab
->textEditFile
->goToAnnotation(id
, direction
);
132 void FileView::updateSpinBoxValue() {
134 SCRef ids
= fileTab
->histListView
->currentText(QGit::ANN_ID_COL
);
136 || !fileTab
->spinBoxRevision
->isEnabled()
137 || fileTab
->spinBoxRevision
->value() == ids
.toInt())
140 fileTab
->spinBoxRevision
->setValue(ids
.toInt()); // emit QSpinBox::valueChanged()
143 bool FileView::isMatch(SCRef sha
) {
145 static RangeInfo r
; // fast path here, avoid allocation on each call
146 if (!fileTab
->textEditFile
->getRange(sha
, &r
))
152 void FileView::filterOnRange(bool isOn
) {
154 int matchedCnt
= fileTab
->histListView
->filterRows(isOn
, false);
157 msg
= QString("Found %1 matches. Toggle filter "
158 "button to remove the filter").arg(matchedCnt
);
160 showStatusBarMessage(msg
);
161 QApplication::postEvent(this, new MessageEvent(msg
)); // deferred message, after update
164 bool FileView::doUpdate(bool force
) {
166 if (st
.fileName().isEmpty())
169 if (st
.isChanged(StateInfo::FILE_NAME
) || force
) {
172 setTabCaption(st
.fileName());
174 if (git
->startFileHistory(st
.sha(), st
.fileName(), model())) {
175 QApplication::restoreOverrideCursor();
176 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor
));
177 showStatusBarMessage("Retrieving history of '" +
178 st
.fileName() + "'...");
180 } else if (fileTab
->histListView
->update() || st
.sha().isEmpty()) {
182 updateSpinBoxValue();
183 showStatusBarMessage(git
->getRevInfo(st
.sha()));
185 if (!fileTab
->toolButtonPin
->isChecked())
186 fileTab
->textEditFile
->doUpdate();
188 return true; // always accept new state
191 // ************************************ SLOTS ********************************
193 void FileView::updateEnabledButtons() {
195 QToolButton
* copy
= fileTab
->toolButtonCopy
;
196 QToolButton
* showAnnotate
= fileTab
->toolButtonShowAnnotate
;
197 QToolButton
* findAnnotate
= fileTab
->toolButtonFindAnnotate
;
198 QToolButton
* goPrev
= fileTab
->toolButtonGoPrev
;
199 QToolButton
* goNext
= fileTab
->toolButtonGoNext
;
200 QToolButton
* rangeFilter
= fileTab
->toolButtonRangeFilter
;
201 QToolButton
* highlight
= fileTab
->toolButtonHighlightText
;
203 bool fileAvailable
= fileTab
->textEditFile
->isFileAvailable();
204 bool annotateAvailable
= fileTab
->textEditFile
->isAnnotateAvailable();
207 copy
->setEnabled(fileAvailable
);
208 showAnnotate
->setEnabled(annotateAvailable
);
209 findAnnotate
->setEnabled(annotateAvailable
);
210 goPrev
->setEnabled(annotateAvailable
);
211 goNext
->setEnabled(annotateAvailable
);
212 rangeFilter
->setEnabled(annotateAvailable
);
213 highlight
->setEnabled(fileAvailable
&& git
->isTextHighlighter());
216 if (!showAnnotate
->isChecked()) {
217 findAnnotate
->setEnabled(false);
218 goPrev
->setEnabled(false);
219 goNext
->setEnabled(false);
221 if (highlight
->isChecked())
222 rangeFilter
->setEnabled(false);
224 if (rangeFilter
->isChecked())
225 highlight
->setEnabled(false);
227 // special case: reset range filter when changing file
228 if (!annotateAvailable
&& rangeFilter
->isChecked())
229 rangeFilter
->toggle();
232 void FileView::on_toolButtonCopy_clicked() {
234 fileTab
->textEditFile
->copySelection();
237 void FileView::on_toolButtonShowAnnotate_toggled(bool b
) {
239 updateEnabledButtons();
240 fileTab
->textEditFile
->setShowAnnotate(b
);
242 if (b
&& fileTab
->toolButtonFindAnnotate
->isChecked())
243 goToCurrentAnnotation();
246 void FileView::on_toolButtonFindAnnotate_toggled(bool b
) {
248 updateEnabledButtons();
250 goToCurrentAnnotation();
253 void FileView::on_toolButtonGoNext_clicked() {
255 goToCurrentAnnotation(1);
258 void FileView::on_toolButtonGoPrev_clicked() {
260 goToCurrentAnnotation(-1);
263 void FileView::on_toolButtonPin_toggled(bool b
) {
264 // button is enabled and togglable only if st.sha() is found
266 fileTab
->spinBoxRevision
->setDisabled(b
);
269 updateSpinBoxValue(); // UPDATE() call is filtered in this case
270 fileTab
->textEditFile
->doUpdate(true);
274 void FileView::on_toolButtonRangeFilter_toggled(bool b
) {
276 updateEnabledButtons();
278 if (!fileTab
->textEditFile
->isAnnotateAvailable()) {
279 dbs("ASSERT in on_toolButtonRangeFilter_toggled: annotate not available");
282 if (!fileTab
->textEditFile
->textCursor().hasSelection()) {
283 showStatusBarMessage("Please select some text");
287 bool rangeFilterActive
= fileTab
->textEditFile
->rangeFilter(b
);
288 filterOnRange(rangeFilterActive
);
291 void FileView::on_toolButtonHighlightText_toggled(bool b
) {
293 updateEnabledButtons();
294 fileTab
->textEditFile
->setHighlightSource(b
);
297 void FileView::on_spinBoxRevision_valueChanged(int id
) {
299 if (id
!= fileTab
->spinBoxRevision
->minimum()) {
301 SCRef
selRev(fileTab
->histListView
->shaFromAnnId(id
));
302 if (st
.sha() != selRev
) { // to avoid looping
304 st
.setSelectItem(true);
310 void FileView::on_loadCompleted(const FileHistory
* f
, const QString
& msg
) {
312 QApplication::restoreOverrideCursor();
317 showStatusBarMessage("");
318 fileTab
->histListView
->showIdValues();
319 int maxId
= model()->rowCount();
323 fileTab
->spinBoxRevision
->setMaximum(maxId
);
324 fileTab
->toolButtonPin
->setEnabled(true);
325 fileTab
->spinBoxRevision
->setEnabled(true);
327 // update histListView now to avoid to miss
328 // following status bar messages
331 QString histTime
= msg
.section(" ms", 0, 0).section(" ", -1);
332 if (fileTab
->textEditFile
->startAnnotate(model(), histTime
))
333 showStatusBarMessage("Annotating revisions of '" + st
.fileName() + "'...");
336 void FileView::showAnnotation() {
338 if ( !fileTab
->toolButtonPin
->isChecked()
339 && fileTab
->toolButtonShowAnnotate
->isEnabled()
340 && fileTab
->toolButtonShowAnnotate
->isChecked()) {
342 fileTab
->textEditFile
->setShowAnnotate(true);
344 if ( fileTab
->toolButtonFindAnnotate
->isEnabled()
345 && fileTab
->toolButtonFindAnnotate
->isChecked())
347 goToCurrentAnnotation();
351 void FileView::on_annotationAvailable(bool b
) {
353 updateEnabledButtons();
355 showAnnotation(); // in case annotation got ready after file
358 void FileView::on_fileAvailable(bool b
) {
360 updateEnabledButtons();
362 // code range is independent from annotation
363 if (fileTab
->toolButtonRangeFilter
->isChecked())
364 fileTab
->textEditFile
->goToRangeStart();
366 showAnnotation(); // in case file got ready after annotation
370 void FileView::on_revIdSelected(int id
) {
375 if (fileTab
->spinBoxRevision
->isEnabled())
376 fileTab
->spinBoxRevision
->setValue(id
);
378 ListView
* h
= fileTab
->histListView
;
379 int row
= h
->model()->rowCount() - id
;
380 QModelIndex idx
= h
->model()->index(row
, 0);
381 h
->setCurrentIndex(idx
);