diff --git a/bin/assets/i18n/de.xml b/bin/assets/i18n/de.xml
index 02ddbf361..d5861e19e 100644
--- a/bin/assets/i18n/de.xml
+++ b/bin/assets/i18n/de.xml
@@ -1292,6 +1292,7 @@ Für sichtbare Änderung ecode neu starten.
Keine weiteren Commits
Im Git-Verlauf anzeigen
Git-Commit-Verlauf – %s
+ Geänderte Dateien (%zu) +%zu -%zu
Commit-SHA
Commit-SHA kopieren
%s
Zur geteilten Diff-Ansicht wechseln
diff --git a/bin/assets/i18n/en.xml b/bin/assets/i18n/en.xml
index 586295b0e..a2b7d6e32 100644
--- a/bin/assets/i18n/en.xml
+++ b/bin/assets/i18n/en.xml
@@ -1277,6 +1277,7 @@ Restart ecode to see the changes.
No additional commits
Show in Git History
Git Commit History - %s
+ Changed files (%zu) +%zu -%zu
Commit SHA
Copy Commit SHA
%s
Switch to split diff view
diff --git a/bin/assets/i18n/fr.xml b/bin/assets/i18n/fr.xml
index de1ce5a2d..e68a81114 100644
--- a/bin/assets/i18n/fr.xml
+++ b/bin/assets/i18n/fr.xml
@@ -1276,6 +1276,7 @@ Redémarrer ecode pour voir les changements.
Aucun commit supplémentaire
Afficher dans l’historique Git
Historique des commits Git – %s
+ Fichiers modifiés (%zu) +%zu -%zu
SHA du commit
Copier le SHA du commit
%s
Passer à la vue des différences séparée
diff --git a/bin/assets/i18n/zh.xml b/bin/assets/i18n/zh.xml
index de3b2502c..684bd63bb 100644
--- a/bin/assets/i18n/zh.xml
+++ b/bin/assets/i18n/zh.xml
@@ -1081,6 +1081,7 @@ file in the directory tree.
没有其他提交
在 Git 历史记录中显示
Git 提交历史记录 - %s
+ 已更改文件(%zu) +%zu -%zu
提交 SHA
复制提交 SHA
%s
切换到拆分差异视图
diff --git a/include/eepp/ui/tools/uidiffview.hpp b/include/eepp/ui/tools/uidiffview.hpp
index a00b917ec..c9185c0ee 100644
--- a/include/eepp/ui/tools/uidiffview.hpp
+++ b/include/eepp/ui/tools/uidiffview.hpp
@@ -17,11 +17,14 @@ class Sprite;
namespace UI {
class UIScrollView;
+class UIPushButton;
+class UITextView;
namespace Tools {
class UIImageViewer;
class UIDiffEditorPlugin;
+class UIMultiDiffView;
class EE_API UIDiffView : public UIWidget, public WidgetCommandExecuter {
public:
@@ -182,6 +185,8 @@ class EE_API UIDiffView : public UIWidget, public WidgetCommandExecuter {
std::string mImageDiffOldPath;
std::string mImageDiffNewPath;
+ friend class UIMultiDiffView;
+
UIDiffView();
virtual void onSizePolicyChange() override;
@@ -231,6 +236,67 @@ class EE_API UIDiffView : public UIWidget, public WidgetCommandExecuter {
void updateFileHeaderInfo();
};
+class EE_API UIMultiDiffView : public UILinearLayout {
+ public:
+ static UIMultiDiffView* New( const std::string& patchText, const std::string& repoPath = "",
+ UIDiffView::ViewMode viewMode = UIDiffView::ViewMode::Unified,
+ bool interactiveFileHeaders = false );
+
+ static UIMultiDiffView* New( std::shared_ptr preparedDiff,
+ const std::string& repoPath = "",
+ UIDiffView::ViewMode viewMode = UIDiffView::ViewMode::Unified,
+ bool interactiveFileHeaders = false );
+
+ const std::vector& getDiffViews() const { return mDiffViews; }
+
+ UIScrollView* getScrollView() const { return mScrollView; }
+
+ void setViewMode( UIDiffView::ViewMode mode );
+
+ UIDiffView::ViewMode getViewMode() const { return mViewMode; }
+
+ void setCollapsed( bool collapsed );
+
+ bool isCollapsed() const { return mCollapsed; }
+
+ void setToolbarVisible( bool visible );
+
+ bool isToolbarVisible() const;
+
+ size_t getFileCount() const { return mFileCount; }
+
+ size_t getAddedLines() const { return mAddedLines; }
+
+ size_t getRemovedLines() const { return mRemovedLines; }
+
+ protected:
+ UILinearLayout* mToolbar{ nullptr };
+ UIPushButton* mFilesToggle{ nullptr };
+ UIPushButton* mModeToggle{ nullptr };
+ UITextView* mFilesStatus{ nullptr };
+ UIScrollView* mScrollView{ nullptr };
+ std::vector mDiffViews;
+ UIDiffView::ViewMode mViewMode{ UIDiffView::ViewMode::Unified };
+ size_t mFileCount{ 0 };
+ size_t mAddedLines{ 0 };
+ size_t mRemovedLines{ 0 };
+ bool mCollapsed{ false };
+
+ UIMultiDiffView();
+
+ void load( std::shared_ptr preparedDiff,
+ const std::string& repoPath, UIDiffView::ViewMode viewMode,
+ bool interactiveFileHeaders );
+
+ void updateFilesToggle();
+
+ void updateModeToggle();
+
+ void updateStatus();
+
+ virtual void onThemeLoaded() override;
+};
+
} // namespace Tools
} // namespace UI
} // namespace EE
diff --git a/src/eepp/ui/tools/uidiffview.cpp b/src/eepp/ui/tools/uidiffview.cpp
index b7b69e6cc..4e12b4577 100644
--- a/src/eepp/ui/tools/uidiffview.cpp
+++ b/src/eepp/ui/tools/uidiffview.cpp
@@ -14,10 +14,12 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
@@ -38,6 +40,8 @@ struct UIDiffView::PreparedPatch {
class UIDiffView::PreparedMultiFileDiff {
public:
std::vector patches;
+ size_t addedLines{ 0 };
+ size_t removedLines{ 0 };
};
static bool imagesHaveSameDimensions( const std::string& oldFilePath,
@@ -160,6 +164,201 @@ void UIDiffView::setMultiFileCollapsed( UIScrollView* multiDiff, bool collapsed
diff->setCollapsed( collapsed );
}
+UIMultiDiffView* UIMultiDiffView::New( const std::string& patchText, const std::string& repoPath,
+ UIDiffView::ViewMode viewMode,
+ bool interactiveFileHeaders ) {
+ return New( UIDiffView::prepareMultiFileDiff( patchText ), repoPath, viewMode,
+ interactiveFileHeaders );
+}
+
+UIMultiDiffView*
+UIMultiDiffView::New( std::shared_ptr preparedDiff,
+ const std::string& repoPath, UIDiffView::ViewMode viewMode,
+ bool interactiveFileHeaders ) {
+ if ( !preparedDiff )
+ return nullptr;
+ auto* view = eeNew( UIMultiDiffView, () );
+ view->load( std::move( preparedDiff ), repoPath, viewMode, interactiveFileHeaders );
+ return view;
+}
+
+UIMultiDiffView::UIMultiDiffView() : UILinearLayout( "multidiffview", UIOrientation::Vertical ) {
+ beginAttributesTransaction();
+
+ setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
+
+ mToolbar = UILinearLayout::NewHorizontal();
+ mToolbar->setParent( this );
+ mToolbar->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent );
+ mToolbar->setPadding( Rectf( 8, 4, 8, 4 ) );
+
+ mFilesToggle = UIPushButton::New();
+ mFilesToggle->setParent( mToolbar );
+ mFilesToggle->addClass( "git_commit_btn" );
+ mFilesToggle->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent );
+ mFilesToggle->onClick( [this]( const Event* ) { setCollapsed( !mCollapsed ); } );
+
+ mModeToggle = UIPushButton::New();
+ mModeToggle->setParent( mToolbar );
+ mModeToggle->addClass( "git_commit_btn" );
+ mModeToggle->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent );
+ mModeToggle->setLayoutMarginLeft( 4 );
+ mModeToggle->setTextAsFallback( true );
+ mModeToggle->onClick( [this]( const Event* ) {
+ setViewMode( mViewMode == UIDiffView::ViewMode::Unified ? UIDiffView::ViewMode::SideBySide
+ : UIDiffView::ViewMode::Unified );
+ } );
+
+ mFilesStatus = UITextView::New();
+ mFilesStatus->setParent( mToolbar );
+ mFilesStatus->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::WrapContent );
+ mFilesStatus->setLayoutWeight( 1 );
+ mFilesStatus->setLayoutMarginLeft( 8 );
+ mFilesStatus->setGravity( UI_VALIGN_CENTER );
+ mFilesStatus->setLayoutGravity( UI_VALIGN_CENTER );
+ mFilesStatus->setUsingCustomStyling( true );
+
+ mScrollView = UIScrollView::New();
+ mScrollView->setParent( this );
+ mScrollView->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::Fixed );
+ mScrollView->setLayoutWeight( 1 );
+
+ endAttributesTransaction();
+}
+
+void UIMultiDiffView::load( std::shared_ptr preparedDiff,
+ const std::string& repoPath, UIDiffView::ViewMode viewMode,
+ bool interactiveFileHeaders ) {
+ auto* uiSceneNode = SceneManager::instance()->getUISceneNode();
+ const bool wasLoading = uiSceneNode && uiSceneNode->isLoading();
+ if ( uiSceneNode )
+ uiSceneNode->setIsLoading( true );
+
+ mViewMode = viewMode;
+ mFileCount = preparedDiff->patches.size();
+ mAddedLines = preparedDiff->addedLines;
+ mRemovedLines = preparedDiff->removedLines;
+ auto* content = UILinearLayout::NewVertical();
+ content->setParent( mScrollView );
+ content->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent );
+ mDiffViews.reserve( preparedDiff->patches.size() );
+ for ( auto& patch : preparedDiff->patches ) {
+ auto* diffView = UIDiffView::New();
+ diffView->setViewMode( viewMode );
+ diffView->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent );
+ diffView->setParent( content );
+ diffView->setHeadersVisible( true );
+ diffView->setViewModeToggleVisible( false );
+ diffView->setCompleteViewToggleVisible( false );
+ diffView->setInteractiveFileHeader( interactiveFileHeaders );
+ diffView->loadPreparedPatch( std::move( patch ), "", "", repoPath );
+ mDiffViews.emplace_back( diffView );
+ }
+
+ updateFilesToggle();
+ updateModeToggle();
+ updateStatus();
+ if ( uiSceneNode ) {
+ uiSceneNode->setIsLoading( wasLoading );
+ if ( !wasLoading ) {
+ uiSceneNode->invalidateStyle( this, true );
+ uiSceneNode->invalidateStyleState( this, true, true );
+ }
+ }
+}
+
+void UIMultiDiffView::setViewMode( UIDiffView::ViewMode mode ) {
+ if ( mViewMode == mode )
+ return;
+ mViewMode = mode;
+ for ( auto* diff : mDiffViews )
+ diff->setViewMode( mode );
+ updateModeToggle();
+}
+
+void UIMultiDiffView::setCollapsed( bool collapsed ) {
+ if ( mCollapsed == collapsed )
+ return;
+ mCollapsed = collapsed;
+ for ( auto* diff : mDiffViews )
+ diff->setCollapsed( collapsed );
+ updateFilesToggle();
+}
+
+void UIMultiDiffView::setToolbarVisible( bool visible ) {
+ mToolbar->setVisible( visible );
+}
+
+bool UIMultiDiffView::isToolbarVisible() const {
+ return mToolbar->isVisible();
+}
+
+void UIMultiDiffView::updateFilesToggle() {
+ const String text = mCollapsed ? i18n( "git_expand_all_files", "Expand All Files" )
+ : i18n( "git_collapse_all_files", "Collapse All Files" );
+ mFilesToggle->setTooltipText( text );
+ if ( auto* scene = getUISceneNode() ) {
+ if ( auto* icon = scene->findIcon( mCollapsed ? "expand-all" : "collapse-all" ) )
+ mFilesToggle->setIcon( icon->createDrawable( PixelDensity::dpToPxI( 12 ) ) );
+ }
+ mFilesToggle->setText( mFilesToggle->hasIcon() ? String{} : text );
+}
+
+void UIMultiDiffView::updateModeToggle() {
+ const bool unified = mViewMode == UIDiffView::ViewMode::Unified;
+ mModeToggle->setText( unified ? i18n( "git_split_diff", "Split" )
+ : i18n( "git_unified_diff", "Unified" ) );
+ mModeToggle->setTooltipText(
+ unified ? i18n( "git_switch_to_split_diff", "Switch to split diff view" )
+ : i18n( "git_switch_to_unified_diff", "Switch to unified diff view" ) );
+ if ( auto* scene = getUISceneNode() ) {
+ if ( auto* icon = scene->findIcon( unified ? "split-horizontal" : "layout" ) )
+ mModeToggle->setIcon( icon->createDrawable( PixelDensity::dpToPxI( 12 ) ) );
+ }
+}
+
+void UIMultiDiffView::updateStatus() {
+ mFilesStatus->setText( String::format(
+ i18n( "git_changed_files_summary", "Changed files (%zu) +%zu -%zu" ).toUtf8(), mFileCount,
+ mAddedLines, mRemovedLines ) );
+ if ( auto* scene = getUISceneNode();
+ scene && scene->getRoot() && scene->getRoot()->getUIStyle() ) {
+ auto* root = scene->getRoot();
+ auto font = root->getUIStyle()->getVariable( "--font" );
+ auto warning = root->getUIStyle()->getVariable( "--theme-warning" );
+ auto success = root->getUIStyle()->getVariable( "--theme-success" );
+ auto error = root->getUIStyle()->getVariable( "--theme-error" );
+ std::vector patterns;
+ patterns.emplace_back( SyntaxPattern( { ".*%((%d+)%)%s+(%+%d+)%s+(%-%d+)" },
+ { "normal", "warning", "keyword", "type" } ) );
+ SyntaxDefinition definition( "multi_diff_files_status", {}, std::move( patterns ) );
+ SyntaxColorScheme scheme(
+ "multi_diff_files_status",
+ { { "normal"_sst,
+ { font.isEmpty() ? mFilesStatus->getFontColor()
+ : Color::fromString( font.getValue() ) } },
+ { "warning"_sst,
+ { warning.isEmpty() ? Color( 220, 170, 0 )
+ : Color::fromString( warning.getValue() ) } },
+ { "keyword"_sst,
+ { success.isEmpty() ? Color( 0, 180, 60 )
+ : Color::fromString( success.getValue() ) } },
+ { "type"_sst,
+ { error.isEmpty() ? Color( 220, 50, 70 )
+ : Color::fromString( error.getValue() ) } } },
+ {} );
+ SyntaxTokenizer::tokenizeText( definition, scheme, mFilesStatus->getTextCache() );
+ mFilesStatus->invalidateDraw();
+ }
+}
+
+void UIMultiDiffView::onThemeLoaded() {
+ UILinearLayout::onThemeLoaded();
+ updateFilesToggle();
+ updateModeToggle();
+ updateStatus();
+}
+
class UIDiffEditorPlugin : public UICodeEditorPlugin {
public:
UIDiffEditorPlugin( UIDiffView* view ) : mView( view ) {}
@@ -1410,8 +1609,12 @@ UIDiffView::prepareMultiFileDiff( const std::string& patchText,
for ( const auto& diff : diffs ) {
if ( cancelled && cancelled->load( std::memory_order_relaxed ) )
return {};
- prepared->patches.emplace_back(
- preparePatch( diff, "", SubLineDiffAlgorithm::LCS, cancelled ) );
+ auto patch = preparePatch( diff, "", SubLineDiffAlgorithm::LCS, cancelled );
+ for ( const auto& line : patch.lines ) {
+ prepared->addedLines += line.type == DiffLineType::Added;
+ prepared->removedLines += line.type == DiffLineType::Removed;
+ }
+ prepared->patches.emplace_back( std::move( patch ) );
}
if ( cancelled && cancelled->load( std::memory_order_relaxed ) )
diff --git a/src/tests/unit_tests/uidiffview_tests.cpp b/src/tests/unit_tests/uidiffview_tests.cpp
index e500b9022..4d4781efb 100644
--- a/src/tests/unit_tests/uidiffview_tests.cpp
+++ b/src/tests/unit_tests/uidiffview_tests.cpp
@@ -125,10 +125,13 @@ diff --git a/second.txt b/second.txt
+after
)patch";
- auto* viewer =
- UIDiffView::NewMultiFileDiffViewer( patchText, "", UIDiffView::ViewMode::SideBySide, true );
- auto diffViews = viewer->findAllByType( UI_TYPE_DIFF_VIEW );
+ auto* viewer = UIMultiDiffView::New( patchText, "", UIDiffView::ViewMode::SideBySide, true );
+ const auto& diffViews = viewer->getDiffViews();
ASSERT_EQ( size_t{ 2 }, diffViews.size() );
+ EXPECT_EQ( size_t{ 2 }, viewer->getFileCount() );
+ EXPECT_EQ( size_t{ 2 }, viewer->getAddedLines() );
+ EXPECT_EQ( size_t{ 2 }, viewer->getRemovedLines() );
+ EXPECT_TRUE( viewer->isToolbarVisible() );
for ( const auto* diffView : diffViews ) {
EXPECT_EQ( UIDiffView::ViewMode::SideBySide, diffView->getViewMode() );
EXPECT_FALSE( diffView->isViewModeToggleVisible() );
@@ -136,14 +139,16 @@ diff --git a/second.txt b/second.txt
EXPECT_TRUE( diffView->isInteractiveFileHeader() );
}
- UIDiffView::setMultiFileViewMode( viewer, UIDiffView::ViewMode::Unified );
- UIDiffView::setMultiFileCollapsed( viewer, true );
+ viewer->setViewMode( UIDiffView::ViewMode::Unified );
+ viewer->setCollapsed( true );
+ EXPECT_EQ( UIDiffView::ViewMode::Unified, viewer->getViewMode() );
+ EXPECT_TRUE( viewer->isCollapsed() );
for ( const auto* diffView : diffViews ) {
EXPECT_EQ( UIDiffView::ViewMode::Unified, diffView->getViewMode() );
EXPECT_TRUE( diffView->isCollapsed() );
EXPECT_TRUE( diffView->getViewLines().empty() );
}
- UIDiffView::setMultiFileCollapsed( viewer, false );
+ viewer->setCollapsed( false );
for ( const auto* diffView : diffViews ) {
EXPECT_FALSE( diffView->isCollapsed() );
EXPECT_FALSE( diffView->getViewLines().empty() );
@@ -202,8 +207,8 @@ UTEST( UIDiffView, MultiFileViewerHandlesLargePatches ) {
"\n+++ b/" + fileName + "\n@@ -1 +1 @@\n-old\n+new\n";
}
- auto* viewer = UIDiffView::NewMultiFileDiffViewer( patchText );
- EXPECT_EQ( fileCount, viewer->findAllByType( UI_TYPE_DIFF_VIEW ).size() );
+ auto* viewer = UIMultiDiffView::New( patchText );
+ EXPECT_EQ( fileCount, viewer->getDiffViews().size() );
EXPECT_TRUE( viewer->findAllByType( UI_TYPE_IMAGE_VIEWER ).empty() );
EXPECT_FALSE( viewer->getUISceneNode()->isLoading() );
diff --git a/src/tests/unit_tests/uiscenenode_tests.cpp b/src/tests/unit_tests/uiscenenode_tests.cpp
index 26b9ebfdc..b5d28f40a 100644
--- a/src/tests/unit_tests/uiscenenode_tests.cpp
+++ b/src/tests/unit_tests/uiscenenode_tests.cpp
@@ -140,7 +140,7 @@ UTEST( UIApplication, CreatesSecondaryWindowWithoutChangingAmbientScene ) {
secondaryUI->getWindow()->getInput()->beginInputFrame();
primaryWindow->getInput()->processEventForWindow( &textEvent );
secondaryUI->getWindow()->getInput()->endInputFrame();
- EXPECT_STREQ( textInput->getText().toUtf8().c_str(), "x" );
+ EXPECT_STDSTREQ( textInput->getText().toUtf8(), "x" );
}
EXPECT_EQ( SceneManager::instance()->getUISceneNode(), app.getUI() );
diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp
index 8a79ddb2e..393851c28 100644
--- a/src/tools/ecode/ecode.cpp
+++ b/src/tools/ecode/ecode.cpp
@@ -2663,21 +2663,16 @@ void App::loadDiffFromMemory( const std::string& content, const std::string& ori
if ( !icon )
icon = getUISceneNode()->findIcon( "file" );
- auto scrollView = UIDiffView::NewMultiFileDiffViewer(
- content, repoPath, mConfig.editor.diffViewMode, interactiveFileHeaders );
- auto [tab, iv] = getSplitter()->createWidget( scrollView, diffViewTitle );
+ auto multiDiff = UIMultiDiffView::New( content, repoPath, mConfig.editor.diffViewMode,
+ interactiveFileHeaders );
+ auto [tab, iv] = getSplitter()->createWidget( multiDiff, diffViewTitle );
if ( icon )
tab->setIcon( icon->createDrawable( getMenuIconSize() ) );
tab->setText( diffViewTitle );
- auto diffView = scrollView->getFirstChild()->asType()->getFirstChild();
-
- while ( diffView ) {
- if ( diffView->isType( UI_TYPE_DIFF_VIEW ) ) {
- configureDiffView( diffView->asType() );
- diffView->asType()->setSyntaxColorScheme( *getCurrentColorScheme() );
- }
- diffView = diffView->getNextNode();
+ for ( auto* diffView : multiDiff->getDiffViews() ) {
+ configureDiffView( diffView );
+ diffView->setSyntaxColorScheme( *getCurrentColorScheme() );
}
return;
}
@@ -2719,21 +2714,15 @@ void App::loadDiffFromPath( const std::string& path ) {
if ( !icon )
icon = getUISceneNode()->findIcon( "file" );
- auto scrollView =
- UIDiffView::NewMultiFileDiffViewer( content, "", mConfig.editor.diffViewMode );
- auto [tab, iv] = getSplitter()->createWidget( scrollView, diffViewTitle );
+ auto multiDiff = UIMultiDiffView::New( content, "", mConfig.editor.diffViewMode );
+ auto [tab, iv] = getSplitter()->createWidget( multiDiff, diffViewTitle );
if ( icon )
tab->setIcon( icon->createDrawable( getMenuIconSize() ) );
tab->setText( diffViewTitle );
- auto diffView = scrollView->getFirstChild()->asType()->getFirstChild();
-
- while ( diffView ) {
- if ( diffView->isType( UI_TYPE_DIFF_VIEW ) ) {
- configureDiffView( diffView->asType() );
- diffView->asType()->setSyntaxColorScheme( *getCurrentColorScheme() );
- }
- diffView = diffView->getNextNode();
+ for ( auto* diffView : multiDiff->getDiffViews() ) {
+ configureDiffView( diffView );
+ diffView->setSyntaxColorScheme( *getCurrentColorScheme() );
}
return;
}
diff --git a/src/tools/ecode/plugins/git/gitplugin.cpp b/src/tools/ecode/plugins/git/gitplugin.cpp
index 6bfb22c98..8e72b9b52 100644
--- a/src/tools/ecode/plugins/git/gitplugin.cpp
+++ b/src/tools/ecode/plugins/git/gitplugin.cpp
@@ -646,28 +646,6 @@ void GitPlugin::updateStatusBarSync() {
mStatusButton->invalidateDraw();
}
-void GitPlugin::styleCommitFilesStatus( UITextView* status ) {
- if ( !status )
- return;
- status->setUsingCustomStyling( true );
- if ( !mCommitStatusCustomTokenizer.has_value() ) {
- std::vector patterns;
- patterns.emplace_back( SyntaxPattern( { ".*%((%d+)%)%s+(%+%d+)%s+(%-%d+)" },
- { "normal", "warning", "keyword", "type" } ) );
- SyntaxDefinition syntaxDef( "git_commit_files_status", {}, std::move( patterns ) );
- SyntaxColorScheme scheme( "git_commit_files_status",
- { { "normal"_sst, { getVarColor( "--font" ) } },
- { "warning"_sst, { getVarColor( "--theme-warning" ) } },
- { "keyword"_sst, { getVarColor( "--theme-success" ) } },
- { "type"_sst, { getVarColor( "--theme-error" ) } } },
- {} );
- mCommitStatusCustomTokenizer = { std::move( syntaxDef ), std::move( scheme ) };
- }
- SyntaxTokenizer::tokenizeText( mCommitStatusCustomTokenizer->def,
- mCommitStatusCustomTokenizer->scheme, status->getTextCache() );
- status->invalidateDraw();
-}
-
void GitPlugin::updateStatus( bool force ) {
if ( !mGit || !mGitFound )
return;
@@ -843,9 +821,6 @@ PluginRequestHandle GitPlugin::processMessage( const PluginMessage& msg ) {
}
case ecode::PluginMessageType::UIThemeReloaded: {
mStatusCustomTokenizer.reset();
- mCommitStatusCustomTokenizer.reset();
- styleCommitFilesStatus( mCommitDetails.status );
- styleCommitFilesStatus( mDetachedHistory.details.status );
updateUINow( true );
break;
}
@@ -3060,19 +3035,8 @@ void GitPlugin::CommitDetailsState::openCommitDetails( GitPlugin& plugin, const
-
-
-
-
-
+
)xml" );
@@ -3086,8 +3050,6 @@ void GitPlugin::CommitDetailsState::openCommitDetails( GitPlugin& plugin, const
view->bind( "git_commit_message", message );
view->bind( "git_commit_files_status", status );
view->bind( "git_commit_message_toggle", messageToggle );
- view->bind( "git_commit_files_toggle", filesToggle );
- view->bind( "git_commit_mode_toggle", modeToggle );
view->bind( "git_commit_github", gitHub );
view->bind( "git_commit_diff", diffContainer );
messageToggle->onClick( [owner, state]( const Event* ) {
@@ -3099,34 +3061,6 @@ void GitPlugin::CommitDetailsState::openCommitDetails( GitPlugin& plugin, const
"Collapse Commit Description" )
: owner->i18n( "git_expand_commit_description", "Expand Commit Description" ) );
} );
- filesToggle->onClick( [owner, state]( const Event* ) {
- state->filesCollapsed = !state->filesCollapsed;
- UIDiffView::setMultiFileCollapsed( state->diff, state->filesCollapsed );
- state->filesToggle->setTooltipText(
- state->filesCollapsed
- ? owner->i18n( "git_expand_all_files", "Expand All Files" )
- : owner->i18n( "git_collapse_all_files", "Collapse All Files" ) );
- if ( auto* icon =
- owner->findIcon( state->filesCollapsed ? "expand-all" : "collapse-all" ) )
- state->filesToggle->setIcon( icon->createDrawable( PixelDensity::dpToPxI( 12 ) ) );
- } );
- modeToggle->onClick( [owner, state]( const Event* ) {
- state->viewMode = state->viewMode == UIDiffView::ViewMode::Unified
- ? UIDiffView::ViewMode::SideBySide
- : UIDiffView::ViewMode::Unified;
- UIDiffView::setMultiFileViewMode( state->diff, state->viewMode );
- state->modeToggle->setText( state->viewMode == UIDiffView::ViewMode::Unified
- ? owner->i18n( "git_split_diff", "Split" )
- : owner->i18n( "git_unified_diff", "Unified" ) );
- state->modeToggle->setTooltipText(
- state->viewMode == UIDiffView::ViewMode::Unified
- ? owner->i18n( "git_switch_to_split_diff", "Switch to split diff view" )
- : owner->i18n( "git_switch_to_unified_diff", "Switch to unified diff view" ) );
- if ( auto* icon = owner->findIcon( state->viewMode == UIDiffView::ViewMode::Unified
- ? "split-horizontal"
- : "layout" ) )
- state->modeToggle->setIcon( icon->createDrawable( PixelDensity::dpToPxI( 12 ) ) );
- } );
gitHub->onClick( [state]( const Event* ) {
if ( !state->url.empty() )
Engine::instance()->openURI( state->url );
@@ -3158,11 +3092,7 @@ void GitPlugin::CommitDetailsState::openCommitDetails( GitPlugin& plugin, const
message->setVisible( false );
messageToggle->setVisible( false );
status->setText( plugin.i18n( "git_loading_changed_files", "Loading changed files..." ) );
- plugin.styleCommitFilesStatus( status );
- filesCollapsed = false;
- filesToggle->setTooltipText( plugin.i18n( "git_collapse_all_files", "Collapse All Files" ) );
- if ( auto* icon = plugin.findIcon( "collapse-all" ) )
- filesToggle->setIcon( icon->createDrawable( PixelDensity::dpToPxI( 12 ) ) );
+ status->setVisible( true );
url.clear();
gitHub->setVisible( false );
view->find( "git_commit_sha" )->setVisible( !isWorkingTree );
@@ -3233,7 +3163,6 @@ void GitPlugin::CommitDetailsState::loadCommitFiles( GitPlugin& plugin, bool det
details.status->setText(
plugin->i18n( "git_changed_files_error", "Could not load changed files" ) +
( result.result.empty() ? "" : ": " + result.result ) );
- plugin->styleCommitFilesStatus( details.status );
return;
}
std::string message = std::move( result.message );
@@ -3258,42 +3187,28 @@ void GitPlugin::CommitDetailsState::loadCommitFiles( GitPlugin& plugin, bool det
details.messageToggle->setText(
plugin->i18n( "git_expand_commit_description", "Expand Commit Description" ) );
- int totalInserts = 0;
- int totalDeletes = 0;
- for ( const auto& file : result.files ) {
- totalInserts += file.inserts;
- totalDeletes += file.deletes;
- }
if ( result.files.empty() ) {
details.status->setText(
plugin->i18n( "git_no_changed_files", "No changed files" ) );
} else {
- details.status->setText( String::format(
- plugin->i18n( "git_changed_files_summary", "Changed files (%zu) +%d -%d" )
- .toUtf8(),
- result.files.size(), totalInserts, totalDeletes ) );
+ details.status->setVisible( false );
}
- plugin->styleCommitFilesStatus( details.status );
details.url = std::move( result.commitURL );
details.gitHub->setVisible( !details.url.empty() );
details.diffContainer->closeAllChildren();
details.diff = nullptr;
if ( preparedDiff ) {
- details.diff = UIDiffView::NewMultiFileDiffViewer( std::move( preparedDiff ), repo,
- details.viewMode );
+ details.diff = UIMultiDiffView::New( std::move( preparedDiff ), repo,
+ UIDiffView::ViewMode::Unified, true );
details.diff->setLayoutSizePolicy( SizePolicy::MatchParent,
SizePolicy::MatchParent );
details.diff->setParent( details.diffContainer );
- for ( auto* diff : UIDiffView::multiFileDiffViews( details.diff ) ) {
- diff->setInteractiveFileHeader( true );
+ for ( auto* diff : details.diff->getDiffViews() ) {
if ( const auto* scheme = plugin->getPluginContext()->getCurrentColorScheme() )
diff->setSyntaxColorScheme( *scheme );
}
}
- const bool hasDiff = details.diff != nullptr;
- details.filesToggle->setVisible( hasDiff );
- details.modeToggle->setVisible( hasDiff );
} );
} );
}
@@ -3496,6 +3411,16 @@ void GitPlugin::buildSidePanelTab() {
#git_commit_details .git_commit_btn:hover {
border-color: var(--primary);
}
+ multidiffview .git_commit_btn {
+ lw: 20dp;
+ lh: 20dp;
+ padding: 0;
+ background-color: var(--list-back);
+ border-color: transparent;
+ }
+ multidiffview .git_commit_btn:hover {
+ border-color: var(--primary);
+ }
#git_commit_details #git_commit_author {
font-size: 11dp;
text-stroke-width: 1dp;
diff --git a/src/tools/ecode/plugins/git/gitplugin.hpp b/src/tools/ecode/plugins/git/gitplugin.hpp
index 078880554..69a8c22cb 100644
--- a/src/tools/ecode/plugins/git/gitplugin.hpp
+++ b/src/tools/ecode/plugins/git/gitplugin.hpp
@@ -178,11 +178,9 @@ class GitPlugin : public PluginBase {
UITextView* message{ nullptr };
UITextView* status{ nullptr };
UIPushButton* messageToggle{ nullptr };
- UIPushButton* filesToggle{ nullptr };
- UIPushButton* modeToggle{ nullptr };
UIPushButton* gitHub{ nullptr };
UIWidget* diffContainer{ nullptr };
- UIScrollView* diff{ nullptr };
+ Tools::UIMultiDiffView* diff{ nullptr };
std::string messageBody;
std::string url;
Git::Commit commit;
@@ -190,9 +188,7 @@ class GitPlugin : public PluginBase {
std::atomic generation{ 0 };
std::shared_ptr diffPreparationCancelled;
EventConnection closeConnection;
- Tools::UIDiffView::ViewMode viewMode{ Tools::UIDiffView::ViewMode::Unified };
bool messageExpanded{ false };
- bool filesCollapsed{ false };
bool workingTree{ false };
void openCommitDetails( GitPlugin& plugin, const Git::Commit& commit, bool detached,
@@ -216,8 +212,6 @@ class GitPlugin : public PluginBase {
message = nullptr;
status = nullptr;
messageToggle = nullptr;
- filesToggle = nullptr;
- modeToggle = nullptr;
gitHub = nullptr;
diffContainer = nullptr;
diff = nullptr;
@@ -225,9 +219,7 @@ class GitPlugin : public PluginBase {
url.clear();
commit = {};
repo.clear();
- viewMode = Tools::UIDiffView::ViewMode::Unified;
messageExpanded = false;
- filesCollapsed = false;
workingTree = false;
}
};
@@ -278,7 +270,6 @@ class GitPlugin : public PluginBase {
SyntaxColorScheme scheme;
};
std::optional mStatusCustomTokenizer;
- std::optional mCommitStatusCustomTokenizer;
std::optional mTooltipCustomSyntaxDef;
Uint32 mModelChangedId{ 0 };
Uint32 mModelStylerId{ 0 };
@@ -365,8 +356,6 @@ class GitPlugin : public PluginBase {
void updateStatusBarSync();
- void styleCommitFilesStatus( UITextView* status );
-
void updateUI();
void updateUINow( bool force = false );