On Thu, Apr 30, 2009 at 12:42:27AM +0200, for...@lyx.org wrote: > Author: forenr > Date: Thu Apr 30 00:42:26 2009 > New Revision: 29444 > URL: http://www.lyx.org/trac/changeset/29444 > > Log: > Speed up FileName operator==, such that working with child documents on > Windows and Solaris is again possible.
Jürgen, OK for branch? Without this patch it is a pain working with child documents. In some cases, when I have finished quickly typing 5 or 6 characters, only the first two have been shown on screen. With this patch I am not able to type ahead, neither on Windows nor on Solaris. > Modified: > lyx-devel/trunk/src/support/FileName.cpp > lyx-devel/trunk/src/support/os.h > lyx-devel/trunk/src/support/os_cygwin.cpp > lyx-devel/trunk/src/support/os_unix.cpp > lyx-devel/trunk/src/support/os_win32.cpp > > Modified: lyx-devel/trunk/src/support/FileName.cpp > ============================================================================== > --- lyx-devel/trunk/src/support/FileName.cpp Wed Apr 29 22:34:41 2009 > (r29443) > +++ lyx-devel/trunk/src/support/FileName.cpp Thu Apr 30 00:42:26 2009 > (r29444) > @@ -921,49 +921,18 @@ > } > > > -// Note: According to Qt, QFileInfo::operator== is undefined when > -// both files do not exist (Qt4.5 gives true for all non-existent > -// files, while Qt4.4 compares the filenames). > -// see: > -// http://www.qtsoftware.com/developer/task-tracker/ > -// index_html?id=248471&method=entry. > -bool operator==(FileName const & l, FileName const & r) > -{ > - // FIXME: In future use Qt. > - // Qt 4.4: We need to solve this warning from Qt documentation: > - // * Long and short file names that refer to the same file on Windows > are > - // treated as if they referred to different files. > - // This is supposed to be fixed for Qt5. > - FileName const lhs(os::internal_path(l.absFilename())); > - FileName const rhs(os::internal_path(r.absFilename())); > - > - if (lhs.empty()) > - // QFileInfo::operator==() returns false if the two QFileInfo > are empty. > - return rhs.empty(); > - > - if (rhs.empty()) > - // Avoid unnecessary checks below. > - return false; > - > - lhs.d->refresh(); > - rhs.d->refresh(); > - > - if (!lhs.d->fi.isSymLink() && !rhs.d->fi.isSymLink()) { > - // Qt already checks if the filesystem is case sensitive or not. > - // see note above why the extra check with fileName is needed. > - return lhs.d->fi == rhs.d->fi > - && lhs.d->fi.fileName() == rhs.d->fi.fileName(); > +bool operator==(FileName const & lhs, FileName const & rhs) > +{ > + // Firstly, compare the filenames. > + if (QString::compare(toqstr(lhs.absFilename()), > + toqstr(rhs.absFilename()), > + os::isFilesystemCaseSensitive() ? > + Qt::CaseSensitive : Qt::CaseInsensitive) == 0) { > + return true; > } > > - // FIXME: When/if QFileInfo support symlink comparison, remove this > code. > - QFileInfo fi1(lhs.d->fi); > - if (fi1.isSymLink()) > - fi1 = QFileInfo(fi1.symLinkTarget()); > - QFileInfo fi2(rhs.d->fi); > - if (fi2.isSymLink()) > - fi2 = QFileInfo(fi2.symLinkTarget()); > - // see note above why the extra check with fileName is needed. > - return fi1 == fi2 && fi1.fileName() == fi2.fileName(); > + // They don't match, so check whether they point to the same file. > + return os::isSameFile(lhs.toFilesystemEncoding(), > rhs.toFilesystemEncoding()); > } > > > > Modified: lyx-devel/trunk/src/support/os.h > ============================================================================== > --- lyx-devel/trunk/src/support/os.h Wed Apr 29 22:34:41 2009 (r29443) > +++ lyx-devel/trunk/src/support/os.h Thu Apr 30 00:42:26 2009 (r29444) > @@ -112,6 +112,9 @@ > */ > bool autoOpenFile(std::string const & filename, auto_open_mode const mode = > VIEW); > > +/// Check whether two filenames point to the same file. > +bool isSameFile(std::string const & fileone, std::string const & filetwo); > + > } // namespace os > } // namespace support > } // namespace lyx > > Modified: lyx-devel/trunk/src/support/os_cygwin.cpp > ============================================================================== > --- lyx-devel/trunk/src/support/os_cygwin.cpp Wed Apr 29 22:34:41 2009 > (r29443) > +++ lyx-devel/trunk/src/support/os_cygwin.cpp Thu Apr 30 00:42:26 2009 > (r29444) > @@ -6,6 +6,7 @@ > * \author Ruurd A. Reitsma > * \author Claus Hentschel > * \author Angus Leeming > + * \author Enrico Forestieri > * > * Full author contact details are available in file CREDITS. > * > @@ -26,8 +27,8 @@ > #include <shellapi.h> > #include <shlwapi.h> > #include <limits.h> > - > #include <sys/cygwin.h> > +#include <sys/stat.h> > > using namespace std; > > @@ -281,6 +282,21 @@ > win_path.c_str(), NULL, NULL, 1)) > 32; > } > > + > +bool isSameFile(string const & fileone, string const & filetwo) > +{ > + struct stat st1; > + struct stat st2; > + > + if (::stat(fileone.c_str(), &st1) == 0 > + && ::stat(filetwo.c_str(), &st2) == 0) { > + return st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev; > + } > + > + // One or both files cannot be accessed. > + return false; > +} > + > } // namespace os > } // namespace support > } // namespace lyx > > Modified: lyx-devel/trunk/src/support/os_unix.cpp > ============================================================================== > --- lyx-devel/trunk/src/support/os_unix.cpp Wed Apr 29 22:34:41 2009 > (r29443) > +++ lyx-devel/trunk/src/support/os_unix.cpp Thu Apr 30 00:42:26 2009 > (r29444) > @@ -17,6 +17,8 @@ > #include "support/FileName.h" > #include "support/lstrings.h" > > +#include <sys/stat.h> > + > #ifdef __APPLE__ > #include <Carbon/Carbon.h> > #endif > @@ -215,6 +217,21 @@ > #endif > } > > + > +bool isSameFile(string const & fileone, string const & filetwo) > +{ > + struct stat st1; > + struct stat st2; > + > + if (::stat(fileone.c_str(), &st1) == 0 > + && ::stat(filetwo.c_str(), &st2) == 0) { > + return st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev; > + } > + > + // One or both files cannot be accessed. > + return false; > +} > + > } // namespace os > } // namespace support > } // namespace lyx > > Modified: lyx-devel/trunk/src/support/os_win32.cpp > ============================================================================== > --- lyx-devel/trunk/src/support/os_win32.cpp Wed Apr 29 22:34:41 2009 > (r29443) > +++ lyx-devel/trunk/src/support/os_win32.cpp Thu Apr 30 00:42:26 2009 > (r29444) > @@ -389,6 +389,43 @@ > to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32; > } > > + > +bool isSameFile(string const & fileone, string const & filetwo) > +{ > + HANDLE h1 = CreateFile(fileone.c_str(), 0, > + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); > + HANDLE h2 = CreateFile(filetwo.c_str(), 0, > + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); > + > + if (h1 == INVALID_HANDLE_VALUE || h2 == INVALID_HANDLE_VALUE) { > + // One or both files cannot be accessed. > + if (h1 != INVALID_HANDLE_VALUE) > + CloseHandle(h1); > + if (h2 != INVALID_HANDLE_VALUE) > + CloseHandle(h2); > + return false; > + } > + > + BY_HANDLE_FILE_INFORMATION info1; > + BY_HANDLE_FILE_INFORMATION info2; > + bool samefile = false; > + if (GetFileInformationByHandle(h1, &info1) != 0 > + && GetFileInformationByHandle(h2, &info2) != 0) { > + // Serial number of the volumes containing the files. > + ULONG st1_dev = info1.dwVolumeSerialNumber; > + ULONG st2_dev = info2.dwVolumeSerialNumber; > + // Unique identifiers associated to the files on the volumes. > + ULONGLONG highbits = info1.nFileIndexHigh & 0x0000FFFF; > + ULONGLONG st1_ino = (highbits << sizeof(ULONG)) | > info1.nFileIndexLow; > + highbits = info2.nFileIndexHigh & 0x0000FFFF; > + ULONGLONG st2_ino = (highbits << sizeof(ULONG)) | > info2.nFileIndexLow; > + samefile = st1_ino == st2_ino && st1_dev == st2_dev; > + } > + CloseHandle(h1); > + CloseHandle(h2); > + return samefile; > +} > + > } // namespace os > } // namespace support > } // namespace lyx -- Enrico