added .chm support for Unix (Markus Sinner)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24117 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
24
configure.in
24
configure.in
@@ -575,6 +575,7 @@ else
|
|||||||
DEFAULT_wxUSE_LIBPNG=yes
|
DEFAULT_wxUSE_LIBPNG=yes
|
||||||
DEFAULT_wxUSE_LIBJPEG=yes
|
DEFAULT_wxUSE_LIBJPEG=yes
|
||||||
DEFAULT_wxUSE_LIBTIFF=yes
|
DEFAULT_wxUSE_LIBTIFF=yes
|
||||||
|
DEFAULT_wxUSE_LIBMSPACK=yes
|
||||||
DEFAULT_wxUSE_ODBC=no
|
DEFAULT_wxUSE_ODBC=no
|
||||||
DEFAULT_wxUSE_OPENGL=no
|
DEFAULT_wxUSE_OPENGL=no
|
||||||
|
|
||||||
@@ -768,6 +769,7 @@ WX_ARG_ENABLE(gtk2, [ --enable-gtk2 use GTK+ 2.0 if available
|
|||||||
WX_ARG_SYS_WITH(libpng, [ --with-libpng use libpng (PNG image format)], wxUSE_LIBPNG)
|
WX_ARG_SYS_WITH(libpng, [ --with-libpng use libpng (PNG image format)], wxUSE_LIBPNG)
|
||||||
WX_ARG_SYS_WITH(libjpeg, [ --with-libjpeg use libjpeg (JPEG file format)], wxUSE_LIBJPEG)
|
WX_ARG_SYS_WITH(libjpeg, [ --with-libjpeg use libjpeg (JPEG file format)], wxUSE_LIBJPEG)
|
||||||
WX_ARG_SYS_WITH(libtiff, [ --with-libtiff use libtiff (TIFF file format)], wxUSE_LIBTIFF)
|
WX_ARG_SYS_WITH(libtiff, [ --with-libtiff use libtiff (TIFF file format)], wxUSE_LIBTIFF)
|
||||||
|
WX_ARG_WITH(libmspack, [ --with-libmspack use libmspack (CHM help files loading)], wxUSE_LIBMSPACK)
|
||||||
WX_ARG_WITH(opengl, [ --with-opengl use OpenGL (or Mesa)], wxUSE_OPENGL)
|
WX_ARG_WITH(opengl, [ --with-opengl use OpenGL (or Mesa)], wxUSE_OPENGL)
|
||||||
|
|
||||||
fi
|
fi
|
||||||
@@ -2203,6 +2205,25 @@ if test "$wxUSE_EXPAT" != "no"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl ------------------------------------------------------------------------
|
||||||
|
dnl Check for libmspack
|
||||||
|
dnl ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if test "$wxUSE_LIBMSPACK" != "no"; then
|
||||||
|
|
||||||
|
AC_CHECK_HEADER([mspack.h], [found_mspack_h=1])
|
||||||
|
if test "x$found_mspack_h" = "x1"; then
|
||||||
|
AC_CHECK_LIB(mspack, mspack_create_chm_decompressor,
|
||||||
|
MSPACK_LINK=" -lmspack")
|
||||||
|
fi
|
||||||
|
if test "x$MSPACK_LINK" = "x" ; then
|
||||||
|
wxUSE_LIBMSPACK=no
|
||||||
|
else
|
||||||
|
AC_DEFINE(wxUSE_LIBMSPACK)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------
|
dnl ----------------------------------------------------------------
|
||||||
dnl search for toolkit (widget sets)
|
dnl search for toolkit (widget sets)
|
||||||
dnl ----------------------------------------------------------------
|
dnl ----------------------------------------------------------------
|
||||||
@@ -5662,6 +5683,7 @@ CXXFLAGS=`echo $CODE_GEN_FLAGS $CODE_GEN_FLAGS_CXX $EXTRA_CFLAGS $CXXFLAGS $CXXW
|
|||||||
LIBS=`echo $LIBS | sed 's/ \+/ /g'`
|
LIBS=`echo $LIBS | sed 's/ \+/ /g'`
|
||||||
EXTRALIBS="$LDFLAGS $LDFLAGS_VERSIONING $LIBS $DMALLOC_LIBS"
|
EXTRALIBS="$LDFLAGS $LDFLAGS_VERSIONING $LIBS $DMALLOC_LIBS"
|
||||||
EXTRALIBS_XML="$EXPAT_LINK"
|
EXTRALIBS_XML="$EXPAT_LINK"
|
||||||
|
EXTRALIBS_HTML="$MSPACK_LINK"
|
||||||
EXTRALIBS_ODBC="$ODBC_LINK"
|
EXTRALIBS_ODBC="$ODBC_LINK"
|
||||||
if test "$wxUSE_GUI" = "yes"; then
|
if test "$wxUSE_GUI" = "yes"; then
|
||||||
EXTRALIBS_GUI=`echo $GUI_TK_LIBRARY $PNG_LINK $JPEG_LINK $TIFF_LINK | sed 's/ \+/ /g'`
|
EXTRALIBS_GUI=`echo $GUI_TK_LIBRARY $PNG_LINK $JPEG_LINK $TIFF_LINK | sed 's/ \+/ /g'`
|
||||||
@@ -5752,6 +5774,7 @@ AC_SUBST(MONOLITHIC)
|
|||||||
AC_SUBST(LIBS)
|
AC_SUBST(LIBS)
|
||||||
AC_SUBST(EXTRALIBS)
|
AC_SUBST(EXTRALIBS)
|
||||||
AC_SUBST(EXTRALIBS_XML)
|
AC_SUBST(EXTRALIBS_XML)
|
||||||
|
AC_SUBST(EXTRALIBS_HTML)
|
||||||
AC_SUBST(EXTRALIBS_ODBC)
|
AC_SUBST(EXTRALIBS_ODBC)
|
||||||
AC_SUBST(EXTRALIBS_GUI)
|
AC_SUBST(EXTRALIBS_GUI)
|
||||||
AC_SUBST(EXTRALIBS_OPENGL)
|
AC_SUBST(EXTRALIBS_OPENGL)
|
||||||
@@ -6046,6 +6069,7 @@ echo " tiff ${wxUSE_LIBTIFF-
|
|||||||
echo " zlib ${wxUSE_ZLIB}"
|
echo " zlib ${wxUSE_ZLIB}"
|
||||||
echo " odbc ${wxUSE_ODBC}"
|
echo " odbc ${wxUSE_ODBC}"
|
||||||
echo " expat ${wxUSE_EXPAT}"
|
echo " expat ${wxUSE_EXPAT}"
|
||||||
|
echo " libmspack ${wxUSE_LIBMSPACK}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
@@ -99,6 +99,11 @@ wxGTK:
|
|||||||
- fix for crash when using user-dashed lines (Chris Borgolte)
|
- fix for crash when using user-dashed lines (Chris Borgolte)
|
||||||
- fixed wxChoice::Delete() in presence of client data
|
- fixed wxChoice::Delete() in presence of client data
|
||||||
|
|
||||||
|
wxHTML:
|
||||||
|
|
||||||
|
- wxHtmlHelpController now supports compressed MS HTML Help files (*.chm)
|
||||||
|
on Unix (Markus Sinner)
|
||||||
|
|
||||||
|
|
||||||
2.5.0
|
2.5.0
|
||||||
-----
|
-----
|
||||||
|
894
src/html/chm.cpp
Normal file
894
src/html/chm.cpp
Normal file
@@ -0,0 +1,894 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: chm.cpp
|
||||||
|
// Purpose: CHM (Help) support for wxHTML
|
||||||
|
// Author: Markus Sinner
|
||||||
|
// Copyright: (c) 2003 Herd Software Development
|
||||||
|
// CVS-ID: $Id$
|
||||||
|
// Licence: wxWindows Licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
|
||||||
|
#include <mspack.h>
|
||||||
|
|
||||||
|
#ifndef WXPRECOMP
|
||||||
|
#include "wx/intl.h"
|
||||||
|
#include "wx/log.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/module.h"
|
||||||
|
#include "wx/filesys.h"
|
||||||
|
#include "wx/mstream.h"
|
||||||
|
#include "wx/wfstream.h"
|
||||||
|
|
||||||
|
#include "wx/html/forcelnk.h"
|
||||||
|
FORCE_LINK_ME(wxhtml_chm_support)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/// wxChmTools
|
||||||
|
/// <p>
|
||||||
|
/// this class is used to abstract access to CHM-Archives
|
||||||
|
/// with library mspack written by Stuart Caie
|
||||||
|
/// http://www.kyz.uklinux.net/libmspack/
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
class wxChmTools
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// constructor
|
||||||
|
wxChmTools(const wxFileName &archive);
|
||||||
|
/// destructor
|
||||||
|
~wxChmTools();
|
||||||
|
|
||||||
|
/// Generate error-string for error-code
|
||||||
|
static const wxString ChmErrorMsg(int error);
|
||||||
|
|
||||||
|
/// get an array of archive-member-filenames
|
||||||
|
const wxArrayString *GetFileNames()
|
||||||
|
{
|
||||||
|
return m_fileNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// get the name of the archive representated by this class
|
||||||
|
const wxString GetArchiveName()
|
||||||
|
{
|
||||||
|
return m_chmFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Find a file in the archive
|
||||||
|
const wxString Find(const wxString& pattern,
|
||||||
|
const wxString& startfrom = wxEmptyString);
|
||||||
|
|
||||||
|
/// Extract a file in the archive into a file
|
||||||
|
size_t Extract(const wxString& pattern, const wxString& filename);
|
||||||
|
|
||||||
|
/// check archive for a file
|
||||||
|
bool Contains(const wxString& pattern);
|
||||||
|
|
||||||
|
/// get a string for the last error occured
|
||||||
|
const wxString GetLastErrorMessage();
|
||||||
|
|
||||||
|
/// Last Error
|
||||||
|
int m_lasterror;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// these vars are used by FindFirst/Next:
|
||||||
|
wxString m_chmFileName;
|
||||||
|
char *m_chmFileNameANSI;
|
||||||
|
|
||||||
|
/// mspack-pointer to mschmd_header
|
||||||
|
struct mschmd_header *m_archive;
|
||||||
|
/// mspack-pointer to mschm_decompressor
|
||||||
|
struct mschm_decompressor *m_decompressor;
|
||||||
|
|
||||||
|
/// Array of filenames in archive
|
||||||
|
wxArrayString * m_fileNames;
|
||||||
|
|
||||||
|
/// Internal function to get filepointer
|
||||||
|
struct mschmd_file *GetMschmdFile(const wxString& pattern);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* constructor
|
||||||
|
*
|
||||||
|
* @param archive The filename of the archive to open
|
||||||
|
*/
|
||||||
|
wxChmTools::wxChmTools(const wxFileName &archive)
|
||||||
|
{
|
||||||
|
m_chmFileName = archive.GetFullPath();
|
||||||
|
|
||||||
|
wxASSERT_MSG( !m_chmFileName.empty(), _T("empty archive name") );
|
||||||
|
|
||||||
|
m_archive = NULL;
|
||||||
|
m_decompressor = NULL;
|
||||||
|
m_fileNames = NULL;
|
||||||
|
m_lasterror = 0;
|
||||||
|
|
||||||
|
struct mschmd_header *chmh;
|
||||||
|
struct mschm_decompressor *chmd;
|
||||||
|
struct mschmd_file *file;
|
||||||
|
|
||||||
|
// Create decompressor
|
||||||
|
chmd = mspack_create_chm_decompressor(NULL);
|
||||||
|
m_decompressor = (struct mschm_decompressor *) chmd;
|
||||||
|
|
||||||
|
// NB: we must make a copy of the string because chmd->open won't call
|
||||||
|
// strdup() [libmspack-20030726], which would cause crashes in
|
||||||
|
// Unicode build when mb_str() returns temporary buffer
|
||||||
|
m_chmFileNameANSI = strdup((const char*)m_chmFileName.mb_str(wxConvFile));
|
||||||
|
|
||||||
|
// Open the archive and store it in class:
|
||||||
|
if ( (chmh = chmd->open(chmd, (char*)m_chmFileNameANSI)) )
|
||||||
|
{
|
||||||
|
m_archive = chmh;
|
||||||
|
|
||||||
|
// Create Filenamearray
|
||||||
|
m_fileNames = new wxArrayString;
|
||||||
|
|
||||||
|
// Store Filenames in array
|
||||||
|
for (file = chmh->files; file; file = file->next)
|
||||||
|
{
|
||||||
|
m_fileNames->Add(wxString::FromAscii(file->filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogError(_("Failed to open CHM archive '%s'."),
|
||||||
|
archive.GetFullPath().c_str());
|
||||||
|
m_lasterror = (chmd->last_error(chmd));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
wxChmTools::~wxChmTools()
|
||||||
|
{
|
||||||
|
struct mschm_decompressor *chmd = m_decompressor;
|
||||||
|
struct mschmd_header *chmh = m_archive;
|
||||||
|
|
||||||
|
delete m_fileNames;
|
||||||
|
|
||||||
|
// Close Archive
|
||||||
|
if (chmh && chmd)
|
||||||
|
chmd->close(chmd, chmh);
|
||||||
|
|
||||||
|
free(m_chmFileNameANSI);
|
||||||
|
|
||||||
|
// Destroy Decompressor
|
||||||
|
if (chmd)
|
||||||
|
mspack_destroy_chm_decompressor(chmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given pattern matches to any
|
||||||
|
* filename stored in archive
|
||||||
|
*
|
||||||
|
* @param pattern The filename pattern, may include '*' and/or '?'
|
||||||
|
* @return true, if any file matching pattern has been found,
|
||||||
|
* false if not
|
||||||
|
*/
|
||||||
|
bool wxChmTools::Contains(const wxString& pattern)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
wxString pattern_tmp = wxString(pattern).MakeLower();
|
||||||
|
|
||||||
|
// loop through filearay
|
||||||
|
if ( m_fileNames && (count = m_fileNames->GetCount()) > 0 )
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
wxString tmp = m_fileNames->Item(i).MakeLower();
|
||||||
|
if ( tmp.Matches(pattern_tmp) || tmp.Mid(1).Matches(pattern_tmp))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find()
|
||||||
|
*
|
||||||
|
* Finds the next file descibed by a pattern in the archive, starting
|
||||||
|
* the file given by second parameter
|
||||||
|
*
|
||||||
|
* @param pattern The file-pattern to search for. May contain '*' and/or '?'
|
||||||
|
* @param startfrom The filename which the search should start after
|
||||||
|
* @returns The full pathname of the found file
|
||||||
|
*/
|
||||||
|
const wxString wxChmTools::Find(const wxString& pattern,
|
||||||
|
const wxString& startfrom)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
wxString tmp;
|
||||||
|
wxString pattern_tmp(pattern);
|
||||||
|
wxString startfrom_tmp(startfrom);
|
||||||
|
pattern_tmp.MakeLower();
|
||||||
|
startfrom_tmp.MakeLower();
|
||||||
|
|
||||||
|
if ( m_fileNames && (count = m_fileNames->GetCount()) > 0 )
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
tmp = m_fileNames->Item(i).MakeLower();
|
||||||
|
// if we find the string where the search should began
|
||||||
|
if ( tmp.Matches(startfrom_tmp) ||
|
||||||
|
tmp.Mid(1).Matches(startfrom_tmp) )
|
||||||
|
continue;
|
||||||
|
if ( tmp.Matches(pattern_tmp) ||
|
||||||
|
tmp.Mid(1).Matches(pattern_tmp) )
|
||||||
|
{
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract ()
|
||||||
|
*
|
||||||
|
* extracts the first hit of pattern to the given position
|
||||||
|
*
|
||||||
|
* @param pattern A filename pattern (may contain * and ? chars)
|
||||||
|
* @param filename The FileName where to temporary extract the file to
|
||||||
|
* @return 0 at no file extracted<br>
|
||||||
|
* number of bytes extracted else
|
||||||
|
*/
|
||||||
|
size_t wxChmTools::Extract(const wxString& pattern, const wxString& filename)
|
||||||
|
{
|
||||||
|
struct mschm_decompressor *d = m_decompressor;
|
||||||
|
struct mschmd_header *h = m_archive;
|
||||||
|
struct mschmd_file *f;
|
||||||
|
|
||||||
|
wxString tmp;
|
||||||
|
wxString pattern_tmp = (wxString(pattern)).MakeLower();
|
||||||
|
|
||||||
|
for (f = h->files; f; f = f->next)
|
||||||
|
{
|
||||||
|
tmp = wxString::FromAscii(f->filename).MakeLower();
|
||||||
|
if ( tmp.Matches(pattern_tmp) ||
|
||||||
|
tmp.Mid(1).Matches(pattern_tmp) )
|
||||||
|
{
|
||||||
|
// ignore leading '/'
|
||||||
|
if (d->extract(d, f,
|
||||||
|
(char*)(const char*)filename.mb_str(wxConvFile)))
|
||||||
|
{
|
||||||
|
// Error
|
||||||
|
m_lasterror = d->last_error(d);
|
||||||
|
wxLogError(_("Could not extract %s into %s: %s"),
|
||||||
|
wxString::FromAscii(f->filename).c_str(),
|
||||||
|
filename.c_str(),
|
||||||
|
ChmErrorMsg(m_lasterror).c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (size_t) f->length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a file by pattern
|
||||||
|
*
|
||||||
|
* @param pattern A filename pattern (may contain * and ? chars)
|
||||||
|
* @return A pointer to the file (mschmd_file*)
|
||||||
|
*/
|
||||||
|
struct mschmd_file *wxChmTools::GetMschmdFile(const wxString& pattern_orig)
|
||||||
|
{
|
||||||
|
struct mschmd_file *f;
|
||||||
|
struct mschmd_header *h = (struct mschmd_header *) m_archive;
|
||||||
|
wxString tmp;
|
||||||
|
wxString pattern = wxString(pattern_orig).MakeLower();
|
||||||
|
|
||||||
|
for (f = h->files; f; f = f->next)
|
||||||
|
{
|
||||||
|
tmp = wxString::FromAscii(f->filename).MakeLower();
|
||||||
|
if ( tmp.Matches(pattern) || tmp.Mid(1).Matches(pattern) )
|
||||||
|
{
|
||||||
|
// ignore leading '/'
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString wxChmTools::GetLastErrorMessage()
|
||||||
|
{
|
||||||
|
return ChmErrorMsg(m_lasterror);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString wxChmTools::ChmErrorMsg(int error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case MSPACK_ERR_OK:
|
||||||
|
return _("no error");
|
||||||
|
case MSPACK_ERR_ARGS:
|
||||||
|
return _("bad arguments to library function");
|
||||||
|
case MSPACK_ERR_OPEN:
|
||||||
|
return _("error opening file");
|
||||||
|
case MSPACK_ERR_READ:
|
||||||
|
return _("read error");
|
||||||
|
case MSPACK_ERR_WRITE:
|
||||||
|
return _("write error");
|
||||||
|
case MSPACK_ERR_SEEK:
|
||||||
|
return _("seek error");
|
||||||
|
case MSPACK_ERR_NOMEMORY:
|
||||||
|
return _("out of memory");
|
||||||
|
case MSPACK_ERR_SIGNATURE:
|
||||||
|
return _("bad signature");
|
||||||
|
case MSPACK_ERR_DATAFORMAT:
|
||||||
|
return _("error in data format");
|
||||||
|
case MSPACK_ERR_CHECKSUM:
|
||||||
|
return _("checksum error");
|
||||||
|
case MSPACK_ERR_CRUNCH:
|
||||||
|
return _("compression error");
|
||||||
|
case MSPACK_ERR_DECRUNCH:
|
||||||
|
return _("decompression error");
|
||||||
|
}
|
||||||
|
return _("unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/// wxChmInputStream
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxChmInputStream : public wxInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
wxChmInputStream(const wxString& archive,
|
||||||
|
const wxString& file, bool simulate = false);
|
||||||
|
/// Destructor
|
||||||
|
~wxChmInputStream();
|
||||||
|
|
||||||
|
/// Return the size of the accessed file in archive
|
||||||
|
virtual size_t GetSize() const { return m_size; }
|
||||||
|
/// End of Stream?
|
||||||
|
virtual bool Eof() const;
|
||||||
|
/// Set simulation-mode of HHP-File (if non is found)
|
||||||
|
void SimulateHHP(bool sim) { m_simulateHHP = sim; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// See wxInputStream
|
||||||
|
virtual size_t OnSysRead(void *buffer, size_t bufsize);
|
||||||
|
/// See wxInputStream
|
||||||
|
virtual off_t OnSysSeek(off_t seek, wxSeekMode mode);
|
||||||
|
/// See wxInputStream
|
||||||
|
virtual off_t OnSysTell() const { return m_pos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_size;
|
||||||
|
off_t m_pos;
|
||||||
|
bool m_simulateHHP;
|
||||||
|
|
||||||
|
char * m_content;
|
||||||
|
wxInputStream * m_contentStream;
|
||||||
|
|
||||||
|
void CreateHHPStream();
|
||||||
|
bool CreateFileStream(const wxString& pattern);
|
||||||
|
// this void* is handle of archive . I'm sorry it is void and not proper
|
||||||
|
// type but I don't want to make unzip.h header public.
|
||||||
|
|
||||||
|
|
||||||
|
// locates the file and returns a mspack_file *
|
||||||
|
mspack_file *LocateFile(wxString filename);
|
||||||
|
|
||||||
|
// should store pointer to current file
|
||||||
|
mspack_file *m_file;
|
||||||
|
|
||||||
|
// The Chm-Class for extracting the data
|
||||||
|
wxChmTools *m_chm;
|
||||||
|
|
||||||
|
wxString m_fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param archive The name of the .chm archive. Remember that archive must
|
||||||
|
* be local file accesible via fopen, fread functions!
|
||||||
|
* @param filename The Name of the file to be extracted from archive
|
||||||
|
* @param simulate if true than class should simulate .HHP-File based on #SYSTEM
|
||||||
|
* if false than class does nothing if it doesnt find .hhp
|
||||||
|
*/
|
||||||
|
wxChmInputStream::wxChmInputStream(const wxString& archive,
|
||||||
|
const wxString& filename, bool simulate)
|
||||||
|
: wxInputStream()
|
||||||
|
{
|
||||||
|
m_pos = 0;
|
||||||
|
m_size = 0;
|
||||||
|
m_content = NULL;
|
||||||
|
m_contentStream = NULL;
|
||||||
|
m_lasterror = wxSTREAM_NO_ERROR;
|
||||||
|
m_chm = new wxChmTools (wxFileName(archive));
|
||||||
|
m_file = NULL;
|
||||||
|
m_fileName = wxString(filename).MakeLower();
|
||||||
|
m_simulateHHP = simulate;
|
||||||
|
|
||||||
|
if ( !m_chm->Contains(m_fileName) )
|
||||||
|
{
|
||||||
|
// if the file could not be located, but was *.hhp, than we create
|
||||||
|
// the content of the hhp-file on the fly and store it for reading
|
||||||
|
// by the application
|
||||||
|
if ( m_fileName.Find(_T(".hhp")) != wxNOT_FOUND && m_simulateHHP )
|
||||||
|
{
|
||||||
|
// now we open an hhp-file
|
||||||
|
CreateHHPStream();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogError(_("Could not locate file '%s'."), filename.c_str());
|
||||||
|
m_lasterror = wxSTREAM_READ_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // file found
|
||||||
|
CreateFileStream(m_fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxChmInputStream::~wxChmInputStream()
|
||||||
|
{
|
||||||
|
delete m_chm;
|
||||||
|
|
||||||
|
delete m_contentStream;
|
||||||
|
|
||||||
|
if (m_content)
|
||||||
|
{
|
||||||
|
free (m_content);
|
||||||
|
m_content=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxChmInputStream::Eof() const
|
||||||
|
{
|
||||||
|
return (m_content==NULL ||
|
||||||
|
m_contentStream==NULL ||
|
||||||
|
m_contentStream->Eof() ||
|
||||||
|
m_pos>m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t wxChmInputStream::OnSysRead(void *buffer, size_t bufsize)
|
||||||
|
{
|
||||||
|
if ( m_pos >= m_size )
|
||||||
|
{
|
||||||
|
m_lasterror = wxSTREAM_EOF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m_lasterror = wxSTREAM_NO_ERROR;
|
||||||
|
|
||||||
|
// If the rest to read from the stream is less
|
||||||
|
// than the buffer size, than only read the rest
|
||||||
|
if ( m_pos + bufsize > m_size )
|
||||||
|
bufsize = m_size - m_pos;
|
||||||
|
|
||||||
|
m_contentStream->SeekI(m_pos);
|
||||||
|
m_contentStream->Read(buffer, bufsize);
|
||||||
|
m_pos +=bufsize;
|
||||||
|
m_contentStream->SeekI(m_pos);
|
||||||
|
return bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
off_t wxChmInputStream::OnSysSeek(off_t seek, wxSeekMode mode)
|
||||||
|
{
|
||||||
|
wxString mode_str = wxEmptyString;
|
||||||
|
|
||||||
|
if ( !m_contentStream || m_contentStream->Eof() )
|
||||||
|
{
|
||||||
|
m_lasterror = wxSTREAM_EOF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m_lasterror = wxSTREAM_NO_ERROR;
|
||||||
|
|
||||||
|
off_t nextpos;
|
||||||
|
|
||||||
|
switch ( mode )
|
||||||
|
{
|
||||||
|
case wxFromCurrent:
|
||||||
|
nextpos = seek + m_pos;
|
||||||
|
break;
|
||||||
|
case wxFromStart:
|
||||||
|
nextpos = seek;
|
||||||
|
break;
|
||||||
|
case wxFromEnd:
|
||||||
|
nextpos = m_size - 1 + seek;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nextpos = m_pos;
|
||||||
|
break; /* just to fool compiler, never happens */
|
||||||
|
}
|
||||||
|
m_pos=nextpos;
|
||||||
|
|
||||||
|
// Set current position on stream
|
||||||
|
m_contentStream->SeekI(m_pos);
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help Browser tries to read the contents of the
|
||||||
|
* file by interpreting a .hhp file in the Archiv.
|
||||||
|
* For .chm doesnt include such a file, we need
|
||||||
|
* to rebuild the information based on stored
|
||||||
|
* system-files.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wxChmInputStream::CreateHHPStream()
|
||||||
|
{
|
||||||
|
wxFileName file;
|
||||||
|
bool topic = false;
|
||||||
|
bool hhc = false;
|
||||||
|
bool hhk = false;
|
||||||
|
wxInputStream *i;
|
||||||
|
wxMemoryOutputStream *out;
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
|
// Try to open the #SYSTEM-File and create the HHP File out of it
|
||||||
|
// see http://bonedaddy.net/pabs3/chmspec/0.1/ch05s03.html#SYSTEM
|
||||||
|
if ( ! m_chm->Contains(_("/#SYSTEM")) )
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
wxLogDebug("Archive doesnt contain #SYSTEM file");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = wxFileName(_T("/#SYSTEM"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( CreateFileStream(_T("/#SYSTEM")) )
|
||||||
|
{
|
||||||
|
// New stream for writing a memory area to simulate the
|
||||||
|
// .hhp-file
|
||||||
|
out = new wxMemoryOutputStream();
|
||||||
|
|
||||||
|
tmp = "[OPTIONS]\r\n";
|
||||||
|
out->Write((const void *) tmp, strlen(tmp));
|
||||||
|
|
||||||
|
wxUint16 code;
|
||||||
|
wxUint16 len;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
|
// use the actual stream for reading
|
||||||
|
i = m_contentStream;
|
||||||
|
|
||||||
|
/* Now read the contents, and try to get the needed information */
|
||||||
|
|
||||||
|
// First 4 Bytes are Version information, skip
|
||||||
|
i->SeekI(4);
|
||||||
|
|
||||||
|
while (!i->Eof())
|
||||||
|
{
|
||||||
|
// Read #SYSTEM-Code and length
|
||||||
|
i->Read(&code, 2);
|
||||||
|
i->Read(&len, 2);
|
||||||
|
// data
|
||||||
|
buf = malloc(len);
|
||||||
|
i->Read(buf, len);
|
||||||
|
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case 0: // CONTENTS_FILE
|
||||||
|
tmp = "Contents file=";
|
||||||
|
hhc=true;
|
||||||
|
break;
|
||||||
|
case 1: // INDEX_FILE
|
||||||
|
tmp = "Index file=";
|
||||||
|
hhk = true;
|
||||||
|
break;
|
||||||
|
case 2: // DEFAULT_TOPIC
|
||||||
|
tmp = "Default Topic=";
|
||||||
|
topic = true;
|
||||||
|
break;
|
||||||
|
case 3: // TITLE
|
||||||
|
tmp = "Title=";
|
||||||
|
break;
|
||||||
|
// case 6: // COMPILED_FILE
|
||||||
|
// tmp = "Compiled File=";
|
||||||
|
// break;
|
||||||
|
case 7: // COMPILED_FILE
|
||||||
|
tmp = "Binary Index=YES\r\n";
|
||||||
|
out->Write( (const void *) tmp, strlen(tmp));
|
||||||
|
tmp = NULL;
|
||||||
|
break;
|
||||||
|
case 4: // STRUCT
|
||||||
|
default:
|
||||||
|
tmp=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp)
|
||||||
|
{
|
||||||
|
out->Write((const void *) tmp, strlen(tmp));
|
||||||
|
out->Write(buf, strlen((char*)buf));
|
||||||
|
out->Write("\r\n", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
buf=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Free the old data which wont be used any more
|
||||||
|
delete m_contentStream;
|
||||||
|
if (m_content)
|
||||||
|
free (m_content);
|
||||||
|
|
||||||
|
// Now add entries which are missing
|
||||||
|
if ( !hhc && m_chm->Contains(_T("*.hhc")) )
|
||||||
|
{
|
||||||
|
tmp = "Contents File=*.hhc\r\n";
|
||||||
|
out->Write((const void *) tmp, strlen(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !hhk && m_chm->Contains(_T("*.hhk")) )
|
||||||
|
{
|
||||||
|
tmp = "Index File=*.hhk\r\n";
|
||||||
|
out->Write((const void *) tmp, strlen(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now copy the Data from the memory
|
||||||
|
out->SeekO(0, wxFromEnd);
|
||||||
|
m_size = out->TellO();
|
||||||
|
out->SeekO(0, wxFromStart);
|
||||||
|
m_content = (char *) malloc (m_size+1);
|
||||||
|
out->CopyTo(m_content, m_size);
|
||||||
|
m_content[m_size]='\0';
|
||||||
|
m_size++;
|
||||||
|
m_contentStream = new wxMemoryInputStream(m_content, m_size);
|
||||||
|
|
||||||
|
delete out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Stream pointing to a virtual file in
|
||||||
|
* the current archive
|
||||||
|
*/
|
||||||
|
bool wxChmInputStream::CreateFileStream(const wxString& pattern)
|
||||||
|
{
|
||||||
|
wxFileInputStream * fin;
|
||||||
|
wxString tmpfile = wxFileName::CreateTempFileName(_T("chmstrm"), NULL);
|
||||||
|
|
||||||
|
if ( tmpfile.empty() )
|
||||||
|
{
|
||||||
|
wxLogError(_("Could not create temporary file '%s'"), tmpfile.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to extract the file
|
||||||
|
if ( m_chm->Extract(pattern, tmpfile) <= 0 )
|
||||||
|
{
|
||||||
|
wxLogError(_("Extraction of '%s' into '%s' failed."),
|
||||||
|
pattern.c_str(), tmpfile.c_str());
|
||||||
|
if ( wxFileExists(tmpfile) )
|
||||||
|
wxRemoveFile(tmpfile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Open a filestream to extracted file
|
||||||
|
fin = new wxFileInputStream(tmpfile);
|
||||||
|
m_size = fin->GetSize();
|
||||||
|
m_content = (char *) malloc(m_size+1);
|
||||||
|
fin->Read(m_content, m_size);
|
||||||
|
m_content[m_size]='\0';
|
||||||
|
|
||||||
|
wxRemoveFile(tmpfile);
|
||||||
|
|
||||||
|
delete fin;
|
||||||
|
|
||||||
|
m_contentStream = new wxMemoryInputStream (m_content, m_size);
|
||||||
|
|
||||||
|
return m_contentStream->IsOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxChmFSHandler
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxChmFSHandler : public wxFileSystemHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor and Destructor
|
||||||
|
wxChmFSHandler();
|
||||||
|
~wxChmFSHandler();
|
||||||
|
|
||||||
|
/// Is able to open location?
|
||||||
|
virtual bool CanOpen(const wxString& location);
|
||||||
|
/// Open a file
|
||||||
|
virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
|
||||||
|
/// Find first occurence of spec
|
||||||
|
virtual wxString FindFirst(const wxString& spec, int flags = 0);
|
||||||
|
/// Find next occurence of spec
|
||||||
|
virtual wxString FindNext();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_lasterror;
|
||||||
|
wxString m_pattern;
|
||||||
|
wxString m_found;
|
||||||
|
wxChmTools * m_chm;
|
||||||
|
};
|
||||||
|
|
||||||
|
wxChmFSHandler::wxChmFSHandler() : wxFileSystemHandler()
|
||||||
|
{
|
||||||
|
m_lasterror=0;
|
||||||
|
m_pattern=wxEmptyString;
|
||||||
|
m_found=wxEmptyString;
|
||||||
|
m_chm=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxChmFSHandler::~wxChmFSHandler()
|
||||||
|
{
|
||||||
|
if (m_chm)
|
||||||
|
delete m_chm;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxChmFSHandler::CanOpen(const wxString& location)
|
||||||
|
{
|
||||||
|
wxString p = GetProtocol(location);
|
||||||
|
return (p == _T("chm")) &&
|
||||||
|
(GetProtocol(GetLeftLocation(location)) == _T("file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFSFile* wxChmFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs),
|
||||||
|
const wxString& location)
|
||||||
|
{
|
||||||
|
wxString right = GetRightLocation(location);
|
||||||
|
wxString left = GetLeftLocation(location);
|
||||||
|
|
||||||
|
wxInputStream *s;
|
||||||
|
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if ( GetProtocol(left) != _T("file") )
|
||||||
|
{
|
||||||
|
wxLogError(_("CHM handler currently supports only local files!"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Work around javascript
|
||||||
|
wxString tmp = wxString(right);
|
||||||
|
if ( tmp.MakeLower().Contains(_T("javascipt")) && tmp.Contains(_T("\'")) )
|
||||||
|
{
|
||||||
|
right = right.AfterFirst(_T('\'')).BeforeLast(_T('\''));
|
||||||
|
}
|
||||||
|
|
||||||
|
// now work on the right location
|
||||||
|
if (right.Contains(_T("..")))
|
||||||
|
{
|
||||||
|
wxFileName abs(right);
|
||||||
|
abs.MakeAbsolute(_T("/"));
|
||||||
|
right = abs.GetFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// a workaround for absolute links to root
|
||||||
|
if ( (index=right.Index(_T("//"))) != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
right=wxString(right.Mid(index+1));
|
||||||
|
wxLogWarning(_("Link contained '//', converted to absolute link."));
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFileName leftFilename = wxFileSystem::URLToFileName(left);
|
||||||
|
|
||||||
|
// Open a stream to read the content of the chm-file
|
||||||
|
s = new wxChmInputStream(leftFilename.GetFullPath(), right, true);
|
||||||
|
|
||||||
|
wxString mime = GetMimeTypeFromExt(location);
|
||||||
|
|
||||||
|
if ( s )
|
||||||
|
{
|
||||||
|
return new wxFSFile(s,
|
||||||
|
left + _T("#chm:") + right,
|
||||||
|
mime,
|
||||||
|
GetAnchor(location),
|
||||||
|
wxDateTime(wxFileModificationTime(left)));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete s;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Doku see wxFileSystemHandler
|
||||||
|
*/
|
||||||
|
wxString wxChmFSHandler::FindFirst(const wxString& spec, int flags)
|
||||||
|
{
|
||||||
|
wxString right = GetRightLocation(spec);
|
||||||
|
wxString left = GetLeftLocation(spec);
|
||||||
|
wxString nativename = wxFileSystem::URLToFileName(left).GetFullPath();
|
||||||
|
|
||||||
|
if ( GetProtocol(left) != _T("file") )
|
||||||
|
{
|
||||||
|
wxLogError(_("CHM handler currently supports only local files!"));
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_chm = new wxChmTools(wxFileName(nativename));
|
||||||
|
m_pattern = right.AfterLast(_T('/'));
|
||||||
|
|
||||||
|
wxString m_found = m_chm->Find(m_pattern);
|
||||||
|
|
||||||
|
// now fake around hhp-files which are not existing in projects...
|
||||||
|
if (m_found.empty() &&
|
||||||
|
m_pattern.Contains(_T(".hhp")) &&
|
||||||
|
!m_pattern.Contains(_T(".hhp.cached")))
|
||||||
|
{
|
||||||
|
m_found.Printf(_T("%s#chm:%s.hhp"),
|
||||||
|
left.c_str(), m_pattern.BeforeLast(_T('.')).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_found;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wxString wxChmFSHandler::FindNext()
|
||||||
|
{
|
||||||
|
if (m_pattern.empty())
|
||||||
|
return wxEmptyString;
|
||||||
|
else
|
||||||
|
return m_chm->Find(m_pattern, m_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// wxModule to register CHM handler
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class wxChmSupportModule : public wxModule
|
||||||
|
{
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxChmSupportModule)
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool OnInit()
|
||||||
|
{
|
||||||
|
wxFileSystem::AddHandler(new wxChmFSHandler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual void OnExit() {}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxChmSupportModule, wxModule)
|
||||||
|
|
||||||
|
#endif // wxUSE_LIBMSPACK
|
@@ -38,6 +38,12 @@
|
|||||||
#if wxUSE_HELP
|
#if wxUSE_HELP
|
||||||
#include "wx/tipwin.h"
|
#include "wx/tipwin.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
#include "wx/html/forcelnk.h"
|
||||||
|
FORCE_LINK(wxhtml_chm_support)
|
||||||
|
#endif
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxHelpControllerBase)
|
IMPLEMENT_DYNAMIC_CLASS(wxHtmlHelpController, wxHelpControllerBase)
|
||||||
|
|
||||||
@@ -187,10 +193,15 @@ bool wxHtmlHelpController::Initialize(const wxString& file)
|
|||||||
{
|
{
|
||||||
actualFilename = dir + filename + wxString(wxT(".hhp"));
|
actualFilename = dir + filename + wxString(wxT(".hhp"));
|
||||||
if (!wxFileExists(actualFilename))
|
if (!wxFileExists(actualFilename))
|
||||||
return FALSE;
|
{
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
actualFilename = dir + filename + wxString(wxT(".chm"));
|
||||||
|
if (!wxFileExists(actualFilename))
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddBook(wxFileName(actualFilename));
|
return AddBook(wxFileName(actualFilename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -570,14 +570,24 @@ bool wxHtmlHelpData::AddBookParam(const wxFSFile& bookfile,
|
|||||||
|
|
||||||
bool wxHtmlHelpData::AddBook(const wxString& book)
|
bool wxHtmlHelpData::AddBook(const wxString& book)
|
||||||
{
|
{
|
||||||
if (book.Right(4).Lower() == wxT(".zip") ||
|
wxString extension(book.Right(4).Lower());
|
||||||
book.Right(4).Lower() == wxT(".htb") /*html book*/)
|
if (extension == wxT(".zip") ||
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
extension == wxT(".chm") /*compressed html help book*/ ||
|
||||||
|
#endif
|
||||||
|
extension == wxT(".htb") /*html book*/)
|
||||||
{
|
{
|
||||||
wxFileSystem fsys;
|
wxFileSystem fsys;
|
||||||
wxString s;
|
wxString s;
|
||||||
bool rt = FALSE;
|
bool rt = FALSE;
|
||||||
|
|
||||||
s = fsys.FindFirst(book + wxT("#zip:") + wxT("*.hhp"), wxFILE);
|
#if wxUSE_LIBMSPACK
|
||||||
|
if (extension == wxT(".chm"))
|
||||||
|
s = fsys.FindFirst(book + wxT("#chm:*.hhp"), wxFILE);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
s = fsys.FindFirst(book + wxT("#zip:*.hhp"), wxFILE);
|
||||||
|
|
||||||
while (!s.IsEmpty())
|
while (!s.IsEmpty())
|
||||||
{
|
{
|
||||||
if (AddBook(s)) rt = TRUE;
|
if (AddBook(s)) rt = TRUE;
|
||||||
|
@@ -1389,22 +1389,29 @@ void wxHtmlHelpFrame::OnToolbar(wxCommandEvent& event)
|
|||||||
|
|
||||||
case wxID_HTML_OPENFILE :
|
case wxID_HTML_OPENFILE :
|
||||||
{
|
{
|
||||||
|
wxString filemask = wxString(
|
||||||
|
_("HTML files (*.html;*.htm)|*.html;*.htm|")) +
|
||||||
|
_("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|") +
|
||||||
|
_("HTML Help Project (*.hhp)|*.hhp|") +
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
_("Compressed HTML Help file (*.chm)|*.chm|") +
|
||||||
|
#endif
|
||||||
|
_("All files (*.*)|*");
|
||||||
wxString s = wxFileSelector(_("Open HTML document"),
|
wxString s = wxFileSelector(_("Open HTML document"),
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
_(
|
filemask,
|
||||||
"HTML files (*.htm)|*.htm|HTML files (*.html)|*.html|\
|
|
||||||
Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
|
|
||||||
HTML Help Project (*.hhp)|*.hhp|\
|
|
||||||
All files (*.*)|*"
|
|
||||||
),
|
|
||||||
wxOPEN | wxFILE_MUST_EXIST,
|
wxOPEN | wxFILE_MUST_EXIST,
|
||||||
this);
|
this);
|
||||||
if (!s.IsEmpty())
|
if (!s.IsEmpty())
|
||||||
{
|
{
|
||||||
wxString ext = s.Right(4).Lower();
|
wxString ext = s.Right(4).Lower();
|
||||||
if (ext == _T(".zip") || ext == _T(".htb") || ext == _T(".hhp"))
|
if (ext == _T(".zip") || ext == _T(".htb") ||
|
||||||
|
#if wxUSE_LIBMSPACK
|
||||||
|
ext == _T(".chm") ||
|
||||||
|
#endif
|
||||||
|
ext == _T(".hhp"))
|
||||||
{
|
{
|
||||||
wxBusyCursor bcur;
|
wxBusyCursor bcur;
|
||||||
m_Data->AddBook(s);
|
m_Data->AddBook(s);
|
||||||
|
@@ -64,6 +64,7 @@ CORE_GUI_LIBS="@CORE_GUI_LIBS@"
|
|||||||
ldlibs_base="@WXCONFIG_EXTRALIBS@"
|
ldlibs_base="@WXCONFIG_EXTRALIBS@"
|
||||||
ldlibs_core="@EXTRALIBS_GUI@"
|
ldlibs_core="@EXTRALIBS_GUI@"
|
||||||
ldlibs_xml="@EXTRALIBS_XML@"
|
ldlibs_xml="@EXTRALIBS_XML@"
|
||||||
|
ldlibs_html="@EXTRALIBS_HTML@"
|
||||||
ldlibs_odbc="@EXTRALIBS_ODBC@"
|
ldlibs_odbc="@EXTRALIBS_ODBC@"
|
||||||
|
|
||||||
ldflags_gl="@LDFLAGS_GL@"
|
ldflags_gl="@LDFLAGS_GL@"
|
||||||
|
Reference in New Issue
Block a user