This is what it looks like simplifed and rewritten to use
boost.filesystem.

I have not changed the visual apparence of the dialog, so there are
one widget too many on it currently (unused).

Please comment.

Index: FormFiledialog.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormFiledialog.C,v
retrieving revision 1.65
diff -u -p -B -b -w -r1.65 FormFiledialog.C
--- FormFiledialog.C	10 Jan 2005 19:17:41 -0000	1.65
+++ FormFiledialog.C	29 Jan 2005 14:18:32 -0000
@@ -19,8 +19,6 @@
 
 #include "frontends/Dialogs.h"
 
-#include "support/convert.h"
-#include "support/FileInfo.h"
 #include "support/filefilterlist.h"
 #include "support/filetools.h"
 #include "support/globbing.h"
@@ -31,47 +29,21 @@
 #include "lyx_forms.h"
 
 #include <boost/bind.hpp>
-#include <boost/regex.hpp>
+#include <boost/filesystem/operations.hpp>
 #include <boost/tokenizer.hpp>
 
 #include <algorithm>
-#include <map>
 #include <sstream>
 
-#include <grp.h>
-#include <pwd.h>
-
-//#ifdef HAVE_ERRNO_H
-//#include <cerrno>
-//#endif
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-#else
-# define dirent direct
-# if HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif
-
 using lyx::support::AbsolutePath;
 using lyx::support::AddName;
 using lyx::support::ExpandPath;
 using lyx::support::FileFilterList;
-using lyx::support::FileInfo;
 using lyx::support::getcwd;
-using lyx::support::LyXReadLink;
 using lyx::support::MakeAbsPath;
 using lyx::support::OnlyFilename;
 using lyx::support::package;
 using lyx::support::split;
-using lyx::support::subst;
 using lyx::support::suffixIs;
 using lyx::support::trim;
 
@@ -79,11 +51,10 @@ using std::max;
 using std::sort;
 using std::ostringstream;
 using std::string;
-using std::map;
 using std::vector;
 
 using namespace lyx::frontend;
