diff --git a/CHANGES.md b/CHANGES.md index c7682251..625ef156 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,14 @@ Features: Bug fixes: ------------------------------------------------------------------------------ -version 2.2.2 (Unofficial), 2022-07-19 +version 2.3.0 (Unofficial), 2022-07-29 +------------------------------------------------------------------------------ + +Features: + * Add ability to underline text using `` tags or panel buttons/hotkeys. (haganbmj#30) + +------------------------------------------------------------------------------ +version 2.2.2 (Unofficial), 2022-07-22 ------------------------------------------------------------------------------ Bug fixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index cbc3450a..27aa9610 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.13) -project(magicseteditor VERSION 2.2.2) +project(magicseteditor VERSION 2.3.0) +add_definitions(-DUNOFFICIAL_BUILD) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index 66a4a552..54de6efc 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -67,7 +67,8 @@ menu: format: F&ormat bold: &Bold Ctrl+B - italic: &Italic Ctrl+I + italic: &Italic Ctrl+I + underline: &Underline Ctrl+U symbols: &Symbols Ctrl+M reminder text: &Reminder Text Ctrl+R insert symbol: I&nsert Symbol @@ -187,7 +188,8 @@ help: #format: bold: Makes the selected text bold - italic: Makes the selected text italic + italic: Makes the selected text italic + underline: Makes the selected text underlined symbols: Draws the selected text with symbols reminder text: Show reminder text for the selected keyword # spelling @@ -390,6 +392,7 @@ tooltip: bold: Bold italic: Italic + underline: Underline symbols: Symbols reminder text: Reminder Text diff --git a/resource/tool/underline.png b/resource/tool/underline.png new file mode 100644 index 00000000..90d0df28 Binary files /dev/null and b/resource/tool/underline.png differ diff --git a/resource/win32_res.rc b/resource/win32_res.rc index 6b5d2d66..bbdf8f37 100644 --- a/resource/win32_res.rc +++ b/resource/win32_res.rc @@ -39,6 +39,7 @@ tool/find IMAGE "tool/find.png" tool/bold IMAGE "tool/bold.png" tool/italic IMAGE "tool/italic.png" +tool/underline IMAGE "tool/underline.png" tool/symbol IMAGE "tool/symbol.png" tool/reminder IMAGE "tool/reminder.png" tool/no_auto IMAGE "tool/no_auto.png" diff --git a/src/data/font.cpp b/src/data/font.cpp index d5c34b7c..db81e41b 100644 --- a/src/data/font.cpp +++ b/src/data/font.cpp @@ -50,7 +50,7 @@ void Font::initDependencies(Context& ctx, const Dependency& dep) const { shadow_color.initDependencies(ctx, dep); } -FontP Font::make(int add_flags, String const* other_family, Color const* other_color, double const* other_size) const { +FontP Font::make(int add_flags, bool add_underline, String const* other_family, Color const* other_color, double const* other_size) const { FontP f(new Font(*this)); f->flags |= add_flags; if (add_flags & FONT_CODE_STRING) { @@ -66,6 +66,9 @@ FontP Font::make(int add_flags, String const* other_family, Color const* other_c if (add_flags & FONT_SOFT) { f->color = f->separator_color; f->shadow_displacement = RealSize(0,0); // no shadow + } + if (add_underline) { + f->underline = true; } if (other_color) { f->color = *other_color; diff --git a/src/data/font.hpp b/src/data/font.hpp index 13a055a4..cc030f92 100644 --- a/src/data/font.hpp +++ b/src/data/font.hpp @@ -60,7 +60,7 @@ public: } /// Add style to a font, and optionally change the font family, color and size - FontP make(int add_flags, String const* other_family, Color const* other_color, double const* other_size) const; + FontP make(int add_flags, bool add_underline, String const* other_family, Color const* other_color, double const* other_size) const; /// Convert this font to a wxFont wxFont toWxFont(double scale) const; diff --git a/src/gui/set/cards_panel.cpp b/src/gui/set/cards_panel.cpp index a70e222b..f9fa804d 100644 --- a/src/gui/set/cards_panel.cpp +++ b/src/gui/set/cards_panel.cpp @@ -88,7 +88,8 @@ CardsPanel::CardsPanel(Window* parent, int id) menuFormat = new wxMenu(); add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, "bold", "bold", wxITEM_CHECK); - add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, "italic", "italic", wxITEM_CHECK); + add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, "italic", "italic", wxITEM_CHECK); + add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, "underline", "underline", wxITEM_CHECK); add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, "symbol", "symbols", wxITEM_CHECK); add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, "reminder", "reminder_text", wxITEM_CHECK); menuFormat->AppendSeparator(); @@ -184,7 +185,8 @@ wxMenu* CardsPanel::makeAddCardsSubmenu(bool add_single_card_option) { void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar add_tool_tr(tb, ID_FORMAT_BOLD, "bold", "bold", false, wxITEM_CHECK); - add_tool_tr(tb, ID_FORMAT_ITALIC, "italic", "italic", false, wxITEM_CHECK); + add_tool_tr(tb, ID_FORMAT_ITALIC, "italic", "italic", false, wxITEM_CHECK); + add_tool_tr(tb, ID_FORMAT_UNDERLINE, "underline", "underline", false, wxITEM_CHECK); add_tool_tr(tb, ID_FORMAT_SYMBOL, "symbol", "symbols", false, wxITEM_CHECK); add_tool_tr(tb, ID_FORMAT_REMINDER, "reminder", "reminder_text", false, wxITEM_CHECK); tb->AddSeparator(); @@ -214,7 +216,8 @@ void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { void CardsPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar tb->DeleteTool(ID_FORMAT_BOLD); - tb->DeleteTool(ID_FORMAT_ITALIC); + tb->DeleteTool(ID_FORMAT_ITALIC); + tb->DeleteTool(ID_FORMAT_UNDERLINE); tb->DeleteTool(ID_FORMAT_SYMBOL); tb->DeleteTool(ID_FORMAT_REMINDER); tb->DeleteTool(ID_CARD_ADD); @@ -253,7 +256,7 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) { break; } case ID_CARD_REMOVE: ev.Enable(card_list->canDelete()); break; - case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { + case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_UNDERLINE: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { if (focused_control(this) == ID_EDITOR) { ev.Enable(editor->canFormat(ev.GetId())); ev.Check (editor->hasFormat(ev.GetId())); @@ -327,7 +330,7 @@ void CardsPanel::onCommand(int id) { case ID_SELECT_COLUMNS: { card_list->selectColumns(); } - case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { + case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_UNDERLINE: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { if (focused_control(this) == ID_EDITOR) { editor->doFormat(id); } diff --git a/src/gui/set/set_info_panel.cpp b/src/gui/set/set_info_panel.cpp index d421e0f3..4e65fd37 100644 --- a/src/gui/set/set_info_panel.cpp +++ b/src/gui/set/set_info_panel.cpp @@ -35,14 +35,16 @@ void SetInfoPanel::onChangeSet() { void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar add_tool_tr(tb, ID_FORMAT_BOLD, "bold", "bold", false, wxITEM_CHECK); - add_tool_tr(tb, ID_FORMAT_ITALIC, "italic", "italic", false, wxITEM_CHECK); + add_tool_tr(tb, ID_FORMAT_ITALIC, "italic", "italic", false, wxITEM_CHECK); + add_tool_tr(tb, ID_FORMAT_UNDERLINE, "underline", "underline", false, wxITEM_CHECK); add_tool_tr(tb, ID_FORMAT_SYMBOL, "symbol", "symbols", false, wxITEM_CHECK); add_tool_tr(tb, ID_FORMAT_REMINDER, "reminder", "reminder_text", false, wxITEM_CHECK); tb->Realize(); // Menus auto menuFormat = new wxMenu(); add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, "bold", "bold", wxITEM_CHECK); - add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, "italic", "italic", wxITEM_CHECK); + add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, "italic", "italic", wxITEM_CHECK); + add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, "underline", "underline", wxITEM_CHECK); add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, "symbol", "symbols", wxITEM_CHECK); add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, "reminder", "reminder_text", wxITEM_CHECK); mb->Insert(2, menuFormat, _MENU_("format")); @@ -53,7 +55,8 @@ void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) { void SetInfoPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) { // Toolbar tb->DeleteTool(ID_FORMAT_BOLD); - tb->DeleteTool(ID_FORMAT_ITALIC); + tb->DeleteTool(ID_FORMAT_ITALIC); + tb->DeleteTool(ID_FORMAT_UNDERLINE); tb->DeleteTool(ID_FORMAT_SYMBOL); tb->DeleteTool(ID_FORMAT_REMINDER); // Menus @@ -62,7 +65,7 @@ void SetInfoPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) { void SetInfoPanel::onUpdateUI(wxUpdateUIEvent& ev) { switch (ev.GetId()) { - case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { + case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_UNDERLINE: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { ev.Enable(editor->canFormat(ev.GetId())); ev.Check (editor->hasFormat(ev.GetId())); break; @@ -72,7 +75,7 @@ void SetInfoPanel::onUpdateUI(wxUpdateUIEvent& ev) { void SetInfoPanel::onCommand(int id) { switch (id) { - case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { + case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_UNDERLINE: case ID_FORMAT_SYMBOL: case ID_FORMAT_REMINDER: { editor->doFormat(id); break; } diff --git a/src/gui/symbol/part_list.cpp b/src/gui/symbol/part_list.cpp index 310b21c3..24445514 100644 --- a/src/gui/symbol/part_list.cpp +++ b/src/gui/symbol/part_list.cpp @@ -266,8 +266,10 @@ void SymbolPartList::onChar(wxKeyEvent& ev) { } break; default: - // See gui/value/text.cpp - #ifdef __WXMSW__ + // See gui/value/text.cpp + #if defined UNICODE + if (ev.GetUnicodeKey() >= WXK_SPACE) { + #elif defined __WXMSW__ if (ev.GetKeyCode() >= _(' ') && ev.GetKeyCode() == (int)ev.GetRawKeyCode()) { #else if (ev.GetKeyCode() >= _(' ') /*&& ev.GetKeyCode() == (int)ev.GetRawKeyCode()*/) { diff --git a/src/gui/value/text.cpp b/src/gui/value/text.cpp index cb705b27..703cb0e7 100644 --- a/src/gui/value/text.cpp +++ b/src/gui/value/text.cpp @@ -805,7 +805,7 @@ bool TextValueEditor::doDelete() { bool TextValueEditor::canFormat(int type) const { switch (type) { - case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: + case ID_FORMAT_BOLD: case ID_FORMAT_ITALIC: case ID_FORMAT_UNDERLINE: return !style().always_symbol && style().allow_formating; case ID_FORMAT_SYMBOL: return !style().always_symbol && style().allow_formating && style().symbol_font.valid(); @@ -822,7 +822,9 @@ bool TextValueEditor::hasFormat(int type) const { case ID_FORMAT_BOLD: return is_in_tag(value().value(), _(" 0 ? FONT_SOFT : FONT_NORMAL) | (code > 0 ? FONT_CODE : FONT_NORMAL) | (code_kw > 0 ? FONT_CODE_KW : FONT_NORMAL) | - (code_string > 0 ? FONT_CODE_STRING : FONT_NORMAL), + (code_string > 0 ? FONT_CODE_STRING : FONT_NORMAL), + underline > 0, fonts.empty() ? nullptr : &fonts.back(), param > 0 || param_ref > 0 ? ¶m_colors[(param_id++) % param_colors_count] diff --git a/src/script/functions/export.cpp b/src/script/functions/export.cpp index 89908299..361112a8 100644 --- a/src/script/functions/export.cpp +++ b/src/script/functions/export.cpp @@ -209,7 +209,8 @@ String to_html(const String& str_in, const SymbolFontP& symbol_font, double symb String str = remove_tag_contents(str_in,_(""), _("")), - italic(_(""), _("")), + italic(_(""), _("")), + underline(_(""), _("")), symbol(_(""), _("")); TagStack tags; String symbols; @@ -224,7 +225,11 @@ String to_html(const String& str_in, const SymbolFontP& symbol_font, double symb } else if (is_substr(str, i, _("i"))) { tags.open (ret, italic); } else if (is_substr(str, i, _("/i"))) { - tags.close(ret, italic); + tags.close(ret, italic); + } else if (is_substr(str, i, _("u"))) { + tags.open(ret, underline); + } else if (is_substr(str, i, _("/u"))) { + tags.close(ret, underline); } else if (is_substr(str, i, _("sym"))) { tags.open (ret, symbol); } else if (is_substr(str, i, _("/sym"))) { @@ -300,7 +305,8 @@ String to_bbcode(const String& str_in) { String str = remove_tag_contents(str_in,_(" is the negation of tag) bool add_or_cancel_tag(const String& tag, String& stack, bool all = false) { if (all || starts_with(tag, _("/")) || - starts_with(tag, _("b")) || starts_with(tag, _("i")) || starts_with(tag, _("sym"))) { + starts_with(tag, _("b")) || + starts_with(tag, _("i")) || + starts_with(tag, _("u")) || + starts_with(tag, _("sym"))) { // cancel out all close tags, but not all open tags, // so is always removed // but is not @@ -692,8 +695,10 @@ String simplify_tagged_overlap(const String& str) { Char c = str.GetChar(i); if (c == _('<')) { String tag = tag_at(str, i); - if (starts_with(tag, _("b")) || starts_with(tag, _("i")) || starts_with(tag, _("sym")) || - starts_with(tag, _("/b")) || starts_with(tag, _("/i")) || starts_with(tag, _("/sym"))) { + if (starts_with(tag, _("b")) || starts_with(tag, _("/b")) || + starts_with(tag, _("i")) || starts_with(tag, _("/i")) || + starts_with(tag, _("u")) || starts_with(tag, _("/u")) || + starts_with(tag, _("sym")) || starts_with(tag, _("/sym"))) { // optimize this tag if (open_tags.find(_("<") + tag + _(">")) == String::npos) { // we are not already inside this tag diff --git a/src/util/version.cpp b/src/util/version.cpp index 319f26b2..0aebbcab 100644 --- a/src/util/version.cpp +++ b/src/util/version.cpp @@ -51,11 +51,14 @@ template <> void GetDefaultMember::handle(const Version& v) { // ----------------------------------------------------------------------------- : Versions // NOTE: Don't use leading zeroes, they mean octal -const Version app_version = 10000 * MSE_VERSION_MAJOR + 100 * MSE_VERSION_MINOR + MSE_VERSION_PATCH; -#ifdef UNICODE -const Char* version_suffix = _(""); -#else -const Char* version_suffix = _(" (ascii build)"); +const Version app_version = 10000 * MSE_VERSION_MAJOR + 100 * MSE_VERSION_MINOR + MSE_VERSION_PATCH; + +#if defined UNOFFICIAL_BUILD +const Char* version_suffix = _(" (Unofficial)"); +#elif defined UNICODE +const Char* version_suffix = _(""); +#else +const Char* version_suffix = _(" (ascii build)"); #endif /// Which version of MSE are the files we write out compatible with? diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index 2506828b..35b84be8 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -115,7 +115,8 @@ enum ChildMenuID { // Format menu ID_FORMAT_BOLD = 6201, - ID_FORMAT_ITALIC, + ID_FORMAT_ITALIC, + ID_FORMAT_UNDERLINE, ID_FORMAT_SYMBOL, ID_FORMAT_REMINDER, ID_INSERT_SYMBOL,