fix crash with curve fx in macro
This commit is contained in:
parent
55a5931ad4
commit
e3d315d033
3 changed files with 52 additions and 23 deletions
|
@ -703,11 +703,18 @@ void TFx::setNewIdentifier() { m_imp->m_id = ++m_imp->m_nextId; }
|
|||
void TFx::loadData(TIStream &is) {
|
||||
std::string tagName;
|
||||
VersionNumber tnzVersion = is.getVersion();
|
||||
|
||||
// Prevent to load "params" tag under "super" tag on saving macro fx.
|
||||
// For now "params" tag is no longer saved under "super" tag.
|
||||
// This is for keeping compatibility with older versions.
|
||||
bool isInSuperTag = (is.getCurrentTagName() == "super");
|
||||
QList<int> groupIds;
|
||||
QList<std::wstring> groupNames;
|
||||
while (is.openChild(tagName)) {
|
||||
if (tagName == "params") {
|
||||
if (isInSuperTag) { // skip loading "params" tag under "super" tag
|
||||
is.skipCurrentTag();
|
||||
continue;
|
||||
}
|
||||
while (!is.eos()) {
|
||||
std::string paramName;
|
||||
while (is.openChild(paramName)) {
|
||||
|
@ -829,29 +836,36 @@ void TFx::loadData(TIStream &is) {
|
|||
//--------------------------------------------------
|
||||
|
||||
void TFx::saveData(TOStream &os) {
|
||||
// Prevent to save "params" tag under "super" tag on saving macro fx.
|
||||
// Parameters for macro fx are saved in "nodes" tag and corrected upon
|
||||
// loading. Therefore, "params" tag is not needed and even causes crash if
|
||||
// macrofx contains CurveFx (See the issue #2424)
|
||||
bool isInSuperTag = (os.getCurrentTagName() == "super");
|
||||
TFx *linkedSetRoot = this;
|
||||
if (m_imp->m_next != m_imp) {
|
||||
TFxImp *imp = m_imp->m_next;
|
||||
int guard = 0;
|
||||
while (guard++ < 1000 && imp != m_imp) {
|
||||
if (imp->m_fx < linkedSetRoot) linkedSetRoot = imp->m_fx;
|
||||
imp = imp->m_next;
|
||||
imp = imp->m_next;
|
||||
}
|
||||
assert(imp == m_imp);
|
||||
assert(linkedSetRoot);
|
||||
}
|
||||
if (linkedSetRoot == this) {
|
||||
os.openChild("params");
|
||||
for (int i = 0; i < getParams()->getParamCount(); i++) {
|
||||
std::string paramName = getParams()->getParamName(i);
|
||||
const TParamVar *paramVar = getParams()->getParamVar(i);
|
||||
// skip saving for the obsolete parameters
|
||||
if (paramVar->isObsolete()) continue;
|
||||
os.openChild(paramName);
|
||||
paramVar->getParam()->saveData(os);
|
||||
if (!isInSuperTag) { // skip saving "params" tag under "super" tag
|
||||
os.openChild("params");
|
||||
for (int i = 0; i < getParams()->getParamCount(); i++) {
|
||||
std::string paramName = getParams()->getParamName(i);
|
||||
const TParamVar *paramVar = getParams()->getParamVar(i);
|
||||
// skip saving for the obsolete parameters
|
||||
if (paramVar->isObsolete()) continue;
|
||||
os.openChild(paramName);
|
||||
paramVar->getParam()->saveData(os);
|
||||
os.closeChild();
|
||||
}
|
||||
os.closeChild();
|
||||
}
|
||||
os.closeChild();
|
||||
} else {
|
||||
os.openChild("paramsLinkedTo");
|
||||
os << linkedSetRoot;
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace {
|
|||
string escape(string v) {
|
||||
int i = 0;
|
||||
for (;;) {
|
||||
// Removing escaping of apostrophe from Windows and OSX as it's not needed and causes problems
|
||||
// Removing escaping of apostrophe from Windows and OSX as it's not needed and
|
||||
// causes problems
|
||||
#ifdef LINUX
|
||||
i = v.find_first_of("\\\'\"", i);
|
||||
#else
|
||||
|
@ -353,10 +354,11 @@ TOStream &TOStream::operator<<(string v) {
|
|||
}
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%')
|
||||
|| v[i] < 32 // Less than ASCII for SPACE
|
||||
|| v[i] > 126 // Greater than ASCII for ~
|
||||
) break;
|
||||
if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%') ||
|
||||
v[i] < 32 // Less than ASCII for SPACE
|
||||
|| v[i] > 126 // Greater than ASCII for ~
|
||||
)
|
||||
break;
|
||||
if (i == len)
|
||||
os << v << " ";
|
||||
else {
|
||||
|
@ -381,10 +383,11 @@ TOStream &TOStream::operator<<(QString _v) {
|
|||
}
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%')
|
||||
|| v[i] < 32 // Less than ASCII for SPACE
|
||||
|| v[i] > 126 // Greater than ASCII for ~
|
||||
) break;
|
||||
if ((!iswalnum(v[i]) && v[i] != '_' && v[i] != '%') ||
|
||||
v[i] < 32 // Less than ASCII for SPACE
|
||||
|| v[i] > 126 // Greater than ASCII for ~
|
||||
)
|
||||
break;
|
||||
if (i == len)
|
||||
os << v << " ";
|
||||
else {
|
||||
|
@ -467,7 +470,7 @@ TOStream &TOStream::operator<<(const TPixel64 &v) {
|
|||
|
||||
void TOStream::cr() {
|
||||
*(m_imp->m_os) << endl;
|
||||
for (int i = 0; i < m_imp->m_tab; i++) *(m_imp->m_os) << " ";
|
||||
for (int i = 0; i < m_imp->m_tab; i++) *(m_imp->m_os) << " ";
|
||||
m_imp->m_justStarted = false;
|
||||
}
|
||||
|
||||
|
@ -584,6 +587,10 @@ bool TOStream::checkStatus() const {
|
|||
return m_imp->m_os->rdstate() == ios_base::goodbit;
|
||||
}
|
||||
|
||||
std::string TOStream::getCurrentTagName() {
|
||||
return (m_imp->m_tagStack.empty()) ? "" : m_imp->m_tagStack.back();
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
/*!
|
||||
This class contains TIStream's attributes.
|
||||
|
@ -1109,8 +1116,8 @@ TIStream &TIStream::operator>>(TPersist *&v) {
|
|||
m_imp->m_currentTag = StreamTag();
|
||||
string tagName = tag.m_name;
|
||||
std::map<std::string, string>::iterator it;
|
||||
int id = -1;
|
||||
it = tag.m_attributes.find("id");
|
||||
int id = -1;
|
||||
it = tag.m_attributes.find("id");
|
||||
if (it != tag.m_attributes.end()) id = atoi(it->second.c_str());
|
||||
// cout << "tagname = " << tagName << " id = " << id << endl;
|
||||
|
||||
|
@ -1268,3 +1275,7 @@ void TIStream::setVersion(const VersionNumber &version) {
|
|||
//---------------------------------------------------------------
|
||||
|
||||
void TIStream::skipCurrentTag() { m_imp->skipCurrentTag(); }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
std::string TIStream::getCurrentTagName() { return m_imp->m_tagStack.back(); }
|
|
@ -155,6 +155,8 @@ reimplementation of the TPersist::loadData() function.
|
|||
void skipCurrentTag(); //!< Silently ignores the content of currently opened
|
||||
//! tag up to its end.
|
||||
|
||||
std::string getCurrentTagName();
|
||||
|
||||
private:
|
||||
// Not copyable
|
||||
TIStream(const TIStream &); //!< Not implemented
|
||||
|
@ -266,6 +268,8 @@ checking the status.
|
|||
*/
|
||||
bool checkStatus() const; //!< \b Flushes the stream and checks its validity.
|
||||
|
||||
std::string getCurrentTagName();
|
||||
|
||||
private:
|
||||
// Not copyable
|
||||
TOStream(const TOStream &) = delete; //!< Not implemented
|
||||
|
|
Loading…
Reference in a new issue