namespace lyx {
namespace frontend {
+TocTypeModel::TocTypeModel(QObject * parent): QStandardItemModel(parent)
+{
+}
+
+
+void TocTypeModel::reset()
+{
+ QStandardItemModel::reset();
+}
+
TocItem const & TocModel::tocItem(QModelIndex const & index) const
{
- return toc_[data(index, Qt::UserRole).toUInt()];
+ return (*toc_)[data(index, Qt::UserRole).toUInt()];
}
QModelIndex TocModel::modelIndex(DocIterator const & dit) const
{
- if (toc_.empty())
+ if (toc_->empty())
return QModelIndex();
- unsigned int const toc_index = toc_.item(dit) - toc_.begin();
+ unsigned int const toc_index = toc_->item(dit) - toc_->begin();
QModelIndexList list = match(index(0, 0), Qt::UserRole,
QVariant(toc_index), 1,
}
-TocModel::TocModel(Toc const & toc): toc_(toc)
+TocModel::TocModel(QObject * parent): QStandardItemModel(parent)
+{
+}
+
+
+void TocModel::reset()
+{
+ QStandardItemModel::reset();
+}
+
+
+void TocModel::reset(Toc const & toc)
{
- if (toc_.empty())
+ toc_ = &toc;
+ if (toc_->empty()) {
+ reset();
return;
+ }
+
+ blockSignals(true);
int current_row;
QModelIndex top_level_item;
insertColumns(0, 1);
maxdepth_ = 0;
mindepth_ = INT_MAX;
- size_t end = toc.size();
+ size_t end = toc_->size();
for (unsigned int index = 0; index != end; ++index) {
- TocItem const & item = toc_[index];
+ TocItem const & item = (*toc_)[index];
maxdepth_ = max(maxdepth_, item.depth());
mindepth_ = min(mindepth_, item.depth());
current_row = rowCount();
}
setHeaderData(0, Qt::Horizontal, QVariant("title"), Qt::DisplayRole);
+ blockSignals(false);
+ reset();
// emit headerDataChanged();
}
void TocModel::populate(unsigned int & index, QModelIndex const & parent)
{
- int curdepth = toc_[index].depth() + 1;
+ int curdepth = (*toc_)[index].depth() + 1;
int current_row;
QModelIndex child_item;
insertColumns(0, 1, parent);
- size_t end = toc_.size();
+ size_t end = toc_->size();
++index;
for (; index != end; ++index) {
- TocItem const & item = toc_[index];
+ TocItem const & item = (*toc_)[index];
if (item.depth() < curdepth) {
--index;
return;
///////////////////////////////////////////////////////////////////////////////
// TocModels implementation.
///////////////////////////////////////////////////////////////////////////////
+
+TocModels::TocModels(): bv_(0)
+{
+ names_ = new TocTypeModel(this);
+}
+
+
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];
+ names_->blockSignals(true);
+ names_->clear();
+ names_->blockSignals(false);
+ iterator end = models_.end();
+ for (iterator it = models_.begin(); it != end; ++it) {
+ it.value()->blockSignals(true);
+ it.value()->clear();
+ it.value()->blockSignals(false);
}
- models_.clear();
}
-int TocModels::depth(int type)
+int TocModels::depth(QString const & type)
{
- if (type < 0)
+ const_iterator it = models_.find(type);
+ if (!bv_ || it == models_.end())
return 0;
- return models_[type]->modelDepth();
+ return it.value()->modelDepth();
}
-QStandardItemModel * TocModels::model(int type)
+QStandardItemModel * TocModels::model(QString const & type)
{
- if (type < 0)
- return 0;
-
- if (models_.empty()) {
- LYXERR(Debug::GUI, "TocModels::tocModel(): no types available ");
+ if (!bv_)
return 0;
- }
-
- LYXERR(Debug::GUI, "TocModels: type " << type
- << " models_.size() " << models_.size());
-
- LASSERT(type >= 0 && type < int(models_.size()), /**/);
- return models_[type];
+ iterator it = models_.find(type);
+ if (it != models_.end())
+ return it.value();
+ LYXERR0("type not found: " << type);
+ return 0;
}
-QModelIndex TocModels::currentIndex(int type) const
+QModelIndex TocModels::currentIndex(QString const & type) const
{
- if (type < 0 || !bv_)
+ const_iterator it = models_.find(type);
+ if (!bv_ || it == models_.end())
return QModelIndex();
- return models_[type]->modelIndex(bv_->cursor());
+ return it.value()->modelIndex(bv_->cursor());
}
-void TocModels::goTo(int type, QModelIndex const & index) const
+void TocModels::goTo(QString const & type, QModelIndex const & index) const
{
- if (type < 0 || !index.isValid()
- || index.model() != models_[type]) {
+ const_iterator it = models_.find(type);
+ if (it == models_.end() || !index.isValid()) {
LYXERR(Debug::GUI, "TocModels::goTo(): QModelIndex is invalid!");
return;
}
-
- LASSERT(type >= 0 && type < int(models_.size()), /**/);
- TocItem const item = models_[type]->tocItem(index);
+ LASSERT(index.model() == it.value(), return);
+ TocItem const item = it.value()->tocItem(index);
LYXERR(Debug::GUI, "TocModels::goTo " << item.str());
dispatch(item.action());
}
{
bv_ = bv;
clear();
- if (!bv_)
+ if (!bv_) {
+ iterator end = models_.end();
+ for (iterator it = models_.begin(); it != end; ++it)
+ it.value()->reset();
+ names_->reset();
return;
+ }
+ names_->blockSignals(true);
+ names_->insertColumns(0, 1);
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));
+ TocList::const_iterator toc_end = tocs.end();
+ for (; it != toc_end; ++it) {
+ QString const type = toqstr(it->first);
+
+ // First, fill in the toc models.
+ iterator mod_it = models_.find(type);
+ if (mod_it == models_.end())
+ mod_it = models_.insert(type, new TocModel(this));
+ mod_it.value()->reset(it->second);
+
+ // Fill in the names_ model.
+ QString const gui_name = guiName(it->first, bv->buffer().params());
+ int const current_row = names_->rowCount();
+ names_->insertRows(current_row, 1);
+ QModelIndex const index = names_->index(current_row, 0);
+ names_->setData(index, gui_name, Qt::DisplayRole);
+ names_->setData(index, type, Qt::UserRole);
}
+ names_->blockSignals(false);
+ names_->reset();
}
-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
namespace frontend {
+class TocTypeModel : public QStandardItemModel
+{
+public:
+ ///
+ TocTypeModel(QObject * parent = 0);
+ ///
+ void reset();
+};
+
+
class TocModel : public QStandardItemModel
{
public:
///
- TocModel(Toc const & toc);
+ TocModel(QObject * parent = 0);
+ ///
+ void reset(Toc const & toc);
+ ///
+ void reset();
///
TocItem const & tocItem(QModelIndex const & index) const;
///
///
QList<QModelIndex> toc_indexes_;
///
- Toc const & toc_;
+ Toc const * toc_;
///
int maxdepth_;
int mindepth_;
Q_OBJECT
public:
///
- TocModels(): bv_(0) {}
+ TocModels();
///
- ~TocModels() { clear(); }
+ typedef QHash<QString, TocModel *>::const_iterator const_iterator;
+ const_iterator begin() const { return models_.begin(); }
+ const_iterator end() const { return models_.end(); }
///
void reset(BufferView const * bv);
///
- int depth(int type);
+ int depth(QString const & type);
+ ///
+ QStandardItemModel * model(QString const & type);
///
- QStandardItemModel * model(int type);
+ QStandardItemModel * nameModel() { return names_; }
///
- QModelIndex currentIndex(int type) const;
+ QModelIndex currentIndex(QString const & type) const;
///
- void goTo(int type, QModelIndex const & index) const;
+ void goTo(QString const & type, QModelIndex const & index) const;
///
void init(Buffer const & buffer);
- /// Test if outlining operation is possible
- bool canOutline(int type) const;
- /// Return the list of types available
- QStringList const & typeNames() const { return type_names_; }
///
void updateBackend() const;
- ///
- int decodeType(QString const & str) const;
Q_SIGNALS:
/// Signal that the internal toc_models_ has been reset.
void modelReset();
private:
+ typedef QHash<QString, TocModel *>::iterator iterator;
///
void clear();
///
- BufferView const * bv_;
+ void deleteAll();
///
- QList<TocModel *> models_;
+ BufferView const * bv_;
///
- QStringList types_;
+ QHash<QString, TocModel *> models_;
///
- QStringList type_names_;
+ TocTypeModel * names_;
};
} // namespace frontend
// Only one item selected at a time.
tocTV->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // The toc types combo won't change its model.
+ typeCO->setModel(gui_view_.tocModels().nameModel());
}
LYXERR(Debug::GUI, "goto " << index.row()
<< ", " << index.column());
- gui_view_.tocModels().goTo(typeCO->currentIndex(), index);
+ gui_view_.tocModels().goTo(current_type_, index);
}
void TocWidget::setTreeDepth(int depth)
{
depth_ = depth;
+ if (!tocTV->model())
+ return;
// expanding and then collapsing is probably better,
// but my qt 4.1.2 doesn't have expandAll()..
}
-void TocWidget::on_typeCO_currentIndexChanged(int)
+void TocWidget::on_typeCO_currentIndexChanged(int index)
{
+ current_type_ = typeCO->itemData(index).toString();
updateView();
gui_view_.setFocus();
}
}
+/// Test if outlining operation is possible
+static bool canOutline(QString const & type)
+{
+ return type == "tableofcontents";
+}
+
+
void TocWidget::enableControls(bool enable)
{
updateTB->setEnabled(enable);
- if (!gui_view_.tocModels().canOutline(typeCO->currentIndex()))
+ if (!canOutline(current_type_))
enable = false;
moveUpTB->setEnabled(enable);
LYXERR(Debug::GUI, "In TocWidget::updateView()");
setTocModel();
setTreeDepth(depth_);
- select(gui_view_.tocModels().currentIndex(typeCO->currentIndex()));
+ select(gui_view_.tocModels().currentIndex(current_type_));
+}
+
+
+static QString decodeType(QString const & str)
+{
+ QString type = str;
+ if (type.contains("tableofcontents")) {
+ type = "tableofcontents";
+ } else if (type.contains("floatlist")) {
+ if (type.contains("\"figure"))
+ type = "figure";
+ else if (type.contains("\"table"))
+ type = "table";
+ else if (type.contains("\"algorithm"))
+ type = "algorithm";
+ }
+ return type;
}
void TocWidget::init(QString const & str)
{
- QStringList const & type_names = gui_view_.tocModels().typeNames();
- if (type_names.isEmpty()) {
+ if (!gui_view_.view()) {
enableControls(false);
typeCO->setEnabled(false);
- tocTV->setModel(new QStandardItemModel);
+ tocTV->setModel(0);
tocTV->setEnabled(false);
return;
}
typeCO->setEnabled(true);
tocTV->setEnabled(true);
- int selected_type = gui_view_.tocModels().decodeType(str);
- QString const current_text = typeCO->currentText();
typeCO->blockSignals(true);
- typeCO->clear();
- for (int i = 0; i != type_names.size(); ++i)
- typeCO->addItem(type_names[i]);
- if (!str.isEmpty())
- typeCO->setCurrentIndex(selected_type);
- else {
- int const new_index = typeCO->findText(current_text);
- if (new_index != -1)
- typeCO->setCurrentIndex(new_index);
- else
- typeCO->setCurrentIndex(selected_type);
+
+ int new_index;
+ if (str.isEmpty())
+ new_index = typeCO->findData(current_type_);
+ else
+ new_index = typeCO->findData(decodeType(str));
+
+ // If everything else fails, settle on the table of contents which is
+ // guaranted to exist.
+ if (new_index == -1) {
+ current_type_ = "tableofcontents";
+ new_index = typeCO->findData(current_type_);
}
+ typeCO->setCurrentIndex(new_index);
typeCO->blockSignals(false);
-
- // setTocModel produce QTreeView reset and setting depth again
- // is needed. That must be done after all Qt updates are processed.
- QTimer::singleShot(0, this, SLOT(updateView()));
}
void TocWidget::setTocModel()
{
- int const toc_type = typeCO->currentIndex();
- QStandardItemModel * toc_model = gui_view_.tocModels().model(toc_type);
- LASSERT(toc_model, return);
+ QStandardItemModel * toc_model = gui_view_.tocModels().model(current_type_);
if (tocTV->model() != toc_model) {
tocTV->setModel(toc_model);
tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
- bool controls_enabled = toc_model->rowCount() > 0;;
+ bool controls_enabled = toc_model && toc_model->rowCount() > 0;;
enableControls(controls_enabled);
if (controls_enabled) {
- depthSL->setMaximum(gui_view_.tocModels().depth(toc_type));
+ depthSL->setMaximum(gui_view_.tocModels().depth(current_type_));
depthSL->setValue(depth_);
}
}