Do prevent the app from exiting when the help frame is shown in the special case of the help viewer application where the default behaviour of exiting the application when only the help window remains open is inappropriate and results in unexpected program exit if we open and then close any dialog, e.g. from the help frame toolbar. Even though the previous commit actually already fixed the problem in the current code, still apply this fix as well, just in case we can (or could, in the future) should any dialogs with NULL parent in this program. Closes #15880. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75634 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
497 lines
14 KiB
C++
497 lines
14 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: helpview.h
|
|
// Purpose: HelpView application
|
|
// A standalone viewer for wxHTML Help (.htb) files
|
|
// Author: Vaclav Slavik, Julian Smart
|
|
// Modified by:
|
|
// Created: 2002-07-09
|
|
// Copyright: (c) 2002 Vaclav Slavik, Julian Smart and others
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx/wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
// for all others, include the necessary headers (this file is usually all you
|
|
// need because it includes almost all "standard" wxWidgets headers
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/filename.h"
|
|
#include "wx/image.h"
|
|
#include "wx/wxhtml.h"
|
|
#include "wx/fs_zip.h"
|
|
#include "wx/log.h"
|
|
#include "wx/artprov.h"
|
|
#include "wx/filedlg.h"
|
|
|
|
#include "helpview.h"
|
|
|
|
class AlternateArtProvider : public wxArtProvider
|
|
{
|
|
protected:
|
|
virtual wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client,
|
|
const wxSize& size);
|
|
};
|
|
|
|
IMPLEMENT_APP(hvApp)
|
|
|
|
hvApp::hvApp()
|
|
{
|
|
#if wxUSE_IPC
|
|
m_server = NULL;
|
|
#endif
|
|
}
|
|
|
|
bool hvApp::OnInit()
|
|
{
|
|
#ifdef __WXMOTIF__
|
|
delete wxLog::SetActiveTarget(new wxLogStderr); // So dialog boxes aren't used
|
|
#endif
|
|
|
|
wxArtProvider::Push(new AlternateArtProvider);
|
|
|
|
#if defined( __WXOSX_MAC__ ) && wxOSX_USE_CARBON
|
|
wxApp::s_macAboutMenuItemId = wxID_ABOUT;
|
|
wxFileName::MacRegisterDefaultTypeAndCreator( wxT("htb") , 'HTBD' , 'HTBA' ) ;
|
|
#endif
|
|
|
|
int istyle = wxHF_DEFAULT_STYLE;
|
|
|
|
wxString service, windowName, titleFormat, argStr;
|
|
wxString book[10];
|
|
int bookCount = 0;
|
|
int i;
|
|
bool hasService = false;
|
|
bool hasWindowName = false;
|
|
bool createServer = false;
|
|
|
|
#if wxUSE_IPC
|
|
m_server = NULL;
|
|
#endif
|
|
|
|
// Help books are recognized by extension ".hhp" ".htb" or ".zip".
|
|
// Service and window_name can occur anywhere in arguments,
|
|
// but service must be first
|
|
// Other arguments (topic?) could be added
|
|
|
|
// modes of operation:
|
|
// 1) no arguments - stand alone, prompt user for book
|
|
// 2) books only - stand alone, open books
|
|
// 3) "--server" as (any) arg - start connection with default service;
|
|
// also open any books passed as other arguments
|
|
// 4) at least one argument which is not book, and not "--server" - take first
|
|
// such argument as service, second (if present) as window name,
|
|
// start service, open any books
|
|
|
|
for( i=1; i<argc; i++ )
|
|
{
|
|
argStr = argv[i];
|
|
|
|
if ( argStr.Find( wxT(".hhp") ) >= 0
|
|
|| argStr.Find( wxT(".htb") ) >= 0
|
|
|| argStr.Find( wxT(".zip") ) >= 0 )
|
|
{
|
|
book[bookCount] = argStr;
|
|
bookCount++;
|
|
}
|
|
else if ( argStr == wxT("--server") )
|
|
{
|
|
createServer = true;
|
|
#if defined(__WXMSW__)
|
|
service = wxT("generic_helpservice");
|
|
#elif defined(__UNIX__)
|
|
service = wxT("/tmp/") + wxString(wxT("generic_helpservice"));
|
|
#else
|
|
service = wxT("4242");
|
|
#endif
|
|
}
|
|
else if ( !hasService )
|
|
{
|
|
service = argStr;
|
|
hasService = true;
|
|
createServer = true;
|
|
}
|
|
else if ( !hasWindowName )
|
|
{
|
|
windowName = argStr;
|
|
hasWindowName = true;
|
|
}
|
|
else if ( argStr.Find( wxT("--Style") ) >= 0 )
|
|
{
|
|
long i;
|
|
wxString numb = argStr.AfterLast(wxT('e'));
|
|
if ( !(numb.ToLong(&i) ) )
|
|
{
|
|
wxLogError( wxT("Integer conversion failed for --Style") );
|
|
}
|
|
else
|
|
{
|
|
istyle = i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//unknown - could be topic?
|
|
}
|
|
}
|
|
|
|
// No book - query user; but not on Mac, since there
|
|
// may be an AppleEvent to open a document on the way
|
|
#ifndef __WXMAC__
|
|
if ( bookCount < 1 )
|
|
{
|
|
wxString s = wxFileSelector( wxT("Open help file"),
|
|
wxGetCwd(),
|
|
wxEmptyString,
|
|
wxEmptyString,
|
|
wxT("Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|HTML Help Project (*.hhp)|*.hhp"),
|
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST,
|
|
NULL);
|
|
|
|
if (!s.empty())
|
|
{
|
|
book[0] = s;
|
|
bookCount = 1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if wxUSE_IPC
|
|
|
|
if ( createServer )
|
|
{
|
|
// Create a new server
|
|
m_server = new hvServer;
|
|
|
|
if ( !m_server->Create(service) )
|
|
{
|
|
wxString wxm = wxT("Server Create failed - service: ");
|
|
wxString xxm = wxm << service;
|
|
wxLogError( xxm );
|
|
//if MSW quits here, probably another copy already exists
|
|
return false;
|
|
}
|
|
createServer = false;
|
|
wxUnusedVar(createServer);
|
|
}
|
|
|
|
#endif // wxUSE_IPC
|
|
|
|
//now add help
|
|
wxInitAllImageHandlers();
|
|
wxFileSystem::AddHandler(new wxZipFSHandler);
|
|
|
|
SetVendorName(wxT("wxWidgets") );
|
|
SetAppName(wxT("wxHTMLHelpServer") );
|
|
wxConfig::Get(); // create an instance
|
|
|
|
m_helpController = new wxHtmlHelpController( istyle );
|
|
|
|
// By default, the application doesn't continue running if only the help
|
|
// frame remains. This makes sense for the programs doing something else
|
|
// and also showing help, but as this one only shows help, we should keep
|
|
// it running as long as this frame is opened.
|
|
m_helpController->SetShouldPreventAppExit(true);
|
|
|
|
if ( !hasWindowName )
|
|
{
|
|
titleFormat = wxT("Help: %s") ;
|
|
}
|
|
else
|
|
{
|
|
//remove underscores
|
|
windowName.Replace( wxT("_"), wxT(" ") );
|
|
titleFormat = windowName;
|
|
}
|
|
|
|
m_helpController->SetTitleFormat( titleFormat );
|
|
|
|
for( i=0; i<bookCount; i++ )
|
|
{
|
|
wxFileName fileName(book[i]);
|
|
m_helpController->AddBook(fileName);
|
|
}
|
|
|
|
#ifdef __WXMOTIF__
|
|
delete wxLog::SetActiveTarget(new wxLogGui);
|
|
#endif
|
|
|
|
m_helpController->DisplayContents();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
int hvApp::OnExit()
|
|
{
|
|
#if wxUSE_IPC
|
|
wxObjectList::compatibility_iterator node = m_connections.GetFirst();
|
|
while (node)
|
|
{
|
|
wxObjectList::compatibility_iterator next = node->GetNext();
|
|
hvConnection* connection = (hvConnection*) node->GetData();
|
|
connection->Disconnect();
|
|
delete connection;
|
|
node = next;
|
|
}
|
|
m_connections.Clear();
|
|
|
|
if (m_server)
|
|
{
|
|
delete m_server;
|
|
m_server = NULL;
|
|
}
|
|
#endif
|
|
|
|
delete m_helpController;
|
|
delete wxConfig::Set(NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool hvApp::OpenBook(wxHtmlHelpController* controller)
|
|
{
|
|
wxString s = wxFileSelector(_("Open help file"),
|
|
wxGetCwd(),
|
|
wxEmptyString,
|
|
wxEmptyString,
|
|
_(
|
|
"Help books (*.htb)|*.htb|Help books (*.zip)|*.zip|\
|
|
HTML Help Project (*.hhp)|*.hhp"),
|
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST,
|
|
NULL);
|
|
|
|
if ( !s.empty() )
|
|
{
|
|
wxString ext = s.Right(4).Lower();
|
|
if (ext == wxT(".zip") || ext == wxT(".htb") || ext == wxT(".hhp"))
|
|
{
|
|
wxBusyCursor bcur;
|
|
wxFileName fileName(s);
|
|
controller->AddBook(fileName);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#ifdef __WXMAC__
|
|
/// Respond to Apple Event for opening a document
|
|
void hvApp::MacOpenFiles(const wxArrayString& fileNames)
|
|
{
|
|
wxBusyCursor bcur;
|
|
wxFileName fileName(fileNames[0]);
|
|
m_helpController->AddBook(fileName);
|
|
m_helpController->DisplayContents();
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
* Art provider class
|
|
*/
|
|
|
|
// ---------------------------------------------------------------------
|
|
// helper macros
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Standard macro for getting a resource from XPM file:
|
|
#define ART(artId, xpmRc) \
|
|
if ( id == artId ) return wxBitmap(xpmRc##_xpm);
|
|
|
|
#define GET_STD_ICON_FROM_APP(iconId)
|
|
|
|
// There are two ways of getting the standard icon: either via XPMs or via
|
|
// wxIcon ctor. This depends on the platform:
|
|
#if defined(__WXUNIVERSAL__)
|
|
#define CREATE_STD_ICON(iconId, xpmRc) return wxNullBitmap;
|
|
#elif defined(__WXGTK__) || defined(__WXMOTIF__)
|
|
#define CREATE_STD_ICON(iconId, xpmRc) return wxBitmap(xpmRc##_xpm);
|
|
#else
|
|
#define CREATE_STD_ICON(iconId, xpmRc) \
|
|
{ \
|
|
wxIcon icon(wxT(iconId)); \
|
|
wxBitmap bmp; \
|
|
bmp.CopyFromIcon(icon); \
|
|
return bmp; \
|
|
}
|
|
#endif
|
|
|
|
// Macro used in CreateBitmap to get wxICON_FOO icons:
|
|
#define ART_MSGBOX(artId, iconId, xpmRc) \
|
|
if ( id == artId ) \
|
|
{ \
|
|
GET_STD_ICON_FROM_APP(iconId) \
|
|
CREATE_STD_ICON(#iconId, xpmRc) \
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// XPMs with the art
|
|
// ---------------------------------------------------------------------
|
|
|
|
// XPM hack: make the arrays const
|
|
//#define static static const
|
|
|
|
#include "bitmaps/helpback.xpm"
|
|
#include "bitmaps/helpbook.xpm"
|
|
#include "bitmaps/helpdown.xpm"
|
|
#include "bitmaps/helpforward.xpm"
|
|
#include "bitmaps/helpoptions.xpm"
|
|
#include "bitmaps/helppage.xpm"
|
|
#include "bitmaps/helpsidepanel.xpm"
|
|
#include "bitmaps/helpup.xpm"
|
|
#include "bitmaps/helpuplevel.xpm"
|
|
#include "bitmaps/helpicon.xpm"
|
|
#include "bitmaps/helpopen.xpm"
|
|
|
|
//#undef static
|
|
|
|
// ---------------------------------------------------------------------
|
|
// CreateBitmap routine
|
|
// ---------------------------------------------------------------------
|
|
|
|
wxBitmap AlternateArtProvider::CreateBitmap(const wxArtID& id,
|
|
const wxArtClient& client,
|
|
const wxSize& WXUNUSED(size))
|
|
{
|
|
ART(wxART_HELP_SIDE_PANEL, helpsidepanel)
|
|
ART(wxART_HELP_SETTINGS, helpoptions)
|
|
ART(wxART_HELP_BOOK, helpbook)
|
|
ART(wxART_HELP_FOLDER, helpbook)
|
|
ART(wxART_HELP_PAGE, helppage)
|
|
//ART(wxART_ADD_BOOKMARK, addbookm)
|
|
//ART(wxART_DEL_BOOKMARK, delbookm)
|
|
ART(wxART_GO_BACK, helpback)
|
|
ART(wxART_GO_FORWARD, helpforward)
|
|
ART(wxART_GO_UP, helpup)
|
|
ART(wxART_GO_DOWN, helpdown)
|
|
ART(wxART_GO_TO_PARENT, helpuplevel)
|
|
ART(wxART_FILE_OPEN, helpopen)
|
|
if (client == wxART_HELP_BROWSER)
|
|
{
|
|
//ART(wxART_FRAME_ICON, helpicon)
|
|
ART(wxART_HELP, helpicon)
|
|
}
|
|
|
|
//ART(wxART_GO_HOME, home)
|
|
|
|
// Any wxWidgets icons not implemented here
|
|
// will be provided by the default art provider.
|
|
return wxNullBitmap;
|
|
}
|
|
|
|
#if wxUSE_IPC
|
|
|
|
wxConnectionBase *hvServer::OnAcceptConnection(const wxString& topic)
|
|
{
|
|
if (topic == wxT("HELP"))
|
|
return new hvConnection();
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// hvConnection
|
|
// ----------------------------------------------------------------------------
|
|
|
|
hvConnection::hvConnection()
|
|
: wxConnection()
|
|
{
|
|
wxGetApp().GetConnections().Append(this);
|
|
}
|
|
|
|
hvConnection::~hvConnection()
|
|
{
|
|
wxGetApp().GetConnections().DeleteObject(this);
|
|
}
|
|
|
|
bool hvConnection::OnExec(const wxString& WXUNUSED(topic),
|
|
const wxString& data)
|
|
{
|
|
// wxLogStatus("Execute command: %s", data);
|
|
|
|
if ( data == "--intstring" )
|
|
{
|
|
long i;
|
|
wxString argStr = data;
|
|
wxString numb = argStr.AfterLast(wxT('g'));
|
|
if ( !(numb.ToLong(&i) ) )
|
|
{
|
|
wxLogError( wxT("Integer conversion failed for --intstring") );
|
|
}
|
|
else
|
|
{
|
|
wxGetApp().GetHelpController()->Display(int(i));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wxGetApp().GetHelpController()->Display(data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool hvConnection::OnPoke(const wxString& WXUNUSED(topic),
|
|
const wxString& item,
|
|
const void *buf,
|
|
size_t size,
|
|
wxIPCFormat format)
|
|
{
|
|
const wxString data = GetTextFromData(buf, size, format);
|
|
|
|
// wxLogStatus("Poke command: %s = %s", item.c_str(), data);
|
|
//topic is not tested
|
|
|
|
if ( wxGetApp().GetHelpController() )
|
|
{
|
|
if ( item == wxT("--AddBook") )
|
|
{
|
|
wxGetApp().GetHelpController()->AddBook(data);
|
|
}
|
|
else if ( item == wxT("--DisplayContents") )
|
|
{
|
|
wxGetApp().GetHelpController()->DisplayContents();
|
|
}
|
|
else if ( item == wxT("--DisplayIndex") )
|
|
{
|
|
wxGetApp().GetHelpController()->DisplayIndex();
|
|
}
|
|
else if ( item == wxT("--KeywordSearch") )
|
|
{
|
|
wxGetApp().GetHelpController()->KeywordSearch(data);
|
|
}
|
|
else if ( item == wxT("--SetTitleFormat") )
|
|
{
|
|
wxString newname = data;
|
|
newname.Replace( wxT("_"), wxT(" ") );
|
|
wxGetApp().GetHelpController()->SetTitleFormat(newname);
|
|
//does not redraw title bar?
|
|
//wxGetApp().GetHelpController()->ReFresh(); - or something
|
|
}
|
|
else if ( item == wxT("--SetTempDir") )
|
|
{
|
|
wxGetApp().GetHelpController()->SetTempDir(data);
|
|
}
|
|
else if ( item == wxT("--YouAreDead") )
|
|
{
|
|
// don't really know how to kill app from down here...
|
|
// use wxKill from client instead
|
|
//wxWindow *win = wxTheApp->GetTopWindow();
|
|
//if ( win )
|
|
// win->Destroy();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif // #if wxUSE_IPC
|