mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-31 18:46:29 +03:00
Added multi-file diff / patch visualization support.
This commit is contained in:
@@ -1231,10 +1231,15 @@ TextInput.table_cell_edit {
|
||||
|
||||
DiffView > SelectButton {
|
||||
border-color: transparent;
|
||||
padding: 2dp 4dp 2dp 4dp;
|
||||
padding: 0dp 4dp 0dp 4dp;
|
||||
font-size: 10dp;
|
||||
}
|
||||
|
||||
DiffView > SelectButton:hover,
|
||||
DiffView > SelectButton:focus {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
|
||||
:root {
|
||||
|
||||
@@ -1040,7 +1040,7 @@ class EE_API String {
|
||||
|
||||
static bool isLatin1( String::View str );
|
||||
|
||||
Uint32 getTextHints();
|
||||
Uint32 getTextHints() const;
|
||||
|
||||
static Uint32 getTextHints( String::View str );
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
#include <eepp/ui/uilinearlayout.hpp>
|
||||
#include <eepp/ui/uiselectbutton.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace Tools {
|
||||
namespace EE { namespace UI {
|
||||
|
||||
class UIScrollView;
|
||||
|
||||
namespace Tools {
|
||||
|
||||
class UIDiffEditorPlugin;
|
||||
|
||||
@@ -16,6 +20,12 @@ class EE_API UIDiffView : public UIWidget {
|
||||
|
||||
static UIDiffView* New();
|
||||
|
||||
static UIScrollView* NewMultiFileDiffViewer( const std::string& patchText );
|
||||
|
||||
static std::vector<std::string> splitDiff( const std::string& multiFileDiff );
|
||||
|
||||
static bool isMultiFileDiff( const std::string& diff );
|
||||
|
||||
virtual ~UIDiffView();
|
||||
|
||||
virtual Uint32 getType() const override;
|
||||
@@ -56,6 +66,14 @@ class EE_API UIDiffView : public UIWidget {
|
||||
void setSubLineDiffAlgorithm( SubLineDiffAlgorithm algo );
|
||||
SubLineDiffAlgorithm getSubLineDiffAlgorithm() const { return mSubLineDiffAlgorithm; }
|
||||
|
||||
void setSyntaxColorScheme( const SyntaxColorScheme& colorScheme );
|
||||
|
||||
void setHeadersVisible( bool visible );
|
||||
|
||||
bool areHeadersVisible() const { return mHeadersVisible; }
|
||||
|
||||
const String& getFileName() const { return mFileName; }
|
||||
|
||||
protected:
|
||||
UICodeEditor* mEditor{ nullptr };
|
||||
UICodeEditor* mLeftEditor{ nullptr };
|
||||
@@ -72,10 +90,16 @@ class EE_API UIDiffView : public UIWidget {
|
||||
bool mViewModeToggleVisible{ true };
|
||||
bool mShowCompleteView{ false };
|
||||
bool mCompleteViewToggleVisible{ true };
|
||||
bool mHeadersVisible{ false };
|
||||
std::shared_ptr<SyntaxDefinition> mSyntaxDef;
|
||||
String mFileName;
|
||||
|
||||
UIDiffView();
|
||||
|
||||
virtual void onSizePolicyChange() override;
|
||||
|
||||
virtual void onAutoSize() override;
|
||||
|
||||
virtual void onSizeChange() override;
|
||||
|
||||
void createEditor( UICodeEditor*& editor, std::unique_ptr<UIDiffEditorPlugin>& plugin );
|
||||
|
||||
@@ -1140,6 +1140,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
|
||||
|
||||
bool gutterSpaceExists( UICodeEditorPlugin* plugin ) const;
|
||||
|
||||
Float getTotalTopSpace() const;
|
||||
|
||||
bool topSpaceExists( UICodeEditorPlugin* plugin ) const;
|
||||
|
||||
bool createContextMenu();
|
||||
|
||||
@@ -1480,7 +1480,7 @@ bool String::isLatin1( String::View str ) {
|
||||
return isAsciiTpl<String::View, 255>( str );
|
||||
}
|
||||
|
||||
Uint32 String::getTextHints() {
|
||||
Uint32 String::getTextHints() const {
|
||||
if ( isAscii() )
|
||||
return TextHints::AllAscii | TextHints::AllLatin1;
|
||||
if ( isLatin1() )
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/ui/tools/uicodeeditorsplitter.hpp>
|
||||
#include <eepp/ui/tools/uidiffview.hpp>
|
||||
#include <eepp/ui/uimessagebox.hpp>
|
||||
#include <eepp/window/displaymanager.hpp>
|
||||
#include <eepp/window/engine.hpp>
|
||||
@@ -812,7 +813,10 @@ UICodeEditor* UICodeEditorSplitter::findEditorFromPath( const std::string& path
|
||||
|
||||
void UICodeEditorSplitter::applyColorScheme( const SyntaxColorScheme& colorScheme ) {
|
||||
forEachEditor(
|
||||
[colorScheme]( UICodeEditor* editor ) { editor->setColorScheme( colorScheme ); } );
|
||||
[&colorScheme]( UICodeEditor* editor ) { editor->setColorScheme( colorScheme ); } );
|
||||
forEachWidgetType( UI_TYPE_DIFF_VIEW, [&colorScheme]( UIWidget* widget ) {
|
||||
widget->asType<UIDiffView>()->setSyntaxColorScheme( colorScheme );
|
||||
} );
|
||||
mClient->onColorSchemeChanged( mCurrentColorScheme );
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,32 @@
|
||||
#include <eepp/ui/tools/uidiffview.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <eepp/ui/uiscrollbar.hpp>
|
||||
#include <eepp/ui/uiscrollview.hpp>
|
||||
#include <eepp/ui/uithememanager.hpp>
|
||||
|
||||
#include <dtl/dtl.hpp>
|
||||
|
||||
namespace EE { namespace UI { namespace Tools {
|
||||
|
||||
UIScrollView* UIDiffView::NewMultiFileDiffViewer( const std::string& patchText ) {
|
||||
auto scrollView = UIScrollView::New();
|
||||
auto vbox = UILinearLayout::NewVertical();
|
||||
vbox->setParent( scrollView );
|
||||
vbox->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent );
|
||||
|
||||
auto diffs = UIDiffView::splitDiff( patchText );
|
||||
|
||||
for ( const auto& diff : diffs ) {
|
||||
auto* diffView = UIDiffView::New();
|
||||
diffView->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent );
|
||||
diffView->setParent( vbox );
|
||||
diffView->setHeadersVisible( true );
|
||||
diffView->loadFromPatch( diff );
|
||||
}
|
||||
|
||||
return scrollView;
|
||||
}
|
||||
|
||||
class UIDiffEditorPlugin : public UICodeEditorPlugin {
|
||||
public:
|
||||
UIDiffEditorPlugin( UIDiffView* view ) : mView( view ) {}
|
||||
@@ -45,16 +66,56 @@ class UIDiffEditorPlugin : public UICodeEditorPlugin {
|
||||
Float glyphWidth = editor->getGlyphWidth();
|
||||
Float totalChars = mView->getViewMode() == UIDiffView::ViewMode::Unified ? 10 : 5;
|
||||
mGutterWidth = PixelDensity::dpToPx( glyphWidth * totalChars );
|
||||
mPluginTopSpace = PixelDensity::dpToPxI( 20 );
|
||||
editor->registerGutterSpace( this, mGutterWidth, 0 );
|
||||
|
||||
if ( mView->areHeadersVisible() ) {
|
||||
editor->registerTopSpace( this, mPluginTopSpace, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void onUnregister( UICodeEditor* editor ) override { editor->unregisterGutterSpace( this ); }
|
||||
Float getPluginTopSpace() const { return mPluginTopSpace; }
|
||||
|
||||
void onUnregister( UICodeEditor* editor ) override {
|
||||
editor->unregisterGutterSpace( this );
|
||||
editor->unregisterTopSpace( this );
|
||||
}
|
||||
|
||||
void registerUpdate( UICodeEditor* editor ) {
|
||||
onUnregister( editor );
|
||||
onRegister( editor );
|
||||
}
|
||||
|
||||
void drawTop( UICodeEditor* editor, const Vector2f& screenStart, const Sizef& size,
|
||||
const Float& /*fontSize*/ ) override {
|
||||
Float width = editor->getTopAreaWidth();
|
||||
Primitives p;
|
||||
Color backColor( editor->getColorScheme().getEditorColor( SyntaxStyleTypes::Background ) );
|
||||
p.setColor( backColor );
|
||||
p.drawRectangle( Rectf( screenStart, Sizef( width, mPluginTopSpace ) ) );
|
||||
|
||||
Color lineColor(
|
||||
editor->getColorScheme().getEditorColor( SyntaxStyleTypes::LineBreakColumn ) );
|
||||
p.setColor( lineColor );
|
||||
Float lineHeight = eefloor( PixelDensity::dpToPxI( 1 ) );
|
||||
p.drawRectangle( { { screenStart.x, screenStart.y + size.getHeight() - lineHeight },
|
||||
Sizef( width, lineHeight ) } );
|
||||
|
||||
Font* font = mView->getUISceneNode()->getUIThemeManager()->getDefaultFont();
|
||||
if ( !font || mView->getFileName().empty() )
|
||||
return;
|
||||
|
||||
Float fontSize = editor->getUISceneNode()->getUIThemeManager()->getDefaultFontSize();
|
||||
Float textOffsetY =
|
||||
eefloor( ( size.getHeight() - font->getLineSpacing( fontSize ) ) * 0.5f );
|
||||
Color textColor( editor->getColorScheme().getEditorColor( SyntaxStyleTypes::LineNumber2 ) );
|
||||
Vector2f pos( screenStart.x + eefloor( PixelDensity::dpToPx( 8 ) ),
|
||||
screenStart.y + textOffsetY );
|
||||
|
||||
Text::draw( mView->getFileName(), pos, font, fontSize, textColor, 0, 0.f, Color::Black,
|
||||
Color::Black, { 1, 1 }, 4, mView->getFileName().getTextHints() );
|
||||
}
|
||||
|
||||
void drawBeforeLineText( UICodeEditor* editor, const Int64& index, Vector2f position,
|
||||
const Float& /*fontSize*/, const Float& lineHeight ) override {
|
||||
const auto& viewLines = mView->getViewLines();
|
||||
@@ -177,12 +238,62 @@ class UIDiffEditorPlugin : public UICodeEditorPlugin {
|
||||
protected:
|
||||
UIDiffView* mView;
|
||||
Float mGutterWidth{ 0 };
|
||||
Float mPluginTopSpace{ 0 };
|
||||
};
|
||||
|
||||
UIDiffView* UIDiffView::New() {
|
||||
return eeNew( UIDiffView, () );
|
||||
}
|
||||
|
||||
bool UIDiffView::isMultiFileDiff( const std::string& diff ) {
|
||||
size_t startPos = 0;
|
||||
if ( diff.substr( 0, 5 ) != "diff " ) {
|
||||
size_t firstDiff = diff.find( "\ndiff " );
|
||||
if ( firstDiff != std::string::npos ) {
|
||||
startPos = firstDiff + 1; // Skip the preamble and the newline
|
||||
}
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
while ( startPos < diff.size() && count < 2 ) {
|
||||
size_t nextPos = diff.find( "\ndiff ", startPos );
|
||||
if ( nextPos == std::string::npos ) {
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
startPos = nextPos + 1;
|
||||
}
|
||||
return count >= 2;
|
||||
}
|
||||
|
||||
std::vector<std::string> UIDiffView::splitDiff( const std::string& multiFileDiff ) {
|
||||
std::vector<std::string> diffs;
|
||||
if ( multiFileDiff.empty() )
|
||||
return diffs;
|
||||
|
||||
size_t startPos = 0;
|
||||
// Skip any preamble (e.g. commit message from git show)
|
||||
if ( multiFileDiff.substr( 0, 5 ) != "diff " ) {
|
||||
size_t firstDiff = multiFileDiff.find( "\ndiff " );
|
||||
if ( firstDiff != std::string::npos ) {
|
||||
startPos = firstDiff + 1; // Skip the preamble and the newline
|
||||
}
|
||||
}
|
||||
|
||||
while ( startPos < multiFileDiff.size() ) {
|
||||
size_t nextPos = multiFileDiff.find( "\ndiff ", startPos );
|
||||
if ( nextPos == std::string::npos ) {
|
||||
diffs.push_back( multiFileDiff.substr( startPos ) );
|
||||
break;
|
||||
}
|
||||
diffs.push_back( multiFileDiff.substr( startPos, nextPos + 1 - startPos ) );
|
||||
startPos = nextPos + 1;
|
||||
}
|
||||
|
||||
return diffs;
|
||||
}
|
||||
|
||||
UIDiffView::UIDiffView() : UIWidget( "diffview" ) {
|
||||
setFlags( UI_AUTO_SIZE );
|
||||
createEditor( mEditor, mPlugin );
|
||||
@@ -328,33 +439,65 @@ void UIDiffView::syncScroll( UICodeEditor* source, UICodeEditor* target, bool em
|
||||
|
||||
void UIDiffView::updateModeButton() {
|
||||
auto margin = PixelDensity::dpToPx( 4 );
|
||||
Float emptySpace =
|
||||
mPlugin->getPluginTopSpace() - std::max( mModeToggle->getPixelsSize().getHeight(),
|
||||
mCompleteViewToggle->getPixelsSize().getHeight() );
|
||||
auto vmargin = mHeadersVisible ? emptySpace * 0.5f : margin;
|
||||
|
||||
Float currentX = getPixelsSize().getWidth() - margin;
|
||||
currentX -= mRightEditor->getVScrollBar()->getPixelsSize().getWidth();
|
||||
|
||||
if ( mViewModeToggleVisible && mModeToggle ) {
|
||||
currentX -= mModeToggle->getPixelsSize().getWidth();
|
||||
mModeToggle->setPixelsPosition( currentX, margin );
|
||||
mModeToggle->setPixelsPosition( currentX, vmargin );
|
||||
currentX -= margin;
|
||||
}
|
||||
|
||||
if ( mCompleteViewToggleVisible && mCompleteViewToggle ) {
|
||||
currentX -= mCompleteViewToggle->getPixelsSize().getWidth();
|
||||
mCompleteViewToggle->setPixelsPosition( currentX, margin );
|
||||
mCompleteViewToggle->setPixelsPosition( currentX, vmargin );
|
||||
}
|
||||
}
|
||||
|
||||
void UIDiffView::onSizePolicyChange() {
|
||||
if ( mHeightPolicy == SizePolicy::WrapContent && mEditor && mLeftEditor ) {
|
||||
mEditor->setLayoutHeightPolicy( mHeightPolicy );
|
||||
mLeftEditor->setLayoutHeightPolicy( mHeightPolicy );
|
||||
mRightEditor->setLayoutHeightPolicy( mHeightPolicy );
|
||||
onAutoSize();
|
||||
}
|
||||
}
|
||||
|
||||
void UIDiffView::onAutoSize() {
|
||||
if ( mHeightPolicy == SizePolicy::WrapContent && mEditor && mLeftEditor ) {
|
||||
setPixelsSize( getPixelsSize().getWidth(), mViewMode == ViewMode::Unified
|
||||
? mEditor->getPixelsSize().getHeight()
|
||||
: mLeftEditor->getPixelsSize().getHeight() );
|
||||
}
|
||||
}
|
||||
|
||||
void UIDiffView::onSizeChange() {
|
||||
if ( mViewMode == ViewMode::Unified ) {
|
||||
mEditor->setPixelsSize( getPixelsSize() );
|
||||
mEditor->setPixelsSize(
|
||||
{ getPixelsSize().getWidth(), mHeightPolicy == SizePolicy::WrapContent
|
||||
? mEditor->getPixelsSize().getHeight()
|
||||
: getPixelsSize().getHeight() } );
|
||||
} else {
|
||||
mLeftEditor->setPixelsSize( std::ceil( getPixelsSize().getWidth() * 0.5f ),
|
||||
getPixelsSize().getHeight() );
|
||||
mHeightPolicy == SizePolicy::WrapContent
|
||||
? mLeftEditor->getPixelsSize().getHeight()
|
||||
: getPixelsSize().getHeight() );
|
||||
|
||||
mRightEditor->setPixelsSize( std::floor( getPixelsSize().getWidth() * 0.5f ),
|
||||
getPixelsSize().getHeight() );
|
||||
mHeightPolicy == SizePolicy::WrapContent
|
||||
? mRightEditor->getPixelsSize().getHeight()
|
||||
: getPixelsSize().getHeight() );
|
||||
|
||||
mRightEditor->setPixelsPosition( std::floor( getPixelsSize().getWidth() * 0.5f ), 0.f );
|
||||
}
|
||||
|
||||
onAutoSize();
|
||||
|
||||
updateModeButton();
|
||||
}
|
||||
|
||||
@@ -639,10 +782,12 @@ void UIDiffView::loadFromPatch( const std::string& patchText,
|
||||
auto def = SyntaxDefinitionManager::instance()->getByExtension( filename );
|
||||
mSyntaxDef =
|
||||
SyntaxDefinitionManager::instance()->getLanguageDefinition( def.getLanguageIndex() );
|
||||
mFileName = std::move( filename );
|
||||
}
|
||||
|
||||
updateEditorsText();
|
||||
updateButtonsText();
|
||||
onSizeChange();
|
||||
}
|
||||
|
||||
void UIDiffView::loadFromStrings( const std::string& oldText, const std::string& newText ) {
|
||||
@@ -686,6 +831,7 @@ void UIDiffView::loadFromStrings( const std::string& oldText, const std::string&
|
||||
mShowCompleteView = false;
|
||||
mCompleteViewToggle->setText( i18n( "diffview_complete", "Complete" ) );
|
||||
updateEditorsText();
|
||||
onSizeChange();
|
||||
}
|
||||
|
||||
void UIDiffView::loadFromFile( const std::string& oldFilePath, const std::string& newFilePath ) {
|
||||
@@ -699,6 +845,7 @@ void UIDiffView::loadFromFile( const std::string& oldFilePath, const std::string
|
||||
mEditor->getDocument().setSyntaxDefinition( def );
|
||||
mLeftEditor->getDocument().setSyntaxDefinition( def );
|
||||
mRightEditor->getDocument().setSyntaxDefinition( def );
|
||||
mFileName = FileSystem::fileNameFromPath( newFilePath );
|
||||
|
||||
loadFromStrings( oldText, newText );
|
||||
}
|
||||
@@ -710,4 +857,20 @@ void UIDiffView::updateButtonsText() {
|
||||
mCompleteViewToggle->setSelected( !mShowCompleteView );
|
||||
}
|
||||
|
||||
void UIDiffView::setSyntaxColorScheme( const SyntaxColorScheme& colorScheme ) {
|
||||
mEditor->setColorScheme( colorScheme );
|
||||
mLeftEditor->setColorScheme( colorScheme );
|
||||
mRightEditor->setColorScheme( colorScheme );
|
||||
}
|
||||
|
||||
void UIDiffView::setHeadersVisible( bool visible ) {
|
||||
if ( visible == mHeadersVisible )
|
||||
return;
|
||||
mHeadersVisible = visible;
|
||||
mPlugin->registerUpdate( mEditor );
|
||||
mLeftPlugin->registerUpdate( mLeftEditor );
|
||||
mRightPlugin->registerUpdate( mRightEditor );
|
||||
updateModeButton();
|
||||
}
|
||||
|
||||
}}} // namespace EE::UI::Tools
|
||||
|
||||
@@ -2040,6 +2040,7 @@ void UICodeEditor::drawCursor( const Vector2f& startScroll, const Float& lineHei
|
||||
}
|
||||
|
||||
void UICodeEditor::onSizeChange() {
|
||||
onAutoSize();
|
||||
invalidateEditor( false );
|
||||
invalidateLineWrapMaxWidth( false );
|
||||
if ( !mDocView.isWrapEnabled() )
|
||||
@@ -3352,6 +3353,16 @@ Float UICodeEditor::getPluginsGutterSpace() const {
|
||||
return mPluginsGutterSpace;
|
||||
}
|
||||
|
||||
Float UICodeEditor::getTotalTopSpace() const {
|
||||
Float space = 0.f;
|
||||
if ( mPluginsTopSpace > 0 ) {
|
||||
for ( auto& plugin : mPluginTopSpaces ) {
|
||||
space += plugin.space;
|
||||
}
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
||||
bool UICodeEditor::topSpaceExists( UICodeEditorPlugin* plugin ) const {
|
||||
for ( const auto& space : mPluginTopSpaces ) {
|
||||
if ( space.plugin == plugin )
|
||||
@@ -5574,8 +5585,8 @@ void UICodeEditor::onAutoSize() {
|
||||
if ( mHeightPolicy == SizePolicy::WrapContent ) {
|
||||
auto visibleLineCount = getDocumentView().getVisibleLinesCount();
|
||||
Float lineHeight = getLineHeight();
|
||||
Float height =
|
||||
lineHeight * visibleLineCount + getPixelsPadding().Top + getPixelsPadding().Bottom;
|
||||
Float height = lineHeight * visibleLineCount + getPixelsPadding().Top +
|
||||
getPixelsPadding().Bottom + getTotalTopSpace();
|
||||
setPixelsSize( getPixelsSize().getWidth(), height );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2608,6 +2608,28 @@ void App::loadAudioFromPath( const std::string& path, bool autoPlay ) {
|
||||
}
|
||||
|
||||
void App::loadDiffFromMemory( const std::string& content, const std::string& originalFilePath ) {
|
||||
if ( UIDiffView::isMultiFileDiff( content ) ) {
|
||||
auto diffViewTitle = i18n( "diff_viewer", "Diff Viewer" ) + ": " + originalFilePath;
|
||||
UIIcon* icon = getUISceneNode()->findIcon( "filetype-diff" );
|
||||
if ( !icon )
|
||||
icon = getUISceneNode()->findIcon( "file" );
|
||||
|
||||
auto scrollView = UIDiffView::NewMultiFileDiffViewer( content );
|
||||
auto [tab, iv] = getSplitter()->createWidget( scrollView, diffViewTitle );
|
||||
if ( icon )
|
||||
tab->setIcon( icon->getSize( getMenuIconSize() ) );
|
||||
tab->setText( diffViewTitle );
|
||||
|
||||
auto diffView = scrollView->getFirstChild()->asType<UILinearLayout>()->getFirstChild();
|
||||
|
||||
while ( diffView ) {
|
||||
if ( diffView->isType( UI_TYPE_DIFF_VIEW ) )
|
||||
diffView->asType<UIDiffView>()->setSyntaxColorScheme( *getCurrentColorScheme() );
|
||||
diffView = diffView->getNextNode();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto diffViewTitle = i18n( "diff_viewer", "Diff Viewer" );
|
||||
auto* diffView = Tools::UIDiffView::New();
|
||||
auto [tab, iv] = getSplitter()->createWidget( diffView, diffViewTitle );
|
||||
@@ -2623,10 +2645,39 @@ void App::loadDiffFromMemory( const std::string& content, const std::string& ori
|
||||
icon = getUISceneNode()->findIcon( "file" );
|
||||
if ( icon )
|
||||
tab->setIcon( icon->getSize( getMenuIconSize() ) );
|
||||
diffView->setHeadersVisible( true );
|
||||
diffView->loadFromPatch( content, originalFilePath );
|
||||
diffView->setSyntaxColorScheme( *getCurrentColorScheme() );
|
||||
}
|
||||
|
||||
void App::loadDiffFromPath( const std::string& path ) {
|
||||
std::string content;
|
||||
if ( !FileSystem::fileGet( path, content ) )
|
||||
return;
|
||||
|
||||
if ( UIDiffView::isMultiFileDiff( content ) ) {
|
||||
auto diffViewTitle =
|
||||
i18n( "diff_viewer", "Diff Viewer" ) + ": " + FileSystem::fileNameFromPath( path );
|
||||
UIIcon* icon = getUISceneNode()->findIcon( "filetype-diff" );
|
||||
if ( !icon )
|
||||
icon = getUISceneNode()->findIcon( "file" );
|
||||
|
||||
auto scrollView = UIDiffView::NewMultiFileDiffViewer( content );
|
||||
auto [tab, iv] = getSplitter()->createWidget( scrollView, diffViewTitle );
|
||||
if ( icon )
|
||||
tab->setIcon( icon->getSize( getMenuIconSize() ) );
|
||||
tab->setText( diffViewTitle );
|
||||
|
||||
auto diffView = scrollView->getFirstChild()->asType<UILinearLayout>()->getFirstChild();
|
||||
|
||||
while ( diffView ) {
|
||||
if ( diffView->isType( UI_TYPE_DIFF_VIEW ) )
|
||||
diffView->asType<UIDiffView>()->setSyntaxColorScheme( *getCurrentColorScheme() );
|
||||
diffView = diffView->getNextNode();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto diffViewTitle = i18n( "diff_viewer", "Diff Viewer" );
|
||||
auto* diffView = Tools::UIDiffView::New();
|
||||
auto [tab, iv] = mSplitter->createWidget( diffView, i18n( "diff_viewer", "Diff Viewer" ) );
|
||||
@@ -2639,9 +2690,10 @@ void App::loadDiffFromPath( const std::string& path ) {
|
||||
}
|
||||
auto icon = findIcon( "filetype-diff" );
|
||||
tab->setIcon( icon ? icon : findIcon( "file" ) );
|
||||
std::string text;
|
||||
if ( FileSystem::fileGet( path, text ) )
|
||||
diffView->loadFromPatch( text, path );
|
||||
|
||||
diffView->setHeadersVisible( true );
|
||||
diffView->loadFromPatch( content, path );
|
||||
diffView->setSyntaxColorScheme( *getCurrentColorScheme() );
|
||||
}
|
||||
|
||||
void App::openFileFromPath( const std::string& path ) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <eepp/ui/uiloader.hpp>
|
||||
#include <eepp/ui/uipopupmenu.hpp>
|
||||
#include <eepp/ui/uiradiobutton.hpp>
|
||||
#include <eepp/ui/uiscrollview.hpp>
|
||||
#include <eepp/ui/uistackwidget.hpp>
|
||||
#include <eepp/ui/uistyle.hpp>
|
||||
#include <eepp/ui/uitextedit.hpp>
|
||||
@@ -1087,8 +1088,6 @@ void GitPlugin::diff( const Git::DiffMode mode, const std::string& repoPath ) {
|
||||
|
||||
std::string repoName = this->repoName( repoPath );
|
||||
getUISceneNode()->runOnMainThread( [this, mode, res, repoName] {
|
||||
auto ret = mManager->getSplitter()->createEditorInNewTab();
|
||||
auto doc = ret.second->getDocumentRef();
|
||||
std::string modeName;
|
||||
switch ( mode ) {
|
||||
case Git::DiffHead: {
|
||||
@@ -1099,12 +1098,8 @@ void GitPlugin::diff( const Git::DiffMode mode, const std::string& repoPath ) {
|
||||
modeName = "staged";
|
||||
break;
|
||||
}
|
||||
doc->setDefaultFileName( repoName + "-" + modeName + ".diff" );
|
||||
ret.second->setSyntaxDefinition(
|
||||
SyntaxDefinitionManager::instance()->getByLSPName( "diff" ) );
|
||||
doc->textInput( res.result, false );
|
||||
doc->moveToStartOfDoc();
|
||||
doc->resetUndoRedo();
|
||||
getPluginContext()->loadDiffFromMemory(
|
||||
res.result, UIDiffView::isMultiFileDiff( res.result ) ? modeName : "" );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ class UITabWidget;
|
||||
class UISceneNode;
|
||||
class UICodeEditor;
|
||||
|
||||
namespace Doc {
|
||||
class SyntaxColorScheme;
|
||||
}
|
||||
|
||||
namespace Tools {
|
||||
class UICodeEditorSplitter;
|
||||
}
|
||||
@@ -159,6 +163,8 @@ class PluginContextProvider {
|
||||
virtual bool projectIsOpen() const = 0;
|
||||
|
||||
virtual size_t getMenuIconSize() const = 0;
|
||||
|
||||
virtual const SyntaxColorScheme* getCurrentColorScheme() const = 0;
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user