void DialogStyling::Commit(bool next) { if (!c->ass->GetStyle(from_wx(style_name->GetValue()))) return; active_line->Style = from_wx(style_name->GetValue()); c->ass->Commit(_("styling assistant"), AssFile::COMMIT_DIAG_META); if (next) cmd::call("grid/line/next", c); }
bool StringBinder::TransferFromWindow() { wxWindow *window = GetWindow(); if (wxTextCtrl *ctrl = dynamic_cast<wxTextCtrl*>(window)) *value = from_wx(ctrl->GetValue()); else if (wxComboBox *ctrl = dynamic_cast<wxComboBox*>(window)) *value = from_wx(ctrl->GetValue()); else throw agi::InternalError("Unsupported control type"); return true; }
AssDialogue *TTXTSubtitleFormat::ProcessLine(wxXmlNode *node, AssDialogue *prev, int version) const { // Get time wxString sampleTime = node->GetAttribute("sampleTime", "00:00:00.000"); AssTime time(from_wx(sampleTime)); // Set end time of last line if (prev) prev->End = time; // Get text wxString text; if (version == 0) text = node->GetAttribute("text", ""); else text = node->GetNodeContent(); // Create line if (text.empty()) return nullptr; // Create dialogue auto diag = new AssDialogue; diag->Start = time; diag->End = 36000000-10; // Process text for 1.0 if (version == 0) { wxString finalText; finalText.reserve(text.size()); bool in = false; bool first = true; for (auto chr : text) { if (chr == '\'') { if (!in && !first) finalText += "\\N"; first = false; in = !in; } else if (in) finalText += chr; } diag->Text = from_wx(finalText); } // Process text for 1.1 else { text.Replace("\r", ""); text.Replace("\n", "\\N"); diag->Text = from_wx(text); } return diag; }
void DialogProperties::OnOK(wxCommandEvent &) { int count = 0; for (auto const& prop : properties) count += SetInfoIfDifferent(prop.first, from_wx(prop.second->GetValue())); count += SetInfoIfDifferent("PlayResX", from_wx(ResX->GetValue())); count += SetInfoIfDifferent("PlayResY", from_wx(ResY->GetValue())); count += SetInfoIfDifferent("WrapStyle", std::to_string(WrapStyle->GetSelection())); count += SetInfoIfDifferent("ScaledBorderAndShadow", ScaleBorder->GetValue() ? "yes" : "no"); if (count) c->ass->Commit(_("property changes"), AssFile::COMMIT_SCRIPTINFO); EndModal(!!count); }
/// @brief Get provider /// @param video /// @return /// VideoProvider *VideoProviderFactory::GetProvider(wxString video) { std::vector<std::string> list = GetClasses(OPT_GET("Video/Provider")->GetString()); if (video.StartsWith("?dummy")) list.insert(list.begin(), "Dummy"); list.insert(list.begin(), "YUV4MPEG"); bool fileFound = false; bool fileSupported = false; std::string errors; errors.reserve(1024); for (auto const& factory : list) { std::string err; try { VideoProvider *provider = Create(factory, video); LOG_I("manager/video/provider") << factory << ": opened " << from_wx(video); if (provider->WantsCaching()) { return new VideoProviderCache(provider); } return provider; } catch (agi::FileNotFoundError const&) { err = factory + ": file not found."; // Keep trying other providers as this one may just not be able to // open a valid path } catch (VideoNotSupported const&) { fileFound = true; err = factory + ": video is not in a supported format."; } catch (VideoOpenError const& ex) { fileSupported = true; err = factory + ": " + ex.GetMessage(); } catch (agi::vfr::Error const& ex) { fileSupported = true; err = factory + ": " + ex.GetMessage(); } errors += err; errors += "\n"; LOG_D("manager/video/provider") << err; } // No provider could open the file LOG_E("manager/video/provider") << "Could not open " << from_wx(video); std::string msg = "Could not open " + from_wx(video) + ":\n" + errors; if (!fileFound) throw agi::FileNotFoundError(from_wx(video)); if (!fileSupported) throw VideoNotSupported(msg); throw VideoOpenError(msg); }
void TimeEdit::OnChar(wxKeyEvent &event) { event.Skip(); if (byFrame || insert) return; int key = event.GetUnicodeKey(); if ((key < '0' || key > '9') && key != ';' && key != '.' && key != ',') return; event.Skip(false); long start = GetInsertionPoint(); std::string text = from_wx(GetValue()); // Cursor is at the end so do nothing if (start >= (long)text.size()) return; // If the cursor is at punctuation, move it forward to the next digit if (text[start] == ':' || text[start] == '.' || text[start] == ',') ++start; // : and . hop over punctuation but never insert anything if (key == ':' || key == ';' || key == '.' || key == ',') { SetInsertionPoint(start); return; } // Overwrite the digit text[start] = (char)key; time = text; SetValue(to_wx(time.GetAssFormated())); SetInsertionPoint(start + 1); }
wxString GetEncoding(wxString const& filename) { agi::charset::CharsetListDetected list; try { list = agi::charset::DetectAll(from_wx(filename)); } catch (const agi::charset::UnknownCharset&) { /// @todo If the charset is unknown we need to display a complete list of character sets. } if (list.size() == 1) { auto charset = list.begin(); LOG_I("charset/file") << filename << " (" << charset->second << ")"; return to_wx(charset->second); } wxArrayString choices; std::string log_choice; for (auto const& charset : list) { choices.push_back(to_wx(charset.second)); log_choice.append(" " + charset.second); } LOG_I("charset/file") << filename << " (" << log_choice << ")"; int choice = wxGetSingleChoiceIndex(_("Aegisub could not narrow down the character set to a single one.\nPlease pick one below:"),_("Choose character set"),choices); if (choice == -1) throw "Canceled"; return choices[choice]; }
void DialogStyleEditor::UpdateWorkStyle() { work->font = from_wx(FontName->GetValue()); FontSize->GetValue().ToDouble(&(work->fontsize)); ScaleX->GetValue().ToDouble(&(work->scalex)); ScaleY->GetValue().ToDouble(&(work->scaley)); long templ = 0; Encoding->GetValue().BeforeFirst('-').ToLong(&templ); work->encoding = templ; Angle->GetValue().ToDouble(&(work->angle)); Spacing->GetValue().ToDouble(&(work->spacing)); work->borderstyle = OutlineType->IsChecked() ? 3 : 1; Shadow->GetValue().ToDouble(&(work->shadow_w)); Outline->GetValue().ToDouble(&(work->outline_w)); work->alignment = ControlToAlign(Alignment->GetSelection()); for (size_t i = 0; i < 3; ++i) work->Margin[i] = margin[i]->GetValue(); work->bold = BoxBold->IsChecked(); work->italic = BoxItalic->IsChecked(); work->underline = BoxUnderline->IsChecked(); work->strikeout = BoxStrikeout->IsChecked(); }
void DialogSpellChecker::OnAdd(wxCommandEvent&) { spellchecker->AddWord(from_wx(orig_word->GetValue())); // Remember the word that was last added LastAdded = orig_word->GetValue(); FindNext(); }
static void browse_button(wxTextCtrl *ctrl) { wxDirDialog dlg(nullptr, _("Please choose the folder:"), config::path->Decode(from_wx(ctrl->GetValue())).wstring()); if (dlg.ShowModal() == wxID_OK) { wxString dir = dlg.GetPath(); if (!dir.empty()) ctrl->SetValue(dir); } }
void DialogExport::RefreshOptions() { for (size_t i = 0; i < filter_list->GetCount(); ++i) { if (wxSizer *sizer = exporter->GetSettingsSizer(from_wx(filter_list->GetString(i)))) opt_sizer->Show(sizer, filter_list->IsChecked(i), true); } Layout(); GetSizer()->Fit(this); }
void DialogSpellChecker::OnRemove(wxCommandEvent&) { wxTextEntryDialog * dialog = new wxTextEntryDialog(NULL, _("Word to remove from dictionary"), _("Remove word"), LastAdded); if (dialog -> ShowModal() == wxID_OK) spellchecker -> RemoveWord(from_wx(dialog -> GetValue())); delete dialog; }
bool DoubleValidator::TransferFromWindow() { auto ctrl = static_cast<wxTextCtrl *>(GetWindow()); if (!Validate(ctrl)) return false; auto str = from_wx(ctrl->GetValue()); if (decimal_sep != '.') replace(begin(str), end(str), (char)decimal_sep, '.'); agi::util::try_parse(str, value); return true; }
bool DialogSpellChecker::CheckLine(AssDialogue *active_line, int start_pos, int *commit_id) { if (active_line->Comment && skip_comments->GetValue()) return false; std::string text = from_wx(active_line->Text); auto tokens = agi::ass::TokenizeDialogueBody(text); agi::ass::SplitWords(text, tokens); word_start = 0; for (auto const& tok : tokens) { if (tok.type != agi::ass::DialogueTokenType::WORD || word_start < start_pos) { word_start += tok.length; continue; } word_len = tok.length; std::string word = text.substr(word_start, word_len); if (auto_ignore.count(word) || spellchecker->CheckWord(word)) { word_start += tok.length; continue; } auto auto_rep = auto_replace.find(word); if (auto_rep == auto_replace.end()) { #ifdef __WXGTK__ // http://trac.wxwidgets.org/ticket/14369 orig_word->Remove(0, -1); replace_word->Remove(0, -1); #endif SubtitleSelection sel; sel.insert(active_line); context->selectionController->SetSelectionAndActive(sel, active_line); SetWord(word); return true; } text.replace(word_start, word_len, auto_rep->second); active_line->Text = from_wx(text); *commit_id = context->ass->Commit(_("spell check replace"), AssFile::COMMIT_DIAG_TEXT, *commit_id); word_start += auto_rep->second.size(); } return false; }
std::string AegisubLocale::PickLanguage() { if (active_language.empty()) { wxString os_ui_language = GetTranslations()->GetBestTranslation(AEGISUB_CATALOG); if (!os_ui_language.empty()) return from_wx(os_ui_language); } wxArrayString langs = GetTranslations()->GetAvailableTranslations(AEGISUB_CATALOG); // No translations available, so don't bother asking the user if (langs.empty() && active_language.empty()) return "en_US"; langs.insert(langs.begin(), "en_US"); // Check if user local language is available, if so, make it first const wxLanguageInfo *info = wxLocale::GetLanguageInfo(wxLocale::GetSystemLanguage()); if (info) { auto it = std::find(langs.begin(), langs.end(), info->CanonicalName); if (it != langs.end()) std::rotate(langs.begin(), it, it + 1); } // Generate names wxArrayString langNames; for (auto const& lang : langs) langNames.push_back(LocalizedLanguageName(lang)); long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxOK | wxCENTRE; if (!active_language.empty()) style |= wxCANCEL; wxSingleChoiceDialog dialog(nullptr, "Please choose a language:", "Language", langNames, (void **)nullptr, style); if (dialog.ShowModal() == wxID_OK) { int picked = dialog.GetSelection(); if (langs[picked] != active_language) return from_wx(langs[picked]); } return ""; }
void TimeEdit::OnModified(wxCommandEvent &event) { event.Skip(); if (byFrame) { long temp = 0; GetValue().ToLong(&temp); time = c->videoController->TimeAtFrame(temp, isEnd ? agi::vfr::END : agi::vfr::START); } else if (insert) time = from_wx(GetValue()); }
DialogSelection::~DialogSelection() { OPT_SET("Tool/Select Lines/Text")->SetString(from_wx(match_text->GetValue())); OPT_SET("Tool/Select Lines/Condition")->SetInt(select_unmatching_lines->GetValue()); OPT_SET("Tool/Select Lines/Field")->SetInt(dialogue_field->GetSelection()); OPT_SET("Tool/Select Lines/Action")->SetInt(selection_change_type->GetSelection()); OPT_SET("Tool/Select Lines/Mode")->SetInt(match_mode->GetSelection()); OPT_SET("Tool/Select Lines/Match/Case")->SetBool(case_sensitive->IsChecked()); OPT_SET("Tool/Select Lines/Match/Dialogue")->SetBool(apply_to_dialogue->IsChecked()); OPT_SET("Tool/Select Lines/Match/Comment")->SetBool(apply_to_comments->IsChecked()); }
DialogExport::~DialogExport() { std::string infoList; for (size_t i = 0; i < filter_list->GetCount(); ++i) { if (filter_list->IsChecked(i)) { if (!infoList.empty()) infoList += "|"; infoList += from_wx(filter_list->GetString(i)); } } c->ass->SetScriptInfo("Export filters", infoList); }
void DialogSpellChecker::Replace() { AssDialogue *active_line = context->selectionController->GetActiveLine(); // Only replace if the user hasn't changed the selection to something else if (to_wx(active_line->Text.get().substr(word_start, word_len)) == orig_word->GetValue()) { std::string text = active_line->Text; text.replace(word_start, word_len, from_wx(replace_word->GetValue())); active_line->Text = text; context->ass->Commit(_("spell check replace"), AssFile::COMMIT_DIAG_TEXT); context->textSelectionController->SetInsertionPoint(word_start + replace_word->GetValue().size()); } }
void DialogSearchReplace::FindReplace(int mode) { if (mode < 0 || mode > 2) return; // Variables wxString LookFor = FindEdit->GetValue(); if (!LookFor) return; // Setup Search.isReg = CheckRegExp->IsChecked() && CheckRegExp->IsEnabled(); Search.matchCase = CheckMatchCase->IsChecked(); Search.updateVideo = CheckUpdateVideo->IsChecked() && CheckUpdateVideo->IsEnabled(); Search.LookFor = LookFor; Search.CanContinue = true; Search.affect = Affect->GetSelection(); Search.field = Field->GetSelection(); // Find if (mode == 0) { Search.FindNext(); if (hasReplace) { wxString ReplaceWith = ReplaceEdit->GetValue(); Search.ReplaceWith = ReplaceWith; config::mru->Add("Replace", from_wx(ReplaceWith)); } } // Replace else { wxString ReplaceWith = ReplaceEdit->GetValue(); Search.ReplaceWith = ReplaceWith; if (mode == 1) Search.ReplaceNext(); else Search.ReplaceAll(); config::mru->Add("Replace", from_wx(ReplaceWith)); } // Add to history config::mru->Add("Find", from_wx(LookFor)); UpdateDropDowns(); }
AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename) { provider_creator creator; AudioProvider *provider = nullptr; provider = creator.try_create("Dummy audio provider", [&]() { return new DummyAudioProvider(filename); }); // Try a PCM provider first if (!provider && !OPT_GET("Provider/Audio/PCM/Disable")->GetBool()) provider = creator.try_create("PCM audio provider", [&]() { return CreatePCMAudioProvider(filename); }); if (!provider) { std::vector<std::string> list = GetClasses(OPT_GET("Audio/Provider")->GetString()); if (list.empty()) throw agi::NoAudioProvidersError("No audio providers are available.", 0); for (auto const& name : list) { provider = creator.try_create(name, [&]() { return Create(name, filename); }); if (provider) break; } } if (!provider) { if (creator.found_audio) throw agi::AudioProviderOpenError(creator.msg, 0); if (creator.found_file) throw agi::AudioDataNotFoundError(creator.msg, 0); throw agi::FileNotFoundError(from_wx(filename)); } bool needsCache = provider->NeedsCache(); // Give it a converter if needed if (provider->GetBytesPerSample() != 2 || provider->GetSampleRate() < 32000 || provider->GetChannels() != 1) provider = CreateConvertAudioProvider(provider); // Change provider to RAM/HD cache if needed int cache = OPT_GET("Audio/Cache/Type")->GetInt(); if (!cache || !needsCache) return new LockAudioProvider(provider); DialogProgress progress(wxGetApp().frame, _("Load audio")); // Convert to RAM if (cache == 1) return new RAMAudioProvider(provider, &progress); // Convert to HD if (cache == 2) return new HDAudioProvider(provider, &progress); throw agi::AudioCacheOpenError("Unknown caching method", 0); }
void DialogExport::OnProcess(wxCommandEvent &) { if (!TransferDataFromWindow()) return; auto filename = SaveFileSelector(_("Export subtitles file"), "", "", "", to_wx(SubtitleFormat::GetWildcards(1)), this); if (filename.empty()) return; for (size_t i = 0; i < filter_list->GetCount(); ++i) { if (filter_list->IsChecked(i)) exporter->AddFilter(from_wx(filter_list->GetString(i))); } try { wxBusyCursor busy; c->ass->SetScriptInfo("Export Encoding", from_wx(charset_list->GetStringSelection())); exporter->Export(filename, from_wx(charset_list->GetStringSelection()), this); } catch (agi::UserCancelException const&) { } catch (const char *error) { wxMessageBox(error, "Error exporting subtitles", wxOK | wxICON_ERROR | wxCENTER, this); } catch (wxString const& error) { wxMessageBox(error, "Error exporting subtitles", wxOK | wxICON_ERROR | wxCENTER, this); } catch (agi::Exception const& err) { wxMessageBox(to_wx(err.GetMessage()), "Error exporting subtitles", wxOK | wxICON_ERROR | wxCENTER, this); } catch (std::exception const& err) { wxMessageBox(to_wx(err.what()), "Error exporting subtitles", wxOK | wxICON_ERROR | wxCENTER, this); } catch (...) { wxMessageBox("Unknown error", "Error exporting subtitles", wxOK | wxICON_ERROR | wxCENTER, this); } EndModal(0); }
void DialogShiftTimes::SaveHistory(json::Array const& shifted_blocks) { json::Object new_entry; new_entry["filename"] = context->subsController->Filename().filename().string(); new_entry["is by time"] = shift_by_time->GetValue(); new_entry["is backward"] = shift_backward->GetValue(); new_entry["amount"] = from_wx(shift_by_time->GetValue() ? shift_time->GetValue() : shift_frames->GetValue()); new_entry["fields"] = time_fields->GetSelection(); new_entry["mode"] = selection_mode->GetSelection(); new_entry["selection"] = shifted_blocks; history->push_front(new_entry); try { json::Writer::Write(*history, agi::io::Save(history_filename).Get()); } catch (agi::fs::FileSystemError const& e) { LOG_E("dialog_shift_times/save_history") << "Cannot save shift times history: " << e.GetChainedMessage(); } }
void TTXTSubtitleFormat::ReadFile(AssFile *target, agi::fs::path const& filename, std::string const& encoding) const { target->LoadDefault(false); // Load XML document wxXmlDocument doc; if (!doc.Load(filename.wstring())) throw TTXTParseError("Failed loading TTXT XML file.", nullptr); // Check root node name if (doc.GetRoot()->GetName() != "TextStream") throw TTXTParseError("Invalid TTXT file.", nullptr); // Check version wxString verStr = doc.GetRoot()->GetAttribute("version", ""); int version = -1; if (verStr == "1.0") version = 0; else if (verStr == "1.1") version = 1; else throw TTXTParseError("Unknown TTXT version: " + from_wx(verStr), nullptr); // Get children AssDialogue *diag = nullptr; int lines = 0; for (wxXmlNode *child = doc.GetRoot()->GetChildren(); child; child = child->GetNext()) { // Line if (child->GetName() == "TextSample") { if ((diag = ProcessLine(child, diag, version))) { lines++; target->Line.push_back(*diag); } } // Header else if (child->GetName() == "TextStreamHeader") { ProcessHeader(child); } } // No lines? if (lines == 0) target->Line.push_back(*new AssDialogue); }
void Ebu3264SubtitleFormat::WriteFile(const AssFile *src, wxString const& filename, wxString const& encoding) const { // collect data from user EbuExportSettings export_settings = get_export_config(0); AssFile copy(*src); std::vector<EbuSubtitle> subs_list = convert_subtitles(copy, export_settings); std::vector<BlockTTI> tti = create_blocks(subs_list, export_settings); BlockGSI gsi = create_header(copy, export_settings); BlockTTI &block0 = tti.front(); snprintf(gsi.tcf, 8, "%02u%02u%02u%02u", (unsigned int)block0.tci.h, (unsigned int)block0.tci.m, (unsigned int)block0.tci.s, (unsigned int)block0.tci.f); snprintf(gsi.tnb, 5, "%5u", (unsigned int)tti.size()); snprintf(gsi.tns, 5, "%5u", (unsigned int)subs_list.size()); // write file agi::io::Save f(from_wx(filename), true); f.Get().write((const char *)&gsi, sizeof(gsi)); for (auto const& block : tti) f.Get().write((const char *)&block, sizeof(block)); }
void DialogTranslation::Commit(bool next) { wxString new_value = translated_text->GetValue(); new_value.Replace("\r\n", "\\N"); new_value.Replace("\r", "\\N"); new_value.Replace("\n", "\\N"); blocks[cur_block] = AssDialogueBlockPlain(from_wx(new_value)); active_line->UpdateText(blocks); file_change_connection.Block(); c->ass->Commit(_("translation assistant"), AssFile::COMMIT_DIAG_TEXT); file_change_connection.Unblock(); if (next) { if (!NextBlock()) { wxMessageBox(_("No more lines to translate.")); EndModal(1); } } else { UpdateDisplay(); } }
void DialogStyleEditor::UpdateWorkStyle() { updating = true; TransferDataFromWindow(); updating = false; work->font = from_wx(FontName->GetValue()); long templ = 0; Encoding->GetValue().BeforeFirst('-').ToLong(&templ); work->encoding = templ; work->borderstyle = OutlineType->IsChecked() ? 3 : 1; work->alignment = ControlToAlign(Alignment->GetSelection()); for (size_t i = 0; i < 3; ++i) work->Margin[i] = margin[i]->GetValue(); work->bold = BoxBold->IsChecked(); work->italic = BoxItalic->IsChecked(); work->underline = BoxUnderline->IsChecked(); work->strikeout = BoxStrikeout->IsChecked(); }
PCMAudioProvider::PCMAudioProvider(const wxString &filename) : current_mapping(0) , mapping_start(0) , mapping_length(0) #ifdef _WIN32 , file_handle(0, CloseHandle) , file_mapping(0, CloseHandle) { file_handle = CreateFile( filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, 0); if (file_handle == INVALID_HANDLE_VALUE) throw agi::FileNotFoundError(from_wx(filename)); LARGE_INTEGER li_file_size = {0}; if (!GetFileSizeEx(file_handle, &li_file_size)) throw agi::AudioProviderOpenError("Failed getting file size", 0); file_size = li_file_size.QuadPart; file_mapping = CreateFileMapping( file_handle, 0, PAGE_READONLY, 0, 0, 0); if (file_mapping == 0) throw agi::AudioProviderOpenError("Failed creating file mapping", 0); #else , file_handle(open(filename.mb_str(*wxConvFileName), O_RDONLY), close)
AssTransformFramerateFilter::AssTransformFramerateFilter() : AssExportFilter(from_wx(_("Transform Framerate")), from_wx(_("Transform subtitle times, including those in override tags, from an input framerate to an output framerate.\n\nThis is useful for converting regular time subtitles to VFRaC time subtitles for hardsubbing.\nIt can also be used to convert subtitles to a different speed video, such as NTSC to PAL speedup.")), 1000) { }
void DialogSelection::Process(wxCommandEvent&) { std::set<AssDialogue*> matches; try { matches = process( from_wx(match_text->GetValue()), case_sensitive->IsChecked(), match_mode->GetSelection(), select_unmatching_lines->GetValue(), apply_to_comments->IsChecked(), apply_to_dialogue->IsChecked(), dialogue_field->GetSelection(), con->ass); } catch (agi::Exception const&) { Close(); return; } int action = selection_change_type->GetSelection(); SubtitleSelection old_sel, new_sel; if (action != ACTION_SET) con->selectionController->GetSelectedSet(old_sel); wxString message; size_t count = 0; switch (action) { case ACTION_SET: new_sel = matches; switch (count = new_sel.size()) { case 0: message = _("Selection was set to no lines"); break; case 1: message = _("Selection was set to one line"); break; default: message = wxString::Format(_("Selection was set to %u lines"), (unsigned)count); } break; case ACTION_ADD: set_union(old_sel.begin(), old_sel.end(), matches.begin(), matches.end(), inserter(new_sel, new_sel.begin())); switch (count = new_sel.size() - old_sel.size()) { case 0: message = _("No lines were added to selection"); break; case 1: message = _("One line was added to selection"); break; default: message = wxString::Format(_("%u lines were added to selection"), (unsigned)count); } break; case ACTION_SUB: set_difference(old_sel.begin(), old_sel.end(), matches.begin(), matches.end(), inserter(new_sel, new_sel.begin())); switch (count = old_sel.size() - new_sel.size()) { case 0: message = _("No lines were removed from selection"); break; case 1: message = _("One line was removed from selection"); break; default: message = wxString::Format(_("%u lines were removed from selection"), (unsigned)count); } break; case ACTION_INTERSECT: set_intersection(old_sel.begin(), old_sel.end(), matches.begin(), matches.end(), inserter(new_sel, new_sel.begin())); switch (count = old_sel.size() - new_sel.size()) { case 0: message = _("No lines were removed from selection"); break; case 1: message = _("One line was removed from selection"); break; default: message = wxString::Format(_("%u lines were removed from selection"), (unsigned)count); } break; } if (count == 0) wxMessageBox(message, _("Selection"), wxOK | wxCENTER, this); else StatusTimeout(message); if (new_sel.size() && !new_sel.count(con->selectionController->GetActiveLine())) con->selectionController->SetActiveLine(*new_sel.begin()); con->selectionController->SetSelectedSet(new_sel); AssDialogue *new_active = con->selectionController->GetActiveLine(); if (new_sel.size() && !new_sel.count(new_active)) new_active = *new_sel.begin(); con->selectionController->SetSelectionAndActive(new_sel, new_active); Close(); }