OSDN Git Service

TEditor、TTaskTrayの配布先変更に追従
[winbottle/winbottle.git] / bottleclient / SettingForm.pas
1 unit SettingForm;
2
3 {
4   \90Ý\92è\89æ\96Ê\81B\82»\82ê\96¢\96\9e\82Å\82à\82»\82ê\88È\8fã\82Å\82à\82È\82¢\81B
5   Pref\83I\83u\83W\83F\83N\83g\82ð\8eÀ\8dÛ\82É\91\80\8dì\82·\82é\81B
6 }
7
8 interface
9
10 uses
11   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
12   ComCtrls, StdCtrls, ExtCtrls, BottleDef, Spin,
13   CPCConfigTreeView, ColorSettingFrame, BottleChainListFrame, SakuraSeekerInstance,
14   ImgList, StrListEditor, SppList, Plugins, Clipbrd, SsPlayTime, StrUtils,
15   SpecialCharEditor, ReplacePresetListFrame;
16
17 type
18   TfrmSetting = class(TForm)
19     PageControl: TPageControl;
20     btnClose: TButton;
21     tstGeneral: TTabSheet;
22     tstDisplay: TTabSheet;
23     tstKeys: TTabSheet;
24     rgpWhenReturn: TRadioGroup;
25     rgpWhenShiftReturn: TRadioGroup;
26     rgpWhenCtrlReturn: TRadioGroup;
27     memDefaultScript: TMemo;
28     lblDefaultScript: TLabel;
29     tstReceive: TTabSheet;
30     OpenDialog: TOpenDialog;
31     spnWaitScriptEnd: TSpinEdit;
32     lblWaitScriptEnd: TLabel;
33     cbxConfirmOnExit: TCheckBox;
34     ctvBottle: TCPCConfigTreeView;
35     gbxColor: TGroupBox;
36     frmColorSetting: TfrmColorSetting;
37     tstRule: TTabSheet;
38     frmRuleList: TfrmBottleChainList;
39     tstDetailed: TTabSheet;
40     lblFMOName: TLabel;
41     memFMOName: TMemo;
42     tstChannel: TTabSheet;
43     lblAutoJoinChannels: TLabel;
44     memAutoJoinChannels: TMemo;
45     cbxAutoStart: TCheckBox;
46     btnUseCurrentJoinChannels: TButton;
47     ImageList: TImageList;
48     tstSurfacePreview: TTabSheet;
49     lblSurfacePreview: TLabel;
50     lvwPluginList: TListView;
51     lblPluginList: TLabel;
52     ctvSurfacePreview: TCPCConfigTreeView;
53     btnVisibleGhosts: TButton;
54     cbxHideGhosts: TCheckBox;
55     cbxNoExtraSSTPHeaders: TCheckBox;
56     lblLUID: TLabel;
57     edtLUID: TEdit;
58     cbxShowRuler: TCheckBox;
59     rgpTabPosition: TRadioGroup;
60     lblGhostDropDownCount: TLabel;
61     spnGhostDropDownCount: TSpinEdit;
62     cbxIgnoreTimeCritical: TCheckBox;
63     cbxAutoClip: TCheckBox;
64     btnCopyLUID: TButton;
65     tvwCategory: TTreeView;
66     Label1: TLabel;
67     pnlHeading: TPanel;
68     cbxConfirmOnTabClose: TCheckBox;
69     tstConnection: TTabSheet;
70     grpProxy: TGroupBox;
71     lblProxyAddress: TLabel;
72     lblProxyPort: TLabel;
73     Label6: TLabel;
74     edtProxyAddress: TEdit;
75     edtProxyPort: TEdit;
76     cbxUseHttpProxy: TCheckBox;
77     spnReconnectWait: TSpinEdit;
78     lblReconnectWait: TLabel;
79     lblPartialConfirmFormat: TLabel;
80     edtPartialConfirmFormat: TEdit;
81     cbxAutoPartialConfirm: TCheckBox;
82     tstPlayTime: TTabSheet;
83     grpPlayTimeParams: TGroupBox;
84     lblPlayTimeProfile: TLabel;
85     cbxPlayTimeProfile: TComboBox;
86     spnCostDBChar: TSpinEdit;
87     spnCostWait: TSpinEdit;
88     spnCostSurface: TSpinEdit;
89     spnCostChar: TSpinEdit;
90     spnCostQuickChar: TSpinEdit;
91     lblCostWait: TLabel;
92     lblCostSurface: TLabel;
93     lblCostChar: TLabel;
94     lblCostDBChar: TLabel;
95     lblCostQuickChar: TLabel;
96     btnSavePlayTimeProfile: TButton;
97     lvwCostSpecials: TListView;
98     lblCostSpecials: TLabel;
99     btnPlaySpecialAdd: TButton;
100     btnPlaySpecialDelete: TButton;
101     gbxTabWidth: TGroupBox;
102     cbxAutoTabWidth: TCheckBox;
103     spnTabWidth: TSpinEdit;
104     lblBrowser: TLabel;
105     edtBrowserName: TEdit;
106     BrowserLocateOpenDialog: TOpenDialog;
107     btnBrowserLocate: TButton;
108     tstPresetReplace: TTabSheet;
109     ReplacePresetList: TfrmReplacePresetList;
110     cbxAskUseHttpProxy: TCheckBox;
111     cbxNoWarnOfEmptyFMO: TCheckBox;
112     procedure FormClose(Sender: TObject; var Action: TCloseAction);
113     procedure edtProxyPortKeyPress(Sender: TObject; var Key: Char);
114     procedure ctvBottleNodeChecked(Sender: TObject;
115       Node: TCPCConfigItemNode);
116     procedure ctvBottleNodeChecking(Sender: TObject;
117       Node: TCPCConfigItemNode; var Allow: Boolean);
118     procedure tstRuleShow(Sender: TObject);
119     procedure btnUseCurrentJoinChannelsClick(Sender: TObject);
120     procedure btnVisibleGhostsClick(Sender: TObject);
121     procedure lvwPluginListDblClick(Sender: TObject);
122     procedure edtLUIDEnter(Sender: TObject);
123     procedure edtLUIDExit(Sender: TObject);
124     procedure btnCopyLUIDClick(Sender: TObject);
125     procedure FormCreate(Sender: TObject);
126     procedure tvwCategoryChange(Sender: TObject; Node: TTreeNode);
127     procedure tvwCategoryMouseMove(Sender: TObject; Shift: TShiftState; X,
128       Y: Integer);
129     procedure cbxPlayTimeProfileChange(Sender: TObject);
130     procedure btnSavePlayTimeProfileClick(Sender: TObject);
131     procedure spnCostWaitChange(Sender: TObject);
132     procedure btnPlaySpecialAddClick(Sender: TObject);
133     procedure btnPlaySpecialDeleteClick(Sender: TObject);
134     procedure lvwCostSpecialsDblClick(Sender: TObject);
135     procedure spnTabWidthChange(Sender: TObject);
136     procedure cbxAutoTabWidthClick(Sender: TObject);
137     procedure btnBrowserLocateClick(Sender: TObject);
138     procedure tstPresetReplaceShow(Sender: TObject);
139   private
140     { Private \90é\8c¾ }
141     FOldLUID: String;
142     FSpinUpdateFlag: boolean;
143     procedure LoadPlayTimeProfiles;
144     procedure PlayTimeParamsToSpinControl(Params: TSsPlayTimeParams);
145     procedure SpinControlToPlayTimeParams(Params: TSsPlayTimeParams);
146     procedure UpdateSpecialChars;
147   public
148     { Public \90é\8c¾ }
149     procedure Execute;
150   end;
151
152 var
153   frmSetting: TfrmSetting;
154
155 const
156   DefaultNode = -1;
157   ChannelDefaultGhost = '(\83`\83\83\83\93\83l\83\8b\90\84\8f§\83S\81[\83X\83g)';
158   CheckedBottle = 22;
159   UnCheckedBottle = 17;
160
161 implementation
162
163 {$R *.DFM}
164
165 const
166   SettingIcon = 4;
167
168 procedure TfrmSetting.Execute;
169 var i: integer;
170     Node: TCPCGroupNode;
171 begin
172   PageControl.ActivePage := tstGeneral;
173   memDefaultScript.Text := Pref.DefaultScript;
174   cbxShowRuler.Checked := Pref.ShowRuler;
175   cbxIgnoreTimeCritical.Checked := Pref.IgnoreTimeCritical;
176   edtPartialConfirmFormat.Text := Pref.PartialConfirmFormat;
177   cbxAutoPartialConfirm.Checked := Pref.AutoPartialConfirm;
178   cbxConfirmOnExit.Checked := Pref.ConfirmOnExit;
179   cbxConfirmOnTabClose.Checked := Pref.ConfirmOnTabClose;
180   cbxAutoClip.Checked := Pref.AutoClip;
181   //
182   with frmColorSetting do begin
183     Color['H'] := Pref.TalkColorH;
184     Color['U'] := Pref.TalkColorU;
185     Color['Synchro'] := Pref.TalkColorS;
186     Color['Tag'] := Pref.MarkUpColor;
187     Color['Meta'] := Pref.MetaWordColor;
188     Color['Error'] := Pref.MarkErrorColor;
189     Color['Text'] := Pref.TextColor;
190     Color['Background'] := Pref.BgColor;
191   end;
192   //
193   cbxPlayTimeProfile.Items.Clear;
194   cbxPlayTimeProfile.Items.Add(Pref.PlayTimeParams.ProfileName);
195   cbxPlayTimeProfile.ItemIndex := 0;
196   LoadPlayTimeProfiles;
197   PlayTimeParamsToSpinControl(Pref.PlayTimeParams);
198   UpdateSpecialChars;
199   //
200   cbxAutoStart.Checked := Pref.AutoStart;
201   rgpTabPosition.ItemIndex := Ord(Pref.TabPosition);
202   spnTabWidth.Value := Pref.TabWidth;
203   if Pref.TabWidth <= 0 then
204     spnTabWidth.Value := 0;
205   cbxAutoTabWidth.Checked := Pref.TabWidth <= 0;
206   spnGhostDropDownCount.Value := Pref.GhostDropDownCount;
207   try
208     with ctvBottle do begin
209       (GetNodeFromKeyPath('Arrive\NoTranslate') as TCPCCheckBoxNode).Checked := Pref.NoTranslate;
210       (GetNodeFromKeyPath('Arrive\NoDescript') as TCPCCheckBoxNode).Checked := Pref.NoDescript;
211       if Pref.NoTransUrl then
212         (GetNodeFromKeyPath('Arrive\UrlTag\NoSelection') as TCPCRadioNode).Check
213       else
214         (GetNodeFromKeyPath('Arrive\UrlTag\WithSelection') as TCPCRadioNode).Check;
215       (GetNodeFromKeyPath('Arrive\SilentWhenHidden') as TCPCCheckBoxNode).Checked := Pref.SilentWhenHidden;
216       (GetNodeFromKeyPath('Arrive\FixMessySurface') as TCPCCheckBoxNode).Checked := Pref.FixMessySurface;
217       (GetNodeFromKeyPath('Arrive\HUTagTo01Tag') as TCPCCheckBoxNode).Checked := Pref.HUTagTo01Tag;
218       (GetNodeFromKeyPath('Out\ResetIfGhostAfterSend') as TCPCCheckBoxNode).Checked := Pref.ResetIfGhostAfterSend;
219       (GetNodeFromKeyPath('Out\ClearAfterSend') as TCPCCheckBoxNode).Checked := Pref.ClearAfterSend;
220       (GetNodeFromKeyPath('Out\NeedConfirmBeforeSend') as TCPCCheckBoxNode).Checked := Pref.NeedConfirmBeforeSend;
221       (GetNodeFromKeyPath('Out\Confirm') as TCPCCheckBoxNode).Checked := not Pref.NoConfirm;
222       (GetNodeFromKeyPath('Out\Warn\ScopeChangeInSynchronize') as TCPCCheckBoxNode).Checked := Pref.WarnScopeChangeInSynchronize;
223       (GetNodeFromKeyPath('Out\Warn\YenTNotExist') as TCPCCheckBoxNode).Checked := Pref.WarnYenTNotExist;
224     end;
225   except
226     on E: Exception do ShowMessage(E.Message);
227   end;
228   //cbxIgnoreFrequentYenS.Checked := Pref.IgnoreFrequentYenS;
229   spnWaitScriptEnd.Value := Pref.WaitScriptEnd;
230   //
231   rgpWhenReturn.ItemIndex := Ord(Pref.WhenReturn);
232   rgpWhenShiftReturn.ItemIndex := Ord(Pref.WhenShiftReturn);
233   rgpWhenCtrlReturn.ItemIndex := Ord(Pref.WhenCtrlReturn);
234   //
235   cbxUseHttpProxy.Checked := Pref.UseHttpProxy;
236   cbxAskUseHttpProxy.Checked := Pref.AskUseHttpProxy;
237   edtProxyAddress.Text := Pref.ProxyAddress;
238   edtProxyPort.Text := IntToStr(Pref.ProxyPort);
239   //
240   spnReconnectWait.Value := Pref.ReconnectWait;
241   //
242   edtLUID.Text := Pref.LUID;
243   //
244   memFMOName.Lines := Pref.FMOName;
245   cbxHideGhosts.Checked := Pref.HideGhosts;
246   memAutoJoinChannels.Lines := Pref.AutoJoinChannels;
247   cbxNoExtraSSTPHeaders.Checked := Pref.NoExtraSSTPHeaders;
248   //
249   with ctvSurfacePreview do
250   begin
251     (GetNodeFromKeyPath('OnHint\DoPreview') as TCPCCheckBoxNode).Checked := Pref.SurfacePreviewOnHint;
252     (GetNodeFromKeyPath('OnScriptPoint\DoPreview') as TCPCCheckBoxNode).Checked := Pref.SurfacePreviewOnScriptPoint;
253     Node := GetNodeFromKeyPath('OnScriptPoint\Position') as TCPCGroupNode;
254     (Node.Item[Ord(Pref.SurfacePreviewOnScriptPointPosition)] as TCPCRadioNode).Check;
255   end;
256   for i := 0 to Spps.Count-1 do
257   begin
258     with lvwPluginList.Items.Add do
259     begin
260       Caption := ExtractFileName(Spps.SppItem[i].ModuleName);
261       SubItems.Add(Spps.SppItem[i].PluginName);
262     end;
263   end;
264   edtBrowserName.Text := Pref.BrowserExeName;
265   cbxNoWarnOfEmptyFMO.Checked := Pref.NoWarnOfEmptyFMO;
266
267   //
268   ShowModal;
269 end;
270
271 procedure TfrmSetting.FormClose(Sender: TObject; var Action: TCloseAction);
272 var i: integer;
273     Node: TCPCGroupNode;
274 begin
275   Pref.DefaultScript := memDefaultScript.Text;
276   Pref.ShowRuler := cbxShowRuler.Checked;
277   Pref.IgnoreTimeCritical := cbxIgnoreTimeCritical.Checked;
278   Pref.PartialConfirmFormat := edtPartialConfirmFormat.Text;
279   Pref.AutoPartialConfirm := cbxAutoPartialConfirm.Checked;
280   Pref.ConfirmOnExit := cbxConfirmOnExit.Checked;
281   Pref.ConfirmOnTabClose := cbxConfirmOnTabClose.Checked;
282   Pref.AutoClip := cbxAutoClip.Checked;
283   //
284   with frmColorSetting do begin
285     Pref.TalkColorH := Color['H'];
286     Pref.TalkColorU := Color['U'];
287     Pref.TalkColorS := Color['Synchro'];
288     Pref.MarkUpColor := Color['Tag'];
289     Pref.MetaWordColor := Color['Meta'];
290     Pref.MarkErrorColor := Color['Error'];
291     Pref.TextColor := Color['Text'];
292     Pref.BgColor := Color['Background'];
293   end;
294   //
295   Pref.PlayTimeParams.ProfileName := cbxPlayTimeProfile.Text;
296   SpinControlToPlayTimeParams(Pref.PlayTimeParams);
297   //
298   Pref.AutoStart := cbxAutoStart.Checked;
299   Pref.TabPosition := TTabPosition(rgpTabPosition.ItemIndex);
300   Pref.TabWidth := spnTabWidth.Value;
301   if cbxAutoTabWidth.Checked then
302     Pref.TabWidth := 0;
303   Pref.GhostDropDownCount := spnGhostDropDownCount.Value;
304   try
305     with ctvBottle do begin
306       Pref.NoTranslate := (GetNodeFromKeyPath('Arrive\NoTranslate') as TCPCCheckBoxNode).Checked;
307       Pref.NoDescript := (GetNodeFromKeyPath('Arrive\NoDescript') as TCPCCheckBoxNode).Checked;
308       Pref.NoTransUrl := (GetNodeFromKeyPath('Arrive\UrlTag\NoSelection') as TCPCRadioNode).Checked;
309       Pref.SilentWhenHidden := (GetNodeFromKeyPath('Arrive\SilentWhenHidden') as TCPCCheckBoxNode).Checked;
310       Pref.FixMessySurface := (GetNodeFromKeyPath('Arrive\FixMessySurface') as TCPCCheckBoxNode).Checked;
311       Pref.HUTagTo01Tag := (GetNodeFromKeyPath('Arrive\HUTagTo01Tag') as TCPCCheckBoxNode).Checked;
312       Pref.ResetIfGhostAfterSend := (GetNodeFromKeyPath('Out\ResetIfGhostAfterSend') as TCPCCheckBoxNode).Checked;
313       Pref.ClearAfterSend := (GetNodeFromKeyPath('Out\ClearAfterSend') as TCPCCheckBoxNode).Checked;
314       Pref.NeedConfirmBeforeSend := (GetNodeFromKeyPath('Out\NeedConfirmBeforeSend') as TCPCCheckBoxNode).Checked;
315       Pref.NoConfirm := not (GetNodeFromKeyPath('Out\Confirm') as TCPCCheckBoxNode).Checked;
316       Pref.WarnYenTNotExist := (GetNodeFromKeyPath('Out\Warn\YenTNotExist') as TCPCCheckBoxNode).Checked;
317       Pref.WarnScopeChangeInSynchronize := (GetNodeFromKeyPath('Out\Warn\ScopeChangeInSynchronize') as TCPCCheckBoxNode).Checked;
318     end;
319   except
320     on E: Exception do ShowMessage(E.Message);
321   end;
322   //Pref.IgnoreFrequentYenS := cbxIgnoreFrequentYenS.Checked;
323   Pref.WaitScriptEnd := spnWaitScriptEnd.Value;
324   //
325   Pref.WhenReturn := TReturnKeyFunction(rgpWhenReturn.ItemIndex);
326   Pref.WhenShiftReturn := TReturnKeyFunction(rgpWhenShiftReturn.ItemIndex);
327   Pref.WhenCtrlReturn := TReturnKeyFunction(rgpWhenCtrlReturn.ItemIndex);
328   //
329   Pref.UseHttpProxy := cbxUseHttpProxy.Checked;
330   Pref.AskUseHttpProxy := cbxAskUseHttpProxy.Checked;
331   Pref.ProxyAddress := edtProxyAddress.Text;
332   Pref.ProxyPort := StrToInt(edtProxyPort.Text);
333   //
334   Pref.ReconnectWait := spnReconnectWait.Value;
335   //
336   Pref.LUID := edtLUID.Text;
337   //
338   Pref.FMOName := memFMOName.Lines;
339   SakuraSeeker.FileMappingTarget := Pref.FMOName;
340   Pref.HideGhosts := cbxHideGhosts.Checked;
341   Pref.NoExtraSSTPHeaders := cbxNoExtraSSTPHeaders.Checked;
342   //
343   Pref.AutoJoinChannels := memAutoJoinChannels.Lines;
344   //
345   with ctvSurfacePreview do
346   begin
347     Pref.SurfacePreviewOnHint := (GetNodeFromKeyPath('OnHint\DoPreview') as TCPCCheckBoxNode).Checked;
348     Pref.SurfacePreviewOnScriptPoint := (GetNodeFromKeyPath('OnScriptPoint\DoPreview') as TCPCCheckBoxNode).Checked;
349     Node := GetNodeFromKeyPath('OnScriptPoint\Position') as TCPCGroupNode;
350     for i := 0 to Node.Count-1 do
351       if (Node.Item[i] as TCPCRadioNode).Checked then
352         Pref.SurfacePreviewOnScriptPointPosition := TSurfacePreviewOnScriptPointPosition(i);
353   end;
354   //
355   Pref.BrowserExeName := edtBrowserName.Text;
356   Pref.NoWarnOfEmptyFMO := cbxNoWarnOfEmptyFMO.Checked;
357 end;
358
359 procedure TfrmSetting.edtProxyPortKeyPress(Sender: TObject; var Key: Char);
360 begin
361   if not(Key in ['0'..'9']) then Key := Char(0);
362 end;
363
364 procedure TfrmSetting.ctvBottleNodeChecked(Sender: TObject;
365   Node: TCPCConfigItemNode);
366 begin
367   //ShowMessage(ctvBottle.GetFullKeyPath(Node));
368 end;
369
370 procedure TfrmSetting.ctvBottleNodeChecking(Sender: TObject;
371   Node: TCPCConfigItemNode; var Allow: Boolean);
372 begin
373   if Node.KeyName = 'IgnoreBottle' then begin
374     MessageDlg('\82±\82Ì\8b@\94\\82Í\8eÀ\91\95\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ', mtError, [mbOk], 0);
375     Allow := false;
376   end;
377 end;
378
379 procedure TfrmSetting.tstRuleShow(Sender: TObject);
380 begin
381   frmRuleList.UpdateDisplay;
382 end;
383
384 procedure TfrmSetting.btnUseCurrentJoinChannelsClick(Sender: TObject);
385 begin
386   memAutoJoinChannels.Lines := JoinChannels;
387 end;
388
389 procedure TfrmSetting.btnVisibleGhostsClick(Sender: TObject);
390 var i: integer;
391     FullGhosts: TStringList;
392 begin
393   FullGhosts := TStringList.Create;
394   SakuraSeeker.BeginDetect;
395   try
396     for i := 0 to SakuraSeeker.Count-1 do
397       FullGhosts.Add(SakuraSeeker[i].Name);
398     StrListEdit(Pref.VisibleGhostsList, '\83S\81[\83X\83g\82ð\8ew\92è', true, FullGhosts);
399   finally
400     FullGhosts.Free;
401   end;
402 end;
403
404 procedure TfrmSetting.lvwPluginListDblClick(Sender: TObject);
405 var Index: integer;
406 begin
407   if lvwPluginList.Selected = nil then
408     Exit;
409   Index := lvwPluginList.Selected.Index;
410   if pfConfigure in Spps.SppItem[Index].PluginFunctions then
411     Spps.SppItem[Index].Configure
412   else
413     ShowMessage('\92Ç\89Á\82Ì\90Ý\92è\8d\80\96Ú\82Í\82 \82è\82Ü\82¹\82ñ\81B');
414 end;
415
416 procedure TfrmSetting.edtLUIDEnter(Sender: TObject);
417 begin
418   FOldLUID := edtLUID.Text;
419 end;
420
421 procedure TfrmSetting.edtLUIDExit(Sender: TObject);
422 var TmpLUID: String;
423     i: integer;
424     Err: boolean;
425 begin
426   TmpLUID := edtLUID.Text;
427   i := 1;
428   Err := false;
429   if Length(TmpLUID) <> 82 then
430     Err := true
431   else
432     while i <= Length(TmpLUID) do
433     begin
434       if not (TmpLUID[i] in ['0'..'9', 'a'..'z', 'A'..'Z', '.', ',']) then
435       begin
436         Err := true;
437         Break;
438       end;
439       Inc(i);
440     end;
441   if Err then
442   begin
443     ShowMessage('LUID\82Ì\93à\97e\82ª\95s\90³\82Å\82·');
444     edtLUID.Text := FOldLUID;
445   end;
446 end;
447
448 procedure TfrmSetting.btnCopyLUIDClick(Sender: TObject);
449 begin
450   Clipboard.SetTextBuf(PChar(edtLUID.Text));
451 end;
452
453 procedure TfrmSetting.FormCreate(Sender: TObject);
454 var
455   i: integer;
456   Cap: String;
457   Node: TTreeNode;
458 begin
459   for i := 0 to PageControl.PageCount-1 do
460   begin
461     Cap := PageControl.Pages[i].Caption;
462     if Pos(':', Cap) > 0 then
463       Cap := Copy(Cap, 1, Pos(':', Cap)-1);
464     Node := tvwCategory.Items.Add(nil, Cap);
465     Node.ImageIndex := -1;
466     Node.SelectedIndex := SettingIcon;
467   end;
468   tvwCategoryChange(Self, tvwCategory.Items[0]);
469   tvwCategory.Items[0].Selected := true;
470 end;
471
472 procedure TfrmSetting.tvwCategoryChange(Sender: TObject; Node: TTreeNode);
473 begin
474   PageControl.ActivePageIndex := Node.Index;
475   pnlHeading.Caption := PageControl.ActivePage.Caption;
476 end;
477
478 procedure TfrmSetting.tvwCategoryMouseMove(Sender: TObject;
479   Shift: TShiftState; X, Y: Integer);
480 var
481   Node: TTreeNode;
482   NewHint: String;
483   CPos: TPoint;
484 begin
485   Node := tvwCategory.GetNodeAt(X, Y);
486   if Node <> nil then
487   begin
488     NewHint := PageControl.Pages[Node.Index].Caption;
489     if tvwCategory.Hint <> NewHint then
490     begin
491       tvwCategory.Hint := NewHint;
492       GetCursorPos(CPos);
493       Application.ActivateHint(CPos);
494     end;
495   end else
496   begin
497     tvwCategory.Hint := '';
498     Application.HideHint;
499   end;
500 end;
501
502 procedure TfrmSetting.PlayTimeParamsToSpinControl(Params: TSsPlayTimeParams);
503 begin
504   FSpinUpdateFlag := true;
505   with Params do
506   begin
507     spnCostWait.Value         := CostWait;
508     spnCostSurface.Value      := CostSurface;
509     spnCostChar.Value         := CostChar;
510     spnCostDBChar.Value       := CostDBChar;
511     spnCostQuickChar.Value    := CostQuickChar;
512     lvwCostSpecials.Items.Clear;
513   end;
514   FSpinUpdateFlag := false;
515 end;
516
517 procedure TfrmSetting.SpinControlToPlayTimeParams(Params: TSsPlayTimeParams);
518 begin
519   with Params do
520   begin
521     CostWait         := spnCostWait.Value;
522     CostSurface      := spnCostSurface.Value;
523     CostChar         := spnCostChar.Value;
524     CostDBChar       := spnCostDBChar.Value;
525     CostQuickChar    := spnCostQuickChar.Value;
526   end;
527 end;
528
529
530 procedure TfrmSetting.LoadPlayTimeProfiles;
531 var i: integer;
532     F: TSearchRec;
533     Path, Item: String;
534 begin
535   Path := ExtractFilePath(Application.ExeName);
536   i := FindFirst(Path + 'playtime\*.txt', 0, F);
537   if i = 0 then begin
538     repeat
539       Item := ChangeFileExt(F.Name, '');
540       if cbxPlayTimeProfile.Items.IndexOf(Item) < 0 then
541         cbxPlayTimeProfile.Items.Add(ChangeFileExt(F.Name, ''));
542       i := FindNext(F);
543     until i <> 0;
544   end;
545   FindClose(F);
546 end;
547
548 procedure TfrmSetting.cbxPlayTimeProfileChange(Sender: TObject);
549 var
550   Params: TSsPlayTimeParams;
551   Strs: TStringList;
552   Path, ProName: String;
553 begin
554   try
555     Strs := TStringList.Create;
556     ProName := cbxPlayTimeProfile.Text;
557     try
558       Path := ExtractFilePath(Application.ExeName) + 'playtime\';
559       Strs.LoadFromFile(Path + ProName + '.txt');
560       Params := StringToComponent(Strs.Text) as TSsPlayTimeParams;
561       try
562         PlayTimeParamsToSpinControl(Params);
563         Pref.PlayTimeParams.Assign(Params);
564         UpdateSpecialChars;
565       finally
566         Params.Free;
567       end;
568     finally
569       Strs.Free;
570     end;
571     with cbxPlayTimeProfile do
572     begin
573       Items.Clear;
574       LoadPlayTimeProfiles;
575       ItemIndex := Items.IndexOf(ProName);
576     end;
577   except
578     ; // Do nothing
579   end;
580 end;
581
582 procedure TfrmSetting.btnSavePlayTimeProfileClick(Sender: TObject);
583 var
584   ProfileName, Path, FileName: String;
585   Strs: TStringList;
586 begin
587   ProfileName := cbxPlayTimeProfile.Text;
588   if InputQuery('\83v\83\8d\83t\83@\83C\83\8b\96¼', '\95Û\91\82·\82é\83v\83\8d\83t\83@\83C\83\8b\96¼', ProfileName) then
589   begin
590     try
591       Path := ExtractFilePath(Application.ExeName) + 'playtime\';
592       FileName := Path + ProfileName + '.txt';
593       if FileExists(FileName) then
594         if MessageDlg(Format('\83v\83\8d\83t\83@\83C\83\8b"%s"\82ð\8fã\8f\91\82«\82µ\82Ü\82·', [ProfileName]),
595           mtConfirmation, mbOkCancel, 0) = mrCancel then
596           Exit;
597       Strs := TStringList.Create;
598       try
599         SpinControlToPlayTimeParams(Pref.PlayTimeParams);
600         Pref.PlayTimeParams.ProfileName := ProfileName;
601         Strs.Text := ComponentToString(Pref.PlayTimeParams);
602         Strs.SaveToFile(FileName);
603       finally
604         Strs.Free;
605       end;
606       with cbxPlayTimeProfile do
607       begin
608         Items.Clear;
609         Items.Add(ProfileName);
610         ItemIndex := 0;
611         LoadPlayTimeProfiles;
612       end;
613     except
614       on E: Exception do
615         ShowMessage('\95Û\91\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B' + E.Message);
616     end;
617   end;
618 end;
619
620 procedure TfrmSetting.spnCostWaitChange(Sender: TObject);
621 var
622   ProName: String;
623 const
624   Modified = '(\95Ï\8dX\8dÏ\82Ý)';
625 begin
626   if FSpinUpdateFlag then
627     Exit;
628   ProName := cbxPlayTimeProfile.Text;
629   if Copy(ProName, Length(ProName)-Length(Modified)+1, Length(Modified)) <> Modified then
630   begin
631     ProName := Format('%s%s', [ProName, Modified]);
632     with cbxPlayTimeProfile do
633     begin
634       Items.Clear;
635       Items.Add(ProName);
636       ItemIndex := 0;
637       LoadPlayTimeProfiles;
638     end;
639   end;
640 end;
641
642 procedure TfrmSetting.btnPlaySpecialAddClick(Sender: TObject);
643 var
644   Item: TListItem;
645   SPChar: TSsPlayTimeSpecialChar;
646 begin
647   Application.CreateForm(TfrmSpecialCharEditor, frmSpecialCharEditor);
648   try
649     with frmSpecialCharEditor do
650     begin
651       SpecialChar := '';
652       Cost := 50;
653       if Execute then
654       begin
655         SPChar := Pref.PlayTimeParams.SpecialChars.Add as TSsPlayTimeSpecialChar;
656         SPChar.Char := SpecialChar;
657         SPChar.Wait := Cost;
658         Item := lvwCostSpecials.Items.Add;
659         Item.Caption := SPChar.DisplayChar;
660         Item.SubItems.Add(IntToStr(Cost));
661         spnCostWaitChange(Self);
662       end;
663     end;
664   finally
665     frmSpecialCharEditor.Release;
666   end;
667 end;
668
669 procedure TfrmSetting.btnPlaySpecialDeleteClick(Sender: TObject);
670 begin
671   with lvwCostSpecials do
672     if Selected <> nil then
673     begin
674       Pref.PlayTimeParams.SpecialChars.Delete(Selected.Index);
675       Selected.Delete;
676       spnCostWaitChange(Self);
677     end;
678 end;
679
680 procedure TfrmSetting.lvwCostSpecialsDblClick(Sender: TObject);
681 var
682   Item: TListItem;
683   SPChar: TSsPlayTimeSpecialChar;
684 begin
685   with lvwCostSpecials do
686   begin
687     Item := Selected;
688     if Item <> nil then
689     begin
690       Application.CreateForm(TfrmSpecialCharEditor, frmSpecialCharEditor);
691       try
692         with frmSpecialCharEditor do
693         begin
694           SPChar := Pref.PlayTimeParams.SpecialChars.Items[Item.Index] as TSsPlayTimeSpecialChar;
695           SpecialChar := SPChar.Char;
696           Cost := SPChar.Wait;
697           if Execute then
698           begin
699             SPChar.Char := SpecialChar;
700             SPChar.Wait := Cost;
701             Item.Caption := SPChar.DisplayChar;
702             Item.SubItems[0] := IntToStr(Cost);
703             spnCostWaitChange(Self);
704           end;
705         end;
706       finally
707         frmSpecialCharEditor.Release;
708       end;
709     end;
710   end;
711 end;
712
713 procedure TfrmSetting.UpdateSpecialChars;
714 var
715   i: integer;
716   Item: TListItem;
717   SPChar: TSsPlayTimeSpecialChar;
718 begin
719   with lvwCostSpecials do
720   begin
721     Items.Clear;
722     for i := 0 to Pref.PlayTimeParams.SpecialChars.Count-1 do
723     begin
724       SPChar := Pref.PlayTimeParams.SpecialChars.Items[i] as TSsPlayTimeSpecialChar;
725       Item := Items.Add;
726       Item.Caption := SPChar.DisplayChar;
727       Item.SubItems.Add(IntToStr(SPChar.Wait));
728     end;
729   end;
730 end;
731
732 procedure TfrmSetting.spnTabWidthChange(Sender: TObject);
733 begin
734   with cbxAutoTabWidth do
735   begin
736     OnClick := nil;
737     cbxAutoTabWidth.Checked := false;
738     OnClick := cbxAutoTabWidthClick;
739   end;
740 end;
741
742 procedure TfrmSetting.cbxAutoTabWidthClick(Sender: TObject);
743 begin
744   with spnTabWidth do
745   begin
746     OnChange := nil;
747     try
748       if not cbxAutoTabWidth.Checked then
749         if Value = 0 then
750           Value := 80;
751     finally
752       OnChange := spnTabWidthChange;
753     end;
754   end;
755 end;
756
757 procedure TfrmSetting.btnBrowserLocateClick(Sender: TObject);
758 begin
759   with BrowserLocateOpenDialog do
760   begin
761     FileName := edtBrowserName.Text;
762     if Execute then
763       edtBrowserName.Text := FileName;
764   end;
765 end;
766
767 procedure TfrmSetting.tstPresetReplaceShow(Sender: TObject);
768 begin
769   ReplacePresetList.UpdateControls;
770 end;
771
772 end.