-
+namespace fs = boost::filesystem;
 
 namespace {
 
@@ -114,11 +85,6 @@ vector<string> const expand_globs(string
 }
 
 
-// six months, in seconds
-long const SIX_MONTH_SEC = 6L * 30L * 24L * 60L * 60L;
-//static
-long const ONE_HOUR_SEC = 60L * 60L;
-
 extern "C" {
 
 	static
@@ -141,72 +107,6 @@ extern "C" {
 
 }
 
-// *** User cache class implementation
-/// User cache class definition
-class UserCache {
-public:
-	/// seeks user name from group ID
-	string const & find(uid_t ID) const {
-		Users::const_iterator cit = users.find(ID);
-		if (cit == users.end()) {
-			add(ID);
-			return users[ID];
-		}
-		return cit->second;
-	}
-private:
-	///
-	void add(uid_t ID) const;
-	///
-	typedef map<uid_t, string> Users;
-	///
-	mutable Users users;
-};
-
-
-void UserCache::add(uid_t ID) const
-{
-	struct passwd const * entry = getpwuid(ID);
-	users[ID] = entry ? entry->pw_name : convert<string>(int(ID));
-}
-
-
-/// Group cache class definition
-class GroupCache {
-public:
-	/// seeks group name from group ID
-	string const & find(gid_t ID) const ;
-private:
-	///
-	void add(gid_t ID) const;
-	///
-	typedef map<gid_t, string> Groups;
-	///
-	mutable Groups groups;
-};
-
-
-string const & GroupCache::find(gid_t ID) const
-{
-	Groups::const_iterator cit = groups.find(ID);
-	if (cit == groups.end()) {
-		add(ID);
-		return groups[ID];
-	}
-	return cit->second;
-}
-
-
-void GroupCache::add(gid_t ID) const
-{
-	struct group const * entry = getgrgid(ID);
-	groups[ID] = entry ? entry->gr_name : convert<string>(int(ID));
-}
-
-
-// local instances
-UserCache lyxUserCache;
-GroupCache lyxGroupCache;
 
 // compares two LyXDirEntry objects content (used for sort)
 class comp_direntry : public std::binary_function<DirEntry, DirEntry, bool> {
@@ -240,15 +140,13 @@ int FileDialog::Private::minh_ = 0;
 void FileDialog::Private::Reread()
 {
 	// Opens directory
-	DIR * dir = ::opendir(directory_.c_str());
-	if (!dir) {
+	if (!fs::exists(directory_) || !fs::is_directory(directory_)) {
 // FIXME: re-add ...
 #if 0
 		Alert::err_alert(_("Warning! Couldn't open directory."),
 			directory_);
 #endif
 		directory_ = getcwd();
-		dir = ::opendir(directory_.c_str());
 	}
 
 	// Clear the present namelist
@@ -261,14 +159,14 @@ void FileDialog::Private::Reread()
 
 	// Splits complete directory name into directories and compute depth
 	depth_ = 0;
-	string line, Temp;
-	string mode;
+	string line;
+	string Temp;
 	string File = directory_;
 	if (File != "/")
 		File = split(File, Temp, '/');
 
 	while (!File.empty() || !Temp.empty()) {
-		string dline = "@b" + line + Temp + '/';
+		string const dline = "@b" + line + Temp + '/';
 		fl_add_browser_line(file_dlg_form_->List, dline.c_str());
 		File = split(File, Temp, '/');
 		line += ' ';
@@ -277,118 +175,37 @@ void FileDialog::Private::Reread()
 
 	vector<string> const glob_matches = expand_globs(mask_, directory_);
 
-	time_t curTime = time(0);
-	rewinddir(dir);
-	while (dirent * entry = readdir(dir)) {
-		bool isLink = false, isDir = false;
+	fs::directory_iterator beg(directory_);
+	fs::directory_iterator end;
+	for (; beg != end; ++beg) {
+		string const fname = beg->leaf();
 
 		// If the pattern doesn't start with a dot, skip hidden files
-		if (!mask_.empty() && mask_[0] != '.' &&
-		    entry->d_name[0] == '.')
-			continue;
-
-		// Gets filename
-		string fname = entry->d_name;
-
-		// Under all circumstances, "." and ".." are not wanted
-		if (fname == "." || fname == "..")
-			continue;
-
-		// gets file status
-		File = AddName(directory_, fname);
-
-		FileInfo fileInfo(File, true);
-
-		// can this really happen?
-		if (!fileInfo.isOK())
+		if (!mask_.empty() && mask_[0] != '.' && fname[0] == '.')
 			continue;
 
-		mode = fileInfo.modeString();
-		string const user  = lyxUserCache.find(fileInfo.getUid());
-		string const group = lyxGroupCache.find(fileInfo.getGid());
-
-		time_t modtime = fileInfo.getModificationTime();
-		string Time = ctime(&modtime);
-
-		if (curTime > modtime + SIX_MONTH_SEC
-		    || curTime < modtime + ONE_HOUR_SEC) {
-			// The file is fairly old or in the future. POSIX says
-			// the cutoff is 6 months old. Allow a 1 hour slop
-			// factor for what is considered "the future", to
-			// allow for NFS server/client clock disagreement.
-			// Show the year instead of the time of day.
-			Time.erase(10, 9);
-			Time.erase(15, string::npos);
-		} else {
-			Time.erase(16, string::npos);
-		}
-
-		string buffer = mode + ' ' +
-			user + ' ' +
-			group + ' ' +
-			Time.substr(4, string::npos) + ' ';
-
-		buffer += entry->d_name;
-		buffer += fileInfo.typeIndicator();
-
-		isLink = fileInfo.isLink();
-		if (isLink) {
-			string Link;
-
-			if (LyXReadLink(File, Link)) {
-				buffer += " -> ";
-				buffer += Link;
-
-				// This gives the FileType of the file that
-				// is really pointed to after resolving all
-				// symlinks. This is not necessarily the same
-				// as the type of Link (which could again be a
-				// link). Is that intended?
-				//                              JV 199902
-				fileInfo.newFile(File);
-				if (fileInfo.isOK())
-					buffer += fileInfo.typeIndicator();
-				else
-					continue;
-			}
-		}
+		bool const isDir = fs::is_directory(*beg);
 
 		// filters files according to pattern and type
-		if (fileInfo.isRegular()
-		    || fileInfo.isChar()
-		    || fileInfo.isBlock()
-		    || fileInfo.isFifo()) {
 			typedef vector<string>::const_iterator viterator;
 			viterator gbegin = glob_matches.begin();
 			viterator const gend = glob_matches.end();
-			if (std::find(gbegin, gend, fname) == gend)
-				continue;
-		} else if (!(isDir = fileInfo.isDir()))
+		
+		if (!isDir && std::find(gbegin, gend, fname) == gend)
 			continue;
 
 		DirEntry tmp;
-
-		// Note ls_entry_ is an string!
-		tmp.ls_entry_ = buffer;
 		// creates used name
-		string temp = fname;
+		tmp.name_ = fname;
+		
 		if (isDir)
-			temp += '/';
+			tmp.name_ += '/';
 
-		tmp.name_ = temp;
 		// creates displayed name
-		temp = entry->d_name;
-		if (isLink)
-			temp += '@';
-		else
-			temp += fileInfo.typeIndicator();
-		tmp.displayed_ = temp;
-
+		tmp.displayed_ = fname;
 		dir_entries_.push_back(tmp);
 	}
 
-	closedir(dir);
-
 	// Sort the names
 	sort(dir_entries_.begin(), dir_entries_.end(), comp_direntry());
 
@@ -414,14 +231,12 @@ void FileDialog::Private::SetDirectory(s
 		tmp = MakeAbsPath(ExpandPath(path), directory_);
 
 	// must check the directory exists
-	DIR * dir = ::opendir(tmp.c_str());
-	if (!dir) {
+	if (!fs::exists(tmp) || !fs::is_directory(tmp)) {
 // FIXME: re-add ...
 #if 0
 		Alert::err_alert(_("Warning! Couldn't open directory."), tmp);
 #endif
 	} else {
-		::closedir(dir);
 		directory_ = tmp;
 	}
 }
@@ -457,14 +272,6 @@ void FileDialog::Private::SetFilters(Fil
 }
 
 
-// SetInfoLine: sets dialog information line
-void FileDialog::Private::SetInfoLine(string const & line)
-{
-	info_line_ = line;
-	fl_set_object_label(file_dlg_form_->FileInfo, info_line_.c_str());
-}
-
-
 FileDialog::Private::Private()
 {
 	directory_ = MakeAbsPath(string("."));
@@ -644,10 +451,12 @@ void FileDialog::Private::HandleListHit(
 {
 	// set info line
 	int const select_ = fl_get_browser(file_dlg_form_->List);
-	if (select_ > depth_)
-		SetInfoLine(dir_entries_[select_ - depth_ - 1].ls_entry_);
-	else
-		SetInfoLine(string());
+       string line = (select_ > depth_ ?
+			    dir_entries_[select_ - depth_ - 1].name_ :
+			    string());
+       if (suffixIs(line, '/'))
+	       line.clear();
+       fl_set_input(file_dlg_form_->Filename, line.c_str());
 }
 
 
@@ -670,14 +479,11 @@ bool FileDialog::Private::HandleDoubleCl
 	int const select_ = fl_get_browser(file_dlg_form_->List);
 	if (select_ > depth_) {
 		tmp = dir_entries_[select_ - depth_ - 1].name_;
-		SetInfoLine(dir_entries_[select_ - depth_ - 1].ls_entry_);
 		if (!suffixIs(tmp, '/')) {
 			isDir = false;
 			fl_set_input(file_dlg_form_->Filename, tmp.c_str());
 		}
-	} else if (select_ != 0) {
-		SetInfoLine(string());
-	} else
+	} else if (select_ == 0)
 		return true;
 
 	// executes action
@@ -696,7 +502,7 @@ bool FileDialog::Private::HandleDoubleCl
 			// Directory higher up
 			Temp.erase();
 			for (int i = 0; i < select_; ++i) {
-				string piece = fl_get_browser_line(file_dlg_form_->List, i+1);
+				string const piece = fl_get_browser_line(file_dlg_form_->List, i + 1);
 				// The '+2' is here to count the '@b' (JMarc)
 				Temp += piece.substr(i + 2);
 			}
@@ -808,7 +614,6 @@ string const FileDialog::Private::Select
 	current_dlg_ = this;
 
 	// runs dialog
-	SetInfoLine(string());
 	setEnabled(file_dlg_form_->Filename, true);
 	fl_set_input(file_dlg_form_->Filename, suggested.c_str());
 	fl_set_button(file_dlg_form_->Cancel, 0);
@@ -858,11 +663,10 @@ string const FileDialog::Private::Select
 			string tmp = suggested;
 			if (!suffixIs(tmp, '/'))
 				tmp += '/';
-			string full_path = path;
-			full_path += tmp;
+			string const full_path = path + tmp;
 			// check if this is really a directory
-			DIR * dir = ::opendir(full_path.c_str());
-			if (dir)
+			if (fs::exists(full_path)
+			    && fs::is_directory(full_path))
 				SetDirectory(full_path);
 			else
 				SetDirectory(path);
@@ -879,7 +683,6 @@ string const FileDialog::Private::Select
 	current_dlg_ = this;
 
 	// runs dialog
-	SetInfoLine(string());
 	fl_set_input(file_dlg_form_->Filename, "");
 	setEnabled(file_dlg_form_->Filename, false);
 	fl_set_button(file_dlg_form_->Cancel, 0);
Index: FormFiledialog.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/FormFiledialog.h,v
retrieving revision 1.21
diff -u -p -B -b -w -r1.21 FormFiledialog.h
--- FormFiledialog.h	19 May 2004 15:11:35 -0000	1.21
+++ FormFiledialog.h	29 Jan 2005 14:18:32 -0000
@@ -43,8 +43,6 @@ public:
 	std::string name_;
 	///
 	std::string displayed_;
-	///
-	std::string ls_entry_;
 };
 
 
@@ -115,8 +113,6 @@ private:
 	///
 	long last_time_;
 	///
-	std::string info_line_;
-	///
 	typedef std::vector<lyx::frontend::DirEntry> DirEntries;
 	///
 	DirEntries dir_entries_;
@@ -136,8 +132,6 @@ private:
 	/// sets dialog file mask
 	void SetFilters(std::string const & filters);
 	void SetFilters(lyx::support::FileFilterList const & filters);
-	/// sets dialog information line
-	void SetInfoLine(std::string const & pszLine);
 	/// handle dialog during file selection
 	bool RunDialog();
 	/// Handle callback from list
-- 
        Lgb

Reply via email to