]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/TocModel.cpp
Mac compile fix.
[lyx.git] / src / frontends / qt4 / TocModel.cpp
index cf68a115a9b55b2dbed076b5c5f72863b1624705..cd6cd7058e235dd1e9a9cb95ba5e6d8e0fe9e65b 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * \file GuiTocDialog.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)
-{
-       populate(toc);
-}
-
-
-TocModel const & TocModel::operator=(Toc const & toc)
+TocItem const & TocModel::tocItem(QModelIndex const & index) const
 {
-       populate(toc);
-       return *this;
+       return toc_[data(index, Qt::UserRole).toUInt()];
 }
 
 
-TocIterator const TocModel::tocIterator(QModelIndex const & index) const
+QModelIndex TocModel::modelIndex(DocIterator const & dit) const
 {
-       TocMap::const_iterator map_it = toc_map_.find(index);
-       BOOST_ASSERT(map_it != toc_map_.end());
-       return map_it->second;
-}
-
-
-QModelIndex const TocModel::modelIndex(TocIterator const & it) const
-{
-       ModelMap::const_iterator map_it = model_map_.find(it);
-       //BOOST_ASSERT(it != model_map_.end());
-
-       if (map_it == model_map_.end())
+       if (toc_.empty())
                return QModelIndex();
 
-       return map_it->second;
-}
+       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));
 
-void TocModel::clear()
-{
-       QStandardItemModel::clear();
-       toc_map_.clear();
-       model_map_.clear();
-       removeRows(0, rowCount());
-       removeColumns(0, columnCount());
+       LASSERT(!list.isEmpty(), return QModelIndex());
+       return list[0];
 }
 
 
-void TocModel::populate(Toc const & toc)
+TocModel::TocModel(Toc const & toc): toc_(toc)
 {
-       clear();
-
-       if (toc.empty())
+       if (toc_.empty())
                return;
        int current_row;
        QModelIndex top_level_item;
-
-       TocIterator iter = toc.begin();
-       TocIterator end = toc.end();
-
        insertColumns(0, 1);
        maxdepth_ = 0;
        mindepth_ = INT_MAX;
 
-       while (iter != end) {
-               maxdepth_ = max(maxdepth_, iter->depth());
-               mindepth_ = min(mindepth_, iter->depth());
+       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(iter->str()));
-               setData(top_level_item, toqstr(iter->str()), Qt::DisplayRole);
-
-               // 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;
+               setData(top_level_item, toqstr(item.str()), Qt::DisplayRole);
+               setData(top_level_item, index, Qt::UserRole);
 
-               LYXERR(Debug::GUI)
-                       << "Toc: at depth " << iter->depth()
-                       << ", added item " << to_utf8(iter->str())
-                       << endl;
+               LYXERR(Debug::GUI, "Toc: at depth " << item.depth()
+                       << ", added item " << item.str());
 
-               populate(iter, end, top_level_item);
-
-               if (iter == end)
+               populate(index, top_level_item);
+               if (index >= end)
                        break;
-
-               ++iter;
        }
 
        setHeaderData(0, Qt::Horizontal, QVariant("title"), Qt::DisplayRole);
@@ -123,51 +89,165 @@ void TocModel::populate(Toc const & toc)
 }
 
 
-void TocModel::populate(TocIterator & iter,
-                                               TocIterator const & end,
-                                               QModelIndex const & parent)
+void TocModel::populate(unsigned int & index, QModelIndex const & parent)
 {
-       int curdepth = iter->depth() + 1;
+       int curdepth = toc_[index].depth() + 1;
 
        int current_row;
        QModelIndex child_item;
-
        insertColumns(0, 1, parent);
-       while (iter != end) {
-
-               ++iter;
 
-               if (iter == end)
-                       break;
-
-               if (iter->depth() < curdepth) {
-                       --iter;
+       size_t end = toc_.size();
+       ++index;
+       for (; index != end; ++index) {
+               TocItem const & item = toc_[index];
+               if (item.depth() < curdepth) {
+                       --index;
                        return;
                }
-
-               maxdepth_ = max(maxdepth_, iter->depth());
-               mindepth_ = min(mindepth_, iter->depth());
+               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(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);
+               setData(child_item, toqstr(item.str()), Qt::DisplayRole);
+               setData(child_item, index, Qt::UserRole);
+               populate(index, child_item);
+               if (index >= end)
+                       break;
        }
 }
 
 
-int TocModel::modelDepth()
+int TocModel::modelDepth() const
 {
        return maxdepth_ - mindepth_;
 }
 
+
+///////////////////////////////////////////////////////////////////////////////
+// TocModels implementation.
+///////////////////////////////////////////////////////////////////////////////
+void TocModels::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();
+}
+
+
+int TocModels::depth(int type)
+{
+       if (type < 0)
+               return 0;
+       return models_[type]->modelDepth();
+}
+
+
+QStandardItemModel * TocModels::model(int type)
+{
+       if (type < 0)
+               return 0;
+
+       if (models_.empty()) {
+               LYXERR(Debug::GUI, "TocModels::tocModel(): no types available ");
+               return 0;
+       }
+
+       LYXERR(Debug::GUI, "TocModels: type " << type
+               << "  models_.size() " << models_.size());
+
+       LASSERT(type >= 0 && type < int(models_.size()), /**/);
+       return models_[type];
+}
+
+
+QModelIndex TocModels::currentIndex(int type) const
+{
+       if (type < 0 || !bv_)
+               return QModelIndex();
+       return models_[type]->modelIndex(bv_->cursor());
+}
+
+
+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;
+       }
+
+       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 TocModels::updateBackend() const
+{
+       bv_->buffer().masterBuffer()->tocBackend().update();
+       bv_->buffer().structureChanged();
+}
+
+
+void TocModels::reset(BufferView const * bv)
+{
+       bv_ = bv;
+       clear();
+       if (!bv_)
+               return;
+
+       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));
+       }
+}
+
+
+bool TocModels::canOutline(int type) const
+{
+       if (type < 0 || type >= types_.size())
+               return false;
+       return types_[type] == "tableofcontents";
+}
+
+
+int TocModels::decodeType(QString const & str) const
+{
+       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
 } // namespace lyx