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.
QString name = "vnotebook";
name = VUtils::getFileNameWithSequence(vnoteFolder, name);
name = VUtils::getDirNameWithSequence(vnoteFolder, name);
nameEdit->setText(name);
ret = true;
} else {

View File

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

View File

@ -430,7 +430,7 @@ void VDirectoryTree::newSubDirectory()
.arg(g_config->c_dataTextStyle)
.arg(curDir->getName());
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);
if (dialog.exec() == QDialog::Accepted) {
QString name = dialog.getNameInput();
@ -467,7 +467,7 @@ void VDirectoryTree::newRootDirectory()
.arg(g_config->c_dataTextStyle)
.arg(m_notebook->getName());
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);
if (dialog.exec() == QDialog::Accepted) {
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.")
.arg(suffixStr);
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);
if (dialog.exec() == QDialog::Accepted) {
VNoteFile *file = m_directory->createFile(dialog.getNameInput());
@ -349,7 +351,7 @@ void VFileList::newFile()
qWarning() << "fail to open newly-created note" << file->getName();
} else {
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);
if (!file->save()) {
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);
Q_ASSERT(!name.isEmpty());
name = VUtils::getFileNameWithSequence(dirPath, name);
name = VUtils::getFileNameWithSequence(dirPath, name, true);
QString targetFilePath = dir.filePath(name);
bool ret = VUtils::copyFile(file, targetFilePath, false);
if (!ret) {
@ -763,10 +765,14 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
}
// Rename it to xxx_copy.md.
fileName = VUtils::generateCopiedFileName(file->fetchBasePath(), fileName);
fileName = VUtils::generateCopiedFileName(file->fetchBasePath(),
fileName,
true);
} else {
// 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;

View File

@ -233,7 +233,9 @@ bool VNoteFile::addAttachment(const QString &p_file)
QString folderPath = fetchAttachmentFolderPath();
QString name = VUtils::fileNameFromPath(p_file);
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);
if (!VUtils::copyFile(p_file, destPath, false)) {
return false;
@ -543,7 +545,7 @@ bool VNoteFile::copyFile(VDirectory *p_destDir,
if (!attaFolderPath.isEmpty()) {
QDir dir(destFile->fetchBasePath());
QString folderPath = dir.filePath(destFile->getNotebook()->getAttachmentFolder());
attaFolder = VUtils::getFileNameWithSequence(folderPath, attaFolder);
attaFolder = VUtils::getDirNameWithSequence(folderPath, attaFolder);
folderPath = QDir(folderPath).filePath(attaFolder);
// Copy attaFolderPath to folderPath.