You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
23 KiB
677 lines
23 KiB
/***************************************************************************
|
|
File: tdeio_sword.cpp
|
|
Project: Kio-Sword -- An ioslave for SWORD and KDE
|
|
Copyright: Copyright (C) 2004-2005 Luke Plant
|
|
|
|
File info:
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
// Mine
|
|
#include "renderer.h"
|
|
#include "tdeio_sword.h"
|
|
#include "utils.h"
|
|
#include "template.h"
|
|
#include "option.h"
|
|
|
|
// KDE
|
|
#include <kdebug.h>
|
|
#include <tdeglobal.h>
|
|
#include <tdelocale.h>
|
|
#include <kurl.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
// TQt
|
|
#include <ntqcstring.h>
|
|
#include <ntqmap.h>
|
|
|
|
// Standard C++ /C
|
|
#include <list>
|
|
#include <stdlib.h>
|
|
|
|
using namespace TDEIO;
|
|
using std::list;
|
|
using std::vector;
|
|
|
|
|
|
// main --------------------------------------------------------------------------------------------------------
|
|
extern "C" {
|
|
int kdemain(int argc, char **argv) {
|
|
TDEInstance instance("tdeio_sword");
|
|
|
|
kdDebug(7101) << "*** Starting tdeio_sword " << endl;
|
|
|
|
if (argc != 4) {
|
|
kdDebug(7101) <<
|
|
"Usage: tdeio_sword protocol domain-socket1 domain-socket2"
|
|
<< endl;
|
|
exit(-1);
|
|
}
|
|
|
|
KioSword::SwordProtocol slave(argv[2], argv[3]);
|
|
slave.dispatchLoop();
|
|
|
|
kdDebug(7101) << "*** tdeio_sword Done" << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
namespace KioSword
|
|
{
|
|
class SwordOptions;
|
|
|
|
// HTML fragments that will be initialised at run time -------------------------------------------------------------------------
|
|
static TQString search_form;
|
|
static TQString help_page;
|
|
|
|
|
|
|
|
SwordProtocol::SwordProtocol(const TQCString & pool_socket,
|
|
const TQCString & app_socket)
|
|
: SlaveBase("tdeio_sword", pool_socket, app_socket)
|
|
{
|
|
kdDebug() << "SwordProtocol::SwordProtocol()" << endl;
|
|
m_config = TDEGlobal::config();
|
|
}
|
|
|
|
|
|
SwordProtocol::~SwordProtocol()
|
|
{
|
|
kdDebug() << "SwordProtocol::~SwordProtocol()" << endl;
|
|
}
|
|
|
|
void SwordProtocol::get(const KURL & url)
|
|
{
|
|
TQString modname;
|
|
TQString query;
|
|
TQString error;
|
|
|
|
kdDebug() << "SwordProtocol::get(const KURL& url)" << endl;
|
|
|
|
/* kdDebug() << "Seconds: " << url.query() << endl;
|
|
TQString remoteServer = url.host();
|
|
int remotePort = url.port();
|
|
kdDebug() << "myURL: " << url.prettyURL() << endl; */
|
|
|
|
// Send the mimeType as soon as it is known
|
|
mimeType("text/html");
|
|
|
|
// Set user defaults from user config file
|
|
// (with internal defaults supplied if any options
|
|
// are missing from users config file)
|
|
readUserConfig();
|
|
|
|
// Get options/actions from URL
|
|
parseURL(url);
|
|
|
|
if (!m_path.isEmpty() && m_path != "/") {
|
|
if (!m_path.startsWith("/")) {
|
|
// sword:xxx is a shortcut for bible verses
|
|
modname = m_options.defaultBible();
|
|
if (modname.isEmpty())
|
|
{
|
|
error = i18n("No default Bible has been specified.");
|
|
}
|
|
else
|
|
{
|
|
// do redirection
|
|
query = m_path;
|
|
KURL newurl(url);
|
|
newurl.setPath('/' + modname + '/' + query);
|
|
redirection(newurl);
|
|
finished();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
modname = m_path.section('/', 0, 0, TQString::SectionSkipEmpty);
|
|
query = m_path.section('/', 1, -1, TQString::SectionSkipEmpty);
|
|
}
|
|
}
|
|
|
|
// handle redirections first
|
|
if (m_action == REDIRECT_QUERY) {
|
|
if (!m_redirect.module.isEmpty())
|
|
modname = m_redirect.module;
|
|
if (!m_redirect.query.isEmpty())
|
|
query = m_redirect.query;
|
|
|
|
if (modname.isEmpty()) {
|
|
switch (m_moduletype) {
|
|
case DEFBIBLE:
|
|
modname = m_options.defaultBible();
|
|
error = i18n("No default Bible has been specified.");
|
|
break;
|
|
case GREEKSTRONGS:
|
|
modname = m_options.defaultGreekStrongs();
|
|
error = i18n("No default Greek Strongs module has been specified.");
|
|
break;
|
|
case HEBREWSTRONGS:
|
|
modname = m_options.defaultHebrewStrongs();
|
|
error = i18n("No default Hebrew Strongs module has been specified.");
|
|
break;
|
|
case GREEKMORPH:
|
|
modname = m_options.defaultGreekMorph();
|
|
error = i18n("No default Greek morphological module has been specified.");
|
|
break;
|
|
case HEBREWMORPH:
|
|
modname = m_options.defaultHebrewMorph();
|
|
error = i18n("No default Hebrew morphological module has been specified.");
|
|
break;
|
|
case DEFMODULETYPE_NONE:
|
|
error = i18n("No module specified.");
|
|
}
|
|
}
|
|
|
|
if (modname.isEmpty()) {
|
|
error = "<p class='usererror'>" + error + "</p><hr />";
|
|
m_action = QUERY; // revert back to displaying list of modules
|
|
} else {
|
|
KURL newurl(url);
|
|
// Remove anything that will trigger a redirection
|
|
newurl.removeQueryItem("module");
|
|
newurl.removeQueryItem("query");
|
|
newurl.removeQueryItem("testsettings");
|
|
newurl.removeQueryItem("modtype");
|
|
newurl.setPath('/' + modname + '/' + query);
|
|
redirection(newurl);
|
|
finished();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Send the data
|
|
Template* tmplt = new Template();
|
|
tmplt->setCurrentPath(m_path);
|
|
|
|
switch (m_action) {
|
|
case QUERY:
|
|
if (!modname.isEmpty()) {
|
|
m_renderer.moduleQuery(modname, query, m_options, tmplt);
|
|
} else {
|
|
TQString body;
|
|
tmplt->setTitle(i18n("Modules - Kio-Sword"));
|
|
if (!error.isEmpty()) {
|
|
body = error;
|
|
}
|
|
body += m_renderer.listModules(m_options);
|
|
tmplt->setContent(body);
|
|
}
|
|
break;
|
|
|
|
case SEARCH_FORM:
|
|
tmplt->setTitle(i18n("Search - Kio-Sword"));
|
|
tmplt->setContent(searchForm(m_options));
|
|
break;
|
|
|
|
case SEARCH_QUERY:
|
|
tmplt->setTitle(i18n("Search Results - Kio-Sword"));
|
|
tmplt->setContent(m_renderer.search(m_redirect.module, m_redirect.query, m_stype, m_options));
|
|
break;
|
|
|
|
case SETTINGS_FORM:
|
|
tmplt->setTitle(i18n("Settings - Kio-Sword"));
|
|
tmplt->setContent(settingsForm());
|
|
break;
|
|
|
|
case SETTINGS_SAVE:
|
|
tmplt->setTitle(i18n("Settings saved - Kio-Sword"));
|
|
tmplt->setContent(saveUserConfig());
|
|
break;
|
|
|
|
case HELP:
|
|
tmplt->setTitle(i18n("Kio-Sword Help"));
|
|
tmplt->setContent(helpPage());
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
sendPage(tmplt);
|
|
delete tmplt;
|
|
|
|
}
|
|
|
|
|
|
void SwordProtocol::mimetype(const KURL& url) {
|
|
mimeType("text/html");
|
|
finished();
|
|
}
|
|
|
|
/* redefine data for TQCStrings so we don't send the trailing
|
|
null */
|
|
void SwordProtocol::data(const TQCString& text) {
|
|
TQByteArray nonull;
|
|
nonull.setRawData(text.data(), text.size()-1);
|
|
SlaveBase::data(nonull);
|
|
nonull.resetRawData(text.data(), text.size()-1);
|
|
}
|
|
|
|
void SwordProtocol::data(const TQByteArray& array) {
|
|
SlaveBase::data(array);
|
|
}
|
|
|
|
void SwordProtocol::readUserConfig()
|
|
{
|
|
m_options.readFromConfig(m_config);
|
|
}
|
|
|
|
TQString SwordProtocol::saveUserConfig()
|
|
{
|
|
TQString message;
|
|
m_options.saveToConfig(m_config);
|
|
m_config->sync();
|
|
// search form depends on settings, so force it to be recreated
|
|
search_form.truncate(0);
|
|
message = "<p>" + i18n("Settings saved.") + "</p>";
|
|
return message;
|
|
}
|
|
|
|
|
|
#define ENUM_OPTION(option, tag, v) \
|
|
if (!strcasecmp(key, tag)) { \
|
|
option = v; \
|
|
}
|
|
|
|
void SwordProtocol::parseURL(const KURL& url)
|
|
{
|
|
// Reset data members that should always be
|
|
// retrieved from URL
|
|
m_action = QUERY;
|
|
m_path = TQString::null;
|
|
m_redirect.module = TQString::null;
|
|
m_redirect.query = TQString::null;
|
|
m_previous.module = TQString::null;
|
|
m_previous.query = TQString::null;
|
|
m_moduletype = DEFMODULETYPE_NONE;
|
|
|
|
if (url.hasPath())
|
|
m_path = url.path();
|
|
|
|
m_options.readFromQueryString(url.queryItems(KURL::CaseInsensitiveKeys));
|
|
|
|
// URLs will be encoded in UTF-8 since they are sometimes
|
|
// generated from the search form, and the browser will
|
|
// encode in UTF-8 since the whole page has UTF-8 charset
|
|
TQMap<TQString, TQString> items = url.queryItems(KURL::CaseInsensitiveKeys, 106);
|
|
TQMap<TQString, TQString>::const_iterator it;
|
|
TQMap<TQString, TQString>::const_iterator it_end = items.end();
|
|
TQString val;
|
|
|
|
const char *key;
|
|
for(it = items.begin(); it != it_end; it++) {
|
|
key = it.key().latin1();
|
|
val = it.data();
|
|
|
|
if (!strcasecmp(key, "query")) {
|
|
m_redirect.query = val;
|
|
}
|
|
else if (!strcasecmp(key, "module")) {
|
|
m_redirect.module = val;
|
|
}
|
|
else if (!strcasecmp(key, "modtype")) {
|
|
if (!strcasecmp(val.latin1(), "bible")) {
|
|
m_moduletype = DEFBIBLE;
|
|
m_action = REDIRECT_QUERY;
|
|
} else if (!strcasecmp(val.latin1(), "greekstrongs")) {
|
|
m_moduletype = GREEKSTRONGS;
|
|
m_action = REDIRECT_QUERY;
|
|
} else if (!strcasecmp(val.latin1(), "hebrewstrongs")) {
|
|
m_moduletype = HEBREWSTRONGS;
|
|
m_action = REDIRECT_QUERY;
|
|
} else if (!strcasecmp(val.latin1(), "greekmorph")) {
|
|
m_moduletype = GREEKMORPH;
|
|
m_action = REDIRECT_QUERY;
|
|
} else if (!strcasecmp(val.latin1(), "hebrewmorph")) {
|
|
m_moduletype = HEBREWMORPH;
|
|
m_action = REDIRECT_QUERY;
|
|
}
|
|
}
|
|
// search
|
|
else if (!strcasecmp(key, "stype")) {
|
|
if (!strcasecmp(val.latin1(), "words")) {
|
|
m_stype = Renderer::SEARCH_WORDS;
|
|
} else if (!strcasecmp(val.latin1(), "phrase")) {
|
|
m_stype = Renderer::SEARCH_PHRASE;
|
|
} else if (!strcasecmp(val.latin1(), "regex")) {
|
|
m_stype = Renderer::SEARCH_REGEX;
|
|
} else {
|
|
m_stype = Renderer::SEARCH_WORDS;
|
|
}
|
|
}
|
|
|
|
// Actions
|
|
else ENUM_OPTION(m_action, "help", HELP)
|
|
else ENUM_OPTION(m_action, "search", SEARCH_FORM)
|
|
else ENUM_OPTION(m_action, "searchq", SEARCH_QUERY)
|
|
else ENUM_OPTION(m_action, "settings", SETTINGS_FORM)
|
|
else ENUM_OPTION(m_action, "savesettings", SETTINGS_SAVE)
|
|
else ENUM_OPTION(m_action, "testsettings", REDIRECT_QUERY)
|
|
|
|
else if (!strcasecmp(key, "previouspath")) {
|
|
m_previous.module = val.section('/', 0, 0, TQString::SectionSkipEmpty);
|
|
m_previous.query = val.section('/', 1, -1, TQString::SectionSkipEmpty);
|
|
}
|
|
}
|
|
|
|
// Once all the URL is parsed:
|
|
if ((m_action == QUERY) && (
|
|
!m_redirect.query.isEmpty() || !m_redirect.module.isEmpty()))
|
|
m_action = REDIRECT_QUERY;
|
|
}
|
|
|
|
#undef ENUM_OPTION
|
|
|
|
|
|
void SwordProtocol::sendPage(const Template* tplt) {
|
|
data(tplt->render(m_options));
|
|
data(TQByteArray()); // empty array means we're done sending the data
|
|
finished();
|
|
}
|
|
|
|
/** Returns a string representing notes about an option for the settings page
|
|
*/
|
|
template <class T>
|
|
TQString optionNotes(const Option<T>& option)
|
|
{
|
|
TQString output;
|
|
if (!option.m_propagate)
|
|
{
|
|
output += "<sup>1</sup>";
|
|
}
|
|
if (option.m_configName.isNull())
|
|
{
|
|
if (output.length() > 0)
|
|
{
|
|
output += "<sup>,</sup>";
|
|
}
|
|
output += "<sup>2</sup>";
|
|
}
|
|
return output;
|
|
}
|
|
|
|
|
|
/** HTML for a boolean option */
|
|
TQString settingsBooleanOptionRow(const TQString& description, const Option<bool>& option) {
|
|
static const TQString boolean_option_row(
|
|
"<tr><td>%1</td><td><nobr><input type='radio' name='%2' value='1' %3>%4 <input type='radio' name='%2' value='0' %5>%6</nobr></td><td>%2, %7</td></tr>");
|
|
return boolean_option_row
|
|
.arg(description + optionNotes(option))
|
|
.arg(option.m_qsShortName)
|
|
.arg(option.m_qsShortName)
|
|
.arg(option.m_qsShortName)
|
|
.arg(option() ? "checked" : "")
|
|
.arg(i18n("On"))
|
|
.arg(option() ? "" : "checked")
|
|
.arg(i18n("Off"))
|
|
.arg(option.m_qsLongName);
|
|
}
|
|
/** */
|
|
|
|
/** HTML for a general option row
|
|
*
|
|
* @param description User visible description of option
|
|
* @param option option metadata
|
|
* @param optionList HTML containing the <option>s
|
|
* @return
|
|
*/
|
|
TQString settingsGeneralOptionRow(const TQString& description, const Option<TQString>& option,
|
|
const TQString& optionList)
|
|
{
|
|
static const TQString general_option_row(
|
|
"<tr><td>%1</td><td><select name='%2'>%3</select></td><td>%4, %5</td></tr>");
|
|
return general_option_row
|
|
.arg(description + optionNotes(option))
|
|
.arg(option.m_qsLongName)
|
|
.arg(optionList)
|
|
.arg(option.m_qsShortName)
|
|
.arg(option.m_qsLongName);
|
|
}
|
|
|
|
TQString SwordProtocol::settingsForm() {
|
|
TQString output;
|
|
TQStringList modules;
|
|
TQStringList::Iterator it;
|
|
TQString temp;
|
|
|
|
static const TQString separator_row(
|
|
"<tr><td class='settingscategory' colspan='3'>%1</td></tr>");
|
|
|
|
|
|
// Start output
|
|
output += i18n("<h1>Settings</h1>"
|
|
"<p>Select the settings using the form below. Use the 'Save settings' button to "
|
|
" save these settings to your own configuration file. 'Test settings' will return "
|
|
" you to the previous page with the options you have specified. <br>");
|
|
|
|
output += TQString(
|
|
"<form action='sword:/' method='GET'>"
|
|
"<table class='settings' border=0 cellspacing=0>"
|
|
" <tr><th>%1</th><th>%2</th><th>%4</th></tr>")
|
|
.arg(i18n("Description"))
|
|
.arg(i18n("Value"))
|
|
.arg(i18n("URL parameter"));
|
|
|
|
output += separator_row.arg(i18n("Formatting options"));
|
|
output += settingsBooleanOptionRow(i18n("Display verse numbers for Bible modules"), m_options.verseNumbers);
|
|
output += settingsBooleanOptionRow(i18n("Insert line breaks between Bible verses"), m_options.verseLineBreaks);
|
|
output += settingsBooleanOptionRow(i18n("Include footnotes."), m_options.footnotes);
|
|
output += settingsBooleanOptionRow(i18n("Words of Christ in red."), m_options.redWords);
|
|
output += settingsBooleanOptionRow(i18n("Display strongs numbers (for Bibles that include them)."), m_options.strongs);
|
|
output += settingsBooleanOptionRow(i18n("Display morphological tags (for Bibles that include them)."), m_options.morph);
|
|
|
|
output += separator_row.arg(i18n("Language"));
|
|
|
|
// Locale
|
|
TQStringList locales = m_renderer.availableLocales();
|
|
temp = "";
|
|
for (int i = 0; i < locales.size(); i++)
|
|
{
|
|
temp += TQString("<option value='%1' %3>%2</option>")
|
|
.arg(locales[i])
|
|
.arg(locales[i])
|
|
.arg((m_options.locale() == locales[i]) ? "selected" : "");
|
|
}
|
|
output += settingsGeneralOptionRow(i18n("Locale"), m_options.locale, temp);
|
|
|
|
// Formatting options
|
|
output += settingsBooleanOptionRow(i18n("Use Hebrew cantillation."), m_options.cantillation);
|
|
output += settingsBooleanOptionRow(i18n("Show Hebrew vowel points."), m_options.hebrewVowelPoints);
|
|
output += settingsBooleanOptionRow(i18n("Show Greek accents."), m_options.greekAccents);
|
|
|
|
output += separator_row.arg(i18n("Navigation options"));
|
|
output += settingsBooleanOptionRow(i18n("Display the whole book when a Bible book is selected, instead of an index of the chapters"),
|
|
m_options.wholeBook);
|
|
output += settingsBooleanOptionRow(i18n("Display the booklist for bibles if no book is requested"),
|
|
m_options.doBibleIndex);
|
|
output += settingsBooleanOptionRow(i18n("Display an index for dictionaries if no entry is requested"),
|
|
m_options.doDictIndex);
|
|
output += settingsBooleanOptionRow(i18n("Display an index for other books if no entry is request"),
|
|
m_options.doOtherIndex);
|
|
output += settingsBooleanOptionRow(i18n("Display a full index for books that have a multiple level index, instead of just the first level"),
|
|
m_options.doFullTreeIndex);
|
|
|
|
|
|
// Default modules
|
|
output += separator_row.arg(i18n("Default modules"));
|
|
modules = m_renderer.moduleList();
|
|
|
|
vector<TQString> dm_desc;
|
|
vector<Option<TQString> > dm_options;
|
|
vector<TQString>::size_type i;
|
|
dm_desc.push_back(i18n("Default Bible"));
|
|
dm_options.push_back(m_options.defaultBible);
|
|
|
|
dm_desc.push_back(i18n("Default Greek Strong's Lexicon"));
|
|
dm_options.push_back(m_options.defaultGreekStrongs);
|
|
|
|
dm_desc.push_back(i18n("Default Hebrew Strong's Lexicon"));
|
|
dm_options.push_back(m_options.defaultHebrewStrongs);
|
|
|
|
dm_desc.push_back(i18n("Default Greek Morphological Lexicon"));
|
|
dm_options.push_back(m_options.defaultGreekMorph);
|
|
|
|
dm_desc.push_back(i18n("Default Hebrew Morphological Lexicon"));
|
|
dm_options.push_back(m_options.defaultHebrewMorph);
|
|
|
|
for (i = 0; i < dm_options.size(); i++) {
|
|
temp = TQString("<option value='' %1> </option>")
|
|
.arg(dm_options[i]().stripWhiteSpace().isEmpty() ? "selected" : "");
|
|
|
|
for (it = modules.begin(); it != modules.end(); ++it ) {
|
|
temp += TQString("<option value='%1' %3>%2</option>")
|
|
.arg(*it)
|
|
.arg(*it)
|
|
.arg(((*it) == dm_options[i]() ? "selected" : ""));
|
|
}
|
|
output += settingsGeneralOptionRow(dm_desc[i], dm_options[i], temp);
|
|
}
|
|
|
|
// Misc options
|
|
output += separator_row.arg(i18n("Other options"));
|
|
output += settingsBooleanOptionRow(i18n("Make formatting options propagate. This makes Kio-Sword remember formatting settings that you have set, by propagating them in the links. (Some navigation options are always excluded from this behaviour)."),
|
|
m_options.propagate);
|
|
|
|
output += TQString("</table>");
|
|
|
|
output += i18n("<p>Notes:<br/>"
|
|
"1) These options never propagate<br/>"
|
|
"2) These options are never saved<br/></p>");
|
|
|
|
output += TQString(
|
|
"<br><input type='hidden' name='module' value='%1'>" // redirection path
|
|
"<input type='hidden' name='query' value='%2'>" // redirection path
|
|
"<input type='submit' name='testsettings' value='%3'> " // "Test settings"
|
|
"<input type='submit' name='savesettings' value='%4''>" // "Save settings"
|
|
"</form>")
|
|
.arg(m_previous.module)
|
|
.arg(m_previous.query)
|
|
.arg(i18n("Test settings"))
|
|
.arg(i18n("Save settings"));
|
|
|
|
output += i18n("<hr><h1>Stylesheet</h1>"
|
|
"<p>To further customise the appearance of the Kio-Sword page, you can make your own modified "
|
|
"version of the style sheet. "
|
|
"Simply copy the file '%1kio_sword/tdeio_sword.css' to $HOME/.kde/share/apps/tdeio_sword/ and modify it as desired. You may want to use the 'simplepage' option above to make the most of this.</p>")
|
|
.arg(TDEGlobal::dirs()->findResourceDir("data", "tdeio_sword/tdeio_sword.css")); // FIXME - this must always return the system dir, not users dir.
|
|
|
|
|
|
return output;
|
|
}
|
|
|
|
TQString SwordProtocol::helpPage() {
|
|
if (help_page.isEmpty()) {
|
|
help_page += i18n("<h1>Help</h1>"
|
|
"<p>For full documentation, see <a href=\"help:/tdeio_sword\">installed help files</a>.</p>"
|
|
"<p>Kio-Sword allows you to view SWORD modules (such as Bibles and commentaries) from Konqueror.\n"
|
|
" These modules must already be installed - you can download them from <a href=\"http://www.crosswire.org/\">"
|
|
"crosswire.org</a> or you can use a program such as <a href=\"http:/www.bibletime.info\">BibleTime</a> to help"
|
|
" install them."
|
|
"<h3>Quick help</h3>\n"
|
|
"<ul>\n"
|
|
" <li>To start, simply type <b><a href=\"sword:/\">sword:/</a></b> in the location bar, and follow the links like any normal web page<br /><br />\n"
|
|
" <li>You can type the exact reference in the Location bar, instead of browsing to it, e.g.<br />\n"
|
|
" <b>sword:/KJV/Hebrews 1:3-5</b> will look up Hebrews chapter 1 verses 3 to 5 in the King James Bible.<br /><br /></li>\n"
|
|
" <li>You can specify various formatting options in the URL - see <a href=\"sword:/?settings\">Settings</a> for more info.<br /><br /></li>\n"
|
|
" <li>To use your default Bible, just omit the first forward slash: <b>sword:Hebs 1:3-5</b> <br /><br /></li>\n"
|
|
" <li>You can bookmark Kio-Sword pages just like any other web page.<br /><br /></li>\n"
|
|
" <li>You can use keyboards shortcuts - press 'Ctrl' to activate 'Acess Keys' in Konqueror, \n"
|
|
" and the following shortcuts are then available:"
|
|
" <ul><li>'u' to go up</li>\n"
|
|
" <li>'n' for next section/chapter</li>\n"
|
|
" <li>'p' for previous section/chapter</li>\n"
|
|
" <li>'t' for the module list</li>\n"
|
|
" <li>'v' to toggle verse numbers</li>\n"
|
|
" <li>'l' to toggle line breaks between verses</li>\n"
|
|
" <li>'s' to toggle Strongs numbers</li>\n"
|
|
" <li>'m' to toggle morphological tags</li>\n"
|
|
" </ul>\n"
|
|
" (Depending on the context, some of these will either not be available or won't be much use).<br/><br/>"
|
|
" Also, remember the following Konqueror shortcuts to make keyboard navigation even better:<br/>"
|
|
" <b>/</b> starts find-as-you-type<br/>"
|
|
" <b>'</b> starts find-as-you-type for link text<br/>"
|
|
" </li>\n"
|
|
"</ul>\n"
|
|
"<p>Problems, comments, feature requests? Email the author. "
|
|
"<p>Author: <a href=\"mailto:L.Plant.98@cantab.net\">L.Plant.98@cantab.net</a>"
|
|
"<p>Website: <a href=\"http://lukeplant.me.uk/tdeio-sword/\">http://lukeplant.me.uk/tdeio-sword/</a>.");
|
|
}
|
|
return help_page;
|
|
}
|
|
|
|
TQString SwordProtocol::searchForm(const SwordOptions& options) {
|
|
static const TQString search_form_tmpl(
|
|
"<h1 class='searchform'>%1</h1>" // title
|
|
"<div class='searchform'>"
|
|
"<form action='sword:/' method='GET'>"
|
|
" <table class='searchform'>"
|
|
" <tr>"
|
|
" <td><label for='query'>%2</label></td>" // Search terms
|
|
" <td><input type='text' name='query'></td>"
|
|
" </tr>"
|
|
" <tr>"
|
|
" <td><label for='module'>%3</label></td>" // Module
|
|
" <td><select name='module'>"
|
|
" %4</select></td>" // (list of modules)
|
|
" </tr>"
|
|
" <tr>"
|
|
" <td valign='top'><label for='stype'>%5</label></td>" // Search type
|
|
" <td><input type='radio' name='stype' value='words' checked>%6<br>" // words
|
|
" <input type='radio' name='stype' value='phrase'>%7<br>" // phrase
|
|
" <input type='radio' name='stype' value='regex'>%8" // regex
|
|
" </td>"
|
|
" </tr>"
|
|
" <tr>"
|
|
" <td colspan='2' align='center'><input type='submit' name='searchq' value='%9'></td>" // Search
|
|
" </tr>"
|
|
" </table>"
|
|
"</form>"
|
|
"</div>");
|
|
|
|
if (search_form.isEmpty()) { // avoid calculating this twice
|
|
TQStringList modules = m_renderer.moduleList();
|
|
TQString temp;
|
|
TQStringList::Iterator it;
|
|
|
|
temp = "<option value=''></option>";
|
|
for (it = modules.begin(); it != modules.end(); ++it ) {
|
|
temp += TQString("<option value='%1' %3>%2</option>")
|
|
.arg(*it)
|
|
.arg(*it)
|
|
.arg((*it == m_options.defaultBible()) ? "selected='selected'" : "");
|
|
}
|
|
search_form = search_form_tmpl
|
|
.arg(i18n("Search"))
|
|
.arg(i18n("Search terms"))
|
|
.arg(i18n("Module"))
|
|
.arg(temp)
|
|
.arg(i18n("Search type"))
|
|
.arg(i18n("Words"))
|
|
.arg(i18n("Phrase"))
|
|
.arg(i18n("Regular expression"))
|
|
.arg(i18n("Search"));
|
|
}
|
|
// search_form is generated once, but we need to modify
|
|
// form each time to include propagated values
|
|
TQString output(search_form);
|
|
return output.replace("</form>", optionsAsHiddenFields(options) + "</form>");
|
|
}
|
|
}
|