1
2 /*
3 * CodeQuery
4 * Copyright (C) 2013-2017 ruben2020 https://github.com/ruben2020/
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 */
11
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <QProcess>
16 #include <QInputDialog>
17 #include <QFontDatabase>
18
19 #include "ScintillaEdit.h"
20 #include "SciLexer.h"
21
22 #include "fileviewer.h"
23 #include "mainwindow.h"
24 #include "fileviewsettingsdialog.h"
25 #include "themes.h"
26
27 #ifdef _WIN32
28 #define EXT_EDITOR_DEFAULT_PATH "notepad %f"
29 #else
30 #define EXT_EDITOR_DEFAULT_PATH "gedit %f +%n"
31 #endif
32
filedata()33 filedata::filedata()
34 {
35 linenum = "1";
36 fileid = -99;
37 }
filedata(const QString & fn,const QString & ln,const int & fi)38 filedata::filedata(const QString& fn, const QString& ln, const int& fi)
39 {
40 linenum = ln;
41 filename = fn;
42 fileid = fi;
43 }
44
compare(const filedata & fd)45 bool filedata::compare(const filedata& fd)
46 {
47 bool cmp;
48 if ((fileid < 0)||(fd.fileid < 0))
49 {
50 cmp = ((linenum.compare(fd.linenum) == 0)&&
51 (filename.compare(fd.filename) == 0));
52 }
53 else
54 {
55 cmp = ((linenum.compare(fd.linenum) == 0)&&
56 (fileid == fd.fileid));
57 }
58 return cmp;
59 }
60
compareFilePathOnly(const filedata & fd)61 bool filedata::compareFilePathOnly(const filedata& fd)
62 {
63 bool cmp;
64 if ((fileid < 0)||(fd.fileid < 0))
65 {
66 cmp = (filename.compare(fd.filename) == 0);
67 }
68 else
69 {
70 cmp = (fileid == fd.fileid);
71 }
72 return cmp;
73 }
74
compareFileNameOnly(const filedata & fd)75 bool filedata::compareFileNameOnly(const filedata& fd)
76 {
77 bool cmp;
78 if ((fileid < 0)||(fd.fileid < 0))
79 {
80 cmp =(strcmp(
81 extract_filename(filename.C_STR()),
82 extract_filename(fd.filename.C_STR())) == 0);
83 }
84 else
85 {
86 cmp = (fileid == fd.fileid);
87 }
88 return cmp;
89 }
90
filedata(const filedata & fd)91 filedata::filedata(const filedata& fd)
92 {
93 linenum = fd.linenum;
94 filename = fd.filename;
95 fileid = fd.fileid;
96 }
97
operator =(const filedata & fd)98 filedata& filedata::operator=(const filedata& fd)
99 {
100 if (&fd != this)
101 {
102 linenum = fd.linenum;
103 filename = fd.filename;
104 fileid = fd.fileid;
105 }
106 return *this;
107 }
108
fileviewer(mainwindow * pmw)109 fileviewer::fileviewer(mainwindow* pmw)
110 :mw(pmw)
111 ,m_pushButtonPrev(NULL)
112 ,m_pushButtonNext(NULL)
113 ,m_pushButtonOpenInEditor(NULL)
114 ,m_pushButtonPaste(NULL)
115 ,m_pushButtonGoToLine(NULL)
116 ,m_labelFilePath(NULL)
117 ,m_textEditSource(NULL)
118 ,m_textEditSourceFont("Courier New", 12)
119 ,m_externalEditorPath(EXT_EDITOR_DEFAULT_PATH)
120 ,m_timestampMismatchWarned(false)
121 ,m_lexer(SCLEX_NULL)
122 ,m_fontsize(0)
123 ,m_currentlang(enHighlightCPP)
124 ,m_currentline(1)
125 ,m_annotline(1)
126 ,m_pushButtonTextShrink(NULL)
127 ,m_pushButtonTextEnlarge(NULL)
128 ,m_checkBoxSymbolOnly(NULL)
129 ,m_listWidgetFunc(NULL)
130 ,m_comboBoxFuncListSort(NULL)
131 ,m_fontwidthtemp(1)
132 ,m_markerhandle(1)
133 ,m_markerhandle2(2)
134 {
135 m_iter = m_fileDataList.begin();
136 m_textEditSourceFont.setStyleHint(QFont::TypeWriter);
137 }
138
~fileviewer()139 fileviewer::~fileviewer()
140 {
141 disconnect();
142 }
143
createFontList(void)144 void fileviewer::createFontList(void)
145 {
146 QFontDatabase fontdb;
147 QStringList fontlst = fontdb.families(QFontDatabase::Latin);
148 QStringList fixedpitch;
149 QStringList::iterator it;
150 for(it = fontlst.begin(); it != fontlst.end(); it++)
151 {
152 if (fontdb.isFixedPitch(*it))
153 {
154 fixedpitch << (*it);
155 }
156 }
157 fixedpitch.sort();
158 m_fontlist = fixedpitch;
159 }
160
checkFontFamily(QString fontname)161 QString fileviewer::checkFontFamily(QString fontname)
162 {
163 QString newfont;
164 #ifdef _WIN32
165 QString tryfont1 = "Consolas";
166 QString tryfont2 = "Courier New";
167 #else
168 QString tryfont1 = "Monospace";
169 QString tryfont2 = "Ubuntu Mono";
170 #endif
171 if (m_fontlist.isEmpty()) createFontList();
172 if (m_fontlist.contains(fontname))
173 {
174 newfont = fontname;
175 }
176 else
177 {
178 #if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
179 newfont = QFontDatabase::systemFont(QFontDatabase::FixedFont).family();
180 #else
181 if (m_fontlist.contains(tryfont1)) newfont = tryfont1;
182 else if (m_fontlist.contains(tryfont2)) newfont = tryfont2;
183 else newfont = m_fontlist[0];
184 #endif
185 }
186 return newfont;
187 }
188
init(void)189 void fileviewer::init(void)
190 {
191 Scintilla_LinkLexers();
192 m_pushButtonPaste->setEnabled(false);
193 m_pushButtonPrev->setEnabled(false);
194 m_pushButtonNext->setEnabled(false);
195 m_pushButtonTextShrink->setEnabled(false);
196 m_pushButtonTextEnlarge->setEnabled(false);
197 m_pushButtonGoToLine->setEnabled(false);
198 m_pushButtonOpenInEditor->setEnabled(false);
199 m_labelFilePath->clear();
200 m_textEditSource->setWrapMode(SC_WRAP_NONE);
201 m_textEditSource->setReadOnly(true);
202 m_markerhandle = 0;
203 m_markerhandle2 = 1;
204 m_textEditSource->markerDefine(m_markerhandle, SC_MARK_BACKGROUND);
205 m_textEditSource->markerDefine(m_markerhandle2, SC_MARK_ARROW);
206 m_textEditSource->setMarginTypeN(0, SC_MARGIN_NUMBER);
207 m_textEditSource->setMarginTypeN(1, SC_MARGIN_SYMBOL);
208 m_textEditSource->annotationSetVisible(ANNOTATION_BOXED);
209 m_textEditSource->setCodePage(SC_CP_UTF8);
210 m_textEditSource->setCaretPeriod(0);
211 createFontList();
212 ScintillaEditBase *textEditSourceBase = m_textEditSource;
213 connect(textEditSourceBase, SIGNAL(selectionChanged(bool)),
214 this, SLOT(AbleToCopy(bool)));
215 connect(m_pushButtonGoToLine, SIGNAL(clicked(bool)),
216 this, SLOT(GoToLine_ButtonClick(bool)));
217 connect(m_pushButtonPaste, SIGNAL(clicked(bool)),
218 this, SLOT(Paste_ButtonClick(bool)));
219 connect(m_pushButtonPrev, SIGNAL(clicked(bool)),
220 this, SLOT(Prev_ButtonClick(bool)));
221 connect(m_pushButtonNext, SIGNAL(clicked(bool)),
222 this, SLOT(Next_ButtonClick(bool)));
223 connect(m_pushButtonOpenInEditor, SIGNAL(clicked(bool)),
224 this, SLOT(OpenInEditor_ButtonClick(bool)));
225 connect(m_pushButtonTextShrink, SIGNAL(clicked(bool)),
226 this, SLOT(TextShrink_ButtonClick(bool)));
227 connect(m_pushButtonTextEnlarge, SIGNAL(clicked(bool)),
228 this, SLOT(TextEnlarge_ButtonClick(bool)));
229 connect(m_listWidgetFunc, SIGNAL(itemPressed(QListWidgetItem *)),
230 this, SLOT(funcItemSelected(QListWidgetItem *)));
231 connect(m_comboBoxFuncListSort, SIGNAL(currentIndexChanged(int)),
232 this, SLOT(FuncListSort_indexChanged(int)));
233 m_fileDataList.clear();
234 clearTextEdit();
235 setLexer();
236 }
237
clearList()238 void fileviewer::clearList()
239 {
240 //printf("Fileview clearlist\n");
241 m_pushButtonPaste->setEnabled(false);
242 m_pushButtonPrev->setEnabled(false);
243 m_pushButtonNext->setEnabled(false);
244 m_pushButtonTextShrink->setEnabled(false);
245 m_pushButtonTextEnlarge->setEnabled(false);
246 m_pushButtonGoToLine->setEnabled(false);
247 m_pushButtonOpenInEditor->setEnabled(false);
248 m_labelFilePath->clear();
249 clearTextEdit();
250 m_fileDataList.clear();
251 m_iter = m_fileDataList.begin();
252 m_timestampMismatchWarned = false;
253 m_listWidgetFunc->clear();
254 }
255
recvDBtimestamp(QDateTime dt)256 void fileviewer::recvDBtimestamp(QDateTime dt)
257 {
258 m_DBtimestamp = dt;
259 }
260
fileToBeOpened(QString filename,QString linenum,int fileid)261 void fileviewer::fileToBeOpened(QString filename, QString linenum, int fileid)
262 {
263 filename.replace(QString("$HOME"), QDir::homePath());
264 #ifdef _WIN32
265 filename.replace("/", "\\");
266 #endif
267 if (!(QFile::exists(filename)))
268 {
269 m_labelFilePath->setText(tr("File not found"));
270 handleFileCannotBeOpenedCase();
271 return;
272 }
273 QFile file(filename);
274 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
275 {
276 m_labelFilePath->setText(tr("File could not be opened"));
277 handleFileCannotBeOpenedCase();
278 return;
279 }
280 file.close();
281
282 QFileInfo fi(filename);
283 if ((m_DBtimestamp < fi.lastModified())&&(m_timestampMismatchWarned == false))
284 {
285
286 m_timestampMismatchWarned = true;
287 QMessageBox msgBox((QWidget*)mw);
288 msgBox.setIcon(QMessageBox::Warning);
289 msgBox.setStandardButtons(QMessageBox::Ok);
290 msgBox.setText(tr("The source file to be viewed is newer than the CodeQuery database file. You are recommended to manually regenerate the CodeQuery database file."));
291 msgBox.exec();
292 }
293 filedata fd(filename, linenum, fileid);
294 if (m_fileDataList.isEmpty())
295 {
296 //printf("Fileviewer: empty list\n");
297 m_fileDataList.push_back(fd);
298 m_iter = m_fileDataList.end() - 1;
299 m_pushButtonPrev->setEnabled(false);
300 m_pushButtonNext->setEnabled(false);
301 updateTextEdit();
302 return;
303 }
304 else if (m_iter == m_fileDataList.end())
305 {
306 // previous file not found
307 //printf("Fileviewer: previous file not found %d, %d\n", m_fileDataList.end(), m_fileDataList.end() - 1);
308 m_fileDataList.push_back(fd);
309 m_iter = m_fileDataList.end() - 1;
310 m_pushButtonPrev->setEnabled(m_iter != m_fileDataList.begin());
311 m_pushButtonNext->setEnabled(false);
312 updateTextEdit();
313 }
314 else if (m_iter->compare(fd))
315 {
316 // the same filename and line number
317 //printf("Fileviewer: same filename and line number\n");
318 updateFilePathLabel();
319 return;
320 }
321 else if (m_iter->compareFilePathOnly(fd))
322 {
323 // same file, different line number
324 //printf("Fileviewer: same file, different line number\n");
325 m_fileDataList.push_back(fd);
326 m_iter = m_fileDataList.end() - 1;
327 m_pushButtonPrev->setEnabled(true);
328 m_pushButtonNext->setEnabled(false);
329 highlightLine(fd.linenum.toInt());
330 updateFilePathLabel();
331 }
332 else
333 {
334 // different file
335 //printf("Fileviewer: different file\n");
336 m_fileDataList.push_back(fd);
337 m_iter = m_fileDataList.end() - 1;
338 m_pushButtonPrev->setEnabled(true);
339 m_pushButtonNext->setEnabled(false);
340 updateTextEdit();
341 }
342 if ((m_fileDataList.isEmpty())||(m_iter == m_fileDataList.end())) return;
343 QVector<filedata>::iterator it = m_fileDataList.begin();
344 while ((it != m_fileDataList.end() - 1)&&(it != m_fileDataList.end()))
345 {
346 if (it->compare(fd)) it = m_fileDataList.erase(it);
347 else it++;
348 }
349 if (m_fileDataList.size() > 20) m_fileDataList.erase(m_fileDataList.begin());
350 m_iter = m_fileDataList.end() - 1;
351 }
352
clearTextEdit(void)353 void fileviewer::clearTextEdit(void)
354 {
355 m_textEditSource->setReadOnly(false);
356 m_textEditSource->clearAll();
357 m_textEditSource->setReadOnly(true);
358 }
359
updateTextEdit(void)360 void fileviewer::updateTextEdit(void)
361 {
362 if (m_iter == m_fileDataList.end()) return;
363 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
364 clearTextEdit();
365
366 QFile file(m_iter->filename);
367 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
368 {
369 QApplication::restoreOverrideCursor();
370 return;
371 }
372 QTextStream in(&file);
373
374 int lang = enHighlightCPP; // default
375
376 QRegExp rx1("\\.py$", Qt::CaseInsensitive);
377 int pos = rx1.indexIn(m_iter->filename);
378 if (pos != -1) lang = enHighlightPython;
379
380 QRegExp rx2("\\.java$", Qt::CaseInsensitive);
381 pos = rx2.indexIn(m_iter->filename);
382 if (pos != -1) lang = enHighlightJava;
383
384 QRegExp rx3("\\.rb$", Qt::CaseInsensitive);
385 pos = rx3.indexIn(m_iter->filename);
386 if (pos != -1) lang = enHighlightRuby;
387
388 QRegExp rx4("\\.js$", Qt::CaseInsensitive);
389 pos = rx4.indexIn(m_iter->filename);
390 if (pos != -1) lang = enHighlightJavascript;
391
392 QRegExp rx5("\\.go$", Qt::CaseInsensitive);
393 pos = rx5.indexIn(m_iter->filename);
394 if (pos != -1) lang = enHighlightGo;
395
396 m_currentlang = lang;
397
398 QString alltext;
399 while (!in.atEnd())
400 {
401 alltext = in.readAll();
402 }
403 m_textEditSource->setReadOnly(false);
404 m_textEditSource->setText(alltext.toUtf8().data());
405 m_textEditSource->setReadOnly(true);
406 m_textEditSource->setMarginWidthN(0, m_textEditSource->textWidth(STYLE_LINENUMBER, QString::number(m_textEditSource->lineCount() * 10).C_STR()));
407 highlightLine(m_iter->linenum.toInt());
408 updateFilePathLabel();
409 m_pushButtonGoToLine->setEnabled(true);
410 m_pushButtonOpenInEditor->setEnabled(true);
411 m_pushButtonTextShrink->setEnabled(true);
412 m_pushButtonTextEnlarge->setEnabled(true);
413 m_listWidgetFunc->clear();
414 if (m_iter->fileid < 0) {emit requestFuncList_filename(m_iter->filename);}
415 else {emit requestFuncList_fileid(m_iter->fileid);}
416 setLexer(lang);
417 QApplication::restoreOverrideCursor();
418 }
419
updateFilePathLabel(void)420 void fileviewer::updateFilePathLabel(void)
421 {
422 QString labeltext = m_iter->filename;
423 labeltext += ":";
424 labeltext += m_iter->linenum;
425 m_labelFilePath->setText(labeltext);
426 m_pushButtonGoToLine->setEnabled(true);
427 }
428
braceMatchCheck(void)429 void fileviewer::braceMatchCheck(void)
430 {
431 long cpos, matchpos;
432 cpos = m_textEditSource->currentPos();
433 matchpos = m_textEditSource->braceMatch(cpos, 0);
434 if (matchpos == -1)
435 {
436 cpos--;
437 matchpos = m_textEditSource->braceMatch(cpos, 0);
438 }
439 if (matchpos != -1) m_textEditSource->braceHighlight(cpos, matchpos);
440 else m_textEditSource->braceHighlight(-1, -1);
441 }
442
updateFuncList(void)443 void fileviewer::updateFuncList(void)
444 {
445 if (m_funclist.resultlist.empty()) return;
446 long line = m_textEditSource->lineFromPosition(m_textEditSource->currentPos()) + 1;
447 tStr selectedfunc = "";
448 unsigned int selectedline, line1;
449 auto previt = m_funclist.resultlist.begin();
450 for (auto it = m_funclist.resultlist.begin(); it != m_funclist.resultlist.end(); it++)
451 {
452 if ( (line < it->intLinenum) && (line >= previt->intLinenum) )
453 {
454 selectedfunc = previt->symname;
455 selectedline = previt->intLinenum;
456 break;
457 }
458 previt = it;
459 }
460 if (selectedfunc.isEmpty() == false)
461 {
462 auto itemlist = m_listWidgetFunc->findItems(selectedfunc, Qt::MatchExactly);
463 for (auto it = itemlist.begin(); it != itemlist.end(); it++)
464 {
465 line1 = (*it)->data(Qt::UserRole).toUInt();
466 if (selectedline == line1)
467 {
468 m_listWidgetFunc->setCurrentItem(*it);
469 break;
470 }
471 }
472 }
473 }
474
AbleToCopy(bool copy)475 void fileviewer::AbleToCopy(bool copy)
476 {
477 m_pushButtonPaste->setEnabled(copy);
478 m_textEditSource->annotationClearAll();
479 braceMatchCheck();
480 updateFuncList();
481 if (copy)
482 {
483 m_textEditSource->copy();
484 m_annotline = m_textEditSource->lineFromPosition(m_textEditSource->selectionEnd());
485 QString str = (QApplication::clipboard())->text();
486 if (str.length() > 0)
487 {
488 emit requestAnnotation(str);
489 }
490 }
491 }
492
GoToLine_ButtonClick(bool checked)493 void fileviewer::GoToLine_ButtonClick(bool checked)
494 {
495 if (!checked) highlightLine(m_iter->linenum.toInt());
496 }
497
Prev_ButtonClick(bool checked)498 void fileviewer::Prev_ButtonClick(bool checked)
499 {
500 if (m_fileDataList.isEmpty())
501 {
502 m_pushButtonPrev->setEnabled(false);
503 m_pushButtonNext->setEnabled(false);
504 return;
505 }
506 if(m_iter == m_fileDataList.begin())
507 {
508 m_pushButtonPrev->setEnabled(false);
509 return;
510 }
511 if (!checked)
512 {
513 QVector<filedata>::iterator it = m_iter;
514 m_iter--;
515 if ((it != m_fileDataList.end())&&(m_iter->compareFilePathOnly(*it)))
516 {
517 highlightLine(m_iter->linenum.toInt());
518 updateFilePathLabel();
519 }
520 else
521 {
522 updateTextEdit();
523 }
524 m_pushButtonPrev->setEnabled(m_iter != m_fileDataList.begin());
525 m_pushButtonNext->setEnabled(m_iter != m_fileDataList.end() - 1);
526 }
527 }
528
Next_ButtonClick(bool checked)529 void fileviewer::Next_ButtonClick(bool checked)
530 {
531 if (m_fileDataList.isEmpty())
532 {
533 m_pushButtonPrev->setEnabled(false);
534 m_pushButtonNext->setEnabled(false);
535 return;
536 }
537 if((m_iter == m_fileDataList.end() - 1)||
538 (m_iter == m_fileDataList.end()))
539 {
540 m_pushButtonNext->setEnabled(false);
541 return;
542 }
543 if (!checked)
544 {
545 QVector<filedata>::iterator it = m_iter;
546 m_iter++;
547 if (m_iter->compareFilePathOnly(*it))
548 {
549 highlightLine(m_iter->linenum.toInt());
550 updateFilePathLabel();
551 }
552 else
553 {
554 updateTextEdit();
555 }
556 m_pushButtonPrev->setEnabled(m_iter != m_fileDataList.begin());
557 m_pushButtonNext->setEnabled(m_iter != m_fileDataList.end() - 1);
558 }
559 }
560
handleFileCannotBeOpenedCase(void)561 void fileviewer::handleFileCannotBeOpenedCase(void)
562 {
563 //printf("handleFileCannotBeOpenedCase\n");
564 clearTextEdit();
565 m_pushButtonTextShrink->setEnabled(false);
566 m_pushButtonTextEnlarge->setEnabled(false);
567 m_pushButtonGoToLine->setEnabled(false);
568 m_pushButtonNext->setEnabled(false);
569 m_pushButtonPrev->setEnabled(m_fileDataList.isEmpty() == false);
570 m_iter = m_fileDataList.end();
571 }
572
573
Paste_ButtonClick(bool checked)574 void fileviewer::Paste_ButtonClick(bool checked)
575 {
576 if (!checked)
577 {
578 m_textEditSource->copy();
579 if (m_checkBoxSymbolOnly->isChecked())
580 emit searchCopiedTextSymbolOnly();
581 else emit searchCopiedText();
582 }
583 }
584
fileViewSettings_Triggered(bool checked)585 void fileviewer::fileViewSettings_Triggered(bool checked)
586 {
587 cqDialogFileViewSettings cqdg((QWidget*)mw, this,
588 m_fontlist, themes::getThemesList());
589 m_fonttemp = m_textEditSourceFont.family();
590 m_fontwidthtemp = (m_textEditSource->tabWidth());
591 m_themetemp = m_theme;
592 cqdg.setCurrentFontType(m_fonttemp);
593 cqdg.setTabWidth(m_fontwidthtemp);
594 cqdg.setCurrentTheme(m_themetemp);
595 cqdg.setModal(true);
596 cqdg.exec();
597 if (cqdg.result() == QDialog::Accepted)
598 {
599 m_textEditSourceFont.setFamily(m_fonttemp);
600 //m_lexer->setFont(m_textEditSourceFont);
601 m_textEditSource->setTabWidth(m_fontwidthtemp);
602 m_textEditSource->setZoom(m_fontsize);
603 m_theme = m_themetemp;
604 m_themelast = "1234";
605 setLexer();
606 }
607 }
608
OptionsExtEditor_Triggered(bool checked)609 void fileviewer::OptionsExtEditor_Triggered(bool checked)
610 {
611 bool ok;
612 QString inptext;
613 QInputDialog qinp(mw);
614 qinp.setCancelButtonText(tr("Cancel"));
615 qinp.setOkButtonText(tr("OK"));
616 qinp.setInputMode(QInputDialog::TextInput);
617 qinp.setWindowTitle(tr("External Editor Configuration"));
618 QString exted = tr("Please enter the path and arguments for the external editor. Replace as follows:");
619 exted += "\n%f - ";
620 exted += tr("for file path");
621 exted += "\n%n - ";
622 exted += tr("for line number");
623 exted += "\n";
624 exted += tr("For example:");
625 #ifdef _WIN32
626 exted += "\n\"C:\\Program Files\\Notepad++\\notepad++.exe\" -n%n %f";
627 #else
628 exted += "\ngedit %f +%n";
629 #endif
630 qinp.setLabelText(exted);
631 qinp.setTextEchoMode(QLineEdit::Normal);
632 qinp.setTextValue(m_externalEditorPath);
633 qinp.exec();
634 ok = (qinp.result() == QDialog::Accepted);
635 inptext = qinp.textValue();
636 if (ok && (inptext.isEmpty() == false)) m_externalEditorPath = inptext.trimmed();
637 }
638
OpenInEditor_ButtonClick(bool checked)639 void fileviewer::OpenInEditor_ButtonClick(bool checked)
640 {
641 QMessageBox msgBox(mw);
642 msgBox.setIcon(QMessageBox::Warning);
643 msgBox.setStandardButtons(QMessageBox::Ok);
644 if (!checked)
645 {
646 QFile file(m_iter->filename);
647 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
648 {
649 msgBox.setText(tr("File could not be opened!"));
650 msgBox.exec();
651 return;
652 }
653 file.close();
654
655 QStringList arguments;
656 QString program;
657 QRegExp rx("^\"([^\"]+)\" (.*)");
658 int pos = rx.indexIn(m_externalEditorPath);
659 if (pos != -1)
660 {
661 program = rx.cap(1);
662 arguments = (rx.cap(2)).split(QRegExp("[ ]+"));
663 }
664 else
665 {
666 arguments = m_externalEditorPath.split(QRegExp("[ ]+"));
667 program = arguments.takeFirst();
668 }
669 arguments.replaceInStrings(QRegExp("%f"), m_iter->filename);
670 arguments.replaceInStrings(QRegExp("%n"), m_iter->linenum);
671
672 if (QProcess::startDetached(program, arguments) == false)
673 {
674 msgBox.setText(tr("External editor could not be started. Please check Options!"));
675 msgBox.exec();
676 return;
677 }
678 }
679 }
680
TextShrink_ButtonClick(bool checked)681 void fileviewer::TextShrink_ButtonClick(bool checked)
682 {
683 if (!checked)
684 {
685 textSizeChange(0-1);
686 //m_textEditSource->zoomOut();
687 }
688 }
689
TextEnlarge_ButtonClick(bool checked)690 void fileviewer::TextEnlarge_ButtonClick(bool checked)
691 {
692 if (!checked)
693 {
694 textSizeChange(1);
695 //m_textEditSource->zoomIn();
696 }
697 }
698
textSizeChange(int n)699 void fileviewer::textSizeChange(int n)
700 {
701 //m_fontwidthtemp = (m_textEditSource->tabWidth());
702 //m_lexer->setFont(m_textEditSourceFont);
703 m_fontsize += n;
704 m_textEditSource->setZoom(m_fontsize);
705 m_textEditSource->setMarginWidthN(0, m_textEditSource->textWidth(STYLE_LINENUMBER, QString::number(m_textEditSource->lineCount() * 10).C_STR()));
706 //m_textEditSource->setTabWidth(m_fontwidthtemp);
707 }
708
fontSelectionTemporary(const QString & fonttxt)709 void fileviewer::fontSelectionTemporary(const QString &fonttxt)
710 {
711 m_fonttemp = fonttxt;
712 }
713
themeSelectionTemporary(const QString & themetxt)714 void fileviewer::themeSelectionTemporary(const QString &themetxt)
715 {
716 m_themetemp = themetxt;
717 }
718
tabWidthSelectionTemporary(const QString & width)719 void fileviewer::tabWidthSelectionTemporary(const QString &width)
720 {
721 m_fontwidthtemp = width.toInt();
722 }
723
highlightLine(unsigned int num)724 void fileviewer::highlightLine(unsigned int num)
725 {
726 m_textEditSource->markerDeleteAll(-1);
727 if (num <= 0)
728 {
729 num = 1;
730 }
731 else
732 {
733 num = num - 1; // not sure why it's one off
734 m_textEditSource->markerAdd(num, m_markerhandle);
735 m_textEditSource->markerAdd(num, m_markerhandle2);
736 }
737 m_textEditSource->setFirstVisibleLine(num);
738 m_currentline = num;
739 }
740
setLexer(int lang)741 void fileviewer::setLexer(int lang)
742 {
743 if (lang == -1) lang = m_currentlang;
744
745 switch(lang)
746 {
747
748 case enHighlightCPP:
749 replaceLexer(SCLEX_CPP, lang);
750 break;
751
752 case enHighlightPython:
753 replaceLexer(SCLEX_PYTHON, lang);
754 break;
755
756 case enHighlightJava:
757 replaceLexer(SCLEX_CPP, lang);
758 break;
759
760 case enHighlightRuby:
761 replaceLexer(SCLEX_RUBY, lang);
762 break;
763
764 case enHighlightJavascript:
765 replaceLexer(SCLEX_CPP, lang);
766 break;
767
768 default:
769 replaceLexer(SCLEX_CPP, lang);
770 break;
771
772 }
773 }
774
replaceLexer(int sclang,int lang)775 void fileviewer::replaceLexer(int sclang, int lang)
776 {
777 QColor markerlinebgcolor;
778 QColor linenumfgcolor;
779 //if (m_lexer != sclang)
780 {
781 switch (lang)
782 {
783 case enHighlightCPP:
784 m_lexer = SCLEX_CPP;
785 break;
786
787 case enHighlightPython:
788 m_lexer = SCLEX_PYTHON;
789 break;
790
791 case enHighlightJava:
792 m_lexer = SCLEX_CPP;
793 break;
794
795 case enHighlightRuby:
796 m_lexer = SCLEX_RUBY;
797 break;
798
799 case enHighlightJavascript:
800 m_lexer = SCLEX_CPP;
801 break;
802
803 default:
804 m_lexer = SCLEX_CPP;
805 break;
806 }
807 m_textEditSource->setLexer(m_lexer);
808 m_textEditSource->clearDocumentStyle();
809 m_textEditSource->setZoom(m_fontsize);
810 m_themelast = "1234";
811 }
812 //if (m_themelast.compare(m_theme) != 0)
813 {
814 m_themelast = m_theme;
815 themes::setTheme(m_theme, lang, m_textEditSource, m_textEditSourceFont, markerlinebgcolor, linenumfgcolor);
816 m_textEditSource->markerSetBack(m_markerhandle, themes::QC2SC(markerlinebgcolor));
817 m_textEditSource->markerSetBack(m_markerhandle2, themes::QC2SC(linenumfgcolor));
818 m_textEditSource->markerSetAlpha(m_markerhandle, SC_ALPHA_NOALPHA);
819 m_textEditSource->markerSetAlpha(m_markerhandle2, SC_ALPHA_NOALPHA);
820 m_textEditSource->styleSetFont(STYLE_LINENUMBER, m_textEditSourceFont.family().C_STR());
821 m_textEditSource->setZoom(m_fontsize);
822 m_textEditSource->setMarginWidthN(0, m_textEditSource->textWidth(STYLE_LINENUMBER, QString::number(m_textEditSource->lineCount() * 10).C_STR()));
823 themes::setKeywords(lang, m_textEditSource);
824 m_textEditSource->colourise(0, -1);
825 }
826 }
827
annotate(QStringList annotstrLst)828 void fileviewer::annotate(QStringList annotstrLst)
829 {
830 m_textEditSource->copy();
831 QString str = (QApplication::clipboard())->text();
832 m_annotline = m_textEditSource->lineFromPosition(m_textEditSource->selectionEnd());
833 if ((annotstrLst.length() >= 2)&&(annotstrLst[0] == str))
834 {
835 m_textEditSource->annotationClearAll();
836 m_textEditSource->annotationSetText(m_annotline, annotstrLst[1].toUtf8().data());
837 m_textEditSource->annotationSetStyle(m_annotline, 29);
838 }
839 else if (str.length() > 0)
840 {
841 emit requestAnnotation(str);
842 }
843 }
844
recvFuncList(sqlqueryresultlist * reslist)845 void fileviewer::recvFuncList(sqlqueryresultlist* reslist)
846 {
847 m_listWidgetFunc->clear();
848 if ((m_fileDataList.isEmpty())||(m_iter == m_fileDataList.end())) return;
849 m_funclist = *reslist;
850 m_funclist.sort_by_linenum();
851 for (auto it = m_funclist.resultlist.begin(); it != m_funclist.resultlist.end(); it++)
852 {
853 it->intLinenum = atoi(it->linenum.C_STR());
854 }
855 filedata fd(m_funclist.resultlist[0].filename, "1", -99);
856 if (m_iter->compareFileNameOnly(fd) == false)
857 {
858 if (m_iter->fileid < 0) {emit requestFuncList_filename(m_iter->filename);}
859 else {emit requestFuncList_fileid(m_iter->fileid);}
860 return;
861 }
862 sqlqueryresultlist templist = m_funclist;
863 if (m_comboBoxFuncListSort->currentIndex() != 0) templist.sort_by_name();
864 QListWidgetItem* item;
865 for (auto it = templist.resultlist.begin(); it != templist.resultlist.end(); it++)
866 {
867 item = new QListWidgetItem(it->symname);
868 item->setData(Qt::UserRole, QVariant(it->intLinenum));
869 m_listWidgetFunc->addItem(item);
870 }
871 }
872
funcItemSelected(QListWidgetItem * curitem)873 void fileviewer::funcItemSelected(QListWidgetItem * curitem)
874 {
875 if (curitem == nullptr) return;
876 unsigned int num = curitem->data(Qt::UserRole).toUInt();
877 m_textEditSource->setFirstVisibleLine(num - 1);
878 }
879
FuncListSort_indexChanged(const int & idx)880 void fileviewer::FuncListSort_indexChanged(const int& idx)
881 {
882 recvFuncList(&m_funclist);
883 }
884
885