1 /*
2 	Copyright (C) 2008, 2009 Andres Cabrera
3 	mantaraya36@gmail.com
4 
5 	This file is part of CsoundQt.
6 
7 	CsoundQt is free software; you can redistribute it
8 	and/or modify it under the terms of the GNU Lesser General Public
9 	License as published by the Free Software Foundation; either
10 	version 2.1 of the License, or (at your option) any later version.
11 
12 	CsoundQt is distributed in the hope that it will be useful,
13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 	GNU Lesser General Public License for more details.
16 
17 	You should have received a copy of the GNU Lesser General Public
18 	License along with Csound; if not, write to the Free Software
19 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 	02111-1307 USA
21 */
22 
23 #include "dockhelp.h"
24 #include "ui_dockhelp.h"
25 
26 #ifdef USE_QT5
27 #include <QtWidgets>
28 #else
29 #include <QtGui>
30 #endif
31 
DockHelp(QWidget * parent)32 DockHelp::DockHelp(QWidget *parent)
33 	: QDockWidget(parent), ui(new Ui::DockHelp)
34 {
35 	ui->setupUi(this);
36 	findFlags = 0;
37     setWindowTitle("Help"); // titlebar and overall layout
38 	setMinimumSize(400,200);
39 
40     connect(ui->toggleFindButton, SIGNAL(toggled(bool)), this, SLOT(toggleFindBarVisible(bool)));
41     connect(ui->backButton, SIGNAL(released()), this, SLOT(browseBack()));
42 	connect(ui->forwardButton, SIGNAL(released()), this, SLOT(browseForward()));
43     // connect(ui->opcodesToolButton, SIGNAL(released()), this, SLOT(showOverview()));
44 	connect(ui->homeToolButton, SIGNAL(released()), this, SLOT(showManual()));
45 	connect(ui->findLine,SIGNAL(returnPressed()),this,SLOT(onReturnPressed()));
46 	connect(ui->findLine,SIGNAL(textEdited(QString)),this,SLOT(onTextChanged()));
47 	ui->findPreviousAct->setShortcut(QKeySequence::FindPrevious);
48 	ui->nextFindAct->setShortcut(QKeySequence::FindNext);
49 	connect(ui->findPreviousAct,SIGNAL(triggered()),this,SLOT(onPreviousButtonPressed()));
50 	connect(ui->nextFindAct,SIGNAL(triggered()),this,SLOT(onNextButtonPressed()));
51 	ui->previousFindButton->setDefaultAction(ui->findPreviousAct);
52 	ui->nextFindButton->setDefaultAction(ui->nextFindAct);
53 
54 	connect(ui->caseBox,SIGNAL(stateChanged(int)),this,SLOT(onCaseBoxChanged(int)));
55 	connect(ui->wholeWordBox,SIGNAL(stateChanged(int)),this,SLOT(onWholeWordBoxChanged(int)));
56 	connect(ui->text, SIGNAL(anchorClicked(QUrl)), this, SLOT(followLink(QUrl)));
57 
58     ui->toggleFindButton->setChecked(false);
59     ui->findLine->setVisible(false);
60     ui->caseBox->setVisible(false);
61     ui->wholeWordBox->setVisible(false);
62     ui->label->setVisible(false);
63     ui->nextFindButton->setVisible(false);
64     ui->previousFindButton->setVisible(false);
65 }
66 
~DockHelp()67 DockHelp::~DockHelp()
68 {
69 }
70 
hasFocus()71 bool DockHelp::hasFocus()
72 {
73     return QDockWidget::hasFocus()
74            || ui->text->hasFocus()
75            || ui->findLine->hasFocus();
76 }
77 
loadFile(QString fileName)78 void DockHelp::loadFile(QString fileName)
79 {
80 	QFile file(fileName);
81 	if (!file.open(QFile::ReadOnly | QFile::Text)) {
82 		ui->text->setText(tr("Not Found! Make sure the documentation path is set in the Configuration Dialog."));
83 		return;
84 	}
85 #ifdef Q_OS_WIN32
86 	QStringList searchPaths;
87 	searchPaths << docDir;
88 	ui->text->setSearchPaths(searchPaths);
89 	QTextStream in(&file);
90 	in.setAutoDetectUnicode(true);
91 	ui->text->setHtml(in.readAll());
92 #else
93 	ui->text->setSource(QUrl::fromLocalFile(fileName));
94 #endif
95 
96 }
97 
closeEvent(QCloseEvent *)98 void DockHelp::closeEvent(QCloseEvent * /*event*/)
99 {
100 	emit Close(false);
101 }
102 
showManual()103 void DockHelp::showManual()
104 {
105 	this->setVisible(true);
106 	this->loadFile(docDir + "/index.html");
107 }
108 
showGen()109 void DockHelp::showGen()
110 {
111 	this->setVisible(true);
112 	this->loadFile(docDir + "/ScoreGenRef.html");
113 }
114 
showOverview()115 void DockHelp::showOverview()
116 {
117 	this->setVisible(true);
118 	this->loadFile(docDir + "/PartOpcodesOverview.html");
119 }
120 
showOpcodeQuickRef()121 void DockHelp::showOpcodeQuickRef()
122 {
123 	this->setVisible(true);
124 	this->loadFile(docDir + "/MiscQuickref.html");
125 }
126 
browseBack()127 void DockHelp::browseBack()
128 {
129 	ui->text->backward();
130 }
131 
browseForward()132 void DockHelp::browseForward()
133 {
134 	ui->text->forward();
135 }
136 
followLink(QUrl url)137 void DockHelp::followLink(QUrl url)
138 {
139 	if (url.host() == "") {
140 		// Will not follow external links for safety, only local files
141 		if (url.toString().endsWith(".csd")) {
142             QString csdFile = url.toLocalFile().isEmpty() ? url.toString() : url.toLocalFile(); // necessary for windows 10
143             emit openManualExample(csdFile);
144 		}
145 		else {
146 			if (!url.toString().endsWith("indexframes.html") ) {
147 				ui->text->setSource(url);
148 			}
149 			else { // Don't do anything with frames version...
150 				// This could be fixed using the WebKit rendering engine
151 				QMessageBox::warning(this, tr("CsoundQt"),
152 									 tr("Frames version only available in external browser."));
153 			}
154 		}
155 	}
156 	else {
157 		QMessageBox::warning(this, tr("CsoundQt"),
158 							 tr("External links can't be followed in help browser."));
159 	}
160 }
161 
copy()162 void DockHelp::copy()
163 {
164 	ui->text->copy();
165 }
166 
onTextChanged()167 void DockHelp::onTextChanged()
168 {
169 	QTextCursor tmpCursor = ui->text->textCursor();
170 	tmpCursor.setPosition(ui->text->textCursor().selectionStart());
171 	ui->text->setTextCursor(tmpCursor);
172 	findFlags &= 6; // first bit (FindBackward) to zero
173 	findText(ui->findLine->text());
174 }
175 
onReturnPressed()176 void DockHelp::onReturnPressed()
177 {
178 	findFlags &= 6; // first bit (FindBackward) to zero
179 	findText(ui->findLine->text());
180 }
181 
onNextButtonPressed()182 void DockHelp::onNextButtonPressed()
183 {
184 	findFlags &= 6; // first bit to zero
185 	findText(ui->findLine->text());
186 }
187 
onPreviousButtonPressed()188 void DockHelp::onPreviousButtonPressed()
189 {
190 	findFlags |= QTextDocument::FindBackward;
191 	findText(ui->findLine->text());
192 }
193 
194 
onCaseBoxChanged(int value)195 void DockHelp::onCaseBoxChanged(int value)
196 {
197 	if (value)
198 		findFlags |=  QTextDocument::FindCaseSensitively;
199 	else
200 		findFlags &= 5; // set 2 bit to 0
201 }
202 
onWholeWordBoxChanged(int value)203 void DockHelp::onWholeWordBoxChanged(int value)
204 {
205 	if (value)
206 		findFlags |=  QTextDocument::FindWholeWords;
207 	else
208 		findFlags &= 3; // set 3rd bit to 0
209 }
210 
findText(QString expr)211 void DockHelp::findText(QString expr)
212 {
213 	QTextCursor tmpCursor = ui->text->textCursor();
214 	if (!ui->text->find(expr,findFlags)) { // if not found, try from start
215 		ui->text->moveCursor(QTextCursor::Start);
216 		if (!ui->text->find(ui->findLine->text(),findFlags)) {
217 			ui->text->setTextCursor(tmpCursor); // if not found at all, restore position
218 		}
219 	} else {
220 		int cursorY = ui->text->cursorRect().top();
221 		QScrollBar *vbar = ui->text->verticalScrollBar();
222 		vbar->setValue(vbar->value() + cursorY);
223 	}
224 }
225 
resizeEvent(QResizeEvent * e)226 void DockHelp::resizeEvent(QResizeEvent *e)
227 {
228 	QDockWidget::resizeEvent(e);
229     // ui->backButton->move(frameGeometry().width()/2-25, 0);
230     // ui->forwardButton->move(frameGeometry().width()/2, 0);
231 }
232 
233 
focusText()234 void DockHelp::focusText() {
235     ui->text->setFocus();
236 }
237 
keyPressEvent(QKeyEvent * event)238 void DockHelp::keyPressEvent(QKeyEvent *event) {
239     if(event->key() == Qt::Key_Escape) {
240         toggleFindBarVisible(false);
241     }
242 }
243 
toggleFindBarVisible(bool show)244 void DockHelp::toggleFindBarVisible(bool show) {
245     ui->findLine->setVisible(show);
246     ui->label->setVisible(show);
247     ui->caseBox->setVisible(show);
248     ui->wholeWordBox->setVisible(show);
249     ui->nextFindButton->setVisible(show);
250     ui->previousFindButton->setVisible(show);
251     if(show) {
252         ui->findLine->setFocus();
253     }
254 }
255