Updated for 1.2.0 - all changes relating to full background validation
This commit is contained in:
parent
eaf4729051
commit
73b96def2a
|
@ -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
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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")
|
||||
|
|
159
src/xmlctrl.cpp
159
src/xmlctrl.cpp
|
@ -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;
|
||||
clearErrorIndicators ( GetLineCount() );
|
||||
std::string bufferUtf8 = myGetTextRaw();
|
||||
|
||||
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 );
|
||||
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()
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue