Updated for 1.2.0 - all changes relating to full background validation

This commit is contained in:
Gerald Schmidt 2008-07-08 22:54:48 +00:00
parent eaf4729051
commit 73b96def2a
8 changed files with 174 additions and 95 deletions

View File

@ -24,7 +24,7 @@ xmlcopyeditor_SOURCES = xmlcopyeditor.cpp associatedialog.cpp casehandler.cpp \
insertpanel.cpp xmlwordcount.cpp getword.cpp locationpanel.cpp catalogresolver.cpp getlinuxappdir.cpp \ insertpanel.cpp xmlwordcount.cpp getword.cpp locationpanel.cpp catalogresolver.cpp getlinuxappdir.cpp \
xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.cpp \ xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.cpp \
findreplacepanel.cpp commandpanel.cpp \ findreplacepanel.cpp commandpanel.cpp \
binaryfile.cpp xmlencodingspy.cpp wrapaspell.cpp \ binaryfile.cpp xmlencodingspy.cpp wrapaspell.cpp validationthread.cpp \
rulesets png rng xpm templates copying help po \ rulesets png rng xpm templates copying help po \
xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \ xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \
xmlcopyeditor.desktop xmlcopyeditor.desktop

View File

@ -70,7 +70,7 @@ am_xmlcopyeditor_OBJECTS = xmlcopyeditor.$(OBJEXT) \
xmlshallowvalidator.$(OBJEXT) wrapxerces.$(OBJEXT) \ xmlshallowvalidator.$(OBJEXT) wrapxerces.$(OBJEXT) \
findreplacepanel.$(OBJEXT) commandpanel.$(OBJEXT) \ findreplacepanel.$(OBJEXT) commandpanel.$(OBJEXT) \
binaryfile.$(OBJEXT) xmlencodingspy.$(OBJEXT) \ binaryfile.$(OBJEXT) xmlencodingspy.$(OBJEXT) \
wrapaspell.$(OBJEXT) wrapaspell.$(OBJEXT) validationthread.$($OBJEXT)
xmlcopyeditor_OBJECTS = $(am_xmlcopyeditor_OBJECTS) xmlcopyeditor_OBJECTS = $(am_xmlcopyeditor_OBJECTS)
xmlcopyeditor_LDADD = $(LDADD) xmlcopyeditor_LDADD = $(LDADD)
xmlcopyeditor_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ xmlcopyeditor_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
@ -209,7 +209,7 @@ xmlcopyeditor_SOURCES = xmlcopyeditor.cpp associatedialog.cpp casehandler.cpp \
insertpanel.cpp xmlwordcount.cpp getword.cpp locationpanel.cpp catalogresolver.cpp getlinuxappdir.cpp \ insertpanel.cpp xmlwordcount.cpp getword.cpp locationpanel.cpp catalogresolver.cpp getlinuxappdir.cpp \
xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.cpp \ xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.cpp \
findreplacepanel.cpp commandpanel.cpp \ findreplacepanel.cpp commandpanel.cpp \
binaryfile.cpp xmlencodingspy.cpp wrapaspell.cpp \ binaryfile.cpp xmlencodingspy.cpp wrapaspell.cpp validationthread.cpp \
rulesets png rng xpm templates copying help po \ rulesets png rng xpm templates copying help po \
xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \ xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \
xmlcopyeditor.desktop xmlcopyeditor.desktop
@ -351,6 +351,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rule.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rule.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/styledialog.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/styledialog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapaspell.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapaspell.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validationthread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapexpat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapexpat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wraplibxml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wraplibxml.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapregex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapregex.Po@am__quote@

View File

