Develop and Download Open Source Software

Browse Subversion Repository

Contents of /CopalPro/Script.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Thu Jul 28 09:05:52 2011 UTC (12 years, 9 months ago) by kaityo
File MIME type: text/x-c++src
File size: 16986 byte(s)
First Commit
1 //---------------------------------------------------------------------------
2 // スクリプトを入力するフォーム
3 //---------------------------------------------------------------------------
4 #include <vcl.h>
5 #pragma hdrstop
6
7 #include "Main.h"
8 #include "KCopalConfig.h"
9 #include "Script.h"
10 //---------------------------------------------------------------------------
11 #pragma package(smart_init)
12 #pragma link "Base"
13 #pragma resource "*.dfm"
14 TFScript *FScript;
15 //---------------------------------------------------------------------------
16 __fastcall
17 TFScript::TFScript(TComponent* Owner)
18 : TFBase(Owner) {
19 //自分をドッキングする
20 Caption = "Script";
21 Width = 400;
22 Height = 400;
23 ManualDock(FMain->PageControl,FMain->PageControl,alClient);
24 Visible = true;
25 Modified = false;
26 FileName = "";
27 Delimiter = D_CRLF;
28 Code = C_SJIS;
29 }
30 //---------------------------------------------------------------------------
31 void
32 TFScript::SetCode(int CodeMode) {
33 if(CodeMode !=CM_AUTOSELECT) {
34 Code = CodeMode;
35 }
36 }
37 //---------------------------------------------------------------------------
38 void
39 TFScript::SetTabWidth(KCopalConfig *CopalConfig,int tabwidth){
40 CopalConfig->SetTabWidthToRichEdit(REScript, tabwidth);
41 }
42 //---------------------------------------------------------------------------
43 /**
44 * ウィンドウにフォーカスをあてる
45 */
46 void
47 TFScript::SetWindowFocus(void) {
48 REScript->SetFocus();
49 }
50 //---------------------------------------------------------------------------
51 /**
52 * 検索
53 */
54 void
55 TFScript::Find(void) {
56 FMain->FindDialog->OnFind = OnFind;
57 SearchOption.Clear();
58 FMain->FindDialog->FindText = FindWord;
59 if(!FMain->FindDialog->Execute()) {
60 return;
61 }
62 }
63 //---------------------------------------------------------------------------
64 void __fastcall
65 TFScript::OnFind(TObject *Sender) {
66 FMain->FindDialog->CloseDialog();
67 FindWord = FMain->FindDialog->FindText;
68 //オプションの設定
69 if (FMain->FindDialog->Options.Contains(frMatchCase)) {
70 SearchOption = SearchOption << stMatchCase;
71 }
72 if (FMain->FindDialog->Options.Contains(frWholeWord)) {
73 SearchOption = SearchOption << stWholeWord;
74 }
75 if (FMain->FindDialog->Options.Contains(frDown)) {
76 //下方向に検索
77 FindNext();
78 } else {
79 //上方向に検索
80 FindPrev();
81 }
82 }
83 //---------------------------------------------------------------------------
84 /**
85 * 次を検索
86 */
87 void
88 TFScript::FindNext(void) {
89 if(FindWord == "") {
90 Find();
91 return;
92 }
93
94 //現在のカーソル位置の行
95 int line = REScript->Perform(EM_LINEFROMCHAR,-1,0);
96
97 //カーソル行の頭の位置
98 int linetop = REScript->Perform(EM_LINEINDEX,line,0);
99 AnsiString Str = REScript->Lines->Strings[line];
100 int startpos = REScript->SelStart;
101 if(REScript->SelLength)
102 startpos++;
103 Str = Str.SubString(startpos - linetop+1,Str.Length()-startpos+linetop);
104
105 //現在の位置で見つかるか
106 int pos = Str.AnsiPos(FindWord);
107 if(pos!=0) {
108 pos += startpos-1;
109 REScript->SelStart = pos;
110 REScript->SelLength = FindWord.Length();
111 MakeCursorVisible();
112 return;
113 }
114 //以下の行を検索する
115 line++;
116 int count = REScript->Lines->Count;//毎回参照すると遅いので退避
117 while(line < count) {
118 Str = REScript->Lines->Strings[line];
119 int pos = Str.AnsiPos(FindWord);
120 if(pos!=0) {
121 int linetop = REScript->Perform(EM_LINEINDEX,line,0);
122 pos += linetop-1;
123 REScript->SelStart = pos;
124 REScript->SelLength = FindWord.Length();
125 MakeCursorVisible();
126 return;
127 } else {
128 line++;
129 }
130 }
131 }
132 //---------------------------------------------------------------------------
133 /**
134 * 与えられた文字列の最後にマッチする位置を返す
135 * マッチしなければ 0を返す
136 */
137 int
138 FindLast(AnsiString asTarget, AnsiString asFindWord) {
139 int pos = asTarget.AnsiPos(asFindWord);
140 if(pos==0) {
141 return 0;
142 }
143 while(1) {
144 asTarget = asTarget.SubString(pos+1,asTarget.Length()-pos);
145 int pos2 = asTarget.AnsiPos(asFindWord);
146 if(pos2!=0) {
147 pos+=pos2;
148 } else {
149 break;
150 }
151 }
152 return pos;
153 }
154 //---------------------------------------------------------------------------
155 void
156 TFScript::FindPrev(void) {
157
158 //現在のカーソル位置の行
159 int line = REScript->Perform(EM_LINEFROMCHAR,-1,0);
160
161 //カーソル行の頭の位置
162 int linetop = REScript->Perform(EM_LINEINDEX,line,0);
163 AnsiString Str = REScript->Lines->Strings[line];
164 Str = Str.SubString(0,REScript->SelStart-linetop-1);
165 int pos = FindLast(Str,FindWord);
166 if(pos!=0) {
167 pos += linetop-1;
168 REScript->SelStart = pos;
169 REScript->SelLength = FindWord.Length();
170 return;
171 } else {
172 line--;
173 }
174 while(line >= 0) {
175 Str = REScript->Lines->Strings[line];
176 int pos = FindLast(Str,FindWord);
177 if(pos!=0) {
178 int linetop = REScript->Perform(EM_LINEINDEX,line,0);
179 pos += linetop-1;
180 REScript->SelStart = pos;
181 REScript->SelLength = FindWord.Length();
182 MakeCursorVisible();
183 return;
184 } else {
185 line--;
186 }
187 }
188 }
189 //---------------------------------------------------------------------------
190 /**
191 * テンポラリファイルとして保存
192 */
193 void
194 TFScript::SaveToTemporaryFile(AnsiString File) {
195 KCodeConv::SaveConvertedFile(File,REScript->Lines->Text,Code,Delimiter);
196 }
197 //---------------------------------------------------------------------------
198 void
199 TFScript::SaveToFile(AnsiString File) {
200
201 KCodeConv::SaveConvertedFile(File,REScript->Lines->Text,Code,Delimiter);
202 FMain->AddHistory(File);
203 FileDate = FileAge(FileName);
204 Modified = false;
205 FMain->UpdateCaption();
206 //カレントディレクトリをスクリプトのある場所にする
207 AnsiString Dir = ExtractFileDir(FileName);
208 if(Dir!="") {
209 SetMyCurrentDir(Dir);
210 }
211 FMain->UpdateStatusBar();
212 }
213 //---------------------------------------------------------------------------
214 /**
215 * ファイルのロードを行う
216 * 改行コード変換、文字コード変換も行う
217 */
218 void
219 TFScript::LoadFromFile(AnsiString File) {
220
221 if(!FileExists(File)) {
222 AnsiString msg = File+"が見当たりません。\n新規作成しますか?";
223 int mr = Application->MessageBox(msg.c_str(),"CopalPro",MB_YESNO);
224 if (mr == ID_NO) {
225 return;
226 } else {
227 FileName = File;
228 Modified = true;
229 FMain->UpdateCaption();
230 return;
231 }
232 }
233
234 FileName = File;
235 FileDate = FileAge(FileName);
236
237 Delimiter = KCodeConv::GetDelimiterType(File.c_str());
238
239 if(CopalConfig->GetCodeMode() == CM_AUTOSELECT) {
240 Code = KCodeConv::GetCodeType(File.c_str());
241 }
242
243 TMemoryStream *msIn = new TMemoryStream;
244 TMemoryStream *msOut = new TMemoryStream;
245 msIn->LoadFromFile(FileName);
246
247 if(KCodeConv::NKF32Exists()) {
248 AnsiString option = KCodeConv::GetConvertOption(Code,C_SJIS);
249 KCodeConv::ConvertStream(msIn,msOut,option.c_str());
250 REScript->Lines->LoadFromStream(msOut);
251 } else {
252 //改行コードのみ変更
253 KCodeConv::ConvertDelimiter(msIn,D_CRLF);
254 REScript->Lines->LoadFromStream(msIn);
255 }
256 delete msOut;
257 delete msIn;
258 Modified = false;
259
260 //カレントディレクトリをスクリプトのある場所にする
261 AnsiString Dir = ExtractFileDir(File);
262 if(Dir!="") {
263 SetMyCurrentDir(Dir);
264 }
265
266 //拡張子から言語設定を変更
267 CopalConfig->SearchByExt(File);
268
269 FMain->AddHistory(File);
270 FMain->UpdateAll();
271 }
272 //---------------------------------------------------------------------------
273 /**
274 * 新規作成
275 */
276 void
277 TFScript::New(void) {
278 FileName="";
279 REScript->Lines->Clear();
280 Modified=false;
281
282 FMain->CloseError();
283 CopalConfig->SetReadOnly(false);
284 FMain->UpdateAll();
285 }
286 //---------------------------------------------------------------------------
287 void __fastcall
288 TFScript::FormActivate(TObject *Sender) {
289 FMain->ChangeWindow(SCRIPT_WINDOW);
290 }
291 //---------------------------------------------------------------------------
292 // クリップボード関連
293 //---------------------------------------------------------------------------
294 /**
295 * 切り取り
296 */
297 void
298 TFScript::Cut(void) {
299 if(REScript->SelText=="") {
300 return;
301 }
302 TClipboard *cb = Clipboard();
303 cb->AsText = REScript->SelText;
304 REScript->Lines->BeginUpdate();
305 REScript->Perform(EM_REPLACESEL,true,(int)"");
306 REScript->Lines->EndUpdate();
307 }
308 //---------------------------------------------------------------------------
309 /**
310 * コピー
311 */
312 void
313 TFScript::Copy(void) {
314 if(REScript->SelText=="") {
315 return;
316 }
317 TClipboard *cb = Clipboard();
318 cb->AsText = REScript->SelText;
319 }
320 //---------------------------------------------------------------------------
321 /**
322 * 貼り付け
323 */
324 void
325 TFScript::Paste(void) {
326 TClipboard *cb = Clipboard();
327 REScript->Lines->BeginUpdate();
328 REScript->Perform(EM_REPLACESEL,true,(int)(cb->AsText.c_str()));
329 REScript->Lines->EndUpdate();
330 }
331 //---------------------------------------------------------------------------
332 // エディット関連
333 //---------------------------------------------------------------------------
334 /**
335 * アンドゥ
336 */
337 void
338 TFScript::Undo(void) {
339 REScript->Perform(EM_UNDO,0,0);
340 }
341 //---------------------------------------------------------------------------
342 /**
343 * ファイルの読み込み
344 */
345 void
346 TFScript::Load(void) {
347 OpenDialog->Filter = CopalConfig->GetFileFilter();
348 OpenDialog->Title = "スクリプトを開く";
349 OpenDialog->InitialDir = GetMyCurrentDir();
350 if(!OpenDialog->Execute()) {
351 return;
352 }
353 LoadFromFile(OpenDialog->FileName);
354 AnsiString Dir = ExtractFileDir(FileName);
355 if(Dir!="") {
356 SetMyCurrentDir(Dir);
357 }
358 CopalConfig->SetReadOnly(false);
359 }
360 //---------------------------------------------------------------------------
361 /**
362 * ファイルの保存
363 */
364 void
365 TFScript::Save(void) {
366 if(FileName!="") {
367 SaveToFile(FileName);
368 } else {
369 SaveAs();
370 }
371 }
372 //---------------------------------------------------------------------------
373 /**
374 * ファイルの保存
375 */
376 void
377 TFScript::SaveAs(void) {
378 FMain->SaveDialog->Filter = CopalConfig->GetFileFilter();
379 FMain->SaveDialog->Title = "スクリプトを保存";
380 FMain->SaveDialog->InitialDir = GetMyCurrentDir();
381 FMain->SaveDialog->DefaultExt = CopalConfig->GetDefaultExt();
382
383 if(!FMain->SaveDialog->Execute()) {
384 return;
385 }
386 FileName = FMain->SaveDialog->FileName;
387 SaveToFile(FileName);
388 }
389 //---------------------------------------------------------------------------
390 /**
391 * 保存するか聞く
392 * 返り値
393 * true 処理を進めてOK
394 * false 処理を進めてはいけない
395 */
396 bool
397 TFScript::SaveQuery(void) {
398
399 if(!Modified) {
400 return true;
401 }
402
403 AnsiString msg;
404
405 if (FileName=="") {
406 msg = "スクリプト ";
407 } else {
408 msg = FileName;
409 }
410 msg += "は変更されています。保存しますか?";
411 int result = MessageBox(this->Handle,msg.c_str(),"Copal - 保存確認",MB_YESNOCANCEL|MB_ICONEXCLAMATION);
412
413 switch(result) {
414 case IDYES:
415 //保存する
416 Save();
417 if(Modified) {
418 return false;
419 }
420 break;
421
422 case IDNO:
423 //保存しないで終了
424 break;
425 case IDCANCEL:
426 //終了しない
427 return false;
428 }
429 return true;
430 }
431 //---------------------------------------------------------------------------
432 /**
433 * キャプション用の文字列を返す
434 */
435 AnsiString
436 TFScript::GetCaptionStr(void) {
437
438 if(FileName=="") {
439 return "Copal2 * 新規スクリプト";
440 }
441 if(Modified) {
442 return "Copal2 * " + FileName;
443 } else {
444 return "Copal2 - " + FileName;
445 }
446 }
447 //---------------------------------------------------------------------------
448 /**
449 * 外部エディタの実行
450 * 実行したらtrueを返す
451 */
452 bool
453 TFScript::ExecuteEditor(void) {
454
455 if(CopalConfig->Editor=="") {
456 return false;
457 }
458
459 if(Modified) {
460 if(!SaveQuery()) {
461 return false;
462 }
463 }
464
465 AnsiString as1 = FileName;
466
467 if(CopalConfig->UseDoubleQuotes) {
468 as1 = "\""+as1+"\"";
469 }
470
471 if(!FileExists(CopalConfig->Editor)) {
472 ShowMessage(CopalConfig->Editor+"が見つかりません。パスを確認してください。");
473 return false;
474 }
475
476 ShellExecute(this->Handle,NULL,CopalConfig->Editor.c_str(),as1.c_str(),NULL,SW_SHOW);
477
478 return true;
479 }
480 //---------------------------------------------------------------------------
481 /**
482 * カーソル位置を画面内に配置するコード
483 */
484 void
485 TFScript::MakeCursorVisible(void) {
486 const int TopLineMargin = 5;
487 int firstline = REScript->Perform(EM_GETFIRSTVISIBLELINE,0,0);
488 int line = REScript->Perform(EM_LINEFROMCHAR,-1,0);
489 if(line>TopLineMargin) {
490 firstline += TopLineMargin;
491 REScript->Perform(EM_LINESCROLL,0,line-firstline);
492 } else {
493 REScript->Perform(EM_LINESCROLL,0,-firstline);
494 }
495 }
496 //---------------------------------------------------------------------------
497 /**
498 * 行ジャンプをするインターフェース
499 */
500 void
501 TFScript::LineJump(int line) {
502 int pos = REScript->Perform(EM_LINEINDEX,line - 1,0);
503 REScript->SelStart = pos;
504 MakeCursorVisible();
505 REScript->SetFocus();
506 }
507 //---------------------------------------------------------------------------
508 /**
509 * ヘルプ検索用の文字列を作る
510 */
511 AnsiString
512 TFScript::GetHelpKeyWord(void) {
513 int line_number = SendMessage(REScript->Handle,EM_LINEFROMCHAR,REScript->SelStart,0);
514 int line_pos = SendMessage(REScript->Handle,EM_LINEINDEX,line_number,0);
515 int pos = REScript->SelStart - line_pos;
516 AnsiString Line = REScript->Lines->Strings[line_number];
517 int startpos,endpos;
518
519 if(pos==0)
520 pos++;
521 if(pos==Line.Length())
522 pos--;
523
524 if(pos!=0) {
525 for(startpos = pos;startpos>1;startpos--) {
526 if(Line[startpos] == ' ') {
527 startpos++;
528 break;
529 }
530 if(Line[startpos] == ')') {
531 startpos++;
532 break;
533 }
534 if(Line[startpos] == '}') {
535 startpos++;
536 break;
537 }
538 if(Line[startpos] == '(') {
539 startpos++;
540 break;
541 }
542 if(Line[startpos] == '{') {
543 startpos++;
544 break;
545 }
546 if(Line[startpos] == '/') {
547 startpos++;
548 break;
549 }
550 if(Line[startpos] == '=') {
551 startpos++;
552 break;
553 }
554 }
555 }
556
557 if(pos!=Line.Length()) {
558 for(endpos = pos;endpos<=Line.Length();endpos++) {
559 if(Line[endpos] == ' ') {
560 endpos--;
561 break;
562 }
563 if(Line[endpos] == '(') {
564 endpos--;
565 break;
566 }
567 if(Line[endpos] == '{') {
568 endpos--;
569 break;
570 }
571 if(Line[endpos] == ')') {
572 endpos--;
573 break;
574 }
575 if(Line[endpos] == '}') {
576 endpos--;
577 break;
578 }
579 if(Line[endpos] == '/') {
580 endpos--;
581 break;
582 }
583 if(Line[endpos] == '=') {
584 endpos--;
585 break;
586 }
587 }
588 }
589 return Line.SubString(startpos,endpos-startpos+1);
590 }
591 //---------------------------------------------------------------------------
592 /**
593 * ステータスバー表示用の文字列を作る
594 */
595 AnsiString
596 TFScript::GetCaretString(void) {
597 AnsiString as;
598 int line_number = SendMessage(REScript->Handle,EM_LINEFROMCHAR,REScript->SelStart,0);
599 int line_pos = SendMessage(REScript->Handle,EM_LINEINDEX,line_number,0);
600 int pos = REScript->SelStart - line_pos;
601 as+=" "+IntToStr(line_number+1);
602 as+=": ";
603 as+=IntToStr(pos+1);
604 if(REScript->SelLength!=0) {
605 as+=" ("+IntToStr(REScript->SelLength)+")";
606 }
607 return as;
608 }
609 //---------------------------------------------------------------------------
610 /**
611 * ファイルスタンプをチェックする
612 * 外部で変更されていたら処理する
613 */
614 void
615 TFScript::CheckFileDate(void) {
616
617 if(FileName =="") {
618 return;
619 }
620 if(!FileExists(FileName)) {
621 return;
622 }
623 if(FileDate == FileAge(FileName)) {
624 return;
625 }
626
627 if(CopalConfig->AutoRefresh) {
628 LoadFromFile(FileName);
629 } else {
630 FileDate = FileAge(FileName);
631 PostMessage(FMain->Handle,WM_FILEUPDATED,0,0);
632 }
633 }
634 //---------------------------------------------------------------------------
635 void __fastcall
636 TFScript::REScriptChange(TObject *Sender) {
637 Modified = true;
638 FMain->UpdateCaption();
639 FMain->UpdateStatusBar();
640 }
641 //---------------------------------------------------------------------------
642 void __fastcall
643 TFScript::REScriptMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
644 FMain->UpdateStatusBar();
645 }
646 //---------------------------------------------------------------------------
647 void __fastcall
648 TFScript::REScriptKeyUp(TObject *Sender, WORD &Key, TShiftState Shift) {
649 FMain->UpdateStatusBar();
650 FMain->UpdateMenu();
651 }
652 //---------------------------------------------------------------------------
653 void __fastcall
654 TFScript::REScriptMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) {
655 FMain->UpdateStatusBar();
656 }
657 //---------------------------------------------------------------------------
658

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26