bug-fix: use completeBaseName() when adding sequence to file name

- When adding attachments, if the name conflicts, we add sequence after
the base name. "abc.tar.gz" to "abc_001.tar.gz".
- When handling notes and folders, if the name conflicts, we add
sequence after the complete base name. "abc.5.9.1.md" to
"abc.5.9.1_001.md".
This commit is contained in:
Le Tan 2017-10-09 19:39:29 +08:00
parent cff6a1e49a
commit 893c0b2823
6 changed files with 84 additions and 32 deletions

View File

@ -314,7 +314,7 @@ bool VNewNotebookDialog::autoComplete()
// Get a folder name under vnoteFolder and set it as the name of the notebook. // Get a folder name under vnoteFolder and set it as the name of the notebook.
QString name = "vnotebook"; QString name = "vnotebook";
name = VUtils::getFileNameWithSequence(vnoteFolder, name); name = VUtils::getDirNameWithSequence(vnoteFolder, name);
nameEdit->setText(name); nameEdit->setText(name);
ret = true; ret = true;
} else { } else {

View File

@ -377,31 +377,35 @@ int VUtils::showMessage(QMessageBox::Icon p_icon, const QString &p_title, const
return msgBox.exec(); return msgBox.exec();
} }
QString VUtils::generateCopiedFileName(const QString &p_dirPath, const QString &p_fileName) QString VUtils::generateCopiedFileName(const QString &p_dirPath,
const QString &p_fileName,
bool p_completeBaseName)
{ {
QString suffix; QDir dir(p_dirPath);
QString base = p_fileName; if (!dir.exists() || !dir.exists(p_fileName)) {
int dotIdx = p_fileName.lastIndexOf('.'); return p_fileName;
if (dotIdx != -1) {
// .md
suffix = p_fileName.right(p_fileName.size() - dotIdx);
base = p_fileName.left(dotIdx);
} }
QDir dir(p_dirPath); QFileInfo fi(p_fileName);
QString name = p_fileName; QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName();
QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix();
int index = 0; int index = 0;
while (dir.exists(name)) { QString fileName;
do {
QString seq; QString seq;
if (index > 0) { if (index > 0) {
seq = QString::number(index); seq = QString("%1").arg(QString::number(index), 3, '0');
} }
index++; index++;
name = QString("%1_copy%2%3").arg(base).arg(seq).arg(suffix); fileName = QString("%1_copy%2").arg(baseName).arg(seq);
if (!suffix.isEmpty()) {
fileName = fileName + "." + suffix;
} }
} while (fileExists(dir, fileName, true));
return name; return fileName;
} }
QString VUtils::generateCopiedDirName(const QString &p_parentDirPath, const QString &p_dirName) QString VUtils::generateCopiedDirName(const QString &p_parentDirPath, const QString &p_dirName)
@ -614,7 +618,8 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exp
} }
QString VUtils::getFileNameWithSequence(const QString &p_directory, QString VUtils::getFileNameWithSequence(const QString &p_directory,
const QString &p_baseFileName) const QString &p_baseFileName,
bool p_completeBaseName)
{ {
QDir dir(p_directory); QDir dir(p_directory);
if (!dir.exists() || !dir.exists(p_baseFileName)) { if (!dir.exists() || !dir.exists(p_baseFileName)) {
@ -623,8 +628,8 @@ QString VUtils::getFileNameWithSequence(const QString &p_directory,
// Append a sequence. // Append a sequence.
QFileInfo fi(p_baseFileName); QFileInfo fi(p_baseFileName);
QString baseName = fi.baseName(); QString baseName = p_completeBaseName ? fi.completeBaseName() : fi.baseName();
QString suffix = fi.completeSuffix(); QString suffix = p_completeBaseName ? fi.suffix() : fi.completeSuffix();
int seq = 1; int seq = 1;
QString fileName; QString fileName;
do { do {
@ -637,6 +642,24 @@ QString VUtils::getFileNameWithSequence(const QString &p_directory,
return fileName; return fileName;
} }
QString VUtils::getDirNameWithSequence(const QString &p_directory,
const QString &p_baseDirName)
{
QDir dir(p_directory);
if (!dir.exists() || !dir.exists(p_baseDirName)) {
return p_baseDirName;
}
// Append a sequence.
int seq = 1;
QString fileName;
do {
fileName = QString("%1_%2").arg(p_baseDirName).arg(QString::number(seq++), 3, '0');
} while (fileExists(dir, fileName, true));
return fileName;
}
QString VUtils::getRandomFileName(const QString &p_directory) QString VUtils::getRandomFileName(const QString &p_directory)
{ {
Q_ASSERT(!p_directory.isEmpty()); Q_ASSERT(!p_directory.isEmpty());
@ -850,7 +873,8 @@ bool VUtils::deleteFile(const QString &p_recycleBinFolderPath,
} }
QString destName = getFileNameWithSequence(binPath, QString destName = getFileNameWithSequence(binPath,
fileNameFromPath(p_path)); fileNameFromPath(p_path),
true);
qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName; qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName;
if (!binDir.rename(p_path, binDir.filePath(destName))) { if (!binDir.rename(p_path, binDir.filePath(destName))) {

View File

@ -80,9 +80,19 @@ public:
// Given the file name @p_fileName and directory path @p_dirPath, generate // Given the file name @p_fileName and directory path @p_dirPath, generate
// a file name based on @p_fileName which does not exist in @p_dirPath. // a file name based on @p_fileName which does not exist in @p_dirPath.
static QString generateCopiedFileName(const QString &p_dirPath, const QString &p_fileName); // @p_completeBaseName: use complete base name or complete suffix. For example,
// "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar",
// otherwise, it is "abc".
static QString generateCopiedFileName(const QString &p_dirPath,
const QString &p_fileName,
bool p_completeBaseName = true);
// Given the directory name @p_dirName and directory path @p_parentDirPath,
// generate a directory name based on @p_dirName which does not exist in
// @p_parentDirPath.
static QString generateCopiedDirName(const QString &p_parentDirPath,
const QString &p_dirName);
static QString generateCopiedDirName(const QString &p_parentDirPath, const QString &p_dirName);
static void processStyle(QString &style, const QVector<QPair<QString, QString> > &varMap); static void processStyle(QString &style, const QVector<QPair<QString, QString> > &varMap);
// Return the last directory name of @p_path. // Return the last directory name of @p_path.
@ -148,8 +158,18 @@ public:
// Get an available file name in @p_directory with base @p_baseFileName. // Get an available file name in @p_directory with base @p_baseFileName.
// If there already exists a file named @p_baseFileName, try to add sequence // If there already exists a file named @p_baseFileName, try to add sequence
// suffix to the name, such as _001. // suffix to the name, such as _001.
// @p_completeBaseName: use complete base name or complete suffix. For example,
// "abc.tar.gz", if @p_completeBaseName is true, the base name is "abc.tar",
// otherwise, it is "abc".
static QString getFileNameWithSequence(const QString &p_directory, static QString getFileNameWithSequence(const QString &p_directory,
const QString &p_baseFileName); const QString &p_baseFileName,
bool p_completeBaseName = true);
// Get an available directory name in @p_directory with base @p_baseDirName.
// If there already exists a file named @p_baseFileName, try to add sequence
// suffix to the name, such as _001.
static QString getDirNameWithSequence(const QString &p_directory,
const QString &p_baseDirName);
// Get an available random file name in @p_directory. // Get an available random file name in @p_directory.
static QString getRandomFileName(const QString &p_directory); static QString getRandomFileName(const QString &p_directory);

View File

@ -430,7 +430,7 @@ void VDirectoryTree::newSubDirectory()
.arg(g_config->c_dataTextStyle) .arg(g_config->c_dataTextStyle)
.arg(curDir->getName()); .arg(curDir->getName());
QString defaultName("new_folder"); QString defaultName("new_folder");
defaultName = VUtils::getFileNameWithSequence(curDir->fetchPath(), defaultName); defaultName = VUtils::getDirNameWithSequence(curDir->fetchPath(), defaultName);
VNewDirDialog dialog(tr("Create Folder"), info, defaultName, curDir, this); VNewDirDialog dialog(tr("Create Folder"), info, defaultName, curDir, this);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput(); QString name = dialog.getNameInput();
@ -467,7 +467,7 @@ void VDirectoryTree::newRootDirectory()
.arg(g_config->c_dataTextStyle) .arg(g_config->c_dataTextStyle)
.arg(m_notebook->getName()); .arg(m_notebook->getName());
QString defaultName("new_folder"); QString defaultName("new_folder");
defaultName = VUtils::getFileNameWithSequence(rootDir->fetchPath(), defaultName); defaultName = VUtils::getDirNameWithSequence(rootDir->fetchPath(), defaultName);
VNewDirDialog dialog(tr("Create Root Folder"), info, defaultName, rootDir, this); VNewDirDialog dialog(tr("Create Root Folder"), info, defaultName, rootDir, this);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput(); QString name = dialog.getNameInput();

View File

@ -330,7 +330,9 @@ void VFileList::newFile()
info = info + "<br>" + tr("Note with name ending with \"%1\" will be treated as Markdown type.") info = info + "<br>" + tr("Note with name ending with \"%1\" will be treated as Markdown type.")
.arg(suffixStr); .arg(suffixStr);
QString defaultName = QString("new_note.%1").arg(defaultSuf); QString defaultName = QString("new_note.%1").arg(defaultSuf);
defaultName = VUtils::getFileNameWithSequence(m_directory->fetchPath(), defaultName); defaultName = VUtils::getFileNameWithSequence(m_directory->fetchPath(),
defaultName,
true);
VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this); VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
VNoteFile *file = m_directory->createFile(dialog.getNameInput()); VNoteFile *file = m_directory->createFile(dialog.getNameInput());
@ -349,7 +351,7 @@ void VFileList::newFile()
qWarning() << "fail to open newly-created note" << file->getName(); qWarning() << "fail to open newly-created note" << file->getName();
} else { } else {
Q_ASSERT(file->getContent().isEmpty()); Q_ASSERT(file->getContent().isEmpty());
QString content = QString("# %1\n").arg(QFileInfo(file->getName()).baseName()); QString content = QString("# %1\n").arg(QFileInfo(file->getName()).completeBaseName());
file->setContent(content); file->setContent(content);
if (!file->save()) { if (!file->save()) {
qWarning() << "fail to write to newly-created note" << file->getName(); qWarning() << "fail to write to newly-created note" << file->getName();
@ -621,7 +623,7 @@ bool VFileList::importFiles(const QStringList &p_files, QString *p_errMsg)
QString name = VUtils::fileNameFromPath(file); QString name = VUtils::fileNameFromPath(file);
Q_ASSERT(!name.isEmpty()); Q_ASSERT(!name.isEmpty());
name = VUtils::getFileNameWithSequence(dirPath, name); name = VUtils::getFileNameWithSequence(dirPath, name, true);
QString targetFilePath = dir.filePath(name); QString targetFilePath = dir.filePath(name);
bool ret = VUtils::copyFile(file, targetFilePath, false); bool ret = VUtils::copyFile(file, targetFilePath, false);
if (!ret) { if (!ret) {
@ -763,10 +765,14 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
} }
// Rename it to xxx_copy.md. // Rename it to xxx_copy.md.
fileName = VUtils::generateCopiedFileName(file->fetchBasePath(), fileName); fileName = VUtils::generateCopiedFileName(file->fetchBasePath(),
fileName,
true);
} else { } else {
// Rename it to xxx_copy.md if needed. // Rename it to xxx_copy.md if needed.
fileName = VUtils::generateCopiedFileName(p_destDir->fetchPath(), fileName); fileName = VUtils::generateCopiedFileName(p_destDir->fetchPath(),
fileName,
true);
} }
QString msg; QString msg;

View File

@ -233,7 +233,9 @@ bool VNoteFile::addAttachment(const QString &p_file)
QString folderPath = fetchAttachmentFolderPath(); QString folderPath = fetchAttachmentFolderPath();
QString name = VUtils::fileNameFromPath(p_file); QString name = VUtils::fileNameFromPath(p_file);
Q_ASSERT(!name.isEmpty()); Q_ASSERT(!name.isEmpty());
name = VUtils::getFileNameWithSequence(folderPath, name); // For attachments, we do not use complete base name.
// abc.tar.gz should be abc_001.tar.gz instead of abc.tar_001.gz.
name = VUtils::getFileNameWithSequence(folderPath, name, false);
QString destPath = QDir(folderPath).filePath(name); QString destPath = QDir(folderPath).filePath(name);
if (!VUtils::copyFile(p_file, destPath, false)) { if (!VUtils::copyFile(p_file, destPath, false)) {
return false; return false;
@ -543,7 +545,7 @@ bool VNoteFile::copyFile(VDirectory *p_destDir,
if (!attaFolderPath.isEmpty()) { if (!attaFolderPath.isEmpty()) {
QDir dir(destFile->fetchBasePath()); QDir dir(destFile->fetchBasePath());
QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder()); QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder());
attaFolder = VUtils::getFileNameWithSequence(folderPath, attaFolder); attaFolder = VUtils::getDirNameWithSequence(folderPath, attaFolder);
folderPath = QDir(folderPath).filePath(attaFolder); folderPath = QDir(folderPath).filePath(attaFolder);
// Copy attaFolderPath to folderPath. // Copy attaFolderPath to folderPath.