添加书源整理工具

pull/219/head
yangyxd 5 years ago
parent 467caf3d23
commit fa805d9cb4
  1. 22
      tool/书源整理工具/BookSourceMgr.dpr
  2. 654
      tool/书源整理工具/BookSourceMgr.dproj
  3. BIN
      tool/书源整理工具/BookSourceMgr.otares
  4. BIN
      tool/书源整理工具/BookSourceMgr.res
  5. 3
      tool/书源整理工具/ReadMe.txt
  6. BIN
      tool/书源整理工具/doc/Main.ico
  7. 361
      tool/书源整理工具/uBookSourceBean.pas
  8. 247
      tool/书源整理工具/uBookSourceBean20.pas
  9. 1397
      tool/书源整理工具/uFrmEditSource.dfm
  10. 668
      tool/书源整理工具/uFrmEditSource.pas
  11. 780
      tool/书源整理工具/uFrmMain.dfm
  12. 1784
      tool/书源整理工具/uFrmMain.pas
  13. 80
      tool/书源整理工具/uFrmReplaceGroup.dfm
  14. 62
      tool/书源整理工具/uFrmReplaceGroup.pas
  15. 62
      tool/书源整理工具/uFrmWait.dfm
  16. 77
      tool/书源整理工具/uFrmWait.pas

@ -0,0 +1,22 @@
program BookSourceMgr;
uses
Forms,
uFrmMain in 'uFrmMain.pas' {Form1},
Themes,
Styles,
uFrmWait in 'uFrmWait.pas' {Form2},
uBookSourceBean in 'uBookSourceBean.pas',
uFrmEditSource in 'uFrmEditSource.pas' {frmEditSource},
uFrmReplaceGroup in 'uFrmReplaceGroup.pas' {frmReplaceGroup},
uBookSourceBean20 in 'uBookSourceBean20.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.Title := 'ÔĶÁÊéÔ´¹ÜÀí¹¤¾ß';
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

@ -0,0 +1,654 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{b1648034-9a9f-40d4-a355-b3335a5a9446}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>bin\BookSourceMgr.exe</DCC_DependencyCheckOutputName>
<MainSource>BookSourceMgr.dpr</MainSource>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>18.3</ProjectVersion>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<SanitizedProjectName>BookSourceMgr</SanitizedProjectName>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>2052</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_UnitSearchPath>D:\Documents\Desktop\delphi\SynEdit\Source;D:\Documents\Desktop\delphi\YxdJson\source;D:\Documents\Desktop\delphi\YxdIocp\YxdIocp\source\IOCP;D:\Documents\Desktop\delphi\YxdWorker\YxdWorker\source;E:\Projects\Delphi\YxdIocp\source\IOCP;E:\Projects\Delphi\YxdJson\source;E:\Projects\Delphi\YxdWorker\source;\\Mac\Home\Desktop\Project\SynEdit\SynEdit\Source;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>doc\Main.ico</Icon_MainIcon>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<AppEnableHighDPI>true</AppEnableHighDPI>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>BookSourceMgr_Icon1.ico</Icon_MainIcon>
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<UWP_DelphiLogo44>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png</UWP_DelphiLogo44>
<UWP_DelphiLogo150>$(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png</UWP_DelphiLogo150>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<BT_BuildType>Debug</BT_BuildType>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<Version>7.0</Version>
<DCC_DebugInformation>0</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppEnableHighDPI>true</AppEnableHighDPI>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppEnableHighDPI>true</AppEnableHighDPI>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<Version>7.0</Version>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_ExeOutput>.\bin</DCC_ExeOutput>
<DCC_DcuOutput>.\dcu</DCC_DcuOutput>
<DCC_ObjOutput>.\dcu</DCC_ObjOutput>
<DCC_HppOutput>.\dcu</DCC_HppOutput>
<DCC_ResourcePath>D:\Documents\Desktop\YxdJson\source;D:\Documents\Desktop\YxdIocp\YxdIocp\source\IOCP;D:\Documents\Desktop\YxdWorker\YxdWorker\source;$(DCC_ResourcePath)</DCC_ResourcePath>
<DCC_ObjPath>D:\Documents\Desktop\YxdJson\source;D:\Documents\Desktop\YxdIocp\YxdIocp\source\IOCP;D:\Documents\Desktop\YxdWorker\YxdWorker\source;$(DCC_ObjPath)</DCC_ObjPath>
<DCC_IncludePath>D:\Documents\Desktop\YxdJson\source;D:\Documents\Desktop\YxdIocp\YxdIocp\source\IOCP;D:\Documents\Desktop\YxdWorker\YxdWorker\source;$(DCC_IncludePath)</DCC_IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppEnableHighDPI>true</AppEnableHighDPI>
<VerInfo_Keys>CompanyName=YangYxd;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=阅读书源管理工具;ProgramID=com.embarcadero.$(MSBuildProjectName)</VerInfo_Keys>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_AutoGenVersion>true</VerInfo_AutoGenVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
<AppEnableHighDPI>true</AppEnableHighDPI>
<VerInfo_Keys>CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>doc\Main.ico</Icon_MainIcon>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">2052</VersionInfo>
<VersionInfo Name="CodePage">936</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\gitide250.bpl">Embarcadero Git Integration</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k250.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp250.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
<Source>
<Source Name="MainSource">BookSourceMgr.dpr</Source>
</Source>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
<Deployment Version="3">
<DeployFile LocalName="bin\BookSourceMgr.exe" Configuration="Debug" Class="ProjectOutput">
<Platform Name="Win32">
<RemoteName>BookSourceMgr.exe</RemoteName>
<Overwrite>true</Overwrite>
</Platform>
</DeployFile>
<DeployClass Name="AdditionalDebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidClassesDexFile">
<Platform Name="Android">
<RemoteDir>classes</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidGDBServer">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeArmeabiFile">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidLibnativeMipsFile">
<Platform Name="Android">
<RemoteDir>library\lib\mips</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidServiceOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashImageDef">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="AndroidSplashStyles">
<Platform Name="Android">
<RemoteDir>res\values</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_DefaultAppIcon">
<Platform Name="Android">
<RemoteDir>res\drawable</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon144">
<Platform Name="Android">
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon36">
<Platform Name="Android">
<RemoteDir>res\drawable-ldpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon48">
<Platform Name="Android">
<RemoteDir>res\drawable-mdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon72">
<Platform Name="Android">
<RemoteDir>res\drawable-hdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_LauncherIcon96">
<Platform Name="Android">
<RemoteDir>res\drawable-xhdpi</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage426">
<Platform Name="Android">
<RemoteDir>res\drawable-small</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage470">
<Platform Name="Android">
<RemoteDir>res\drawable-normal</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage640">
<Platform Name="Android">
<RemoteDir>res\drawable-large</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="Android_SplashImage960">
<Platform Name="Android">
<RemoteDir>res\drawable-xlarge</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DebugSymbols">
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyFramework">
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.framework</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="DependencyModule">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.dll;.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="DependencyPackage">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
<Extensions>.dylib</Extensions>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
<Extensions>.bpl</Extensions>
</Platform>
</DeployClass>
<DeployClass Name="File">
<Platform Name="Android">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>0</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>0</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\Resources\StartUp\</RemoteDir>
<Operation>0</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1024">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch1536">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch2048">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPad_Launch768">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch320">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="iPhone_Launch640x1136">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectAndroidManifest">
<Platform Name="Android">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceDebug">
<Platform Name="iOSDevice32">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSDeviceResourceRules">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSEntitlements">
<Platform Name="iOSDevice32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSInfoPList">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectiOSResource">
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXEntitlements">
<Platform Name="OSX32">
<RemoteDir>..\</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXInfoPList">
<Platform Name="OSX32">
<RemoteDir>Contents</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectOSXResource">
<Platform Name="OSX32">
<RemoteDir>Contents\Resources</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Required="true" Name="ProjectOutput">
<Platform Name="Android">
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice32">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSDevice64">
<Operation>1</Operation>
</Platform>
<Platform Name="iOSSimulator">
<Operation>1</Operation>
</Platform>
<Platform Name="Linux64">
<Operation>1</Operation>
</Platform>
<Platform Name="OSX32">
<RemoteDir>Contents\MacOS</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win32">
<Operation>0</Operation>
</Platform>
</DeployClass>
<DeployClass Name="ProjectUWPManifest">
<Platform Name="Win32">
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo150">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<DeployClass Name="UWP_DelphiLogo44">
<Platform Name="Win32">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
<Platform Name="Win64">
<RemoteDir>Assets</RemoteDir>
<Operation>1</Operation>
</Platform>
</DeployClass>
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME).app"/>
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
</Deployment>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uFrmMain.pas">
<Form>Form1</Form>
</DCCReference>
<DCCReference Include="uFrmWait.pas">
<Form>Form2</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="uBookSourceBean.pas"/>
<DCCReference Include="uFrmEditSource.pas">
<Form>frmEditSource</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="uFrmReplaceGroup.pas">
<Form>frmReplaceGroup</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="uBookSourceBean20.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ItemGroup/>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
</Project>

