Dear list,

Attached is a patch that

1. add autoViewable to Format. This will return true, under windows,
if a file extension is associated with a file.

2. If the format of a file is empty, but is autoViewable, because of a
change in graph.C, it will appear in the menu.

3. File with empty format (but autoViewable) will be opened by
windows' default viewer.

Current  behavior:

1. configure.py proceeds as usual

2. If viewer() is not empty, use the searched viewer (potential
problem, see later)

3. if viewer() is empty, and the file is autoViewable, menu->ps/pdf
etc will appear and do the correct thing.

4. if viewer() is empty, and the file is not autoViewable,
menu->ps/pdf etc will *disappear* (potential problem, see later).


Problems:

1. configure.py may find gsview32.exe and set it. If gsview32 is
uninstalled, this entry will be there, until reconfiguration. In this
case, view->ps will appear but will fail.

2. if gsview is uninstalled and ps viewer() is empty, there will be no
view->postscript.

3. Currently, in src/support/Makefile.am, I use libsupport_la_LIBADD =
-;lshlwapi wiithout proper automake/autoconf conditioning. Please help
me fix it. (I am too tired)


I would propse:

1. do not search for viewers at all under windows, to avoid problem 1.
Actually, my configure.py view pdf files with gsview, which is simply
ugly. (What will happen if there is no \format entries at all?)

2. find some way to show a disabled 'view->postscript' to tell the
user lyx can handle postscript, just a viewer has not been installed.

Please:

1. test
2. check for cygwin
3. add autoconf things for -lshlwapi

Cheers,
Bo
Index: src/format.C
===================================================================
--- src/format.C	(revision 13752)
+++ src/format.C	(working copy)
@@ -35,6 +35,8 @@
 using lyx::support::quoteName;
 using lyx::support::subst;
 using lyx::support::Systemcall;
+using lyx::support::canAutoOpenFile;
+using lyx::support::autoOpenFile;
 
 using std::string;
 using std::distance;
@@ -87,7 +89,9 @@
 Format::Format(string const & n, string const & e, string const & p,
 	       string const & s, string const & v, string const & ed)
 	: name_(n), extension_(e), prettyname_(p), shortcut_(s), viewer_(v), editor_(ed)
-{}
+{
+	autoViewable_ = canAutoOpenFile(e);
+}
 
 
 bool Format::dummy() const
@@ -223,13 +227,17 @@
 	if (format && format->viewer().empty() &&
 	    format->isChildFormat())
 		format = getFormat(format->parentFormat());
+
+	// auto viewer is the default setting under windows
 	if (!format || format->viewer().empty()) {
-// I believe this is the wrong place to show alerts, it should be done by
-// the caller (this should be "utility" code)
-		Alert::error(_("Cannot view file"),
-			bformat(_("No information for viewing %1$s"),
-				prettyName(format_name)));
-		return false;
+		if (!autoOpenFile(filename, "open")) {
+			// I believe this is the wrong place to show alerts, it should be done by
+			// the caller (this should be "utility" code)
+			Alert::error(_("Cannot view file"),
+			     _("No default viewer for viewing ") + filename);
+			return false;
+		}
+		return true;
 	}
 
 	string command = libScriptSearch(format->viewer());
@@ -279,13 +287,17 @@
 	if (format && format->editor().empty() &&
 	    format->isChildFormat())
 		format = getFormat(format->parentFormat());
+
+	// auto editor is the default setting under windows
 	if (!format || format->editor().empty()) {
-// I believe this is the wrong place to show alerts, it should be done by
-// the caller (this should be "utility" code)
-		Alert::error(_("Cannot edit file"),
-			bformat(_("No information for editing %1$s"),
-				prettyName(format_name)));
-		return false;
+		if (!autoOpenFile(filename, "edit")) {
+			// I believe this is the wrong place to show alerts, it should be done by
+			// the caller (this should be "utility" code)
+			Alert::error(_("Cannot edit file"),
+				_("No default editor for editing " + filename));
+			return false;
+		}
+		return true;
 	}
 
 	string command = format->editor();
Index: src/format.h
===================================================================
--- src/format.h	(revision 13752)
+++ src/format.h	(working copy)
@@ -49,6 +49,10 @@
 		return viewer_;
 	}
 	///
