diff --git a/include/eepp/ui/abstract/uiabstracttableview.hpp b/include/eepp/ui/abstract/uiabstracttableview.hpp index 8831fa9e7..917550050 100644 --- a/include/eepp/ui/abstract/uiabstracttableview.hpp +++ b/include/eepp/ui/abstract/uiabstracttableview.hpp @@ -196,8 +196,11 @@ class EE_API UIAbstractTableView : public UIAbstractView { virtual Uint32 onTextInput( const TextInputEvent& event ); + virtual Uint32 onKeyDown( const KeyEvent& event ); + virtual void bindNavigationClick( UIWidget* widget ); + void updateHeaderSize(); int visibleColumn(); diff --git a/include/eepp/ui/abstract/uiabstractview.hpp b/include/eepp/ui/abstract/uiabstractview.hpp index 274834f9d..8d5837388 100644 --- a/include/eepp/ui/abstract/uiabstractview.hpp +++ b/include/eepp/ui/abstract/uiabstractview.hpp @@ -51,6 +51,8 @@ class EE_API UIAbstractView : public UIScrollableWidget { enum SelectionType { Row, Cell }; + enum SelectionKind { Single, Multiple }; + bool isCellSelection() const; bool isRowSelection() const; @@ -94,9 +96,9 @@ class EE_API UIAbstractView : public UIScrollableWidget { void setEditTriggers( Uint32 editTriggers ); - KeyBindings::Shortcut getEditShortcut() const; + std::vector getEditShortcuts() const; - void setEditShortcut( const KeyBindings::Shortcut& editShortcut ); + void setEditShortcuts( const std::vector& editShortcut ); void beginEditing( const ModelIndex& index, UIWidget* editedWidget ); @@ -111,6 +113,10 @@ class EE_API UIAbstractView : public UIScrollableWidget { Uint32 onModelEvent( const std::function& callback, const Event::EventType& triggerEventType = Event::EventType::NoEvent ); + SelectionKind getSelectionKind() const; + + void setSelectionKind( SelectionKind selectionKind ); + protected: friend class EE::UI::Models::Model; @@ -136,8 +142,9 @@ class EE_API UIAbstractView : public UIScrollableWidget { std::function mOnSelection; Uint32 mEditTriggers{ EditTrigger::None }; - KeyBindings::Shortcut mEditShortcut{ KEY_F2 }; + std::vector mEditShortcuts{ { KEY_F2 } }; SelectionType mSelectionType{ SelectionType::Row }; + SelectionKind mSelectionKind{ SelectionKind::Single }; virtual void editingWidgetDidChange( const ModelIndex& ) {} }; diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index 5d51e02df..8b2155e87 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -472,10 +472,18 @@ UITableRow* UIAbstractTableView::createRow() { !isRowSelection() ) return; auto index = event->getNode()->asType()->getCurIndex(); - if ( getUISceneNode()->getWindow()->getInput()->isControlPressed() ) { + if ( mSelectionKind == SelectionKind::Single && + getUISceneNode()->getWindow()->getInput()->getSanitizedModState() & + KeyMod::getDefaultModifier() ) { getSelection().remove( index ); } else { - getSelection().set( index ); + if ( mSelectionKind == SelectionKind::Multiple && + getUISceneNode()->getWindow()->getInput()->getSanitizedModState() & + KeyMod::getDefaultModifier() ) { + getSelection().toggle( index ); + } else { + getSelection().set( index ); + } } } ); onRowCreated( rowWidget ); @@ -774,6 +782,20 @@ Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) { return 1; } +Uint32 UIAbstractTableView::onKeyDown( const KeyEvent& event ) { + if ( isEditable() && getSelection().first().isValid() && getModel() && + getModel()->isEditable( getSelection().first() ) && + ( mEditTriggers & EditTrigger::EditKeyPressed ) && !mEditShortcuts.empty() ) { + for ( const auto& shortcut : mEditShortcuts ) { + if ( shortcut == KeyBindings::Shortcut{ event.getKeyCode(), event.getMod() } ) { + beginEditing( getSelection().first(), getCellFromIndex( getSelection().first() ) ); + return 1; + } + } + } + return UIAbstractView::onKeyDown( event ); +} + bool UIAbstractTableView::applyProperty( const StyleSheetProperty& attribute ) { if ( !checkPropertyDefinition( attribute ) ) return false; diff --git a/src/eepp/ui/abstract/uiabstractview.cpp b/src/eepp/ui/abstract/uiabstractview.cpp index 8a7927724..deaa3eb30 100644 --- a/src/eepp/ui/abstract/uiabstractview.cpp +++ b/src/eepp/ui/abstract/uiabstractview.cpp @@ -11,6 +11,14 @@ UIAbstractView::~UIAbstractView() { eeSAFE_DELETE( mEditingDelegate ); } +UIAbstractView::SelectionKind UIAbstractView::getSelectionKind() const { + return mSelectionKind; +} + +void UIAbstractView::setSelectionKind( UIAbstractView::SelectionKind selectionKind ) { + mSelectionKind = selectionKind; +} + UIAbstractView::SelectionType UIAbstractView::getSelectionType() const { return mSelectionType; } @@ -38,12 +46,12 @@ Uint32 UIAbstractView::onModelEvent( const std::function UIAbstractView::getEditShortcuts() const { + return mEditShortcuts; } -void UIAbstractView::setEditShortcut( const KeyBindings::Shortcut& editShortcut ) { - mEditShortcut = editShortcut; +void UIAbstractView::setEditShortcuts( const std::vector& editShortcuts ) { + mEditShortcuts = editShortcuts; } Uint32 UIAbstractView::getEditTriggers() const { @@ -149,7 +157,7 @@ ModelIndex UIAbstractView::findRowWithText( const std::string&, const bool&, con void UIAbstractView::beginEditing( const ModelIndex& index, UIWidget* editedWidget ) { if ( !isEditable() || !mModel || mEditIndex == index || !mModel->isEditable( index ) || - !onCreateEditingDelegate ) + !onCreateEditingDelegate || !editedWidget ) return; if ( mEditWidget ) { diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index 0dfc942b1..82f31af4e 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -955,7 +955,7 @@ bool UICodeEditorSplitter::tryTabClose( UIWidget* widget, mTryCloseMsgBox = UIMessageBox::New( UIMessageBox::OK_CANCEL, String::format( widget->getUISceneNode() - ->i18n( "@string/confirm_close_tab", + ->i18n( "confirm_close_tab", "Do you really want to close this tab?\nAll changes in " "\"%s\" will be lost." ) .toUtf8(), @@ -972,8 +972,8 @@ bool UICodeEditorSplitter::tryTabClose( UIWidget* widget, if ( onMsgBoxCloseCb ) onMsgBoxCloseCb(); } ); - mTryCloseMsgBox->setTitle( widget->getUISceneNode()->getTranslatorString( - "@string/ask_close_tab", "Close Tab?" ) ); + mTryCloseMsgBox->setTitle( + widget->getUISceneNode()->i18n( "ask_close_tab", "Close Tab?" ) ); mTryCloseMsgBox->center(); mTryCloseMsgBox->show(); return false; diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 616d73011..3a373ec48 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1055,8 +1055,8 @@ UIMenuItem* UICodeEditor::menuAdd( UIPopUpMenu* menu, const std::string& transla const String& translateString, const std::string& icon, const std::string& cmd ) { UIMenuItem* menuItem = - menu->add( getTranslatorString( "@string/uicodeeditor_" + translateKey, translateString ), - findIcon( icon ), mKeyBindings.getCommandKeybindString( cmd ) ); + menu->add( i18n( "uicodeeditor_" + translateKey, translateString ), findIcon( icon ), + mKeyBindings.getCommandKeybindString( cmd ) ); menuItem->setId( cmd ); return menuItem; } diff --git a/src/eepp/ui/uiconsole.cpp b/src/eepp/ui/uiconsole.cpp index a9de1bc3a..5c1550768 100644 --- a/src/eepp/ui/uiconsole.cpp +++ b/src/eepp/ui/uiconsole.cpp @@ -1196,8 +1196,8 @@ UIMenuItem* UIConsole::menuAdd( UIPopUpMenu* menu, const std::string& translateK const String& translateString, const std::string& icon, const std::string& cmd ) { UIMenuItem* menuItem = - menu->add( getTranslatorString( "@string/uiconsole_" + translateKey, translateString ), - findIcon( icon ), mKeyBindings.getCommandKeybindString( cmd ) ); + menu->add( i18n( "uiconsole_" + translateKey, translateString ), findIcon( icon ), + mKeyBindings.getCommandKeybindString( cmd ) ); menuItem->setId( cmd ); return menuItem; } diff --git a/src/eepp/ui/uifiledialog.cpp b/src/eepp/ui/uifiledialog.cpp index f5b560fce..30ba1ad85 100644 --- a/src/eepp/ui/uifiledialog.cpp +++ b/src/eepp/ui/uifiledialog.cpp @@ -50,9 +50,9 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa mContainer->setSize( getSize() ); if ( allowFolderSelect() ) { - setTitle( getTranslatorString( "@string/uifiledialog_select_folder", "Select a folder" ) ); + setTitle( i18n( "uifiledialog_select_folder", "Select a folder" ) ); } else { - setTitle( getTranslatorString( "@string/uifiledialog_select_file", "Select a file" ) ); + setTitle( i18n( "uifiledialog_select_file", "Select a file" ) ); } UILinearLayout* linearLayout = UILinearLayout::NewVertical(); @@ -67,7 +67,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa ->setId( "lay1" ); UITextView::New() - ->setText( getTranslatorString( "@string/uifiledialog_look_in", "Look in:" ) ) + ->setText( i18n( "uifiledialog_look_in", "Look in:" ) ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent ) ->setLayoutMargin( Rectf( 0, 0, 4, 0 ) ) ->setParent( hLayout ) @@ -83,14 +83,14 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa mPath->addEventListener( Event::OnPressEnter, cb::Make1( this, &UIFileDialog::onPressEnter ) ); mButtonUp = UIPushButton::New(); - mButtonUp->setText( getTranslatorString( "@string/uifiledialog_go_up", "Up" ) ) + mButtonUp->setText( i18n( "uifiledialog_go_up", "Up" ) ) ->setLayoutMarginLeft( 4 ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent ) ->setParent( hLayout ); mButtonNewFolder = UIPushButton::New(); mButtonNewFolder - ->setText( getTranslatorString( "@string/uifiledialog_new_folder", "New Folder" ) ) + ->setText( i18n( "uifiledialog_new_folder", "New Folder" ) ) ->setLayoutMarginLeft( 4 ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent ) ->setParent( hLayout ); @@ -98,9 +98,9 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa if ( event->asMouseEvent()->getFlags() & EE_BUTTON_LMASK ) { UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::INPUT, - getTranslatorString( "@string/uifiledialog_enter_new_folder_name", + i18n( "uifiledialog_enter_new_folder_name", "Enter new folder name:" ) ); - msgBox->setTitle( getTranslatorString( "@string/uifiledialog_create_new_folder", + msgBox->setTitle( i18n( "uifiledialog_create_new_folder", "Create new folder" ) ); msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } ); msgBox->show(); @@ -116,7 +116,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa } ); mButtonListView = UISelectButton::New(); - mButtonListView->setText( getTranslatorString( "@string/uifiledialog_list", "List" ) ) + mButtonListView->setText( i18n( "uifiledialog_list", "List" ) ) ->setLayoutMarginLeft( 4 ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent ) ->setParent( hLayout ); @@ -127,7 +127,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa } ); mButtonTableView = UISelectButton::New(); - mButtonTableView->setText( getTranslatorString( "@string/uifiledialog_table", "Table" ) ) + mButtonTableView->setText( i18n( "uifiledialog_table", "Table" ) ) ->setLayoutMarginLeft( 4 ) ->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent ) ->setParent( hLayout ); @@ -189,7 +189,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa ->setParent( linearLayout ); UITextView::New() - ->setText( getTranslatorString( "@string/uifiledialog_file_name", "File Name:" ) ) + ->setText( i18n( "uifiledialog_file_name", "File Name:" ) ) ->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::MatchParent ) ->setSize( 74, 0 ) ->setParent( hLayout ) @@ -205,8 +205,8 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa mButtonOpen = UIPushButton::New(); mButtonOpen - ->setText( isSaveDialog() ? getTranslatorString( "@string/uifiledialog_save", "Save" ) - : getTranslatorString( "@string/uifiledialog_open", "Open" ) ) + ->setText( isSaveDialog() ? i18n( "uifiledialog_save", "Save" ) + : i18n( "uifiledialog_open", "Open" ) ) ->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::WrapContent ) ->setSize( 80, 0 ) ->setParent( hLayout ); @@ -216,7 +216,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa ->setParent( linearLayout ); UITextView::New() - ->setText( getTranslatorString( "@string/uifiledialog_files_of_type", "Files of type:" ) ) + ->setText( i18n( "uifiledialog_files_of_type", "Files of type:" ) ) ->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::MatchParent ) ->setSize( 74, 0 ) ->setParent( hLayout ) @@ -232,7 +232,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa mFiletype->setLayoutMargin( Rectf( 0, 0, 4, 0 ) ); mButtonCancel = UIPushButton::New(); - mButtonCancel->setText( getTranslatorString( "@string/uifiledialog_cancel", "Cancel" ) ) + mButtonCancel->setText( i18n( "uifiledialog_cancel", "Cancel" ) ) ->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::WrapContent ) ->setSize( 80, 0 ) ->setParent( hLayout ); diff --git a/src/eepp/ui/uimessagebox.cpp b/src/eepp/ui/uimessagebox.cpp index e08d22c97..f766ec77a 100644 --- a/src/eepp/ui/uimessagebox.cpp +++ b/src/eepp/ui/uimessagebox.cpp @@ -75,22 +75,22 @@ UIMessageBox::UIMessageBox( const Type& type, const String& message, const Uint3 case UIMessageBox::INPUT: case UIMessageBox::TEXT_EDIT: case UIMessageBox::OK_CANCEL: { - mButtonOK->setText( getTranslatorString( "@string/msg_box_ok", "Ok" ) ); - mButtonCancel->setText( getTranslatorString( "@string/msg_box_cancel", "Cancel" ) ); + mButtonOK->setText( i18n( "msg_box_ok", "Ok" ) ); + mButtonCancel->setText( i18n( "msg_box_cancel", "Cancel" ) ); break; } case UIMessageBox::YES_NO: { - mButtonOK->setText( getTranslatorString( "@string/msg_box_yes", "Yes" ) ); - mButtonCancel->setText( getTranslatorString( "@string/msg_box_no", "No" ) ); + mButtonOK->setText( i18n( "msg_box_yes", "Yes" ) ); + mButtonCancel->setText( i18n( "msg_box_no", "No" ) ); break; } case UIMessageBox::RETRY_CANCEL: { - mButtonOK->setText( getTranslatorString( "@string/msg_box_retry", "Retry" ) ); - mButtonCancel->setText( getTranslatorString( "@string/msg_box_cancel", "Cancel" ) ); + mButtonOK->setText( i18n( "msg_box_retry", "Retry" ) ); + mButtonCancel->setText( i18n( "msg_box_cancel", "Cancel" ) ); break; } case UIMessageBox::OK: { - mButtonOK->setText( getTranslatorString( "@string/msg_box_ok", "Ok" ) ); + mButtonOK->setText( i18n( "msg_box_ok", "Ok" ) ); mButtonCancel->setVisible( false ); mButtonCancel->setEnabled( false ); break; @@ -115,7 +115,7 @@ void UIMessageBox::setTheme( UITheme* theme ) { mButtonOK->setTheme( theme ); mButtonCancel->setTheme( theme ); - if ( getTranslatorString( "@string/msg_box_retry", "Retry" ) != mButtonOK->getText() ) { + if ( i18n( "msg_box_retry", "Retry" ) != mButtonOK->getText() ) { Drawable* okIcon = getUISceneNode()->findIconDrawable( "ok", PixelDensity::dpToPxI( 16 ) ); Drawable* cancelIcon = getUISceneNode()->findIconDrawable( "cancel", PixelDensity::dpToPxI( 16 ) ); diff --git a/src/eepp/ui/uitextinput.cpp b/src/eepp/ui/uitextinput.cpp index db1c0454e..eadd4a513 100644 --- a/src/eepp/ui/uitextinput.cpp +++ b/src/eepp/ui/uitextinput.cpp @@ -880,7 +880,7 @@ UIMenuItem* UITextInput::menuAdd( UIPopUpMenu* menu, const std::string& translat const String& translateString, const std::string& icon, const std::string& cmd ) { UIMenuItem* menuItem = - menu->add( getTranslatorString( "@string/uicodeeditor_" + translateKey, translateString ), + menu->add( i18n( "uicodeeditor_" + translateKey, translateString ), findIcon( icon ), mKeyBindings.getCommandKeybindString( cmd ) ); menuItem->setId( cmd ); return menuItem; diff --git a/src/eepp/ui/uitreeview.cpp b/src/eepp/ui/uitreeview.cpp index fdadbfb48..c9900fb6b 100644 --- a/src/eepp/ui/uitreeview.cpp +++ b/src/eepp/ui/uitreeview.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -44,11 +45,12 @@ UITreeView::MetadataForIndex& UITreeView::getIndexMetadata( const ModelIndex& in void UITreeView::traverseTree( TreeViewCallback callback ) const { if ( !getModel() ) return; - auto& model = *getModel(); Lock l( const_cast( getModel() )->resourceMutex() ); + auto& model = *getModel(); int indentLevel = 0; Float yOffset = getHeaderHeight(); int rowIndex = -1; + Float rowHeight = getRowHeight(); std::function traverseIndex = [&]( const ModelIndex& index ) { if ( index.isValid() ) { @@ -57,7 +59,7 @@ void UITreeView::traverseTree( TreeViewCallback callback ) const { IterationDecision decision = callback( rowIndex, index, indentLevel, yOffset ); if ( decision == IterationDecision::Break || decision == IterationDecision::Stop ) return decision; - yOffset += getRowHeight(); + yOffset += rowHeight; if ( !metadata.open ) { return IterationDecision::Continue; } @@ -344,12 +346,13 @@ Sizef UITreeView::getContentSize() const { void UITreeView::drawChilds() { int realIndex = 0; + Float rowHeight = getRowHeight(); - traverseTree( [this, &realIndex]( const int&, const ModelIndex& index, - const size_t& indentLevel, const Float& yOffset ) { + traverseTree( [this, &realIndex, rowHeight]( const int&, const ModelIndex& index, + const size_t& indentLevel, const Float& yOffset ) { if ( yOffset - mScrollOffset.y > mSize.getHeight() ) return IterationDecision::Stop; - if ( yOffset - mScrollOffset.y + getRowHeight() < 0 ) + if ( yOffset - mScrollOffset.y + rowHeight < 0 ) return IterationDecision::Continue; for ( size_t colIndex = 0; colIndex < getModel()->columnCount(); colIndex++ ) { if ( columnData( colIndex ).visible ) { @@ -396,18 +399,19 @@ Node* UITreeView::overFind( const Vector2f& point ) { if ( mHeader && ( pOver = mHeader->overFind( point ) ) ) return pOver; int realIndex = 0; - traverseTree( - [&, point]( int, const ModelIndex& index, const size_t&, const Float& yOffset ) { - if ( yOffset - mScrollOffset.y > mSize.getHeight() ) - return IterationDecision::Stop; - if ( yOffset - mScrollOffset.y + getRowHeight() < 0 ) - return IterationDecision::Continue; - pOver = updateRow( realIndex, index, yOffset )->overFind( point ); - realIndex++; - if ( pOver ) - return IterationDecision::Stop; + Float rowHeight = getRowHeight(); + traverseTree( [&, point, rowHeight]( int, const ModelIndex& index, const size_t&, + const Float& yOffset ) { + if ( yOffset - mScrollOffset.y > mSize.getHeight() ) + return IterationDecision::Stop; + if ( yOffset - mScrollOffset.y + rowHeight < 0 ) return IterationDecision::Continue; - } ); + pOver = updateRow( realIndex, index, yOffset )->overFind( point ); + realIndex++; + if ( pOver ) + return IterationDecision::Stop; + return IterationDecision::Continue; + } ); if ( !pOver ) pOver = this; } @@ -709,6 +713,7 @@ Uint32 UITreeView::onKeyDown( const KeyEvent& event ) { default: break; } + return UIAbstractTableView::onKeyDown( event ); } diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index 20f0cc83b..ab3903f3d 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -557,8 +557,8 @@ UIMenuItem* UITerminal::menuAdd( UIPopUpMenu* menu, const std::string& translate const String& translateString, const std::string& icon, const std::string& cmd ) { UIMenuItem* menuItem = - menu->add( getTranslatorString( "@string/uiterminal_" + translateKey, translateString ), - findIcon( icon ), mKeyBindings.getCommandKeybindString( cmd ) ); + menu->add( i18n( "uiterminal_" + translateKey, translateString ), findIcon( icon ), + mKeyBindings.getCommandKeybindString( cmd ) ); menuItem->setId( cmd ); return menuItem; } diff --git a/src/tools/ecode/plugins/git/git.cpp b/src/tools/ecode/plugins/git/git.cpp index 9e7c96740..c08ef8802 100644 --- a/src/tools/ecode/plugins/git/git.cpp +++ b/src/tools/ecode/plugins/git/git.cpp @@ -229,6 +229,10 @@ Git::Result Git::stash( std::vector files, const std::string& proje projectDir ); } +Git::Result Git::restore( std::vector files, const std::string& projectDir ) { + return gitSimple( String::format( "restore -- %s", asList( files ) ), projectDir ); +} + Git::Result Git::restore( const std::string& file, const std::string& projectDir ) { return gitSimple( String::format( "restore \"%s\"", file ), projectDir ); } diff --git a/src/tools/ecode/plugins/git/git.hpp b/src/tools/ecode/plugins/git/git.hpp index 4e48f80fe..a10b52c37 100644 --- a/src/tools/ecode/plugins/git/git.hpp +++ b/src/tools/ecode/plugins/git/git.hpp @@ -247,6 +247,8 @@ class Git { Result stash( std::vector files, const std::string& projectDir = "" ); + Result restore( std::vector files, const std::string& projectDir = "" ); + Result restore( const std::string& file, const std::string& projectDir = "" ); Result reset( std::vector files, const std::string& projectDir = "" ); diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp index 81dccc4fe..5ff493627 100644 --- a/src/tools/ecode/plugins/git/gitplugin.cpp +++ b/src/tools/ecode/plugins/git/gitplugin.cpp @@ -886,6 +886,25 @@ void GitPlugin::unstage( const std::vector& files ) { true, false ); } +void GitPlugin::discard( const std::vector& files ) { + UIMessageBox* msgBox = UIMessageBox::New( + UIMessageBox::OK_CANCEL, + i18n( "git_confirm_discard_changes", "Are you sure you want to discard all file changes?" ) + .toUtf8() ); + + msgBox->on( Event::OnConfirm, [this, files]( auto ) { + runAsync( + [this, files]() { + return mGit->restore( fixFilePaths( files ), mGit->repoPath( files[0] ) ); + }, + true, false ); + } ); + msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } ); + msgBox->setTitle( i18n( "git_confirm", "Confirm" ) ); + msgBox->center(); + msgBox->showWhenReady(); +} + void GitPlugin::discard( const std::string& file ) { UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::OK_CANCEL, @@ -1347,6 +1366,7 @@ void GitPlugin::buildSidePanelTab() { mStatusTree->setHeadersVisible( false ); mStatusTree->setExpandersAsIcons( true ); mStatusTree->setScrollViewType( UIScrollableWidget::Inclusive ); + mStatusTree->setIndentWidth( PixelDensity::dpToPx( 4 ) ); mStatusTree->on( Event::OnRowCreated, [this]( const Event* event ) { UITableRow* row = event->asRowCreatedEvent()->getRow(); row->on( Event::MouseUp, [this, row]( const Event* event ) { @@ -1394,7 +1414,6 @@ void GitPlugin::buildSidePanelTab() { if ( status->type == Git::GitStatusType::Staged ) { addMenuItem( menu, "git-commit", "Commit", "git-commit" ); - addMenuItem( menu, "git-unstage-all", "Unstage All" ); } @@ -1402,6 +1421,11 @@ void GitPlugin::buildSidePanelTab() { status->type == Git::GitStatusType::Changed ) addMenuItem( menu, "git-stage-all", "Stage All" ); + if ( status->type == Git::GitStatusType::Changed ) { + menu->addSeparator(); + addMenuItem( menu, "git-discard-all", "Discard All" ); + } + menu->on( Event::OnItemClicked, [this, model, repoPath]( const Event* event ) { if ( !mGit ) @@ -1417,6 +1441,9 @@ void GitPlugin::buildSidePanelTab() { } else if ( id == "git-unstage-all" ) { unstage( model->getFiles( repoFullName( repoPath ), (Uint32)Git::GitStatusType::Staged ) ); + } else if ( id == "git-discard-all" ) { + discard( model->getFiles( repoFullName( repoPath ), + (Uint32)Git::GitStatusType::Changed ) ); } } ); @@ -1449,6 +1476,9 @@ void GitPlugin::buildSidePanelTab() { if ( repo->hasStatusType( Git::GitStatusType::Staged ) ) { addMenuItem( menu, "git-commit", "Commit", "git-commit" ); + } + + if ( repo->hasStatusType( Git::GitStatusType::Untracked ) ) { addMenuItem( menu, "git-stage-all", "Stage All" ); } @@ -1583,7 +1613,8 @@ void GitPlugin::openFileStatusMenu( const Git::DiffFile& file ) { menu->addSeparator(); - addMenuItem( menu, "git-discard", "Discard" ); + if ( file.report.type != Git::GitStatusType::Staged ) + addMenuItem( menu, "git-discard", "Discard" ); menu->on( Event::OnItemClicked, [this, file]( const Event* event ) { if ( !mGit ) diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp index c5fb1f3c2..45bcfc40f 100644 --- a/src/tools/ecode/plugins/git/gitplugin.hpp +++ b/src/tools/ecode/plugins/git/gitplugin.hpp @@ -171,6 +171,8 @@ class GitPlugin : public PluginBase { void unstage( const std::vector& files ); + void discard( const std::vector& files ); + void discard( const std::string& file ); void diff( const std::string& file, bool isStaged ); diff --git a/src/tools/ecode/uibuildsettings.cpp b/src/tools/ecode/uibuildsettings.cpp index aee0587c9..ab184ba69 100644 --- a/src/tools/ecode/uibuildsettings.cpp +++ b/src/tools/ecode/uibuildsettings.cpp @@ -707,8 +707,8 @@ void UIBuildSettings::bindTable( const std::string& name, const std::string& key }; return delegate; }; - model->setColumnName( 0, getTranslatorString( key + "_name", "Name" ) ); - model->setColumnName( 1, getTranslatorString( key + "_value", "Value" ) ); + model->setColumnName( 0, i18n( key + "_name", "Name" ) ); + model->setColumnName( 1, i18n( key + "_value", "Value" ) ); model->setIsEditable( true ); table->setMainColumn( 1 ); table->setAutoColumnsWidth( true );