Warning, file /office/calligra/libs/text/KoSectionModel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #include "KoSectionModel.h" 0002 0003 #include <climits> 0004 #include <KoTextDocument.h> 0005 #include <KLocalizedString> 0006 0007 KoSectionModel::KoSectionModel(QTextDocument *doc) 0008 : QAbstractItemModel() 0009 , m_doc(doc) 0010 { 0011 KoTextDocument(m_doc).setSectionModel(this); 0012 } 0013 0014 KoSectionModel::~KoSectionModel() 0015 { 0016 foreach(KoSection *sec, m_registeredSections) { 0017 delete sec; // This will delete associated KoSectionEnd in KoSection destructor 0018 } 0019 } 0020 0021 KoSection *KoSectionModel::createSection(const QTextCursor &cursor, KoSection *parent, const QString &name) 0022 { 0023 if (!isValidNewName(name)) { 0024 return 0; 0025 } 0026 0027 KoSection *result = new KoSection(cursor, name, parent); 0028 0029 // Lets find our number in parent's children by cursor position 0030 QVector<KoSection *> children = (parent ? parent->children() : m_rootSections); 0031 int childrenId = children.size(); 0032 for (int i = 0; i < children.size(); i++) { 0033 if (cursor.position() < children[i]->bounds().first) { 0034 childrenId = i; 0035 break; 0036 } 0037 } 0038 // We need to place link from parent to children in childId place 0039 // Also need to find corresponding index and declare operations in terms of model 0040 insertToModel(result, childrenId); 0041 0042 return result; 0043 } 0044 0045 KoSection *KoSectionModel::createSection(const QTextCursor &cursor, KoSection *parent) 0046 { 0047 return createSection(cursor, parent, possibleNewName()); 0048 } 0049 0050 KoSectionEnd *KoSectionModel::createSectionEnd(KoSection *section) 0051 { 0052 return new KoSectionEnd(section); 0053 } 0054 0055 KoSection *KoSectionModel::sectionAtPosition(int pos) const 0056 { 0057 // TODO: Rewrite it by traversing Model as tree 0058 KoSection *result = 0; 0059 int level = -1; // Seeking the section with maximum level 0060 QHash<QString, KoSection *>::ConstIterator it = m_sectionNames.begin(); 0061 for (; it != m_sectionNames.end(); ++it) { 0062 QPair<int, int> bounds = it.value()->bounds(); 0063 if (bounds.first > pos || bounds.second < pos) { 0064 continue; 0065 } 0066 0067 if (it.value()->level() > level) { 0068 result = it.value(); 0069 level = it.value()->level(); 0070 } 0071 } 0072 0073 return result; 0074 } 0075 0076 bool KoSectionModel::isValidNewName(const QString &name) const 0077 { 0078 return (m_sectionNames.constFind(name) == m_sectionNames.constEnd()); 0079 } 0080 0081 QString KoSectionModel::possibleNewName() 0082 { 0083 QString newName; 0084 int i = m_registeredSections.count(); 0085 do { 0086 i++; 0087 newName = i18nc("new numbered section name", "New section %1", i); 0088 } while (!isValidNewName(newName)); 0089 0090 return newName; 0091 } 0092 0093 bool KoSectionModel::setName(KoSection *section, const QString &name) 0094 { 0095 if (section->name() == name || isValidNewName(name)) { 0096 section->setName(name); 0097 //TODO: we don't have name in columns, but need something to notify views about change 0098 emit dataChanged(m_modelIndex[section], m_modelIndex[section]); 0099 return true; 0100 } 0101 return false; 0102 } 0103 0104 void KoSectionModel::allowMovingEndBound() 0105 { 0106 QSet<KoSection *>::ConstIterator it = m_registeredSections.constBegin(); 0107 for (; it != m_registeredSections.constEnd(); ++it) { 0108 (*it)->setKeepEndBound(false); 0109 } 0110 } 0111 0112 int KoSectionModel::findRowOfChild(KoSection *section) const 0113 { 0114 QVector<KoSection *> lookOn; 0115 if (!section->parent()) { 0116 lookOn = m_rootSections; 0117 } else { 0118 lookOn = section->parent()->children(); 0119 } 0120 0121 int result = lookOn.indexOf(section); 0122 Q_ASSERT(result != -1); 0123 return result; 0124 } 0125 0126 QModelIndex KoSectionModel::index(int row, int column, const QModelIndex &parentIdx) const 0127 { 0128 if (!hasIndex(row, column, parentIdx)) { 0129 return QModelIndex(); 0130 } 0131 0132 if (!parentIdx.isValid()) { 0133 return createIndex(row, column, m_rootSections[row]); 0134 } 0135 0136 KoSection *parent = static_cast<KoSection *>(parentIdx.internalPointer()); 0137 return createIndex(row, column, parent->children().at(row)); 0138 } 0139 0140 QModelIndex KoSectionModel::parent(const QModelIndex &child) const 0141 { 0142 if (!child.isValid()) { 0143 return QModelIndex(); 0144 } 0145 0146 KoSection *section = static_cast<KoSection *>(child.internalPointer()); 0147 KoSection *parent = section->parent(); 0148 if (parent) { 0149 return createIndex(findRowOfChild(parent), 0, parent); 0150 } 0151 return QModelIndex(); 0152 } 0153 0154 int KoSectionModel::rowCount(const QModelIndex &parent) const 0155 { 0156 if (!parent.isValid()) { 0157 return m_rootSections.size(); 0158 } 0159 return static_cast<KoSection *>(parent.internalPointer())->children().size(); 0160 } 0161 0162 int KoSectionModel::columnCount(const QModelIndex &/*parent*/) const 0163 { 0164 return 1; 0165 } 0166 0167 QVariant KoSectionModel::data(const QModelIndex &index, int role) const 0168 { 0169 if (!index.isValid()) { 0170 return QVariant(); 0171 } 0172 0173 if (index.column() == 0 && role == PointerRole) { 0174 QVariant v; 0175 v.setValue(static_cast<KoSection *>(index.internalPointer())); 0176 return v; 0177 } 0178 return QVariant(); 0179 } 0180 0181 void KoSectionModel::insertToModel(KoSection *section, int childIdx) 0182 { 0183 Q_ASSERT(isValidNewName(section->name())); 0184 0185 KoSection *parent = section->parent(); 0186 if (parent) { // Inserting to some section 0187 beginInsertRows(m_modelIndex[parent], childIdx, childIdx); 0188 parent->insertChild(childIdx, section); 0189 endInsertRows(); 0190 m_modelIndex[section] = QPersistentModelIndex(index(childIdx, 0, m_modelIndex[parent])); 0191 } else { // It will be root section 0192 beginInsertRows(QModelIndex(), childIdx, childIdx); 0193 m_rootSections.insert(childIdx, section); 0194 endInsertRows(); 0195 m_modelIndex[section] = QPersistentModelIndex(index(childIdx, 0, QModelIndex())); 0196 } 0197 0198 m_registeredSections.insert(section); 0199 m_sectionNames[section->name()] = section; 0200 } 0201 0202 void KoSectionModel::deleteFromModel(KoSection *section) 0203 { 0204 KoSection *parent = section->parent(); 0205 int childIdx = findRowOfChild(section); 0206 if (parent) { // Deleting non root section 0207 beginRemoveRows(m_modelIndex[parent], childIdx, childIdx); 0208 parent->removeChild(childIdx); 0209 endRemoveRows(); 0210 } else { // Deleting root section 0211 beginRemoveRows(QModelIndex(), childIdx, childIdx); 0212 m_rootSections.remove(childIdx); 0213 endRemoveRows(); 0214 } 0215 m_modelIndex.remove(section); 0216 m_sectionNames.remove(section->name()); 0217 }