/* Copyright (C) 2003 Razvan Cojocaru XML-RPC/Context ID code contributed by Eamon Millman / PCI Geomatics This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #ifdef WITH_LIBXMLRPC using namespace XmlRpc; // The better way to use a singleton. Can't rely on the order of // construction/initialization of global objects. XmlRpcServer& getXmlRpcServer() { static XmlRpcServer s; return s; } CHMApp::CHMApp() : wxApp(), XmlRpcServerMethod( "xCHM", &getXmlRpcServer()) {} void CHMApp::execute(XmlRpcValue& params, XmlRpcValue& result) { result = FALSE; if( params.size() > 0 && params[0].getType() == XmlRpcValue::TypeInt ) { switch( int(params[0]) ) { case 0: // we want to close everything up! //_frame->Command(ID_Quit); ExitMainLoop(); result = TRUE; break; case 1: if( params.size() == 2 && params[1].getType() == XmlRpcValue::TypeString ) { result = _frame->LoadCHM( CURRENT_CHAR_STRING( std::string(params[1]).c_str())); } if( params.size() == 3 && params[1].getType() == XmlRpcValue::TypeString && params[2].getType() == XmlRpcValue::TypeInt ) { result = _frame->LoadCHM( CURRENT_CHAR_STRING( std::string(params[1]).c_str())) && _frame->LoadContextID( int(params[2]) ); } break; case 2: if( params.size() == 2 && params[1].getType() == XmlRpcValue::TypeInt ) { result = _frame->LoadContextID( int(params[1]) ); } break; } } } #endif bool CHMApp::OnInit() { #ifdef WITH_LIBXMLRPC long port = -1; #endif long id = -1; wxString file; _cmdLP.SetCmdLine( argc, argv ); _cmdLP.AddParam( wxT("file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL ); _cmdLP.AddOption( wxT("c"), wxT("contextid"), wxT("context-Id to open in file, requires that a file be specified"), wxCMD_LINE_VAL_NUMBER ); #ifdef WITH_LIBXMLRPC _cmdLP.AddOption( wxT("x"), wxT("xmlrpc"), wxT("starts xCHM in XML-RPC server mode listening on port "), wxCMD_LINE_VAL_NUMBER ); #endif _cmdLP.AddSwitch( wxT("h"), wxT("help"), wxT("displays this message."), wxCMD_LINE_OPTION_HELP ); if( _cmdLP.Parse() != 0 ) // 0 means everything is ok { return FALSE; } #ifdef WITH_LIBXMLRPC // catch the xmlrpc setup if desired _cmdLP.Found( wxT("xmlrpc"), &port ); #endif if( _cmdLP.GetParamCount() == 1 ) // catch the optional file to load { file = _cmdLP.GetParam(0); _cmdLP.Found( wxT("contextid"), &id ); } else if( _cmdLP.Found( wxT("contextid") ) ) // can't use a context-ID without a file! { _cmdLP.Usage(); return FALSE; } long xorig = 50, yorig = 50, width = 600, height = 450; long sashPos = CONTENTS_MARGIN; long fontSize = CHM_DEFAULT_FONT_SIZE; wxString lastOpenedDir, normalFont, fixedFont; #ifndef __WXMAC__ _loc.Init(); _loc.AddCatalog(wxT("xchm")); #endif wxInitAllImageHandlers(); wxFileSystem::AddHandler(new CHMFSHandler); wxFileSystem::AddHandler(new wxInternetFSHandler); wxFileSystem::AddHandler(new wxMemoryFSHandler); wxConfig config(wxT("xchm")); if(config.Read(wxT("/Position/xOrig"), &xorig)) { config.Read(wxT("/Position/yOrig"), &yorig); config.Read(wxT("/Position/width"), &width); config.Read(wxT("/Position/height"), &height); config.Read(wxT("/Paths/lastOpenedDir"), &lastOpenedDir); config.Read(wxT("/Fonts/normalFontFace"), &normalFont); config.Read(wxT("/Fonts/fixedFontFace"), &fixedFont); config.Read(wxT("/Fonts/size"), &fontSize); config.Read(wxT("/Sash/leftMargin"), &sashPos); } wxString fullAppPath; if(argv > 0) fullAppPath = getAppPath(argv[0], wxGetCwd()); _frame = new CHMFrame(wxT("xCHM v. " VERSION), lastOpenedDir, wxPoint(xorig, yorig), wxSize(width, height), normalFont, fixedFont, static_cast(fontSize), static_cast(sashPos), fullAppPath); _frame->SetSizeHints(200, 200); _frame->Show(TRUE); SetTopWindow(_frame); #ifdef WITH_LIBXMLRPC if( port != -1 ) { // do the XML RPC init stuff here _timer.SetOwner( this, TIMER_ID ); _timer.Start(100); getXmlRpcServer().bindAndListen(port); } #endif if( _cmdLP.GetParamCount() == 1 ) { _frame->LoadCHM( file ); if( id != -1 ) _frame->LoadContextID( id ); } return TRUE; } wxString CHMApp::getAppPath(const wxString& argv0, const wxString& cwd) { if(wxIsAbsolutePath(argv0)) return argv0; wxString cwdtmp(cwd), apppath; if(cwdtmp.Last() != wxFILE_SEP_PATH) cwdtmp += wxFILE_SEP_PATH; apppath = cwdtmp + apppath; if(wxFileExists(apppath)) return apppath; wxPathList pathList; pathList.AddEnvList(wxT("PATH")); apppath = pathList.FindAbsoluteValidPath(argv0); if(!apppath.IsEmpty()) return wxPathOnly(apppath); return wxEmptyString; } #ifdef __WXMAC__ void CHMApp::MacOpenFile(const wxString& filename) { _frame->LoadCHM(filename); } #endif #ifdef WITH_LIBXMLRPC void CHMApp::WatchForXMLRPC( wxTimerEvent& ) { getXmlRpcServer().work(0.0); // check for a XMLRPC message } #endif #ifdef WITH_LIBXMLRPC BEGIN_EVENT_TABLE( CHMApp, wxApp ) EVT_TIMER(TIMER_ID, CHMApp::WatchForXMLRPC ) END_EVENT_TABLE() #endif // Apparently this macro gets main() pumping. IMPLEMENT_APP(CHMApp) /* Local Variables: mode: c++ c-basic-offset: 8 tab-width: 8 c-indent-comments-syntactically-p: t c-tab-always-indent: t indent-tabs-mode: t End: */ // vim:shiftwidth=8:autoindent:tabstop=8:noexpandtab:softtabstop=8