Browse Source

bug-fix: compare two paths with case convertion on Windows

On Windows, case difference in file name is ignored.
Le Tan 8 years ago
parent
commit
a87048cac2

+ 10 - 9
src/dialog/vdeletenotebookdialog.cpp

@@ -18,12 +18,13 @@ void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_nam
     m_warningLabel = new QLabel();
     m_warningLabel->setWordWrap(true);
 
-    m_notDeleteCheck = new QCheckBox(tr("Do not delete files from disk."), this);
-    m_notDeleteCheck->setChecked(true);
-    m_notDeleteCheck->setToolTip(tr("When checked, VNote just removes the notebook instead of deleting files from disk"));
-    connect(m_notDeleteCheck, &QCheckBox::stateChanged, this, &VDeleteNotebookDialog::notDeleteCheckChanged);
+    m_deleteCheck = new QCheckBox(tr("Delete files from disk"), this);
+    m_deleteCheck->setChecked(false);
+    m_deleteCheck->setToolTip(tr("When checked, VNote will delete all the files within this notebook from disk"));
+    connect(m_deleteCheck, &QCheckBox::stateChanged,
+            this, &VDeleteNotebookDialog::deleteCheckChanged);
 
-    notDeleteCheckChanged(true);
+    deleteCheckChanged(false);
 
     // Ok is the default button.
     m_btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
@@ -49,7 +50,7 @@ void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_nam
 
     QVBoxLayout *infoLayout = new QVBoxLayout();
     infoLayout->addWidget(infoLabel);
-    infoLayout->addWidget(m_notDeleteCheck);
+    infoLayout->addWidget(m_deleteCheck);
     infoLayout->addWidget(m_warningLabel);
 
     QHBoxLayout *topLayout = new QHBoxLayout();
@@ -67,7 +68,7 @@ void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_nam
 
 bool VDeleteNotebookDialog::getDeleteFiles() const
 {
-    return !m_notDeleteCheck->isChecked();
+    return m_deleteCheck->isChecked();
 }
 
 QPixmap VDeleteNotebookDialog::standardIcon(QMessageBox::Icon p_icon)
@@ -104,9 +105,9 @@ QPixmap VDeleteNotebookDialog::standardIcon(QMessageBox::Icon p_icon)
     return QPixmap();
 }
 
