Пример #1
0
void VDirectoryTree::handleItemCollapsed(QTreeWidgetItem *p_item)
{
    if (p_item) {
        VDirectory *dir = getVDirectory(p_item);
        dir->setExpanded(false);
    }
}
Пример #2
0
bool VNoteFile::deleteFile(VNoteFile *p_file, QString *p_errMsg)
{
    Q_ASSERT(!p_file->isOpened());

    bool ret = true;
    QString name = p_file->getName();
    QString path = p_file->fetchPath();

    if (!p_file->deleteFile(p_errMsg)) {
        qWarning() << "fail to delete file" << name << path;
        ret = false;
    }

    VDirectory *dir = p_file->getDirectory();
    Q_ASSERT(dir);
    if (!dir->removeFile(p_file)) {
        qWarning() << "fail to remove file from directory" << name << path;
        VUtils::addErrMsg(p_errMsg, tr("Fail to remove the note from the folder configuration."));
        ret = false;
    }

    delete p_file;

    return ret;
}
Пример #3
0
void VDirectoryTree::copySelectedDirectories(bool p_isCut)
{
    QList<QTreeWidgetItem *> items = selectedItems();
    if (items.isEmpty()) {
        return;
    }

    QJsonArray dirs;
    for (int i = 0; i < items.size(); ++i) {
        VDirectory *dir = getVDirectory(items[i]);
        dirs.append(dir->fetchPath());
    }

    QJsonObject clip;
    clip[ClipboardConfig::c_magic] = getNewMagic();
    clip[ClipboardConfig::c_type] = (int)ClipboardOpType::CopyDir;
    clip[ClipboardConfig::c_isCut] = p_isCut;
    clip[ClipboardConfig::c_dirs] = dirs;

    QClipboard *clipboard = QApplication::clipboard();
    clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact));

    qDebug() << "copied directories info" << clipboard->text();

    int cnt = dirs.size();
    g_mainWin->showStatusMessage(tr("%1 %2 %3")
                                   .arg(cnt)
                                   .arg(cnt > 1 ? tr("folders") : tr("folder"))
                                   .arg(p_isCut ? tr("cut") : tr("copied")));
}
Пример #4
0
void VDirectoryTree::deleteSelectedDirectory()
{
    Q_ASSERT(selectedItems().size() <= 1);

    QTreeWidgetItem *curItem = currentItem();
    if (!curItem) {
        return;
    }

    VDirectory *curDir = getVDirectory(curItem);
    int ret = VUtils::showMessage(QMessageBox::Warning,
                                  tr("Warning"),
                                  tr("Are you sure to delete folder <span style=\"%1\">%2</span>?")
                                    .arg(g_config->c_dataTextStyle)
                                    .arg(curDir->getName()),
                                  tr("<span style=\"%1\">WARNING</span>: "
                                     "VNote will delete the whole directory "
                                     "<span style=\"%2\">%3</span>."
                                     "Deleted files could be found in the recycle bin "
                                     "of this folder.<br>"
                                     "The operation is IRREVERSIBLE!")
                                    .arg(g_config->c_warningTextStyle)
                                    .arg(g_config->c_dataTextStyle)
                                    .arg(curDir->fetchPath()),
                                  QMessageBox::Ok | QMessageBox::Cancel,
                                  QMessageBox::Ok,
                                  this,
                                  MessageBoxType::Danger);

    if (ret == QMessageBox::Ok) {
        int nrDeleted = 1;
        m_editArea->closeFile(curDir, true);

        // Remove the item from the tree.
        delete curItem;

        QString msg;
        QString dirName = curDir->getName();
        QString dirPath = curDir->fetchPath();
        if (!VDirectory::deleteDirectory(curDir, false, &msg)) {
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to delete folder <span style=\"%1\">%2</span>.<br>"
                                   "Please check <span style=\"%1\">%3</span> and manually delete it.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(dirName)
                                  .arg(dirPath),
                                msg,
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);
        } else {
            g_mainWin->showStatusMessage(tr("%1 %2 deleted")
                                           .arg(nrDeleted)
                                           .arg(nrDeleted > 1 ? tr("folders") : tr("folder")));
        }
    }
}
Пример #5
0
void VDirectoryTree::handleItemExpanded(QTreeWidgetItem *p_item)
{
    if (p_item) {
        buildChildren(p_item);

        VDirectory *dir = getVDirectory(p_item);
        dir->setExpanded(true);
    }
}
Пример #6
0
void VDirectoryTree::expandSubTree(QTreeWidgetItem *p_item)
{
    if (!p_item) {
        return;
    }

    VDirectory *dir = getVDirectory(p_item);
    int nrChild = p_item->childCount();
    for (int i = 0; i < nrChild; ++i) {
        expandSubTree(p_item->child(i));
    }

    if (dir->isExpanded()) {
        Q_ASSERT(nrChild > 0);
        expandItem(p_item);
    }
}
Пример #7
0
void VListFolderUE::processCommand(int p_id, const QString &p_cmd)
{
    Q_UNUSED(p_id);

    init();

    QString folderPath = m_folderPath;
    if (folderPath.isEmpty()) {
        VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory();
        folderPath = dir->fetchPath();
    }

    listFolder(folderPath, p_cmd);

    m_listWidget->updateGeometry();
    emit widgetUpdated();
    emit stateUpdated(State::Success);
}
Пример #8
0
void VDirectoryTree::updateDirectoryTree()
{
    clear();

    VDirectory *rootDir = m_notebook->getRootDir();
    const QVector<VDirectory *> &subDirs = rootDir->getSubDirs();
    for (int i = 0; i < subDirs.size(); ++i) {
        VDirectory *dir = subDirs[i];
        QTreeWidgetItem *item = new QTreeWidgetItem(this);

        fillTreeItem(item, dir);

        buildSubTree(item, 1);
    }

    if (!restoreCurrentItem() && topLevelItemCount() > 0) {
        setCurrentItem(topLevelItem(0));
    }
}
Пример #9
0
void VDirectoryTree::newSubDirectory()
{
    if (!m_notebook) {
        return;
    }

    QTreeWidgetItem *curItem = currentItem();
    if (!curItem) {
        return;
    }

    VDirectory *curDir = getVDirectory(curItem);

    QString info = tr("Create a subfolder in <span style=\"%1\">%2</span>.")
                     .arg(g_config->c_dataTextStyle)
                     .arg(curDir->getName());
    QString defaultName("new_folder");
    defaultName = VUtils::getDirNameWithSequence(curDir->fetchPath(), defaultName);
    VNewDirDialog dialog(tr("Create Folder"), info, defaultName, curDir, this);
    if (dialog.exec() == QDialog::Accepted) {
        QString name = dialog.getNameInput();
        QString msg;
        VDirectory *subDir = curDir->createSubDirectory(name, &msg);
        if (!subDir) {
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to create subfolder <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(name),
                                msg,
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);
            return;
        }

        updateItemDirectChildren(curItem);

        locateDirectory(subDir);
    }
}
Пример #10
0
void VDirectoryTree::editDirectoryInfo()
{
    QTreeWidgetItem *curItem = currentItem();
    if (!curItem) {
        return;
    }

    VDirectory *curDir = getVDirectory(curItem);
    QString curName = curDir->getName();

    VDirInfoDialog dialog(tr("Folder Information"),
                          "",
                          curDir,
                          curDir->getParentDirectory(),
                          this);
    if (dialog.exec() == QDialog::Accepted) {
        QString name = dialog.getNameInput();
        if (name == curName) {
            return;
        }

        if (!curDir->rename(name)) {
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to rename folder <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(curName),
                                "",
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);
            return;
        }

        fillTreeItem(curItem, curDir);

        emit directoryUpdated(curDir, UpdateAction::InfoChanged);
    }
}
Пример #11
0
bool VNoteFile::rename(const QString &p_name)
{
    if (m_name == p_name) {
        return true;
    }

    QString oldName = m_name;

    VDirectory *dir = getDirectory();
    Q_ASSERT(dir);

    // Rename it in disk.
    QDir diskDir(dir->fetchPath());
    if (!diskDir.rename(m_name, p_name)) {
        qWarning() << "fail to rename file" << m_name << "to" << p_name << "in disk";
        return false;
    }

    m_name = p_name;

    // Update parent directory's config file.
    if (!dir->updateFileConfig(this)) {
        m_name = oldName;
        diskDir.rename(p_name, m_name);
        return false;
    }

    // Can't not change doc type.
    Q_ASSERT(m_docType == DocType::Unknown
             || m_docType == VUtils::docTypeFromName(m_name));

    m_docType = VUtils::docTypeFromName(m_name);

    qDebug() << "file renamed from" << oldName << "to" << m_name;
    return true;
}
Пример #12
0
void VDirectoryTree::newRootDirectory()
{
    if (!m_notebook) {
        return;
    }

    VDirectory *rootDir = m_notebook->getRootDir();

    QString info = tr("Create a root folder in notebook <span style=\"%1\">%2</span>.")
                     .arg(g_config->c_dataTextStyle)
                     .arg(m_notebook->getName());
    QString defaultName("new_folder");
    defaultName = VUtils::getDirNameWithSequence(rootDir->fetchPath(), defaultName);
    VNewDirDialog dialog(tr("Create Root Folder"), info, defaultName, rootDir, this);
    if (dialog.exec() == QDialog::Accepted) {
        QString name = dialog.getNameInput();
        QString msg;
        VDirectory *dir = rootDir->createSubDirectory(name, &msg);
        if (!dir) {
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to create root folder <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(name),
                                msg,
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);
            return;
        }

        updateItemDirectChildren(NULL);

        locateDirectory(dir);
    }
}
Пример #13
0
void VDirectoryTree::buildSubTree(QTreeWidgetItem *p_parent, int p_depth)
{
    if (p_depth == 0) {
        return;
    }

    Q_ASSERT(p_parent);

    VDirectory *dir = getVDirectory(p_parent);
    if (!dir->open()) {
        VUtils::showMessage(QMessageBox::Warning,
                            tr("Warning"),
                            tr("Fail to open folder <span style=\"%1\">%2</span>.")
                              .arg(g_config->c_dataTextStyle)
                              .arg(dir->getName()),
                            tr("Please check if directory <span style=\"%1\">%2</span> exists.")
                              .arg(g_config->c_dataTextStyle)
                              .arg(dir->fetchPath()),
                            QMessageBox::Ok,
                            QMessageBox::Ok,
                            this);
        return;
    }

    if (p_parent->childCount() > 0) {
        // This directory has been built before. Try its children directly.
        int cnt = p_parent->childCount();
        for (int i = 0; i < cnt; ++i) {
            buildSubTree(p_parent->child(i), p_depth -1);
        }
    } else {
        const QVector<VDirectory *> &subDirs = dir->getSubDirs();
        for (int i = 0; i < subDirs.size(); ++i) {
            VDirectory *subDir = subDirs[i];
            QTreeWidgetItem *item = new QTreeWidgetItem(p_parent);
            fillTreeItem(item, subDir);
            buildSubTree(item, p_depth - 1);
        }
    }

    if (dir->isExpanded()) {
        expandItem(p_parent);
    }
}
Пример #14
0
bool VListFolderUE::listFolder(const QString &p_path, const QString &p_cmd)
{
    VDirectory *dir = g_vnote->getInternalDirectory(p_path);
    if (!dir) {
        // See if it is a notebook.
        VNotebook *nb = g_vnote->getNotebook(p_path);
        if (!nb) {
            return false;
        }

        dir = nb->getRootDir();
    }

    m_panel->clearTitle();
    m_listWidget->clearAll();
    m_data.clear();

    m_currentFolderPath = dir->fetchPath();
    m_panel->setTitle(m_currentFolderPath);

    if (!dir->open()) {
        return true;
    }

    if (p_cmd.isEmpty()) {
        // List the content.
        for (auto const & it : dir->getSubDirs()) {
            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Folder,
                                                                         VSearchResultItem::LineNumber,
                                                                         it->getName(),
                                                                         it->fetchPath()));
            addResultItem(item);
        }

        for (auto const & file : dir->getFiles()) {
            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Note,
                                                                         VSearchResultItem::LineNumber,
                                                                         file->getName(),
                                                                         file->fetchPath()));
            addResultItem(item);
        }
    } else {
        // Search the content.
        VSearchConfig config(VSearchConfig::CurrentFolder,
                             VSearchConfig::Name,
                             VSearchConfig::Note | VSearchConfig::Folder,
                             VSearchConfig::Internal,
                             VSearchConfig::NoneOption,
                             p_cmd,
                             QString());

        for (auto const & it : dir->getSubDirs()) {
            QString name = it->getName();
            if (!config.m_token.matched(name)) {
                continue;
            }

            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Folder,
                                                                         VSearchResultItem::LineNumber,
                                                                         name,
                                                                         it->fetchPath()));
            addResultItem(item);
        }

        for (auto const & file : dir->getFiles()) {
            QString name = file->getName();
            if (!config.m_token.matched(name)) {
                continue;
            }

            QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Note,
                                                                         VSearchResultItem::LineNumber,
                                                                         name,
                                                                         file->fetchPath()));
            addResultItem(item);
        }
    }

    return true;
}
Пример #15
0
bool VNoteFile::copyFile(VDirectory *p_destDir,
                         const QString &p_destName,
                         VNoteFile *p_file,
                         bool p_isCut,
                         VNoteFile **p_targetFile,
                         QString *p_errMsg)
{
    bool ret = true;
    *p_targetFile = NULL;
    int nrImageCopied = 0;
    bool attachmentFolderCopied = false;

    QString srcPath = QDir::cleanPath(p_file->fetchPath());
    QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName));
    if (VUtils::equalPath(srcPath, destPath)) {
        *p_targetFile = p_file;
        return false;
    }

    if (!p_destDir->isOpened()) {
        VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder."));
        return false;
    }

    QString opStr = p_isCut ? tr("cut") : tr("copy");
    VDirectory *srcDir = p_file->getDirectory();
    DocType docType = p_file->getDocType();

    Q_ASSERT(srcDir->isOpened());
    Q_ASSERT(docType == VUtils::docTypeFromName(p_destName));

    // Images to be copied.
    QVector<ImageLink> images;
    if (docType == DocType::Markdown) {
        images = VUtils::fetchImagesFromMarkdownFile(p_file,
                                                     ImageLink::LocalRelativeInternal);
    }

    // Attachments to be copied.
    QString attaFolder = p_file->getAttachmentFolder();
    QString attaFolderPath;
    if (!attaFolder.isEmpty()) {
        attaFolderPath = p_file->fetchAttachmentFolderPath();
    }

    // Copy the note file.
    if (!VUtils::copyFile(srcPath, destPath, p_isCut)) {
        VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the note file.").arg(opStr));
        qWarning() << "fail to" << opStr << "the note file" << srcPath << "to" << destPath;
        return false;
    }

    // Add file to VDirectory.
    VNoteFile *destFile = NULL;
    if (p_isCut) {
        srcDir->removeFile(p_file);
        p_file->setName(p_destName);
        if (p_destDir->addFile(p_file, -1)) {
            destFile = p_file;
        } else {
            destFile = NULL;
        }
    } else {
        destFile = p_destDir->addFile(p_destName, -1);
    }

    if (!destFile) {
        VUtils::addErrMsg(p_errMsg, tr("Fail to add the note to target folder's configuration."));
        return false;
    }

    // Copy images.
    if (!copyInternalImages(images,
                            destFile->fetchBasePath(),
                            p_isCut,
                            &nrImageCopied,
                            p_errMsg)) {
        ret = false;
    }

    // Copy attachment folder.
    if (!attaFolderPath.isEmpty()) {
        QDir dir(destFile->fetchBasePath());
        QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder());
        attaFolder = VUtils::getDirNameWithSequence(folderPath, attaFolder);
        folderPath = QDir(folderPath).filePath(attaFolder);

        // Copy attaFolderPath to folderPath.
        if (!VUtils::copyDirectory(attaFolderPath, folderPath, p_isCut)) {
            VUtils::addErrMsg(p_errMsg, tr("Fail to %1 attachments folder %2 to %3. "
                                           "Please manually maintain it.")
                                          .arg(opStr).arg(attaFolderPath).arg(folderPath));
            QVector<VAttachment> emptyAttas;
            destFile->setAttachments(emptyAttas);
            ret = false;
        } else {
            attachmentFolderCopied = true;

            destFile->setAttachmentFolder(attaFolder);
            if (!p_isCut) {
                destFile->setAttachments(p_file->getAttachments());
            }
        }

        if (!p_destDir->updateFileConfig(destFile)) {
            VUtils::addErrMsg(p_errMsg, tr("Fail to update configuration of note %1.")
                                          .arg(destFile->fetchPath()));
            ret = false;
        }
    }

    qDebug() << "copyFile:" << p_file << "to" << destFile
             << "copied_images:" << nrImageCopied
             << "copied_attachments:" << attachmentFolderCopied;

    *p_targetFile = destFile;
    return ret;
}
Пример #16
0
void VDirectoryTree::pasteDirectories(VDirectory *p_destDir,
                                      const QVector<QString> &p_dirs,
                                      bool p_isCut)
{
    if (!p_destDir || p_dirs.isEmpty()) {
        return;
    }

    int nrPasted = 0;
    for (int i = 0; i < p_dirs.size(); ++i) {
        VDirectory *dir = g_vnote->getInternalDirectory(p_dirs[i]);
        if (!dir) {
            qWarning() << "Copied dir is not an internal folder" << p_dirs[i];
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to paste folder <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(p_dirs[i]),
                                tr("VNote could not find this folder in any notebook."),
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);

            continue;
        }

        if (dir == p_destDir) {
            continue;
        }

        QString dirName = dir->getName();
        VDirectory *paDir = dir->getParentDirectory();
        if (paDir == p_destDir) {
            if (p_isCut) {
                continue;
            }

            // Copy and paste in the same folder.
            // Rename it to xxx_copy.
            dirName = VUtils::generateCopiedDirName(paDir->fetchPath(), dirName);
        } else {
            // Rename it to xxx_copy if needed.
            dirName = VUtils::generateCopiedDirName(p_destDir->fetchPath(), dirName);
        }

        QString msg;
        VDirectory *destDir = NULL;
        bool ret = VDirectory::copyDirectory(p_destDir,
                                             dirName,
                                             dir,
                                             p_isCut,
                                             &destDir,
                                             &msg);
        if (!ret) {
            VUtils::showMessage(QMessageBox::Warning,
                                tr("Warning"),
                                tr("Fail to copy folder <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle)
                                  .arg(p_dirs[i]),
                                msg,
                                QMessageBox::Ok,
                                QMessageBox::Ok,
                                this);
        }

        if (destDir) {
            ++nrPasted;

            // Update QTreeWidget.
            bool isWidget;
            QTreeWidgetItem *destItem = findVDirectory(p_destDir, &isWidget);
            if (destItem || isWidget) {
                updateItemDirectChildren(destItem);
            }

            if (p_isCut) {
                QTreeWidgetItem *srcItem = findVDirectory(paDir, &isWidget);
                if (srcItem || isWidget) {
                    updateItemDirectChildren(srcItem);
                }
            }

            // Broadcast this update
            emit directoryUpdated(destDir, p_isCut ? UpdateAction::Moved : UpdateAction::InfoChanged);
        }
    }

    qDebug() << "pasted" << nrPasted << "directories";
    if (nrPasted > 0) {
        g_mainWin->showStatusMessage(tr("%1 %2 pasted")
                                       .arg(nrPasted)
                                       .arg(nrPasted > 1 ? tr("folders") : tr("folder")));
    }

    getNewMagic();
}
Пример #17
0
void VSearcher::startSearch()
{
    if (m_inSearch) {
        return;
    }

    m_searchBtn->setEnabled(false);
    setProgressVisible(true);
    m_results->clearResults();
    m_askedToStop = false;
    m_inSearch = true;
    m_consoleEdit->clear();
    appendLogLine(tr("Search started."));

    updateItemToComboBox(m_keywordCB);
    updateItemToComboBox(m_filePatternCB);

    m_search.clear();

    QSharedPointer<VSearchConfig> config(new VSearchConfig(m_searchScopeCB->currentData().toInt(),
                                                           m_searchObjectCB->currentData().toInt(),
                                                           m_searchTargetCB->currentData().toInt(),
                                                           m_searchEngineCB->currentData().toInt(),
                                                           getSearchOption(),
                                                           m_keywordCB->currentText(),
                                                           m_filePatternCB->currentText()));
    m_search.setConfig(config);

    g_config->setSearchOptions(config->toConfig());

    QSharedPointer<VSearchResult> result;
    switch (config->m_scope) {
    case VSearchConfig::CurrentNote:
    {
        QVector<VFile *> files;
        files.append(g_mainWin->getCurrentFile());
        if (files[0]) {
            QString msg(tr("Search current note %1.").arg(files[0]->getName()));
            appendLogLine(msg);
            showMessage(msg);
        }

        result = m_search.search(files);
        break;
    }

    case VSearchConfig::OpenedNotes:
    {
        QVector<VEditTabInfo> tabs = g_mainWin->getEditArea()->getAllTabsInfo();
        QVector<VFile *> files;
        files.reserve(tabs.size());
        for (auto const & ta : tabs) {
            files.append(ta.m_editTab->getFile());
        }

        result = m_search.search(files);
        break;
    }

    case VSearchConfig::CurrentFolder:
    {
        VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory();
        if (dir) {
            QString msg(tr("Search current folder %1.").arg(dir->getName()));
            appendLogLine(msg);
            showMessage(msg);
        }

        result = m_search.search(dir);
        break;
    }

    case VSearchConfig::CurrentNotebook:
    {
        QVector<VNotebook *> notebooks;
        notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook());
        if (notebooks[0]) {
            QString msg(tr("Search current notebook %1.").arg(notebooks[0]->getName()));
            appendLogLine(msg);
            showMessage(msg);
        }

        result = m_search.search(notebooks);
        break;
    }

    case VSearchConfig::AllNotebooks:
    {
        const QVector<VNotebook *> &notebooks = g_vnote->getNotebooks();
        result = m_search.search(notebooks);
        break;
    }

    case VSearchConfig::ExplorerDirectory:
    {
        QString rootDirectory = g_mainWin->getExplorer()->getRootDirectory();
        if (!rootDirectory.isEmpty()) {
            QString msg(tr("Search Explorer directory %1.").arg(rootDirectory));
            appendLogLine(msg);
            showMessage(msg);
        }

        result = m_search.search(rootDirectory);
        break;
    }

    default:
        break;
    }

    handleSearchFinished(result);
}
Пример #18
0
void VDirectoryTree::reloadFromDisk()
{
    if (!m_notebook) {
        return;
    }

    QString msg;
    QString info;
    VDirectory *curDir = NULL;
    QTreeWidgetItem *curItem = currentItem();
    if (curItem) {
        // Reload current directory.
        curDir = getVDirectory(curItem);
        info = tr("Are you sure to reload folder <span style=\"%1\">%2</span>?")
                 .arg(g_config->c_dataTextStyle).arg(curDir->getName());
        msg = tr("Folder %1 reloaded from disk").arg(curDir->getName());
    } else {
        // Reload notebook.
        info = tr("Are you sure to reload notebook <span style=\"%1\">%2</span>?")
                 .arg(g_config->c_dataTextStyle).arg(m_notebook->getName());
        msg = tr("Notebook %1 reloaded from disk").arg(m_notebook->getName());
    }

    if (g_config->getConfirmReloadFolder()) {
        int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"),
                                      info,
                                      tr("VNote will close all the related notes before reload."),
                                      QMessageBox::Ok | QMessageBox::YesToAll | QMessageBox::Cancel,
                                      QMessageBox::Ok,
                                      this);
        switch (ret) {
        case QMessageBox::YesToAll:
            g_config->setConfirmReloadFolder(false);
            // Fall through.

        case QMessageBox::Ok:
            break;

        case QMessageBox::Cancel:
            return;

        default:
            return;
        }
    }

    m_notebookCurrentDirMap.remove(m_notebook);

    if (curItem) {
        if (!m_editArea->closeFile(curDir, false)) {
            return;
        }

        setCurrentItem(NULL);

        curItem->setExpanded(false);
        curDir->setExpanded(false);

        curDir->close();

        // Remove all its children.
        QList<QTreeWidgetItem *> children = curItem->takeChildren();
        for (int i = 0; i < children.size(); ++i) {
            delete children[i];
        }

        buildSubTree(curItem, 1);

        setCurrentItem(curItem);
    } else {
        if (!m_editArea->closeFile(m_notebook, false)) {
            return;
        }

        m_notebook->close();

        if (!m_notebook->open()) {
            VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
                                tr("Fail to open notebook <span style=\"%1\">%2</span>.")
                                  .arg(g_config->c_dataTextStyle).arg(m_notebook->getName()),
                                tr("Please check if path <span style=\"%1\">%2</span> exists.")
                                  .arg(g_config->c_dataTextStyle).arg(m_notebook->getPath()),
                                QMessageBox::Ok, QMessageBox::Ok, this);
            clear();
            return;
        }

        updateDirectoryTree();
    }

    if (!msg.isEmpty()) {
        g_mainWin->showStatusMessage(msg);
    }
}