diff --git a/aegisub/src/ass_style_storage.cpp b/aegisub/src/ass_style_storage.cpp index 6d695bfd8..3edb1580a 100644 --- a/aegisub/src/ass_style_storage.cpp +++ b/aegisub/src/ass_style_storage.cpp @@ -60,7 +60,7 @@ void AssStyleStorage::Save() { throw "Failed creating directory for style catalogs"; TextFileWriter file(StandardPaths::DecodePath("?user/catalog/" + storage_name + ".sty"), "UTF-8"); - for (std::list::iterator cur = style.begin(); cur != style.end(); ++cur) + for (iterator cur = begin(); cur != end(); ++cur) file.WriteLineToFile((*cur)->GetEntryData()); } @@ -87,20 +87,24 @@ void AssStyleStorage::Load(wxString const& name) { } } -void AssStyleStorage::Clear () { +void AssStyleStorage::Clear() { delete_clear(style); } +void AssStyleStorage::Delete(int idx) { + delete style[idx]; + style.erase(style.begin() + idx); +} + wxArrayString AssStyleStorage::GetNames() { wxArrayString names; - for (std::list::iterator cur=style.begin();cur!=style.end();cur++) { + for (iterator cur = begin(); cur != end(); ++cur) names.Add((*cur)->name); - } return names; } -AssStyle *AssStyleStorage::GetStyle(wxString name) { - for (std::list::iterator cur = style.begin(); cur != style.end(); ++cur) { +AssStyle *AssStyleStorage::GetStyle(wxString const& name) { + for (iterator cur = begin(); cur != end(); ++cur) { if ((*cur)->name.CmpNoCase(name) == 0) return *cur; } diff --git a/aegisub/src/ass_style_storage.h b/aegisub/src/ass_style_storage.h index eba2dec9a..c50922145 100644 --- a/aegisub/src/ass_style_storage.h +++ b/aegisub/src/ass_style_storage.h @@ -35,7 +35,7 @@ /// #ifndef AGI_PRE -#include +#include #include #endif @@ -49,10 +49,18 @@ class AssStyle; /// DOCME class AssStyleStorage { wxString storage_name; + std::deque style; + public: ~AssStyleStorage(); - std::list style; + typedef std::deque::iterator iterator; + iterator begin() { return style.begin(); } + iterator end() { return style.end(); } + void push_back(AssStyle *new_style) { style.push_back(new_style); } + AssStyle *back() { return style.back(); } + AssStyle *operator[](size_t idx) const { return style[idx]; } + size_t size() const { return style.size(); } /// Get the names of all styles in this storage wxArrayString GetNames(); @@ -60,10 +68,13 @@ public: /// Delete all styles in this storage void Clear(); + /// Delete the style at the given index + void Delete(int idx); + /// Get the style with the given name /// @param name Case-insensitive style name /// @return Style or NULL if the requested style is not found - AssStyle *GetStyle(wxString name); + AssStyle *GetStyle(wxString const& name); /// Save stored styles to a file void Save(); diff --git a/aegisub/src/dialog_style_editor.cpp b/aegisub/src/dialog_style_editor.cpp index ba61719e1..b06f2e9f8 100644 --- a/aegisub/src/dialog_style_editor.cpp +++ b/aegisub/src/dialog_style_editor.cpp @@ -464,7 +464,7 @@ void DialogStyleEditor::Apply(bool apply, bool close) { style->UpdateData(); if (is_new) { if (store) - store->style.push_back(style); + store->push_back(style); else c->ass->InsertStyle(style); is_new = false; diff --git a/aegisub/src/dialog_style_manager.cpp b/aegisub/src/dialog_style_manager.cpp index 416b31f6f..d01b3b056 100644 --- a/aegisub/src/dialog_style_manager.cpp +++ b/aegisub/src/dialog_style_manager.cpp @@ -272,23 +272,19 @@ void DialogStyleManager::LoadCurrentStyles(AssFile *subs) { UpdateButtons(); } -void DialogStyleManager::LoadStorageStyles() { - StorageList->Clear(); - styleStorageMap.clear(); +void DialogStyleManager::UpdateStorage() { + Store.Save(); - for (std::list::iterator cur=Store.style.begin();cur!=Store.style.end();cur++) { - AssStyle *style = *cur; - StorageList->Append(style->name); - styleStorageMap.push_back(style); - } + StorageList->Clear(); + for (AssStyleStorage::iterator cur = Store.begin(); cur != Store.end(); ++cur) + StorageList->Append((*cur)->name); UpdateButtons(); } void DialogStyleManager::OnChangeCatalog() { Store.Load(CatalogList->GetStringSelection()); - LoadStorageStyles(); - UpdateButtons(); + UpdateStorage(); } void DialogStyleManager::OnCatalogNew() { @@ -322,8 +318,7 @@ void DialogStyleManager::OnCatalogNew() { CatalogList->SetStringSelection(name); Store.Load(name); - Store.Save(); - StorageList->Clear(); + UpdateStorage(); } UpdateButtons(); } @@ -346,12 +341,12 @@ void DialogStyleManager::OnStorageEdit() { wxArrayInt selections; int n = StorageList->GetSelections(selections); if (n == 1) { - AssStyle *selStyle = styleStorageMap[selections[0]]; + AssStyle *selStyle = Store[selections[0]]; DialogStyleEditor(this, selStyle, c, &Store).ShowModal(); - StorageList->SetString(selections[0], selStyle->name); - Store.Save(); + UpdateStorage(); + StorageList->SetStringSelection(selStyle->name); + UpdateButtons(); } - UpdateButtons(); } void DialogStyleManager::OnCurrentEdit() { @@ -384,15 +379,15 @@ void DialogStyleManager::OnCopyToStorage() { } } if (addStyle) { - Store.style.push_back(new AssStyle(*styleMap.at(selections[i]))); + Store.push_back(new AssStyle(*styleMap.at(selections[i]))); copied.push_back(styleName); } } - Store.Save(); - LoadStorageStyles(); - for (std::list::iterator name = copied.begin(); name != copied.end(); ++name) { + + UpdateStorage(); + for (std::list::iterator name = copied.begin(); name != copied.end(); ++name) StorageList->SetStringSelection(*name, true); - } + UpdateButtons(); } @@ -408,14 +403,14 @@ void DialogStyleManager::OnCopyToCurrent() { if ((*style)->name.CmpNoCase(styleName) == 0) { addStyle = false; if (wxYES == wxMessageBox(wxString::Format(_("There is already a style with the name \"%s\" in the current script. Proceed and overwrite anyway?"), styleName), _("Style name collision"), wxYES_NO)) { - **style = *styleStorageMap.at(selections[i]); + **style = *Store[selections[i]]; copied.push_back(styleName); } break; } } if (addStyle) { - c->ass->InsertStyle(new AssStyle(*styleStorageMap.at(selections[i]))); + c->ass->InsertStyle(new AssStyle(*Store[selections[i]])); copied.push_back(styleName); } } @@ -443,13 +438,12 @@ void DialogStyleManager::OnStorageCopy() { StorageList->GetSelections(selections); if (selections.empty()) return; - AssStyle *s = styleStorageMap[selections[0]]; + AssStyle *s = Store[selections[0]]; DialogStyleEditor editor(this, s, c, &Store, unique_name(bind(&AssStyleStorage::GetStyle, &Store, _1), s->name)); if (editor.ShowModal()) { - Store.Save(); - LoadStorageStyles(); + UpdateStorage(); StorageList->SetStringSelection(editor.GetStyleName()); UpdateButtons(); } @@ -471,7 +465,8 @@ void DialogStyleManager::OnCurrentCopy() { } } -void DialogStyleManager::CopyToClipboard(wxListBox *list, std::vector v) { +template +void DialogStyleManager::CopyToClipboard(wxListBox *list, T const& v) { wxString data; wxArrayInt selections; list->GetSelections(selections); @@ -529,17 +524,18 @@ void DialogStyleManager::PasteToCurrent() { void DialogStyleManager::PasteToStorage() { add_styles( bind(&AssStyleStorage::GetStyle, &Store, _1), - bind(&std::list::push_back, &Store.style, _1)); + bind(&AssStyleStorage::push_back, &Store, _1)); - Store.Save(); - LoadStorageStyles(); - StorageList->SetStringSelection(Store.style.back()->name); + UpdateStorage(); + StorageList->SetStringSelection(Store.back()->name); + UpdateButtons(); } void DialogStyleManager::OnStorageNew() { - DialogStyleEditor(this, 0, c, &Store).ShowModal(); - Store.Save(); - LoadStorageStyles(); + bool did_add = !!DialogStyleEditor(this, 0, c, &Store).ShowModal(); + UpdateStorage(); + if (did_add) + StorageList->SetStringSelection(Store.back()->name); UpdateButtons(); } @@ -561,15 +557,10 @@ void DialogStyleManager::OnStorageDelete() { int n = StorageList->GetSelections(selections); if (confirm_delete(n, this, _("Confirm delete from storage")) == wxYES) { - for (int i=0;iFindString mess is a silly workaround for the fact that to vsfilter - // (and the duplicate check a few lines above), style names aren't case sensitive, but to the - // rest of Aegisub they are. - *(c->ass->GetStyle(CurrentList->GetString(CurrentList->FindString(styles[selections[i]], false)))) = *temp.GetStyle(styles[selections[i]]); + // The result of GetString is used rather than the name + // itself to deal with that AssFile::GetStyle is + // case-sensitive, but style names are case insensitive + *c->ass->GetStyle(CurrentList->GetString(test)) = *temp.GetStyle(styles[selections[i]]); } continue; } @@ -724,6 +715,51 @@ static bool cmp_style_name(const AssStyle *lft, const AssStyle *rgt) { return lft->name < rgt->name; } +template +static void do_move(Cont& styls, int type, int& first, int& last, bool storage) { + Cont::iterator begin = styls.begin(); + + // Move up + if (type == 0) { + if (first == 0) return; + rotate(begin + first - 1, begin + first, begin + last + 1); + first--; + last--; + } + // Move to top + else if (type == 1) { + rotate(begin, begin + first, begin + last + 1); + last = last - first; + first = 0; + } + // Move down + else if (type == 2) { + if (last + 1 == styls.size()) return; + rotate(begin + first, begin + last + 1, begin + last + 2); + first++; + last++; + } + // Move to bottom + else if (type == 3) { + rotate(begin + first, begin + last + 1, styls.end()); + first = styls.size() - (last - first + 1); + last = styls.size() - 1; + } + // Sort + else if (type == 4) { + // Get confirmation + if (storage) { + int res = wxMessageBox(_("Are you sure? This cannot be undone!"), _("Sort styles"), wxYES_NO); + if (res == wxNO) return; + } + + sort(styls.begin(), styls.end(), cmp_style_name); + + first = 0; + last = 0; + } +} + void DialogStyleManager::MoveStyles(bool storage, int type) { wxListBox *list = storage ? StorageList : CurrentList; @@ -735,63 +771,13 @@ void DialogStyleManager::MoveStyles(bool storage, int type) { int first = sels.front(); int last = sels.back(); - // Get styles - std::vector& styls = storage ? styleStorageMap : styleMap; - - // Move up - if (type == 0) { - AssStyle *rem = styls[first - 1]; - styls.erase(styls.begin() + first - 1); - styls.insert(styls.begin() + last, rem); - first--; - last--; - } - // Move to top - else if (type == 1) { - std::vector tmp(styls.begin() + first, styls.begin() + last + 1); - styls.erase(styls.begin() + first, styls.begin() + last + 1); - styls.insert(styls.begin(), tmp.begin(), tmp.end()); - last = last - first; - first = 0; - } - // Move down - else if (type == 2) { - AssStyle *rem = styls[last + 1]; - styls.erase(styls.begin() + last + 1); - styls.insert(styls.begin() + first, rem); - first++; - last++; - } - // Move to bottom - else if (type == 3) { - std::vector tmp(styls.begin() + first, styls.begin() + last + 1); - styls.erase(styls.begin() + first, styls.begin() + last + 1); - styls.insert(styls.end(), tmp.begin(), tmp.end()); - first = styls.size() - (last - first + 1); - last = styls.size() - 1; - } - // Sort - else if (type == 4) { - // Get confirmation - if (storage) { - int res = wxMessageBox(_("Are you sure? This cannot be undone!"),_("Sort styles"),wxYES_NO); - if (res == wxNO) return; - } - - sort(styls.begin(), styls.end(), cmp_style_name); - - first = 0; - last = 0; - } - - // Storage if (storage) { - Store.style.clear(); - copy(styls.begin(), styls.end(), back_inserter(Store.style)); - Store.Save(); + do_move(Store, type, first, last, true); + UpdateStorage(); } - // Current else { + do_move(styleMap, type, first, last, false); + // Replace styles entryIter next; int curn = 0; @@ -799,17 +785,17 @@ void DialogStyleManager::MoveStyles(bool storage, int type) { next = cur; next++; if (dynamic_cast(*cur)) { - c->ass->Line.insert(cur, styls[curn]); + c->ass->Line.insert(cur, styleMap[curn]); c->ass->Line.erase(cur); curn++; } } c->ass->Commit(_("style move"), AssFile::COMMIT_STYLES); + LoadCurrentStyles(c->ass); } - for (int i = 0 ; i < (int)styls.size(); ++i) { - list->SetString(i, styls[i]->name); + for (int i = 0 ; i < (int)list->GetCount(); ++i) { if (i < first || i > last) list->Deselect(i); else @@ -834,7 +820,7 @@ void DialogStyleManager::OnKeyDown(wxKeyEvent &event) { case 'c' : if (event.CmdDown()) { if (focus == StorageList) - CopyToClipboard(StorageList, styleStorageMap); + CopyToClipboard(StorageList, Store); else if (focus == CurrentList) CopyToClipboard(CurrentList, styleMap); } diff --git a/aegisub/src/dialog_style_manager.h b/aegisub/src/dialog_style_manager.h index 34e5b5adc..931e8757b 100644 --- a/aegisub/src/dialog_style_manager.h +++ b/aegisub/src/dialog_style_manager.h @@ -63,9 +63,6 @@ class DialogStyleManager : public wxDialog { /// Styles in the current subtitle file std::vector styleMap; - /// Styles in the currently selected style storage - std::vector styleStorageMap; - /// Style storage manager AssStyleStorage Store; @@ -98,14 +95,10 @@ class DialogStyleManager : public wxDialog { wxButton *CurrentMoveBottom; wxButton *CurrentSort; - /// Enable or disable the storage buttons - void StorageActions(bool state); /// Load the list of available storages void LoadCatalog(); /// Load the style list from the subtitles file void LoadCurrentStyles(AssFile *subs); - /// Load the style list from the current storage - void LoadStorageStyles(); /// Enable/disable all of the buttons as appropriate void UpdateButtons(); /// Move styles up or down @@ -113,6 +106,9 @@ class DialogStyleManager : public wxDialog { /// @param type 0: up; 1: top; 2: down; 3: bottom; 4: sort void MoveStyles(bool storage, int type); + /// Save the storage and update the view after a change + void UpdateStorage(); + void OnChangeCatalog(); void OnCatalogNew(); void OnCatalogDelete(); @@ -128,10 +124,12 @@ class DialogStyleManager : public wxDialog { void OnCurrentDelete(); void OnCurrentImport(); void OnKeyDown(wxKeyEvent &event); - void CopyToClipboard(wxListBox *list, std::vector v); void PasteToCurrent(); void PasteToStorage(); + template + void CopyToClipboard(wxListBox *list, T const& v); + public: DialogStyleManager(agi::Context *context); ~DialogStyleManager();