+	bool const isAutoViewable() const {
+		return autoViewable_;
+	}
+	///
 	void setViewer(std::string const & v) {
 		viewer_ = v;
 	}
@@ -67,6 +71,8 @@
 	///
 	std::string viewer_;
 	///
+	bool autoViewable_;
+	///
 	std::string editor_;
 };
 
Index: src/graph.C
===================================================================
--- src/graph.C	(revision 13752)
+++ src/graph.C	(working copy)
@@ -78,7 +78,7 @@
 		Q_.pop();
 		Format const & format = formats.get(i);
 		if (!only_viewable || !format.viewer().empty() ||
-		    format.isChildFormat())
+		    format.isAutoViewable() || format.isChildFormat())
 			result.push_back(i);
 
 		vector<int>::const_iterator cit =
Index: src/support/filetools.C
===================================================================
--- src/support/filetools.C	(revision 13752)
+++ src/support/filetools.C	(working copy)
@@ -51,6 +51,12 @@
 #include <fstream>
 #include <sstream>
 
+#if defined(_WIN32) || defined(__CYGWIN__)
+# include <windef.h>
+# include <shellapi.h>	
+# include <shlwapi.h>
+#endif
+
 #ifndef CXX_GLOBAL_CSTD
 using std::fgetc;
 using std::isalnum;
@@ -1225,5 +1231,53 @@
 	return cmp;
 }
 
+
+bool canAutoOpenFile(string const & ext)
+{
+#if defined(_WIN32) || defined(__CYGWIN__)
+	DWORD bufSize = MAX_PATH + 100;
+	TCHAR buf[MAX_PATH + 100];
+	// reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc
+	//                 /platform/shell/reference/shlwapi/registry/assocquerystring.asp
+	HRESULT res = AssocQueryString(0, ASSOCSTR_EXECUTABLE,
+		ext.c_str(), "open", buf, &bufSize);
+	// if an application if found, test if it exists
+	if (res == S_OK)
+		return fs::exists(buf);
+	return false;
+#else
+	// currently, no default viewer is tried for non-windows system
+	// support for KDE/Gnome/Macintosh may be added later
+	return false;
+#endif
+}
+
+
+bool autoOpenFile(string const & filename, string const & mode)
+{
+#if defined(_WIN32) || defined(__CYGWIN__)
+	lyxerr[Debug::FILES] << mode << " file: " << filename << std::endl;
+
+	// reference: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc
+	//                 /platform/shell/reference/functions/shellexecute.asp
+# ifdef __CYGWIN__
+	string const converted_path =
+		os::convert_path(filename, os::PathStyle(os::windows));
+	char const * const win_path = converted_path.c_str();
+	// Need to sync the Windows environment
+	os::setup_windows_environment();
+# else
+	char const * const win_path = filename.c_str();
+# endif
+	int const res = reinterpret_cast<int>(ShellExecute(NULL, mode.c_str(), 
+		win_path, NULL, NULL, 1));
+	return res > 32;
+#else
+	// currently, no default viewer is tried for non-windows system
+	// support for KDE/Gnome/Macintosh may be added later
+	return false;
+#endif
+}
+
 } //namespace support
 } // namespace lyx
Index: src/support/filetools.h
===================================================================
--- src/support/filetools.h	(revision 13752)
+++ src/support/filetools.h	(working copy)
@@ -266,6 +266,19 @@
 
 cmd_ret const runCommand(std::string const & cmd);
 
+/** Check whether or not a file can be viewed by a default viewer 
+ *  \param extension (without leading .)
+ *  \returns whether or not the format can be viewed
+ */
+bool canAutoOpenFile(std::string const & ext);
+
+/** view a file, with given command and parameter.
+ *  \param filename
+ *  \param mode  "open" or "edit"
+ *  \returns whether or not the file is viewed (or edited) successfully.
+ */
+bool autoOpenFile(std::string const & filename, std::string const & mode="open");
+
 } // namespace support
 } // namespace lyx
 
Index: src/support/Makefile.am
===================================================================
--- src/support/Makefile.am	(revision 13752)
+++ src/support/Makefile.am	(working copy)
@@ -76,6 +76,8 @@
 	userinfo.h \
 	unlink.C
 
+# FIXME: this is only valid under windows
+libsupport_la_LIBADD = -lshlwapi
 
 package.C: build_package
 

Reply via email to