@ -24,6 +24,7 @@
#include <xercesc/sax2/SAX2XMLReader.hpp> #include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/DefaultHandler.hpp> #include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/util/XMLUni.hpp> #include <xercesc/util/XMLUni.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <sstream> #include <sstream>
#include <utility> #include <utility>
#include <stdexcept> #include <stdexcept>
@ -58,6 +59,7 @@ bool WrapXerces::validate ( const std::string& fileName )
parser->setFeature ( XMLUni::fgXercesSchema, true ); parser->setFeature ( XMLUni::fgXercesSchema, true );
parser->setFeature ( XMLUni::fgXercesSchemaFullChecking, true ); parser->setFeature ( XMLUni::fgXercesSchemaFullChecking, true );
parser->setFeature ( XMLUni::fgXercesValidationErrorAsFatal, true ); parser->setFeature ( XMLUni::fgXercesValidationErrorAsFatal, true );
parser->setFeature ( XMLUni::fgXercesLoadExternalDTD, true );
DefaultHandler handler; DefaultHandler handler;
MySAX2Handler mySAX2Handler; MySAX2Handler mySAX2Handler;
@ -98,8 +100,75 @@ bool WrapXerces::validate ( const std::string& fileName )
return true; return true;
} }
// tbd: cache grammar
bool WrapXerces::validateMemory (
const char *buffer,
const char *system,
unsigned len )
{
SAX2XMLReader *parser = XMLReaderFactory::createXMLReader();
parser->setFeature ( XMLUni::fgSAX2CoreNameSpaces, true );
parser->setFeature ( XMLUni::fgSAX2CoreValidation, true );
parser->setFeature ( XMLUni::fgXercesDynamic, true );
parser->setFeature ( XMLUni::fgXercesSchema, true );
parser->setFeature ( XMLUni::fgXercesSchemaFullChecking, true );
parser->setFeature ( XMLUni::fgXercesValidationErrorAsFatal, true );
parser->setFeature ( XMLUni::fgXercesLoadExternalDTD, true );
DefaultHandler handler;
MySAX2Handler mySAX2Handler;
parser->setContentHandler ( &handler );
parser->setErrorHandler ( &mySAX2Handler );
parser->setEntityResolver ( &handler );
XMLByte* xmlBuffer = (XMLByte*) buffer;
MemBufInputSource source (
xmlBuffer,
len,
system );
try
{
parser->parse ( source );
}
catch ( XMLException& e )
{
delete parser;
lastError = "";
return false;
}
catch ( SAXParseException& e )
{
delete parser;
char *err = XMLString::transcode ( e.getMessage() );
std::stringstream ss;
ss << "Ln " << e.getLineNumber() << " Col " << e.getColumnNumber() << ": " << err;
lastError = ss.str();
errorPosition = std::make_pair ( e.getLineNumber(), e.getColumnNumber() );
XMLString::release ( &err );
return false;
}
catch ( ... )
{
delete parser;
lastError = "";
return false;
}
delete parser;
return true;
}
std::string WrapXerces::getLastError() std::string WrapXerces::getLastError()
{ {
char *rawError, *it;
rawError = (char *)lastError.c_str();
it = strstr ( rawError, "Message:" );
if ( it )
{
lastError = it + 8;
}
return lastError; return lastError;
} }

View File

@ -34,6 +34,7 @@ class WrapXerces
WrapXerces(); WrapXerces();
~WrapXerces(); ~WrapXerces();
bool validate ( const std::string& fileName ); bool validate ( const std::string& fileName );
bool validateMemory ( const char *buffer, const char *system, unsigned len );
std::string getLastError(); std::string getLastError();
std::pair<int, int> getErrorPosition(); std::pair<int, int> getErrorPosition();
private: private:

View File

@ -3112,7 +3112,7 @@ bool MyFrame::openFile ( wxString& fileName, bool largeFile )
if ( !largeFile && ( properties.validateAsYouType && doc->getGrammarFound() ) ) if ( !largeFile && ( properties.validateAsYouType && doc->getGrammarFound() ) )
{ {
statusProgress ( _T ( "Validating document..." ) ); statusProgress ( _T ( "Validating document..." ) );
doc->shallowValidate ( finalBuffer, finalBufferLen ); doc->shallowValidate ( finalBuffer, doc->getFullFileName().mb_str(wxConvUTF8), finalBufferLen );
statusProgress ( wxEmptyString ); statusProgress ( wxEmptyString );
} }
@ -3811,7 +3811,7 @@ void MyFrame::OnValidateSchema ( wxCommandEvent& event )
int cursorPos = int cursorPos =
doc->PositionFromLine ( posPair.first - 1 ); doc->PositionFromLine ( posPair.first - 1 );
doc->SetSelection ( cursorPos, cursorPos ); doc->SetSelection ( cursorPos, cursorPos );
doc->setErrorIndicator ( posPair.first - 1, posPair.second ); doc->setErrorIndicator ( posPair.first - 1, 0 ); //posPair.second );
} }
else else
documentOk ( _ ( "valid" ) ); documentOk ( _ ( "valid" ) );
@ -4744,7 +4744,7 @@ bool MyFrame::saveFile ( XmlDoc *doc, wxString& fileName, bool checkLastModified
if ( properties.validateAsYouType && isXml ) if ( properties.validateAsYouType && isXml )
{ {
doc->clearErrorIndicators(); doc->clearErrorIndicators();
doc->shallowValidate ( utf8Buffer.c_str(), utf8Buffer.size() ); doc->shallowValidate ( utf8Buffer.c_str(), doc->getFullFileName().mb_str(wxConvUTF8), utf8Buffer.size() );
} }
if ( !unlimitedUndo ) if ( !unlimitedUndo )

View File

@ -41,5 +41,5 @@
"License along with this program; if not, write to the Free\n"\ "License along with this program; if not, write to the Free\n"\
"Software Foundation, Inc., 59 Temple Place, Suite 330,\n"\ "Software Foundation, Inc., 59 Temple Place, Suite 330,\n"\
"Boston, MA 02111-1307 USA.") "Boston, MA 02111-1307 USA.")
#define ABOUT_VERSION _T("1.1.0.7") #define ABOUT_VERSION _T("1.2.0")
#define XMLCE_VAR _T("XMLCE_VAR") #define XMLCE_VAR _T("XMLCE_VAR")