@ -0,0 +1,3 @@
本程序用到了 SynEdit
https://github.com/SynEdit/SynEdit

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,361 @@
unit uBookSourceBean;
interface
uses
YxdJson, Classes, SysUtils, Math;
type
TBookSourceItem = class(JSONObject)
private
function GetIndexValue(const Index: Integer): string;
procedure SetIndexValue(const Index: Integer; const Value: string);
function GetEnable: Boolean;
function GetSerialNumber: Integer;
function GetWeight: Integer;
procedure SetEnable(const Value: Boolean);
procedure SetSerialNumber(const Value: Integer);
procedure SetWeight(const Value: Integer);
function GetLastUpdateTime: Int64;
procedure SetLastUpdateTime(const Value: Int64);
function GetScore: Integer;
procedure SetScore(const Value: Integer);
function GetEnabledExplore: Boolean;
procedure SetEnabledExplore(const Value: Boolean);
function GetBookSourceType: Integer;
procedure SetBookSourceType(const Value: Integer);
public
procedure AddGroup(const Name: string);
procedure RemoveGroup(const Name: string);
procedure ReplaceGroup(const Name, NewName: string);
function GetGroupList(): TArray<string>;
procedure SetStrValue(const AKey, Value: string);
function GetStr(const AKey: string): string;
property bookSourceType: Integer read GetBookSourceType write SetBookSourceType; // 书源类型
property bookSourceGroup: string index 0 read GetIndexValue write SetIndexValue; // 书源分组
property bookSourceName: string index 1 read GetIndexValue write SetIndexValue; // 书源名称
property bookSourceUrl: string index 2 read GetIndexValue write SetIndexValue; // 书源URL
property bookUrlPattern: string index 45 read GetIndexValue write SetIndexValue; // 链接验证
property header: string index 3 read GetIndexValue write SetIndexValue; // 请求头
property loginUrl: string index 4 read GetIndexValue write SetIndexValue; // 登录URL
property searchUrl: string index 6 read GetIndexValue write SetIndexValue; // 搜索地址
property exploreUrl: string index 7 read GetIndexValue write SetIndexValue; // 发现地址
property ruleSearch_bookList: string index 8 read GetIndexValue write SetIndexValue;
property ruleSearch_name: string index 9 read GetIndexValue write SetIndexValue;
property ruleSearch_author: string index 10 read GetIndexValue write SetIndexValue;
property ruleSearch_kind: string index 11 read GetIndexValue write SetIndexValue;
property ruleSearch_wordCount: string index 12 read GetIndexValue write SetIndexValue;
property ruleSearch_lastChapter: string index 13 read GetIndexValue write SetIndexValue;
property ruleSearch_intro: string index 14 read GetIndexValue write SetIndexValue;
property ruleSearch_coverUrl: string index 15 read GetIndexValue write SetIndexValue;
property ruleSearch_bookUrl: string index 16 read GetIndexValue write SetIndexValue;
property ruleExplore_bookList: string index 17 read GetIndexValue write SetIndexValue;
property ruleExplore_name: string index 18 read GetIndexValue write SetIndexValue;
property ruleExplore_author: string index 19 read GetIndexValue write SetIndexValue;
property ruleExplore_kind: string index 20 read GetIndexValue write SetIndexValue;
property ruleExplore_wordCount: string index 21 read GetIndexValue write SetIndexValue;
property ruleExplore_lastChapter: string index 22 read GetIndexValue write SetIndexValue;
property ruleExplore_intro: string index 23 read GetIndexValue write SetIndexValue;
property ruleExplore_coverUrl: string index 24 read GetIndexValue write SetIndexValue;
property ruleExplore_bookUrl: string index 25 read GetIndexValue write SetIndexValue;
property ruleBookInfo_init: string index 26 read GetIndexValue write SetIndexValue;
property ruleBookInfo_name: string index 27 read GetIndexValue write SetIndexValue;
property ruleBookInfo_author: string index 28 read GetIndexValue write SetIndexValue;
property ruleBookInfo_kind: string index 29 read GetIndexValue write SetIndexValue;
property ruleBookInfo_wordCount: string index 30 read GetIndexValue write SetIndexValue;
property ruleBookInfo_lastChapter: string index 31 read GetIndexValue write SetIndexValue;
property ruleBookInfo_intro: string index 32 read GetIndexValue write SetIndexValue;
property ruleBookInfo_coverUrl: string index 33 read GetIndexValue write SetIndexValue;
property ruleBookInfo_tocUrl: string index 34 read GetIndexValue write SetIndexValue;
property ruleToc_chapterList: string index 35 read GetIndexValue write SetIndexValue;
property ruleToc_chapterName: string index 36 read GetIndexValue write SetIndexValue;
property ruleToc_chapterUrl: string index 37 read GetIndexValue write SetIndexValue;
property ruleToc_isVip: string index 38 read GetIndexValue write SetIndexValue;
property ruleToc_updateTime: string index 39 read GetIndexValue write SetIndexValue;
property ruleToc_nextTocUrl: string index 40 read GetIndexValue write SetIndexValue;
property ruleContent_content: string index 41 read GetIndexValue write SetIndexValue;
property ruleContent_nextContentUrl: string index 42 read GetIndexValue write SetIndexValue;
property ruleContent_webJs: string index 43 read GetIndexValue write SetIndexValue;
property ruleContent_sourceRegex: string index 44 read GetIndexValue write SetIndexValue;
property lastUpdateTime: Int64 read GetLastUpdateTime write SetLastUpdateTime; // 最后更新时间
property enable: Boolean read GetEnable write SetEnable;
property enabledExplore: Boolean read GetEnabledExplore write SetEnabledExplore;
property customOrder: Integer read GetSerialNumber write SetSerialNumber;
property weight: Integer read GetWeight write SetWeight;
property score: Integer read GetScore write SetScore; // 评分
end;
implementation
{ TBookSourceItem }
const
SKeyArray: array [0..45] of string = (
'bookSourceGroup',
'bookSourceName',
'bookSourceUrl',
'header',
'loginUrl',
'bookSourceType',
'searchUrl',
'exploreUrl',
'ruleSearch_bookList',
'ruleSearch_name',
'ruleSearch_author',
'ruleSearch_kind',
'ruleSearch_wordCount',
'ruleSearch_lastChapter',
'ruleSearch_intro',
'ruleSearch_coverUrl',
'ruleSearch_bookUrl',
'ruleExplore_bookList',
'ruleExplore_name',
'ruleExplore_author',
'ruleExplore_kind',
'ruleExplore_wordCount',
'ruleExplore_lastChapter',
'ruleExplore_intro',
'ruleExplore_coverUrl',
'ruleExplore_bookUrl',
'ruleBookInfo_init',
'ruleBookInfo_name',
'ruleBookInfo_author',
'ruleBookInfo_kind',
'ruleBookInfo_wordCount',
'ruleBookInfo_lastChapter',
'ruleBookInfo_intro',
'ruleBookInfo_coverUrl',
'ruleBookInfo_tocUrl',
'ruleToc_chapterList',
'ruleToc_chapterName',
'ruleToc_chapterUrl',
'ruleToc_isVip',
'ruleToc_updateTime',
'ruleToc_nextTocUrl',
'ruleContent_content',
'ruleContent_nextContentUrl',
'ruleContent_webJs',
'ruleContent_sourceRegex',
'bookUrlPattern'
);
SEnabled = 'enable';
SEnabledExplore = 'enabledExplore';
SSerialNumber = 'customOrder';
SWeight = 'weight';
procedure TBookSourceItem.AddGroup(const Name: string);
var
S: string;
List: TArray<string>;
I: Integer;
begin
S := Trim(bookSourceGroup);
if S = '' then
bookSourceGroup := Name
else begin
List := GetGroupList();
for I := Low(List) to High(List) do begin
if Trim(List[I]) = Name then
Exit;
end;
bookSourceGroup := bookSourceGroup + '; ' + Name;
end;
end;
function TBookSourceItem.GetBookSourceType: Integer;
begin
Result := Self.I[SKeyArray[5]];
end;
function TBookSourceItem.GetEnable: Boolean;
begin
Result := Self.B[SEnabled];
end;
function TBookSourceItem.GetEnabledExplore: Boolean;
begin
Result := Self.B[SEnabledExplore];
end;
function TBookSourceItem.GetGroupList: TArray<string>;
var
S: string;
begin
S := Trim(bookSourceGroup);
Result := S.Split([',', ';', ':', ',', ';']);
end;
function TBookSourceItem.GetIndexValue(const Index: Integer): string;
begin
Result := GetStr(SKeyArray[Index]);
end;
function TBookSourceItem.GetLastUpdateTime: Int64;
begin
Result := Self.I['lastUpdateTime'];
end;
function TBookSourceItem.GetScore: Integer;
begin
Result := Self.I['score'];
end;
function TBookSourceItem.GetSerialNumber: Integer;
begin
Result := Self.I[SSerialNumber];
end;
function TBookSourceItem.GetStr(const AKey: string): string;
var
Key, PKey: string;
J: Integer;
Json: JSONObject;
begin
Key := AKey;
J := Key.IndexOf('_');
if J > 0 then begin
PKey := Key.Substring(0, J);
Json := Self.O[PKey];
if Json = nil then
Result := ''
else begin
Key := Key.Substring(J + 1);
Result := Json.S[Key];
end;
end else
Result := Self.S[Key];
end;
function TBookSourceItem.GetWeight: Integer;
begin
Result := SElf.I[SWeight];
end;
procedure TBookSourceItem.RemoveGroup(const Name: string);
var
S: string;
List: TArray<string>;
I, J: Integer;
SB: TStringBuilder;
begin
S := Trim(bookSourceGroup);
if S <> '' then begin
J := 0;
List := GetGroupList();
SB := TStringBuilder.Create(Length(bookSourceGroup) * 2);
for I := Low(List) to High(List) do begin
if Trim(List[I]) <> Name then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(List[I]));
Inc(J);
end;
end;
bookSourceGroup := SB.ToString;
end;
end;
procedure TBookSourceItem.ReplaceGroup(const Name, NewName: string);
var
S: string;
List: TArray<string>;
I, J: Integer;
SB: TStringBuilder;
begin
S := Trim(bookSourceGroup);
if S <> '' then begin
J := 0;
List := GetGroupList();
SB := TStringBuilder.Create(Length(bookSourceGroup) * 2);
for I := Low(List) to High(List) do begin
if Trim(List[I]) <> Name then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(List[I]));
Inc(J);
end else if NewName <> '' then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(NewName));
Inc(J);
end;
end;
bookSourceGroup := SB.ToString;
end;
end;
procedure TBookSourceItem.SetBookSourceType(const Value: Integer);
begin
Self.I[SKeyArray[5]] := Value;
end;
procedure TBookSourceItem.SetEnable(const Value: Boolean);
begin
Self.B[SEnabled] := Value;
end;
procedure TBookSourceItem.SetEnabledExplore(const Value: Boolean);
begin
Self.B[SEnabledExplore] := Value;
end;
procedure TBookSourceItem.SetIndexValue(const Index: Integer;
const Value: string);
begin
SetStrValue(SKeyArray[Index], Value);
end;
procedure TBookSourceItem.SetStrValue(const AKey, Value: string);
var
Key, PKey: string;
J: Integer;
Json: JSONObject;
begin
Key := AKey;
J := Key.IndexOf('_');
if J > 0 then begin
PKey := Key.Substring(0, J);
Json := Self.O[PKey];
if Json = nil then
Json := Self.AddChildObject(PKey);
Key := Key.Substring(J + 1);
Json.S[Key] := Value;
end else
Self.S[Key] := Value;
end;
procedure TBookSourceItem.SetLastUpdateTime(const Value: Int64);
begin
Self.I['lastUpdateTime'] := Value;
end;
procedure TBookSourceItem.SetScore(const Value: Integer);
begin
Self.I['score'] := Value;
end;
procedure TBookSourceItem.SetSerialNumber(const Value: Integer);
begin
Self.I[SSerialNumber] := Value;
end;
procedure TBookSourceItem.SetWeight(const Value: Integer);
begin
Self.I[SWeight] := Value;
end;
end.

