Assistant has a left-side content panel now.

This commit is contained in:
Matthias Koefferlein 2017-09-08 00:25:17 +02:00
parent fd36ee37d9
commit 468c3f4952
6 changed files with 517 additions and 159 deletions

View File

@ -1186,6 +1186,10 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "<a name=\"detailed\"/><h2>" << tl::to_string (QObject::tr ("Detailed description")) << "</h2>" << std::endl;
std::string prev_title;
os << "<table>";
for (std::multimap <std::string, std::pair<const gsi::MethodBase *, size_t> >::const_iterator i = mm.begin (); i != mm.end (); ++i, ++n) {
const gsi::MethodBase::MethodSynonym &syn = i->second.first->begin_synonyms () [i->second.second];
@ -1195,14 +1199,23 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "<a name=\"method" << n << "\"/>"
<< "<a name=\"m_" << escape_xml (i->first) << "\"/>"
<< "<keyword title=\"" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << ", " << tl::to_string (QObject::tr ("Method")) << " " << escape_xml (i->first) << "\" name=\"" << escape_xml (cls) << "#" << escape_xml (i->first) << "\"/>" << std::endl;
os << "<h3>";
os << "<tr><td>";
if (i->first != prev_title) {
os << "<h3>" << escape_xml (i->first) << "</h3>" << std::endl;
prev_title = i->first;
}
os << "</td><td style=\"padding-bottom: 16px\">";
os << "<p><b>" << tl::to_string (QObject::tr ("Signature")) << "</b>: ";
std::string attr = method_attributes (i->second.first, method_doc);
if (! attr.empty ()) {
os << "<i>[" << escape_xml (attr) << "] </i>";
}
os << method_return (i->second.first, method_doc, true) << " " << escape_xml (i->first) << method_arguments (i->second.first, cls_obj, method_doc, true, "");
os << "</h3>" << std::endl;
os << method_return (i->second.first, method_doc, true) << " <b> " << escape_xml (i->first) << " </b> " << method_arguments (i->second.first, cls_obj, method_doc, true, "");
os << "</p>" << std::endl;
os << "<div style=\"margin-left: 10px\">";
os << "<p><b>" << tl::to_string (QObject::tr ("Description")) << "</b>: " << replace_references (escape_xml (method_doc.brief_doc), cls_obj) << "</p>" << std::endl;
@ -1237,8 +1250,13 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
}
}
os << "</div>";
os << "</td></tr>";
}
os << "</table>";
os << "</doc>" << std::endl;
return os.str ();

View File

