diff --git a/languages.ini b/languages.ini
index 3604df0..fb149e1 100644
--- a/languages.ini
+++ b/languages.ini
@@ -1097,6 +1097,372 @@ ctxmenu_undo="&Deshacer Ctrl+Z"
ctxmenu_redo="&Rehacer Ctrl+Y"
ctxmenu_add_new_line="&Añadir Nueva Línea Ctrl+I"
+[french]
+; Panel labels (visible text on the control elements)
+panel_find_what="Rechercher :"
+panel_replace_with="Remplacer par :"
+panel_match_whole_word_only="Mot entier uniquement"
+panel_match_case="Respecter la casse"
+panel_use_variables="Utiliser des variables"
+panel_replace_first_match_only="Remplacer uniquement la première occurrence"
+panel_wrap_around="Parcourir le document"
+panel_search_mode="Mode de recherche"
+panel_normal="Normal"
+panel_extended="Étendu (\\n, \\r, \\t, \\0, \\x...)"
+panel_regular_expression="Expression régulière"
+panel_scope="Portée"
+panel_all_text="Tout le texte"
+panel_selection="Sélection"
+panel_csv="CSV"
+panel_cols="Cols:"
+panel_delim="Delim:"
+panel_quote="Guil.:"
+panel_add_into_list="Ajouter à la liste"
+panel_replace_all="Remplacer tout"
+panel_replace="Remplacer"
+panel_find_next="Rechercher suivant"
+panel_find_next_small="Rech. suiv."
+panel_mark_matches="Marquer les occurrences"
+panel_mark_matches_small="Marquer"
+panel_clear_all_marks="Effacer tous les marquages"
+panel_load_list="Charger la liste"
+panel_save_list="Enregistrer la liste"
+panel_save_as="Enregistrer sous..."
+panel_export_to_bash="Exporter en Bash"
+panel_move_lines="Déplacer les lignes"
+panel_use_list="Utiliser la liste"
+panel_help="?"
+
+; File Dialog
+filetype_all_files="Tous les fichiers (*.*)"
+filetype_csv="Fichiers CSV (*.csv)"
+filetype_bash="Fichiers Bash (*.sh)"
+
+; Tooltips
+tooltip_replace_all="Remplacer tout"
+tooltip_2_buttons_mode="Mode 2 boutons"
+tooltip_columns="Colonnes : '1,3,5-12' (unités, plages)"
+tooltip_delimiter="Délimiteur : caractère simple/combinaison, \t pour Tab"
+tooltip_quote="Guillemets : ', \" ou vide"
+tooltip_sort_descending="Trier par ordre décroissant"
+tooltip_sort_ascending="Trier par ordre croissant"
+tooltip_drop_columns="Supprimer les colonnes"
+tooltip_copy_columns="Copier les colonnes dans le presse-papiers"
+tooltip_column_highlight="Surlignage de colonne : Activé/Désactivé"
+tooltip_copy_marked_text="Copier le texte marqué"
+tooltip_display_statistics_columns="Afficher/Masquer les colonnes de statistiques"
+tooltip_new_list="Nouvelle liste"
+tooltip_save="Enregistrer la liste"
+tooltip_enable_list="Activer la liste"
+tooltip_disable_list="Désactiver la liste"
+
+; List headers
+header_find_count="Nb. Rech."
+header_replace_count="Nb. Rempl."
+header_find="Rech."
+header_replace="Rempl."
+header_whole_word="M"
+header_match_case="C"
+header_use_variables="V"
+header_extended="E"
+header_regex="R"
+header_comments="Commentaires"
+
+; Tooltips for headers
+tooltip_header_whole_word="Mot entier"
+tooltip_header_match_case="Respecter la casse"
+tooltip_header_use_variables="Utiliser des variables"
+tooltip_header_extended="Étendu"
+tooltip_header_regex="Expression régulière"
+tooltip_header_delete="Supprimer"
+
+; Entries for SplitButton
+split_menu_replace_all="Remplacer tout"
+split_menu_replace_all_in_docs="Remplacer tout dans tous les documents ouverts"
+split_button_replace_all="Remplacer tout"
+split_button_replace_all_in_docs="Remplacer tout dans les documents"
+
+; Static Status Messages
+status_duplicate_entry="Entrée en double : "
+status_value_added="Valeur ajoutée à la liste."
+status_no_rows_selected="Aucune ligne sélectionnée pour le déplacement."
+status_one_line_deleted="1 ligne supprimée."
+status_column_marks_cleared="Marques de colonne effacées."
+status_all_marks_cleared="Toutes les marques sont effacées."
+status_cannot_replace_read_only="Impossible de remplacer. Le document est en lecture seule."
+status_add_values_instructions="Ajoutez des valeurs dans la liste ou décochez 'Utiliser la liste' pour remplacer directement."
+status_no_find_string="Aucune chaîne 'Rechercher' saisie. Veuillez fournir une valeur pour l'ajouter à la liste."
+status_no_rows_selected_to_shift="Aucune ligne sélectionnée à déplacer."
+status_add_values_or_uncheck="Ajoutez des valeurs dans la liste ou décochez 'Utiliser la liste'."
+status_no_occurrence_found="Aucune occurrence trouvée."
+status_found_text_not_replaced="Le texte trouvé n'a pas été remplacé."
+status_replace_one_next_found="Remplacer : 1 occurrence remplacée. Suivante trouvée."
+status_replace_one_none_left="Remplacer : 1 occurrence remplacée. Plus rien."
+status_add_values_or_find_directly="Ajoutez des valeurs dans la liste ou décochez 'Utiliser la liste' pour rechercher directement."
+status_wrapped="Bouclé"
+status_no_matches_found="Aucune correspondance trouvée."
+status_no_matches_after_wrap="Aucune correspondance après bouclage."
+status_add_values_or_mark_directly="Ajoutez des valeurs dans la liste ou décochez 'Utiliser la liste' pour marquer directement."
+status_no_text_to_copy="Aucun texte à copier."
+status_failed_to_copy="Échec de la copie dans le presse-papiers."
+status_failed_allocate_memory="Échec d'allocation de mémoire pour le presse-papiers."
+status_invalid_column_or_delimiter="Données de colonne ou de délimiteur invalides."
+status_missing_column_or_delimiter_data="Données de colonne ou de délimiteur manquantes."
+status_invalid_range_in_column_data="Plage invalide dans les données de colonne."
+status_syntax_error_in_column_data="Erreur de syntaxe dans les données de colonne."
+status_invalid_column_number="Numéro de colonne invalide."
+status_extended_delimiter_empty="Le délimiteur étendu est vide."
+status_invalid_quote_character="Caractère de guillemet invalide. Utilisez \" ou ' ou laissez vide."
+status_unable_to_save_file="Erreur : Impossible d'ouvrir ou d'écrire dans le fichier."
+status_saved_items_to_csv="$REPLACE_STRING éléments enregistrés dans le CSV."
+status_no_valid_items_in_csv="Aucun élément valide trouvé dans le fichier CSV."
+status_list_exported_to_bash="Liste exportée dans un script BASH."
+status_invalid_column_count="Fichier non chargé ! Nombre de colonnes invalide dans le CSV."
+status_invalid_data_in_columns="Fichier non chargé ! Données invalides trouvées dans les colonnes CSV."
+status_no_find_replace_list_input="Aucune chaîne 'Rechercher' ou 'Remplacer' fournie. Veuillez entrer une valeur."
+status_found_in_list="Entrée trouvée dans la liste."
+status_not_found_in_list="Aucune entrée trouvée dans la liste pour les champs saisis."
+status_enable_list="Mode liste activé. Les actions utiliseront les entrées de la liste."
+status_disable_list="Mode liste désactivé. Les actions utiliseront 'Rechercher' et 'Remplacer par'."
+
+; Dynamic Status Messages
+status_rows_shifted="$REPLACE_STRING lignes déplacées avec succès."
+status_lines_deleted="$REPLACE_STRING lignes supprimées."
+status_find_column_sorted="Colonne 'Rechercher' triée en ordre $REPLACE_STRING."
+status_replace_column_sorted="Colonne 'Remplacer' triée en ordre $REPLACE_STRING."
+status_occurrences_replaced="$REPLACE_STRING occurrences ont été remplacées."
+status_replace_next_found="$REPLACE_STRING occurrence(s) remplacée(s). Occurrence suivante trouvée."
+status_replace_none_left="$REPLACE_STRING occurrence(s) remplacée(s). Aucune restante."
+status_no_matches_found_for="Aucune correspondance trouvée pour '$REPLACE_STRING'."
+status_actual_position="Position actuelle $REPLACE_STRING"
+status_items_loaded_from_csv="$REPLACE_STRING éléments chargés depuis le CSV."
+status_occurrences_marked="$REPLACE_STRING occurrences marquées."
+status_items_copied_to_clipboard="$REPLACE_STRING éléments copiés dans le presse-papiers."
+status_no_matches_after_wrap_for="Aucune correspondance pour '$REPLACE_STRING' après bouclage."
+status_deleted_fields_count="$REPLACE_STRING champs supprimés."
+status_line_and_column_position=" (Ligne : $REPLACE_STRING1, Colonne : $REPLACE_STRING2)"
+status_unable_to_open_file="Impossible d'ouvrir le fichier : $REPLACE_STRING"
+
+; MessageBox Titles
+msgbox_title_error="Erreur"
+msgbox_title_confirm="Confirmer"
+msgbox_title_use_variables_syntax_error="Utiliser des variables : Erreur de syntaxe"
+msgbox_title_use_variables_execution_error="Utiliser des variables : Erreur d'exécution"
+msgbox_title_save_list="Enregistrer la liste"
+msgbox_title_reload="Recharger"
+msgbox_title_warning="Avertissement"
+
+; MessageBox Messages
+msgbox_failed_create_control="Impossible de créer le contrôle avec l'ID : $REPLACE_STRING1, GetLastError a renvoyé : $REPLACE_STRING2"
+msgbox_confirm_replace_all="Êtes-vous sûr de vouloir remplacer toutes les occurrences dans tous les documents ouverts ?"
+msgbox_confirm_delete_columns="Êtes-vous sûr de vouloir supprimer $REPLACE_STRING colonne(s) ?"
+msgbox_error_saving_settings="Une erreur est survenue lors de l'enregistrement des paramètres :
$REPLACE_STRING"
+msgbox_use_variables_execution_error="Exécution interrompue en raison d'une erreur d'exécution dans :
$REPLACE_STRING"
+msgbox_confirm_delete_single="Êtes-vous sûr de vouloir supprimer cette ligne ?"
+msgbox_confirm_delete_multiple="Êtes-vous sûr de vouloir supprimer $REPLACE_STRING lignes ?"
+msgbox_unsaved_changes_file="Vous avez des modifications non enregistrées dans la liste : '$REPLACE_STRING'.
Enregistrer ces modifications ?"
+msgbox_unsaved_changes="Vous avez des modifications non enregistrées.
Enregistrer maintenant ?"
+msgbox_file_modified_prompt="'$REPLACE_STRING'
Le fichier a été modifié par un autre programme.
Voulez-vous charger les modifications et perdre vos changements non enregistrés ?"
+msgbox_use_variables_not_exported="Certains éléments avec 'Utiliser des variables' activé n'ont pas été exportés."
+
+; Context Menu
+ctxmenu_transfer_to_input_fields="&Transférer vers les champs de saisie Alt+Up"
+ctxmenu_search_in_list="&Rechercher dans la liste Ctrl+F"
+ctxmenu_cut="Co&uper Ctrl+X"
+ctxmenu_copy="&Copier Ctrl+C"
+ctxmenu_paste="&Coller Ctrl+V"
+ctxmenu_edit="&Modifier le champ"
+ctxmenu_delete="&Supprimer Del"
+ctxmenu_select_all="Tout sé&lectionner Ctrl+A"
+ctxmenu_enable="Acti&ver Alt+E"
+ctxmenu_disable="Désacti&ver Alt+D"
+ctxmenu_undo="&Annuler Ctrl+Z"
+ctxmenu_redo="&Rétablir Ctrl+Y"
+ctxmenu_add_new_line="&Ajouter une nouvelle ligne Ctrl+I"
+
+[portuguese]
+; Panel labels (visible text on the control elements)
+panel_find_what="Localizar:"
+panel_replace_with="Substituir por:"
+panel_match_whole_word_only="Apenas palavra inteira"
+panel_match_case="Diferenciar maiúsc./minúsc."
+panel_use_variables="Usar variáveis"
+panel_replace_first_match_only="Substituir apenas a 1ª ocorrência"
+panel_wrap_around="Pesquisar no documento inteiro"
+panel_search_mode="Modo de pesquisa"
+panel_normal="Normal"
+panel_extended="Estendido (\\n, \\r, \\t, \\0, \\x...)"
+panel_regular_expression="Expressão regular"
+panel_scope="Escopo"
+panel_all_text="Todo o texto"
+panel_selection="Seleção"
+panel_csv="CSV"
+panel_cols="Cols:"
+panel_delim="Delim:"
+panel_quote="Aspas:"
+panel_add_into_list="Adicionar à lista"
+panel_replace_all="Substituir tudo"
+panel_replace="Substituir"
+panel_find_next="Localizar próximo"
+panel_find_next_small="Próximo"
+panel_mark_matches="Marcar ocorrências"
+panel_mark_matches_small="Marcar ocorr."
+panel_clear_all_marks="Limpar todas as marcas"
+panel_load_list="Carregar lista"
+panel_save_list="Salvar lista"
+panel_save_as="Salvar como..."
+panel_export_to_bash="Exportar para Bash"
+panel_move_lines="Mover linhas"
+panel_use_list="Usar lista"
+panel_help="?"
+
+; File Dialog
+filetype_all_files="Todos os arquivos (*.*)"
+filetype_csv="Arquivos CSV (*.csv)"
+filetype_bash="Arquivos Bash (*.sh)"
+
+; Tooltips
+tooltip_replace_all="Substituir tudo"
+tooltip_2_buttons_mode="Modo de 2 botões"
+tooltip_columns="Colunas: '1,3,5-12' (individuais, intervalos)"
+tooltip_delimiter="Delimitador: caractere único/combinado, \t p/ Tab"
+tooltip_quote="Aspas: ', \" ou vazio"
+tooltip_sort_descending="Classificar em ordem decrescente"
+tooltip_sort_ascending="Classificar em ordem crescente"
+tooltip_drop_columns="Remover colunas"
+tooltip_copy_columns="Copiar colunas para a área de transferência"
+tooltip_column_highlight="Destaque de coluna: Ligado/Desligado"
+tooltip_copy_marked_text="Copiar texto marcado"
+tooltip_display_statistics_columns="Mostrar/Ocultar colunas de estatísticas"
+tooltip_new_list="Nova lista"
+tooltip_save="Salvar lista"
+tooltip_enable_list="Habilitar lista"
+tooltip_disable_list="Desabilitar lista"
+
+; List headers
+header_find_count="Contagem de localizações"
+header_replace_count="Contagem de substituições"
+header_find="Localizar"
+header_replace="Substituir"
+header_whole_word="W"
+header_match_case="C"
+header_use_variables="V"
+header_extended="E"
+header_regex="R"
+header_comments="Comentários"
+
+; Tooltips for headers
+tooltip_header_whole_word="Apenas palavra inteira"
+tooltip_header_match_case="Diferenciar maiúsc./minúsc."
+tooltip_header_use_variables="Usar variáveis"
+tooltip_header_extended="Estendido"
+tooltip_header_regex="Expressão regular"
+tooltip_header_delete="Excluir"
+
+; Entries for SplitButton
+split_menu_replace_all="Substituir tudo"
+split_menu_replace_all_in_docs="Substituir tudo em todos os documentos abertos"
+split_button_replace_all="Substituir tudo"
+split_button_replace_all_in_docs="Substituir tudo nos documentos"
+
+; Static Status Messages
+status_duplicate_entry="Entrada duplicada: "
+status_value_added="Valor adicionado à lista."
+status_no_rows_selected="Nenhuma linha selecionada para mover."
+status_one_line_deleted="1 linha excluída."
+status_column_marks_cleared="Marcas de coluna removidas."
+status_all_marks_cleared="Todas as marcas foram removidas."
+status_cannot_replace_read_only="Não é possível substituir. O documento é somente leitura."
+status_add_values_instructions="Adicione valores à lista ou desmarque 'Usar lista' para substituir diretamente."
+status_no_find_string="Nenhum texto de 'Localizar' informado. Forneça um valor para adicionar à lista."
+status_no_rows_selected_to_shift="Nenhuma linha selecionada para mover."
+status_add_values_or_uncheck="Adicione valores à lista ou desmarque 'Usar lista'."
+status_no_occurrence_found="Nenhuma ocorrência encontrada."
+status_found_text_not_replaced="O texto encontrado não foi substituído."
+status_replace_one_next_found="Substituição: 1 ocorrência substituída. Próxima encontrada."
+status_replace_one_none_left="Substituição: 1 ocorrência substituída. Nenhuma restante."
+status_add_values_or_find_directly="Adicione valores à lista ou desmarque 'Usar lista' para localizar diretamente."
+status_wrapped="Envolvido"
+status_no_matches_found="Nenhuma correspondência encontrada."
+status_no_matches_after_wrap="Nenhuma correspondência encontrada após o envolvimento."
+status_add_values_or_mark_directly="Adicione valores à lista ou desmarque 'Usar lista' para marcar diretamente."
+status_no_text_to_copy="Nenhum texto para copiar."
+status_failed_to_copy="Falha ao copiar para a área de transferência."
+status_failed_allocate_memory="Falha ao alocar memória para a área de transferência."
+status_invalid_column_or_delimiter="Dados de coluna ou delimitador inválidos."
+status_missing_column_or_delimiter_data="Dados de coluna ou delimitador ausentes."
+status_invalid_range_in_column_data="Intervalo inválido nos dados de coluna."
+status_syntax_error_in_column_data="Erro de sintaxe nos dados de coluna."
+status_invalid_column_number="Número de coluna inválido."
+status_extended_delimiter_empty="O delimitador estendido está vazio."
+status_invalid_quote_character="Caractere de aspa inválido. Use \" ou ' ou deixe em branco."
+status_unable_to_save_file="Erro: Não é possível abrir ou gravar no arquivo."
+status_saved_items_to_csv="$REPLACE_STRING itens salvos em CSV."
+status_no_valid_items_in_csv="Nenhum item válido encontrado no arquivo CSV."
+status_list_exported_to_bash="Lista exportada para script BASH."
+status_invalid_column_count="Arquivo não carregado! Número de colunas inválido no arquivo CSV."
+status_invalid_data_in_columns="Arquivo não carregado! Dados inválidos encontrados nas colunas CSV."
+status_no_find_replace_list_input="Nenhum texto de 'Localizar' ou 'Substituir' fornecido. Insira um valor."
+status_found_in_list="Entrada encontrada na lista."
+status_not_found_in_list="Nenhuma entrada foi encontrada na lista com base nos campos informados."
+status_enable_list="Modo lista habilitado. As ações usarão as entradas da lista."
+status_disable_list="Modo lista desabilitado. As ações usarão 'Localizar' e 'Substituir por'."
+
+; Dynamic Status Messages
+status_rows_shifted="$REPLACE_STRING linhas movidas com sucesso."
+status_lines_deleted="$REPLACE_STRING linhas excluídas."
+status_find_column_sorted="Coluna 'Localizar' classificada em ordem $REPLACE_STRING."
+status_replace_column_sorted="Coluna 'Substituir' classificada em ordem $REPLACE_STRING."
+status_occurrences_replaced="$REPLACE_STRING ocorrências foram substituídas."
+status_replace_next_found="$REPLACE_STRING ocorrência(s) substituídas. Próxima encontrada."
+status_replace_none_left="$REPLACE_STRING ocorrência(s) substituídas. Nenhuma restante."
+status_no_matches_found_for="Nenhuma correspondência encontrada para '$REPLACE_STRING'."
+status_actual_position="Posição atual $REPLACE_STRING"
+status_items_loaded_from_csv="$REPLACE_STRING itens carregados do CSV."
+status_occurrences_marked="$REPLACE_STRING ocorrências foram marcadas."
+status_items_copied_to_clipboard="$REPLACE_STRING itens copiados para a área de transferência."
+status_no_matches_after_wrap_for="Nenhuma correspondência encontrada para '$REPLACE_STRING' após envolvimento."
+status_deleted_fields_count="$REPLACE_STRING campos excluídos."
+status_line_and_column_position=" (Linha: $REPLACE_STRING1, Coluna: $REPLACE_STRING2)"
+status_unable_to_open_file="Falha ao abrir o arquivo: $REPLACE_STRING"
+
+; MessageBox Titles
+msgbox_title_error="Erro"
+msgbox_title_confirm="Confirmar"
+msgbox_title_use_variables_syntax_error="Usar Variáveis: Erro de Sintaxe"
+msgbox_title_use_variables_execution_error="Usar Variáveis: Erro de Execução"
+msgbox_title_save_list="Salvar lista"
+msgbox_title_reload="Recarregar"
+msgbox_title_warning="Aviso"
+
+; MessageBox Messages
+msgbox_failed_create_control="Falha ao criar o controle com ID: $REPLACE_STRING1, GetLastError retornou: $REPLACE_STRING2"
+msgbox_confirm_replace_all="Tem certeza de que deseja substituir todas as ocorrências em todos os documentos abertos?"
+msgbox_confirm_delete_columns="Tem certeza de que deseja excluir $REPLACE_STRING coluna(s)?"
+msgbox_error_saving_settings="Ocorreu um erro ao salvar as configurações:
$REPLACE_STRING"
+msgbox_use_variables_execution_error="Execução interrompida devido a falha na execução em:
$REPLACE_STRING"
+msgbox_confirm_delete_single="Tem certeza de que deseja excluir esta linha?"
+msgbox_confirm_delete_multiple="Tem certeza de que deseja excluir $REPLACE_STRING linhas?"
+msgbox_unsaved_changes_file="Você tem alterações não salvas na lista: '$REPLACE_STRING'.
Deseja salvar as alterações?"
+msgbox_unsaved_changes="Você tem alterações não salvas.
Deseja salvar as alterações?"
+msgbox_file_modified_prompt="'$REPLACE_STRING'
O arquivo foi modificado por outro programa.
Deseja carregar as alterações e perder as modificações não salvas?"
+msgbox_use_variables_not_exported="Alguns itens com 'Usar Variáveis' ativadas não foram exportados."
+
+; Context Menu
+ctxmenu_transfer_to_input_fields="&Transferir para campos de entrada Alt+Up"
+ctxmenu_search_in_list="&Pesquisar na lista Ctrl+F"
+ctxmenu_cut="Cor&tar Ctrl+X"
+ctxmenu_copy="&Copiar Ctrl+C"
+ctxmenu_paste="&Colar Ctrl+V"
+ctxmenu_edit="&Editar Campo"
+ctxmenu_delete="&Excluir Del"
+ctxmenu_select_all="Selecionar &tudo Ctrl+A"
+ctxmenu_enable="Habilit&ar Alt+E"
+ctxmenu_disable="Desabilit&ar Alt+D"
+ctxmenu_undo="&Desfazer Ctrl+Z"
+ctxmenu_redo="&Refazer Ctrl+Y"
+ctxmenu_add_new_line="&Adicionar Nova Linha Ctrl+I"
+
[danish]
; Panel labels (visible text on the control elements)
@@ -1280,3 +1646,186 @@ ctxmenu_disable="&Deaktiver Alt+D"
ctxmenu_undo="&Fortryd Ctrl+Z"
ctxmenu_redo="&Gentag Ctrl+Y"
ctxmenu_add_new_line="Indsæt &Ny Linje Ctrl+I"
+
+[ukrainian]
+; Panel labels (visible text on the control elements)
+panel_find_what="Знайти:"
+panel_replace_with="Замінити на:"
+panel_match_whole_word_only="Тільки цілі слова"
+panel_match_case="Ураховувати регістр"
+panel_use_variables="Використовувати змінні"
+panel_replace_first_match_only="Тільки першу заміну"
+panel_wrap_around="Пошук знову"
+panel_search_mode="Режим пошуку"
+panel_normal="Звичайний"
+panel_extended="Розширений (\\n, \\r, \\t, \\0, \\x...)"
+panel_regular_expression="Регулярний вираз"
+panel_scope="Область"
+panel_all_text="Увесь текст"
+panel_selection="Виділення"
+panel_csv="CSV"
+panel_cols="Стовп:"
+panel_delim="Розд:"
+panel_quote="Кав:"
+panel_add_into_list="Додати до списку"
+panel_replace_all="Замінити все"
+panel_replace="Замінити"
+panel_find_next="Знайти наступне"
+panel_find_next_small="Знайти наступне"
+panel_mark_matches="Позначити відповідності"
+panel_mark_matches_small="Позначити збіги"
+panel_clear_all_marks="Очистити всі позначки"
+panel_load_list="Завантажити список"
+panel_save_list="Зберегти список"
+panel_save_as="Зберегти як..."
+panel_export_to_bash="Експортувати до Bash"
+panel_move_lines="Перемістити рядки"
+panel_use_list="Використовувати список"
+panel_help="?"
+
+; File Dialog
+filetype_all_files="Усі файли (*.*)"
+filetype_csv="CSV файли (*.csv)"
+filetype_bash="Bash файли (*.sh)"
+
+; Tooltips
+tooltip_replace_all="Замінити все"
+tooltip_2_buttons_mode="Режим двох кнопок"
+tooltip_columns="Стовпці: '1,3,5-12' (окремі, діапазони)"
+tooltip_delimiter="Роздільник: Один/кілька символів, \\t для табуляції"
+tooltip_quote="Кавички: ', \" або порожньо"
+tooltip_sort_descending="Сортувати за спаданням"
+tooltip_sort_ascending="Сортувати за зростанням"
+tooltip_drop_columns="Видалити стовпці"
+tooltip_copy_columns="Скопіювати стовпці у буфер обміну"
+tooltip_column_highlight="Виділення стовпців: Увімк./Вимк."
+tooltip_copy_marked_text="Скопіювати виділений текст"
+tooltip_display_statistics_columns="Показати/Сховати статистичні стовпці"
+tooltip_new_list="Новий список"
+tooltip_save="Зберегти список"
+tooltip_enable_list="Увімкнути список"
+tooltip_disable_list="Вимкнути список"
+
+; List headers
+header_find_count="Ліч. пошуку"
+header_replace_count="Ліч. замін"
+header_find="Знайти"
+header_replace="Замінити"
+header_whole_word="W"
+header_match_case="C"
+header_use_variables="V"
+header_extended="E"
+header_regex="R"
+header_comments="Коментарі"
+
+; Tooltips for headers
+tooltip_header_whole_word="Цілі слова"
+tooltip_header_match_case="Ураховувати регістр"
+tooltip_header_use_variables="Використовувати змінні"
+tooltip_header_extended="Розширений"
+tooltip_header_regex="Регулярний вираз"
+tooltip_header_delete="Видалити"
+
+; Entries for SplitButton
+split_menu_replace_all="Замінити все"
+split_menu_replace_all_in_docs="Замінити все у всіх відкритих документах"
+split_button_replace_all="Замінити все"
+split_button_replace_all_in_docs="Замінити все у документах"
+
+; Static Status Messages
+status_duplicate_entry="Дубль запису: "
+status_value_added="Значення додано до списку."
+status_no_rows_selected="Не вибрано рядків для переміщення."
+status_one_line_deleted="1 рядок видалено."
+status_column_marks_cleared="Позначки стовпців очищено."
+status_all_marks_cleared="Усі позначки очищено."
+status_cannot_replace_read_only="Замінити неможливо. Документ тільки для читання."
+status_add_values_instructions="Додайте значення до списку. Або зніміть позначку 'Використовувати список' для прямої заміни."
+status_no_find_string="Рядок 'Знайти' не введено. Введіть значення для додавання до списку."
+status_no_rows_selected_to_shift="Не вибрано рядків для переміщення."
+status_add_values_or_uncheck="Додайте значення до списку або зніміть позначку 'Використовувати список'."
+status_no_occurrence_found="Збігів не знайдено."
+status_found_text_not_replaced="Знайдений текст не замінено."
+status_replace_one_next_found="Замінено: 1 збіг замінено. Наступне знайдено."
+status_replace_one_none_left="Замінено: 1 збіг замінено. Більше не залишилося."
+status_add_values_or_find_directly="Додайте значення до списку. Або зніміть позначку 'Використовувати список' для прямого пошуку."
+status_wrapped="Циклічний пошук"
+status_no_matches_found="Немає збігів."
+status_no_matches_after_wrap="Немає збігів після циклу."
+status_add_values_or_mark_directly="Додайте значення до списку. Або зніміть позначку 'Використовувати список' для прямого позначення."
+status_no_text_to_copy="Немає тексту для копіювання."
+status_failed_to_copy="Не вдалося скопіювати до буфера обміну."
+status_failed_allocate_memory="Не вдалося виділити пам'ять для буфера обміну."
+status_invalid_column_or_delimiter="Неправильні дані стовпців або роздільників."
+status_missing_column_or_delimiter_data="Відсутні дані стовпців або роздільників."
+status_invalid_range_in_column_data="Недійсний діапазон у даних стовпців."
+status_syntax_error_in_column_data="Синтаксична помилка у даних стовпців."
+status_invalid_column_number="Недійсний номер стовпця."
+status_extended_delimiter_empty="Розширений роздільник порожній."
+status_invalid_quote_character="Недійсний символ кавичок. Використовуйте ' або \" або залиште порожнім."
+status_unable_to_save_file="Помилка: Не вдалося відкрити або записати у файл."
+status_saved_items_to_csv="$REPLACE_STRING елементів збережено у CSV."
+status_no_valid_items_in_csv="У CSV файлі не знайдено дійсних елементів."
+status_list_exported_to_bash="Список експортовано у Bash."
+status_invalid_column_count="Файл не завантажено! Неправильна кількість стовпців у CSV файлі."
+status_invalid_data_in_columns="Файл не завантажено! Недійсні дані знайдені у стовпцях CSV."
+status_no_find_replace_list_input="Не введено 'Знайти' або 'Замінити'. Будь ласка, введіть значення."
+status_found_in_list="Елемент знайдено у списку."
+status_not_found_in_list="Елемент не знайдено у списку за введеними полями."
+status_enable_list="Режим списку увімкнено. Дії використовують елементи списку."
+status_disable_list="Режим списку вимкнено. Дії використовують поля 'Знайти' та 'Замінити'."
+
+; Dynamic Status Messages
+status_rows_shifted="$REPLACE_STRING рядків успішно переміщено."
+status_lines_deleted="$REPLACE_STRING рядків видалено."
+status_find_column_sorted="Стовпець пошуку відсортовано у $REPLACE_STRING порядку."
+status_replace_column_sorted="Стовпець замін відсортовано у $REPLACE_STRING порядку."
+status_occurrences_replaced="$REPLACE_STRING збігів замінено."
+status_replace_next_found="$REPLACE_STRING збіг(ів) замінено. Наступне знайдено."
+status_replace_none_left="$REPLACE_STRING збіг(ів) замінено. Більше не знайдено."
+status_no_matches_found_for="Збігів для '$REPLACE_STRING' не знайдено."
+status_actual_position="Поточна позиція $REPLACE_STRING"
+status_items_loaded_from_csv="$REPLACE_STRING елементів завантажено з CSV."
+status_occurrences_marked="$REPLACE_STRING збігів позначено."
+status_items_copied_to_clipboard="$REPLACE_STRING елементів скопійовано до буфера обміну."
+status_no_matches_after_wrap_for="Збігів для '$REPLACE_STRING' після циклу не знайдено."
+status_deleted_fields_count="$REPLACE_STRING полів видалено."
+status_line_and_column_position=" (Рядок: $REPLACE_STRING1, Стовпець: $REPLACE_STRING2)"
+status_unable_to_open_file="Не вдалося відкрити файл: $REPLACE_STRING"
+
+; MessageBox Titles
+msgbox_title_error="Помилка"
+msgbox_title_confirm="Підтвердити"
+msgbox_title_use_variables_syntax_error="Синтаксична помилка: Використання змінних"
+msgbox_title_use_variables_execution_error="Помилка виконання: Використання змінних"
+msgbox_title_save_list="Зберегти список"
+msgbox_title_reload="Перезавантажити"
+msgbox_title_warning="Попередження"
+
+; MessageBox Messages
+msgbox_failed_create_control="Не вдалося створити елемент керування з ID: $REPLACE_STRING1, GetLastError повернув: $REPLACE_STRING2"
+msgbox_confirm_replace_all="Ви впевнені, що хочете замінити всі відповідності у всіх відкритих документах?"
+msgbox_confirm_delete_columns="Ви впевнені, що хочете видалити $REPLACE_STRING стовпці?"
+msgbox_error_saving_settings="Помилка під час збереження налаштувань:
$REPLACE_STRING"
+msgbox_use_variables_execution_error="Виконання зупинено через помилку:
$REPLACE_STRING"
+msgbox_confirm_delete_single="Ви впевнені, що хочете видалити цей рядок?"
+msgbox_confirm_delete_multiple="Ви впевнені, що хочете видалити $REPLACE_STRING рядків?"
+msgbox_unsaved_changes_file="У вас є незбережені зміни у списку: '$REPLACE_STRING'.
Зберегти зміни?"
+msgbox_unsaved_changes="У вас є незбережені зміни.
Зберегти зміни?"
+msgbox_file_modified_prompt="'$REPLACE_STRING'
Файл змінено іншою програмою.
Ви хочете завантажити зміни та втратити незбережені правки?"
+msgbox_use_variables_not_exported="Деякі елементи з увімкненими 'Використовувати змінні' не були експортовані."
+
+; Context Menu
+ctxmenu_transfer_to_input_fields="&Передати у поля вводу Alt+Up"
+ctxmenu_search_in_list="Шу&кати у списку Ctrl+F"
+ctxmenu_cut="Ви&різати Ctrl+X"
+ctxmenu_copy="Ско&піювати Ctrl+C"
+ctxmenu_paste="Вста&вити Ctrl+V"
+ctxmenu_edit="Редагувати поле"
+ctxmenu_delete="&Видалити Del"
+ctxmenu_select_all="Вибрати &все Ctrl+A"
+ctxmenu_enable="Увімк&нути Alt+E"
+ctxmenu_disable="Вимк&нути Alt+D"
+ctxmenu_undo="Скас&увати Ctrl+Z"
+ctxmenu_redo="Повто&рити Ctrl+Y"
+ctxmenu_add_new_line="&Додати новий рядок Ctrl+I"
diff --git a/src/MultiReplacePanel.cpp b/src/MultiReplacePanel.cpp
index 26fb58f..4afbdc9 100644
--- a/src/MultiReplacePanel.cpp
+++ b/src/MultiReplacePanel.cpp
@@ -7807,58 +7807,6 @@ sptr_t MultiReplace::send(unsigned int iMessage, uptr_t wParam, sptr_t lParam, b
}
}
-/*
-sptr_t MultiReplace::send(unsigned int iMessage, uptr_t wParam, sptr_t lParam, bool useDirect) {
- sptr_t result;
-
- if (useDirect && pSciMsg) {
- result = pSciMsg(pSciWndData, iMessage, wParam, lParam);
- }
- else {
- result = ::SendMessage(_hScintilla, iMessage, wParam, lParam);
- }
-
- // Check Scintilla's error status
- int status = static_cast(::SendMessage(_hScintilla, SCI_GETSTATUS, 0, 0));
-
- if (status != SC_STATUS_OK) {
- wchar_t buffer[512];
- switch (status) {
- case SC_STATUS_FAILURE:
- wcscpy(buffer, L"Error: Generic failure");
- break;
- case SC_STATUS_BADALLOC:
- wcscpy(buffer, L"Error: Memory is exhausted");
- break;
- case SC_STATUS_WARN_REGEX:
- wcscpy(buffer, L"Warning: Regular expression is invalid");
- break;
- default:
- swprintf(buffer, L"Error/Warning with status code: %d", status);
- break;
- }
-
- // Append the function call details
- wchar_t callDetails[512];
- #if defined(_WIN64)
- swprintf(callDetails, L"\niMessage: %u\nwParam: %llu\nlParam: %lld", iMessage, static_cast(wParam), static_cast(lParam));
- #else
- swprintf(callDetails, L"\niMessage: %u\nwParam: %lu\nlParam: %ld", iMessage, static_cast(wParam), static_cast(lParam));
- #endif
-
-
- wcscat(buffer, callDetails);
-
- MessageBox(NULL, buffer, L"Scintilla Error/Warning", MB_OK | (status >= SC_STATUS_WARN_START ? MB_ICONWARNING : MB_ICONERROR));
-
- // Clear the error status
- ::SendMessage(_hScintilla, SCI_SETSTATUS, SC_STATUS_OK, 0);
- }
-
- return result;
-}
-*/
-
bool MultiReplace::normalizeAndValidateNumber(std::string& str) {
if (str.empty()) {
return false; // An empty string is not a valid number
@@ -8194,31 +8142,42 @@ int MultiReplace::checkForUnsavedChanges() {
}
void MultiReplace::loadListFromCsvSilent(const std::wstring& filePath, std::vector& list) {
- // Open file in binary mode to read UTF-8 data
+ // Open the CSV file
std::ifstream inFile(filePath);
if (!inFile.is_open()) {
std::wstring shortenedFilePathW = getShortenedFilePath(filePath, 500);
- std::string errorMessage = wstringToString(getLangStr(L"status_unable_to_open_file", { shortenedFilePathW }));
- throw CsvLoadException(errorMessage);
+ throw CsvLoadException(wstringToString(getLangStr(L"status_unable_to_open_file", { shortenedFilePathW })));
}
- std::vector tempList; // Temporary list to hold items
+ // Read the file content into a UTF-8 string
std::string utf8Content((std::istreambuf_iterator(inFile)), std::istreambuf_iterator());
+ inFile.close();
+
+ // Convert UTF-8 string to std::wstring
std::wstring content = stringToWString(utf8Content);
std::wstringstream contentStream(content);
+ // Read the header line
+ std::wstring headerLine;
+ if (!std::getline(contentStream, headerLine)) {
+ throw CsvLoadException(wstringToString(getLangStr(L"status_invalid_column_count")));
+ }
+
+ // Temporary list to hold parsed items
+ std::vector tempList;
std::wstring line;
- std::getline(contentStream, line); // Skip the CSV header
+ // Read and process each line in the file
while (std::getline(contentStream, line)) {
std::vector columns = parseCsvLine(line);
+ // Check if column count is valid
if (columns.size() < 8 || columns.size() > 9) {
throw CsvLoadException(wstringToString(getLangStr(L"status_invalid_column_count")));
}
- ReplaceItemData item;
try {
+ ReplaceItemData item;
item.isEnabled = std::stoi(columns[0]) != 0;
item.findText = columns[1];
item.replaceText = columns[2];
@@ -8227,15 +8186,7 @@ void MultiReplace::loadListFromCsvSilent(const std::wstring& filePath, std::vect
item.useVariables = std::stoi(columns[5]) != 0;
item.extended = std::stoi(columns[6]) != 0;
item.regex = std::stoi(columns[7]) != 0;
-
- // Handle Comments column for compatibility with old format
- if (columns.size() == 9) {
- item.comments = columns[8];
- }
- else {
- item.comments = L""; // Initialize as empty string if not present
- }
-
+ item.comments = (columns.size() == 9) ? columns[8] : L"";
tempList.push_back(item);
}
catch (const std::exception&) {
@@ -8243,33 +8194,35 @@ void MultiReplace::loadListFromCsvSilent(const std::wstring& filePath, std::vect
}
}
- inFile.close();
- list = tempList; // Transfer data from temporary list to the final list
+ // Check if the file contains valid data rows
+ if (tempList.empty()) {
+ throw CsvLoadException(wstringToString(getLangStr(L"status_no_valid_items_in_csv")));
+ }
+
+ // Transfer parsed data to the target list
+ list = std::move(tempList);
}
void MultiReplace::loadListFromCsv(const std::wstring& filePath) {
-
try {
loadListFromCsvSilent(filePath, replaceListData);
- // Store the file path only if loading was successful
+ // Update the file path and display it
listFilePath = filePath;
-
- // Display the path below the list
showListFilePath();
- // Calculate the original list hash after loading
+ // Compute the hash of the loaded list
originalListHash = computeListHash(replaceListData);
- // Clear the Undo and Redo stacks after successful load
+ // Clear Undo and Redo stacks
undoStack.clear();
redoStack.clear();
- // Update the list view control
+ // Update the ListView
ListView_SetItemCountEx(_replaceListView, static_cast(replaceListData.size()), LVSICF_NOINVALIDATEALL);
InvalidateRect(_replaceListView, NULL, TRUE);
- // Show success message
+ // Display success or error message based on the loaded data
if (replaceListData.empty()) {
showStatusMessage(getLangStr(L"status_no_valid_items_in_csv"), COLOR_ERROR);
}
@@ -8278,9 +8231,7 @@ void MultiReplace::loadListFromCsv(const std::wstring& filePath) {
}
}
catch (const CsvLoadException& ex) {
- // Resolve the error key to a localized string when displaying the message
showStatusMessage(stringToWString(ex.what()), COLOR_ERROR);
- return;
}
}
@@ -8289,25 +8240,16 @@ void MultiReplace::checkForFileChangesAtStartup() {
return;
}
- std::wstring shortenedFilePath = getShortenedFilePath(listFilePath, 500);
-
try {
std::vector tempListFromFile;
- loadListFromCsvSilent(listFilePath, tempListFromFile); // Load the list into a temporary list
-
- std::size_t newFileHash = computeListHash(tempListFromFile); // Calculate the new file hash
+ loadListFromCsvSilent(listFilePath, tempListFromFile);
- // Check if the file has been modified externally
+ std::size_t newFileHash = computeListHash(tempListFromFile);
if (newFileHash != originalListHash) {
+ std::wstring shortenedFilePath = getShortenedFilePath(listFilePath, 500);
std::wstring message = getLangStr(L"msgbox_file_modified_prompt", { shortenedFilePath });
- int response = MessageBox(
- nppData._nppHandle,
- message.c_str(),
- getLangStr(L"msgbox_title_reload").c_str(),
- MB_YESNO | MB_ICONWARNING | MB_SETFOREGROUND
- );
-
+ int response = MessageBox(nppData._nppHandle, message.c_str(), getLangStr(L"msgbox_title_reload").c_str(), MB_YESNO | MB_ICONWARNING | MB_SETFOREGROUND);
if (response == IDYES) {
replaceListData = tempListFromFile;
originalListHash = newFileHash;
@@ -8315,9 +8257,7 @@ void MultiReplace::checkForFileChangesAtStartup() {
}
}
catch (const CsvLoadException& ex) {
- // Resolve the error key to a localized string when displaying the message
showStatusMessage(stringToWString(ex.what()), COLOR_ERROR);
- return;
}
if (replaceListData.empty()) {
@@ -8325,8 +8265,6 @@ void MultiReplace::checkForFileChangesAtStartup() {
}
else {
showStatusMessage(getLangStr(L"status_items_loaded_from_csv", { std::to_wstring(replaceListData.size()) }), COLOR_SUCCESS);
-
- // Update the list view control, if necessary
ListView_SetItemCountEx(_replaceListView, replaceListData.size(), LVSICF_NOINVALIDATEALL);
InvalidateRect(_replaceListView, NULL, TRUE);
}
@@ -8934,7 +8872,6 @@ void MultiReplace::loadSettingsFromIni(const std::wstring& iniFilePath) {
}
void MultiReplace::loadSettings() {
- // Generate the paths to the configuration files
auto [iniFilePath, csvFilePath] = generateConfigFilePaths();
try {
@@ -8949,7 +8886,6 @@ void MultiReplace::loadSettings() {
updateHeaderSelection();
ListView_SetItemCountEx(_replaceListView, replaceListData.size(), LVSICF_NOINVALIDATEALL);
InvalidateRect(_replaceListView, NULL, TRUE);
-
}
void MultiReplace::loadUIConfigFromIni() {