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

Last change on this file since 681 was 655, checked in by dai_9181, 16 years ago

FileManager周りをリファクタリング

File size: 14.9 KB
RevLine 
[475]1#include "stdafx.h"
2
[3]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}
[655]22void CClassTreeView::AddValidItem(HTREEITEM hItem,HTREEITEM hFileTreeItem){
[3]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;
[655]44 pth->hFileTreeItem = hFileTreeItem;
[3]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){
[655]87 if(pth->hItem && (hNowFileTreeItem==(HTREEITEM)-1 || hNowFileTreeItem==pth->hFileTreeItem)){
[3]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
[655]98HTREEITEM CClassTreeView::insert(HTREEITEM hParentItem,int flag,char *lpszName,HTREEITEM hFileTreeItem){
[3]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 //既に挿入済みの場合
[655]112 AddValidItem(hNextItem,hFileTreeItem);
[3]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);
[655]160 AddValidItem(hNextItem,hFileTreeItem);
[3]161 return hNextItem;
162}
163
164
165
166CClassTreeView::CClassTreeView(){
167 memset(this,0,sizeof(CClassTreeView));
168}
169CClassTreeView::~CClassTreeView(){
170 while(bSearchingClasses) Sleep(10);
171
[655]172 this->hNowFileTreeItem = (HTREEITEM)-1;
[3]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}
[655]188void CClassTreeView::init(HWND hwnd,HTREEITEM hFileTreeItem){
[3]189 hTreeWnd=hwnd;
190
[655]191 this->hNowFileTreeItem = hFileTreeItem;
[3]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 char temporary[VN_SIZE];
[619]201 sprintf(temporary,"%s クラス",projectInfo.GetName().c_str());
[3]202 hRootFolder=insert(
203 TVI_ROOT,
204 CTV_ROOT,
[655]205 temporary,(HTREEITEM)-1);
[3]206}
207void CClassTreeView::InsertGlobalProcedureFolder(void){
208 hGlobalProcedureFolder=insert(
209 hRootFolder,
210 CTV_FOLDER,
[655]211 "グローバル関数",(HTREEITEM)-1);
[3]212}
213
[655]214HTREEITEM CClassTreeView::InsertGlobalProcedure(int flag,char *lpszName,HTREEITEM hFileTreeItem){
[3]215 return pobj_ClassTreeView->insert(
216 hGlobalProcedureFolder,
217 CTV_GLOBAL_PROC,
218 lpszName,
[655]219 hFileTreeItem);
[3]220}
221
[655]222HTREEITEM CClassTreeView::insert_code_item(HTREEITEM hParentItem,int flag,char *lpszName,HTREEITEM hFileTreeItem,char *pBuf,int p){
[3]223 int i4;
224 i4=NumberOfProcedures;
225 pProcInfo=(PROCINFO *)HeapReAlloc(hHeap,0,pProcInfo,sizeof(PROCINFO)*(i4+1));
226 pProcInfo[i4].name=(char *)HeapAlloc(hHeap,0,lstrlen(lpszName)+1);
227 lstrcpy(pProcInfo[i4].name,lpszName);
[655]228 pProcInfo[i4].hFileTreeItem = hFileTreeItem;
[3]229
230 //コード位置
231 pProcInfo[i4].code_pos=p;
232
233 //ツリーアイテムを挿入
234 HTREEITEM hTempItem;
235 hTempItem=insert(
236 hParentItem,
237 flag,
238 lpszName,
[655]239 hFileTreeItem);
[3]240
241 pProcInfo[i4].hTreeItem=hTempItem;
242
243 NumberOfProcedures++;
244
245 return hTempItem;
246}
247
[655]248void CClassTreeView::InsertClassFolder(char *lpszName,HTREEITEM hFileTreeItem,char *pBuf,int p){
249 hNowClassFolder=insert_code_item(hRootFolder,CTV_CLASS,lpszName,hFileTreeItem,pBuf,p);
[3]250}
[655]251void CClassTreeView::InsertClassMember(int flag,char *lpszName,HTREEITEM hFileTreeItem,char *pBuf,int p){
252 insert_code_item(hNowClassFolder,flag,lpszName,hFileTreeItem,pBuf,p);
[3]253}
254
255void CClassTreeView::finish(){
256 DeleteInvalidItems(TreeView_GetRoot(hTreeWnd));
257}
258
259
[655]260void AnalysisClass(char *pBuf,int *p,HTREEITEM hFileTreeItem){
[3]261 int i2;
262 i2=*p;
263
264
265 CClassInfo *pobj_ClassInfo;
266 pobj_ClassInfo=new CClassInfo();
267
268 pobj_ClassInfo->Analyze(pBuf,p);
269
270
271 //クラスフォルダを挿入
272 pobj_ClassTreeView->InsertClassFolder(
273 pobj_ClassInfo->ClassName,
[655]274 hFileTreeItem,
[3]275 pBuf,
276 i2);
277
278
279
280 ///////////////////////////////
281 // メンバ及びメソッドを挿入
282 ///////////////////////////////
283
284 int i;
285 for(i=0;i<pobj_ClassInfo->MemberNum;i++){
286 int flag;
287 if(pobj_ClassInfo->pMemberInfo[i].dwProc==0){
288 //メンバ変数
289 if(pobj_ClassInfo->pMemberInfo[i].dwAccess==ACCESS_PUBLIC){
290 //公開
291 flag=CTV_PUBLIC_MEMBER;
292 }
293 else{
294 //非公開
295 flag=CTV_PRIVATE_MEMBER;
296 }
297 }
298 else{
299 //メソッド
300 if(pobj_ClassInfo->pMemberInfo[i].dwAccess==ACCESS_PUBLIC){
301 //公開
302 flag=CTV_PUBLIC_METHOD;
303 }
304 else{
305 //非公開
306 flag=CTV_PRIVATE_METHOD;
307 }
308 }
[655]309 pobj_ClassTreeView->InsertClassMember(flag,pobj_ClassInfo->pMemberInfo[i].pName,hFileTreeItem,pBuf,pobj_ClassInfo->pMemberInfo[i].code_pos);
[3]310 }
311
312
313 delete pobj_ClassInfo;
314 pobj_ClassInfo=0;
315}
316
317
[655]318void SetClassTreeFromOneFile_Buf( char *pBuf, HTREEITEM hFileTreeItem ){
[81]319 int i2,i3,i4;
[3]320 char temporary[GENERAL_SIZE];
321
322 for(i2=0;;i2++){
323 if(pBuf[i2]=='\0') break;
324 while(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n'&&pBuf[i2+2]=='\r'&&pBuf[i2+3]=='\n') i2+=2;
325 if(i2==0||(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n')){
326 if(pBuf[i2]=='\r'&&pBuf[i2+1]=='\n') i2+=2;
327 while(pBuf[i2]>='0'&&pBuf[i2]<='9') i2++;
328 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
329
330 i4=i2;
331 for(i3=0;;i2++,i3++){
332 if(!IsVariableChar(pBuf[i2])){
333 temporary[i3]=0;
334 break;
335 }
336 temporary[i3]=pBuf[i2];
337 }
338 if(pBuf[i2]=='\0') break;
339
340 if(lstrcmpi(temporary,"Class")==0||
341 lstrcmpi(temporary,"Type")==0||
342 lstrcmpi(temporary,"Interface")==0){
343
344 /////////////////////////////
345 // クラスの解析
346 /////////////////////////////
[655]347 AnalysisClass(pBuf,&i4,hFileTreeItem);
[3]348
349 i2=i4-1;
350 continue;
351 }
352
353 int sw;
354 if(lstrcmpi(temporary,"Sub")==0) sw=1;
355 else if(lstrcmpi(temporary,"Function")==0) sw=2;
356 else sw=0;
357
358 if(sw){
359 //Sub/Function
360 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
361 for(i3=0;;i2++,i3++){
362 if(!IsVariableChar(pBuf[i2])){
363 temporary[i3]=0;
364 break;
365 }
366 temporary[i3]=pBuf[i2];
367 }
368
369 if(lstrcmpi(temporary,"Export")==0){
370 //Export修飾子はとばす
371 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
372
373 for(i3=0;;i2++,i3++){
374 if(!IsVariableChar(pBuf[i2])){
375 temporary[i3]=0;
376 break;
377 }
378 temporary[i3]=pBuf[i2];
379 }
380 }
381
382 i4=pobj_ClassTreeView->NumberOfProcedures;
383 pobj_ClassTreeView->pProcInfo=(PROCINFO *)HeapReAlloc(hHeap,0,pobj_ClassTreeView->pProcInfo,sizeof(PROCINFO)*(i4+1));
384 pobj_ClassTreeView->pProcInfo[i4].name=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
385 lstrcpy(pobj_ClassTreeView->pProcInfo[i4].name,temporary);
[655]386 pobj_ClassTreeView->pProcInfo[i4].hFileTreeItem = hFileTreeItem;
[3]387
388 //定義行の選択範囲
389 pobj_ClassTreeView->pProcInfo[i4].code_pos=i2;
390
391 //パラメータ部
392 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
393 if(pBuf[i2]=='('){
394 int IsStr,PareNum;
395 for(i2++,i3=0,IsStr=0,PareNum=0;;i2++,i3++){
396 if(pBuf[i2]=='\"') IsStr^=1;
397 if(pBuf[i2]=='('&&IsStr==0) PareNum++;
398 if(pBuf[i2]==')'&&IsStr==0){
399 PareNum--;
400 if(PareNum<0){
401 temporary[i3]=0;
402 break;
403 }
404 }
405 if(pBuf[i2]=='\0') break;
406 temporary[i3]=pBuf[i2];
407 }
408 //temporaryはパラメータの内容が格納されるが、不要
409 }
410
411 for(;;i2++){
412 if(IsCommandDelimitation(pBuf,i2)){
413 break;
414 }
415 if((pBuf[i2]=='a'||pBuf[i2]=='A')&&(pBuf[i2+1]=='s'||pBuf[i2+1]=='S')&&(pBuf[i2+2]==' '||pBuf[i2+2]=='\t')){
416 i2+=3;
417 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
418 for(i3=0;;i2++,i3++){
419 if(!IsVariableChar(pBuf[i2])){
420 temporary[i3]=0;
421 break;
422 }
423 temporary[i3]=pBuf[i2];
424 }
425 //temporaryには型情報が格納されるが、不要
426 break;
427 }
428 }
429
430 //ツリーアイテムを挿入
431 HTREEITEM hTempItem;
432 hTempItem=pobj_ClassTreeView->InsertGlobalProcedure(
433 CTV_GLOBAL_PROC,
434 pobj_ClassTreeView->pProcInfo[i4].name,
[655]435 hFileTreeItem);
[3]436 pobj_ClassTreeView->pProcInfo[i4].hTreeItem=hTempItem;
437
438 pobj_ClassTreeView->NumberOfProcedures++;
439
440 i2--;
441 }
442 }
443 }
[81]444}
[655]445void SetClassTreeFromOneFile( const ActiveBasic::PM::FM::File &file){
[81]446 int WndNum;
447 HWND hChild=GetWindow(hClient,GW_CHILD);
448 while(hChild){
449 WndNum=GetWndNum(hChild);
[625]450 if( WndNum != -1 )
451 {
[629]452 if(IS_DOCUMENT_TEXT(MdiInfo[WndNum]->DocType)){
[655]453 if(lstrcmpi(MdiInfo[WndNum]->path.c_str(),file.GetFullPath().c_str())==0) break;
[625]454 }
455 hChild=GetNextWindow(hChild,GW_HWNDNEXT);
[81]456 }
457 }
[3]458
[81]459 char *pBuf;
460 if(hChild){
461 //すでに指定されたファイルが開かれている場合
[629]462 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
[81]463 }
464 else{
465 //開かれていない場合
[655]466 pBuf=ReadBuffer(file.GetFullPath());
[81]467 if(!pBuf) pBuf=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);
468 }
469
[655]470 SetClassTreeFromOneFile_Buf( pBuf, file.GetTreeItemHandle() );
[81]471
[3]472 if(!hChild) HeapDefaultFree(pBuf);
473}
[655]474void SetClassTreeFromAllFile( ActiveBasic::PM::FM::Folder &folder )
475{
476 BOOST_FOREACH( ActiveBasic::PM::FM::Folder &childFolder, folder.folders )
477 {
478 SetClassTreeFromAllFile( childFolder );
479 }
[3]480
[655]481 BOOST_FOREACH( ActiveBasic::PM::FM::File &file, folder.files )
482 {
483 SetClassTreeFromOneFile( file );
484 }
485}
486
487void SetProcedureTreeData(void *temp_hFileTreeItem)
488{
[3]489 BOOL bExpand;
490 TVITEM tvItem;
491 SCROLLINFO si;
492
[655]493 HTREEITEM hFileTreeItem = (HTREEITEM)temp_hFileTreeItem;
[3]494
495 if(bSearchingClasses){
496 bRetrySearchingClasses=1;
497 _endthread();
498 return;
499 }
500 bSearchingClasses=1;
501
502 if(pobj_ClassTreeView->pProcInfo){
503wait_repeat:
504 Sleep(700);
505 if(bRetrySearchingClasses){
506 bRetrySearchingClasses=0;
507 goto wait_repeat;
508 }
509
510 PROCINFO *pNewProcInfo;
511 pNewProcInfo=(PROCINFO *)HeapAlloc(hHeap,0,pobj_ClassTreeView->NumberOfProcedures*sizeof(PROCINFO));
512 int NewProcNum;
513 NewProcNum=0;
514
515 //プロシージャ情報のメモリを解放
[655]516 for(int i=0;i<pobj_ClassTreeView->NumberOfProcedures;i++){
517 if(hFileTreeItem==(HTREEITEM)-1 || hFileTreeItem==pobj_ClassTreeView->pProcInfo[i].hFileTreeItem){
[3]518 HeapDefaultFree(pobj_ClassTreeView->pProcInfo[i].name);
519 }
520 else{
521 pNewProcInfo[NewProcNum]=pobj_ClassTreeView->pProcInfo[i];
522 NewProcNum++;
523 }
524 }
525 HeapDefaultFree(pobj_ClassTreeView->pProcInfo);
526
527 pobj_ClassTreeView->pProcInfo=pNewProcInfo;
528 pobj_ClassTreeView->NumberOfProcedures=NewProcNum;
529 }
530 else{
531 pobj_ClassTreeView->pProcInfo=(PROCINFO *)HeapAlloc(hHeap,0,1);
532 pobj_ClassTreeView->NumberOfProcedures=0;
533 }
534
535 extern HWND hProcedureTreeView;
536 tvItem.hItem=TreeView_GetRoot(hProcedureTreeView);
537 if(tvItem.hItem){
538 TreeView_GetItem(hProcedureTreeView,&tvItem);
539 if(tvItem.state&TVIS_EXPANDED){
540 bExpand=1;
541
542 si.cbSize=sizeof(SCROLLINFO);
543 si.fMask=SIF_POS;
544 GetScrollInfo(hProcedureTreeView,SB_VERT,&si);
545 }
546 else bExpand=0;
547 }
548 else bExpand=1;
549
550
[655]551 pobj_ClassTreeView->init(hProcedureTreeView,hFileTreeItem);
[3]552
553 //ルートフォルダ
554 pobj_ClassTreeView->InsertRootFolder();
555
556 //グローバル関数フォルダ
557 pobj_ClassTreeView->InsertGlobalProcedureFolder();
558
559
560 //描画をロック
561 LockWindowUpdate(hProcedureTreeView);
562
[619]563 if( projectInfo.IsOpened() ){
[81]564 // プロジェクトが開かれているとき
[655]565 if(hFileTreeItem==(HTREEITEM)-1){
566 boost::mutex::scoped_lock lock( projectInfo.fileSystem.mutex );
567
[81]568 //プロジェクトのすべてのファイルを解析
[655]569 SetClassTreeFromAllFile( projectInfo.fileSystem.root );
[3]570
[81]571 //不要になったアイテムを除去
572 //pobj_ClassTreeView->finish();
[3]573 }
[81]574 else{
575 /////////////////////////////////
576 // 編集中のファイルのみを解析
577 /////////////////////////////////
[3]578
[655]579 SetClassTreeFromOneFile( projectInfo.fileSystem.root.FindFile( hFileTreeItem ) );
[81]580 }
[3]581 }
582 else{
[81]583 // 編集中の単体ファイルを解析
[3]584
[81]585 HWND hChild=GetWindow(hClient,GW_CHILD);
586 int WndNum=GetWndNum(hChild);
[629]587 char *pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
[655]588 SetClassTreeFromOneFile_Buf( pBuf, (HTREEITEM)-1 );
[3]589
590 }
591
592 //不要になったアイテムを除去
593 pobj_ClassTreeView->finish();
594
595 //描画ロックを解除
596 LockWindowUpdate(0);
597
598
599 if(bExpand){
600 TreeView_Expand(hProcedureTreeView,pobj_ClassTreeView->hRootFolder,TVE_EXPAND);
601
602 SetScrollInfo(hProcedureTreeView,SB_VERT,&si,1);
603 }
604
605
606 bSearchingClasses=0;
607 if(bRetrySearchingClasses){
608 bRetrySearchingClasses=0;
[655]609 ResetClassTree(hFileTreeItem);
[3]610 }
611
612 if(pobj_ClassTreeView->bCloseSwitch){
613 //コード解析中に終了ボタンが押されたとき
614 PostMessage(hOwner,WM_CLOSE,0,0);
615 }
616 if(pobj_ClassTreeView->bShowSwitch){
617 //コード解析中にクラスビューがダブルクリックされたとき
618 extern HWND hProjectViewTab;
619 PostMessage(hProjectViewTab,WM_COMMAND,IDM_PROCEDURETREE_SHOW,0);
620 pobj_ClassTreeView->bShowSwitch=0;
621 }
622
623 _endthread();
624}
[655]625void ResetClassTree(HTREEITEM hFileTreeItem){
626 _beginthread(SetProcedureTreeData,0,(void *)hFileTreeItem);
[3]627}
Note: See TracBrowser for help on using the repository browser.