#include "stdafx.h" #include "common.h" #include "sabbu.h" #include "kryString.h" #include "kryArray.h" #include "krySSACommandParser.h" #include "krySSACommandHighlighter.h" #include "spell.h" //#include "gui_spell.h" #include "gui_text_editor.h" extern struct sabbu app; krySSACommandHighlighterHiddenPart::krySSACommandHighlighterHiddenPart() : m_strings(NULL) { } krySSACommandHighlighterHiddenPart::~krySSACommandHighlighterHiddenPart() { for(GList *ptr = this->m_strings; ptr; ptr = ptr->next) kry_free(ptr->data); g_list_free(this->m_strings); } void krySSACommandHighlighterHiddenPart::AddString(char *text) { this->m_strings = g_list_append(this->m_strings, kry_strdup(text)); } GList *krySSACommandHighlighterHiddenPart::GetStringGList() { return this->m_strings; } krySSACommandHighlighterHiddenPartList::krySSACommandHighlighterHiddenPartList() : m_parts(NULL), m_part_cur(NULL) { } krySSACommandHighlighterHiddenPartList::~krySSACommandHighlighterHiddenPartList() { for(GList *ptr = this->m_parts; ptr; ptr = ptr->next) delete ((krySSACommandHighlighterHiddenPart *) ptr->data); g_list_free(this->m_parts); } void krySSACommandHighlighterHiddenPartList::StartPart() { krySSACommandHighlighterHiddenPart *part = new krySSACommandHighlighterHiddenPart(); this->m_parts = g_list_append(this->m_parts, part); this->m_part_cur = part; } void krySSACommandHighlighterHiddenPartList::AddText(char *text) { if(!this->m_part_cur) this->StartPart(); this->m_part_cur->AddString(text); } void krySSACommandHighlighterHiddenPartList::EndPart() { this->m_part_cur = NULL; } GList *krySSACommandHighlighterHiddenPartList::GetGList() { return this->m_parts; } // this class can probably be obsoleted by improving the parent class krySSACommandHighlighter::krySSACommandHighlighter(kryString str, gboolean icon_mode, GList *cursors) { this->m_state = kry_new0(struct krySSACommandHighlighterState); this->m_alternate_tag = FALSE; this->m_is_last_tag_command = FALSE; this->m_is_icon_mode = icon_mode; this->m_parts = NULL; this->m_length_parts = 0; this->m_hidden_parts = new krySSACommandHighlighterHiddenPartList(); this->m_free_hidden_parts = TRUE; this->m_cursors = g_list_copy(cursors); this->m_state->m_buffer_strings = FALSE; this->m_state->m_str_pos = 0; ParseSubtitleString(str); } krySSACommandHighlighter::~krySSACommandHighlighter() { kry_free(this->m_state); if(this->m_free_hidden_parts) delete this->m_hidden_parts; g_list_foreach(this->m_parts, (GFunc) kry_free_minimal, NULL); g_list_free(this->m_parts); } krySSACommandHighlighterHiddenPartList *krySSACommandHighlighter::GetHiddenPartList() { this->m_free_hidden_parts = FALSE; return this->m_hidden_parts; } void krySSACommandHighlighter::AddPart(char *str, int len, enum highlight_type type) { struct krySSACommandHighlighterPart *part = kry_new(struct krySSACommandHighlighterPart, 1); part->type = type; part->text = kry_strdup(str); this->m_parts = g_list_append(this->m_parts, part); this->m_length_parts += len; } void krySSACommandHighlighter::OnAnything(kryString &str, gboolean is_command, enum highlight_type highlight_type) { if(this->m_state->m_buffer_strings) { this->m_state->m_unprocessed.Add(new kryString(str)); return; } this->m_state->m_str_pos += str.GetLength(); if(is_command && this->m_is_icon_mode) { this->m_hidden_parts->AddText(str.GetBuffer()); } else { this->AddPart(str.GetBuffer(), str.GetLength(), highlight_type); } if(this->m_is_icon_mode) { GList *ptr_next; for(GList *ptr = this->m_cursors; ptr; ptr = ptr_next) { ptr_next = ptr->next; int *cursor = (int *) ptr->data; if(this->m_state->m_str_pos >= *cursor) { *cursor = this->m_length_parts - (this->m_state->m_str_pos - *cursor); this->m_cursors = g_list_delete_link(this->m_cursors, ptr); } } } } void krySSACommandHighlighter::OnString(kryString &str, int offset) { this->m_hidden_parts->EndPart(); this->m_is_last_tag_command = FALSE; this->OnAnything(str, FALSE, HIGHLIGHT_TEXT); } void krySSACommandHighlighter::OnCommandGroupStart(kryString str, int offset) { if(this->m_is_icon_mode && this->m_is_last_tag_command != TRUE) { this->AddPart("\xEF\xBF\xBC\x00", 1, HIGHLIGHT_GEAR); this->m_is_last_tag_command = TRUE; } this->OnAnything(str); } void krySSACommandHighlighter::OnCommandGroupEnd(kryString str, int offset) { this->OnAnything(str); } void krySSACommandHighlighter::OnCommandParameterStart(kryString str) { this->OnAnything(str, TRUE, (this->m_alternate_tag ? HIGHLIGHT_COMMAND2 : HIGHLIGHT_COMMAND1)); } void krySSACommandHighlighter::OnCommandParameterEnd(kryString str) { this->OnAnything(str, TRUE, (this->m_alternate_tag ? HIGHLIGHT_COMMAND2 : HIGHLIGHT_COMMAND1)); } void krySSACommandHighlighter::OnCommandParameter(kryString &str) { kryString str2(str); if(!str2.Trim().IsEmpty() && this->m_state->m_buffer_strings && this->m_state->m_parameter_count < 4) { this->m_state->m_last_parameter_index = this->m_state->m_unprocessed.GetCount(); this->m_state->m_parameter_count++; } this->OnAnything(str); } void krySSACommandHighlighter::OnCommandParameterSeparator(kryString str) { this->OnAnything(str); } void krySSACommandHighlighter::OnCommandUnparsed(kryString &str) { this->OnAnything(str, TRUE, HIGHLIGHT_ERROR); } void krySSACommandHighlighter::OnCommandText(kryString &str) { if(!this->m_is_icon_mode && str == "\\t") { this->m_state->m_buffer_strings = TRUE; this->m_state->m_last_parameter_index = -1; this->m_state->m_parameter_count = 0; } this->OnAnything(str, TRUE, (this->m_alternate_tag ? HIGHLIGHT_COMMAND2 : HIGHLIGHT_COMMAND1)); } void krySSACommandHighlighter::OnCommandEnd() { if(!this->m_state->m_buffer_strings) { this->m_alternate_tag = !this->m_alternate_tag; return; } kryListIterator iter; this->m_state->m_buffer_strings = FALSE; this->m_state->m_unprocessed.GetIterator(&iter); int index = 0; while(kryString *str = iter.GetNext()) { if(index == this->m_state->m_last_parameter_index) { struct krySSACommandHighlighterState *state_old = this->m_state; this->m_state = kry_new0(struct krySSACommandHighlighterState); ParseSSATag(*str); kry_free(this->m_state); this->m_state = state_old; } else if(index == 0) { this->OnAnything(*str, TRUE, (this->m_alternate_tag ? HIGHLIGHT_COMMAND2 : HIGHLIGHT_COMMAND1)); } else { this->OnAnything(*str); } delete str; index++; } this->m_state->m_unprocessed.Clear(); } GList *krySSACommandHighlighter::GetPartList() { return this->m_parts; } char *krySSACommandHighlighter::GetStringFromPartList() { int length = 0; for(GList *ptr = this->m_parts; ptr; ptr = ptr->next) { struct krySSACommandHighlighterPart *part = (struct krySSACommandHighlighterPart *) ptr->data; length += strlen(part->text); } int offset = 0; char *newstr = (char *) kry_malloc(length + 1); newstr[length] = 0; for(GList *ptr = this->m_parts; ptr; ptr = ptr->next) { struct krySSACommandHighlighterPart *part = (struct krySSACommandHighlighterPart *) ptr->data; int len = strlen(part->text); memcpy(newstr + offset, part->text, len); offset += len; } return newstr; }