Bo
------------------------------------------------------------------------
Index: src/graph.C
===================================================================
--- src/graph.C (revision 13784)
+++ src/graph.C (working copy)
@@ -77,8 +77,9 @@
int const i = Q_.front();
Q_.pop();
Format const & format = formats.get(i);
- if (!only_viewable || !format.viewer().empty() ||
- format.isChildFormat())
+ if (!only_viewable || format.isChildFormat() ||
+ (!format.viewer().empty() &&
+ (format.viewer() != "auto" || format.isAutoViewable())))
result.push_back(i);
vector<int>::const_iterator cit =
Index: src/format.C
===================================================================
--- src/format.C (revision 13784)
+++ src/format.C (working copy)
@@ -35,6 +35,10 @@
using lyx::support::quoteName;
using lyx::support::subst;
using lyx::support::Systemcall;
+using lyx::support::VIEW;
+using lyx::support::EDIT;
+using lyx::support::canAutoOpenFile;
+using lyx::support::autoOpenFile;
using std::string;
using std::distance;
@@ -87,7 +91,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, VIEW);
+}
bool Format::dummy() const
@@ -231,6 +237,17 @@
prettyName(format_name)));
return false;
}
+ // viewer is 'auto'
+ if (format->viewer() == "auto") {
+ if (autoOpenFile(filename, VIEW))
+ return true;
+ else {
+ Alert::error(_("Cannot view file"),
+ bformat(_("Auto-view file %1$s failed"),
+ filename));
+ return false;
+ }
+ }
string command = libScriptSearch(format->viewer());
@@ -287,6 +304,17 @@
prettyName(format_name)));
return false;
}
+ // editor is 'auto'
+ if (format->editor() == "auto") {
+ if (autoOpenFile(filename, EDIT))
+ return true;
+ else {
+ Alert::error(_("Cannot edit file"),
+ bformat(_("Auto-edit file %1$s failed"),
+ filename));
+ return false;
+ }
+ }
string command = format->editor();
Index: src/support/os.h
===================================================================
--- src/support/os.h (revision 13784)
+++ src/support/os.h (working copy)
@@ -80,6 +80,23 @@
*/
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 13784)
+++ 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,64 @@
return cmp;
}
+
+bool canAutoOpenFile(string const & ext, auto_open_mode const mode)
+{
+#if defined(_WIN32) || defined(__CYGWIN__)
+ if (ext == "")
+ return false;
+
+ string full_ext = ext;
+ // if the extension is passed without leading dot
+ if (full_ext[0] != '.')
+ full_ext = "." + ext;
+
+ 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
+ if (mode == VIEW)
+ return S_OK == AssocQueryString(0, ASSOCSTR_EXECUTABLE,
+ full_ext.c_str(), "open", buf, &bufSize);
+ else
+ return S_OK == AssocQueryString(0, ASSOCSTR_EXECUTABLE,
+ full_ext.c_str(), "edit", buf, &bufSize);
+#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, auto_open_mode const mode)
+{
+#if defined(_WIN32) || defined(__CYGWIN__)
+ lyxerr[Debug::FILES] << "Auto open 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
+ if (mode == VIEW)
+ return reinterpret_cast<int>(ShellExecute(NULL, "open",
+ win_path, NULL, NULL, 1)) > 32;
+ else
+ return reinterpret_cast<int>(ShellExecute(NULL, "edit",
+ win_path, NULL, NULL, 1)) > 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/os_cygwin.C
===================================================================
--- src/support/os_cygwin.C (revision 13784)
+++ src/support/os_cygwin.C (working copy)
@@ -86,13 +86,9 @@
(!contains(p, '\\') && (p.length() <= 1 || p[1] == ':'));
}
+} // namespace anon
-enum PathStyle {
- posix,
- windows
-};
-
string convert_path(string const & p, PathStyle const & target)
{
char path_buf[PATH_MAX];
@@ -139,9 +135,7 @@
return subst(p, '\\', '/');
}
-} // namespace anon
-
string external_path(string const & p)
{
return convert_path(p, cygwin_path_fix_ ? PathStyle(windows)
@@ -199,6 +193,49 @@
}
+// 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());
+ }
+}
+
+
// returns a string suitable to be passed to popen when
// reading a pipe
char const * popen_read_mode()
Index: src/support/filetools.h
===================================================================
--- src/support/filetools.h (revision 13784)
+++ src/support/filetools.h (working copy)
@@ -266,6 +266,25 @@
cmd_ret const runCommand(std::string const & cmd);
+enum auto_open_mode {
+ VIEW,
+ EDIT
+};
+
+/** Check whether or not a file can be viewed by a default viewer
+ * \param extension (without leading .)
+ * \mode can be opened in VIEW or EDIT mode
+ * \returns whether or not the format can be viewed
+ */
+bool canAutoOpenFile(std::string const & ext, auto_open_mode const mode=VIEW);
+
+/** view a file, with given command and parameter.
+ * \param filename
+ * \param mode open in VIEW or EDIT mode
+ * \returns whether or not the file is viewed (or edited) successfully.
+ */
+bool autoOpenFile(std::string const & filename, auto_open_mode const
mode=VIEW);
+
} // namespace support
} // namespace lyx
Index: src/support/Makefile.am
===================================================================
--- src/support/Makefile.am (revision 13784)
+++ src/support/Makefile.am (working copy)
@@ -9,6 +9,8 @@
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 13784)
+++ 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: lib/configure.py
===================================================================
--- lib/configure.py (revision 13784)
+++ lib/configure.py (working copy)
@@ -108,7 +108,7 @@
## Searching some useful programs
-def checkProg(description, progs, rc_entry = [], path = [] ):
+def checkProg(description, progs, rc_entry = [], path = [], check = True ):
'''
This function will search a program in $PATH plus given path
If found, return directory and program name (not the options).
@@ -119,21 +119,32 @@
for searching but the whole string is used to replace
%% for a rc_entry. So, feel free to add '$$i' etc for programs.
- path: additional path
+ path: additional pathes
- rc_entry: entry to outfile, can be emtpy, one pattern (%% for chosen
- prog or 'none'), or one for each prog and 'none'.
+ rc_entry: entry to outfile, can be
+ 1. emtpy: no rc entry will be added
+ 2. one pattern: %% will be replaced by the first found program,
+ or 'none' is no program is found.
+ 3. several patterns for each prog and 'none'. This is used
+ when different programs have different usages. If you do not
+ want 'none' entry to be added to the RC file, you can specify
+ an entry for each prog and use '' for the 'none' entry.
- NOTE: if you do not want 'none' entry to be added to the RC file,
- specify an entry for each prog and use '' for 'none' entry.
-
- FIXME: under windows, we should check registry instead of $PATH
+ check: whether or not check given programs. If check == False,
+ 1. rc_entry[0] will be used, with %% replaced by 'auto'
+ 2. ['', 'auto'] will be returned.
+ This is currently used under windows.
'''
# one rc entry for each progs plus none entry
if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
print "rc entry should have one item or item for each prog and none."
sys.exit(2)
print 'checking for ' + description + '...'
+ if not check:
+ print '+checking for "auto"... yes'
+ if len(rc_entry) > 0:
+ addToRC(rc_entry[0].replace('%%', 'auto'))
+ return ['', 'auto']
## print '(' + ','.join(progs) + ')',
for idx in range(len(progs)):
# ac_prog may have options, ac_word is the command name
@@ -186,22 +197,26 @@
return ''
-def checkFormatEntries():
+def checkFormatEntries(chk = True):
''' Check all formats (\Format entries) '''
checkProg('a Tgif viewer and editor', ['tgif'],
- rc_entry = [ r'\Format tgif obj Tgif "" "%%"
"%%"'])
+ rc_entry = [ r'\Format tgif obj Tgif "" "%%"
"%%"'],
+ check = chk)
#
checkProg('a FIG viewer and editor', ['xfig'],
- rc_entry = [ r'\Format fig fig FIG "" "%%"
"%%"'] )
+ rc_entry = [ r'\Format fig fig FIG "" "%%"
"%%"'],
+ check = chk)
#
checkProg('a Grace viewer and editor', ['xmgrace'],
- rc_entry = [ r'\Format agr agr Grace "" "%%"
"%%"'] )
+ rc_entry = [ r'\Format agr agr Grace "" "%%"
"%%"'],
+ check = chk)
#
checkProg('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'],
- rc_entry = [ r'\Format fen fen FEN "" "%%"
"%%"' ])
+ rc_entry = [ r'\Format fen fen FEN "" "%%"
"%%"'],
+ check = chk)
#
- path, iv = checkProg('a raster image viewer', ['xv', 'kview', 'gimp'])
- path, ie = checkProg('a raster image editor', ['gimp'])
+ path, iv = checkProg('a raster image viewer', ['xv', 'kview', 'gimp'], check
= chk)
+ path, ie = checkProg('a raster image editor', ['gimp'], check = chk)
addToRC(r'''\Format bmp bmp BMP "" "%s" "%s"
\Format gif gif GIF "" "%s" "%s"
\Format jpg jpg JPEG "" "%s" "%s"
@@ -227,25 +242,30 @@
\Format linuxdoc sgml LinuxDoc x "" "%%"
\Format pdflatex tex "LaTeX (pdflatex)" "" "" "%%"
\Format text txt "Plain text" a "" "%%"
-\Format textparagraph txt "Plain text (paragraphs)" "" "" "%%"''' ])
+\Format textparagraph txt "Plain text (paragraphs)" "" "" "%%"''' ],
+ check = chk)
#
#checkProg('a Postscript interpreter', ['gs'],
# rc_entry = [ r'\ps_command "%%"' ])
checkProg('a Postscript previewer', ['gsview32', 'gv', 'ghostview -swap',
'kghostview'],
rc_entry = [ r'''\Format eps eps EPS "" "%%"
""
-\Format ps ps Postscript t "%%" ""''' ])
+\Format ps ps Postscript t "%%" ""''' ],
+ check = chk)
#
checkProg('a PDF previewer', ['acrobat', 'acrord32', 'gsview32', \
'acroread', 'gv', 'ghostview', 'xpdf', 'kpdf', 'kghostview'],
rc_entry = [ r'''\Format pdf pdf "PDF (ps2pdf)" P "%%"
""
\Format pdf2 pdf "PDF (pdflatex)" F "%%" ""
-\Format pdf3 pdf "PDF (dvipdfm)" m "%%" ""''' ])
+\Format pdf3 pdf "PDF (dvipdfm)" m "%%" ""'''],
+ check = chk)
#
checkProg('a DVI previewer', ['xdvi', 'windvi', 'yap', 'kdvi'],
- rc_entry = [ r'\Format dvi dvi DVI D "%%"
""' ])
+ rc_entry = [ r'\Format dvi dvi DVI D "%%"
""' ],
+ check = chk)
#
checkProg('a HTML previewer', ['mozilla file://$$p$$i', 'netscape'],
- rc_entry = [ r'\Format html html HTML H "%%"
""' ])
+ rc_entry = [ r'\Format html html HTML H "%%"
""' ],
+ check = chk)
#
# entried that do not need checkProg
addToRC(r'''\Format date "" "date command" "" "" ""
@@ -273,7 +293,7 @@
Use PATH to avoid any problems with paths-with-spaces.
'''
path_orig = os.environ["PATH"]
- os.environ["PATH"] = os.path.join('..','src','tex2lyx') + \
+ os.environ["PATH"] = os.path.join('..', 'src', 'tex2lyx') + \
os.pathsep + path_orig
checkProg('a LaTeX -> LyX converter', ['tex2lyx -f $$i $$o', \
@@ -671,7 +691,8 @@
''')
# check latex
LATEX = checkLatex()
- checkFormatEntries()
+ # viewers under windows are handled automatically
+ checkFormatEntries(os.name != 'nt' and sys.platform != 'cygwin')
checkConverterEntries()
(chk_linuxdoc, bool_linuxdoc, linuxdoc_cmd) = checkLinuxDoc()
(chk_docbook, bool_docbook, docbook_cmd) = checkDocBook()
Index: config/cygwin.m4
===================================================================
--- config/cygwin.m4 (revision 13784)
+++ config/cygwin.m4 (working copy)
@@ -22,4 +22,10 @@
done
;;
esac
+
+ case $host_os in
+ cygwin* | mingw* )
+ AC_SUBST(LIBSHLWAPI, [-lshlwapi])
+ ;;
+ esac
])