【UE】支持使用不同IDE打开不同源代码

前言

本地使用rider和vscode,vscode处理python,其余使用rider

代码修改

USourceCodeAccessSettings

UCLASS(config=EditorSettings)
class USourceCodeAccessSettings : public UObject
{
   GENERATED_UCLASS_BODY()

   /** The source code editor we prefer to use. */
   UPROPERTY(Config, EditAnywhere, Category="Source Code Editor", meta=(DisplayName="Source Code Editor", ConfigRestartRequired = true))
   FString PreferredAccessor;
   
   //新增python的ide
   /** The source code editor we prefer to use. */
   UPROPERTY(Config, EditAnywhere, Category="Source Code Editor", meta=(DisplayName="Python Source Code Editor", ConfigRestartRequired = true))
   FString PythonPreferredAccessor;
};

USourceCodeAccessSettings::USourceCodeAccessSettings(const FObjectInitializer& ObjectInitializer)
   : Super(ObjectInitializer)
{
    ...
 
    //初始化
    PythonPreferredAccessor = PreferredAccessor;
}

ISourceCodeAccessModule

//新增该接口
virtual ISourceCodeAccessor& GetAccessorBySourcePath( const FString& AbsoluteSourcePath) = 0;

FSourceCodeAccessModule

//实现新增接口
ISourceCodeAccessor& FSourceCodeAccessModule::GetAccessorBySourcePath( const FString& AbsoluteSourcePath)
{
   FString PreferredAccessor;
   //python使用python的ide,后续如果有其他需求,也可以在这个函数进行扩展
   if(AbsoluteSourcePath.EndsWith(".py"))
   {
      PreferredAccessor = GetDefault<USourceCodeAccessSettings>()->PythonPreferredAccessor;
   }
   else
   {
      PreferredAccessor = GetDefault<USourceCodeAccessSettings>()->PreferredAccessor;
   }

   bool isNeedRegister = !CurrentSourceCodeAccessor;
   if(CurrentSourceCodeAccessor && CurrentSourceCodeAccessor->GetFName().ToString() != PreferredAccessor)
   {
      isNeedRegister = true;
      ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");

      if (SettingsModule != nullptr)
      {
         SettingsModule->UnregisterSettings("Editor", "General", "Source Code");
      }
   }

   if(isNeedRegister)
   {
      FName PreferredAccessorName = FName(PreferredAccessor);
      SetAccessor(PreferredAccessorName);
   }

   return *CurrentSourceCodeAccessor;
}

FSourceCodeNavigation

//通知IDE打开单个源文件,如果需要支持打开多个源文件,修改函数:OpenSourceFiles
bool FSourceCodeNavigation::OpenSourceFile( const FString& AbsoluteSourcePath, int32 LineNumber, int32 ColumnNumber )
{
   if ( IsCompilerAvailable() )
   {
      ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess");
      //传入需要打开的文件路径
      return SourceCodeAccessModule.GetAccessorBySourcePath(AbsoluteSourcePath).OpenFileAtLine(AbsoluteSourcePath, LineNumber, ColumnNumber);
   }

   // Let others know that we've failed to open a source file.
   AccessOnCompilerNotFound().Broadcast();

   return false;
}

编辑器修改

这里改不改都无所谓,改了就好看些
在这里插入图片描述

//声明
class FSourceCodeAccessSettingsDetails : public IDetailCustomization
{
public:
   /** Makes a new instance of this detail layout class for a specific detail view requesting it */
   static TSharedRef<IDetailCustomization> MakeInstance();

   /** IDetailCustomization interface */
   virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override;

private:
   /** Generate a row widget for display in the list view */
   TSharedRef<SWidget> OnGenerateWidget( TSharedPtr<FAccessorItem> InItem );

    //调整参数
   /** Set the accessor when we change selection */
   void OnSelectionChanged(TSharedPtr<FAccessorItem> InItem, ESelectInfo::Type InSeletionInfo, FName PropertyName);

    //调整参数
   /** Get the text to display on the accessor drop-down */
   FText GetAccessorText(FName PropertyName) const;

private:
    //新增成员变量和函数
   /** Accessor names to display in a drop-down list */
   TMap<FName,TArray<TSharedPtr<FAccessorItem>>> Property2Accessors;
   TMap<FName,TSharedRef<IPropertyHandle>>  Property2PropertyHandle;
   
   void PropertyCustomizeDetails(IDetailLayoutBuilder& DetailLayout,const FName& PropertyName,const FText& FilterString);
};

//实现
void FSourceCodeAccessSettingsDetails::CustomizeDetails( IDetailLayoutBuilder& DetailLayout )
{
   Property2Accessors.Empty();
   Property2PropertyHandle.Empty();
   
   PropertyCustomizeDetails(DetailLayout,"PreferredAccessor",LOCTEXT("PreferredAccessorFilterString", "Source Code Editor"));
   PropertyCustomizeDetails(DetailLayout,"PythonPreferredAccessor",LOCTEXT("PythonPreferredAccessorFilterString", "Python Source Code Editor"));
}

