📄 maildirfolder.cpp
字号:
throw exceptions::illegal_state("Store disconnected"); return vmime::create <maildirFolder>(m_path / name, store);}std::vector <ref <folder> > maildirFolder::getFolders(const bool recursive){ ref <maildirStore> store = m_store.acquire(); if (!isOpen() && !store) throw exceptions::illegal_state("Store disconnected"); std::vector <ref <folder> > list; listFolders(list, recursive); return (list);}void maildirFolder::listFolders(std::vector <ref <folder> >& list, const bool recursive){ ref <maildirStore> store = m_store.acquire(); try { std::vector <folder::path> pathList = store->getFormat()->listFolders(m_path, recursive); list.reserve(pathList.size()); for (unsigned int i = 0, n = pathList.size() ; i < n ; ++i) { ref <maildirFolder> subFolder = vmime::create <maildirFolder>(pathList[i], store); list.push_back(subFolder); } } catch (exceptions::filesystem_exception& e) { throw exceptions::command_error("LIST", "", "", e); }}void maildirFolder::rename(const folder::path& newPath){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (m_path.isEmpty() || newPath.isEmpty()) throw exceptions::illegal_operation("Cannot rename root folder"); else if (!store->isValidFolderName(newPath.getLastComponent())) throw exceptions::invalid_folder_name(); // Rename the directory on the file system try { store->getFormat()->renameFolder(m_path, newPath); } catch (vmime::exception& e) { throw exceptions::command_error("RENAME", "", "", e); } // Notify folder renamed folder::path oldPath(m_path); m_path = newPath; m_name = newPath.getLastComponent(); events::folderEvent event (thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, newPath); notifyFolder(event); // Notify folders with the same path for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == oldPath) { (*it)->m_path = newPath; (*it)->m_name = newPath.getLastComponent(); events::folderEvent event ((*it)->thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, newPath); (*it)->notifyFolder(event); } else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) { folder::path oldPath((*it)->m_path); (*it)->m_path.renameParent(oldPath, newPath); events::folderEvent event ((*it)->thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); (*it)->notifyFolder(event); } }}void maildirFolder::deleteMessage(const int num){ // Mark messages as deleted setMessageFlags(num, num, message::FLAG_DELETED, message::FLAG_MODE_ADD);}void maildirFolder::deleteMessages(const int from, const int to){ // Mark messages as deleted setMessageFlags(from, to, message::FLAG_DELETED, message::FLAG_MODE_ADD);}void maildirFolder::deleteMessages(const std::vector <int>& nums){ // Mark messages as deleted setMessageFlags(nums, message::FLAG_DELETED, message::FLAG_MODE_ADD);}void maildirFolder::setMessageFlags (const int from, const int to, const int flags, const int mode){ ref <maildirStore> store = m_store.acquire(); if (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Construct the list of message numbers const int to2 = (to == -1) ? m_messageCount : to; const int count = to - from + 1; std::vector <int> nums; nums.resize(count); for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) nums[j] = i; // Change message flags setMessageFlagsImpl(nums, flags, mode); // Update local flags switch (mode) { case message::FLAG_MODE_ADD: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; } } break; } case message::FLAG_MODE_REMOVE: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; } } break; } default: case message::FLAG_MODE_SET: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; } } break; } } // Notify message flags changed events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event); // TODO: notify other folders with the same path}void maildirFolder::setMessageFlags (const std::vector <int>& nums, const int flags, const int mode){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Sort the list of message numbers std::vector <int> list; list.resize(nums.size()); std::copy(nums.begin(), nums.end(), list.begin()); std::sort(list.begin(), list.end()); // Change message flags setMessageFlagsImpl(list, flags, mode); // Update local flags switch (mode) { case message::FLAG_MODE_ADD: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; } } break; } case message::FLAG_MODE_REMOVE: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; } } break; } default: case message::FLAG_MODE_SET: { for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; } } break; } } // Notify message flags changed events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event); // TODO: notify other folders with the same path}void maildirFolder::setMessageFlagsImpl (const std::vector <int>& nums, const int flags, const int mode){ ref <maildirStore> store = m_store.acquire(); utility::fileSystemFactory* fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path curDirPath = store->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); for (std::vector <int>::const_iterator it = nums.begin() ; it != nums.end() ; ++it) { const int num = *it - 1; try { const utility::file::path::component path = m_messageInfos[num].path; ref <utility::file> file = fsf->create(curDirPath / path); int newFlags = maildirUtils::extractFlags(path); switch (mode) { case message::FLAG_MODE_ADD: newFlags |= flags; break; case message::FLAG_MODE_REMOVE: newFlags &= ~flags; break; default: case message::FLAG_MODE_SET: newFlags = flags; break; } const utility::file::path::component newPath = maildirUtils::buildFilename (maildirUtils::extractId(path), newFlags); file->rename(curDirPath / newPath); if (flags & message::FLAG_DELETED) m_messageInfos[num].type = messageInfos::TYPE_DELETED; else m_messageInfos[num].type = messageInfos::TYPE_CUR; m_messageInfos[num].path = newPath; } catch (exceptions::filesystem_exception& e) { // Ignore (not important) } }}void maildirFolder::addMessage(ref <vmime::message> msg, const int flags, vmime::datetime* date, utility::progressListener* progress){ std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); msg->generate(ossAdapter); const std::string& str = oss.str(); utility::inputStreamStringAdapter strAdapter(str); addMessage(strAdapter, str.length(), flags, date, progress);}void maildirFolder::addMessage(utility::inputStream& is, const int size, const int flags, vmime::datetime* /* date */, utility::progressListener* progress){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); utility::fileSystemFactory* fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path tmpDirPath = store->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::TMP_DIRECTORY); utility::file::path curDirPath = store->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); const utility::file::path::component filename = maildirUtils::buildFilename(maildirUtils::generateId(), ((flags == message::FLAG_UNDEFINED) ? 0 : flags)); try { ref <utility::file> tmpDir = fsf->create(tmpDirPath); tmpDir->createDirectory(true); } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } try { ref <utility::file> curDir = fsf->create(curDirPath); curDir->createDirectory(true); } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } // Actually add the message copyMessageImpl(tmpDirPath, curDirPath, filename, is, size, progress); // Append the message to the cache list messageInfos msgInfos; msgInfos.path = filename; msgInfos.type = messageInfos::TYPE_CUR; m_messageInfos.push_back(msgInfos); m_messageCount++; if ((flags == message::FLAG_UNDEFINED) || !(flags & message::FLAG_SEEN)) m_unreadMessageCount++; // Notification std::vector <int> nums; nums.push_back(m_messageCount); events::messageCountEvent event (thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); notifyMessageCount(event); // Notify folders with the same path for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; (*it)->m_messageInfos.resize(m_messageInfos.size()); std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->notifyMessageCount(event); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -