Dear LyX Developers,

I am writing to request a bit of code review.  For the past week, or so,
I have been working on the TocModel in LyX so that I can get it to
support more than a single column.  This modification is important for
the specialized views that I would like to create.  (For more
information on what I'm trying to accomplish, take a look at this
webpage: http://blog.oak-tree.us/index.php/2009/03/04/perfect-tool).

After trying several different approaches, I finally found that appears
to work with negatively impacting the performance or stability of LyX.
The result of that work is attached, and I would greatly appreciate your
feedback on it.

Briefly, here is what I did:

1.) TocBackend::TocItem - I created a simple vector that can be used to
store TocItems.  In the addToToc methods of InsetText.cpp, this vector
is used to find store TocItems of Note insets that are included in the
heading.
2.) TocModel - Code was added that can read the vector from a particular
TocItem add any Note information to a second column of the existing
model.
3.) InsetText - Code was added to addToToc that recognizes any Note
insets that are part of the current heading.  These are then added to
the TocItem vector referenced above.
4.) TocWidget - Code was added that hides the second column of the
model, so that the UI remains unchanged.

So far, these modifications appear to be stable.  I have been testing
them against the most recent SVN of LyX 2 and I have not had any
problems with crashes, application freezes or file corruption.

I understand that the code may be a bit crude (I am neither a software
developer or proficient with C++, though getting better).  And for that
reason, I would appreciate any thoughts/recommendations that you might
have.

Cheers,

Rob Oakes
=== modified file 'src/insets/InsetText.cpp'
--- src/insets/InsetText.cpp	2010-04-26 22:46:21 +0000
+++ src/insets/InsetText.cpp	2010-05-23 23:24:11 +0000
@@ -672,9 +672,9 @@
 }
 
 
-
 void InsetText::addToToc(DocIterator const & cdit)
 {
+	TocItem paragraph_item;
 	DocIterator dit = cdit;
 	dit.push_back(CursorSlice(*this));
 	Toc & toc = buffer().tocBackend().toc("tableofcontents");
@@ -691,13 +691,37 @@
 		dit.pit() = pit;
 		// the string that goes to the toc (could be the optarg)
 		docstring tocstring;
+
+		// Create an Entry in the Table of Contents for the Paragraph
+		int const toclevel = par.layout().toclevel;
+		if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel) {
+			dit.pos() = 0;
+			// insert this into the table of contents
+			if (tocstring.empty())
+				tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
+			paragraph_item = TocItem(dit, toclevel - min_toclevel, tocstring, tocstring);
+		}
+
+		// Traverse the Paragraph Insets and allow them to be added to the
+		// appropriate toc list
 		InsetList::const_iterator it  = par.insetList().begin();
 		InsetList::const_iterator end = par.insetList().end();
 		for (; it != end; ++it) {
 			Inset & inset = *it->inset;
 			dit.pos() = it->pos;
+
+			// Check whether the inset is a note and add to paragraph_item
+			if (inset.name()== from_ascii("Note:Note")){
+				DocIterator pit = dit;
+				pit.push_back(CursorSlice(inset));
+				docstring str_summary = pit.paragraph().asString();
+				paragraph_item.summary_notes.push_back(TocItem(pit, toclevel - min_toclevel, 1,
+					str_summary, str_summary));
+			}
+
 			//lyxerr << (void*)&inset << " code: " << inset.lyxCode() << std::endl;
 			inset.addToToc(dit);
+
 			switch (inset.lyxCode()) {
 			case OPTARG_CODE: {
 				if (!tocstring.empty())
@@ -714,16 +738,9 @@
 				break;
 			}
 		}
-		// now the toc entry for the paragraph
-		int const toclevel = par.layout().toclevel;
-		if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel) {
-			dit.pos() = 0;
-			// insert this into the table of contents
-			if (tocstring.empty())
-				tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
-			toc.push_back(TocItem(dit, toclevel - min_toclevel,
-				tocstring, tocstring));
-		}
+
+		if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel)
+			toc.push_back(paragraph_item);
 		
 		// And now the list of changes.
 		par.addChangesToToc(dit, buffer());

=== modified file 'src/TocBackend.cpp'
--- src/TocBackend.cpp	2010-05-18 16:39:42 +0000
+++ src/TocBackend.cpp	2010-05-23 22:00:10 +0000
@@ -47,10 +47,14 @@
 ///////////////////////////////////////////////////////////////////////////
 
 TocItem::TocItem(DocIterator const & dit, int d, docstring const & s,
-	docstring const & t) : dit_(dit), depth_(d), str_(s), tooltip_(t)
+	docstring const & t) : dit_(dit), depth_(d), str_(s), tooltip_(t), column_(0)
 {
 }
 
+TocItem::TocItem(DocIterator const & dit, int d, int c, docstring const & s,
+	docstring const & t) : dit_(dit), depth_(d), str_(s), tooltip_(t), column_(c)
+{
+}
 
 int TocItem::id() const
 {
@@ -63,13 +67,16 @@
 	return depth_;
 }
 