-void VDeleteNotebookDialog::notDeleteCheckChanged(int p_state)
+void VDeleteNotebookDialog::deleteCheckChanged(int p_state)
 {
-    if (p_state) {
+    if (!p_state) {
         m_warningLabel->setText(tr("VNote won't delete files in directory <span style=\"%1\">%2</span>.")
                                   .arg(vconfig.c_dataTextStyle).arg(m_path));
     } else {

+ 4 - 2
src/dialog/vdeletenotebookdialog.h

@@ -16,10 +16,12 @@ class VDeleteNotebookDialog : public QDialog
 public:
     VDeleteNotebookDialog(const QString &p_title, const QString &p_name, const QString &p_path,
                           QWidget *p_parent = 0);
+
+    // Whether delete files from disk.
     bool getDeleteFiles() const;
 
 private slots:
-    void notDeleteCheckChanged(int p_state);
+    void deleteCheckChanged(int p_state);
 
 private:
     void setupUI(const QString &p_title, const QString &p_name);
@@ -27,7 +29,7 @@ private:
 
     QString m_path;
     QLabel *m_warningLabel;
-    QCheckBox *m_notDeleteCheck;
+    QCheckBox *m_deleteCheck;
     QDialogButtonBox *m_btnBox;
 };
 

+ 6 - 4
src/dialog/vnewnotebookdialog.cpp

@@ -96,7 +96,9 @@ QString VNewNotebookDialog::getNameInput() const
 
 QString VNewNotebookDialog::getPathInput() const
 {
-    return QDir::cleanPath(pathEdit->text());
+    // absoluteFilePath() to convert the drive to upper case.
+    // cleanPath() to remove duplicate separator, '.', and '..'.
+    return QDir::cleanPath(QFileInfo(pathEdit->text()).absoluteFilePath());
 }
 
 QString VNewNotebookDialog::getImageFolder() const
@@ -205,9 +207,8 @@ void VNewNotebookDialog::handleInputChanged()
     if (pathOk) {
         // Check if this path has been in VNote.
         int idx = -1;
-        path = QDir::cleanPath(path);
         for (idx = 0; idx < m_notebooks.size(); ++idx) {
-            if (QDir::cleanPath(m_notebooks[idx]->getPath()) == path) {
+            if (VUtils::equalPath(m_notebooks[idx]->getPath(), path)) {
                 break;
             }
         }
@@ -261,7 +262,8 @@ bool VNewNotebookDialog::autoComplete()
 
     QString vnoteFolder = vconfig.getVnoteNotebookFolderPath();
     QString pathText = pathEdit->text();
-    if (!pathText.isEmpty() && vnoteFolder != VUtils::basePathFromPath(pathText)) {
+    if (!pathText.isEmpty()
+        && !VUtils::equalPath(vnoteFolder, VUtils::basePathFromPath(pathText))) {
         return false;
     }
 

+ 28 - 0
src/utils/vutils.cpp

@@ -610,6 +610,13 @@ bool VUtils::checkPathLegal(const QString &p_path)
     }
 
     if (QFileInfo::exists(p_path)) {
+#if defined(Q_OS_WIN)
+            // On Windows, "/" and ":" will also make exists() return true.
+            if (p_path.startsWith('/') || p_path == ":") {
+                return false;
+            }
+#endif
+
         return true;
     }
 
@@ -626,6 +633,14 @@ bool VUtils::checkPathLegal(const QString &p_path)
 
         if (QFileInfo::exists(basePath)) {
             ret = true;
+
+#if defined(Q_OS_WIN)
+            // On Windows, "/" and ":" will also make exists() return true.
+            if (basePath.startsWith('/') || basePath == ":") {
+                ret = false;
+            }
+#endif
+
             break;
         }
 
@@ -636,3 +651,16 @@ bool VUtils::checkPathLegal(const QString &p_path)
     delete validator;
     return ret;
 }
+
+bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb)
+{
+    QString a = QDir::cleanPath(p_patha);
+    QString b = QDir::cleanPath(p_pathb);
+
+#if defined(Q_OS_WIN)
+    a = a.toLower();
+    b = b.toLower();
+#endif
+
+    return a == b;
+}

+ 3 - 0
src/utils/vutils.h

@@ -106,6 +106,9 @@ public:
     // Try to check if @p_path is legal.
     static bool checkPathLegal(const QString &p_path);
 
+    // Returns true if @p_patha and @p_pathb points to the same file/directory.
+    static bool equalPath(const QString &p_patha, const QString &p_pathb);
+
     // Regular expression for image link.
     // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
     // Captured texts (need to be trimmed):

+ 3 - 3
src/vdirectory.cpp

@@ -484,7 +484,7 @@ VFile *VDirectory::copyFile(VDirectory *p_destDir, const QString &p_destName,
 {
     QString srcPath = QDir::cleanPath(p_srcFile->retrivePath());
     QString destPath = QDir::cleanPath(QDir(p_destDir->retrivePath()).filePath(p_destName));
-    if (srcPath == destPath) {
+    if (VUtils::equalPath(srcPath, destPath)) {
         return p_srcFile;
     }
 
@@ -554,7 +554,7 @@ VFile *VDirectory::copyFile(VDirectory *p_destDir, const QString &p_destName,
                     destImagePath = QDir(destImagePath).filePath(VUtils::fileNameFromPath(link.m_path));
 
                     // Copy or Cut the images accordingly.
-                    if (destImagePath == link.m_path) {
+                    if (VUtils::equalPath(destImagePath, link.m_path)) {
                         ret = false;
                     } else {
                         ret = VUtils::copyFile(link.m_path, destImagePath, p_cut);
@@ -607,7 +607,7 @@ VDirectory *VDirectory::copyDirectory(VDirectory *p_destDir, const QString &p_de
 {
     QString srcPath = QDir::cleanPath(p_srcDir->retrivePath());
     QString destPath = QDir::cleanPath(QDir(p_destDir->retrivePath()).filePath(p_destName));
-    if (srcPath == destPath) {
+    if (VUtils::equalPath(srcPath, destPath)) {
         return p_srcDir;
     }
 

+ 1 - 1
src/vdirectorytree.cpp

@@ -619,7 +619,7 @@ bool VDirectoryTree::copyDirectory(VDirectory *p_destDir, const QString &p_destN
     QString srcName = p_srcDir->getName();
     QString srcPath = QDir::cleanPath(p_srcDir->retrivePath());
     QString destPath = QDir::cleanPath(QDir(p_destDir->retrivePath()).filePath(p_destName));
-    if (srcPath == destPath) {
+    if (VUtils::equalPath(srcPath, destPath)) {
         return true;
     }
 

+ 2 - 1
src/vfile.cpp

@@ -212,7 +212,8 @@ FileType VFile::getType() const
 
 bool VFile::isInternalImageFolder(const QString &p_path) const
 {
-    return VUtils::basePathFromPath(p_path) == getDirectory()->retrivePath();
+    return VUtils::equalPath(VUtils::basePathFromPath(p_path),
+                             getDirectory()->retrivePath());
 }
 
 QUrl VFile::getBaseUrl() const

+ 1 - 1
src/vfilelist.cpp

@@ -485,7 +485,7 @@ bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile
 {
     QString srcPath = QDir::cleanPath(p_file->retrivePath());
     QString destPath = QDir::cleanPath(QDir(p_destDir->retrivePath()).filePath(p_destName));
-    if (srcPath == destPath) {
+    if (VUtils::equalPath(srcPath, destPath)) {
         return true;
     }
 

+ 2 - 2
src/vmdedit.cpp

@@ -221,7 +221,7 @@ void VMdEdit::clearUnusedImages()
 
             int j;
             for (j = 0; j < images.size(); ++j) {
-                if (link.m_path == images[j].m_path) {
+                if (VUtils::equalPath(link.m_path, images[j].m_path)) {
                     break;
                 }
             }
@@ -246,7 +246,7 @@ void VMdEdit::clearUnusedImages()
 
         int j;
         for (j = 0; j < images.size(); ++j) {
-            if (link.m_path == images[j].m_path) {
+            if (VUtils::equalPath(link.m_path, images[j].m_path)) {
                 break;
             }
         }

+ 2 - 1
src/vorphanfile.cpp

@@ -90,7 +90,8 @@ void VOrphanFile::setContent(const QString & /* p_content */)
 
 bool VOrphanFile::isInternalImageFolder(const QString &p_path) const
 {
-    return VUtils::basePathFromPath(p_path) == VUtils::basePathFromPath(m_path);
+    return VUtils::equalPath(VUtils::basePathFromPath(p_path),
+                             VUtils::basePathFromPath(m_path));
 }
 
 bool VOrphanFile::rename(const QString &p_name)