@ -195,6 +195,7 @@ static QString class_doc_element = QString::fromUtf8 ("class_doc");
static QString doc_element = QString::fromUtf8 ("doc");
static QString h2_element = QString::fromUtf8 ("h2");
static QString h2_index_element = QString::fromUtf8 ("h2-index");
static QString h3_element = QString::fromUtf8 ("h3");
static QString href_attribute = QString::fromUtf8 ("href");
static QString name_attribute = QString::fromUtf8 ("name");
static QString title_attribute = QString::fromUtf8 ("title");
@ -541,10 +542,19 @@ HelpSource::get_css (const std::string &u)
std::string
HelpSource::get (const std::string &u)
{
return process (get_dom (u), u);
BrowserOutline ol;
return process (get_dom (u), u, ol);
}
std::string
BrowserOutline
HelpSource::get_outline (const std::string &u)
{
BrowserOutline ol;
process (get_dom (u), u, ol);
return ol;
}
std::string
HelpSource::next_topic (const std::string &url)
{
std::string u = tl::to_string (QUrl::fromEncoded (url.c_str ()).path ());
@ -724,7 +734,7 @@ HelpSource::parent_of (const std::string &path)
}
std::string
HelpSource::process (const QDomDocument &doc, const std::string &path)
HelpSource::process (const QDomDocument &doc, const std::string &path, BrowserOutline &ol)
{
QBuffer output;
output.open (QIODevice::WriteOnly);
@ -733,7 +743,7 @@ HelpSource::process (const QDomDocument &doc, const std::string &path)
QXmlStreamWriter writer (&output);
writer.writeStartDocument (QString::fromUtf8 ("1.0"));
process (doc.documentElement (), path, writer);
process (doc.documentElement (), path, writer, ol);
writer.writeEndDocument ();
output.close ();
@ -742,7 +752,7 @@ HelpSource::process (const QDomDocument &doc, const std::string &path)
}
void
HelpSource::process_child_nodes (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer)
HelpSource::process_child_nodes (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &ol)
{
if (element.isNull ()) {
return;
@ -750,7 +760,7 @@ HelpSource::process_child_nodes (const QDomElement &element, const std::string &
for (QDomNode n = element.firstChild (); ! n.isNull (); n = n.nextSibling ()) {
if (n.isElement ()) {
process (n.toElement (), path, writer);
process (n.toElement (), path, writer, ol);
} else if (n.isComment ()) {
// ignore
} else if (n.isCDATASection ()) {
@ -762,7 +772,7 @@ HelpSource::process_child_nodes (const QDomElement &element, const std::string &
}
void
HelpSource::writeElement (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer)
HelpSource::writeElement (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &ol)
{
// simply pass all other elements
writer.writeStartElement (element.nodeName ());
@ -778,13 +788,26 @@ HelpSource::writeElement (const QDomElement &element, const std::string &path, Q
}
}
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
writer.writeEndElement ();
}
static void
add_outline_at_level (int i, BrowserOutline &ol, const BrowserOutline &child)
{
if (i == 0) {
ol.add_child (child);
} else if (ol.begin () != ol.end ()) {
add_outline_at_level (i - 1, *(--ol.end ()), child);
} else {
ol.add_child (BrowserOutline (tl::to_string (QObject::tr ("(empty")), std::string ()));
add_outline_at_level (i - 1, *(--ol.end ()), child);
}
}
void
HelpSource::process (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer)
HelpSource::process (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &ol)
{
if (element.localName () == keyword_element) {
@ -805,7 +828,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
writer.writeEndElement ();
// replace <k>..</k> by content
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
} else if (element.localName () == h2_index_element) {
@ -822,21 +845,36 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
}
writer.writeEndElement ();
} else if (element.localName () == h2_element) {
} else if (element.localName () == h2_element || element.localName () == h3_element) {
// replace "h2" by "<a name='h2-line-no'/><h2>"
int level = (element.localName () == h2_element ? 1 : 2);
QString name = element.localName () + QString::fromUtf8 ("-") + QString::number (element.lineNumber ());
QString title = element.text ();
std::string path_wo_anchor = path;
std::string::size_type n;
if ((n = path.rfind ("#")) != std::string::npos) {
path_wo_anchor = std::string (path, 0, n);
}
add_outline_at_level (level, ol, BrowserOutline (tl::to_string (title), path_wo_anchor + "#" + tl::to_string (name)));
// replace "h2"/"h3" by "<a name='hx-line-no'/><h2>"
writer.writeStartElement (QString::fromUtf8 ("a"));
writer.writeAttribute (QString::fromUtf8 ("name"), element.localName () + QString::fromUtf8 ("-") + QString::number (element.lineNumber ()));
writer.writeAttribute (QString::fromUtf8 ("name"), name);
writer.writeEndElement ();
writer.writeStartElement (element.localName ());
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
writer.writeEndElement ();
} else if (element.localName () == title_element) {
add_outline_at_level (0, ol, BrowserOutline (tl::to_string (element.text ()), path));
// replace "title" by "h1"
writer.writeStartElement (QString::fromUtf8 ("h1"));
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
writer.writeEndElement ();
} else if (element.localName () == doc_element) {
@ -887,7 +925,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
}
}
writer.writeEndElement ();
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
writer.writeEndElement ();
writer.writeEndElement ();
@ -895,7 +933,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
// replace "topics" by "ul"
writer.writeStartElement (QString::fromUtf8 ("ul"));
process_child_nodes (element, path, writer);
process_child_nodes (element, path, writer, ol);
writer.writeEndElement ();
} else if (element.localName () == topic_ref_element) {
@ -929,7 +967,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
if (new_el.hasAttribute (href_attribute)) {
new_el.setAttribute (href_attribute, relative_url (path, new_el.attribute (href_attribute)));
}
writeElement (new_el, path, writer);
writeElement (new_el, path, writer, ol);
} else if (element.localName () == img_element) {
@ -937,7 +975,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
if (new_el.hasAttribute (src_attribute)) {
new_el.setAttribute (src_attribute, relative_url (path, new_el.attribute (src_attribute)));
}
writeElement (new_el, path, writer);
writeElement (new_el, path, writer, ol);
} else if (element.localName () == class_doc_element) {
@ -970,7 +1008,7 @@ HelpSource::process (const QDomElement &element, const std::string &path, QXmlSt
} else {
// simply pass all other elements
writeElement (element, path, writer);
writeElement (element, path, writer, ol);
}
}

View File

@ -78,6 +78,7 @@ public:
~HelpSource();
virtual std::string get (const std::string &url);
virtual BrowserOutline get_outline (const std::string &url);
virtual QImage get_image (const std::string &url);
virtual std::string get_css (const std::string &url);
@ -163,11 +164,11 @@ private:
QDomDocument produce_main_index ();
void produce_index_file (const std::string &path);
void initialize_index ();
std::string process (const QDomDocument &doc, const std::string &path);
void process_child_nodes (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer);
void process (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer);
std::string process (const QDomDocument &doc, const std::string &path, BrowserOutline &ol);
void process_child_nodes (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &old);
void process (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &ol);
std::string read (const std::string &u);
void writeElement (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer);
void writeElement (const QDomElement &element, const std::string &path, QXmlStreamWriter &writer, BrowserOutline &ol);
void scan (const std::string &path, tl::AbsoluteProgress &progress);
void scan_child_nodes (const QDomElement &element, const std::string &path, std::vector<std::string> &subtopics, std::string &title, std::string &section);
void scan (const QDomElement &element, const std::string &path, std::vector<std::string> &subtopics, std::string &title, std::string &section);

View File

@ -1,162 +1,257 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BrowserPanel</class>
<widget class="QWidget" name="BrowserPanel" >
<property name="geometry" >
<widget class="QWidget" name="BrowserPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>482</width>
<height>414</height>
<width>826</width>
<height>580</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="spacing" >
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>TextLabel</string>
<item row="0" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>6</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="7">
<widget class="QToolButton" name="next_topic_pb">
<property name="toolTip">
<string>Next Topic</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../lay/lay/layResources.qrc">
<normaloff>:/next_topic.png</normaloff>:/next_topic.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="9" >
<widget class="QLineEdit" name="searchEdit" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>0</vsizetype>
<item row="1" column="0" colspan="10">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="outline_tree">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>true</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="lay::BrowserTextWidget" name="browser">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="9">
<widget class="QLineEdit" name="searchEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="6" >
<widget class="QToolButton" name="prev_topic_pb" >
<property name="toolTip" >
<string>Previous Topic</string>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="icon" >
<iconset resource="layResources.qrc" >:/prev_topic.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="7" >
<widget class="QToolButton" name="next_topic_pb" >
<property name="toolTip" >
<string>Next Topic</string>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="icon" >
<iconset resource="layResources.qrc" >:/next_topic.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QToolButton" name="back_pb" >
<property name="toolTip" >
<item row="0" column="2">
<widget class="QToolButton" name="back_pb">
<property name="toolTip">
<string>Back</string>
</property>
<property name="text" >
<property name="text">
<string>...</string>
</property>
<property name="icon" >
<iconset resource="layResources.qrc" >:/back.png</iconset>
<property name="icon">
<iconset resource="../../lay/lay/layResources.qrc">
<normaloff>:/back.png</normaloff>:/back.png</iconset>
</property>
<property name="iconSize" >
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise" >
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QToolButton" name="forward_pb" >
<property name="toolTip" >
<string>Forward</string>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="icon" >
<iconset resource="layResources.qrc" >:/forward.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QToolButton" name="home_pb" >
<property name="toolTip" >
<item row="0" column="4">
<widget class="QToolButton" name="home_pb">
<property name="toolTip">
<string>Home</string>
</property>
<property name="text" >
<property name="text">
<string>...</string>
</property>
<property name="icon" >
<iconset resource="layResources.qrc" >:/home.png</iconset>
<property name="icon">
<iconset resource="../../lay/lay/layResources.qrc">
<normaloff>:/home.png</normaloff>:/home.png</iconset>
</property>
<property name="iconSize" >
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise" >
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="8" >
<item row="0" column="6">
<widget class="QToolButton" name="prev_topic_pb">
<property name="toolTip">
<string>Previous Topic</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../lay/lay/layResources.qrc">
<normaloff>:/prev_topic.png</normaloff>:/prev_topic.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="forward_pb">
<property name="toolTip">
<string>Forward</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../lay/lay/layResources.qrc">
<normaloff>:/forward.png</normaloff>:/forward.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="8">
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
@ -164,15 +259,22 @@
</property>
</spacer>
</item>
<item row="0" column="1" >
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>6</width>
<height>20</height>
@ -180,25 +282,6 @@
</property>
</spacer>
</item>
<item row="0" column="5" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<size>
<width>6</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="10" >
<widget class="lay::BrowserTextWidget" name="browser" />
</item>
</layout>
</widget>
<customwidgets>
@ -213,10 +296,9 @@
<tabstop>back_pb</tabstop>
<tabstop>forward_pb</tabstop>
<tabstop>home_pb</tabstop>
<tabstop>browser</tabstop>
</tabstops>
<resources>
<include location="layResources.qrc" />
<include location="../../lay/lay/layResources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -33,6 +33,8 @@
# include <QUrlQuery>
#endif
#include <QTreeWidgetItem>
namespace lay
{
@ -80,6 +82,7 @@ BrowserPanel::init ()
connect (mp_ui->browser, SIGNAL (textChanged ()), this, SLOT (text_changed ()));
connect (mp_ui->browser, SIGNAL (backwardAvailable (bool)), mp_ui->back_pb, SLOT (setEnabled (bool)));
connect (mp_ui->browser, SIGNAL (forwardAvailable (bool)), mp_ui->forward_pb, SLOT (setEnabled (bool)));
connect (mp_ui->outline_tree, SIGNAL (itemActivated (QTreeWidgetItem *, int)), this, SLOT (outline_item_clicked (QTreeWidgetItem *)));
mp_ui->searchEdit->hide ();
@ -117,6 +120,15 @@ BrowserPanel::text_changed ()
}
}
void
BrowserPanel::outline_item_clicked (QTreeWidgetItem *item)
{
QString url = item->data (0, Qt::UserRole).toString ();
if (! url.isEmpty ()) {
load (tl::to_string (url));
}
}
void
BrowserPanel::load (const std::string &s)
{
@ -157,6 +169,17 @@ BrowserPanel::set_home (const std::string &url)
{
m_home = url;
home ();
// NOTE: we take this call as a hint that the panel is set up and about to be
// shown. We use this opportunity to resize the outline pane.
mp_ui->outline_tree->header ()->hide ();
QList<int> sizes = mp_ui->splitter->sizes ();
if (sizes.size () >= 2) {
int size_outline = 150;
sizes[1] += sizes[0] - size_outline;
sizes[0] = size_outline;
}
mp_ui->splitter->setSizes (sizes);
}
void
@ -212,7 +235,7 @@ BrowserPanel::home ()
QSize
BrowserPanel::sizeHint () const
{
return QSize (600, 400);
return QSize (800, 600);
}
void
@ -266,6 +289,54 @@ BrowserPanel::set_label (const std::string &text)
mp_ui->label->setVisible (! text.empty ());
}
static void
update_item_with_outline (const BrowserOutline &ol, QTreeWidgetItem *item)
{
item->setData (0, Qt::UserRole, tl::to_qstring (ol.url ()));
item->setData (0, Qt::DisplayRole, tl::to_qstring (ol.title ()));
item->setData (0, Qt::ToolTipRole, tl::to_qstring (ol.title ()));
int i = 0;
for (BrowserOutline::const_child_iterator c = ol.begin (); c != ol.end (); ++c, ++i) {
if (item->childCount () <= i) {
new QTreeWidgetItem (item);
}
update_item_with_outline (*c, item->child (i));
}
while (item->childCount () > i) {
delete item->child (i);
}
}
void
BrowserPanel::set_outline (const BrowserOutline &ol)
{
if (ol.begin () == ol.end ()) {
mp_ui->outline_tree->hide ();
} else {
mp_ui->outline_tree->show ();
int i = 0;
for (BrowserOutline::const_child_iterator c = ol.begin (); c != ol.end (); ++c, ++i) {
if (mp_ui->outline_tree->topLevelItemCount () <= i) {
new QTreeWidgetItem (mp_ui->outline_tree);
}
update_item_with_outline (*c, mp_ui->outline_tree->topLevelItem (i));
}
while (mp_ui->outline_tree->topLevelItemCount () > i) {
delete mp_ui->outline_tree->topLevelItem (i);
}
mp_ui->outline_tree->expandAll ();
}
}
QVariant
BrowserPanel::loadResource (int type, const QUrl &url)
{
@ -309,14 +380,17 @@ BrowserPanel::loadResource (int type, const QUrl &url)
std::string u = tl::to_string (url.toString ());
std::string s;
std::string nu, pu;
BrowserOutline ol;
if (u == m_cached_url) {
s = m_cached_text;
nu = m_cached_next_url;
pu = m_cached_prev_url;
ol = m_cached_outline;
} else {
s = mp_source->get (u);
nu = mp_source->next_topic (u);
pu = mp_source->prev_topic (u);
ol = mp_source->get_outline (u);
}
if (s.empty ()) {
s = " "; // QTextBrowser needs at least something
@ -332,6 +406,7 @@ BrowserPanel::loadResource (int type, const QUrl &url)
m_cached_url = u;
m_cached_next_url = nu;
m_cached_prev_url = pu;
m_cached_outline = ol;
}
ret = QVariant (tl::to_qstring (s));
@ -346,6 +421,9 @@ BrowserPanel::loadResource (int type, const QUrl &url)
mp_ui->next_topic_pb->setEnabled (! nu.empty ());
}
// push the outline
set_outline (ol);
END_PROTECTED
QApplication::restoreOverrideCursor ();
@ -390,6 +468,12 @@ BrowserSource::get_image (const std::string & /*url*/)
return QImage ();
}
BrowserOutline
BrowserSource::get_outline (const std::string & /*url*/)
{
return BrowserOutline ();
}
std::string
BrowserSource::get (const std::string & /*url*/)
{

View File

@ -32,8 +32,11 @@
#include <QTextBrowser>
#include <string>
#include <list>
#include <set>
class QTreeWidgetItem;
namespace Ui
{
class BrowserPanel;
@ -44,6 +47,121 @@ namespace lay
class BrowserPanel;
/**
* @brief Specifies the outline of the document
*
* The outline is a hierarchical tree of items. Each node has a title, a URL to navigate to and
* optional child items.
*/
class LAYBASIC_PUBLIC BrowserOutline
{
public:
typedef std::list<BrowserOutline>::const_iterator const_child_iterator;
typedef std::list<BrowserOutline>::iterator child_iterator;
/**
* @brief Default constructor: creates an empty browser outline
*/
BrowserOutline ()
{
// .. nothing yet ..
}
/**
* @brief Default constructor: creates a single entry with title and URL
*/
BrowserOutline (const std::string &title, const std::string &url)
: m_title (title), m_url (url)
{
// .. nothing yet ..
}
/**
* @brief Gets the title
*/
const std::string &title () const
{
return m_title;
}
/**
* @brief Sets the title
*/
void set_title (const std::string &t)
{
m_title = t;
}
/**
* @brief Gets the URL
*/
const std::string &url () const
{
return m_url;
}
/**
* @brief Sets the URL
*/
void set_url (const std::string &u)
{
m_url = u;
}
/**
* @brief Returns the begin iterator for the children
*/
const_child_iterator begin () const
{
return m_children.begin ();
}
/**
* @brief Returns the end iterator for the children
*/
const_child_iterator end () const
{
return m_children.end ();
}
/**
* @brief Returns the non-const begin iterator for the children
*/
child_iterator begin ()
{
return m_children.begin ();
}
/**
* @brief Returns the non-const end iterator for the children
*/
child_iterator end ()
{
return m_children.end ();
}
/**
* @brief Adds a child entry at the end of the list
*/
void add_child (const BrowserOutline &ol)
{
m_children.push_back (ol);
}
/**
* @brief Clears the child list of the node
*/
void clear_children ()
{
m_children.clear ();
}
private:
std::string m_title;
std::string m_url;
std::list<BrowserOutline> m_children;
};
/**
* @brief The source for BrowserDialog's "int" URL's
*/
@ -76,6 +194,16 @@ public:
*/
virtual std::string get (const std::string &url);
/**
* @brief Gets the outline object if the source provides one
*
* The outline is a dictionary of item and subitems, each with a title and a
* URL to navigate to if selected.
*
* If an empty outline is returned, no outline is shown.
*/
virtual BrowserOutline get_outline (const std::string &url);
/**
* @brief Get the image for a given "int" URL in an image
*/
@ -205,6 +333,11 @@ public:
*/
void set_label (const std::string &text);
/**
* @brief Sets the outline
*/
void set_outline (const BrowserOutline &ol);
/**
* @brief Enables the search bx and sets the Url and query item name for the search
*/
@ -255,6 +388,7 @@ public slots:
protected slots:
void search_edited ();
void text_changed ();
void outline_item_clicked (QTreeWidgetItem *item);
protected:
virtual QVariant loadResource (int type, const QUrl &url);
@ -268,6 +402,7 @@ private:
std::string m_cached_text;
std::string m_cached_next_url;
std::string m_cached_prev_url;
BrowserOutline m_cached_outline;
Ui::BrowserPanel *mp_ui;
bool m_schedule_back;
tl::DeferredMethod<BrowserPanel> m_back_dm;