]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/TocModel.cpp
Mac compile fix.
[lyx.git] / src / frontends / qt4 / TocModel.cpp
index 08f1d12419dab609a3b530fde574eb657aacf44a..cd6cd7058e235dd1e9a9cb95ba5e6d8e0fe9e65b 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * \file QTocDialog.C
+ * \file TocModel.cpp
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
 
 #include "TocModel.h"
 
-#include "debug.h"
+#include "Buffer.h"
+#include "BufferView.h"
+#include "Cursor.h"
+#include "DocIterator.h"
+#include "FuncRequest.h"
+#include "LyXFunc.h"
+#include "TocBackend.h"
 
-#include <vector>
-#include <string>
+#include "support/convert.h"
+#include "support/debug.h"
+#include "support/lassert.h"
 
-using std::endl;
-using std::pair;
-using std::map;
-using std::vector;
-using std::string;
-using std::make_pair;
-using std::max;
-using std::min;
+#include <climits>
+
+using namespace std;
 
 namespace lyx {
 namespace frontend {
 
 
-TocModel::TocModel(Toc const & toc)
+TocItem const & TocModel::tocItem(QModelIndex const & index) const
 {
-       populate(toc);
+       return toc_[data(index, Qt::UserRole).toUInt()];
 }
 
 
-TocModel const & TocModel::operator=(Toc const & toc)
+QModelIndex TocModel::modelIndex(DocIterator const & dit) const
 {
-       populate(toc);
-       return *this;
+       if (toc_.empty())
+               return QModelIndex();
+
+       unsigned int const toc_index = toc_.item(dit) - toc_.begin();
+
+       QModelIndexList list = match(index(0, 0), Qt::UserRole,
+               QVariant(toc_index), 1,
+               Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive));
+
+       LASSERT(!list.isEmpty(), return QModelIndex());
+       return list[0];
 }
 
 
-TocIterator const TocModel::tocIterator(QModelIndex const & index) const
+TocModel::TocModel(Toc const & toc): toc_(toc)
 {
-       TocMap::const_iterator map_it = toc_map_.find(index);
-       BOOST_ASSERT(map_it != toc_map_.end());
-       return map_it->second;
+       if (toc_.empty())
+               return;
+       int current_row;
+       QModelIndex top_level_item;
+       insertColumns(0, 1);
+       maxdepth_ = 0;
+       mindepth_ = INT_MAX;
+
+       size_t end = toc.size();
+       for (unsigned int index = 0; index != end; ++index) {
+               TocItem const & item = toc_[index];
+               maxdepth_ = max(maxdepth_, item.depth());
+               mindepth_ = min(mindepth_, item.depth());
+               current_row = rowCount();
+               insertRows(current_row, 1);
+               top_level_item = QStandardItemModel::index(current_row, 0);
+               setData(top_level_item, toqstr(item.str()), Qt::DisplayRole);
+               setData(top_level_item, index, Qt::UserRole);
+
+               LYXERR(Debug::GUI, "Toc: at depth " << item.depth()
+                       << ", added item " << item.str());
+
+               populate(index, top_level_item);
+               if (index >= end)
+                       break;
+       }
+
+       setHeaderData(0, Qt::Horizontal, QVariant("title"), Qt::DisplayRole);
+//     emit headerDataChanged();
 }
 
 
-QModelIndex const TocModel::modelIndex(TocIterator const & it) const
+void TocModel::populate(unsigned int & index, QModelIndex const & parent)
 {
-       ModelMap::const_iterator map_it = model_map_.find(it);
-       //BOOST_ASSERT(it != model_map_.end());
+       int curdepth = toc_[index].depth() + 1;
 
-       if (map_it == model_map_.end())
-               return QModelIndex();
+       int current_row;
+       QModelIndex child_item;
+       insertColumns(0, 1, parent);
 
-       return map_it->second;
+       size_t end = toc_.size();
+       ++index;
+       for (; index != end; ++index) {
+               TocItem const & item = toc_[index];
+               if (item.depth() < curdepth) {
+                       --index;
+                       return;
+               }
+               maxdepth_ = max(maxdepth_, item.depth());
+               mindepth_ = min(mindepth_, item.depth());
+               current_row = rowCount(parent);
+               insertRows(current_row, 1, parent);
+               child_item = QStandardItemModel::index(current_row, 0, parent);
+               setData(child_item, toqstr(item.str()), Qt::DisplayRole);
+               setData(child_item, index, Qt::UserRole);
+               populate(index, child_item);
+               if (index >= end)
+                       break;
+       }
 }
 
 
-void TocModel::clear()
+int TocModel::modelDepth() const
 {
-       QStandardItemModel::clear();
-       toc_map_.clear();
-       model_map_.clear();
-       removeRows(0, rowCount());
-       removeColumns(0, columnCount());
+       return maxdepth_ - mindepth_;
 }
 
 
-void TocModel::populate(Toc const & toc)
+///////////////////////////////////////////////////////////////////////////////
+// TocModels implementation.
+///////////////////////////////////////////////////////////////////////////////
+void TocModels::clear()        
 {
-       clear();
+       types_.clear();
+       type_names_.clear();
+       const unsigned int size = models_.size();
+       for (unsigned int i = 0; i < size; ++i) {
+               delete models_[i];
+       }
+       models_.clear();
+}
 
-       if (toc.empty())
-               return;
-       int current_row;
-       QModelIndex top_level_item;
 
-       TocIterator iter = toc.begin();
-       TocIterator end = toc.end();
+int TocModels::depth(int type)
+{
+       if (type < 0)
+               return 0;
+       return models_[type]->modelDepth();
+}
 
-       insertColumns(0, 1);
-       maxdepth_ = 0;
-       mindepth_ = INT_MAX;
 
-       while (iter != end) {
+QStandardItemModel * TocModels::model(int type)
+{
+       if (type < 0)
+               return 0;
 
-               if (iter->isValid()) {
+       if (models_.empty()) {
+               LYXERR(Debug::GUI, "TocModels::tocModel(): no types available ");
+               return 0;
+       }
 
-                       maxdepth_ = max(maxdepth_, iter->depth());
-                       mindepth_ = min(mindepth_, iter->depth());
-                       current_row = rowCount();
-                       insertRows(current_row, 1);
-                       top_level_item = QStandardItemModel::index(current_row, 0);
-                       //setData(top_level_item, toqstr(iter->str()));
-                       setData(top_level_item, toqstr(iter->str()), Qt::DisplayRole);
+       LYXERR(Debug::GUI, "TocModels: type " << type
+               << "  models_.size() " << models_.size());
 
-                       // This looks like a gcc bug, in principle this should work:
-                       //toc_map_[top_level_item] = iter;
-                       // but it crashes with gcc-4.1 and 4.0.2
-                       toc_map_.insert( TocPair(top_level_item, iter) );
-                       model_map_[iter] = top_level_item;
+       LASSERT(type >= 0 && type < int(models_.size()), /**/);
+       return models_[type];
+}
 
-                       LYXERR(Debug::GUI)
-                               << "Toc: at depth " << iter->depth()
-                               << ", added item " << to_utf8(iter->str())
-                               << endl;
 
-                       populate(iter, end, top_level_item);
-               }
+QModelIndex TocModels::currentIndex(int type) const
+{
+       if (type < 0 || !bv_)
+               return QModelIndex();
+       return models_[type]->modelIndex(bv_->cursor());
+}
 
-               if (iter == end)
-                       break;
 
-               ++iter;
+void TocModels::goTo(int type, QModelIndex const & index) const
+{
+       if (type < 0 || !index.isValid()
+               || index.model() != models_[type]) {
+               LYXERR(Debug::GUI, "TocModels::goTo(): QModelIndex is invalid!");
+               return;
        }
 
-       setHeaderData(0, Qt::Horizontal, QVariant("title"), Qt::DisplayRole);
-//     emit headerDataChanged();
+       LASSERT(type >= 0 && type < int(models_.size()), /**/);
+       TocItem const item = models_[type]->tocItem(index);
+       LYXERR(Debug::GUI, "TocModels::goTo " << item.str());
+       dispatch(item.action());
 }
 
 
-void TocModel::populate(TocIterator & iter,
-                                               TocIterator const & end,
-                                               QModelIndex const & parent)
+void TocModels::updateBackend() const
 {
-       int curdepth = iter->depth() + 1;
-
-       int current_row;
-       QModelIndex child_item;
+       bv_->buffer().masterBuffer()->tocBackend().update();
+       bv_->buffer().structureChanged();
+}
 
-       insertColumns(0, 1, parent);
-       while (iter != end) {
 
-               ++iter;
+void TocModels::reset(BufferView const * bv)
+{
+       bv_ = bv;
+       clear();
+       if (!bv_)
+               return;
 
-               if (iter == end)
-                       break;
+       TocList const & tocs = bv_->buffer().masterBuffer()->tocBackend().tocs();
+       TocList::const_iterator it = tocs.begin();
+       TocList::const_iterator end = tocs.end();
+       for (; it != end; ++it) {
+               types_.push_back(toqstr(it->first));
+               type_names_.push_back(guiName(it->first, bv->buffer().params()));
+               models_.push_back(new TocModel(it->second));
+       }
+}
 
-               if (iter->depth() < curdepth) {
-                       --iter;
-                       return;
-               }
 
-               maxdepth_ = max(maxdepth_, iter->depth());
-               mindepth_ = min(mindepth_, iter->depth());
-               current_row = rowCount(parent);
-               insertRows(current_row, 1, parent);
-               child_item = QStandardItemModel::index(current_row, 0, parent);
-               //setData(child_item, toqstr(iter->str()));
-               setData(child_item, toqstr(iter->str()), Qt::DisplayRole);
-
-               // This looks like a gcc bug, in principle this should work:
-               //toc_map_[child_item] = iter;
-               // but it crashes with gcc-4.1 and 4.0.2
-               toc_map_.insert( TocPair(child_item, iter) );
-               model_map_[iter] = child_item;
-               populate(iter, end, child_item);
-       }
+bool TocModels::canOutline(int type) const
+{
+       if (type < 0 || type >= types_.size())
+               return false;
+       return types_[type] == "tableofcontents";
 }
 
 
-int TocModel::modelDepth()
+int TocModels::decodeType(QString const & str) const
 {
-       return maxdepth_ - mindepth_;
+       QString new_type;
+       if (str.contains("tableofcontents")) {
+               new_type = "tableofcontents";
+       } else if (str.contains("floatlist")) {
+               if (str.contains("\"figure"))
+                       new_type = "figure";
+               else if (str.contains("\"table"))
+                       new_type = "table";
+               else if (str.contains("\"algorithm"))
+                       new_type = "algorithm";
+       } else if (!str.isEmpty()) {
+               new_type = str;
+       } else {
+               // Default to Outliner.
+               new_type = "tableofcontents";
+       }
+       int const type = types_.indexOf(new_type);
+       if (type != -1)
+               return type;
+       // If everything else fails, settle on the table of contents which is
+       // guaranted to exist.
+       return types_.indexOf("tableofcontents");
 }
 
 } // namespace frontend