diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp index 42e03030..d5d23c25 100644 --- a/src/dialog/vsettingsdialog.cpp +++ b/src/dialog/vsettingsdialog.cpp @@ -257,6 +257,10 @@ void VReadEditTab::customWebZoomChanged(int p_state) VNoteManagementTab::VNoteManagementTab(QWidget *p_parent) : QWidget(p_parent) { + m_noteBox = new QGroupBox(tr("Notes")); + m_externalBox = new QGroupBox(tr("External Files")); + + // Note. // Image folder. m_customImageFolder = new QCheckBox(tr("Custom image folder"), this); m_customImageFolder->setToolTip(tr("Set the global name of the image folder to store images " @@ -273,8 +277,35 @@ VNoteManagementTab::VNoteManagementTab(QWidget *p_parent) imageFolderLayout->addWidget(m_customImageFolder); imageFolderLayout->addWidget(m_imageFolderEdit); - QFormLayout *mainLayout = new QFormLayout(); - mainLayout->addRow(imageFolderLayout); + QFormLayout *noteLayout = new QFormLayout(); + noteLayout->addRow(imageFolderLayout); + m_noteBox->setLayout(noteLayout); + + // External File. + // Image folder. + m_customImageFolderExt = new QCheckBox(tr("Custom image folder"), this); + m_customImageFolderExt->setToolTip(tr("Set the global name of the image folder to store images " + "of external files (restart VNote to make it work).\nYou " + "could use both absolute or relative path here. If you " + "use an absolute path, VNote will not manage\nthose images, " + "so you need to clean up unused images manually.")); + connect(m_customImageFolderExt, &QCheckBox::stateChanged, + this, &VNoteManagementTab::customImageFolderExtChanged); + + m_imageFolderEditExt = new QLineEdit(this); + m_imageFolderEditExt->setPlaceholderText(tr("Name of the image folder")); + + QHBoxLayout *imageFolderExtLayout = new QHBoxLayout(); + imageFolderExtLayout->addWidget(m_customImageFolderExt); + imageFolderExtLayout->addWidget(m_imageFolderEditExt); + + QFormLayout *externalLayout = new QFormLayout(); + externalLayout->addRow(imageFolderExtLayout); + m_externalBox->setLayout(externalLayout); + + QVBoxLayout *mainLayout = new QVBoxLayout(); + mainLayout->addWidget(m_noteBox); + mainLayout->addWidget(m_externalBox); setLayout(mainLayout); } @@ -285,6 +316,10 @@ bool VNoteManagementTab::loadConfiguration() return false; } + if (!loadImageFolderExt()) { + return false; + } + return true; } @@ -294,6 +329,10 @@ bool VNoteManagementTab::saveConfiguration() return false; } + if (!saveImageFolderExt()) { + return false; + } + return true; } @@ -329,3 +368,36 @@ void VNoteManagementTab::customImageFolderChanged(int p_state) m_imageFolderEdit->setEnabled(false); } } + +bool VNoteManagementTab::loadImageFolderExt() +{ + bool isCustom = vconfig.isCustomImageFolderExt(); + + m_customImageFolderExt->setChecked(isCustom); + m_imageFolderEditExt->setText(vconfig.getImageFolderExt()); + m_imageFolderEditExt->setEnabled(isCustom); + + return true; +} + +bool VNoteManagementTab::saveImageFolderExt() +{ + if (m_customImageFolderExt->isChecked()) { + vconfig.setImageFolderExt(m_imageFolderEditExt->text()); + } else { + vconfig.setImageFolderExt(""); + } + + return true; +} + +void VNoteManagementTab::customImageFolderExtChanged(int p_state) +{ + if (p_state == Qt::Checked) { + m_imageFolderEditExt->setEnabled(true); + m_imageFolderEditExt->selectAll(); + m_imageFolderEditExt->setFocus(); + } else { + m_imageFolderEditExt->setEnabled(false); + } +} diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h index db2d0fa1..9b195738 100644 --- a/src/dialog/vsettingsdialog.h +++ b/src/dialog/vsettingsdialog.h @@ -62,16 +62,27 @@ public: bool loadConfiguration(); bool saveConfiguration(); + QGroupBox *m_noteBox; + QGroupBox *m_externalBox; + // Image folder. QCheckBox *m_customImageFolder; QLineEdit *m_imageFolderEdit; + // Image folder of External File. + QCheckBox *m_customImageFolderExt; + QLineEdit *m_imageFolderEditExt; + private slots: void customImageFolderChanged(int p_state); + void customImageFolderExtChanged(int p_state); private: bool loadImageFolder(); bool saveImageFolder(); + + bool loadImageFolderExt(); + bool saveImageFolderExt(); }; class VSettingsDialog : public QDialog diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 22583600..a8a95226 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -44,6 +44,9 @@ enable_image_caption=false ; Image folder name for the notes image_folder=_v_images +; Image folder name for the external files +external_image_folder=_v_images + ; Enable trailing space highlight enable_trailing_space_highlight=true diff --git a/src/resources/vnote.qss b/src/resources/vnote.qss index 1a26ad5e..98f0c942 100644 --- a/src/resources/vnote.qss +++ b/src/resources/vnote.qss @@ -228,6 +228,42 @@ QLabel[TitleLabel="true"] { background-color: @base-color; } +QLabel[ColorRedLabel="true"] { + padding-left: 3px; + padding-right: 3px; + font: bold; + color: white; + border-radius: 2px; + background-color: @Red7; +} + +QLabel[ColorGreenLabel="true"] { + padding-left: 3px; + padding-right: 3px; + font: bold; + color: white; + border-radius: 2px; + background-color: @Green7; +} + +QLabel[ColorGreyLabel="true"] { + padding-left: 3px; + padding-right: 3px; + font: bold; + color: white; + border-radius: 2px; + background-color: @Grey7; +} + +QLabel[ColorTealLabel="true"] { + padding-left: 3px; + padding-right: 3px; + font: bold; + color: white; + border-radius: 2px; + background-color: @Teal7; +} + QWidget[NotebookPanel="true"] { padding-left: 3px; } diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 33da731a..e4f9d508 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -142,6 +142,9 @@ void VConfigManager::initialize() m_imageFolder = getConfigFromSettings("global", "image_folder").toString(); + m_imageFolderExt = getConfigFromSettings("global", + "external_image_folder").toString(); + m_enableTrailingSpaceHighlight = getConfigFromSettings("global", "enable_trailing_space_highlight").toBool(); diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 9bc825b7..aceed6e3 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -194,6 +194,11 @@ public: void setImageFolder(const QString &p_folder); bool isCustomImageFolder() const; + const QString &getImageFolderExt() const; + // Empty string to reset the default folder. + void setImageFolderExt(const QString &p_folder); + bool isCustomImageFolderExt() const; + bool getEnableTrailingSpaceHighlight() const; void setEnableTrailingSapceHighlight(bool p_enabled); @@ -398,6 +403,10 @@ private: // Each notebook can specify its custom folder. QString m_imageFolder; + // Global default folder name to store images of all external files. + // Each file can specify its custom folder. + QString m_imageFolderExt; + // Enable trailing-space highlight. bool m_enableTrailingSpaceHighlight; @@ -992,6 +1001,32 @@ inline bool VConfigManager::isCustomImageFolder() const return m_imageFolder != getDefaultConfig("global", "image_folder").toString(); } +inline const QString &VConfigManager::getImageFolderExt() const +{ + return m_imageFolderExt; +} + +inline void VConfigManager::setImageFolderExt(const QString &p_folder) +{ + if (p_folder.isEmpty()) { + // Reset the default folder. + m_imageFolderExt = resetDefaultConfig("global", "external_image_folder").toString(); + return; + } + + if (m_imageFolderExt == p_folder) { + return; + } + + m_imageFolderExt = p_folder; + setConfigToSettings("global", "external_image_folder", m_imageFolderExt); +} + +inline bool VConfigManager::isCustomImageFolderExt() const +{ + return m_imageFolderExt != getDefaultConfig("global", "external_image_folder").toString(); +} + inline bool VConfigManager::getEnableTrailingSpaceHighlight() const { return m_enableTrailingSpaceHighlight; diff --git a/src/vfile.cpp b/src/vfile.cpp index e9dd3a5b..56c695c5 100644 --- a/src/vfile.cpp +++ b/src/vfile.cpp @@ -275,3 +275,13 @@ bool VFile::rename(const QString &p_name) return true; } + +bool VFile::isRelativeImageFolder() const +{ + return true; +} + +QString VFile::getImageFolderInLink() const +{ + return getNotebook()->getImageFolder(); +} diff --git a/src/vfile.h b/src/vfile.h index dc63f8b5..38d54681 100644 --- a/src/vfile.h +++ b/src/vfile.h @@ -35,7 +35,10 @@ public: virtual QString retrivePath() const; virtual QString retriveRelativePath() const; virtual QString retriveBasePath() const; + + // The path of the image folder. virtual QString retriveImagePath() const; + bool isModified() const; bool isModifiable() const; bool isOpened() const; @@ -52,6 +55,12 @@ public: // Rename the file. virtual bool rename(const QString &p_name); + // Whether the image folder is a relative path. + virtual bool isRelativeImageFolder() const; + + // Return the image folder part in an image link. + virtual QString getImageFolderInLink() const; + public slots: void setModified(bool p_modified); diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 54bbc696..cf09d1ed 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -23,6 +23,7 @@ #include "vvimindicator.h" #include "vtabindicator.h" #include "dialog/vupdater.h" +#include "vorphanfile.h" extern VConfigManager vconfig; @@ -616,10 +617,32 @@ void VMainWindow::initFileMenu() QMenu *fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->setToolTipsVisible(true); + // Open external files. + QAction *openAct = new QAction(tr("&Open"), this); + openAct->setToolTip(tr("Open external file to edit")); + connect(openAct, &QAction::triggered, + this, [this](){ + static QString lastPath = QDir::homePath(); + QStringList files = QFileDialog::getOpenFileNames(this, + tr("Select External Files To Open"), + lastPath); + + if (files.isEmpty()) { + return; + } + + // Update lastPath + lastPath = QFileInfo(files[0]).path(); + + openExternalFiles(files); + }); + + fileMenu->addAction(openAct); + // Import notes from files. m_importNoteAct = newAction(QIcon(":/resources/icons/import_note.svg"), tr("&Import Notes From Files"), this); - m_importNoteAct->setToolTip(tr("Import notes from external files into current folder")); + m_importNoteAct->setToolTip(tr("Import notes from external files into current folder by copy")); connect(m_importNoteAct, &QAction::triggered, this, &VMainWindow::importNoteFromFile); m_importNoteAct->setEnabled(false); @@ -952,6 +975,7 @@ void VMainWindow::importNoteFromFile() if (files.isEmpty()) { return; } + // Update lastPath lastPath = QFileInfo(files[0]).path(); @@ -1695,7 +1719,9 @@ void VMainWindow::shortcutHelp() if (locale == "zh_CN") { docName = VNote::c_shortcutsDocFile_zh; } - VFile *file = vnote->getOrphanFile(docName); + + VFile *file = vnote->getOrphanFile(docName, false); + (dynamic_cast(file))->setNotebookName(tr("[Help]")); editArea->openFile(file, OpenFileMode::Read); } @@ -1780,3 +1806,12 @@ void VMainWindow::handleVimStatusUpdated(const VVim *p_vim) m_vimIndicator->show(); } } + +void VMainWindow::openExternalFiles(const QStringList &p_files) +{ + qDebug() << "open external files" << p_files; + for (int i = 0; i < p_files.size(); ++i) { + VFile *file = vnote->getOrphanFile(p_files[i], true); + editArea->openFile(file, OpenFileMode::Read); + } +} diff --git a/src/vmainwindow.h b/src/vmainwindow.h index f3624dd2..2e6f48c4 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -149,6 +149,9 @@ private: const QString &p_text, QObject *p_parent = nullptr); + // Open external files @p_files as orphan files. + void openExternalFiles(const QStringList &p_files); + VNote *vnote; QPointer m_curFile; QPointer m_curTab; diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index cdadac35..4e5dee55 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -197,7 +197,11 @@ void VMdEdit::imageInserted(const QString &p_path) { ImageLink link; link.m_path = p_path; - link.m_type = ImageLink::LocalRelativeInternal; + if (m_file->isRelativeImageFolder()) { + link.m_type = ImageLink::LocalRelativeInternal; + } else { + link.m_type = ImageLink::LocalAbsolute; + } m_insertedImages.append(link); } @@ -217,7 +221,9 @@ void VMdEdit::clearUnusedImages() for (int i = 0; i < m_insertedImages.size(); ++i) { const ImageLink &link = m_insertedImages[i]; - V_ASSERT(link.m_type == ImageLink::LocalRelativeInternal); + if (link.m_type != ImageLink::LocalRelativeInternal) { + continue; + } int j; for (j = 0; j < images.size(); ++j) { diff --git a/src/vmdeditoperations.cpp b/src/vmdeditoperations.cpp index 13c9c2f8..9606333a 100644 --- a/src/vmdeditoperations.cpp +++ b/src/vmdeditoperations.cpp @@ -44,13 +44,16 @@ bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source) dialog.setBrowseable(false); dialog.setImage(image); if (dialog.exec() == QDialog::Accepted) { - insertImageFromQImage(dialog.getImageTitleInput(), m_file->retriveImagePath(), image); + insertImageFromQImage(dialog.getImageTitleInput(), + m_file->retriveImagePath(), + m_file->getImageFolderInLink(), + image); } return true; } void VMdEditOperations::insertImageFromQImage(const QString &title, const QString &path, - const QImage &image) + const QString &folderInLink, const QImage &image) { QString fileName = VUtils::generateImageFileName(path, title); QString filePath = QDir(path).filePath(fileName); @@ -79,7 +82,7 @@ void VMdEditOperations::insertImageFromQImage(const QString &title, const QStrin return; } - QString md = QString("![%1](%2/%3)").arg(title).arg(VUtils::directoryNameFromPath(path)).arg(fileName); + QString md = QString("![%1](%2/%3)").arg(title).arg(folderInLink).arg(fileName); insertTextAtCurPos(md); qDebug() << "insert image" << title << filePath; @@ -89,8 +92,8 @@ void VMdEditOperations::insertImageFromQImage(const QString &title, const QStrin mdEditor->imageInserted(filePath); } -void VMdEditOperations::insertImageFromPath(const QString &title, - const QString &path, const QString &oriImagePath) +void VMdEditOperations::insertImageFromPath(const QString &title, const QString &path, + const QString &folderInLink, const QString &oriImagePath) { QString fileName = VUtils::generateImageFileName(path, title, QFileInfo(oriImagePath).suffix()); QString filePath = QDir(path).filePath(fileName); @@ -119,7 +122,7 @@ void VMdEditOperations::insertImageFromPath(const QString &title, return; } - QString md = QString("![%1](%2/%3)").arg(title).arg(VUtils::directoryNameFromPath(path)).arg(fileName); + QString md = QString("![%1](%2/%3)").arg(title).arg(folderInLink).arg(fileName); insertTextAtCurPos(md); qDebug() << "insert image" << title << filePath; @@ -168,10 +171,12 @@ bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl) if (isLocal) { insertImageFromPath(dialog.getImageTitleInput(), m_file->retriveImagePath(), + m_file->getImageFolderInLink(), imagePath); } else { insertImageFromQImage(dialog.getImageTitleInput(), m_file->retriveImagePath(), + m_file->getImageFolderInLink(), dialog.getImage()); } } @@ -186,7 +191,10 @@ bool VMdEditOperations::insertImage() QString title = dialog.getImageTitleInput(); QString imagePath = dialog.getPathInput(); qDebug() << "insert image from" << imagePath << "as" << title; - insertImageFromPath(title, m_file->retriveImagePath(), imagePath); + insertImageFromPath(title, + m_file->retriveImagePath(), + m_file->getImageFolderInLink(), + imagePath); } return true; } diff --git a/src/vmdeditoperations.h b/src/vmdeditoperations.h index c2aaa8bc..faeb791f 100644 --- a/src/vmdeditoperations.h +++ b/src/vmdeditoperations.h @@ -26,12 +26,17 @@ public: void decorateText(TextDecoration p_decoration) Q_DECL_OVERRIDE; private: - void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath); + // Insert image from @oriImagePath as @path. + // @folderInLink: the folder part in the image link. + void insertImageFromPath(const QString &title, const QString &path, + const QString &folderInLink, const QString &oriImagePath); // @title: title of the inserted image; // @path: the image folder path to insert the image in; + // @folderInLink: the folder part in the image link. // @image: the image to be inserted; - void insertImageFromQImage(const QString &title, const QString &path, const QImage &image); + void insertImageFromQImage(const QString &title, const QString &path, + const QString &folderInLink, const QImage &image); // Key press handlers. bool handleKeyTab(QKeyEvent *p_event); diff --git a/src/vnote.cpp b/src/vnote.cpp index c4675785..3ce7a915 100644 --- a/src/vnote.cpp +++ b/src/vnote.cpp @@ -77,6 +77,10 @@ void VNote::initPalette(QPalette palette) m_palette.append(QPair("Teal3", "#4DB6AC")); m_palette.append(QPair("Teal4", "#26A69A")); m_palette.append(QPair("Teal5", "#009688")); + m_palette.append(QPair("Teal6", "#00897B")); + m_palette.append(QPair("Teal7", "#00796B")); + m_palette.append(QPair("Teal8", "#00695C")); + m_palette.append(QPair("Teal9", "#004D40")); m_palette.append(QPair("Indigo0", "#E8EAF6")); m_palette.append(QPair("Indigo1", "#C5CAE9")); @@ -272,7 +276,7 @@ const QString &VNote::getMonospacedFont() const return font; } -VFile *VNote::getOrphanFile(const QString &p_path) +VFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable) { if (p_path.isEmpty()) { return NULL; @@ -280,16 +284,25 @@ VFile *VNote::getOrphanFile(const QString &p_path) // See if the file has already been opened before. for (auto const &file : m_externalFiles) { - if (file->getType() == FileType::Orphan && file->retrivePath() == p_path) { - qDebug() << "find a VFile for path" << p_path; + Q_ASSERT(file->getType() == FileType::Orphan); + if (file->retrivePath() == p_path + && file->isModifiable() == p_modifiable) { return file; } } - // TODO: Clean up unopened file here. + for (int i = 0; i < m_externalFiles.size(); ++i) { + VFile *file = m_externalFiles[i]; + if (!file->isOpened()) { + qDebug() << "release orphan file" << file; + m_externalFiles.removeAt(i); + delete file; + --i; + } + } // Create a VOrphanFile for p_path. - VOrphanFile *file = new VOrphanFile(p_path, this); + VOrphanFile *file = new VOrphanFile(p_path, this, p_modifiable); m_externalFiles.append(file); return file; } diff --git a/src/vnote.h b/src/vnote.h index 9536972e..013f270f 100644 --- a/src/vnote.h +++ b/src/vnote.h @@ -75,7 +75,7 @@ public: QString getNavigationLabelStyle(const QString &p_str) const; // Given the path of an external file, create a VFile struct. - VFile *getOrphanFile(const QString &p_path); + VFile *getOrphanFile(const QString &p_path, bool p_modifiable); public slots: void updateTemplate(); diff --git a/src/vopenedlistmenu.cpp b/src/vopenedlistmenu.cpp index a81ee6ac..0f91860e 100644 --- a/src/vopenedlistmenu.cpp +++ b/src/vopenedlistmenu.cpp @@ -80,16 +80,22 @@ void VOpenedListMenu::updateOpenedList() // Whether add separator. QString curNotebook = file->getNotebookName(); - if (curNotebook != notebook || file->getDirectory() != directory) { + if (curNotebook != notebook + || file->getDirectory() != directory) { notebook = curNotebook; directory = file->getDirectory(); QString dirName; - if (!directory) { - dirName = file->retriveBasePath(); - } else { + if (directory) { dirName = directory->getName(); } - QString text = QString("[%1] %2").arg(notebook).arg(dirName); + + QString text; + if (dirName.isEmpty()) { + text = QString("[%1]").arg(notebook); + } else { + text = QString("[%1] %2").arg(notebook).arg(dirName); + } + QAction *sepAct = addSection(text); sepAct->setFont(sepFont); } diff --git a/src/vorphanfile.cpp b/src/vorphanfile.cpp index 5066031d..accbd469 100644 --- a/src/vorphanfile.cpp +++ b/src/vorphanfile.cpp @@ -4,12 +4,15 @@ #include #include #include "utils/vutils.h" +#include "vconfigmanager.h" -VOrphanFile::VOrphanFile(const QString &p_path, QObject *p_parent) - : VFile(VUtils::fileNameFromPath(p_path), p_parent, FileType::Orphan, false), - m_path(p_path) +extern VConfigManager vconfig; + +VOrphanFile::VOrphanFile(const QString &p_path, QObject *p_parent, bool p_modifiable) + : VFile(VUtils::fileNameFromPath(p_path), p_parent, FileType::Orphan, p_modifiable), + m_path(p_path), m_notebookName("[EXTERNAL]") { - qDebug() << "VOrphanFile" << p_path << m_name; + qDebug() << "VOrphanFile" << p_path << m_name << p_modifiable; } bool VOrphanFile::open() @@ -18,8 +21,10 @@ bool VOrphanFile::open() if (m_opened) { return true; } + Q_ASSERT(m_content.isEmpty()); Q_ASSERT(QFileInfo::exists(m_path)); + m_content = VUtils::readFileFromDisk(m_path); m_modified = false; m_opened = true; @@ -43,14 +48,24 @@ QString VOrphanFile::retriveBasePath() const QString VOrphanFile::retriveImagePath() const { - V_ASSERT(false); - return ""; + QString folder = m_imageFolder; + if (m_imageFolder.isEmpty()) { + folder = vconfig.getImageFolderExt(); + } + + QFileInfo fi(folder); + if (fi.isAbsolute()) { + return folder; + } else { + return QDir(retriveBasePath()).filePath(folder); + } } bool VOrphanFile::save() { - V_ASSERT(false); - return false; + Q_ASSERT(m_opened); + Q_ASSERT(m_modifiable); + return VUtils::writeFileToDisk(retrivePath(), m_content); } void VOrphanFile::convert(DocType /* p_curType */, DocType /* p_targetType */) @@ -75,7 +90,12 @@ const VDirectory *VOrphanFile::getDirectory() const QString VOrphanFile::getNotebookName() const { - return "[EMPTY]"; + return m_notebookName; +} + +void VOrphanFile::setNotebookName(const QString &p_notebook) +{ + m_notebookName = p_notebook; } VNotebook *VOrphanFile::getNotebook() @@ -83,15 +103,16 @@ VNotebook *VOrphanFile::getNotebook() return NULL; } -void VOrphanFile::setContent(const QString & /* p_content */) +void VOrphanFile::setContent(const QString & p_content) { - V_ASSERT(false); + m_content = p_content; } bool VOrphanFile::isInternalImageFolder(const QString &p_path) const { return VUtils::equalPath(VUtils::basePathFromPath(p_path), - VUtils::basePathFromPath(m_path)); + retriveBasePath()) + || VUtils::equalPath(p_path, retriveImagePath()); } bool VOrphanFile::rename(const QString &p_name) @@ -106,3 +127,28 @@ bool VOrphanFile::rename(const QString &p_name) m_path = dir.filePath(m_name); return true; } + +void VOrphanFile::setImageFolder(const QString &p_path) +{ + m_imageFolder = p_path; +} + +bool VOrphanFile::isRelativeImageFolder() const +{ + QString folder = m_imageFolder; + if (m_imageFolder.isEmpty()) { + folder = vconfig.getImageFolderExt(); + } + + return !QFileInfo(folder).isAbsolute(); +} + +QString VOrphanFile::getImageFolderInLink() const +{ + QString folder = m_imageFolder; + if (m_imageFolder.isEmpty()) { + folder = vconfig.getImageFolderExt(); + } + + return folder; +} diff --git a/src/vorphanfile.h b/src/vorphanfile.h index 900cd271..f5c832f9 100644 --- a/src/vorphanfile.h +++ b/src/vorphanfile.h @@ -4,12 +4,12 @@ #include "vfile.h" // VOrphanFile is file not belong to any notebooks or directories. -// Given the path of the file, VNote could load its content as read-only. class VOrphanFile : public VFile { Q_OBJECT public: - VOrphanFile(const QString &p_path, QObject *p_parent); + VOrphanFile(const QString &p_path, QObject *p_parent, bool p_modifiable); + bool open() Q_DECL_OVERRIDE; QString retrivePath() const Q_DECL_OVERRIDE; QString retriveRelativePath() const Q_DECL_OVERRIDE; @@ -17,11 +17,22 @@ public: VDirectory *getDirectory() Q_DECL_OVERRIDE; const VDirectory *getDirectory() const Q_DECL_OVERRIDE; QString getNotebookName() const Q_DECL_OVERRIDE; + + void setNotebookName(const QString &p_notebook); + VNotebook *getNotebook() Q_DECL_OVERRIDE; // Rename file. bool rename(const QString &p_name) Q_DECL_OVERRIDE; + void setImageFolder(const QString &p_path); + + // Whether the image folder is a relative path. + bool isRelativeImageFolder() const Q_DECL_OVERRIDE; + + // Return the image folder part in an image link. + QString getImageFolderInLink() const Q_DECL_OVERRIDE; + private: bool save() Q_DECL_OVERRIDE; void convert(DocType p_curType, DocType p_targetType) Q_DECL_OVERRIDE; @@ -31,6 +42,14 @@ private: bool isInternalImageFolder(const QString &p_path) const Q_DECL_OVERRIDE; QString m_path; + + QString m_notebookName; + + // Image folder path of this file. + // It could be an absolute or relative path. + // Empty to use the global default config. + QString m_imageFolder; + friend class VDirectory; }; diff --git a/src/vtabindicator.cpp b/src/vtabindicator.cpp index 2f42a1a0..a724b21b 100644 --- a/src/vtabindicator.cpp +++ b/src/vtabindicator.cpp @@ -14,12 +14,22 @@ VTabIndicator::VTabIndicator(QWidget *p_parent) void VTabIndicator::setupUI() { m_docTypeLabel = new QLabel(this); - m_readonlyLabel = new QLabel(tr("ReadOnly"), - this); + m_docTypeLabel->setToolTip(tr("The type of the file")); + m_docTypeLabel->setProperty("ColorGreyLabel", true); + + m_readonlyLabel = new QLabel(tr("ReadOnly"), this); + m_readonlyLabel->setToolTip(tr("This file is read-only")); + m_readonlyLabel->setProperty("ColorRedLabel", true); + + m_externalLabel = new QLabel(tr("Standalone"), this); + m_externalLabel->setToolTip(tr("This file is not managed by any notebook or folder")); + m_externalLabel->setProperty("ColorTealLabel", true); + m_cursorLabel = new QLabel(this); QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->addWidget(m_cursorLabel); + mainLayout->addWidget(m_externalLabel); mainLayout->addWidget(m_readonlyLabel); mainLayout->addWidget(m_docTypeLabel); mainLayout->setContentsMargins(0, 0, 0, 0); @@ -61,7 +71,8 @@ void VTabIndicator::update(const VEditTabInfo &p_info) const VEditTab *editTab = NULL; const VFile *file = NULL; DocType docType = DocType::Html; - bool readonly = true; + bool readonly = false; + bool external = false; QString cursorStr; if (p_info.m_editTab) @@ -70,6 +81,7 @@ void VTabIndicator::update(const VEditTabInfo &p_info) file = editTab->getFile(); docType = file->getDocType(); readonly = !file->isModifiable(); + external = file->getType() == FileType::Orphan; if (editTab->isEditMode()) { int line = p_info.m_cursorBlockNumber + 1; @@ -94,4 +106,5 @@ void VTabIndicator::update(const VEditTabInfo &p_info) m_docTypeLabel->setText(docTypeToString(docType)); m_readonlyLabel->setVisible(readonly); + m_externalLabel->setVisible(external); } diff --git a/src/vtabindicator.h b/src/vtabindicator.h index 8c8f1e7f..b5fb8e26 100644 --- a/src/vtabindicator.h +++ b/src/vtabindicator.h @@ -25,6 +25,9 @@ private: // Indicate the readonly property. QLabel *m_readonlyLabel; + // Indicate whether it is a normal note or an external file. + QLabel *m_externalLabel; + // Indicate the position of current cursor. QLabel *m_cursorLabel; };