source: dev/trunk/ab5.0/abdev/abdev/ClassTree.cpp@ 481

Last change on this file since 481 was 475, checked in by dai_9181, 16 years ago

構成管理を変更中・・・(いったんコミット)

File size: 14.3 KB
Line 
1#include "stdafx.h"
2
3#include "Common.h"
4
5#if defined(JPN)
6//日本語
7#include "pj_msg_jpn.h"
8#else
9//英語
10#include "pj_msg_eng.h"
11#endif
12
13
14CClassTreeView *pobj_ClassTreeView;
15
16BOOL bSearchingClasses,bRetrySearchingClasses;
17
18
19int CClassTreeView::hash_default(LONG_PTR lpdata){
20 return lpdata%MAX_HASH;
21}
22void CClassTreeView::AddValidItem(HTREEITEM hItem,int iFileNum){
23 //ハッシュ値を取得
24 int key;
25 key=hash_default((LONG_PTR)hItem);
26
27 //格納位置を取得
28 TREEHASH *pth;
29 pth=&tree_data[key];
30 while(pth->hItem){
31 if(pth->hItem==hItem){
32 //既に存在するときは抜け出す
33 return;
34 }
35 if(pth->pNextData==0){
36 pth->pNextData=(TREEHASH *)HeapAlloc(hHeap,0,sizeof(TREEHASH));
37 pth=pth->pNextData;
38 break;
39 }
40 pth=pth->pNextData;
41 }
42
43 pth->hItem=hItem;
44 pth->iFileNum=iFileNum;
45 pth->pNextData=0;
46}
47
48BOOL CClassTreeView::delete_check(HTREEITEM hItem){
49 //ハッシュ値を取得
50 int key;
51 key=hash_default((LONG_PTR)hItem);
52
53 TREEHASH *pth;
54 pth=&tree_data[key];
55 while(pth->hItem){
56 if(pth->hItem==hItem) return 1;
57
58 if(pth->pNextData==0) break;
59 pth=pth->pNextData;
60 }
61 return 0;
62}
63
64void CClassTreeView::DeleteInvalidItems(HTREEITEM hItem){
65 HTREEITEM hChildItem;
66 while(hItem){
67 if(!delete_check(hItem)){
68 HTREEITEM hTemp;
69 hTemp=hItem;
70
71 hItem=TreeView_GetNextSibling(hTreeWnd,hItem);
72
73 TreeView_DeleteItem(hTreeWnd,hTemp);
74 continue;
75 }
76
77 hChildItem=TreeView_GetChild(hTreeWnd,hItem);
78 if(hChildItem){
79 DeleteInvalidItems(hChildItem);
80 }
81
82 hItem=TreeView_GetNextSibling(hTreeWnd,hItem);
83 }
84}
85
86void CClassTreeView::DeleteTreeHash(TREEHASH *pth){
87 if(pth->hItem && (iNowFile==-1 || iNowFile==pth->iFileNum)){
88 if(pth->pNextData){
89 DeleteTreeHash(pth->pNextData);
90 HeapDefaultFree(pth->pNextData);
91 pth->pNextData=0;
92 }
93 pth->hItem=0;
94 }
95}
96
97
98HTREEITEM CClassTreeView::insert(HTREEITEM hParentItem,int flag,char *lpszName,int iFileNum){
99 char temporary[255];
100
101 TVITEM tvItem;
102 tvItem.pszText=temporary;
103 tvItem.cchTextMax=255;
104 HTREEITEM hNextItem;
105 hNextItem=TreeView_GetChild(hTreeWnd,hParentItem);
106 while(hNextItem){
107 tvItem.mask=TVIF_HANDLE|TVIF_TEXT;
108 tvItem.hItem=hNextItem;
109 TreeView_GetItem(hTreeWnd,&tvItem);
110 if(lstrcmp(lpszName,tvItem.pszText)==0){
111 //既に挿入済みの場合
112 AddValidItem(hNextItem,iFileNum);
113 return hNextItem;
114 }
115
116 hNextItem=TreeView_GetNextSibling(hTreeWnd,hNextItem);
117 }
118
119
120 TV_INSERTSTRUCT tv;
121 tv.hInsertAfter=TVI_SORT;
122 tv.item.mask=TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIS_EXPANDED ;
123 tv.hParent=hParentItem;
124 tv.item.pszText=lpszName;
125
126 if(flag==CTV_ROOT){
127 tv.item.iImage=3;
128 tv.item.iSelectedImage=3;
129 }
130 if(flag==CTV_FOLDER){
131 tv.item.iImage=0;
132 tv.item.iSelectedImage=0;
133 }
134 else if(flag==CTV_GLOBAL_PROC){
135 tv.item.iImage=5;
136 tv.item.iSelectedImage=5;
137 }
138 else if(flag==CTV_CLASS){
139 tv.item.iImage=2;
140 tv.item.iSelectedImage=2;
141 }
142 else if(flag==CTV_PUBLIC_MEMBER){
143 tv.item.iImage=4;
144 tv.item.iSelectedImage=4;
145 }
146 else if(flag==CTV_PUBLIC_METHOD){
147 tv.item.iImage=5;
148 tv.item.iSelectedImage=5;
149 }
150 else if(flag==CTV_PRIVATE_MEMBER){
151 tv.item.iImage=6;
152 tv.item.iSelectedImage=6;
153 }
154 else if(flag==CTV_PRIVATE_METHOD){
155 tv.item.iImage=7;
156 tv.item.iSelectedImage=7;
157 }
158
159 hNextItem=TreeView_InsertItem(hTreeWnd,&tv);
160 AddValidItem(hNextItem,iFileNum);
161 return hNextItem;
162}
163
164
165
166CClassTreeView::CClassTreeView(){
167 memset(this,0,sizeof(CClassTreeView));
168}
169CClassTreeView::~CClassTreeView(){
170 while(bSearchingClasses) Sleep(10);
171
172 iNowFile=-1;
173
174 int i;
175 for(i=0;i<MAX_HASH;i++){
176 DeleteTreeHash(&tree_data[i]);
177 }
178
179 if(pobj_ClassTreeView->pProcInfo){
180 //プロシージャ情報のメモリを解放
181 for(i=0;i<pobj_ClassTreeView->NumberOfProcedures;i++){
182 HeapDefaultFree(pobj_ClassTreeView->pProcInfo[i].name);
183 }
184 HeapDefaultFree(pobj_ClassTreeView->pProcInfo);
185 pobj_ClassTreeView->pProcInfo=0;
186 }
187}
188void CClassTreeView::init(HWND hwnd,int iFileNum){
189 hTreeWnd=hwnd;
190
191 iNowFile=iFileNum;
192
193 int i;
194 for(i=0;i<MAX_HASH;i++){
195 DeleteTreeHash(&tree_data[i]);
196 }
197}
198
199void CClassTreeView::InsertRootFolder(void){
200 extern PROJECTINFO ProjectInfo;
201 char temporary[VN_SIZE];
202 sprintf(temporary,"%s クラス",ProjectInfo.name);
203 hRootFolder=insert(
204 TVI_ROOT,
205 CTV_ROOT,
206 temporary,-1);
207}
208void CClassTreeView::InsertGlobalProcedureFolder(void){
209 hGlobalProcedureFolder=insert(
210 hRootFolder,
211 CTV_FOLDER,
212 "グローバル関数",-1);
213}
214
215HTREEITEM CClassTreeView::InsertGlobalProcedure(int flag,char *lpszName,int iFileNum){
216 return pobj_ClassTreeView->insert(
217 hGlobalProcedureFolder,
218 CTV_GLOBAL_PROC,
219 lpszName,
220 iFileNum);
221}
222
223HTREEITEM CClassTreeView::insert_code_item(HTREEITEM hParentItem,int flag,char *lpszName,int iFileNum,char *pBuf,int p){
224 int i4;
225 i4=NumberOfProcedures;
226 pProcInfo=(PROCINFO *)HeapReAlloc(hHeap,0,pProcInfo,sizeof(PROCINFO)*(i4+1));
227 pProcInfo[i4].name=(char *)HeapAlloc(hHeap,0,lstrlen(lpszName)+1);
228 lstrcpy(pProcInfo[i4].name,lpszName);
229 pProcInfo[i4].FileNum=iFileNum;
230
231 //コード位置
232 pProcInfo[i4].code_pos=p;
233
234 //ツリーアイテムを挿入
235 HTREEITEM hTempItem;
236 hTempItem=insert(
237 hParentItem,
238 flag,
239 lpszName,
240 iFileNum);
241
242 pProcInfo[i4].hTreeItem=hTempItem;
243
244 NumberOfProcedures++;
245
246 return hTempItem;
247}
248
249void CClassTreeView::InsertClassFolder(char *lpszName,int iFileNum,char *pBuf,int p){
250 hNowClassFolder=insert_code_item(hRootFolder,CTV_CLASS,lpszName,iFileNum,pBuf,p);
251}
252void CClassTreeView::InsertClassMember(int flag,char *lpszName,int iFileNum,char *pBuf,int p){
253 insert_code_item(hNowClassFolder,flag,lpszName,iFileNum,pBuf,p);
254}
255
256void CClassTreeView::finish(){
257 DeleteInvalidItems(TreeView_GetRoot(hTreeWnd));
258}
259
260
261void AnalysisClass(char *pBuf,int *p,int iFileNum){
262 int i2;
263 i2=*p;
264
265
266 CClassInfo *pobj_ClassInfo;
267 pobj_ClassInfo=new CClassInfo();
268
269 pobj_ClassInfo->Analyze(pBuf,p);
270
271
272 //クラスフォルダを挿入
273 pobj_ClassTreeView->InsertClassFolder(
274 pobj_ClassInfo->ClassName,
275 iFileNum,
276 pBuf,
277 i2);
278
279
280
281 ///////////////////////////////
282 // メンバ及びメソッドを挿入
283 ///////////////////////////////
284
285 int i;
286 for(i=0;i<pobj_ClassInfo->MemberNum;i++){
287 int flag;
288 if(pobj_ClassInfo->pMemberInfo[i].dwProc==0){
289 //メンバ変数
290 if(pobj_ClassInfo->pMemberInfo[i].dwAccess==ACCESS_PUBLIC){
291 //公開
292 flag=CTV_PUBLIC_MEMBER;
293 }
294 else{
295 //非公開
296 flag=CTV_PRIVATE_MEMBER;
297 }
298 }
299 else{
300 //メソッド
301 if(pobj_ClassInfo->pMemberInfo[i].dwAccess==ACCESS_PUBLIC){
302 //公開
303 flag=CTV_PUBLIC_METHOD;
304 }
305 else{
306 //非公開
307 flag=CTV_PRIVATE_METHOD;
308 }
309 }
310 pobj_ClassTreeView->InsertClassMember(flag,pobj_ClassInfo->pMemberInfo[i].pName,iFileNum,pBuf,pobj_ClassInfo->pMemberInfo[i].code_pos);
311 }
312
313
314 delete pobj_ClassInfo;
315 pobj_ClassInfo=0;
316}
317
318
319void SetClassTreeFromOneFile_Buf( char *pBuf, int iFileNum ){
320 int i2,i3,i4;
321 char temporary[GENERAL_SIZE];
322
323 for(i2=0;;i2++){
324 if(pBuf[i2]=='\0') break;
325 while(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'&&pBuf[i2+2]=='\r'&&pBuf[i2+3]=='\n') i2+=2;
326 if(i2==0||(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){
327 if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n') i2+=2;
328 while(pBuf[i2]>='0'&&pBuf[i2]<='9') i2++;
329 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
330
331 i4=i2;
332 for(i3=0;;i2++,i3++){
333 if(!IsVariableChar(pBuf[i2])){
334 temporary[i3]=0;
335 break;
336 }
337 temporary[i3]=pBuf[i2];
338 }
339 if(pBuf[i2]=='\0') break;
340
341 if(lstrcmpi(temporary,"Class")==0||
342 lstrcmpi(temporary,"Type")==0||
343 lstrcmpi(temporary,"Interface")==0){
344
345 /////////////////////////////
346 // クラスの解析
347 /////////////////////////////
348 AnalysisClass(pBuf,&i4,iFileNum);
349
350 i2=i4-1;
351 continue;
352 }
353
354 int sw;
355 if(lstrcmpi(temporary,"Sub")==0) sw=1;
356 else if(lstrcmpi(temporary,"Function")==0) sw=2;
357 else sw=0;
358
359 if(sw){
360 //Sub/Function
361 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
362 for(i3=0;;i2++,i3++){
363 if(!IsVariableChar(pBuf[i2])){
364 temporary[i3]=0;
365 break;
366 }
367 temporary[i3]=pBuf[i2];
368 }
369
370 if(lstrcmpi(temporary,"Export")==0){
371 //Export修飾子はとばす
372 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
373
374 for(i3=0;;i2++,i3++){
375 if(!IsVariableChar(pBuf[i2])){
376 temporary[i3]=0;
377 break;
378 }
379 temporary[i3]=pBuf[i2];
380 }
381 }
382
383 i4=pobj_ClassTreeView->NumberOfProcedures;
384 pobj_ClassTreeView->pProcInfo=(PROCINFO *)HeapReAlloc(hHeap,0,pobj_ClassTreeView->pProcInfo,sizeof(PROCINFO)*(i4+1));
385 pobj_ClassTreeView->pProcInfo[i4].name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
386 lstrcpy(pobj_ClassTreeView->pProcInfo[i4].name,temporary);
387 pobj_ClassTreeView->pProcInfo[i4].FileNum=iFileNum;
388
389 //定義行の選択範囲
390 pobj_ClassTreeView->pProcInfo[i4].code_pos=i2;
391
392 //パラメータ部
393 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
394 if(pBuf[i2]=='('){
395 int IsStr,PareNum;
396 for(i2++,i3=0,IsStr=0,PareNum=0;;i2++,i3++){
397 if(pBuf[i2]=='\"') IsStr^=1;
398 if(pBuf[i2]=='('&&IsStr==0) PareNum++;
399 if(pBuf[i2]==')'&&IsStr==0){
400 PareNum--;
401 if(PareNum<0){
402 temporary[i3]=0;
403 break;
404 }
405 }
406 if(pBuf[i2]=='\0') break;
407 temporary[i3]=pBuf[i2];
408 }
409 //temporaryはパラメータの内容が格納されるが、不要
410 }
411
412 for(;;i2++){
413 if(IsCommandDelimitation(pBuf,i2)){
414 break;
415 }
416 if((pBuf[i2]=='a'||pBuf[i2]=='A')&&(pBuf[i2+1]=='s'||pBuf[i2+1]=='S')&&(pBuf[i2+2]==' '||pBuf[i2+2]=='\t')){
417 i2+=3;
418 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
419 for(i3=0;;i2++,i3++){
420 if(!IsVariableChar(pBuf[i2])){
421 temporary[i3]=0;
422 break;
423 }
424 temporary[i3]=pBuf[i2];
425 }
426 //temporaryには型情報が格納されるが、不要
427 break;
428 }
429 }
430
431 //ツリーアイテムを挿入
432 HTREEITEM hTempItem;
433 hTempItem=pobj_ClassTreeView->InsertGlobalProcedure(
434 CTV_GLOBAL_PROC,
435 pobj_ClassTreeView->pProcInfo[i4].name,
436 iFileNum);
437 pobj_ClassTreeView->pProcInfo[i4].hTreeItem=hTempItem;
438
439 pobj_ClassTreeView->NumberOfProcedures++;
440
441 i2--;
442 }
443 }
444 }
445}
446void SetClassTreeFromOneFile(char *lpszFilePath,int iFileNum){
447 extern MDIINFO MdiInfo[MAX_WNDNUM];
448 int WndNum;
449 HWND hChild=GetWindow(hClient,GW_CHILD);
450 while(hChild){
451 WndNum=GetWndNum(hChild);
452 if(IS_DOCUMENT_TEXT(MdiInfo[WndNum].DocType)){
453 if(lstrcmpi(MdiInfo[WndNum].path,lpszFilePath)==0) break;
454 }
455 hChild=GetNextWindow(hChild,GW_HWNDNEXT);
456 }
457
458 char *pBuf;
459 if(hChild){
460 //すでに指定されたファイルが開かれている場合
461 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
462 }
463 else{
464 //開かれていない場合
465 pBuf=ReadBuffer(lpszFilePath);
466 if(!pBuf) pBuf=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);
467 }
468
469 SetClassTreeFromOneFile_Buf( pBuf, iFileNum );
470
471 if(!hChild) HeapDefaultFree(pBuf);
472}
473
474void SetProcedureTreeData(void *temp_iFileNum){
475 int i;
476 char temporary[MAX_PATH];
477 BOOL bExpand;
478 TVITEM tvItem;
479 SCROLLINFO si;
480
481 int iFileNum;
482 iFileNum=(int)temp_iFileNum;
483
484 if(bSearchingClasses){
485 bRetrySearchingClasses=1;
486 _endthread();
487 return;
488 }
489 bSearchingClasses=1;
490
491 if(pobj_ClassTreeView->pProcInfo){
492wait_repeat:
493 Sleep(700);
494 if(bRetrySearchingClasses){
495 bRetrySearchingClasses=0;
496 goto wait_repeat;
497 }
498
499 PROCINFO *pNewProcInfo;
500 pNewProcInfo=(PROCINFO *)HeapAlloc(hHeap,0,pobj_ClassTreeView->NumberOfProcedures*sizeof(PROCINFO));
501 int NewProcNum;
502 NewProcNum=0;
503
504 //プロシージャ情報のメモリを解放
505 for(i=0;i<pobj_ClassTreeView->NumberOfProcedures;i++){
506 if(iFileNum==-1 || iFileNum==pobj_ClassTreeView->pProcInfo[i].FileNum){
507 HeapDefaultFree(pobj_ClassTreeView->pProcInfo[i].name);
508 }
509 else{
510 pNewProcInfo[NewProcNum]=pobj_ClassTreeView->pProcInfo[i];
511 NewProcNum++;
512 }
513 }
514 HeapDefaultFree(pobj_ClassTreeView->pProcInfo);
515
516 pobj_ClassTreeView->pProcInfo=pNewProcInfo;
517 pobj_ClassTreeView->NumberOfProcedures=NewProcNum;
518 }
519 else{
520 pobj_ClassTreeView->pProcInfo=(PROCINFO *)HeapAlloc(hHeap,0,1);
521 pobj_ClassTreeView->NumberOfProcedures=0;
522 }
523
524 extern HWND hProcedureTreeView;
525 tvItem.hItem=TreeView_GetRoot(hProcedureTreeView);
526 if(tvItem.hItem){
527 TreeView_GetItem(hProcedureTreeView,&tvItem);
528 if(tvItem.state&TVIS_EXPANDED){
529 bExpand=1;
530
531 si.cbSize=sizeof(SCROLLINFO);
532 si.fMask=SIF_POS;
533 GetScrollInfo(hProcedureTreeView,SB_VERT,&si);
534 }
535 else bExpand=0;
536 }
537 else bExpand=1;
538
539
540 pobj_ClassTreeView->init(hProcedureTreeView,iFileNum);
541
542 //ルートフォルダ
543 pobj_ClassTreeView->InsertRootFolder();
544
545 //グローバル関数フォルダ
546 pobj_ClassTreeView->InsertGlobalProcedureFolder();
547
548
549 //描画をロック
550 LockWindowUpdate(hProcedureTreeView);
551
552 extern PROJECTINFO ProjectInfo;
553 if(ProjectInfo.name[0]){
554 // プロジェクトが開かれているとき
555 if(iFileNum==-1){
556 //プロジェクトのすべてのファイルを解析
557 for(i=0;i<ProjectInfo.pobj_DBFileInfo->iNum;i++){
558 ProjectInfo.pobj_DBFileInfo->ppobj_FileInfo[i]->GetFullPath(temporary);
559
560 SetClassTreeFromOneFile(temporary,i);
561 }
562
563 //不要になったアイテムを除去
564 //pobj_ClassTreeView->finish();
565 }
566 else{
567 /////////////////////////////////
568 // 編集中のファイルのみを解析
569 /////////////////////////////////
570
571 ProjectInfo.pobj_DBFileInfo->ppobj_FileInfo[iFileNum]->GetFullPath(temporary);
572
573 SetClassTreeFromOneFile(temporary,iFileNum);
574 }
575 }
576 else{
577 // 編集中の単体ファイルを解析
578
579 HWND hChild=GetWindow(hClient,GW_CHILD);
580 int WndNum=GetWndNum(hChild);
581 char *pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
582 SetClassTreeFromOneFile_Buf( pBuf, -1 );
583
584 }
585
586 //不要になったアイテムを除去
587 pobj_ClassTreeView->finish();
588
589 //描画ロックを解除
590 LockWindowUpdate(0);
591
592
593 if(bExpand){
594 TreeView_Expand(hProcedureTreeView,pobj_ClassTreeView->hRootFolder,TVE_EXPAND);
595
596 SetScrollInfo(hProcedureTreeView,SB_VERT,&si,1);
597 }
598
599
600 bSearchingClasses=0;
601 if(bRetrySearchingClasses){
602 bRetrySearchingClasses=0;
603 ResetClassTree(iFileNum);
604 }
605
606 if(pobj_ClassTreeView->bCloseSwitch){
607 //コード解析中に終了ボタンが押されたとき
608 PostMessage(hOwner,WM_CLOSE,0,0);
609 }
610 if(pobj_ClassTreeView->bShowSwitch){
611 //コード解析中にクラスビューがダブルクリックされたとき
612 extern HWND hProjectViewTab;
613 PostMessage(hProjectViewTab,WM_COMMAND,IDM_PROCEDURETREE_SHOW,0);
614 pobj_ClassTreeView->bShowSwitch=0;
615 }
616
617 _endthread();
618}
619void ResetClassTree(int iFileNum){
620 _beginthread(SetProcedureTreeData,0,(void *)iFileNum);
621}
Note: See TracBrowser for help on using the repository browser.