bool MCStyledText::visit(MCVisitStyle p_style, uint32_t p_part, MCObjectVisitor *p_visitor) { bool t_continue; t_continue = true; if (p_style == VISIT_STYLE_DEPTH_LAST) t_continue = p_visitor -> OnStyledText(this); if (t_continue && m_paragraphs != NULL) { MCParagraph *pgptr = m_paragraphs; MCParagraph *tpgptr = pgptr; do { t_continue = tpgptr -> visit(p_style, p_part, p_visitor); tpgptr = tpgptr->next(); } while(t_continue && tpgptr != pgptr); } if (p_style == VISIT_STYLE_DEPTH_FIRST) t_continue = p_visitor -> OnStyledText(this); return t_continue; }
MCUndonode::~MCUndonode() { object->freeundo(savedata); switch (savedata->type) { case UT_DELETE: delete object; break; case UT_DELETE_TEXT: case UT_REPLACE_TEXT: case UT_TYPE_TEXT: case UT_MOVE_TEXT: { MCParagraph *pgptr = (MCParagraph *)savedata->ud.text.data; while (pgptr != NULL) { MCParagraph *tpgptr = pgptr->remove (pgptr); delete tpgptr; } } break; default: break; } delete savedata; }
MCParagraph *MCCdata::getparagraphs() { MCParagraph *paragraphs; if (id & COMPACT_PARAGRAPHS) { paragraphs = NULL; char *eptr = (char *)data; while ((eptr = strtok(eptr, "\n")) != NULL) { MCParagraph *tpgptr = new MCParagraph; tpgptr->appendto(paragraphs); uint2 l = strlen(eptr) + 1; char *sptr = new char[l]; memcpy(sptr, eptr, l); tpgptr->settext(sptr, l, false); eptr = NULL; } delete (char *)data; data = paragraphs; id &= ~COMPACT_PARAGRAPHS; } if (data == NULL) data = paragraphs = new MCParagraph; else paragraphs = (MCParagraph *)data; return paragraphs; }
IO_stat MCCdata::load(IO_handle stream, MCObject *parent, const char *version) { IO_stat stat; if ((stat = IO_read_uint4(&id, stream)) != IO_NORMAL) return stat; if (parent->gettype() == CT_BUTTON) { uint1 set; stat = IO_read_uint1(&set, stream); data = (void *)(set ? 1 : 0); return stat; } else { if (id & COMPACT_PARAGRAPHS) { char *string; if ((stat = IO_read_string(string, stream, sizeof(uint1))) != IO_NORMAL) return stat; data = string; } else { MCParagraph *paragraphs = NULL; while (True) { uint1 type; if ((stat = IO_read_uint1(&type, stream)) != IO_NORMAL) return stat; switch (type) { // MW-2012-03-04: [[ StackFile5500 ]] Handle either the paragraph or extended // paragraph tag. case OT_PARAGRAPH: case OT_PARAGRAPH_EXT: { MCParagraph *newpar = new MCParagraph; newpar->setparent((MCField *)parent); // MW-2012-03-04: [[ StackFile5500 ]] If the paragraph tab was the extended // variant, then pass the correct is_ext parameter. if ((stat = newpar->load(stream, version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL) { delete newpar; return stat; } newpar->appendto(paragraphs); } break; default: data = paragraphs; MCS_seek_cur(stream, -1); return IO_NORMAL; } } } } return IO_NORMAL; }
IO_stat MCCdata::save(IO_handle stream, Object_type type, uint4 p_part) { IO_stat stat; // If p_part is non-zero it means we only want to save data specific // to a given card. In this case, we simply don't save the rest. if (p_part != 0 && id != p_part) return IO_NORMAL; if ((stat = IO_write_uint1(type, stream)) != IO_NORMAL) return stat; if ((stat = IO_write_uint4(p_part != 0 ? 0 : id, stream)) != IO_NORMAL) return stat; if (type == OT_BDATA) { uint1 set = data ? 1 : 0; return IO_write_uint1(set, stream); } else if (id & COMPACT_PARAGRAPHS) return IO_write_string((char *)data, stream, sizeof(uint1)); else { MCParagraph *tptr = (MCParagraph *)data; if (tptr != NULL) do { if ((stat = tptr->save(stream, p_part)) != IO_NORMAL) return stat; tptr = (MCParagraph *)tptr->next(); } while (tptr != data); } return IO_NORMAL; }
void MCCdata::CloneData(const MCCdata& cref, MCField* p_new_owner) { id = cref.id; if (cref.data != NULL && cref.data != (void *)1) { if (id & COMPACT_PARAGRAPHS) data = strclone((char *)cref.data); else { MCParagraph *paragraphs = NULL; MCParagraph *tptr = (MCParagraph *)cref.data; do { // Clone the paragraph MCParagraph *newparagraph = new (nothrow) MCParagraph(*tptr); newparagraph->setparent(p_new_owner); newparagraph->appendto(paragraphs); tptr = (MCParagraph *)tptr->next(); } while (tptr != cref.data); data = paragraphs; } } else data = cref.data; }
MCParagraph *MCCdata::getparagraphs() { MCParagraph *paragraphs; if (id & COMPACT_PARAGRAPHS) { paragraphs = NULL; char *eptr = (char *)data; while ((eptr = strtok(eptr, "\n")) != NULL) { MCParagraph *tpgptr = new (nothrow) MCParagraph; tpgptr->appendto(paragraphs); uint2 l = strlen(eptr) + 1; /* UNCHECKED */ MCAutoPointer<char_t[]> sptr = new (nothrow) char_t[l]; memcpy(sptr.Get(), eptr, l); MCAutoStringRef t_string; /* UNCHECKED */ MCStringCreateWithNativeChars(sptr.Get(), l, &t_string); tpgptr->settext(*t_string); eptr = NULL; } delete (char *)data; data = paragraphs; id &= ~COMPACT_PARAGRAPHS; } if (data == NULL) data = paragraphs = new (nothrow) MCParagraph; else paragraphs = (MCParagraph *)data; return paragraphs; }
MCCdata::~MCCdata() { if (data != NULL && data != (void *)1) { if (id & COMPACT_PARAGRAPHS) delete (char *)data; else { MCParagraph *paragraphs = (MCParagraph *)data; while (paragraphs != NULL) { MCParagraph *pptr = (MCParagraph *)paragraphs->remove (paragraphs); delete pptr; } } } }
IO_stat MCCdata::save(IO_handle stream, Object_type type, uint4 p_part, MCObject *p_parent, uint32_t p_version) { IO_stat stat; // If p_part is non-zero it means we only want to save data specific // to a given card. In this case, we simply don't save the rest. if (p_part != 0 && id != p_part) return IO_NORMAL; if ((stat = IO_write_uint1(type, stream)) != IO_NORMAL) return stat; if ((stat = IO_write_uint4(p_part != 0 ? 0 : id, stream)) != IO_NORMAL) return stat; if (type == OT_BDATA) { uint1 set = data ? 1 : 0; return IO_write_uint1(set, stream); } else if (id & COMPACT_PARAGRAPHS) { // MW-2013-11-19: [[ UnicodeFileFormat ]] This flag is never set by newer engines // so is just legacy. (Indeed, this codepath should never be hit!). return IO_write_cstring_legacy((char *)data, stream, sizeof(uint1)); } else { MCParagraph *tptr = (MCParagraph *)data; if (tptr != NULL) do { // Ensure field's saved MCCdata paragraphs have a parent when needed if (p_parent != nil) tptr -> setparent(MCObjectCast<MCField>(p_parent)); if ((stat = tptr->save(stream, p_part, p_version)) != IO_NORMAL) return stat; tptr = (MCParagraph *)tptr->next(); } while (tptr != data); } return IO_NORMAL; }
// MW-2011-01-13: As styledtext is an internal (not published in anyway) format // we can change it to include the paragraph style for now. IO_stat MCStyledText::save(IO_handle p_stream, uint4 p_part, bool p_force_ext) { IO_stat stat; if ((stat = IO_write_uint1(OT_STYLED_TEXT, p_stream)) != IO_NORMAL) return stat; MCParagraph *tptr = m_paragraphs; if (tptr != NULL) do { if ((stat = tptr->save(p_stream, p_part)) != IO_NORMAL) return stat; tptr = (MCParagraph *)tptr->next(); } while (tptr != m_paragraphs); return IO_NORMAL; }
IO_stat MCStyledText::load(IO_handle p_stream, const char *p_version) { IO_stat stat; MCParagraph *paragraphs = NULL; while (True) { uint1 type; if ((stat = IO_read_uint1(&type, p_stream)) != IO_NORMAL) return stat; switch (type) { // MW-2012-03-04: [[ StackFile5500 ]] Handle both the paragraph and extended // paragraph record. case OT_PARAGRAPH: case OT_PARAGRAPH_EXT: { MCParagraph *newpar = new MCParagraph; newpar->setparent((MCField *)parent); // MW-2012-03-04: [[ StackFile5500 ]] If the record is extended then // pass in 'true' for 'is_ext'. if ((stat = newpar->load(p_stream, p_version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL) { delete newpar; return stat; } newpar->appendto(paragraphs); } break; default: m_paragraphs = paragraphs; MCS_seek_cur(p_stream, -1); return IO_NORMAL; } } return IO_NORMAL; }
MCCdata::MCCdata(const MCCdata &cref) : MCDLlist(cref) { id = cref.id; if (cref.data != NULL && cref.data != (void *)1) { if (id & COMPACT_PARAGRAPHS) data = strclone((char *)cref.data); else { MCParagraph *paragraphs = NULL; MCParagraph *tptr = (MCParagraph *)cref.data; do { MCParagraph *newparagraph = new MCParagraph(*tptr); newparagraph->appendto(paragraphs); tptr = (MCParagraph *)tptr->next(); } while (tptr != cref.data); data = paragraphs; } } else data = cref.data; }
IO_stat MCCdata::load(IO_handle stream, MCObject *parent, uint32_t version) { IO_stat stat; if ((stat = IO_read_uint4(&id, stream)) != IO_NORMAL) return checkloadstat(stat); if (parent->gettype() == CT_BUTTON) { uint1 set; stat = IO_read_uint1(&set, stream); data = reinterpret_cast<void *>(set ? 1 : 0); return checkloadstat(stat); } else { if (id & COMPACT_PARAGRAPHS) { // MW-2013-11-19: [[ UnicodeFileFormat ]] This flag is never set by newer engines // so is just legacy. char *string; if ((stat = IO_read_cstring_legacy(string, stream, sizeof(uint1))) != IO_NORMAL) return checkloadstat(stat); data = string; } else { MCParagraph *paragraphs = NULL; while (True) { uint1 type; if ((stat = IO_read_uint1(&type, stream)) != IO_NORMAL) return checkloadstat(stat); switch (type) { // MW-2012-03-04: [[ StackFile5500 ]] Handle either the paragraph or extended // paragraph tag. case OT_PARAGRAPH: case OT_PARAGRAPH_EXT: { MCParagraph *newpar = new (nothrow) MCParagraph; newpar->setparent((MCField *)parent); // MW-2012-03-04: [[ StackFile5500 ]] If the paragraph tab was the extended // variant, then pass the correct is_ext parameter. if ((stat = newpar->load(stream, version, type == OT_PARAGRAPH_EXT)) != IO_NORMAL) { delete newpar; return checkloadstat(stat); } newpar->appendto(paragraphs); } break; default: data = paragraphs; MCS_seek_cur(stream, -1); return IO_NORMAL; } } } } return IO_NORMAL; }