Made UI more responsive

This commit is contained in:
Zane U. Ji 2014-04-24 20:14:29 +08:00
parent a988b943c5
commit 7e7c756c60
9 changed files with 231 additions and 100 deletions

View File

@ -4,6 +4,7 @@
+ Supported HTTPS on validation + Supported HTTPS on validation
* Auto complete list for DTDs that are on the internet * Auto complete list for DTDs that are on the internet
* Show UI before opening any file * Show UI before opening any file
* Made UI more responsive
* Fixed tab order * Fixed tab order
* Fixed encoding problems * Fixed encoding problems
* Fixed invisible captions in high contrast mode (Windows only, http://trac.wxwidgets.org/ticket/16186) * Fixed invisible captions in high contrast mode (Windows only, http://trac.wxwidgets.org/ticket/16186)

View File

@ -109,7 +109,7 @@ void InsertPanel::update (
return; return;
} }
if ( parent == lastParent ) if ( parent == lastParent && !list->IsEmpty() )
return; return;
lastParent = parent; lastParent = parent;

View File

@ -83,7 +83,13 @@ bool MyServerConnection::OnPoke (
} }
else else
{ {
frame->openFile ( ( wxString& ) item ); #if wxCHECK_VERSION(2,9,0)
wxCommandEvent event ( wxEVT_MENU, wxID_OPEN );
#else
wxCommandEvent event ( wxEVT_COMMAND_MENU_SELECTED, wxID_OPEN );
#endif
event.SetString ( item );
wxPostEvent ( frame->GetEventHandler(), event );
//frame->addToFileQueue ( ( wxString& ) item ); // prevent event loop problems //frame->addToFileQueue ( ( wxString& ) item ); // prevent event loop problems
} }
#ifndef __WXMSW__ #ifndef __WXMSW__
@ -190,6 +196,10 @@ bool MyClient::talkToServer ( int argc, const wxChar * const *argv )
if ( !connection || !connection->StartAdvise ( IPC_ADVISE_NAME ) ) if ( !connection || !connection->StartAdvise ( IPC_ADVISE_NAME ) )
return false; return false;
// Grab what we need before the server is too busy to response
IPCSize_t size;
const void *data = connection->Request ( IPC_FRAME_WND, &size );
wxString argument; wxString argument;
// wxConnectionBase::Poke expects something other than NULL in debug // wxConnectionBase::Poke expects something other than NULL in debug
// version // version
@ -207,11 +217,10 @@ bool MyClient::talkToServer ( int argc, const wxChar * const *argv )
break; break;
} }
// Bring the window to front
IPCSize_t size;
const void *data = connection->Request ( IPC_FRAME_WND, &size );
if ( !data ) if ( !data )
return false; return false;
// Bring the window to front
#ifdef __WXMSW__ #ifdef __WXMSW__
if ( size == sizeof ( HWND ) ) if ( size == sizeof ( HWND ) )
{ {

View File

@ -205,6 +205,7 @@ BEGIN_EVENT_TABLE ( MyFrame, wxFrame )
#ifdef __WXMSW__ #ifdef __WXMSW__
EVT_DROP_FILES ( MyFrame::OnDropFiles ) EVT_DROP_FILES ( MyFrame::OnDropFiles )
#endif #endif
EVT_NOTIFY ( myEVT_NOTIFY_PROMPT_GENERATED, wxID_ANY, MyFrame::OnPromptGenerated )
END_EVENT_TABLE() END_EVENT_TABLE()
IMPLEMENT_APP ( MyApp) IMPLEMENT_APP ( MyApp)
@ -2926,10 +2927,6 @@ void MyFrame::newDocument ( const std::string& s, const wxString& path, bool can
doc->setShortFileName ( documentLabel ); doc->setShortFileName ( documentLabel );
doc->SetFocus(); doc->SetFocus();
manager.Update(); manager.Update();
locationPanel->update ( doc, wxEmptyString );
insertChildPanel->update ( doc, wxEmptyString );
insertSiblingPanel->update ( doc, wxEmptyString );
insertEntityPanel->update ( doc );
if ( properties.validateAsYouType ) if ( properties.validateAsYouType )
doc->backgroundValidate(); doc->backgroundValidate();
} }
@ -2939,6 +2936,13 @@ void MyFrame::OnOpen ( wxCommandEvent& event )
bool largeFile; bool largeFile;
largeFile = ( event.GetId() == ID_OPEN_LARGE_FILE ); largeFile = ( event.GetId() == ID_OPEN_LARGE_FILE );
wxString file = event.GetString();
if ( !file.empty() )
{
openFile ( file );
return;
}
wxString defaultFile, defaultDir; wxString defaultFile, defaultDir;
XmlDoc *doc; XmlDoc *doc;
if ( ( doc = getActiveDocument() ) != NULL ) if ( ( doc = getActiveDocument() ) != NULL )
@ -6014,6 +6018,15 @@ void MyFrame::OnDropFiles ( wxDropFilesEvent& event )
} }
#endif #endif
void MyFrame::OnPromptGenerated ( wxNotifyEvent &event )
{
XmlDoc *doc = this->getActiveDocument();
locationPanel->update ( doc, lastParent );
insertChildPanel->update ( doc, lastParent );
insertSiblingPanel->update ( doc, lastParent );
insertEntityPanel->update ( doc );
}
wxString MyFrame::getAuxPath ( const wxString& fileName ) wxString MyFrame::getAuxPath ( const wxString& fileName )
{ {
if ( fileName.Find ( _T ( ".xsl" ) ) != wxNOT_FOUND || if ( fileName.Find ( _T ( ".xsl" ) ) != wxNOT_FOUND ||

View File

@ -318,6 +318,7 @@ class MyFrame : public wxFrame
#ifdef __WXMSW__ #ifdef __WXMSW__
void OnDropFiles ( wxDropFilesEvent& event ); void OnDropFiles ( wxDropFilesEvent& event );
#endif #endif
void OnPromptGenerated ( wxNotifyEvent &event );
void setStrictScrolling ( bool b ); void setStrictScrolling ( bool b );
void validateRelaxNG ( void validateRelaxNG (
XmlDoc *doc, XmlDoc *doc,

View File

@ -41,6 +41,7 @@ BEGIN_EVENT_TABLE ( XmlCtrl, wxStyledTextCtrl )
EVT_RIGHT_UP ( XmlCtrl::OnMouseRightUp ) EVT_RIGHT_UP ( XmlCtrl::OnMouseRightUp )
EVT_MIDDLE_DOWN ( XmlCtrl::OnMiddleDown ) EVT_MIDDLE_DOWN ( XmlCtrl::OnMiddleDown )
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_VALIDATION_COMPLETED, XmlCtrl::OnValidationCompleted) EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_VALIDATION_COMPLETED, XmlCtrl::OnValidationCompleted)
EVT_NOTIFY ( myEVT_NOTIFY_PROMPT_GENERATED, wxID_ANY, XmlCtrl::OnPromptGenerated )
END_EVENT_TABLE() END_EVENT_TABLE()
// global protection for validation threads // global protection for validation threads
@ -69,6 +70,7 @@ XmlCtrl::XmlCtrl (
, auxPath ( auxPathParameter ) , auxPath ( auxPathParameter )
{ {
validationThread = NULL; validationThread = NULL;
mPromptGeneratorThread = NULL;
grammarFound = false; grammarFound = false;
validationRequired = (buffer) ? true : false; // NULL for plain XML template validationRequired = (buffer) ? true : false; // NULL for plain XML template
@ -148,6 +150,8 @@ XmlCtrl::~XmlCtrl()
//validationThread->Delete(); //validationThread->Delete();
//delete validationThread; //delete validationThread;
} }
if ( mPromptGeneratorThread != NULL )
mPromptGeneratorThread->PendingDelete();
} }
@ -1106,19 +1110,48 @@ void XmlCtrl::updatePromptMaps ( const char *utf8Buffer, size_t bufferLen )
attributeMap.clear(); attributeMap.clear();
elementMap.clear(); elementMap.clear();
elementStructureMap.clear(); elementStructureMap.clear();
XmlPromptGenerator xpg ( basePath, auxPath, "UTF-8" );
xpg.parse ( utf8Buffer, bufferLen ); wxCriticalSectionLocker locker ( xmlcopyeditorCriticalSection );
xpg.getAttributeMap ( attributeMap );
xpg.getRequiredAttributeMap ( requiredAttributeMap ); if ( mPromptGeneratorThread )
xpg.getElementMap ( elementMap ); return;
xpg.getElementStructureMap ( elementStructureMap );
xpg.getEntitySet ( entitySet ); mPromptGeneratorThread = new XmlPromptGenerator (
grammarFound = xpg.getGrammarFound(); GetEventHandler(), utf8Buffer, bufferLen, basePath, auxPath, "UTF-8"
);
if ( mPromptGeneratorThread->Create() != wxTHREAD_NO_ERROR
|| mPromptGeneratorThread->Run() != wxTHREAD_NO_ERROR )
{
delete mPromptGeneratorThread;
mPromptGeneratorThread = NULL;
}
}
void XmlCtrl::OnPromptGenerated ( wxNotifyEvent &event )
{
wxCriticalSectionLocker locker ( xmlcopyeditorCriticalSection );
if ( mPromptGeneratorThread == NULL )
return;
attributeMap = mPromptGeneratorThread->getAttributeMap();
requiredAttributeMap = mPromptGeneratorThread->getRequiredAttributeMap();
elementMap = mPromptGeneratorThread->getElementMap();
elementStructureMap = mPromptGeneratorThread->getElementStructureMap();
entitySet = mPromptGeneratorThread->getEntitySet();
grammarFound = mPromptGeneratorThread->getGrammarFound();
entitySet.insert ( _T ( "amp" ) ); entitySet.insert ( _T ( "amp" ) );
entitySet.insert ( _T ( "apos" ) ); entitySet.insert ( _T ( "apos" ) );
entitySet.insert ( _T ( "quot" ) ); entitySet.insert ( _T ( "quot" ) );
entitySet.insert ( _T ( "lt" ) ); entitySet.insert ( _T ( "lt" ) );
entitySet.insert ( _T ( "gt" ) ); entitySet.insert ( _T ( "gt" ) );
mPromptGeneratorThread->Wait();
delete mPromptGeneratorThread;
mPromptGeneratorThread = NULL;
wxPostEvent ( GetParent()->GetEventHandler(), event );
} }
void XmlCtrl::applyProperties ( void XmlCtrl::applyProperties (

View File

@ -29,6 +29,7 @@
#include <map> #include <map>
class ValidationThread; class ValidationThread;
class XmlPromptGenerator;
struct XmlCtrlProperties struct XmlCtrlProperties
{ {
@ -160,6 +161,7 @@ class XmlCtrl: public wxStyledTextCtrl
void toggleComment(); void toggleComment();
private: private:
ValidationThread *validationThread; // used for background validation ValidationThread *validationThread; // used for background validation
XmlPromptGenerator *mPromptGeneratorThread;
int type; int type;
bool *protectTags; bool *protectTags;
@ -203,6 +205,7 @@ class XmlCtrl: public wxStyledTextCtrl
void OnMouseLeftUp ( wxMouseEvent& event ); void OnMouseLeftUp ( wxMouseEvent& event );
void OnMouseRightUp ( wxMouseEvent& event ); void OnMouseRightUp ( wxMouseEvent& event );
void OnMiddleDown ( wxMouseEvent& event ); void OnMiddleDown ( wxMouseEvent& event );
void OnPromptGenerated ( wxNotifyEvent &event );
void insertNewLine(); void insertNewLine();
void adjustNoColumnWidth(); void adjustNoColumnWidth();
void adjustPosRight(); void adjustPosRight();

View File

@ -25,6 +25,7 @@
#include "readfile.h" #include "readfile.h"
#include "replace.h" #include "replace.h"
#include "pathresolver.h" #include "pathresolver.h"
#include "threadreaper.h"
#undef XMLCALL #undef XMLCALL
#include "catalogresolver.h" #include "catalogresolver.h"
@ -45,15 +46,29 @@
using namespace xercesc; using namespace xercesc;
extern wxCriticalSection xmlcopyeditorCriticalSection;
DEFINE_EVENT_TYPE ( myEVT_NOTIFY_PROMPT_GENERATED );
XmlPromptGenerator::XmlPromptGenerator ( XmlPromptGenerator::XmlPromptGenerator (
wxEvtHandler *handler,
const char *buffer,
size_t bufferSize,
const wxString& basePath, const wxString& basePath,
const wxString& auxPath, const wxString& auxPath,
const char *encoding const char *encoding
) )
: WrapExpat ( encoding ) : WrapExpat ( encoding )
, wxThread ( wxTHREAD_JOINABLE )
, d ( new PromptGeneratorData() ) , d ( new PromptGeneratorData() )
, mEventHandler ( handler )
, mBuffer ( buffer, bufferSize )
, mStopping ( false )
{ {
XML_SetUserData ( p, d.get() ); if ( mBuffer.length() != bufferSize )
throw std::bad_alloc();
XML_SetUserData ( p, this );
d->p = p; d->p = p;
d->basePath = basePath; d->basePath = basePath;
d->auxPath = auxPath; d->auxPath = auxPath;
@ -66,7 +81,7 @@ XmlPromptGenerator::XmlPromptGenerator (
XML_SetElementDeclHandler ( p, elementdeclhandler ); XML_SetElementDeclHandler ( p, elementdeclhandler );
XML_SetAttlistDeclHandler ( p, attlistdeclhandler ); XML_SetAttlistDeclHandler ( p, attlistdeclhandler );
XML_SetEntityDeclHandler ( p, entitydeclhandler ); XML_SetEntityDeclHandler ( p, entitydeclhandler );
XML_SetExternalEntityRefHandlerArg ( p, d.get() ); XML_SetExternalEntityRefHandlerArg ( p, this );
XML_SetExternalEntityRefHandler ( p, externalentityrefhandler ); XML_SetExternalEntityRefHandler ( p, externalentityrefhandler );
XML_SetBase ( p, d->basePath.utf8_str() ); XML_SetBase ( p, d->basePath.utf8_str() );
@ -82,15 +97,15 @@ void XMLCALL XmlPromptGenerator::starthandler (
const XML_Char *el, const XML_Char *el,
const XML_Char **attr ) const XML_Char **attr )
{ {
PromptGeneratorData *d; XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
d = ( PromptGeneratorData * ) data; PromptGeneratorData *d = pThis->d.get();
if (d->isRootElement) if (d->isRootElement)
{ {
d->rootElement = el; d->rootElement = el;
handleSchema ( d, el, attr ); // experimental: schema has been pre-parsed pThis->handleSchema ( d, el, attr ); // experimental: schema has been pre-parsed
d->isRootElement = false; d->isRootElement = false;
if ( d->grammarFound )//if ( d->elementMap.size() == 1) // must be 1 for success if ( d->grammarFound || pThis->TestDestroy() )//if ( d->elementMap.size() == 1) // must be 1 for success
{ {
return; return;
} }
@ -119,45 +134,12 @@ void XMLCALL XmlPromptGenerator::starthandler (
void XMLCALL XmlPromptGenerator::endhandler ( void *data, const XML_Char *el ) void XMLCALL XmlPromptGenerator::endhandler ( void *data, const XML_Char *el )
{ {
PromptGeneratorData *d; XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
d = ( PromptGeneratorData * ) data;
d->pop();
}
bool XmlPromptGenerator::getGrammarFound() if ( pThis->TestDestroy() )
{ XML_StopParser ( pThis->d->p, false );
return d->grammarFound; else
} pThis->d->pop();
void XmlPromptGenerator::getAttributeMap (
std::map<wxString, std::map<wxString, std::set<wxString> > >
&attributeMap )
{
attributeMap = d->attributeMap;
}
void XmlPromptGenerator::getRequiredAttributeMap (
std::map<wxString, std::set<wxString> >& requiredAttributeMap )
{
requiredAttributeMap = d->requiredAttributeMap;
}
void XmlPromptGenerator::getElementMap (
std::map<wxString, std::set<wxString> > &elementMap )
{
elementMap = d->elementMap;
}
void XmlPromptGenerator::getEntitySet (
std::set<wxString> &entitySet )
{
entitySet = d->entitySet;
}
void XmlPromptGenerator::getElementStructureMap (
std::map<wxString, wxString> &elementStructureMap )
{
elementStructureMap = d->elementStructureMap;
} }
// handlers for DOCTYPE handling // handlers for DOCTYPE handling
@ -175,13 +157,16 @@ void XMLCALL XmlPromptGenerator::doctypedeclstarthandler (
void XMLCALL XmlPromptGenerator::doctypedeclendhandler ( void *data ) void XMLCALL XmlPromptGenerator::doctypedeclendhandler ( void *data )
{ {
PromptGeneratorData *d; XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
d = ( PromptGeneratorData * ) data; PromptGeneratorData *d = pThis->d.get();
if ( !d->elementMap.empty() ) if ( !d->elementMap.empty() )
{ {
d->grammarFound = true; d->grammarFound = true;
XML_StopParser ( d->p, false ); // experimental XML_StopParser ( d->p, false ); // experimental
} }
if ( pThis->TestDestroy() )
XML_StopParser ( d->p, false );
} }
void XMLCALL XmlPromptGenerator::elementdeclhandler ( void XMLCALL XmlPromptGenerator::elementdeclhandler (
@ -189,14 +174,18 @@ void XMLCALL XmlPromptGenerator::elementdeclhandler (
const XML_Char *name, const XML_Char *name,
XML_Content *model ) XML_Content *model )
{ {
PromptGeneratorData *d; XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
d = ( PromptGeneratorData * ) data; PromptGeneratorData *d = pThis->d.get();
wxString myElement ( name, wxConvUTF8 ); wxString myElement ( name, wxConvUTF8 );
getContent ( *model, d->elementStructureMap[myElement], d->elementMap[myElement] ); pThis->getContent ( *model, d->elementStructureMap[myElement],
d->elementMap[myElement] );
XML_FreeContentModel ( d->p, model ); XML_FreeContentModel ( d->p, model );
if ( pThis->TestDestroy() )
XML_StopParser ( d->p, false );
} }
void XmlPromptGenerator::getContent ( void XmlPromptGenerator::getContent (
@ -204,6 +193,9 @@ void XmlPromptGenerator::getContent (
wxString &contentModel, wxString &contentModel,
std::set<wxString> &list ) std::set<wxString> &list )
{ {
if ( TestDestroy() )
return;
wxString name; wxString name;
switch ( content.type ) switch ( content.type )
{ {
@ -260,8 +252,8 @@ void XMLCALL XmlPromptGenerator::attlistdeclhandler (
const XML_Char *dflt, const XML_Char *dflt,
int isrequired ) int isrequired )
{ {
PromptGeneratorData *d; XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
d = ( PromptGeneratorData * ) data; PromptGeneratorData *d = pThis->d.get();
wxString element ( elname, wxConvUTF8 ); wxString element ( elname, wxConvUTF8 );
wxString attribute ( attname, wxConvUTF8 ); wxString attribute ( attname, wxConvUTF8 );
@ -289,6 +281,9 @@ void XMLCALL XmlPromptGenerator::attlistdeclhandler (
{ {
d->requiredAttributeMap[element].insert ( attribute ); d->requiredAttributeMap[element].insert ( attribute );
} }
if ( pThis->TestDestroy() )
XML_StopParser ( d->p, false );
} }
int XMLCALL XmlPromptGenerator::externalentityrefhandler ( int XMLCALL XmlPromptGenerator::externalentityrefhandler (
@ -298,8 +293,9 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
const XML_Char *systemId, const XML_Char *systemId,
const XML_Char *publicId ) const XML_Char *publicId )
{ {
PromptGeneratorData *d; // arg is set to user data in c'tor
d = ( PromptGeneratorData * ) p; // arg is set to user data in c'tor XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) p;
PromptGeneratorData *d = pThis->d.get();
// Either EXPAT or Xerces-C++ is capable of parsing DTDs. The advantage // Either EXPAT or Xerces-C++ is capable of parsing DTDs. The advantage
// of Xerces-C++ is that it can access DTDs that are on the internet. // of Xerces-C++ is that it can access DTDs that are on the internet.
@ -328,13 +324,13 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
NameIdPoolEnumerator<DTDElementDecl> elemEnum = grammar->getElemEnumerator(); NameIdPoolEnumerator<DTDElementDecl> elemEnum = grammar->getElemEnumerator();
SubstitutionMap substitutions; SubstitutionMap substitutions;
while ( elemEnum.hasMoreElements() ) while ( elemEnum.hasMoreElements() && !pThis->TestDestroy() )
{ {
const DTDElementDecl& curElem = elemEnum.nextElement(); const DTDElementDecl& curElem = elemEnum.nextElement();
buildElementPrompt ( d, &curElem, substitutions ); pThis->buildElementPrompt ( d, &curElem, substitutions );
} }
return XML_STATUS_OK; return pThis->TestDestroy() ? XML_STATUS_ERROR : XML_STATUS_OK;
#else // !PREFER_EXPAT_TO_XERCES_C #else // !PREFER_EXPAT_TO_XERCES_C
@ -352,7 +348,7 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
d->encoding = XmlEncodingHandler::get ( buffer ); d->encoding = XmlEncodingHandler::get ( buffer );
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, d->encoding.c_str() ); XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, d->encoding.c_str() );
if ( !dtdParser ) if ( pThis->TestDestroy() || !dtdParser )
return XML_STATUS_ERROR; return XML_STATUS_ERROR;
XML_SetBase ( dtdParser, d->auxPath.utf8_str() ); XML_SetBase ( dtdParser, d->auxPath.utf8_str() );
ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true ); ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
@ -389,14 +385,15 @@ int XMLCALL XmlPromptGenerator::externalentityrefhandler (
std::string encoding = XmlEncodingHandler::get ( buffer ); std::string encoding = XmlEncodingHandler::get ( buffer );
XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() ); XML_Parser dtdParser = XML_ExternalEntityParserCreate ( d->p, context, encoding.c_str() );
if ( !dtdParser ) if ( pThis->TestDestroy() || !dtdParser )
return XML_STATUS_ERROR; return XML_STATUS_ERROR;
XML_SetBase ( dtdParser, wideSystemId.utf8_str() ); XML_SetBase ( dtdParser, wideSystemId.utf8_str() );
ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true ); ret = XML_Parse ( dtdParser, buffer.c_str(), buffer.size(), true );
XML_ParserFree ( dtdParser ); XML_ParserFree ( dtdParser );
return ret;
return pThis->TestDestroy() ? XML_STATUS_ERROR : ret;
#endif // PREFER_EXPAT_TO_XERCES_C #endif // PREFER_EXPAT_TO_XERCES_C
} }
@ -412,8 +409,9 @@ void XMLCALL XmlPromptGenerator::entitydeclhandler (
const XML_Char *publicId, const XML_Char *publicId,
const XML_Char *notationName ) const XML_Char *notationName )
{ {
PromptGeneratorData *d; // arg is set to user data in c'tor
d = ( PromptGeneratorData * ) data; // arg is set to user data in c'tor XmlPromptGenerator *pThis = ( XmlPromptGenerator * ) data;
PromptGeneratorData *d = pThis->d.get();
if ( if (
entityName && entityName &&
@ -424,6 +422,9 @@ void XMLCALL XmlPromptGenerator::entitydeclhandler (
{ {
d->entitySet.insert ( wxString ( entityName, wxConvUTF8 ) ); d->entitySet.insert ( wxString ( entityName, wxConvUTF8 ) );
} }
if ( pThis->TestDestroy() )
XML_StopParser ( d->p, false );
} }
void XmlPromptGenerator::handleSchema ( void XmlPromptGenerator::handleSchema (
@ -471,6 +472,12 @@ void XmlPromptGenerator::handleSchema (
parser->setDoSchema ( true ); parser->setDoSchema ( true );
parser->setValidationSchemaFullChecking ( true ); parser->setValidationSchemaFullChecking ( true );
if ( TestDestroy() )
{
XML_StopParser ( d->p, false );
return;
}
Grammar *rootGrammar = parser->loadGrammar Grammar *rootGrammar = parser->loadGrammar
( ( const XMLCh * ) WrapXerces::toString ( schemaPath ).GetData() ( ( const XMLCh * ) WrapXerces::toString ( schemaPath ).GetData()
, Grammar::SchemaGrammarType , Grammar::SchemaGrammarType
@ -491,7 +498,7 @@ void XmlPromptGenerator::handleSchema (
SubstitutionMap substitutions; SubstitutionMap substitutions;
buildSubstitutionMap ( substitutions, *grammar ); buildSubstitutionMap ( substitutions, *grammar );
while ( elemEnum.hasMoreElements() ) while ( elemEnum.hasMoreElements() && !TestDestroy() )
{ {
const SchemaElementDecl& curElem = elemEnum.nextElement(); const SchemaElementDecl& curElem = elemEnum.nextElement();
buildElementPrompt ( d, &curElem, substitutions ); buildElementPrompt ( d, &curElem, substitutions );
@ -533,7 +540,8 @@ void XmlPromptGenerator::buildElementPrompt (
return; return;
XMLAttDefList& attIter = element->getAttDefList(); XMLAttDefList& attIter = element->getAttDefList();
for ( unsigned int i = 0; i < attIter.getAttDefCount(); i++ ) unsigned int i = 0;
for ( ; i < attIter.getAttDefCount() && !TestDestroy(); i++ )
{ {
wxString attribute, attributeValue; wxString attribute, attributeValue;
@ -564,7 +572,7 @@ void XmlPromptGenerator::buildSubstitutionMap (
if ( !list.hasMoreElements() ) if ( !list.hasMoreElements() )
return; return;
while ( list.hasMoreElements() ) while ( list.hasMoreElements() && !TestDestroy() )
{ {
const ElemVector &elmts = list.nextElement(); const ElemVector &elmts = list.nextElement();
@ -589,6 +597,8 @@ void XmlPromptGenerator::getContent (
const ContentSpecNode *spec, const ContentSpecNode *spec,
SubstitutionMap &substitutions ) SubstitutionMap &substitutions )
{ {
if ( TestDestroy() )
return;
//if ( spec == NULL) return; //if ( spec == NULL) return;
const QName *qnm = spec->getElement(); const QName *qnm = spec->getElement();
@ -615,3 +625,28 @@ void XmlPromptGenerator::getContent (
if ( spec->getSecond() != NULL) if ( spec->getSecond() != NULL)
getContent( list, spec->getSecond(), substitutions ); getContent( list, spec->getSecond(), substitutions );
} }
void *XmlPromptGenerator::Entry()
{
if ( TestDestroy() )
return NULL;
parse ( mBuffer );
wxCriticalSectionLocker locker ( xmlcopyeditorCriticalSection );
if ( !TestDestroy() )
{
wxNotifyEvent event ( myEVT_NOTIFY_PROMPT_GENERATED );
wxPostEvent ( mEventHandler, event );
}
return NULL;
}
void XmlPromptGenerator::PendingDelete ()
{
Cancel();
ThreadReaper::get().add ( this );
}

View File

@ -21,15 +21,19 @@
#define XML_PROMPT_GENERATOR_H #define XML_PROMPT_GENERATOR_H
#include <wx/wx.h> #include <wx/wx.h>
//#include <expat.h> #include <wx/thread.h>
#include <wx/event.h>
#include <map> #include <map>
#include <set> #include <set>
#include <memory> #include <memory>
#include <string>
#include "wrapexpat.h" #include "wrapexpat.h"
#include "parserdata.h" #include "parserdata.h"
#include <xercesc/validators/common/ContentSpecNode.hpp> #include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/schema/SchemaGrammar.hpp> #include <xercesc/validators/schema/SchemaGrammar.hpp>
DECLARE_EVENT_TYPE ( myEVT_NOTIFY_PROMPT_GENERATED, wxID_ANY );
struct PromptGeneratorData : public ParserData struct PromptGeneratorData : public ParserData
{ {
std::map<wxString, std::map<wxString, std::set<wxString> > > std::map<wxString, std::map<wxString, std::set<wxString> > >
@ -48,26 +52,54 @@ struct PromptGeneratorData : public ParserData
typedef std::map<const xercesc::SchemaElementDecl *, std::set<wxString> > typedef std::map<const xercesc::SchemaElementDecl *, std::set<wxString> >
SubstitutionMap; SubstitutionMap;
class XmlPromptGenerator : public WrapExpat class XmlPromptGenerator : public WrapExpat, public wxThread
{ {
public: public:
XmlPromptGenerator ( XmlPromptGenerator (
wxEvtHandler *handler,
const char *buffer,
size_t bufferSize,
const wxString& basePath = wxEmptyString, const wxString& basePath = wxEmptyString,
const wxString& auxPath = wxEmptyString, const wxString& auxPath = wxEmptyString,
const char *encoding = NULL ); const char *encoding = NULL );
virtual ~XmlPromptGenerator(); virtual ~XmlPromptGenerator();
void getAttributeMap (
std::map<wxString, std::map<wxString, std::set<wxString> > > virtual void *Entry();
&attributeMap ); void PendingDelete();
void getRequiredAttributeMap ( // Since we can't call wxThread::m_internal->Cancel(), the original
std::map<wxString, std::set<wxString> > &requiredAttributeMap ); // TestDestroy() is useless. Here is the work around.
void getElementMap ( virtual void Cancel() { mStopping = true; }
std::map<wxString, std::set<wxString> > &elementMap ); virtual bool TestDestroy() { return mStopping || wxThread::TestDestroy(); }
void getEntitySet (
std::set<wxString> &entitySet ); const std::map<wxString, std::map<wxString, std::set<wxString> > >
bool getGrammarFound(); &getAttributeMap()
void getElementStructureMap ( {
std::map<wxString, wxString> &elementStructureMap ); return d->attributeMap;
}
const std::map<wxString, std::set<wxString> >
&getRequiredAttributeMap ()
{
return d->requiredAttributeMap;
}
const std::map<wxString, std::set<wxString> >
&getElementMap()
{
return d->elementMap;
}
const std::set<wxString>
&getEntitySet()
{
return d->entitySet;
}
bool getGrammarFound()
{
return d->grammarFound;
}
const std::map<wxString, wxString>
&getElementStructureMap()
{
return d->elementStructureMap;
}
private: private:
std::auto_ptr<PromptGeneratorData> d; std::auto_ptr<PromptGeneratorData> d;
static void XMLCALL starthandler ( static void XMLCALL starthandler (
@ -88,7 +120,7 @@ class XmlPromptGenerator : public WrapExpat
void *userData, void *userData,
const XML_Char *name, const XML_Char *name,
XML_Content *model ); XML_Content *model );
static void getContent ( void getContent (
const XML_Content &content, const XML_Content &content,
wxString &contentModel, wxString &contentModel,
std::set<wxString> &list ); std::set<wxString> &list );
@ -115,21 +147,25 @@ class XmlPromptGenerator : public WrapExpat
const XML_Char *systemId, const XML_Char *systemId,
const XML_Char *publicId, const XML_Char *publicId,
const XML_Char *notationName ); const XML_Char *notationName );
static void handleSchema ( void handleSchema (
PromptGeneratorData *d, PromptGeneratorData *d,
const XML_Char *el, const XML_Char *el,
const XML_Char **attr ); const XML_Char **attr );
static void buildSubstitutionMap ( void buildSubstitutionMap (
SubstitutionMap &substitutions, SubstitutionMap &substitutions,
const xercesc::SchemaGrammar &grammar ); const xercesc::SchemaGrammar &grammar );
static void buildElementPrompt ( void buildElementPrompt (
PromptGeneratorData *d, PromptGeneratorData *d,
const xercesc::XMLElementDecl *element, const xercesc::XMLElementDecl *element,
SubstitutionMap &substitutions ); SubstitutionMap &substitutions );
static void getContent ( void getContent (
std::set<wxString> &list, std::set<wxString> &list,
const xercesc::ContentSpecNode *spec, const xercesc::ContentSpecNode *spec,
SubstitutionMap &substitutions ); SubstitutionMap &substitutions );
protected:
wxEvtHandler *mEventHandler;
std::string mBuffer;
bool mStopping;
}; };
#endif #endif