File indexing completed on 2024-12-22 04:48:18
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2024 Louis Schul <schul9louis@gmail.com> 0004 */ 0005 0006 #include "noteMapperParserUtils.h" 0007 0008 #include "kleverconfig.h" 0009 #include "logic/parser/parser.h" 0010 0011 NoteMapperParserUtils::NoteMapperParserUtils(Parser *parser) 0012 : m_parser(parser) 0013 { 0014 } 0015 0016 void NoteMapperParserUtils::setPathsInfo(const QString ¬ePath) 0017 { 0018 // notePath == storagePath/Category/Group/Note/ => /Category/Group/Note 0019 m_mapperNotePath = notePath.chopped(1).remove(KleverConfig::storagePath()); 0020 0021 // /Category/Group/Note => /Category/Group (no '/' at the end to make it easier for m_categPath) 0022 const QString groupPath = m_mapperNotePath.chopped(m_mapperNotePath.size() - m_mapperNotePath.lastIndexOf(QStringLiteral("/"))); 0023 if (m_groupPath != groupPath) { 0024 m_groupPath = groupPath + QStringLiteral("/"); // /Category/Group => /Category/Group/ 0025 m_categPath = groupPath.chopped(groupPath.size() - groupPath.lastIndexOf(QStringLiteral("/")) - 1); // /Category/Group => /Category/ 0026 } 0027 } 0028 0029 QPair<QString, bool> NoteMapperParserUtils::sanitizePath(const QString &_path) const 0030 { 0031 static const QString slashStr = QStringLiteral("/"); 0032 QStringList parts = _path.split(slashStr); 0033 0034 bool leadingSlashRemnant = false; 0035 for (int i = 0; i < parts.count(); i++) { 0036 QString part = parts[i].trimmed(); 0037 if (part.isEmpty()) { 0038 if (i == 0) { 0039 leadingSlashRemnant = true; 0040 } else { // The path is not correctly formed 0041 return qMakePair(_path, false); 0042 } 0043 } 0044 parts[i] = part; 0045 } 0046 0047 if (leadingSlashRemnant) 0048 parts.removeAt(0); 0049 0050 if (parts[0] == KleverConfig::defaultCategoryDisplayNameValue()) 0051 parts[0] = QStringLiteral(".BaseCategory"); 0052 0053 QString path = _path; 0054 switch (parts.count()) { 0055 case 1: // Note name only 0056 path = m_groupPath + parts[0]; 0057 break; 0058 case 2: 0059 if (parts[0] == QStringLiteral(".")) { // Note name only 0060 path = m_groupPath + parts[1]; 0061 } else { // Note inside category 0062 path = slashStr + parts[0] + QStringLiteral("/.BaseGroup/") + parts[1]; 0063 } 0064 break; 0065 case 3: // 'Full' path 0066 path = slashStr + parts.join(slashStr); 0067 break; 0068 default: // Not a note path 0069 return qMakePair(_path, false); 0070 } 0071 0072 return qMakePair(path, true); 0073 } 0074 0075 void NoteMapperParserUtils::setHeaderInfo(const QStringList &headerInfo) 0076 { 0077 m_header = headerInfo[0]; 0078 m_headerLevel = m_header.isEmpty() ? QStringLiteral("0") : headerInfo[1]; 0079 } 0080 0081 QString NoteMapperParserUtils::headerLevel() const 0082 { 0083 return m_headerLevel; 0084 }; 0085 0086 void NoteMapperParserUtils::checkHeaderFound(const QString &header, const QString &level) 0087 { 0088 if (header == m_header && level == QString(m_headerLevel)) { 0089 m_headerFound = true; 0090 } 0091 } 0092 0093 bool NoteMapperParserUtils::headerFound() const 0094 { 0095 return m_headerFound; 0096 } 0097 0098 void NoteMapperParserUtils::addToLinkedNoteInfos(const QStringList &infos) 0099 { 0100 if ((!m_previousLinkedNotesInfos.remove(infos) && !m_linkedNotesInfos.contains(infos)) || infos.isEmpty()) { 0101 m_linkedNotesChanged = true; 0102 } 0103 m_linkedNotesInfos.insert(infos); 0104 } 0105 0106 void NoteMapperParserUtils::addToNoteHeaders(const QString &header) 0107 { 0108 if (!m_previousNoteHeaders.remove(header) && !m_noteHeaders.contains(header)) { 0109 m_noteHeadersChanged = true; 0110 } 0111 m_noteHeaders.insert(header); 0112 } 0113 0114 void NoteMapperParserUtils::postTok() 0115 { 0116 m_notePathChanged = false; 0117 0118 // We try to not spam with signals 0119 if (m_linkedNotesChanged || !m_previousLinkedNotesInfos.isEmpty()) { // The previous is not empty, some links notes are no longer there 0120 Q_EMIT m_parser->newLinkedNotesInfos(m_linkedNotesInfos); 0121 } 0122 m_previousLinkedNotesInfos = m_linkedNotesInfos; 0123 0124 if (m_noteHeadersChanged || !m_previousNoteHeaders.isEmpty()) { // The previous is not empty, some headers are no longer there 0125 m_emptyHeadersSent = false; 0126 Q_EMIT m_parser->noteHeadersSent(m_mapperNotePath, m_noteHeaders.values()); 0127 } else if (m_noteHeaders.isEmpty() && !m_emptyHeadersSent) { 0128 // This way the mapper can receive info about the note (the note has no header), and we still prevent spamming 0129 m_emptyHeadersSent = true; 0130 Q_EMIT m_parser->noteHeadersSent(m_mapperNotePath, {}); 0131 } 0132 m_previousNoteHeaders = m_noteHeaders; 0133 0134 if (!m_headerFound) { // Prevent the TextDisplay.qml scrollToHeader to search an unexisting header 0135 m_headerLevel = QStringLiteral("0"); 0136 m_header = QLatin1String(); 0137 } 0138 } 0139 0140 void NoteMapperParserUtils::clearInfo() 0141 { 0142 m_linkedNotesInfos.clear(); 0143 m_noteHeaders.clear(); 0144 m_linkedNotesInfos.clear(); 0145 0146 m_headerFound = false; 0147 if (!m_notePathChanged) { 0148 m_linkedNotesChanged = false; 0149 } 0150 } 0151 0152 void NoteMapperParserUtils::clearPreviousInfo() 0153 { 0154 m_previousLinkedNotesInfos.clear(); 0155 m_previousNoteHeaders.clear(); 0156 m_linkedNotesChanged = true; 0157 m_notePathChanged = true; 0158 }