@@ -8,6 +8,7 @@ import { onOpenFile } from "@/core/service/GlobalMenu";
88import { ReferenceBlockNode } from "../../stageObject/entity/ReferenceBlockNode" ;
99import { RectangleLittleNoteEffect } from "@/core/service/feedbackService/effectEngine/concrete/RectangleLittleNoteEffect" ;
1010import { SectionReferencePanel } from "@/sub/ReferencesWindow" ;
11+ import { loadAllServicesBeforeInit } from "@/core/loadAllServices" ;
1112
1213interface parserResult {
1314 /**
@@ -32,6 +33,12 @@ interface parserResult {
3233export class ReferenceManager {
3334 constructor ( private readonly project : Project ) { }
3435
36+ /**
37+ * 保险检查函数
38+ * 解析用户在文本节点中输入的引用格式文本,防止直接退出编辑模式后触发转换,导致引用块内容被错误解析
39+ * @param text 引用块文本
40+ * @returns
41+ */
3542 public static referenceBlockTextParser ( text : string ) : parserResult {
3643 if ( ! text . startsWith ( "[[" ) || ! text . endsWith ( "]]" ) ) {
3744 return {
@@ -103,6 +110,136 @@ export class ReferenceManager {
103110 }
104111 }
105112
113+ /**
114+ * 更新当前项目的引用信息
115+ * (清理无效的引用)
116+ */
117+ public async updateCurrentProjectReference ( ) {
118+ const recentFiles = await RecentFileManager . getRecentFiles ( ) ;
119+
120+ // 遍历当前项目的每一个被引用的Section框
121+ for ( const sectionName in this . project . references . sections ) {
122+ const fileNameList = this . project . references . sections [ sectionName ] ;
123+ const fileNameListNew = [ ] ;
124+ for ( const fileName of fileNameList ) {
125+ const file = recentFiles . find (
126+ ( file ) =>
127+ PathString . getFileNameFromPath ( file . uri . path ) === fileName ||
128+ PathString . getFileNameFromPath ( file . uri . fsPath ) === fileName ,
129+ ) ;
130+ if ( file ) {
131+ // 即使文件存在,也要打开看一看引用块是否在那个文件中。
132+ const thatProject = new Project ( file . uri ) ;
133+ loadAllServicesBeforeInit ( thatProject ) ;
134+ await thatProject . init ( ) ;
135+ if ( this . checkReferenceBlockInProject ( thatProject , fileName , sectionName ) ) {
136+ fileNameListNew . push ( fileName ) ;
137+ }
138+ thatProject . dispose ( ) ;
139+ }
140+ }
141+ if ( fileNameListNew . length === 0 ) {
142+ // 直接把这个章节从引用列表中删除
143+ delete this . project . references . sections [ sectionName ] ;
144+ } else {
145+ this . project . references . sections [ sectionName ] = fileNameListNew ;
146+ }
147+ }
148+
149+ // 遍历每一个直接引用自己整个文件的文件
150+ const fileNameListNew = [ ] ;
151+ for ( const fileName of this . project . references . files ) {
152+ const file = recentFiles . find (
153+ ( file ) =>
154+ PathString . getFileNameFromPath ( file . uri . path ) === fileName ||
155+ PathString . getFileNameFromPath ( file . uri . fsPath ) === fileName ,
156+ ) ;
157+ if ( file ) {
158+ // 即使文件存在,也要打开看一看引用块是否在那个文件中。
159+ const thatProject = new Project ( file . uri ) ;
160+ loadAllServicesBeforeInit ( thatProject ) ;
161+ await thatProject . init ( ) ;
162+ if ( this . checkReferenceBlockInProject ( thatProject , fileName , "" ) ) {
163+ fileNameListNew . push ( fileName ) ;
164+ }
165+ thatProject . dispose ( ) ;
166+ }
167+ }
168+ this . project . references . files = fileNameListNew ;
169+ }
170+
171+ public checkReferenceBlockInProject ( project : Project , fileName : string , sectionName : string ) {
172+ const referenceBlocks = project . stage
173+ . filter ( ( object ) => object instanceof ReferenceBlockNode )
174+ . filter (
175+ ( referenceBlockNode ) =>
176+ referenceBlockNode . fileName === fileName && referenceBlockNode . sectionName === sectionName ,
177+ ) ;
178+ if ( referenceBlocks . length > 0 ) {
179+ return true ;
180+ }
181+ return false ;
182+ }
183+
184+ public async insertRefDataToSourcePrgFile ( fileName : string , sectionName : string ) {
185+ // 更新被引用文件的reference.msgpack
186+ const currentFileName = PathString . getFileNameFromPath ( this . project . uri . path ) ;
187+ if ( ! currentFileName ) return ;
188+
189+ try {
190+ // 根据文件名查找被引用文件
191+ const recentFiles = await RecentFileManager . getRecentFiles ( ) ;
192+ const referencedFile = recentFiles . find (
193+ ( file ) =>
194+ PathString . getFileNameFromPath ( file . uri . path ) === fileName ||
195+ PathString . getFileNameFromPath ( file . uri . fsPath ) === fileName ,
196+ ) ;
197+ if ( ! referencedFile ) return ;
198+
199+ // 创建被引用文件的Project实例
200+ const referencedProject = new Project ( referencedFile . uri ) ;
201+
202+ // 初始化项目
203+ loadAllServicesBeforeInit ( referencedProject ) ;
204+ await referencedProject . init ( ) ;
205+
206+ // 更新引用
207+ if ( sectionName ) {
208+ // 引用特定Section的情况
209+ if ( ! referencedProject . references . sections [ sectionName ] ) {
210+ referencedProject . references . sections [ sectionName ] = [ ] ;
211+ }
212+
213+ // 确保数组中没有重复的文件名
214+ const index = referencedProject . references . sections [ sectionName ] . indexOf ( currentFileName ) ;
215+ if ( index === - 1 ) {
216+ referencedProject . references . sections [ sectionName ] . push ( currentFileName ) ;
217+ // 保存更新
218+ await referencedProject . save ( ) ;
219+ }
220+ } else {
221+ // 引用整个文件的情况
222+ if ( ! referencedProject . references . files ) {
223+ referencedProject . references . files = [ ] ;
224+ }
225+
226+ // 确保数组中没有重复的文件名
227+ const index = referencedProject . references . files . indexOf ( currentFileName ) ;
228+ if ( index === - 1 ) {
229+ referencedProject . references . files . push ( currentFileName ) ;
230+ // 保存更新
231+ await referencedProject . save ( ) ;
232+ }
233+ }
234+
235+ // 关闭项目
236+ await referencedProject . dispose ( ) ;
237+ // TODO: 存在隐患,欠考虑如果引用已经被当前软件打开的情况。
238+ } catch ( error ) {
239+ toast . error ( "更新reference.msgpack失败:" + String ( error ) ) ;
240+ }
241+ }
242+
106243 /**
107244 * 从源头 跳转到引用位置
108245 * @param section
0 commit comments