feat(i18n): show the new language when the session language changes

main
reionwong 1 week ago
parent d469ea99cb
commit 92dd9bece3

@ -59,8 +59,8 @@ FindBar::FindBar(Konsole::TerminalView* terminal)
setName("findBar");
setVisible(false);
m_field->setName("findField");
m_field->setFrameVisible(false);
m_field->setPlaceholder(tr("Find"));
m_field->setTextMargins(0, 0);
m_previous->setGlyph("chevron-up", 16);
m_next->setGlyph("chevron-down", 16);
@ -76,6 +76,7 @@ FindBar::FindBar(Konsole::TerminalView* terminal)
m_notFound = !found;
updateColors();
});
retranslate();
updateColors();
}
@ -126,6 +127,11 @@ void FindBar::close()
onClosed();
}
void FindBar::retranslate()
{
m_field->setPlaceholder(tr("Find"));
}
void FindBar::search(bool forwards, bool fromSelection)
{
const std::string text = m_field->text();

@ -34,6 +34,7 @@ public:
void open(const std::string& text);
void close();
void retranslate();
std::function<void()> onClosed;

@ -269,6 +269,7 @@ public:
: m_window(window)
, preview(addChild<Preview>(window))
{
setName("settingsContent");
TerminalSettings& settings = window->settings();
Card* appearance = addCard();
@ -454,6 +455,15 @@ void SettingsDialog::show()
m_dialog->window()->activate();
}
void SettingsDialog::retranslate()
{
if (!m_dialog || !m_content)
return;
m_dialog->setTitle(tr("Settings"));
m_content = m_dialog->setContent<SettingsContent>(m_window);
update();
}
void SettingsDialog::close()
{
if (m_dialog)

@ -29,6 +29,8 @@ public:
void show();
void close();
// An open dialog takes the new language in place, keeping its window.
void retranslate();
private:
void update();

@ -126,6 +126,15 @@ void TerminalPage::applySettings()
m_window->schemeColor(1, accent::red), m_window->schemeColor(4, Theme::current().highlight));
}
void TerminalPage::retranslate()
{
if (m_menu)
m_menu->close();
m_menu.reset();
if (m_findBar)
m_findBar->retranslate();
}
void TerminalPage::startShell()
{
m_session->startShellProgram();

@ -47,6 +47,9 @@ public:
// The settings and the window's zoom and colours, applied again.
void applySettings();
// The menu closes and the find bar takes the new language, keeping its
// search; the shell and its output stay as they are.
void retranslate();
void startShell();
void openFind();

@ -10,6 +10,7 @@
#include "base/i18n.h"
#include "base/strings.h"
#include "ui/animation.h"
#include "ui/application.h"
#include "ui/dialog_window.h"
#include "ui/drag.h"
#include "ui/header_button.h"
@ -345,6 +346,7 @@ TerminalWindow::TerminalWindow(Windows& windows, TerminalSettings& settings, Opt
m_window->onStatesChanged = [this] { applySettings(); };
m_connections.push_back(m_settings.changed.connect([this] { applySettings(); }));
m_connections.push_back(Application::instance()->languageChanged.connect([this] { retranslate(); }));
applySettings();
if (options.detachedPage) {
@ -417,6 +419,32 @@ void TerminalWindow::applySettings()
updateTitle();
}
// The shells, their output and the tabs stay; menus close, and the dialogs are
// made again, an open one shown again with what it was asking about.
void TerminalWindow::retranslate()
{
if (m_tabMenu)
m_tabMenu->close();
m_tabMenu.reset();
for (TerminalPage* page : m_pages)
page->retranslate();
if (m_settingsDialog)
m_settingsDialog->retranslate();
const bool exitShown = m_exitPrompt && m_exitPrompt->window();
const bool linkShown = m_linkConfirm && m_linkConfirm->window();
const bool pasteShown = m_pasteConfirm && m_pasteConfirm->window();
m_exitPrompt.reset();
m_linkConfirm.reset();
m_pasteConfirm.reset();
if (exitShown)
showExitPrompt();
if (linkShown)
showLinkConfirm();
if (pasteShown)
showPasteConfirm();
}
void TerminalWindow::updateBackground()
{
m_window->setBackgroundColor(m_terminalBackground.withAlpha(m_settings.opacity()));
@ -637,6 +665,12 @@ void TerminalWindow::confirmClose(const std::vector<TerminalPage*>& pages, std::
return;
}
m_pendingAction = std::move(action);
showExitPrompt();
}
void TerminalWindow::showExitPrompt()
{
if (!m_exitPrompt) {
m_exitPrompt = std::make_unique<ConfirmDialog>(m_window.get(), tr("Process is running, are you sure you want to quit?"));
m_exitPrompt->setCancelText(tr("Cancel"));
@ -648,7 +682,6 @@ void TerminalWindow::confirmClose(const std::vector<TerminalPage*>& pages, std::
};
m_exitPrompt->onRejected = [this] { m_pendingAction = nullptr; };
}
m_pendingAction = std::move(action);
m_exitPrompt->show();
}
@ -785,14 +818,20 @@ void TerminalWindow::openLink(const std::string& url)
return;
}
m_pendingLink = url;
showLinkConfirm();
}
void TerminalWindow::showLinkConfirm()
{
if (!m_linkConfirm) {
m_linkConfirm = std::make_unique<ConfirmDialog>(m_window.get(), tr("Open this link?"));
m_linkConfirm->setConfirmText(tr("Open"));
m_linkConfirm->onAccepted = [this] { ProcessHelper::openUrl(m_pendingLink); };
}
m_pendingLink = url;
const std::u16string utf16 = strings::utf8ToUtf16(url);
m_linkConfirm->setText(utf16.size() > 300 ? strings::utf16ToUtf8(utf16.substr(0, 299)) + "\xe2\x80\xa6" : url);
const std::u16string utf16 = strings::utf8ToUtf16(m_pendingLink);
m_linkConfirm->setText(utf16.size() > 300 ? strings::utf16ToUtf8(utf16.substr(0, 299)) + "\xe2\x80\xa6"
: m_pendingLink);
m_linkConfirm->show();
}
@ -812,6 +851,14 @@ void TerminalWindow::confirmPaste(const std::string& text, std::function<void()>
if (lines.size() > 4)
shown.push_back("\xe2\x80\xa6");
m_pasteLineCount = lines.size();
m_pastePreview = strings::join(shown, "\n");
m_pendingPaste = std::move(action);
showPasteConfirm();
}
void TerminalWindow::showPasteConfirm()
{
if (!m_pasteConfirm) {
m_pasteConfirm = std::make_unique<ConfirmDialog>(m_window.get(), std::string());
m_pasteConfirm->setConfirmText(tr("Paste"));
@ -822,10 +869,8 @@ void TerminalWindow::confirmPaste(const std::string& text, std::function<void()>
m_pasteConfirm->onRejected = [this] { m_pendingPaste = nullptr; };
}
const size_t count = lines.size();
m_pasteConfirm->setTitle(count > 1 ? trn("Paste {n} line?", "Paste {n} lines?", count)
: std::string(tr("Paste this line and press Enter?")));
m_pasteConfirm->setText(strings::join(shown, "\n"));
m_pendingPaste = std::move(action);
m_pasteConfirm->setTitle(m_pasteLineCount > 1 ? trn("Paste {n} line?", "Paste {n} lines?", m_pasteLineCount)
: std::string(tr("Paste this line and press Enter?")));
m_pasteConfirm->setText(m_pastePreview);
m_pasteConfirm->show();
}

@ -100,9 +100,13 @@ private:
class Overlay;
void applySettings();
void retranslate();
void updateBackground();
void updateTitle();
void confirmClose(const std::vector<TerminalPage*>& pages, std::function<void()> action);
void showExitPrompt();
void showLinkConfirm();
void showPasteConfirm();
void closeProtection(int index);
void detachTab(int index, cutefish::ui::PointF position);
void openTabMenu(int index, cutefish::ui::PointF position);
@ -137,6 +141,8 @@ private:
std::function<void()> m_pendingAction;
std::function<void()> m_pendingPaste;
std::string m_pendingLink;
size_t m_pasteLineCount = 0;
std::string m_pastePreview;
// Set once the close has been confirmed, so closing does not ask again.
bool m_quitting = false;

@ -16,6 +16,7 @@
#include "ui/keys.h"
#include "ui/painter.h"
#include "ui/test_input.h"
#include "ui/text_field.h"
#include "ui/view.h"
#include "ui/window.h"
@ -155,6 +156,61 @@ TEST_F(WindowTest, CloseOtherTabsAfterTheKeptTabEnded)
EXPECT_TRUE(busy->isVisible());
}
static ui::View* findView(ui::View* view, const std::string& name)
{
if (!view || view->name() == name)
return view;
for (const auto& child : view->children()) {
if (ui::View* found = findView(child.get(), name))
return found;
}
return nullptr;
}
TEST_F(WindowTest, LanguageChangeKeepsTheShellsAndTheSearch)
{
Windows windows(m_settings);
TerminalWindow* window = windows.create(shell());
TerminalPage* busy = window->currentPage();
window->openTab(m_directory.path(), {"/bin/sh"});
ASSERT_EQ(window->tabCount(), 2);
TerminalPage* page = window->currentPage();
Konsole::TerminalSession* session = &page->session();
Konsole::TerminalView* terminal = page->terminal();
page->setCustomTitle("Build");
page->openFind();
auto* field = static_cast<ui::TextField*>(findView(page, "findField"));
ASSERT_NE(field, nullptr);
field->setText("needle");
window->showSettings();
ui::Window* settings = ui::Application::instance()->windows().back();
ASSERT_NE(settings, &window->window());
const ui::View* settingsContent = findView(settings->contentView(), "settingsContent");
ASSERT_NE(settingsContent, nullptr);
busy->session().sendText("sleep 30\n");
ASSERT_TRUE(waitFor([&] { return busy->session().hasActiveProcess(); }));
window->closeOtherTabs(1);
ui::Application::instance()->languageChanged.emit();
ASSERT_EQ(window->tabCount(), 2);
EXPECT_EQ(window->currentPage(), page);
EXPECT_EQ(&page->session(), session);
EXPECT_EQ(page->terminal(), terminal);
EXPECT_EQ(page->title(), "Build");
EXPECT_TRUE(busy->session().hasActiveProcess());
EXPECT_EQ(static_cast<ui::TextField*>(findView(page, "findField"))->text(), "needle");
const ui::View* rebuilt = findView(settings->contentView(), "settingsContent");
ASSERT_NE(rebuilt, nullptr);
EXPECT_NE(rebuilt, settingsContent);
// The close question is asked again and still closes the other tab.
confirmLastDialog(window);
ASSERT_EQ(window->tabCount(), 1);
EXPECT_EQ(window->currentPage(), page);
}
TEST_F(WindowTest, CursorBlinksOnlyWithTheKeyboard)
{
Windows windows(m_settings);

Loading…
Cancel
Save