@ -0,0 +1,247 @@
unit uBookSourceBean20;
interface
uses
YxdJson, Classes, SysUtils, Math;
type
TBookSource20Item = class(JSONObject)
private
function GetIndexValue(const Index: Integer): string;
procedure SetIndexValue(const Index: Integer; const Value: string);
function GetEnable: Boolean;
function GetSerialNumber: Integer;
function GetWeight: Integer;
procedure SetEnable(const Value: Boolean);
procedure SetSerialNumber(const Value: Integer);
procedure SetWeight(const Value: Integer);
function GetLastUpdateTime: Int64;
procedure SetLastUpdateTime(const Value: Int64);
function GetScore: Integer;
procedure SetScore(const Value: Integer);
public
procedure AddGroup(const Name: string);
procedure RemoveGroup(const Name: string);
procedure ReplaceGroup(const Name, NewName: string);
function GetGroupList(): TArray<string>;
property bookSourceType: string index 28 read GetIndexValue write SetIndexValue; // 书源类型
property bookSourceGroup: string index 0 read GetIndexValue write SetIndexValue; // 书源分组
property bookSourceName: string index 1 read GetIndexValue write SetIndexValue; // 书源名称
property bookSourceUrl: string index 2 read GetIndexValue write SetIndexValue; // 书源URL
property httpUserAgent: string index 3 read GetIndexValue write SetIndexValue; // HttpUserAgent
property loginUrl: string index 4 read GetIndexValue write SetIndexValue; // 登录URL
property ruleBookAuthor: string index 5 read GetIndexValue write SetIndexValue; // 作者规则
property ruleBookContent: string index 6 read GetIndexValue write SetIndexValue; // 正文规则
property ruleBookKind: string index 7 read GetIndexValue write SetIndexValue; // 分类规则
property ruleBookLastChapter: string index 8 read GetIndexValue write SetIndexValue; // 最新章节规则
property ruleBookName: string index 9 read GetIndexValue write SetIndexValue; // 书名规则
property ruleBookUrlPattern: string index 10 read GetIndexValue write SetIndexValue; // 书籍详情URL正则
property ruleChapterList: string index 11 read GetIndexValue write SetIndexValue; // 目录列表规则
property ruleChapterName: string index 12 read GetIndexValue write SetIndexValue; // 章节名称规则
property ruleChapterUrl: string index 13 read GetIndexValue write SetIndexValue; // 目录URL规则
property ruleChapterUrlNext: string index 14 read GetIndexValue write SetIndexValue; // 目录下一页Url规则
property ruleContentUrl: string index 15 read GetIndexValue write SetIndexValue; // 正文章节URL规则
property ruleContentUrlNext: string index 16 read GetIndexValue write SetIndexValue; // 正文下一页URL规则
property ruleCoverUrl: string index 17 read GetIndexValue write SetIndexValue; // 封面规则
property ruleFindUrl: string index 18 read GetIndexValue write SetIndexValue; // 发现规则
property ruleIntroduce: string index 19 read GetIndexValue write SetIndexValue; // 简介规则
property ruleSearchAuthor: string index 20 read GetIndexValue write SetIndexValue; // 搜索结果作者规则
property ruleSearchCoverUrl: string index 21 read GetIndexValue write SetIndexValue; // 搜索结果封面规则
property ruleSearchKind: string index 22 read GetIndexValue write SetIndexValue; // 搜索结果分类规则
property ruleSearchLastChapter: string index 23 read GetIndexValue write SetIndexValue; // 搜索结果最新章节规则
property ruleSearchList: string index 24 read GetIndexValue write SetIndexValue; // 搜索结果列表规则
property ruleSearchName: string index 25 read GetIndexValue write SetIndexValue; // 搜索结果书名规则
property ruleSearchNoteUrl: string index 26 read GetIndexValue write SetIndexValue; // 搜索结果书籍URL规则
property ruleSearchUrl: string index 27 read GetIndexValue write SetIndexValue; // 搜索规地址
property lastUpdateTime: Int64 read GetLastUpdateTime write SetLastUpdateTime; // 最后更新时间
property enable: Boolean read GetEnable write SetEnable;
property serialNumber: Integer read GetSerialNumber write SetSerialNumber;
property weight: Integer read GetWeight write SetWeight;
property score: Integer read GetScore write SetScore; // 评分
end;
implementation
{ TBookSourceItem }
const
SKeyArray: array [0..28] of string = (
'bookSourceGroup',
'bookSourceName',
'bookSourceUrl',
'httpUserAgent',
'loginUrl',
'ruleBookAuthor',
'ruleBookContent',
'ruleBookKind',
'ruleBookLastChapter',
'ruleBookName',
'ruleBookUrlPattern',
'ruleChapterList',
'ruleChapterName',
'ruleChapterUrl',
'ruleChapterUrlNext',
'ruleContentUrl',
'ruleContentUrlNext',
'ruleCoverUrl',
'ruleFindUrl',
'ruleIntroduce',
'ruleSearchAuthor',
'ruleSearchCoverUrl',
'ruleSearchKind',
'ruleSearchLastChapter',
'ruleSearchList',
'ruleSearchName',
'ruleSearchNoteUrl',
'ruleSearchUrl',
'bookSourceType'
);
SEnabled = 'enable';
SSerialNumber = 'serialNumber';
SWeight = 'weight';
procedure TBookSource20Item.AddGroup(const Name: string);
var
S: string;
List: TArray<string>;
I: Integer;
begin
S := Trim(bookSourceGroup);
if S = '' then
bookSourceGroup := Name
else begin
List := GetGroupList();
for I := Low(List) to High(List) do begin
if Trim(List[I]) = Name then
Exit;
end;
bookSourceGroup := bookSourceGroup + '; ' + Name;
end;
end;
function TBookSource20Item.GetEnable: Boolean;
begin
Result := Self.B[SEnabled];
end;
function TBookSource20Item.GetGroupList: TArray<string>;
var
S: string;
begin
S := Trim(bookSourceGroup);
Result := S.Split([',', ';', ':', ',', ';']);
end;
function TBookSource20Item.GetIndexValue(const Index: Integer): string;
begin
Result := Self.S[SKeyArray[Index]];
end;
function TBookSource20Item.GetLastUpdateTime: Int64;
begin
Result := Self.I['lastUpdateTime'];
end;
function TBookSource20Item.GetScore: Integer;
begin
Result := Self.I['score'];
end;
function TBookSource20Item.GetSerialNumber: Integer;
begin
Result := Self.I[SSerialNumber];
end;
function TBookSource20Item.GetWeight: Integer;
begin
Result := SElf.I[SWeight];
end;
procedure TBookSource20Item.RemoveGroup(const Name: string);
var
S: string;
List: TArray<string>;
I, J: Integer;
SB: TStringBuilder;
begin
S := Trim(bookSourceGroup);
if S <> '' then begin
J := 0;
List := GetGroupList();
SB := TStringBuilder.Create(Length(bookSourceGroup) * 2);
for I := Low(List) to High(List) do begin
if Trim(List[I]) <> Name then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(List[I]));
Inc(J);
end;
end;
bookSourceGroup := SB.ToString;
end;
end;
procedure TBookSource20Item.ReplaceGroup(const Name, NewName: string);
var
S: string;
List: TArray<string>;
I, J: Integer;
SB: TStringBuilder;
begin
S := Trim(bookSourceGroup);
if S <> '' then begin
J := 0;
List := GetGroupList();
SB := TStringBuilder.Create(Length(bookSourceGroup) * 2);
for I := Low(List) to High(List) do begin
if Trim(List[I]) <> Name then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(List[I]));
Inc(J);
end else if NewName <> '' then begin
if J > 0 then
SB.Append('; ');
SB.Append(Trim(NewName));
Inc(J);
end;
end;
bookSourceGroup := SB.ToString;
end;
end;
procedure TBookSource20Item.SetEnable(const Value: Boolean);
begin
Self.B[SEnabled] := Value;
end;
procedure TBookSource20Item.SetIndexValue(const Index: Integer;
const Value: string);
begin
Self.S[SKeyArray[Index]] := Value;
end;
procedure TBookSource20Item.SetLastUpdateTime(const Value: Int64);
begin
Self.I['lastUpdateTime'] := Value;
end;
procedure TBookSource20Item.SetScore(const Value: Integer);
begin
Self.I['score'] := Value;
end;
procedure TBookSource20Item.SetSerialNumber(const Value: Integer);
begin
Self.I[SSerialNumber] := Value;
end;
procedure TBookSource20Item.SetWeight(const Value: Integer);
begin
Self.I[SWeight] := Value;
end;
end.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,668 @@
unit uFrmEditSource;
interface
uses
uBookSourceBean, YxdJson, RegularExpressions,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TNotifyEventA = reference to procedure (Item: TBookSourceItem);
TfrmEditSource = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
CheckBox1: TCheckBox;
Label29: TLabel;
Edit27: TEdit;
Label30: TLabel;
Edit28: TEdit;
Button3: TButton;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
ScrollBox1: TScrollBox;
Panel2: TPanel;
Label33: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label34: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
Label20: TLabel;
Edit18: TEdit;
Edit11: TEdit;
Edit10: TEdit;
Edit9: TEdit;
Edit30: TEdit;
Edit8: TEdit;
Edit7: TEdit;
Edit6: TEdit;
Edit5: TEdit;
Edit4: TEdit;
Panel3: TPanel;
Label14: TLabel;
Label15: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label21: TLabel;
Label22: TLabel;
Label23: TLabel;
Label24: TLabel;
Label25: TLabel;
Label2: TLabel;
Edit12: TEdit;
Edit13: TEdit;
Edit14: TEdit;
Edit15: TEdit;
Edit16: TEdit;
Edit17: TEdit;
Edit19: TEdit;
Edit20: TEdit;
Edit21: TEdit;
Memo1: TMemo;
Panel4: TPanel;
Label26: TLabel;
Label27: TLabel;
Label35: TLabel;
Label36: TLabel;
Label37: TLabel;
Label38: TLabel;
Label39: TLabel;
Label40: TLabel;
Label41: TLabel;
Label42: TLabel;
Edit22: TEdit;
Edit23: TEdit;
Edit24: TEdit;
Edit25: TEdit;
Edit26: TEdit;
Edit31: TEdit;
Edit32: TEdit;
Edit33: TEdit;
Edit35: TEdit;
Panel6: TPanel;
Label32: TLabel;
Label5: TLabel;
Label31: TLabel;
Label4: TLabel;
Label3: TLabel;
Label1: TLabel;
Memo2: TMemo;
Edit3: TEdit;
Edit2: TEdit;
Edit1: TEdit;
ComboBox1: TComboBox;
Edit29: TEdit;
Panel5: TPanel;
Label28: TLabel;
Label43: TLabel;
Label44: TLabel;
Label45: TLabel;
Label46: TLabel;
Edit41: TEdit;
Edit42: TEdit;
Edit43: TEdit;
Memo3: TMemo;
Panel7: TPanel;
Label48: TLabel;
Label49: TLabel;
Label50: TLabel;
Label51: TLabel;
Label52: TLabel;
Label53: TLabel;
Edit34: TEdit;
Edit36: TEdit;
Edit37: TEdit;
Edit38: TEdit;
Edit44: TEdit;
CheckBox4: TCheckBox;
CheckBox5: TCheckBox;
Label47: TLabel;
Edit39: TEdit;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
procedure CheckBox2Click(Sender: TObject);
procedure CheckBox3Click(Sender: TObject);
private
{ Private declarations }
FDisableChange: Boolean;
public
{ Public declarations }
Data: TBookSourceItem;
CallBack: TNotifyEventA;
procedure ApplayEdit(Data: TBookSourceItem);
end;
var
frmEditSource: TfrmEditSource;
procedure ShowEditSource(Item: TBookSourceItem; CallBack: TNotifyEventA = nil);
function Is20Source(Item: JSONObject): Boolean;
procedure ConvertToNewFormat(Item: TBookSourceItem);
implementation
{$R *.dfm}
uses
uFrmMain, Math, uBookSourceBean20;
var
LastW, LastH: Integer;
procedure ShowEditSource(Item: TBookSourceItem; CallBack: TNotifyEventA);
var
F: TfrmEditSource;
begin
F := TfrmEditSource.Create(Application);
F.Data := Item;
F.CallBack := CallBack;
if Is20Source(Item) then
ConvertToNewFormat(F.Data);
F.Show;
end;
function Is20Source(Item: JSONObject): Boolean;
begin
Result := Item.Contains('ruleSearchUrl') and (not Item.Contains('ruleSearch'))
end;
type
RegCallback = reference to procedure(const value: string);
procedure ConvertToNewFormat(Item: TBookSourceItem);
var
Data: TBookSource20Item;
NewData: TBookSourceItem;
Tmp: JSONObject;
S: string;
function RegMatchs(const pattern, txt: string; callback: RegCallback; all: Boolean = False): string;
var
match : TMatch;
groups: TGroupCollection;
group: TGroup;
begin
match := TRegEx.Match(txt, pattern, [roIgnoreCase]);
groups := match.Groups;
if groups.Count = 0 then Exit;
if all then begin
for group in groups do begin
if Assigned(callback) then
callback(group.Value);
end;
end else if Assigned(callback) then
callback(groups[0].Value);
end;
function toNewRule(oldRule: string): string;
var
reverse: Boolean;
allinone: Boolean;
I: Integer;
list: TArray<string>;
begin
if oldRule = '' then begin
Result := '';
Exit;
end;
reverse := False;
allinone := False;
Result := oldRule;
if (Result.StartsWith('-')) then begin
reverse := True;
Result := Result.Substring(1);
end;
if Result.StartsWith('+') then begin
allinone := True;
Result := Result.Substring(1);
end;
if (not Result.StartsWith('@CSS:', True)) and
(not Result.StartsWith('@XPath:', True)) and
(not Result.StartsWith('//')) and
(not Result.StartsWith('##')) and
(not Result.StartsWith(':')) and
(not Result.StartsWith('@js:', True)) and
(not Result.StartsWith('<js>', True))
then begin
if Result.Contains('#') and (not Result.Contains('##')) then begin
Result := Result.Replace('#', '##');
end;
if Result.Contains('|') and (not Result.Contains('||')) then begin
if (Result.Contains('##')) then begin
list := result.Split(['##']);
if (list[0].Contains('|')) then begin
result := list[0].Replace('|', '||');
for I := 0 to High(list) do
Result := Result + '##' + list[i];
end;
end else begin
Result := Result.Replace('|', '||');
end;
end;
if Result.Contains('&') and
(not Result.Contains('&&')) and
(not Result.Contains('http')) and
(not Result.Contains('/')) then begin
result := result.Replace('&', '&&');
end;
end;
if allinone = true then
Result := '+' + Result;
if reverse = true then
Result := '-' + Result;
end;
function toNewUrl(oldUrl: string): string;
var
url: string;
list: TArray<string>;
jsList: TStrings;
map: JSONObject;
mather: Boolean;
I: Integer;
begin
if oldUrl = '' then begin
Result := '';
Exit;
end;
url := oldUrl;
if (oldUrl.startsWith('<js>', true)) then begin
Result := url.replace('=searchKey', '={{key}}')
.replace('=searchPage', '={{page}}');
Exit;
end;
map := JSONObject.Create;
jsList := TStringList.Create;
try
RegMatchs('@Header:\{.+?\}', url,
procedure (const value: string) begin
url := url.Replace(value, '');
map.S['headers'] := value;
end
);
list := url.Split(['|']);
url := list[0];
if Length(list) > 1 then begin
list := list[1].Split(['=']);
if Length(list) > 1 then
map.S['charset'] := list[1];
end;
jsList.Clear;
RegMatchs('\{\{.+?\}\}', url,
procedure (const value: string) begin
jsList.Add(value);
url := url.Replace(value, '$${' + IntToStr(jsList.Count - 1) + '}');
end
);
url := url.replace('{', '<').replace('}', '>');
url := url.replace('searchKey', '{{key}}');
url := TRegEx.Replace(url, '<searchPage([-+]1)>', '{{page$1}}', [roIgnoreCase]);
url := TRegEx.Replace(url, 'searchPage([-+]1)', '{{page$1}}', [roIgnoreCase]);
url := url.replace('searchPage', '{{page}}');
for I := 0 to jsList.Count - 1 do begin
url := url.replace('$' + IntToStr(i), jsList[i].Replace('searchKey', 'key').Replace('searchPage', 'page'));
end;
list := url.Split(['@']);
url := list[0];
if (Length(list) > 1) then begin
map.S['method'] := 'POST';
map.S['body'] := list[1];
end;
if map.Count > 0 then
url := Url + ',' + map.ToString;
Result := url;
finally
FreeAndNil(jsList);
FreeAndNil(map);
end;
end;
function toNewUrls(const oldUrls: string): string;
var
urls: TArray<string>;
i: Integer;
begin
if oldUrls = '' then begin
Result := '';
Exit;
end;
if (not oldUrls.Contains(#13)) and (not oldUrls.Contains('&&')) then begin
Result := toNewUrl(oldUrls);
Exit;
end;
Result := '';
urls := oldurls.Split(['&&', sLineBreak, #13]);
for I := 0 to High(urls) do begin
if Trim(urls[i]) = '' then Continue;
Result := Result + toNewUrl(urls[i]).Replace(sLineBreak, '').Replace(#13, '') + sLineBreak;
end;
end;
procedure SyncItem(const NewKey, LastKey: string; IsURL: Boolean = False; IsURLs: boolean = false);
var
v: string;
begin
v := Data.S[LastKey];
if (v = '') then Exit;
if IsURL then
v := toNewUrl(v)
else if IsURLs then
v := toNewUrls(v)
else
v := toNewRule(v);
NewData.SetStrValue(NewKey, v);
end;
begin
Tmp := JSONObject.Create();
try
Data := TBookSource20Item(Item);
NewData := TBookSourceItem.Create();
NewData.enable := data.enable;
if (data.bookSourceType = 'AUDIO') then
NewData.bookSourceType := 1
else if (data.bookSourceType = 'IMAGE') then
NewData.bookSourceType := 2
else
NewData.bookSourceType := 0;
NewData.bookSourceGroup := data.bookSourceGroup;
NewData.bookSourceUrl := data.bookSourceUrl;
NewData.bookUrlPattern := data.ruleBookUrlPattern;
NewData.bookSourceName := data.bookSourceName;
NewData.customOrder := data.serialNumber;
NewData.weight := data.weight;
NewData.score := data.score;
NewData.loginUrl := data.loginUrl;
if (Data.httpUserAgent <> '') then begin
Tmp.s['User-Agent'] := Data.httpUserAgent;
NewData.header := tmp.ToString;
end;
SyncItem('ruleBookInfo_author', 'ruleBookAuthor');
SyncItem('searchUrl', 'ruleSearchUrl', True);
SyncItem('exploreUrl', 'ruleFindUrl', False, True);
SyncItem('ruleSearch_bookList', 'ruleSearchList');
SyncItem('ruleSearch_name', 'ruleSearchName');
SyncItem('ruleSearch_author', 'ruleSearchAuthor');
SyncItem('ruleSearch_kind', 'ruleSearchKind');
SyncItem('ruleSearch_intro', 'ruleSearchIntroduce');
SyncItem('ruleSearch_bookUrl', 'ruleSearchNoteUrl');
SyncItem('ruleSearch_coverUrl', 'ruleSearchCoverUrl');
SyncItem('ruleSearch_lastChapter', 'ruleSearchLastChapter');
SyncItem('ruleExplore_bookList', 'ruleFindList');
SyncItem('ruleExplore_name', 'ruleFindName');
SyncItem('ruleExplore_author', 'ruleFindAuthor');
SyncItem('ruleExplore_intro', 'ruleFindIntroduce');
SyncItem('ruleExplore_kind', 'ruleFindKind');
SyncItem('ruleExplore_bookUrl', 'ruleFindNoteUrl');
SyncItem('ruleExplore_coverUrl', 'ruleFindCoverUrl');
SyncItem('ruleExplore_lastChapter', 'ruleFindLastChapter');
SyncItem('ruleBookInfo_init', 'ruleBookInfoInit');
SyncItem('ruleBookInfo_name', 'ruleBookName');
SyncItem('ruleBookInfo_author', 'ruleBookAuthor');
SyncItem('ruleBookInfo_intro', 'ruleIntroduce');
SyncItem('ruleBookInfo_kind', 'ruleBookKind');
SyncItem('ruleBookInfo_coverUrl', 'ruleCoverUrl');
SyncItem('ruleBookInfo_lastChapter', 'ruleBookLastChapter');
SyncItem('ruleBookInfo_tocUrl', 'ruleChapterUrl');
SyncItem('ruleToc_chapterList', 'ruleChapterList');
SyncItem('ruleToc_chapterName', 'ruleChapterName');
SyncItem('ruleToc_chapterUrl', 'ruleContentUrl');
SyncItem('ruleToc_nextTocUrl', 'ruleChapterUrlNext');
S := Data.S['ruleBookContent'];
if S.StartsWith('$') and (not S.StartsWith('$.')) then
S := S.Substring(1);
NewData.SetStrValue('ruleContent_content', S);
SyncItem('ruleContent_nextContentUrl', 'ruleContentUrlNext');
Item.Clear;
Item.Assign(NewData);
finally
FreeAndNil(tmp);
end;
end;
procedure TfrmEditSource.ApplayEdit(Data: TBookSourceItem);
procedure SetEditValue(Parent: TWinControl);
var
I, J: Integer;
Item: TControl;
Json: JSONObject;
Key, PKey, Value: string;
begin
for I := 0 to Parent.ControlCount - 1 do begin
Item := Parent.Controls[I];
if not Item.Visible then Continue;
if Item is TPanel then begin
SetEditValue(TWinControl(Item));
Continue;
end;
Key := Item.Hint;
if Key = '' then Continue;
Json := Data;
J := Key.IndexOf('_');
if J > 0 then begin
PKey := Key.Substring(0, J);
Json := Data.O[PKey];
if Json = nil then
Json := Data.AddChildObject(PKey);
Key := Key.Substring(J + 1);
end;
Value := '';
if Item is TEdit then
Value := TEdit(Item).Text
else if Item is TComboBox then
Value := TComboBox(Item).Text
else if Item is TMemo then
Value := TMemo(Item).Text;
Json.S[Key] := Value;
continue;
if Value <> '' then
Json.S[Key] := Value
else
Json.Delete(Key);
end;
end;
begin
Data.enable := CheckBox1.Checked;
if CheckBox2.Checked then
Data.bookSourceType := 1
else if CheckBox3.Checked then
Data.bookSourceType := 2
else
Data.bookSourceType := 0;
Data.weight := StrToIntDef(Edit27.Text, Data.weight);
Data.customOrder := StrToIntDef(Edit28.Text, Data.customOrder);
SetEditValue(ScrollBox1);
end;
procedure TfrmEditSource.Button1Click(Sender: TObject);
begin
FDisableChange := True;
try
ApplayEdit(Data);
finally
FDisableChange := False;
end;
if Assigned(CallBack) then
CallBack(Data);
Close;
end;
procedure TfrmEditSource.Button2Click(Sender: TObject);
begin
Close;
end;
procedure TfrmEditSource.Button3Click(Sender: TObject);
var
Item: TBookSourceItem;
Msg: TStrings;
begin
Msg := TStringList.Create;
Item := TBookSourceItem(JSONObject.Create);
try
Item.Parse(Data.ToString());
ApplayEdit(Item);
if Form1.CheckBookSourceItem(Item, True, Msg) then
MessageBox(Handle, PChar(Msg.Text), '¹§Ï², ¼ì²âͨ¹ý!', 64)
else
MessageBox(Handle, PChar(Msg.Text), 'ÊéÔ´Òì³£', 48)
finally
FreeAndNil(Item);
FreeAndNil(Msg);
end;
end;
procedure TfrmEditSource.CheckBox2Click(Sender: TObject);
begin
if CheckBox2.Checked then
CheckBox3.Checked := False;
end;
procedure TfrmEditSource.CheckBox3Click(Sender: TObject);
begin
if CheckBox3.Checked then
CheckBox2.Checked := False;
end;
procedure TfrmEditSource.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TfrmEditSource.FormCreate(Sender: TObject);
begin
if LastW <= 0 then LastW := Self.Width;
if LastH <= 0 then LastH := Self.Height;
Self.SetBounds(Left, Top, LastW, LastH);
end;
procedure TfrmEditSource.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
if WheelDelta < 0 then
ScrollBox1.Perform(WM_VSCROLL,SB_LINEDOWN,0)
else
ScrollBox1.Perform(WM_VSCROLL,SB_LINEUP,0);
end;
procedure TfrmEditSource.FormResize(Sender: TObject);
begin
LastW := Width;
LastH := Height;
end;
procedure TfrmEditSource.FormShow(Sender: TObject);
procedure SetEditValue(Parent: TWinControl);
var
I, J: Integer;
Item: TControl;
Json: JSONObject;
Key, PKey, Value: string;
begin
for I := 0 to Parent.ControlCount - 1 do begin
Item := Parent.Controls[I];
if not Item.Visible then Continue;
if Item is TPanel then begin
SetEditValue(TWinControl(Item));
Continue;
end;
Key := Item.Hint;
if Key = '' then Continue;
Value := '';
Json := Data;
J := Key.IndexOf('_');
if J > 0 then begin
PKey := Key.Substring(0, J);
Json := Data.O[PKey];
if Json <> nil then begin
Key := Key.Substring(J + 1);
Value := Json.S[Key];
end;
end else
Value := Json.S[Key];
if Item is TEdit then
TEdit(Item).Text := Value
else if Item is TComboBox then
TComboBox(Item).Text := Value
else if Item is TMemo then
TMemo(Item).Text := Value
end;
end;
begin
ComboBox1.Items := Form1.bookGroupList.Items;
if Assigned(Data) then begin
FDisableChange := True;
try
CheckBox1.Checked := Data.enable;
CheckBox2.Checked := False;
CheckBox3.Checked := False;
if Data.bookSourceType = 1 then
CheckBox2.Checked := True;
if Data.bookSourceType = 2 then
CheckBox3.Checked := True;
Edit27.Text := IntToStr(Data.weight);
Edit28.Text := IntToStr(Data.customOrder);
SetEditValue(ScrollBox1);
finally
FDisableChange := False;
end;
end;
end;
end.

@ -0,0 +1,780 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = #38405#35835#20070#28304#25972#29702#24037#20855
ClientHeight = 362
ClientWidth = 1145
Color = 15921906
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Pitch = fpFixed
Font.Style = []
Menu = MainMenu1
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Splitter1: TSplitter
AlignWithMargins = True
Left = 313
Top = 0
Width = 4
Height = 331
Margins.Left = 0
Margins.Top = 0
Margins.Right = 0
Margins.Bottom = 0
Color = clSilver
ParentColor = False
ExplicitLeft = 257
ExplicitHeight = 697
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 313
Height = 331
Align = alLeft
BevelOuter = bvNone
Padding.Left = 4
Padding.Top = 4
Padding.Bottom = 4
TabOrder = 1
object SrcList: TListBox
AlignWithMargins = True
Left = 4
Top = 59
Width = 309
Height = 238
Hint = #23558#20070#28304#25991#20214#25302#20837#27492#22788
Margins.Left = 0
Margins.Top = 2
Margins.Right = 0
Margins.Bottom = 0
Style = lbVirtual
Align = alClient
BorderStyle = bsNone
DoubleBuffered = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = #23435#20307
Font.Pitch = fpFixed
Font.Style = []
ItemHeight = 18
MultiSelect = True
ParentDoubleBuffered = False
ParentFont = False
ParentShowHint = False
PopupMenu = PopupMenu1
ShowHint = True
TabOrder = 0
OnClick = SrcListClick
OnData = SrcListData
OnDblClick = SrcListDblClick
OnKeyDown = SrcListKeyDown
end
object Panel4: TPanel
Left = 4
Top = 4
Width = 309
Height = 53
Align = alTop
BevelOuter = bvNone
DoubleBuffered = True
ParentDoubleBuffered = False
TabOrder = 1
DesignSize = (
309
53)
object lbCount: TLabel
Left = 0
Top = 7
Width = 60
Height = 13
Caption = #20070#28304#21015#34920#65306
Transparent = False
end
object bookGroupList: TComboBox
Left = 80
Top = 3
Width = 223
Height = 21
Anchors = [akLeft, akTop, akRight]
DropDownCount = 24
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Pitch = fpFixed
Font.Style = []
ParentFont = False
TabOrder = 0
OnChange = bookGroupListChange
OnClick = bookGroupListChange
end
object RadioButton1: TRadioButton
Left = 3
Top = 30
Width = 57
Height = 17
Caption = #20840#37096
Checked = True
TabOrder = 1
TabStop = True
OnClick = RadioButton1Click
end
object RadioButton2: TRadioButton
Left = 59
Top = 30
Width = 57
Height = 17
Caption = #25991#26412
TabOrder = 2
OnClick = RadioButton2Click
end
object RadioButton3: TRadioButton
Left = 122
Top = 29
Width = 57
Height = 20
Caption = #38899#39057
TabOrder = 3
OnClick = RadioButton3Click
end
object RadioButton4: TRadioButton
Left = 182
Top = 29
Width = 57
Height = 20
Caption = #22270#28304
TabOrder = 4
OnClick = RadioButton4Click
end
end
object StaticText1: TStaticText
AlignWithMargins = True
Left = 7
Top = 87
Width = 303
Height = 207
Margins.Top = 30
Align = alClient
Alignment = taCenter
Caption = #40736#26631#25302#20837#20070#28304#25991#20214#21040#27492#22788
Color = clWindow
Font.Charset = DEFAULT_CHARSET
Font.Color = 6736896
Font.Height = -16
Font.Name = #24494#36719#38597#40657
Font.Pitch = fpFixed
Font.Style = []
ParentColor = False
ParentFont = False
PopupMenu = PopupMenu1
TabOrder = 2
Transparent = False
end
object Panel6: TPanel
Left = 4
Top = 297
Width = 309
Height = 30
Align = alBottom
BevelOuter = bvNone
Color = clWindow
ParentBackground = False
ShowCaption = False
TabOrder = 3
object Shape1: TShape
Left = 0
Top = 0
Width = 309
Height = 1
Align = alTop
Pen.Color = clSilver
end
object Button2: TButton
Left = 3
Top = 4
Width = 57
Height = 25
Caption = #32622#39030'(&T)'
TabOrder = 0
OnClick = Button2Click
end
object Button3: TButton
Left = 64
Top = 4
Width = 57
Height = 25
Caption = #19978#31227'(&U)'
TabOrder = 1
OnClick = Button3Click
end
object Button4: TButton
Left = 125
Top = 4
Width = 57
Height = 25
Caption = #19979#31227'(&N)'
TabOrder = 2
OnClick = Button4Click
end
object Button5: TButton
Left = 185
Top = 4
Width = 57
Height = 25
Caption = #32622#24213'(&B)'
TabOrder = 3
OnClick = Button5Click
end
end
end
object Panel2: TPanel
Left = 317
Top = 0
Width = 828
Height = 331
Align = alClient
BevelOuter = bvNone
ParentBackground = False
ParentColor = True
TabOrder = 0
object Splitter2: TSplitter
Left = 0
Top = 186
Width = 828
Height = 4
Cursor = crVSplit
Align = alBottom
Color = clSilver
ParentColor = False
ExplicitTop = 373
end
object Panel3: TPanel
Left = 0
Top = 0
Width = 828
Height = 36
Align = alTop
BevelOuter = bvNone
TabOrder = 1
object Label1: TLabel
Left = 144
Top = 10
Width = 64
Height = 13
Caption = #24037#20316#32447#31243#25968':'
Transparent = False
end
object Button1: TButton
Left = 6
Top = 6
Width = 128
Height = 24
Caption = #24320#22987#22788#29702'(&B)'
TabOrder = 0
OnClick = Button1Click
end
object Edit1: TEdit
Left = 212
Top = 7
Width = 35
Height = 21
Alignment = taCenter
NumbersOnly = True
TabOrder = 1
Text = '60'
end
object CheckBox1: TCheckBox
Left = 264
Top = 9
Width = 97
Height = 17
Caption = #21435#38500#37325#22797
Checked = True
State = cbChecked
TabOrder = 2
end
object CheckBox3: TCheckBox
Left = 344
Top = 9
Width = 97
Height = 17
Hint = #21435#37325#26102#19981#26816#27979#20070#28304#21517#31216#21644#20998#32452
Caption = #30495#23454#21435#37325
Checked = True
State = cbChecked
TabOrder = 4
end
object CheckBox2: TCheckBox
Left = 429
Top = 9
Width = 97
Height = 17
Caption = #26657#39564#20070#28304
TabOrder = 3
end
object CheckBox4: TCheckBox
Left = 517
Top = 9
Width = 97
Height = 17
Hint = #33258#21160#32473#20070#28304#28155#21152#25110#21024#38500#21457#29616#20998#32452#26631#35782
Caption = #33258#21160#21457#29616
Checked = True
ParentShowHint = False
ShowHint = True
State = cbChecked
TabOrder = 5
end
object CheckBox5: TCheckBox
Left = 605
Top = 9
Width = 116
Height = 17
Hint = #36873#20013#26102#22788#29702#25152#26377#20070#28304'('#21253#25324#34987#36807#28388#25481#30340#20070#28304'),'#19981#36873#20013#21482#22788#29702#24403#21069#36807#28388#21518#30340#20070#28304
Caption = #22788#29702#25152#26377#20070#28304
Checked = True
ParentShowHint = False
ShowHint = True
State = cbChecked
TabOrder = 6
end
object CheckBox6: TCheckBox
Left = 711
Top = 9
Width = 97
Height = 17
Hint = #33258#21160#32473#20070#28304#35780#20998'('#19981#21246#36873#26102#25209#37327#26657#39564#20070#28304#19981#26657#39564#21457#29616')'
Caption = #33258#21160#35780#20998
Checked = True
ParentShowHint = False
ShowHint = True
State = cbChecked
TabOrder = 7
end
end
object EditData: TSynMemo
Left = 0
Top = 36
Width = 828
Height = 150
Align = alClient
Ctl3D = True
ParentCtl3D = False
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
PopupMenu = PopupMenu2
TabOrder = 0
CodeFolding.GutterShapeSize = 11
CodeFolding.CollapsedLineColor = clGrayText
CodeFolding.FolderBarLinesColor = clGrayText
CodeFolding.IndentGuidesColor = clGray
CodeFolding.IndentGuides = True
CodeFolding.ShowCollapsedLine = False
CodeFolding.ShowHintMark = True
UseCodeFolding = False
BorderStyle = bsNone
Gutter.AutoSize = True
Gutter.BorderStyle = gbsNone
Gutter.Color = cl3DLight
Gutter.BorderColor = clWindowFrame
Gutter.Font.Charset = DEFAULT_CHARSET
Gutter.Font.Color = clWindowText
Gutter.Font.Height = -11
Gutter.Font.Name = 'Courier New'
Gutter.Font.Style = []
Gutter.ShowLineNumbers = True
Highlighter = SynJSONSyn1
WordWrap = True
OnChange = EditDataChange
FontSmoothing = fsmNone
end
object Panel5: TPanel
Left = 0
Top = 190
Width = 828
Height = 141
Align = alBottom
BevelOuter = bvNone
TabOrder = 2
DesignSize = (
828
141)
object Label2: TLabel
Left = 6
Top = 2
Width = 36
Height = 13
Caption = #26085#24535#65306
Transparent = False
end
object SpeedButton1: TSpeedButton
Left = 783
Top = 0
Width = 43
Height = 20
Anchors = [akTop, akRight]
Caption = #28165#31354
Flat = True
Font.Charset = DEFAULT_CHARSET
Font.Color = clTeal
Font.Height = -11
Font.Name = 'Tahoma'
Font.Pitch = fpFixed
Font.Style = []
ParentFont = False
OnClick = SpeedButton1Click
end
object edtLog: TSynMemo
AlignWithMargins = True
Left = 0
Top = 20
Width = 828
Height = 121
Margins.Left = 0
Margins.Top = 20
Margins.Right = 0
Margins.Bottom = 0
Align = alClient
Ctl3D = False
ParentCtl3D = False
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Courier New'
Font.Style = []
TabOrder = 0
CodeFolding.GutterShapeSize = 11
CodeFolding.CollapsedLineColor = clGrayText
CodeFolding.FolderBarLinesColor = clGrayText
CodeFolding.IndentGuidesColor = clGray
CodeFolding.IndentGuides = False
CodeFolding.ShowCollapsedLine = False
CodeFolding.ShowHintMark = True
UseCodeFolding = False
BookMarkOptions.EnableKeys = False
BookMarkOptions.GlyphsVisible = False
BorderStyle = bsNone
Gutter.AutoSize = True
Gutter.BorderStyle = gbsNone
Gutter.Color = cl3DLight
Gutter.BorderColor = clWindowFrame
Gutter.Font.Charset = DEFAULT_CHARSET
Gutter.Font.Color = clWindowText
Gutter.Font.Height = -11
Gutter.Font.Name = 'Courier New'
Gutter.Font.Style = []
Gutter.ShowLineNumbers = True
Gutter.Visible = False
Gutter.Width = 0
Options = [eoScrollPastEol, eoShowScrollHint, eoSmartTabDelete, eoSmartTabs, eoTabsToSpaces]
ReadOnly = True
RightEdge = 0
WordWrap = True
OnChange = EditDataChange
FontSmoothing = fsmClearType
end
end
end
object StatusBar1: TStatusBar
Left = 0
Top = 337
Width = 1145
Height = 25
Panels = <
item
Width = 500
end
item
Width = 50
end>
end
object ProgressBar1: TProgressBar
Left = 0
Top = 331
Width = 1145
Height = 6
Align = alBottom
Position = 100
TabOrder = 3
Visible = False
end
object PopupMenu1: TPopupMenu
OnPopup = PopupMenu1Popup
Left = 136
Top = 192
object C3: TMenuItem
Caption = #22797#21046#26032#22686'(&A)'
OnClick = C3Click
end
object N7: TMenuItem
Caption = #26032#24314#20070#28304'(&N)...'
OnClick = N7Click
end
object E1: TMenuItem
Caption = #32534#36753#20070#28304'(&E)...'
OnClick = E1Click
end
object N18: TMenuItem
Caption = #23548#20986#36873#20013#20070#28304'...'
OnClick = N18Click
end
object N5: TMenuItem
Caption = '-'
end
object S2: TMenuItem
Caption = #25490#24207' - '#20070#28304#21517#31216'(&S)'
OnClick = S2Click
end
object G1: TMenuItem
Caption = #25490#24207' - '#20998#32452'(&G)'
OnClick = G1Click
end
object W3: TMenuItem
Caption = #25490#24207' - '#26435#37325'(&W)'
OnClick = W3Click
end
object O2: TMenuItem
Caption = #25490#24207' - '#35780#20998'(&O)'
OnClick = O2Click
end
object N9: TMenuItem
Caption = '-'
end
object F2: TMenuItem
Caption = #26597#25214#20070#28304'(&F)...'
ShortCut = 16454
OnClick = F2Click
end
object N14: TMenuItem
Caption = #26597#25214#19979#19968#20010
ShortCut = 114
OnClick = N14Click
end
object B1: TMenuItem
Caption = #20070#28304#21517#31216#26367#25442'(&B)...'
OnClick = B1Click
end
object B2: TMenuItem
Caption = #20070#28304'URL'#26367#25442'(&U)...'
OnClick = B2Click
end
object H2: TMenuItem
Caption = #20998#32452#21517#31216#26367#25442'(&H)...'
OnClick = H2Click
end
object N16: TMenuItem
Caption = '-'
end
object N15: TMenuItem
Caption = #25209#37327#28155#21152#20998#32452#21517#31216'...'
OnClick = N15Click
end
object N17: TMenuItem
Caption = #25209#37327#21024#38500#20998#32452#21517#31216'...'
OnClick = N17Click
end
object N6: TMenuItem
Caption = '-'
end
object C4: TMenuItem
Caption = #22797#21046#20070#28304'(&C)'
ShortCut = 16451
OnClick = C4Click
end
object X2: TMenuItem
Caption = #21098#20999#20070#28304'(&X)'
ShortCut = 16472
OnClick = X2Click
end
object P2: TMenuItem
Caption = #31896#36148#20070#28304'(&P)'
ShortCut = 16470
OnClick = P2Click
end
object D1: TMenuItem
Caption = #21024#38500#20070#28304'(&D)'
OnClick = D1Click
end
object N13: TMenuItem
Caption = '-'
end
object C1: TMenuItem
Caption = #28165#31354'(&L)'
OnClick = C1Click
end
end
object SynJSONSyn1: TSynJSONSyn
Options.AutoDetectEnabled = False
Options.AutoDetectLineLimit = 0
Options.Visible = False
Left = 552
Top = 352
end
object PopupMenu2: TPopupMenu
OnPopup = PopupMenu2Popup
Left = 632
Top = 352
object S1: TMenuItem
Caption = #20445#23384#20462#25913'(&S)'
ShortCut = 16467
OnClick = S1Click
end
object T1: TMenuItem
Caption = #27979#35797#20070#28304'(&T)'
OnClick = T1Click
end
object N3: TMenuItem
Caption = '-'
end
object U1: TMenuItem
Caption = #26356#26032#26102#38388#25139'(&U)'
OnClick = U1Click
end
object N20: TMenuItem
Caption = '-'
end
object R1: TMenuItem
Caption = #25764#28040'(&R)'
OnClick = R1Click
end
object Z1: TMenuItem
Caption = #37325#20570'(&Z)'
OnClick = Z1Click
end
object N1: TMenuItem
Caption = '-'
end
object C2: TMenuItem
Caption = #22797#21046'(&C)'
OnClick = C2Click
end
object X1: TMenuItem
Caption = #21098#20999'(&X)'
OnClick = X1Click
end
object P1: TMenuItem
Caption = #31896#36148'(&P)'
OnClick = P1Click
end
object N2: TMenuItem
Caption = '-'
end
object A1: TMenuItem
Caption = #20840#36873'(&A)'
OnClick = A1Click
end
object N4: TMenuItem
Caption = '-'
end
object W1: TMenuItem
Caption = #33258#21160#25442#34892'(&W)'
OnClick = W1Click
end
end
object Timer1: TTimer
Interval = 100
OnTimer = Timer1Timer
Left = 464
Top = 440
end
object MainMenu1: TMainMenu
Left = 448
Top = 136
object F1: TMenuItem
Caption = #25991#20214'(&F)'
object O1: TMenuItem
Caption = #25171#24320#20070#28304#25991#20214'(&O)...'
OnClick = O1Click
end
object A2: TMenuItem
Caption = #28155#21152#20070#28304#25991#20214'(&A)...'
OnClick = A2Click
end
object N12: TMenuItem
Caption = '-'
end
object N11: TMenuItem
Caption = #26032#24314#20070#28304'(&N)...'
OnClick = N7Click
end
object N10: TMenuItem
Caption = '-'
end
object E2: TMenuItem
Caption = #23548#20986#20070#28304#25991#20214'(&E)...'
OnClick = E2Click
end
object S3: TMenuItem
Caption = #23548#20986#36873#20013#20070#28304#21040#25991#20214'(&S)...'
OnClick = S3Click
end
end
object E3: TMenuItem
Caption = #32534#36753'(&E)'
object B3: TMenuItem
Caption = #20070#28304#21517#31216#26367#25442'(&B)...'
OnClick = B1Click
end
object URLU1: TMenuItem
Caption = #20070#28304'URL'#26367#25442'(&U)...'
OnClick = B2Click
end
object H3: TMenuItem
Caption = #20998#32452#21517#31216#26367#25442'(&H)...'
OnClick = H2Click
end
object N19: TMenuItem
Caption = '-'
end
object URL1: TMenuItem
Caption = #26597#25214#20070#28304': '#25628#32034#20070#28304'URL'
Checked = True
OnClick = URL1Click
end
end
object H1: TMenuItem
Caption = #24110#21161'(&H)'
object I1: TMenuItem
Caption = #20851#20110'(&I)'
OnClick = I1Click
end
object N8: TMenuItem
Caption = '-'
end
object W2: TMenuItem
Caption = #20316#32773#21338#23458'(&W)'
OnClick = W2Click
end
object R2: TMenuItem
Caption = #23567#35828#38405#35835#22120'(&R)'
OnClick = R2Click
end
end
end
object SaveDialog1: TSaveDialog
Filter = #20070#28304#25991#20214'(*.json)|*.json|'#25152#26377#25991#20214'(*.*)|*.*'
Options = [ofHideReadOnly, ofPathMustExist, ofNoReadOnlyReturn, ofEnableSizing]
Title = #23548#20986#20070#28304
Left = 472
Top = 352
end
object OpenDialog1: TOpenDialog
Filter = #20070#28304#25991#20214'(*.json)|*.json|'#25152#26377#25991#20214'(*.*)|*.*'
Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing]
Left = 544
Top = 280
end
end

File diff suppressed because it is too large Load Diff

@ -0,0 +1,80 @@
object frmReplaceGroup: TfrmReplaceGroup
Left = 0
Top = 0
BorderStyle = bsDialog
ClientHeight = 166
ClientWidth = 345
Color = clWindow
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poMainFormCenter
DesignSize = (
345
166)
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 24
Top = 16
Width = 60
Height = 13
Caption = #26597#25214#20869#23481#65306
end
object Label2: TLabel
Left = 24
Top = 63
Width = 60
Height = 13
Caption = #26367#25442#20869#23481#65306
end
object Edit1: TEdit
Left = 24
Top = 35
Width = 289
Height = 21
TabOrder = 0
end
object Edit2: TEdit
Left = 24
Top = 82
Width = 289
Height = 21
TabOrder = 1
end
object CheckBox1: TCheckBox
Left = 24
Top = 128
Width = 97
Height = 17
Caption = #20840#23383#21305#37197
Checked = True
State = cbChecked
TabOrder = 2
end
object Button1: TButton
Left = 239
Top = 125
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = #30830#23450'(&O)'
Default = True
TabOrder = 3
OnClick = Button1Click
end
object Button2: TButton
Left = 151
Top = 125
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Cancel = True
Caption = #21462#28040'(&C)'
ModalResult = 2
TabOrder = 4
end
end

@ -0,0 +1,62 @@
unit uFrmReplaceGroup;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TfrmReplaceGroup = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
CheckBox1: TCheckBox;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmReplaceGroup: TfrmReplaceGroup;
function ShowReplaceGroup(Sender: TComponent; const Title: string; var FindStr, NewStr: string; var Flag: Integer): Boolean;
implementation
{$R *.dfm}
function ShowReplaceGroup(Sender: TComponent; const Title: string; var FindStr, NewStr: string; var Flag: Integer): Boolean;
var
F: TfrmReplaceGroup;
begin
F := TfrmReplaceGroup.Create(Sender);
try
F.Caption := Title;
F.CheckBox1.Enabled := Flag = 0;
Result := F.ShowModal = mrOk;
if Result then begin
FindStr := Trim(F.Edit1.Text);
NewStr := Trim(F.Edit2.Text);
Flag := Ord(F.CheckBox1.Checked);
end;
finally
F.Free;
end;
end;
procedure TfrmReplaceGroup.Button1Click(Sender: TObject);
begin
// if Trim(Edit1.Text) = '' then begin
// ShowMessage('ÇëÊäÈëÒª²éÕÒµÄÄÚÈÝ');
// Exit;
// end;
ModalResult := mrOk;
end;
end.

@ -0,0 +1,62 @@
object Form2: TForm2
Left = 0
Top = 0
BorderStyle = bsNone
BorderWidth = 1
Caption = 'Form2'
ClientHeight = 173
ClientWidth = 251
Color = clSilver
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poOwnerFormCenter
OnClose = FormClose
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 251
Height = 173
Align = alClient
BevelOuter = bvNone
Color = clWindow
ParentBackground = False
TabOrder = 0
object Label1: TLabel
Left = 73
Top = 88
Width = 103
Height = 13
Alignment = taCenter
Caption = #27491#22312#22788#29702', '#35831#31561#24453'...'
end
object ActivityIndicator1: TActivityIndicator
AlignWithMargins = True
Left = 112
Top = 32
Animate = True
end
object Button1: TButton
Left = 71
Top = 120
Width = 106
Height = 25
Cancel = True
Caption = #21462#28040'(&C)'
TabOrder = 1
OnClick = Button1Click
end
end
object Timer1: TTimer
Enabled = False
Interval = 100
OnTimer = Timer1Timer
Left = 184
Top = 56
end
end

@ -0,0 +1,77 @@
unit uFrmWait;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.WinXCtrls,
Vcl.ExtCtrls;
type
TForm2 = class(TForm)
Panel1: TPanel;
ActivityIndicator1: TActivityIndicator;
Label1: TLabel;
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
procedure ShowWaitDlg();
procedure HideWaitDlg();
implementation
{$R *.dfm}
uses
uFrmMain;
var
fWait: TForm2;
procedure ShowWaitDlg();
begin
if Assigned(fWait) then
Exit;
fWait := TForm2.Create(Application);
fWait.ShowModal;
end;
procedure HideWaitDlg();
begin
if Assigned(fWait) then
fWait.Timer1.Enabled := True;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
if Form1.Button1.Tag <> 0 then begin
Timer1.Enabled := True;
Form1.Button1Click(Button1);
end;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
fWait := nil;
Action := caFree;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
if Form1.Button1.Tag = 0 then begin
ModalResult := mrCancel;
end;
end;
end.
Loading…
Cancel
Save