View File

@ -21,7 +21,10 @@
#include "xmlpromptgenerator.h" #include "xmlpromptgenerator.h"
#include "xmlshallowvalidator.h" #include "xmlshallowvalidator.h"
#include "xmlencodinghandler.h" #include "xmlencodinghandler.h"
#include "wrapxerces.h"
#include "xmlcopyeditor.h" // needed to enable validation-as-you-type alerts
#include <utility> #include <utility>
#include <memory>
// adapted from wxSTEdit (c) 2005 John Labenski, Otto Wyss // adapted from wxSTEdit (c) 2005 John Labenski, Otto Wyss
#define XMLCTRL_HASBIT(value, bit) (((value) & (bit)) != 0) #define XMLCTRL_HASBIT(value, bit) (((value) & (bit)) != 0)
@ -59,8 +62,13 @@ XmlCtrl::XmlCtrl (
basePath ( basePathParameter ), basePath ( basePathParameter ),
auxPath ( auxPathParameter ) auxPath ( auxPathParameter )
{ {
validationThread = NULL;
validationStarted = false;
validationFinished = false;
grammarFound = false;
validationRequired = (buffer) ? true : false; // NULL for plain XML template
currentMaxLine = 1; currentMaxLine = 1;
validationRequired = grammarFound = false;
applyProperties ( propertiesParameter ); applyProperties ( propertiesParameter );
@ -130,6 +138,24 @@ static wxColor LightColour ( const wxColour& color, int percent )
void XmlCtrl::OnIdle ( wxIdleEvent& event ) void XmlCtrl::OnIdle ( wxIdleEvent& event )
{ {
// poll validation thread output if any
if (validationStarted && validationFinished)
{
validationStarted = false;
MyFrame *frame = (MyFrame *)GetGrandParent();
if ( validationSuccess )
{
clearErrorIndicators ( GetLineCount() );
frame->statusProgress ( wxEmptyString );
}
else
{
clearErrorIndicators ( validationPosition.first -1 );
setErrorIndicator ( validationPosition.first - 1, 0 );
frame->statusProgress ( wxString ( validationMessage.c_str(), wxConvUTF8, validationMessage.size() ) );
}
}
if ( properties.number && type != FILE_TYPE_BINARY ) if ( properties.number && type != FILE_TYPE_BINARY )
adjustNoColumnWidth(); adjustNoColumnWidth();
} }
@ -1968,91 +1994,59 @@ bool XmlCtrl::shallowValidate ( int maxLine, bool segmentOnly )
if ( !properties.validateAsYouType || type != FILE_TYPE_XML ) if ( !properties.validateAsYouType || type != FILE_TYPE_XML )
return true; return true;
validationRequired = false; clearErrorIndicators ( GetLineCount() );
std::string bufferUtf8 = myGetTextRaw();
if ( !maxLine ) return shallowValidate (
maxLine = GetLineCount(); bufferUtf8.c_str(),
basePath.c_str(),
std::string bufferUtf8; bufferUtf8.size() );
int startLine, columnOffset;
startLine = columnOffset = 0;
if ( !segmentOnly )
{
clearErrorIndicators ( maxLine );
bufferUtf8 = myGetTextRaw();
}
else
{
int current,
line,
lineEnd,
parentCloseAngleBracket,
parentStartAngleBracket,
memory;
current = GetCurrentPos();
line = LineFromPosition ( current );
// try to include next line
lineEnd = GetLineEndPosition ( line + 1 );
if ( lineEnd == -1 )
lineEnd = GetLineEndPosition ( line );
// fetch parent
parentCloseAngleBracket = getParentCloseAngleBracket ( current );
parentStartAngleBracket = getTagStartPos ( parentCloseAngleBracket );
if ( parentStartAngleBracket == -1 )
return false;
memory = parentStartAngleBracket;
// fetch grandparent if not at start of document
if ( parentStartAngleBracket > 1 )
{
parentCloseAngleBracket =
getParentCloseAngleBracket ( parentStartAngleBracket - 1 );
parentStartAngleBracket = getTagStartPos ( parentCloseAngleBracket );
if ( parentStartAngleBracket == -1 )
parentStartAngleBracket = memory;
}
startLine = LineFromPosition ( parentStartAngleBracket );
if ( startLine == line )
{
columnOffset = parentStartAngleBracket - PositionFromLine ( line );
// disallow negative offsets
if ( columnOffset < 0 )
columnOffset = 0;
}
// sanity-check range
if ( lineEnd <= parentStartAngleBracket )
return false;
// clear indicators within range
StartStyling ( parentStartAngleBracket, wxSTC_INDIC2_MASK );
int length = lineEnd - parentStartAngleBracket;
SetStyling ( length, 0 );
// tweak raw getTextRange variant
wxString wideBuffer = GetTextRange ( parentStartAngleBracket, lineEnd );
bufferUtf8 = ( const char * ) wideBuffer.mb_str ( wxConvUTF8 );
}
return shallowValidate ( bufferUtf8.c_str(), bufferUtf8.size(), startLine,
maxLine, columnOffset, segmentOnly );
} }
bool XmlCtrl::shallowValidate ( const char *buffer, bool XmlCtrl::shallowValidate (
size_t bufferLen, const char *buffer,
int startLine, const char *system,
int maxLine, size_t bufferLen//,
int columnOffset, //int startLine,
bool segmentOnly ) //int maxLine,
//int columnOffset,
//bool segmentOnly
)
{ {
if ( !validationRequired )
return true;
validationRequired = false;
if (validationThread && !validationFinished)
{
validationThread->Delete();
validationThread = NULL;
}
validationThread = new ValidationThread(
buffer,
system,
&validationFinished,
&validationSuccess,
&validationPosition,
&validationMessage
);
if ( validationThread->Create() != wxTHREAD_NO_ERROR )
{
validationFinished = true;
return false;
}
validationStarted = true;
validationFinished = false;
validationThread->Run();
return true;
/*
std::auto_ptr<XmlShallowValidator> validator ( new XmlShallowValidator ( std::auto_ptr<XmlShallowValidator> validator ( new XmlShallowValidator (
elementMap, elementMap,
attributeMap, attributeMap,
@ -2084,6 +2078,7 @@ bool XmlCtrl::shallowValidate ( const char *buffer,
return false; return false;
} }
return true; return true;
*/
} }
std::string XmlCtrl::myGetTextRaw() std::string XmlCtrl::myGetTextRaw()

View File

@ -1,3 +1,4 @@
/* /*
* Copyright 2005-2007 Gerald Schmidt. * Copyright 2005-2007 Gerald Schmidt.
* *
@ -27,6 +28,7 @@
#include <string> #include <string>
#include <set> #include <set>
#include <map> #include <map>
#include "validationthread.h"
struct XmlCtrlProperties struct XmlCtrlProperties
{ {
@ -111,6 +113,7 @@ class XmlCtrl: public wxStyledTextCtrl
attributeMap.clear(); attributeMap.clear();
elementMap.clear(); elementMap.clear();
entitySet.clear(); entitySet.clear();
// don't delete validationThread in case it's gone
} }
int getType(); int getType();
int getParentCloseAngleBracket ( int pos, int range = USHRT_MAX * 4 ); int getParentCloseAngleBracket ( int pos, int range = USHRT_MAX * 4 );
@ -141,15 +144,25 @@ class XmlCtrl: public wxStyledTextCtrl
int getTagStartPos ( int pos ); int getTagStartPos ( int pos );
void toggleLineBackground(); void toggleLineBackground();
bool shallowValidate ( int maxLine = 0, bool segmentOnly = false ); bool shallowValidate ( int maxLine = 0, bool segmentOnly = false );
bool shallowValidate ( const char *buffer, size_t bufferLen, bool shallowValidate (
int startLine = 0, const char *buffer,
int maxLine = 0, const char *system,
int columnOffset = 0, size_t bufferLen//,
bool segmentOnly = false ); //int startLine = 0,
//int maxLine = 0,
//int columnOffset = 0,
//bool segmentOnly = false
);
std::string myGetTextRaw(); // alternative to faulty stc implementation std::string myGetTextRaw(); // alternative to faulty stc implementation
bool getValidationRequired(); bool getValidationRequired();
void setValidationRequired ( bool b ); void setValidationRequired ( bool b );
private: private:
// the following are used for background validation
ValidationThread *validationThread;
bool validationStarted, validationFinished, validationSuccess;
std::pair<int, int> validationPosition;
std::string validationMessage;
int type; int type;
bool *protectTags; bool *protectTags;
bool validationRequired, grammarFound; bool validationRequired, grammarFound;