Commit 11c8a5eb authored by Victor Yacovlev's avatar Victor Yacovlev

DocBookViewer: implemented List of Algorithms

parent 95bb198e
......@@ -191,18 +191,36 @@ QString ContentView::renderElement(ModelPtr data) const
else if (data == DocBookModel::Entry) {
return renderEntry(data);
}
else if (data == DocBookModel::Subscript) {
return renderSubscript(data);
}
else if (data == DocBookModel::Superscript) {
return renderSuperscript(data);
}
else if (data == DocBookModel::InlineMediaObject) {
return renderInlineMediaObject(data);
}
else if (data == DocBookModel::ImageObject) {
return renderImageObject(data);
}
else if (data == DocBookModel::FuncSynopsys) {
return renderFuncSynopsys(data);
}
else if (data == DocBookModel::Function) {
return renderFunction(data);
}
else if (data == DocBookModel::Parameter) {
return renderParameter(data);
}
else if (data == DocBookModel::ListOfExamples) {
return renderListOfExamples(data);
}
else if (data == DocBookModel::ListOfTables) {
return renderListOfTables(data);
}
else if (data == DocBookModel::ListOfFunctions) {
return renderListOfFunctions(data);
}
else {
return "";
}
......@@ -295,28 +313,7 @@ QString ContentView::renderCode(ModelPtr data) const
const QString programText = renderChilds(data);
result += programTextForLanguage(programText, data->role());
result += "</span>";
ModelPtr parent = data->parent();
if (parent) {
int index = parent->children().indexOf(data);
ModelPtr left, right;
if (index > 0) {
left = parent->children()[index-1];
}
if (index < parent->children().size() - 1) {
right = parent->children()[index+1];
}
if (left == DocBookModel::Text && left->text().length() > 0) {
const QChar achar = left->text()[left->text().length()-1];
if (achar != '(' && achar != '[' && achar != '"' && achar != '\'')
result = " " + result;
}
if (right == DocBookModel::Text && right->text().length() > 0) {
const QChar achar = right->text()[0];
if (!achar.isPunct() || achar == '(' || achar =='[' || achar == '-')
result = result + " ";
}
}
return wrapInlineElement(data, result, true, true);
return result;
}
......@@ -625,21 +622,184 @@ QString ContentView::renderExample(ModelPtr data) const
return result;
}
QString ContentView::renderFuncSynopsys(ModelPtr data) const
{
QString result;
result += "<a name='" + modelToLink(data) + "'></a>";
ModelPtr info, prototype;
foreach (ModelPtr child, data->children()) {
if (child == DocBookModel::FuncSynopsysInfo)
info = child;
else if (child == DocBookModel::FuncPrototype)
prototype = child;
}
if (loadedModel_ == data->indexParent()) {
result += "<h2 align='left' style='margin: 0;'>" +
tr("Algorithm ") +
"<span style='font-weight:normal;'>" +
normalizeText(data->title()) + "</span>" +
"</h2>\n";
if (info)
result += renderFuncSynopsysInfo(info);
}
if (prototype) {
result += "<table border='0' width='100%'><tr><td>";
result += "<tr><td height='10'>&nbsp;</td></tr>\n";
result += "<b>" + tr("Synopsis:") + "</b>";
result += "</td></tr><tr><td>";
result += "<table border='1' bordercolor='gray' cellspacing='0' cellpadding='10' width='100%'>";
result += "<tr><td>";
result += renderFuncPrototype(prototype);
result += "</td></tr><table></td></tr></table>\n";
}
if (loadedModel_ == data->indexParent() && data->parent()) {
int from = data->parent()->children().indexOf(data);
for (int i=from + 1; i<data->parent()->children().size(); i++) {
ModelPtr child = data->parent()->children()[i];
if (child == DocBookModel::Para) {
result += renderParagraph(child);
}
else if (child == DocBookModel::FuncSynopsysInfo) {
break;
}
}
}
if (loadedModel_ == data->indexParent()) {
result += "<hr/>";
}
return result;
}
QString ContentView::renderFunction(ModelPtr data) const
{
QString result;
result += "<span class='code'>" + renderChilds(data) + "</span>";
wrapInlineElement(data, result, true, data->parent() != DocBookModel::FuncDef);
return result;
}
QString ContentView::renderParameter(ModelPtr data) const
{
QString result;
result += "<span class='code'><i>" + renderChilds(data) + "</i></span>";
wrapInlineElement(data, result, true, data->parent() != DocBookModel::ParamDef);
return result;
}
QString ContentView::renderFuncSynopsysInfo(ModelPtr data) const
{
QString result;
return result;
}
QString ContentView::renderFuncPrototype(ModelPtr data) const
{
QString result;
ModelPtr funcdef;
QList<ModelPtr> paramdefs;
foreach (ModelPtr child, data->children()) {
if (child == DocBookModel::FuncDef)
funcdef = child;
else if (child == DocBookModel::ParamDef)
paramdefs.push_back(child);
}
result += "<pre class='code'>";
if (funcdef)
result += renderFuncDef(funcdef);
const QString lang = data->role().toLower().trimmed();
bool requireBraces = lang=="c" || lang=="c++" || lang=="python";
if (paramdefs.size() > 0 || requireBraces)
result += "(";
foreach (ModelPtr paramdef, paramdefs) {
if (paramdefs.indexOf(paramdef) > 0)
result += ",&nbsp;";
result += renderParamDef(paramdef);
}
if (paramdefs.size() > 0 || requireBraces)
result += ")";
result += "</pre>";
return result;
}
QString ContentView::renderFuncDef(ModelPtr data) const
{
QString result;
QString lang = data->role();
ModelPtr parent = data->parent();
while (parent && lang.length() == 0) {
lang = parent->role();
parent = parent->parent();
}
foreach (ModelPtr child, data->children()) {
if (child == DocBookModel::Text)
result += programTextForLanguage(child->text(), lang);
else
result += renderElement(child);
}
return result;
}
QString ContentView::renderParamDef(ModelPtr data) const
{
QString result;
QString lang = data->role();
ModelPtr parent = data->parent();
while (parent && lang.length() == 0) {
lang = parent->role();
parent = parent->parent();
}
foreach (ModelPtr child, data->children()) {
if (child == DocBookModel::Text)
result += programTextForLanguage(child->text(), lang);
else
result += renderElement(child);
}
return result;
}
QString ContentView::renderEmphasis(ModelPtr data) const
{
const QString tag = data->role()=="bold" ? "b" : "i";
QString result = "<" + tag + ">";
result += renderChilds(data);
result += "</" + tag + ">";
return wrapInlineElement(data, result, true, true);
}
QString ContentView::renderSubscript(ModelPtr data) const
{
QString result = "<sub>";
result += renderChilds(data);
result += "</sub>";
return wrapInlineElement(data, result, false, true);
}
QString ContentView::renderSuperscript(ModelPtr data) const
{
QString result = "<sup>";
result += renderChilds(data);
result += "</sup>";
return wrapInlineElement(data, result, false, true);
}
QString& ContentView::wrapInlineElement(ModelPtr data, QString & result,
bool processLeft, bool processRight)
{
ModelPtr parent = data->parent();
if (parent) {
int index = parent->children().indexOf(data);
ModelPtr left, right;
if (index > 0) {
if (processLeft && index > 0) {
left = parent->children()[index-1];
}
if (index < parent->children().size() - 1) {
if (processRight && index < parent->children().size() - 1) {
right = parent->children()[index+1];
}
if (left == DocBookModel::Text && left->text().length() > 0) {
......@@ -729,6 +889,14 @@ QString ContentView::renderListOfTables(ModelPtr data) const
return result;
}
QString ContentView::renderListOfFunctions(ModelPtr data) const
{
QString result;
result += renderTOC(data);
result += renderChilds(data);
return result;
}
QVariant ContentView::loadResource(int type, const QUrl &name)
{
QVariant result;
......@@ -875,7 +1043,7 @@ QString ContentView::renderXref(ModelPtr data) const
.arg(targetTitle);
}
}
return result;
return wrapInlineElement(data, result, true, true);
}
ModelPtr ContentView::findModelById(
......@@ -916,6 +1084,7 @@ ModelPtr ContentView::onePageParentModel(ModelPtr data) const
data->modelType() == DocBookModel::Article ||
data->modelType() == DocBookModel::ListOfExamples ||
data->modelType() == DocBookModel::ListOfTables ||
data->modelType() == DocBookModel::ListOfFunctions ||
data->modelType() == DocBookModel::Book)
{
return data;
......@@ -981,6 +1150,12 @@ QString ContentView::renderTOC(ModelPtr data) const
else if (data == DocBookModel::ListOfTables) {
title = tr("List of tables in \"%1\"").arg(data->title());
}
else if (data == DocBookModel::ListOfFunctions) {
if (data->title().isEmpty())
title = tr("List of Standard Library algorithms");
else
title = tr("List of algorithms of module \"%1\"").arg(data->title());
}
else {
title = sectionNumber(data) + "&nbsp;" + data->title();
}
......@@ -1018,6 +1193,9 @@ QString ContentView::renderTOCElement(ModelPtr data, quint8 level, bool enumerat
? tr("Example&nbsp;%1. ").arg(index)
: tr("Table&nbsp;%1. ").arg(index);
}
else if (data == DocBookModel::FuncSynopsys) {
QString::number(elementNumber(data));
}
else {
index = sectionNumber(data) + " ";
}
......
......@@ -50,6 +50,10 @@ private:
QString renderCode(ModelPtr data) const;
QString renderKeyCombo(ModelPtr data) const;
QString renderKeySym(ModelPtr data) const;
QString renderSubscript(ModelPtr data) const;
QString renderSuperscript(ModelPtr data) const;
static QString& wrapInlineElement(ModelPtr data, QString & result,
bool left, bool right);
QString renderInformalTable(ModelPtr data) const;
QString renderTable(ModelPtr data) const;
......@@ -62,7 +66,16 @@ private:
QString renderInlineMediaObject(ModelPtr data) const;
QString renderImageObject(ModelPtr data) const;
QString renderFuncSynopsys(ModelPtr data) const;
QString renderFuncSynopsysInfo(ModelPtr data) const;
QString renderFuncPrototype(ModelPtr data) const;
QString renderFuncDef(ModelPtr data) const;
QString renderFunction(ModelPtr data) const;
QString renderParamDef(ModelPtr data) const;
QString renderParameter(ModelPtr data) const;
QString renderListOfExamples(ModelPtr data) const;
QString renderListOfFunctions(ModelPtr data) const;
QString renderListOfTables(ModelPtr data) const;
bool isPlainPage(ModelPtr data) const;
......
......@@ -193,6 +193,33 @@ bool DocBookFactory::startElement(
else if (element == "imagedata") {
model = new DocBookModel(root_, DocBookModel::ImageData);
}
else if (element == "subscript") {
model = new DocBookModel(root_, DocBookModel::Subscript);
}
else if (element == "superscript") {
model = new DocBookModel(root_, DocBookModel::Superscript);
}
else if (element == "funcsynopsis") {
model = new DocBookModel(root_, DocBookModel::FuncSynopsys);
}
else if (element == "funcsynopsisinfo") {
model = new DocBookModel(root_, DocBookModel::FuncSynopsysInfo);
}
else if (element == "funcprototype") {
model = new DocBookModel(root_, DocBookModel::FuncPrototype);
}
else if (element == "funcdef") {
model = new DocBookModel(root_, DocBookModel::FuncDef);
}
else if (element == "function") {
model = new DocBookModel(root_, DocBookModel::Function);
}
else if (element == "paramdef") {
model = new DocBookModel(root_, DocBookModel::ParamDef);
}
else if (element == "parameter") {
model = new DocBookModel(root_, DocBookModel::Parameter);
}
else if (element == "xref") {
model = new DocBookModel(root_, DocBookModel::Xref);
model->xrefLinkEnd_ = atts.value("linkend");
......@@ -273,9 +300,9 @@ bool DocBookFactory::characters(const QString &ch)
buffer_ += ch;
}
else {
if (buffer_.length() > 0 && ch.trimmed().length() > 0) {
buffer_.push_back(' ');
}
// if (buffer_.length() > 0 && ch.trimmed().length() > 0) {
// buffer_.push_back(' ');
// }
buffer_ += ch.simplified();
}
return true;
......@@ -298,6 +325,14 @@ bool DocBookFactory::skippedEntity(const QString &name)
else if (name == "ge") {
buffer_.push_back(QChar(0x2265)); // greater or equal
}
else if (name == "times") {
// See: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
buffer_.push_back(QChar(0x00D7)); // multiplication sign
}
else if (name == "hellip") {
// See: http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent
buffer_.push_back(QChar(0x2026)); // three dots at bottom
}
return true;
}
......@@ -313,6 +348,10 @@ bool DocBookFactory::endElement(const QString &namespaceURI,
<< "preface" << "abstract" << "reference"
<< "informaltable" << "table" << "thead" << "tbody" << "row" << "entry"
<< "inlinemediaobject" << "imageobject" << "imagedata"
<< "subscript" << "superscript"
<< "funcsynopsis" << "funcsynopsisinfo" << "package"
<< "funcprototype" << "funcdef" << "function"
<< "paramdef" << "parameter"
<< "emphasis" << "xref" << "keycombo" << "keysym";
const QString element = localName.toLower();
if (root_ && element == "title") {
......@@ -324,6 +363,20 @@ bool DocBookFactory::endElement(const QString &namespaceURI,
buffer_.clear();
}
else if (root_ && tagsToClose.contains(element)) {
if (root_->title().isEmpty()) {
if (root_ == DocBookModel::Example || root_ == DocBookModel::FuncSynopsys) {
ModelPtr parent = root_->parent();
while (parent) {
if (parent == DocBookModel::Section
&& !parent->title().isEmpty())
{
root_->title_ = parent->title();
break;
}
parent = parent->parent();
}
}
}
if (buffer_.length() > 0) {
DocBookModel* text = new DocBookModel(root_, DocBookModel::Text);
text->text_ = buffer_;
......@@ -405,4 +458,50 @@ ModelPtr DocBookFactory::createListOfEntries(ModelPtr root,
return result;
}
QMap<QString, ModelPtr> & DocBookFactory::updateListOfAlgorithms(
ModelPtr root,
QMap<QString, ModelPtr> &result)
{
QList<ModelPtr> allItems = findEntriesOfType(root, DocBookModel::FuncSynopsys);
foreach (ModelPtr item, allItems) {
QString moduleName;
QList<ModelPtr> infos = findEntriesOfType(item,
DocBookModel::FuncSynopsysInfo);
if (infos.size() > 0) {
ModelPtr info = infos.first();
QList<ModelPtr> packages = findEntriesOfType(info,
DocBookModel::Package);
if (packages.size() > 0) {
ModelPtr package = packages.first();
foreach (ModelPtr packageChild, package->children()) {
if (packageChild == DocBookModel::Text) {
if (moduleName.length() > 0)
moduleName += " ";
moduleName += packageChild->text().trimmed();
}
}
}
}
ModelPtr moduleRoot;
if (result.contains(moduleName)) {
moduleRoot = result[moduleName];
}
else {
moduleRoot = ModelPtr(new DocBookModel(
ModelPtr(),
DocBookModel::ListOfFunctions
)
);
result[moduleName] = moduleRoot;
moduleRoot->title_ = moduleName;
}
item->indexParent_ = moduleRoot;
moduleRoot->children_.append(item);
}
return result;
}
}
......@@ -22,6 +22,8 @@ public:
DocBookModel::ModelType resType,
DocBookModel::ModelType findType
);
static QMap<QString,ModelPtr> &
updateListOfAlgorithms(ModelPtr root, QMap<QString,ModelPtr> &result);
......
......@@ -55,10 +55,22 @@ public:
InlineMediaObject,
ImageObject,
ImageData,
Subscript,
Superscript,
FuncSynopsys,
FuncSynopsysInfo,
FuncPrototype,
FuncDef,
ParamDef,
Function,
Parameter,
Package,
// virtual entries
ListOfExamples,
ListOfTables
ListOfTables,
ListOfFunctions
};
quint8 sectionLevel() const;
......@@ -112,4 +124,10 @@ inline bool operator==(const DocBookViewer::ModelPtr & model,
return model && model->modelType() == type;
}
inline bool operator!=(const DocBookViewer::ModelPtr & model,
DocBookViewer::DocBookModel::ModelType type)
{
return ! (model && model->modelType() == type);
}
#endif
......@@ -12,11 +12,11 @@ SidePanel::SidePanel(QWidget *parent) :
{
ui->setupUi(this);
static const QList<QPushButton*> buttons = QList<QPushButton*>()
<< ui->contents << ui->index << ui->examples << ui->tables;
<< ui->contents << ui->algorithms << ui->examples << ui->tables;
static const QList<QTreeWidget*> treeWidgets = QList<QTreeWidget*>()
<< ui->contentsNavigator << ui->examplesNavigator
<< ui->tablesNavigator;
<< ui->contentsNavigator << ui->algorithmsNavigator
<< ui->examplesNavigator << ui->tablesNavigator;
foreach (QPushButton* button, buttons) {
connect(button, SIGNAL(clicked()), this, SLOT(hadleButtonPressed()));
......@@ -51,6 +51,7 @@ void SidePanel::addDocument(Document document)
createNavigationItems(item, model);
createListOfExamples(model);
createListOfTables(model);
createListOfAlgorithms(model);
modelsOfItems_[item] = model;
itemsOfModels_[model] = item;
}
......@@ -60,7 +61,7 @@ void SidePanel::hadleButtonPressed()
{
QObject * who = sender();
static const QList<QPushButton*> buttons = QList<QPushButton*>()
<< ui->contents << ui->index << ui->examples << ui->tables;
<< ui->contents << ui->algorithms << ui->examples << ui->tables;
for (int index = 0; index < buttons.size() ; index ++) {
if (who == buttons[index]) {
......@@ -77,8 +78,8 @@ void SidePanel::saveState(QSettings *settings, const QString &prefix)
QString shown;
if (ui->contents->isChecked())
shown = "Contents";
else if (ui->index->isChecked())
shown = "Index";
else if (ui->algorithms->isChecked())
shown = "Algorithms";
else if (ui->examples->isChecked())
shown = "Examples";
else if (ui->tables->isChecked())
......@@ -91,28 +92,28 @@ void SidePanel::restoreState(QSettings *settings, const QString &prefix)
QString shown = settings->value(prefix + "/ShowMode").toString().toLower();
if (shown == "contents") {
ui->contents->setChecked(true);
ui->index->setChecked(false);
ui->algorithms->setChecked(false);
ui->examples->setChecked(false);
ui->tables->setChecked(false);
ui->stackedWidget->setCurrentIndex(0);
}
else if (shown == "index") {
else if (shown == "algorithms") {
ui->contents->setChecked(false);
ui->index->setChecked(true);
ui->algorithms->setChecked(true);
ui->examples->setChecked(false);
ui->tables->setChecked(false);
ui->stackedWidget->setCurrentIndex(1);
}
else if (shown == "examples") {
ui->contents->setChecked(false);
ui->index->setChecked(false);
ui->algorithms->setChecked(false);
ui->examples->setChecked(true);
ui->tables->setChecked(false);
ui->stackedWidget->setCurrentIndex(2);
}
else if (shown == "tables") {
ui->contents->setChecked(false);
ui->index->setChecked(false);
ui->algorithms->setChecked(false);
ui->examples->setChecked(false);