void FSourceCodeAccessSettingsDetails::PropertyCustomizeDetails(IDetailLayoutBuilder& DetailLayout,const FName& PropertyName,const FText& FilterString)
{
   if(!Property2PropertyHandle.Contains(PropertyName))
   {
      Property2PropertyHandle.Add(PropertyName,DetailLayout.GetProperty(PropertyName));
   }
   TSharedRef<IPropertyHandle> PreferredProviderPropertyHandle = Property2PropertyHandle[PropertyName];
   
   DetailLayout.HideProperty(PropertyName);

   if(!Property2Accessors.Contains(PropertyName))
   {
      TArray<TSharedPtr<FAccessorItem>> Accessors;
      const int32 FeatureCount = IModularFeatures::Get().GetModularFeatureImplementationCount("SourceCodeAccessor");
      for(int32 FeatureIndex = 0; FeatureIndex < FeatureCount; FeatureIndex++)
      {
         IModularFeature* Feature = IModularFeatures::Get().GetModularFeatureImplementation("SourceCodeAccessor", FeatureIndex);
         check(Feature);
    
         ISourceCodeAccessor& Accessor = *static_cast<ISourceCodeAccessor*>(Feature);
         if(Accessor.GetFName() != FName("None"))
         {
            Accessors.Add(MakeShareable(new FAccessorItem(Accessor.GetNameText(), Accessor.GetFName())));
         }
      }
      Property2Accessors.Add(PropertyName,Accessors);
   }
   
   TSharedRef<SWidget> PropertyNameWidget = PreferredProviderPropertyHandle->CreatePropertyNameWidget();
   
   IDetailCategoryBuilder& AccessorCategory = DetailLayout.EditCategory( "Accessor" );
   AccessorCategory.AddCustomRow( FilterString )
   .NameContent()
   [
      PropertyNameWidget
   ]
   .ValueContent()
   .MinDesiredWidth(113)
   .MaxDesiredWidth(113)
   [
      SNew(SComboBox< TSharedPtr<FAccessorItem>>)
      .ToolTipText(LOCTEXT("PreferredAccessorToolTip", "Choose the way to access source code."))
      .OptionsSource(&Property2Accessors[PropertyName])
      .OnSelectionChanged(this, &FSourceCodeAccessSettingsDetails::OnSelectionChanged, PropertyName)
      .ContentPadding(2)
      .OnGenerateWidget(this, &FSourceCodeAccessSettingsDetails::OnGenerateWidget)
      .Content()
      [
         SNew(STextBlock)
         .Text(this, &FSourceCodeAccessSettingsDetails::GetAccessorText,PropertyName)
         .Font( IDetailLayoutBuilder::GetDetailFont() )
      ]
   ];
}

void FSourceCodeAccessSettingsDetails::OnSelectionChanged(TSharedPtr<FAccessorItem> InItem, ESelectInfo::Type InSeletionInfo, FName PropertyName)
{
   TSharedRef<IPropertyHandle>* PreferredProviderPropertyHandlePtr = Property2PropertyHandle.Find(PropertyName);
   if(!PreferredProviderPropertyHandlePtr)
   {
      return;
   }
   
   TSharedRef<IPropertyHandle> PreferredProviderPropertyHandle = *PreferredProviderPropertyHandlePtr;
   PreferredProviderPropertyHandle->SetValue(InItem->Name.ToString());

   //ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess");
   //SourceCodeAccessModule.SetAccessor(InItem->Name);
}

FText FSourceCodeAccessSettingsDetails::GetAccessorText(FName PropertyName) const
{
   ISourceCodeAccessModule& SourceCodeAccessModule = FModuleManager::LoadModuleChecked<ISourceCodeAccessModule>("SourceCodeAccess");
   return FText::FromString(SourceCodeAccessModule.GetAccessorName(PropertyName.ToString()));
}


//---------------
//ISourceCodeAccessModule 新增接口
virtual FString GetAccessorName(const FString& typeName) = 0;


//---------------
//FSourceCodeAccessModule 实现接口
FString FSourceCodeAccessModule::GetAccessorName(const FString& typeName)
{
   FString accessorName;
   if(typeName=="PythonPreferredAccessor")
   {
      accessorName = GetDefault<USourceCodeAccessSettings>()->PythonPreferredAccessor;
   }
   else
   {
      accessorName = GetDefault<USourceCodeAccessSettings>()->PreferredAccessor;
   }

   return accessorName;
}

配置文件修改

可以直接手改,也可以到编辑器改
目录:Engine\Saved\Config\WindowsEditor\EditorSettings.ini

//配置对应的IDE
[/Script/SourceCodeAccess.SourceCodeAccessSettings]
PreferredAccessor=Rider
PythonPreferredAccessor=VisualStudioCode
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值