+int TocItem::modelColumn() const
+{
+	return column_;
+}
 
 docstring const & TocItem::str() const
 {
 	return str_;
 }
 
-
 docstring const & TocItem::tooltip() const
 {
 	return tooltip_;
@@ -95,7 +102,6 @@
 	return FuncRequest(LFUN_PARAGRAPH_GOTO, arg);
 }
 
-
 ///////////////////////////////////////////////////////////////////////////
 //
 // TocBackend implementation

=== modified file 'src/TocBackend.h'
--- src/TocBackend.h	2010-04-26 22:46:21 +0000
+++ src/TocBackend.h	2010-05-23 22:00:47 +0000
@@ -45,6 +45,14 @@
 		docstring const & s,
 		docstring const & t = docstring()
 		);
+
+	TocItem(DocIterator const & dit,
+		int depth,
+		int col,
+		docstring const & s,
+		docstring const & t = docstring()
+		);
+
 	///
 	~TocItem() {}
 	///
@@ -63,8 +71,12 @@
 	/// the action corresponding to the goTo above
 	FuncRequest action() const;
 
-	/// Returns the text of the snyopsis associated with the item.
-	docstring const synopsis() const;
+	/// returns the model column that the item should add itself to
+	int modelColumn() const;
+
+	/// summary_notes_, vector of any note TocItems that
+	/// might be associated with a particular item.
+	std::vector<TocItem> summary_notes;
 
 protected:
 	/// Current position of item.
@@ -78,6 +90,10 @@
 
 	/// The tooltip string
 	docstring tooltip_;
+
+	/// model column, default = 0
+	int column_;
+
 };
 
 

=== modified file 'src/frontends/qt4/TocModel.cpp'
--- src/frontends/qt4/TocModel.cpp	2010-04-26 22:46:21 +0000
+++ src/frontends/qt4/TocModel.cpp	2010-05-23 23:03:31 +0000
@@ -171,7 +171,7 @@
 
 	model_->blockSignals(true);
 	model_->beginResetModel();
-	model_->insertColumns(0, 1);
+	model_->insertColumns(0, 2);
 	maxdepth_ = 0;
 	mindepth_ = INT_MAX;
 
@@ -187,6 +187,15 @@
 		model_->setData(top_level_item, index, Qt::UserRole);
 		model_->setData(top_level_item, toqstr(item.tooltip()), Qt::ToolTipRole);
 
+		size_t notes_size = item.summary_notes.size();
+		if (notes_size != 0){
+			QModelIndex summary_index = model_->index(current_row, 1);
+			TocItem const & summary_item = item.summary_notes[0];
+			model_->setData(summary_index, toqstr(summary_item.str()), Qt::DisplayRole);
+			model_->setData(summary_index, index, Qt::UserRole);
+			model_->setData(summary_index, toqstr(summary_item.tooltip()), Qt::ToolTipRole);
+		}
+
 		LYXERR(Debug::GUI, "Toc: at depth " << item.depth()
 			<< ", added item " << item.str());
 
@@ -210,7 +219,7 @@
 
 	int current_row;
 	QModelIndex child_item;
-	model_->insertColumns(0, 1, parent);
+	model_->insertColumns(0, 2, parent);
 
 	size_t end = toc_->size();
 	++index;
@@ -228,6 +237,17 @@
 		model_->setData(child_item, toqstr(item.str()), Qt::DisplayRole);
 		model_->setData(child_item, index, Qt::UserRole);
 		model_->setData(child_item, toqstr(item.tooltip()), Qt::ToolTipRole);
+
+		// Check for summary_notes
+		size_t notes_size = item.summary_notes.size();
+		if (notes_size != 0){
+			QModelIndex summary_index = model_->index(current_row, 1, parent);
+			TocItem const & summary_item = item.summary_notes[0];
+			model_->setData(summary_index, toqstr(summary_item.str()), Qt::DisplayRole);
+			model_->setData(summary_index, index, Qt::UserRole);
+			model_->setData(summary_index, toqstr(summary_item.tooltip()), Qt::ToolTipRole);
+		}
+
 		populate(index, child_item);
 		if (index >= end)
 			break;

=== modified file 'src/frontends/qt4/TocWidget.cpp'
--- src/frontends/qt4/TocWidget.cpp	2010-05-13 01:00:52 +0000
+++ src/frontends/qt4/TocWidget.cpp	2010-05-23 05:30:56 +0000
@@ -390,6 +390,8 @@
 {
 	if (!gui_view_.documentBufferView()) {
 		tocTV->setModel(0);
+		tocTV->showColumn(0);
+		tocTV->hideColumn(1);
 		depthSL->setMaximum(0);
 		depthSL->setValue(0);
 		setEnabled(false);
@@ -406,6 +408,8 @@
 			gui_view_.tocModels().model(current_type_);
 	if (tocTV->model() != toc_model) {
 		tocTV->setModel(toc_model);
+		tocTV->showColumn(0);
+		tocTV->hideColumn(1);
 		tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
 		if (persistent_)
 			setTreeDepth(depth_);

Reply via email to