On Thu, Apr 27, 2006 at 09:45:02AM -0500, Bo Peng wrote:
> > > Bo> 1. test 2. check for cygwin
> > >
> > > I can't do any of these.
> >
> > I am doing both.
> 
> Thank you. I (or you) can fix the enum{ View, Edit} thing after the
> patch is confirmed to work.

Urgh... I forgot that... But I have added autoconf support for
-lshlwapi.

Here is your patch augmented with the cygwin part. I attach separately
the patch to src/support/Makefile.in as "svn diff" missed it (again).

It seems to work, but I lost "OpenOffice.Org Writer" in the viewers.
I have to investigate but possibly it is a problem I am having recently
in Windows (associations seem to get rotten for no good reason).

-- 
Enrico
Index: src/graph.C
===================================================================
--- src/graph.C (revision 13764)
+++ src/graph.C (working copy)
@@ -78,7 +78,7 @@ Graph::getReachable(int from, bool only_
                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/format.C
===================================================================
--- src/format.C        (revision 13764)
+++ src/format.C        (working copy)
@@ -35,6 +35,8 @@ using lyx::support::Path;
 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 @@ bool operator<(Format const & a, Format 
 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 @@ bool Formats::view(Buffer const & buffer
        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 @@ bool Formats::edit(Buffer const & buffer
        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/support/os.h
===================================================================
--- src/support/os.h    (revision 13764)
+++ src/support/os.h    (working copy)
@@ -80,6 +80,23 @@ char path_separator();
  */
 void cygwin_path_fix(bool use_cygwin_paths);
 
+#if defined(__CYGWIN__) || defined(__CYGWIN32__)
+enum PathStyle {
+       posix,
+       windows
+};
+
+/// Converts a path to a target style.
+std::string convert_path(std::string const & p, PathStyle const & target);
+
+/// Converts a path list to a target style.
+std::string convert_path_list(std::string const & p, PathStyle const & target);
+
+/// Copy cygwin environment variables to the Windows environment
+/// if they're not already there.
+void setup_windows_environment(void);
+#endif
+
 } // namespace os
 } // namespace support
 } // namespace lyx
Index: src/support/filetools.C
===================================================================
--- src/support/filetools.C     (revision 13764)
+++ 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;
@@ -1223,6 +1229,54 @@ int compare_timestamps(string const & fi
        }
 
        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
Index: src/support/os_cygwin.C
===================================================================
--- src/support/os_cygwin.C     (revision 13764)
+++ src/support/os_cygwin.C     (working copy)
@@ -86,11 +86,7 @@ bool is_windows_path(string const & p)
                (!contains(p, '\\') && (p.length() <= 1 || p[1] == ':'));
 }
 
-
-enum PathStyle {
-    posix,
-    windows
-};
+} // namespace anon
 
 
 string convert_path(string const & p, PathStyle const & target)
@@ -139,8 +135,6 @@ string convert_path_list(string const & 
        return subst(p, '\\', '/');
 }
 
-} // namespace anon
-
 
 string external_path(string const & p)
 {
@@ -196,6 +190,49 @@ bool is_absolute_path(string const & p)
        bool isUnixPath = (p[0] == '/');
 
        return isDosPath || isUnixPath;
+}
+
+
+// Copy cygwin environment variables to the Windows environment
+// if they're not already there.
+void setup_windows_environment(void)
+{
+       char **envp = environ;
+       char curval[2];
+       string var;
+       string val;
+       bool temp_seen = false;
+
+       while (envp && *envp) {
+               val = split(*envp++, var, '=');
+
+               if (var == "TEMP")
+                       temp_seen = true;
+               
+               if (GetEnvironmentVariable(var.c_str(), curval, 2) == 0
+                               && GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
+                       /* Convert to Windows style where necessary */
+                       if (var == "PATH" || var == "LD_LIBRARY_PATH") {
+                               string const winpathlist =
+                                   convert_path_list(val, PathStyle(windows));
+                               if (!winpathlist.empty()) {
+                                       SetEnvironmentVariable(var.c_str(),
+                                               winpathlist.c_str());
+                               }
+                       } else if (var == "HOME" || var == "TMPDIR" ||
+                                       var == "TMP" || var == "TEMP") {
+                               string const winpath =
+                                       convert_path(val, PathStyle(windows));
+                               SetEnvironmentVariable(var.c_str(), 
winpath.c_str());
+                       } else {
+                               SetEnvironmentVariable(var.c_str(), 
val.c_str());
+                       }
+               }
+       }
+       if (!temp_seen) {
+               string const winpath = convert_path("/tmp", PathStyle(windows));
+               SetEnvironmentVariable("TEMP", winpath.c_str());
+       }
 }
 
 
Index: src/support/filetools.h
===================================================================
--- src/support/filetools.h     (revision 13764)
+++ src/support/filetools.h     (working copy)
@@ -266,6 +266,19 @@ typedef std::pair<int, std::string> cmd_
 
 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 13764)
+++ src/support/Makefile.am     (working copy)
@@ -9,6 +9,8 @@ EXTRA_DIST = package.C.in pch.h \
 
 noinst_LTLIBRARIES = libsupport.la
 
+libsupport_la_LIBADD = $(LIBSHLWAPI)
+
 BUILT_SOURCES = $(PCH_FILE) package.C
 
 AM_CPPFLAGS += $(PCH_FLAGS) -I$(srcdir)/.. $(BOOST_INCLUDES)
Index: src/format.h
===================================================================
--- src/format.h        (revision 13764)
+++ src/format.h        (working copy)
@@ -49,6 +49,10 @@ public:
                return viewer_;
        }
        ///
+       bool const isAutoViewable() const {
+               return autoViewable_;
+       }
+       ///
        void setViewer(std::string const & v) {
                viewer_ = v;
        }
@@ -66,6 +70,8 @@ private:
        std::string shortcut_;
        ///
        std::string viewer_;
+       ///
+       bool autoViewable_;
        ///
        std::string editor_;
 };
Index: config/cygwin.m4
===================================================================
--- config/cygwin.m4    (revision 13764)
+++ config/cygwin.m4    (working copy)
@@ -22,4 +22,10 @@ AC_DEFUN([CHECK_WITH_CYGWIN],
     done
     ;;
   esac
+
+  case $host_os in
+  cygwin* | mingw* )
+    AC_SUBST(LIBSHLWAPI, [-lshlwapi])
+    ;;
+  esac
 ])
--- src/support/Makefile.in~    Wed Apr 26 20:28:35 2006
+++ src/support/Makefile.in     Thu Apr 27 20:09:39 2006
@@ -48,7 +48,8 @@
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-libsupport_la_LIBADD =
+am__DEPENDENCIES_1 =
+libsupport_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am_libsupport_la_OBJECTS = FileMonitor.lo abort.lo chdir.lo convert.lo \
        copy.lo environment.lo filefilterlist.lo filename.lo \
        filetools.lo forkedcall.lo forkedcallqueue.lo forkedcontr.lo \
@@ -159,6 +160,7 @@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
 LIBS = 
+LIBSHLWAPI = @LIBSHLWAPI@
 LIBTOOL = @LIBTOOL@
 LN_S = @LN_S@
 LTLIBICONV = @LTLIBICONV@
@@ -317,6 +319,7 @@
        os_cygwin.C os_os2.C os_unix.C os_win32.C os_win32.h
 
 noinst_LTLIBRARIES = libsupport.la
+libsupport_la_LIBADD = $(LIBSHLWAPI)
 BUILT_SOURCES = $(PCH_FILE) package.C
 libsupport_la_SOURCES = \
        FileMonitor.h \

Reply via email to