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 \
xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.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 \
xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \
xmlcopyeditor.desktop

View File

@ -70,7 +70,7 @@ am_xmlcopyeditor_OBJECTS = xmlcopyeditor.$(OBJEXT) \
xmlshallowvalidator.$(OBJEXT) wrapxerces.$(OBJEXT) \
findreplacepanel.$(OBJEXT) commandpanel.$(OBJEXT) \
binaryfile.$(OBJEXT) xmlencodingspy.$(OBJEXT) \
wrapaspell.$(OBJEXT)
wrapaspell.$(OBJEXT) validationthread.$($OBJEXT)
xmlcopyeditor_OBJECTS = $(am_xmlcopyeditor_OBJECTS)
xmlcopyeditor_LDADD = $(LDADD)
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 \
xmlparseschemans.cpp xmlshallowvalidator.cpp wrapxerces.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 \
xmlcopyeditor.spec xmlcopyeditor.png custom.xpm \
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)/styledialog.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)/wraplibxml.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/DefaultHandler.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <sstream>
#include <utility>
#include <stdexcept>
@ -58,6 +59,7 @@ bool WrapXerces::validate ( const std::string& fileName )
parser->setFeature ( XMLUni::fgXercesSchema, true );
parser->setFeature ( XMLUni::fgXercesSchemaFullChecking, true );
parser->setFeature ( XMLUni::fgXercesValidationErrorAsFatal, true );
parser->setFeature ( XMLUni::fgXercesLoadExternalDTD, true );
DefaultHandler handler;
MySAX2Handler mySAX2Handler;
@ -98,8 +100,75 @@ bool WrapXerces::validate ( const std::string& fileName )
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()
{
char *rawError, *it;
rawError = (char *)lastError.c_str();
it = strstr ( rawError, "Message:" );
if ( it )
{
lastError = it + 8;
}
return lastError;
}

View File

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

View File

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

View File

@ -41,5 +41,5 @@
"License along with this program; if not, write to the Free\n"\
"Software Foundation, Inc., 59 Temple Place, Suite 330,\n"\
"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")

View File

@ -21,7 +21,10 @@
#include "xmlpromptgenerator.h"
#include "xmlshallowvalidator.h"
#include "xmlencodinghandler.h"
#include "wrapxerces.h"
#include "xmlcopyeditor.h" // needed to enable validation-as-you-type alerts
#include <utility>
#include <memory>
// adapted from wxSTEdit (c) 2005 John Labenski, Otto Wyss
#define XMLCTRL_HASBIT(value, bit) (((value) & (bit)) != 0)
@ -59,8 +62,13 @@ XmlCtrl::XmlCtrl (
basePath ( basePathParameter ),
auxPath ( auxPathParameter )
{
validationThread = NULL;
validationStarted = false;
validationFinished = false;
grammarFound = false;
validationRequired = (buffer) ? true : false; // NULL for plain XML template
currentMaxLine = 1;
validationRequired = grammarFound = false;
applyProperties ( propertiesParameter );
@ -130,6 +138,24 @@ static wxColor LightColour ( const wxColour& color, int percent )
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 )
adjustNoColumnWidth();
}
@ -1968,91 +1994,59 @@ bool XmlCtrl::shallowValidate ( int maxLine, bool segmentOnly )
if ( !properties.validateAsYouType || type != FILE_TYPE_XML )
return true;
validationRequired = false;
if ( !maxLine )
maxLine = GetLineCount();
std::string bufferUtf8;
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 );
clearErrorIndicators ( GetLineCount() );
std::string bufferUtf8 = myGetTextRaw();
return shallowValidate (
bufferUtf8.c_str(),
basePath.c_str(),
bufferUtf8.size() );
}
bool XmlCtrl::shallowValidate ( const char *buffer,
size_t bufferLen,
int startLine,
int maxLine,
int columnOffset,
bool segmentOnly )
bool XmlCtrl::shallowValidate (
const char *buffer,
const char *system,
size_t bufferLen//,
//int startLine,
//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 (
elementMap,
attributeMap,
@ -2084,6 +2078,7 @@ bool XmlCtrl::shallowValidate ( const char *buffer,
return false;
}
return true;
*/
}
std::string XmlCtrl::myGetTextRaw()

View File

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