mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 03:00:23 +03:00
• Fixed the keybinding merge bug. The helper was restoring missing default commands
by overwriting an occupied default shortcut, which treated user bindings like mod+d=duplicate-line-or-selection as stale because that command is not in the default keybinding table. Now it only adds a default when the default shortcut is actually free. Added a regression test in src/tests/unit_tests/uicodeeditor_tests.cpp:108 covering the reported case: mod+d reassigned, then an extra mod+e=show-markdown-preview binding exists. This was reported in SpartanJ/ecode#914. • Implemented the splitter-level focus state cache, it will remember closed documents cursor state when reopened and it will restore cursor state per-code editor and not per-document (SpartanJ/ecode#893).
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include <eepp/ui/uitabwidget.hpp>
|
#include <eepp/ui/uitabwidget.hpp>
|
||||||
|
|
||||||
#include <eepp/system/log.hpp>
|
#include <eepp/system/log.hpp>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
using namespace EE::UI::Doc;
|
using namespace EE::UI::Doc;
|
||||||
|
|
||||||
@@ -387,6 +388,10 @@ class EE_API UICodeEditorSplitter {
|
|||||||
|
|
||||||
bool openDocumentsInMainSplit() const { return mOpenDocumentsInMainSplit; }
|
bool openDocumentsInMainSplit() const { return mOpenDocumentsInMainSplit; }
|
||||||
|
|
||||||
|
void setRestoreEditorSelectionOnFocus( bool restore );
|
||||||
|
|
||||||
|
bool getRestoreEditorSelectionOnFocus() const { return mRestoreEditorSelectionOnFocus; }
|
||||||
|
|
||||||
UITabWidget* getFirstTabWidget() const;
|
UITabWidget* getFirstTabWidget() const;
|
||||||
|
|
||||||
UITabWidget* getPreferredTabWidget() const;
|
UITabWidget* getPreferredTabWidget() const;
|
||||||
@@ -413,6 +418,7 @@ class EE_API UICodeEditorSplitter {
|
|||||||
bool mFirstCodeEditor{ true };
|
bool mFirstCodeEditor{ true };
|
||||||
bool mVisualSplitting{ true };
|
bool mVisualSplitting{ true };
|
||||||
bool mOpenDocumentsInMainSplit{ false };
|
bool mOpenDocumentsInMainSplit{ false };
|
||||||
|
bool mRestoreEditorSelectionOnFocus{ true };
|
||||||
UICodeEditor* mAboutToAddEditor{ nullptr };
|
UICodeEditor* mAboutToAddEditor{ nullptr };
|
||||||
UIMessageBox* mTryCloseMsgBox{ nullptr };
|
UIMessageBox* mTryCloseMsgBox{ nullptr };
|
||||||
Mutex mTabWidgetMutex;
|
Mutex mTabWidgetMutex;
|
||||||
@@ -424,6 +430,7 @@ class EE_API UICodeEditorSplitter {
|
|||||||
size_t mNavigationHistoryMaxSize{ 100 };
|
size_t mNavigationHistoryMaxSize{ 100 };
|
||||||
std::vector<NavigationRecord> mNavigationHistory;
|
std::vector<NavigationRecord> mNavigationHistory;
|
||||||
size_t mNavigationHistoryPos{ std::numeric_limits<size_t>::max() };
|
size_t mNavigationHistoryPos{ std::numeric_limits<size_t>::max() };
|
||||||
|
std::unordered_map<UICodeEditor*, TextRanges> mEditorSelections;
|
||||||
std::function<void( UITabWidget* )> mOnTabWidgetCreateCb;
|
std::function<void( UITabWidget* )> mOnTabWidgetCreateCb;
|
||||||
Float mVisualSplitEdgePercent{ 0.1 };
|
Float mVisualSplitEdgePercent{ 0.1 };
|
||||||
TabTryCloseCallback mTabTryCloseCb;
|
TabTryCloseCallback mTabTryCloseCb;
|
||||||
@@ -436,6 +443,10 @@ class EE_API UICodeEditorSplitter {
|
|||||||
|
|
||||||
virtual void onTabClosed( const TabEvent* tabEvent );
|
virtual void onTabClosed( const TabEvent* tabEvent );
|
||||||
|
|
||||||
|
void saveEditorSelection( UICodeEditor* editor );
|
||||||
|
|
||||||
|
void restoreEditorSelection( UICodeEditor* editor );
|
||||||
|
|
||||||
void closeAllTabs( std::vector<UITab*> tabs, UITabWidget::FocusTabBehavior focusTabBehavior );
|
void closeAllTabs( std::vector<UITab*> tabs, UITabWidget::FocusTabBehavior focusTabBehavior );
|
||||||
|
|
||||||
UITabWidget* createTabWidget( Node* parent );
|
UITabWidget* createTabWidget( Node* parent );
|
||||||
|
|||||||
@@ -257,7 +257,18 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
|
|||||||
/* Splitter commands */
|
/* Splitter commands */
|
||||||
|
|
||||||
editor->on( Event::OnFocus, [this]( const Event* event ) {
|
editor->on( Event::OnFocus, [this]( const Event* event ) {
|
||||||
setCurrentWidget( event->getNode()->asType<UICodeEditor>() );
|
UICodeEditor* editor = event->getNode()->asType<UICodeEditor>();
|
||||||
|
UICodeEditor* prevEditor = mCurEditor;
|
||||||
|
if ( mRestoreEditorSelectionOnFocus && prevEditor && prevEditor != editor &&
|
||||||
|
!prevEditor->hasFocus() )
|
||||||
|
saveEditorSelection( prevEditor );
|
||||||
|
setCurrentWidget( editor );
|
||||||
|
if ( mRestoreEditorSelectionOnFocus && prevEditor && prevEditor != editor )
|
||||||
|
restoreEditorSelection( editor );
|
||||||
|
} );
|
||||||
|
editor->on( Event::OnFocusLoss, [this]( const Event* event ) {
|
||||||
|
if ( mRestoreEditorSelectionOnFocus )
|
||||||
|
saveEditorSelection( event->getNode()->asType<UICodeEditor>() );
|
||||||
} );
|
} );
|
||||||
editor->on( Event::OnTextChanged, [this]( const Event* event ) {
|
editor->on( Event::OnTextChanged, [this]( const Event* event ) {
|
||||||
mClient->onDocumentModified( event->getNode()->asType<UICodeEditor>(),
|
mClient->onDocumentModified( event->getNode()->asType<UICodeEditor>(),
|
||||||
@@ -559,8 +570,9 @@ UICodeEditorSplitter::createCodeEditorInTabWidget( UITabWidget* tabWidget ) {
|
|||||||
UICodeEditor* editor = createCodeEditor();
|
UICodeEditor* editor = createCodeEditor();
|
||||||
mAboutToAddEditor = editor;
|
mAboutToAddEditor = editor;
|
||||||
editor->on( Event::OnDocumentChanged, [this]( const Event* event ) {
|
editor->on( Event::OnDocumentChanged, [this]( const Event* event ) {
|
||||||
mClient->onDocumentStateChanged( event->getNode()->asType<UICodeEditor>(),
|
UICodeEditor* editor = event->getNode()->asType<UICodeEditor>();
|
||||||
event->getNode()->asType<UICodeEditor>()->getDocument() );
|
mEditorSelections.erase( editor );
|
||||||
|
mClient->onDocumentStateChanged( editor, editor->getDocument() );
|
||||||
} );
|
} );
|
||||||
UITab* tab = tabWidget->add( editor->getDocument().getFilename(), editor );
|
UITab* tab = tabWidget->add( editor->getDocument().getFilename(), editor );
|
||||||
editor->setData( (UintPtr)tab );
|
editor->setData( (UintPtr)tab );
|
||||||
@@ -1716,6 +1728,38 @@ void UICodeEditorSplitter::clearNavigationHistory() {
|
|||||||
mNavigationHistoryPos = std::numeric_limits<size_t>::max();
|
mNavigationHistoryPos = std::numeric_limits<size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UICodeEditorSplitter::setRestoreEditorSelectionOnFocus( bool restore ) {
|
||||||
|
if ( mRestoreEditorSelectionOnFocus == restore )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mRestoreEditorSelectionOnFocus = restore;
|
||||||
|
if ( !mRestoreEditorSelectionOnFocus )
|
||||||
|
mEditorSelections.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UICodeEditorSplitter::saveEditorSelection( UICodeEditor* editor ) {
|
||||||
|
if ( editor && editor->hasDocument() )
|
||||||
|
mEditorSelections[editor] = editor->getDocument().getSelections();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UICodeEditorSplitter::restoreEditorSelection( UICodeEditor* editor ) {
|
||||||
|
if ( !editor || !editor->hasDocument() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto it = mEditorSelections.find( editor );
|
||||||
|
if ( it == mEditorSelections.end() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
TextRanges selection = editor->getDocument().sanitizeRange( it->second );
|
||||||
|
if ( selection.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// resetSelection() drops stale extra cursors; setSelection() updates the active cursor index.
|
||||||
|
editor->getDocument().resetSelection( selection );
|
||||||
|
editor->getDocument().setSelection( selection );
|
||||||
|
editor->scrollToCursor();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ThreadPool> UICodeEditorSplitter::getThreadPool() const {
|
std::shared_ptr<ThreadPool> UICodeEditorSplitter::getThreadPool() const {
|
||||||
return mThreadPool;
|
return mThreadPool;
|
||||||
}
|
}
|
||||||
@@ -1798,6 +1842,8 @@ void UICodeEditorSplitter::closeSplitter( UISplitter* splitter ) {
|
|||||||
void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
|
void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
|
||||||
UIWidget* widget = tabEvent->getTab()->getOwnedWidget()->asType<UIWidget>();
|
UIWidget* widget = tabEvent->getTab()->getOwnedWidget()->asType<UIWidget>();
|
||||||
UITabWidget* tabWidget = tabEvent->getTab()->getTabWidget();
|
UITabWidget* tabWidget = tabEvent->getTab()->getTabWidget();
|
||||||
|
if ( widget && widget->isType( UI_TYPE_CODEEDITOR ) )
|
||||||
|
mEditorSelections.erase( widget->asType<UICodeEditor>() );
|
||||||
if ( tabWidget->getTabCount() == 0 ) {
|
if ( tabWidget->getTabCount() == 0 ) {
|
||||||
UISplitter* splitter = splitterFromWidget( widget );
|
UISplitter* splitter = splitterFromWidget( widget );
|
||||||
if ( splitter ) {
|
if ( splitter ) {
|
||||||
|
|||||||
@@ -1605,6 +1605,11 @@ Uint32 UICodeEditor::onMouseDown( const Vector2i& position, const Uint32& flags
|
|||||||
if ( localPos.y < mPluginsTopSpace )
|
if ( localPos.y < mPluginsTopSpace )
|
||||||
return UIWidget::onMouseDown( position, flags );
|
return UIWidget::onMouseDown( position, flags );
|
||||||
|
|
||||||
|
const auto resetSelectionTo = [this]( const TextPosition& pos ) {
|
||||||
|
mDoc->resetSelection();
|
||||||
|
mDoc->setSelection( pos );
|
||||||
|
};
|
||||||
|
|
||||||
bool downOverGutter = localPos.x < mPaddingPx.Left + getGutterWidth();
|
bool downOverGutter = localPos.x < mPaddingPx.Left + getGutterWidth();
|
||||||
|
|
||||||
if ( flags & EE_BUTTON_LMASK ) {
|
if ( flags & EE_BUTTON_LMASK ) {
|
||||||
@@ -1620,14 +1625,14 @@ Uint32 UICodeEditor::onMouseDown( const Vector2i& position, const Uint32& flags
|
|||||||
return UIWidget::onMouseDown( position, flags );
|
return UIWidget::onMouseDown( position, flags );
|
||||||
|
|
||||||
if ( !downOverGutter || mAllowSelectingTextFromGutter )
|
if ( !downOverGutter || mAllowSelectingTextFromGutter )
|
||||||
mDoc->setSelection( textScreenPos );
|
resetSelectionTo( textScreenPos );
|
||||||
if ( downOverGutter && mAllowSelectingTextFromGutter )
|
if ( downOverGutter && mAllowSelectingTextFromGutter )
|
||||||
mDoc->selectLine();
|
mDoc->selectLine();
|
||||||
}
|
}
|
||||||
} else if ( !downOverGutter && tryExecuteMouseBinding( shortcut ) ) {
|
} else if ( !downOverGutter && tryExecuteMouseBinding( shortcut ) ) {
|
||||||
return UIWidget::onMouseDown( position, flags );
|
return UIWidget::onMouseDown( position, flags );
|
||||||
} else if ( !mDoc->hasSelection() ) {
|
} else if ( !mDoc->hasSelection() ) {
|
||||||
mDoc->setSelection( textScreenPos );
|
resetSelectionTo( textScreenPos );
|
||||||
}
|
}
|
||||||
} else if ( !( flags & ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) ) {
|
} else if ( !( flags & ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) ) {
|
||||||
tryExecuteMouseBinding( shortcut );
|
tryExecuteMouseBinding( shortcut );
|
||||||
|
|||||||
@@ -2,14 +2,18 @@
|
|||||||
#include <eepp/scene/node.hpp>
|
#include <eepp/scene/node.hpp>
|
||||||
#include <eepp/scene/scenemanager.hpp>
|
#include <eepp/scene/scenemanager.hpp>
|
||||||
#include <eepp/system/filesystem.hpp>
|
#include <eepp/system/filesystem.hpp>
|
||||||
|
#include <eepp/system/inifile.hpp>
|
||||||
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
||||||
#include <eepp/ui/uiapplication.hpp>
|
#include <eepp/ui/uiapplication.hpp>
|
||||||
#include <eepp/ui/uicodeeditor.hpp>
|
#include <eepp/ui/uicodeeditor.hpp>
|
||||||
|
|
||||||
|
#include "../../tools/ecode/keybindingshelper.cpp"
|
||||||
|
|
||||||
using namespace EE;
|
using namespace EE;
|
||||||
using namespace EE::UI;
|
using namespace EE::UI;
|
||||||
using namespace EE::UI::Doc;
|
using namespace EE::UI::Doc;
|
||||||
using namespace EE::Scene;
|
using namespace EE::Scene;
|
||||||
|
using namespace EE::System;
|
||||||
|
|
||||||
static const std::string userCode = R"objcpp(#import "common.h"
|
static const std::string userCode = R"objcpp(#import "common.h"
|
||||||
#import <cmath>
|
#import <cmath>
|
||||||
@@ -101,6 +105,87 @@ OF_APPLICATION_DELEGATE(test)
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTEST( KeybindingsHelper, PreservesUserShortcutWhenAddingBinding ) {
|
||||||
|
UIApplication app(
|
||||||
|
WindowSettings( 320, 240, "eepp - KeybindingsHelper Test", WindowStyle::Default,
|
||||||
|
WindowBackend::Default, 32 ),
|
||||||
|
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||||
|
|
||||||
|
const std::string path = Sys::getTempPath() + "eepp_keybindingshelper.cfg";
|
||||||
|
const std::string statePath = Sys::getTempPath() + "eepp_keybindingshelper_state.cfg";
|
||||||
|
FileSystem::fileRemove( path );
|
||||||
|
FileSystem::fileRemove( statePath );
|
||||||
|
|
||||||
|
IniFile ini( path, false );
|
||||||
|
IniFile iniState( statePath, false );
|
||||||
|
const std::string group( "editor" );
|
||||||
|
const std::string modD( "mod+d" );
|
||||||
|
const std::string modX( "mod+x" );
|
||||||
|
const std::string modE( "mod+e" );
|
||||||
|
ini.setValue( group, modD, std::string( "duplicate-line-or-selection" ) );
|
||||||
|
ini.setValue( group, modX, std::string( "cut" ) );
|
||||||
|
ini.setValue( group, modE, std::string( "show-markdown-preview" ) );
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> keybindings;
|
||||||
|
std::unordered_map<std::string, std::string> invertedKeybindings;
|
||||||
|
const std::map<KeyBindings::Shortcut, std::string> defaultKeybindings{
|
||||||
|
{ { KEY_D, KeyMod::getDefaultModifier() }, "select-word" },
|
||||||
|
{ { KEY_X, KeyMod::getDefaultModifier() }, "cut" },
|
||||||
|
};
|
||||||
|
|
||||||
|
ecode::KeybindingsHelper::updateKeybindings( ini, group, app.getWindow()->getInput(),
|
||||||
|
keybindings, invertedKeybindings,
|
||||||
|
defaultKeybindings, false, {}, iniState );
|
||||||
|
|
||||||
|
ASSERT_TRUE( keybindings.find( modD ) != keybindings.end() );
|
||||||
|
const std::string savedModD = ini.getValue( group, modD, "" );
|
||||||
|
EXPECT_STREQ( keybindings[modD].c_str(), "duplicate-line-or-selection" );
|
||||||
|
EXPECT_STREQ( savedModD.c_str(), "duplicate-line-or-selection" );
|
||||||
|
EXPECT_STREQ( invertedKeybindings["duplicate-line-or-selection"].c_str(), modD.c_str() );
|
||||||
|
|
||||||
|
FileSystem::fileRemove( path );
|
||||||
|
FileSystem::fileRemove( statePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
UTEST( KeybindingsHelper, RestoresMissingCommandWhenShortcutIsFree ) {
|
||||||
|
UIApplication app(
|
||||||
|
WindowSettings( 320, 240, "eepp - KeybindingsHelper Test", WindowStyle::Default,
|
||||||
|
WindowBackend::Default, 32 ),
|
||||||
|
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
|
||||||
|
|
||||||
|
const std::string path = Sys::getTempPath() + "eepp_keybindingshelper_restore.cfg";
|
||||||
|
const std::string statePath = Sys::getTempPath() + "eepp_keybindingshelper_restore_state.cfg";
|
||||||
|
FileSystem::fileRemove( path );
|
||||||
|
FileSystem::fileRemove( statePath );
|
||||||
|
|
||||||
|
IniFile ini( path, false );
|
||||||
|
IniFile iniState( statePath, false );
|
||||||
|
const std::string group( "editor" );
|
||||||
|
const std::string modD( "mod+d" );
|
||||||
|
const std::string modX( "mod+x" );
|
||||||
|
ini.setValue( group, modX, std::string( "cut" ) );
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::string> keybindings;
|
||||||
|
std::unordered_map<std::string, std::string> invertedKeybindings;
|
||||||
|
const std::map<KeyBindings::Shortcut, std::string> defaultKeybindings{
|
||||||
|
{ { KEY_D, KeyMod::getDefaultModifier() }, "select-word" },
|
||||||
|
{ { KEY_X, KeyMod::getDefaultModifier() }, "cut" },
|
||||||
|
};
|
||||||
|
|
||||||
|
ecode::KeybindingsHelper::updateKeybindings( ini, group, app.getWindow()->getInput(),
|
||||||
|
keybindings, invertedKeybindings,
|
||||||
|
defaultKeybindings, false, {}, iniState );
|
||||||
|
|
||||||
|
ASSERT_TRUE( keybindings.find( modD ) != keybindings.end() );
|
||||||
|
const std::string savedModD = ini.getValue( group, modD, "" );
|
||||||
|
EXPECT_STREQ( keybindings[modD].c_str(), "select-word" );
|
||||||
|
EXPECT_STREQ( savedModD.c_str(), "select-word" );
|
||||||
|
EXPECT_STREQ( invertedKeybindings["select-word"].c_str(), modD.c_str() );
|
||||||
|
|
||||||
|
FileSystem::fileRemove( path );
|
||||||
|
FileSystem::fileRemove( statePath );
|
||||||
|
}
|
||||||
|
|
||||||
UTEST( UICodeEditor, DocumentViewStressTest ) {
|
UTEST( UICodeEditor, DocumentViewStressTest ) {
|
||||||
UIApplication app(
|
UIApplication app(
|
||||||
WindowSettings( 800, 600, "eepp - Stress Test", WindowStyle::Default,
|
WindowSettings( 800, 600, "eepp - Stress Test", WindowStyle::Default,
|
||||||
|
|||||||
@@ -196,6 +196,8 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
|
|||||||
editor.hideTabBarOnSingleTab = ini.getValueB( "editor", "hide_tab_bar_on_single_tab", false );
|
editor.hideTabBarOnSingleTab = ini.getValueB( "editor", "hide_tab_bar_on_single_tab", false );
|
||||||
editor.hideTabBar = ini.getValueB( "editor", "hide_tab_bar", false );
|
editor.hideTabBar = ini.getValueB( "editor", "hide_tab_bar", false );
|
||||||
editor.tabSwitcher = ini.getValueB( "editor", "tab_switcher", false );
|
editor.tabSwitcher = ini.getValueB( "editor", "tab_switcher", false );
|
||||||
|
editor.restoreEditorSelectionOnFocus =
|
||||||
|
ini.getValueB( "editor", "restore_editor_selection_on_focus", true );
|
||||||
editor.tabJumpMode =
|
editor.tabJumpMode =
|
||||||
UITabWidget::tabJumpModefromString( ini.getValue( "editor", "tab_jump_mode", "linear" ) );
|
UITabWidget::tabJumpModefromString( ini.getValue( "editor", "tab_jump_mode", "linear" ) );
|
||||||
|
|
||||||
@@ -388,6 +390,8 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
|
|||||||
ini.setValueB( "editor", "hide_tab_bar_on_single_tab", editor.hideTabBarOnSingleTab );
|
ini.setValueB( "editor", "hide_tab_bar_on_single_tab", editor.hideTabBarOnSingleTab );
|
||||||
ini.setValueB( "editor", "hide_tab_bar", editor.hideTabBar );
|
ini.setValueB( "editor", "hide_tab_bar", editor.hideTabBar );
|
||||||
ini.setValueB( "editor", "tab_switcher", editor.tabSwitcher );
|
ini.setValueB( "editor", "tab_switcher", editor.tabSwitcher );
|
||||||
|
ini.setValueB( "editor", "restore_editor_selection_on_focus",
|
||||||
|
editor.restoreEditorSelectionOnFocus );
|
||||||
ini.setValue( "editor", "tab_jump_mode",
|
ini.setValue( "editor", "tab_jump_mode",
|
||||||
UITabWidget::tabJumpModeToString( editor.tabJumpMode ) );
|
UITabWidget::tabJumpModeToString( editor.tabJumpMode ) );
|
||||||
ini.setValue( "editor", "new_tab_position", NewTabPosition::toString( editor.newTabPosition ) );
|
ini.setValue( "editor", "new_tab_position", NewTabPosition::toString( editor.newTabPosition ) );
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ struct CodeEditorConfig {
|
|||||||
bool hideTabBar{ false };
|
bool hideTabBar{ false };
|
||||||
bool tabSwitcher{ false };
|
bool tabSwitcher{ false };
|
||||||
bool openDocumentsInMainSplit{ false };
|
bool openDocumentsInMainSplit{ false };
|
||||||
|
bool restoreEditorSelectionOnFocus{ true };
|
||||||
UITabWidget::TabJumpMode tabJumpMode{ UITabWidget::TabJumpMode::Linear };
|
UITabWidget::TabJumpMode tabJumpMode{ UITabWidget::TabJumpMode::Linear };
|
||||||
NewTabPosition::Position newTabPosition{ NewTabPosition::Last };
|
NewTabPosition::Position newTabPosition{ NewTabPosition::Last };
|
||||||
|
|
||||||
|
|||||||
@@ -4966,6 +4966,7 @@ void App::init( InitParameters& params ) {
|
|||||||
mSplitter->setHideTabBarOnSingleTab( mConfig.editor.hideTabBarOnSingleTab );
|
mSplitter->setHideTabBarOnSingleTab( mConfig.editor.hideTabBarOnSingleTab );
|
||||||
mSplitter->setHideTabBar( mConfig.editor.hideTabBar );
|
mSplitter->setHideTabBar( mConfig.editor.hideTabBar );
|
||||||
mSplitter->setOpenDocumentsInMainSplit( mConfig.editor.openDocumentsInMainSplit );
|
mSplitter->setOpenDocumentsInMainSplit( mConfig.editor.openDocumentsInMainSplit );
|
||||||
|
mSplitter->setRestoreEditorSelectionOnFocus( mConfig.editor.restoreEditorSelectionOnFocus );
|
||||||
mSplitter->setOnTabWidgetCreateCb( [this]( UITabWidget* tabWidget ) {
|
mSplitter->setOnTabWidgetCreateCb( [this]( UITabWidget* tabWidget ) {
|
||||||
tabWidget->getTabBar()->onDoubleClick(
|
tabWidget->getTabBar()->onDoubleClick(
|
||||||
[this]( const MouseEvent* ) { mSplitter->createEditorInNewTab(); } );
|
[this]( const MouseEvent* ) { mSplitter->createEditorInNewTab(); } );
|
||||||
|
|||||||
@@ -58,22 +58,6 @@ void KeybindingsHelper::updateKeybindings(
|
|||||||
invertedKeybindings[key.second] = shortcutStr;
|
invertedKeybindings[key.second] = shortcutStr;
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
ini.setValue( group, shortcutStr, key.second );
|
||||||
added = true;
|
added = true;
|
||||||
} else if ( foundCmd == invertedKeybindings.end() ) {
|
|
||||||
// Override the shortcut if the command that holds that
|
|
||||||
// shortcut does not exists anymore
|
|
||||||
auto kb = keybindings.find( shortcutStr );
|
|
||||||
if ( kb != keybindings.end() ) {
|
|
||||||
bool found = false;
|
|
||||||
for ( const auto& val : defKeybindings )
|
|
||||||
if ( val.second == kb->second )
|
|
||||||
found = true;
|
|
||||||
if ( !found ) {
|
|
||||||
keybindings[shortcutStr] = key.second;
|
|
||||||
invertedKeybindings[key.second] = shortcutStr;
|
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,22 +131,6 @@ void KeybindingsHelper::updateKeybindings(
|
|||||||
invertedKeybindings[key.second] = shortcutStr;
|
invertedKeybindings[key.second] = shortcutStr;
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
ini.setValue( group, shortcutStr, key.second );
|
||||||
added = true;
|
added = true;
|
||||||
} else if ( foundCmd == invertedKeybindings.end() ) {
|
|
||||||
// Override the shortcut if the command that holds that
|
|
||||||
// shortcut does not exists anymore
|
|
||||||
auto kb = keybindings.find( shortcutStr );
|
|
||||||
if ( kb != keybindings.end() ) {
|
|
||||||
bool found = false;
|
|
||||||
for ( const auto& val : defKeybindings )
|
|
||||||
if ( val.second == kb->second )
|
|
||||||
found = true;
|
|
||||||
if ( !found ) {
|
|
||||||
keybindings[shortcutStr] = key.second;
|
|
||||||
invertedKeybindings[key.second] = shortcutStr;
|
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,22 +203,6 @@ void KeybindingsHelper::updateKeybindings(
|
|||||||
invertedKeybindings[key.second] = shortcutStr;
|
invertedKeybindings[key.second] = shortcutStr;
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
ini.setValue( group, shortcutStr, key.second );
|
||||||
added = true;
|
added = true;
|
||||||
} else if ( foundCmd == invertedKeybindings.end() ) {
|
|
||||||
// Override the shortcut if the command that holds that
|
|
||||||
// shortcut does not exists anymore
|
|
||||||
auto kb = keybindings.find( shortcutStr );
|
|
||||||
if ( kb != keybindings.end() ) {
|
|
||||||
bool found = false;
|
|
||||||
for ( const auto& val : defKeybindings )
|
|
||||||
if ( val.second == kb->second )
|
|
||||||
found = true;
|
|
||||||
if ( !found ) {
|
|
||||||
keybindings[shortcutStr] = key.second;
|
|
||||||
invertedKeybindings[key.second] = shortcutStr;
|
|
||||||
ini.setValue( group, shortcutStr, key.second );
|
|
||||||
added = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2077,6 +2077,15 @@ UIMenu* SettingsMenu::createViewMenu() {
|
|||||||
"Synchronizes the current focused document as the selected\nfile in the "
|
"Synchronizes the current focused document as the selected\nfile in the "
|
||||||
"directory tree." ) )
|
"directory tree." ) )
|
||||||
->setId( "sync-project-tree" );
|
->setId( "sync-project-tree" );
|
||||||
|
mViewMenu
|
||||||
|
->addCheckBox(
|
||||||
|
i18n( "restore_editor_selection_on_focus", "Restore editor selection on focus" ) )
|
||||||
|
->setActive( mApp->getConfig().editor.restoreEditorSelectionOnFocus )
|
||||||
|
->setTooltipText(
|
||||||
|
i18n( "restore_editor_selection_on_focus_tooltip",
|
||||||
|
"Restores each editor split's last cursor and selection state when it regains "
|
||||||
|
"focus." ) )
|
||||||
|
->setId( "restore-editor-selection-on-focus" );
|
||||||
|
|
||||||
mViewMenu->addSeparator();
|
mViewMenu->addSeparator();
|
||||||
mViewMenu
|
mViewMenu
|
||||||
@@ -2210,6 +2219,11 @@ UIMenu* SettingsMenu::createViewMenu() {
|
|||||||
} else if ( item->getId() == "sync-project-tree" ) {
|
} else if ( item->getId() == "sync-project-tree" ) {
|
||||||
mApp->getConfig().editor.syncProjectTreeWithEditor =
|
mApp->getConfig().editor.syncProjectTreeWithEditor =
|
||||||
item->asType<UIMenuCheckBox>()->isActive();
|
item->asType<UIMenuCheckBox>()->isActive();
|
||||||
|
} else if ( item->getId() == "restore-editor-selection-on-focus" ) {
|
||||||
|
mApp->getConfig().editor.restoreEditorSelectionOnFocus =
|
||||||
|
item->asType<UIMenuCheckBox>()->isActive();
|
||||||
|
mSplitter->setRestoreEditorSelectionOnFocus(
|
||||||
|
mApp->getConfig().editor.restoreEditorSelectionOnFocus );
|
||||||
} else {
|
} else {
|
||||||
String text = String( event->getNode()->asType<UIMenuItem>()->getId() ).toLower();
|
String text = String( event->getNode()->asType<UIMenuItem>()->getId() ).toLower();
|
||||||
String::replaceAll( text, " ", "-" );
|
String::replaceAll( text, " ", "-" );
|
||||||
|
|||||||
Reference in New Issue
Block a user