X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FFileName.cpp;h=91b9a33cc4db809d17927a84737af8b7a5e7373d;hb=c23db901ece8b4e21121e43fc2562ac73e79fc98;hp=59b53f7fa7adc77b4d3bab65e8354a130cf13c89;hpb=fbb3abfeac7b65f823b67e41ab5d6bc0a62f3eef;p=lyx.git diff --git a/src/support/FileName.cpp b/src/support/FileName.cpp index 59b53f7fa7..91b9a33cc4 100644 --- a/src/support/FileName.cpp +++ b/src/support/FileName.cpp @@ -19,17 +19,28 @@ #include "debug.h" #include "lyxlib.h" +#include +#include #include #include +#include -#include -#include +#include #include #include #include #include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#include +#include + using std::map; using std::string; @@ -37,12 +48,26 @@ using std::ifstream; using std::ostringstream; using std::endl; -namespace fs = boost::filesystem; - namespace lyx { namespace support { +///////////////////////////////////////////////////////////////////// +// +// FileName::Private +// +///////////////////////////////////////////////////////////////////// + +struct FileName::Private +{ + Private() {} + + Private(string const & abs_filename) : fi(toqstr(abs_filename)) + {} + /// + QFileInfo fi; +}; + ///////////////////////////////////////////////////////////////////// // // FileName @@ -50,35 +75,70 @@ namespace support { ///////////////////////////////////////////////////////////////////// +FileName::FileName() : d(new Private) +{ +} + FileName::FileName(string const & abs_filename) - : name_(abs_filename) + : d(abs_filename.empty() ? new Private : new Private(abs_filename)) { - BOOST_ASSERT(empty() || absolutePath(name_)); + BOOST_ASSERT(empty() || d->fi.isAbsolute()); #if defined(_WIN32) - BOOST_ASSERT(!contains(name_, '\\')); + BOOST_ASSERT(!contains(abs_filename, '\\')); #endif } +FileName::FileName(FileName const & rhs) : d(new Private) +{ + d->fi = rhs.d->fi; +} + + +FileName & FileName::operator=(FileName const & rhs) +{ + d->fi = rhs.d->fi; + return *this; +} + + +bool FileName::empty() const +{ + return d->fi.absoluteFilePath().isEmpty(); +} + + +string FileName::absFilename() const +{ + return fromqstr(d->fi.absoluteFilePath()); +} + + void FileName::set(string const & name) { - name_ = name; - BOOST_ASSERT(absolutePath(name_)); + d->fi.setFile(toqstr(name)); + BOOST_ASSERT(d->fi.isAbsolute()); #if defined(_WIN32) - BOOST_ASSERT(!contains(name_, '\\')); + BOOST_ASSERT(!contains(name, '\\')); #endif } void FileName::erase() { - name_.erase(); + d->fi = QFileInfo(); +} + + +bool FileName::copyTo(FileName const & name) const +{ + return QFile::copy(d->fi.absoluteFilePath(), name.d->fi.absoluteFilePath()); } string FileName::toFilesystemEncoding() const { - QByteArray const encoded = QFile::encodeName(toqstr(name_)); + QByteArray const encoded = QFile::encodeName(d->fi.absoluteFilePath()); return string(encoded.begin(), encoded.end()); } @@ -92,47 +152,67 @@ FileName FileName::fromFilesystemEncoding(string const & name) bool FileName::exists() const { - return QFileInfo(toqstr(name_)).exists(); + return d->fi.exists(); +} + + +bool FileName::isSymLink() const +{ + return d->fi.isSymLink(); +} + + +bool FileName::isFileEmpty() const +{ + return d->fi.size() == 0; } bool FileName::isDirectory() const { - return QFileInfo(toqstr(name_)).isDir(); + return d->fi.isDir(); } bool FileName::isReadOnly() const { - QFileInfo const fi(toqstr(name_)); - return fi.isReadable() && !fi.isWritable(); + return d->fi.isReadable() && !d->fi.isWritable(); +} + + +bool FileName::isReadableDirectory() const +{ + return d->fi.isDir() && d->fi.isReadable(); +} + + +std::string FileName::onlyFileName() const +{ + return support::onlyFilename(absFilename()); } -bool FileName::isReadable() const +FileName FileName::onlyPath() const { - QFileInfo const fi(toqstr(name_)); - return fi.isReadable(); + return FileName(support::onlyPath(absFilename())); } -bool FileName::isFileReadable() const +bool FileName::isReadableFile() const { - QFileInfo const fi(toqstr(name_)); - return fi.isFile() && fi.isReadable(); + return d->fi.isFile() && d->fi.isReadable(); } bool FileName::isWritable() const { - QFileInfo const fi(toqstr(name_)); - return fi.isWritable(); + return d->fi.isWritable(); } bool FileName::isDirWritable() const { - LYXERR(Debug::FILES) << "isDirWriteable: " << *this << std::endl; + LYXERR(Debug::FILES, "isDirWriteable: " << *this); FileName const tmpfl(tempName(*this, "lyxwritetest")); @@ -152,19 +232,50 @@ FileName FileName::tempName(FileName const & dir, std::string const & mask) std::time_t FileName::lastModified() const { - return fs::last_write_time(toFilesystemEncoding()); + return d->fi.lastModified().toTime_t(); +} + + +static bool rmdir(QFileInfo const & fi) +{ + QDir dir(fi.absoluteFilePath()); + QFileInfoList list = dir.entryInfoList(); + bool global_success = true; + for (int i = 0; i < list.size(); ++i) { + if (list.at(i).fileName() == ".") + continue; + if (list.at(i).fileName() == "..") + continue; + bool success; + if (list.at(i).isDir()) { + LYXERR(Debug::FILES, "Erasing dir " + << fromqstr(list.at(i).absoluteFilePath()) << endl); + success = rmdir(list.at(i)); + } + else { + LYXERR(Debug::FILES, "Erasing file " + << fromqstr(list.at(i).absoluteFilePath()) << endl); + success = dir.remove(list.at(i).fileName()); + } + if (!success) { + global_success = false; + lyxerr << "Could not delete " + << fromqstr(list.at(i).absoluteFilePath()) << "." << endl; + } + } + QDir parent = fi.absolutePath(); + global_success |= parent.rmdir(fi.fileName()); + return global_success; } bool FileName::destroyDirectory() const { - try { - return fs::remove_all(toFilesystemEncoding()) > 0; - } catch (fs::filesystem_error const & fe){ - lyxerr << "Could not delete " << *this << ". (" << fe.what() << ")" - << std::endl; - return false; - } + bool const success = rmdir(d->fi); + if (!success) + lyxerr << "Could not delete " << *this << "." << endl; + + return success; } @@ -175,6 +286,48 @@ bool FileName::createDirectory(int permission) const } +std::vector FileName::dirList(std::string const & ext) +{ + std::vector dirlist; + if (!exists() || !isDirectory()) { + lyxerr << "FileName::dirList(): Directory \"" << absFilename() + << "\" does not exist!" << endl; + return dirlist; + } + + QDir dir(d->fi.absoluteFilePath()); + + if (!ext.empty()) { + QString filter; + switch (ext[0]) { + case '.': filter = "*" + toqstr(ext); break; + case '*': filter = toqstr(ext); break; + default: filter = "*." + toqstr(ext); + } + dir.setNameFilters(QStringList(filter)); + LYXERR(Debug::FILES, "FileName::dirList(): filtering on extension " + << fromqstr(filter) << " is requested." << endl); + } + + QFileInfoList list = dir.entryInfoList(); + for (int i = 0; i < list.size(); ++i) { + FileName fi; + fi.d->fi = list.at(i); + dirlist.push_back(fi); + LYXERR(Debug::FILES, "FileName::dirList(): found file " + << fi.absFilename() << endl); + } + + return dirlist; +} + + +docstring FileName::displayName(int threshold) const +{ + return makeDisplayPath(absFilename(), threshold); +} + + string FileName::fileContents() const { if (exists()) { @@ -222,7 +375,7 @@ string FileName::guessFormatFromContents() const // Z \037\235 UNIX compress // paranoia check - if (empty() || !isReadable()) + if (empty() || !isReadableFile()) return string(); ifstream ifs(toFilesystemEncoding().c_str()); @@ -248,10 +401,8 @@ string FileName::guessFormatFromContents() const bool firstLine = true; while ((count++ < max_count) && format.empty()) { if (ifs.eof()) { - LYXERR(Debug::GRAPHICS) - << "filetools(getFormatFromContents)\n" - << "\tFile type not recognised before EOF!" - << endl; + LYXERR(Debug::GRAPHICS, "filetools(getFormatFromContents)\n" + << "\tFile type not recognised before EOF!"); break; } @@ -359,14 +510,12 @@ string FileName::guessFormatFromContents() const } if (!format.empty()) { - LYXERR(Debug::GRAPHICS) - << "Recognised Fileformat: " << format << endl; + LYXERR(Debug::GRAPHICS, "Recognised Fileformat: " << format); return format; } - LYXERR(Debug::GRAPHICS) - << "filetools(getFormatFromContents)\n" - << "\tCouldn't find a known format!\n"; + LYXERR(Debug::GRAPHICS, "filetools(getFormatFromContents)\n" + << "\tCouldn't find a known format!"); return string(); } @@ -433,14 +582,14 @@ DocFileName::DocFileName(FileName const & abs_filename, bool save_abs) void DocFileName::set(string const & name, string const & buffer_path) { save_abs_path_ = absolutePath(name); - name_ = save_abs_path_ ? name : makeAbsPath(name, buffer_path).absFilename(); + FileName::set(save_abs_path_ ? name : makeAbsPath(name, buffer_path).absFilename()); zipped_valid_ = false; } void DocFileName::erase() { - name_.erase(); + FileName::erase(); zipped_valid_ = false; } @@ -448,14 +597,13 @@ void DocFileName::erase() string const DocFileName::relFilename(string const & path) const { // FIXME UNICODE - return to_utf8(makeRelPath(from_utf8(name_), from_utf8(path))); + return to_utf8(makeRelPath(qstring_to_ucs4(d->fi.absoluteFilePath()), from_utf8(path))); } string const DocFileName::outputFilename(string const & path) const { - // FIXME UNICODE - return save_abs_path_ ? name_ : to_utf8(makeRelPath(from_utf8(name_), from_utf8(path))); + return save_abs_path_ ? absFilename() : relFilename(path); } @@ -465,14 +613,15 @@ string const DocFileName::mangledFilename(std::string const & dir) const // filename returns the same mangled name. typedef map MangledMap; static MangledMap mangledNames; - MangledMap::const_iterator const it = mangledNames.find(name_); + MangledMap::const_iterator const it = mangledNames.find(absFilename()); if (it != mangledNames.end()) return (*it).second; + string const name = absFilename(); // Now the real work - string mname = os::internal_path(name_); + string mname = os::internal_path(name); // Remove the extension. - mname = changeExtension(name_, string()); + mname = changeExtension(name, string()); // The mangled name must be a valid LaTeX name. // The list of characters to keep is probably over-restrictive, // but it is not really a problem. @@ -487,7 +636,7 @@ string const DocFileName::mangledFilename(std::string const & dir) const while ((pos = mname.find_first_not_of(keep, pos)) != string::npos) mname[pos++] = '_'; // Add the extension back on - mname = changeExtension(mname, getExtension(name_)); + mname = changeExtension(mname, getExtension(name)); // Prepend a counter to the filename. This is necessary to make // the mangled name unique. @@ -515,7 +664,7 @@ string const DocFileName::mangledFilename(std::string const & dir) const } } - mangledNames[name_] = mname; + mangledNames[absFilename()] = mname; return mname; } @@ -532,7 +681,7 @@ bool DocFileName::isZipped() const string const DocFileName::unzippedFilename() const { - return unzippedFileName(name_); + return unzippedFileName(absFilename()); }