6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ComCtrls, ToolWin, StdCtrls, ExtCtrls, SsParser, BottleDef, Menus,
8 Clipbrd, Logs, ShellAPI, Commctrl, DirectSstp, Contnrs, xmldom, XMLIntf,
12 TSaveLogType = (stLog, stLogWithChannels, stText, stXML);
14 TfrmLog = class(TForm)
16 tbtnClear: TToolButton;
19 StatusBar: TStatusBar;
20 tbtnSaveLog: TToolButton;
21 PopupMenuPreview: TPopupMenu;
23 tbtnVoteMessage: TToolButton;
24 PopupMenuListView: TPopupMenu;
25 mnPopUpVoteMessage: TMenuItem;
26 SaveDialog: TSaveDialog;
30 mnPopUpCopyScript: TMenuItem;
31 PopupMenuSaveLog: TPopupMenu;
33 mnSaveLogChannel: TMenuItem;
34 mnSaveLogScript: TMenuItem;
35 mnSaveLogXML: TMenuItem;
36 ToolButton1: TToolButton;
38 mnPopUpAgreeMessage: TMenuItem;
39 tbtnAgreeMessage: TToolButton;
40 ToolButton2: TToolButton;
41 tbtnPreviewStyle: TToolButton;
42 PopupMenuPreviewStyle: TPopupMenu;
43 mnPreviewStyleConversation: TMenuItem;
44 mnPreviewStyleScript: TMenuItem;
45 mnPreviewStyleScriptWithLineBreak: TMenuItem;
47 tabBottleLog: TTabControl;
49 tbtnDownloadLog: TToolButton;
50 PopupMenuTab: TPopupMenu;
51 mnCloseTab: TMenuItem;
52 tbtnFindBottle: TToolButton;
53 XMLDocument: TXMLDocument;
54 tbtnOpenLog: TToolButton;
55 OpenDialog: TOpenDialog;
56 tbtnInsertCue: TToolButton;
57 mnInsertCue: TMenuItem;
58 procedure tbtnClearClick(Sender: TObject);
59 procedure FormCreate(Sender: TObject);
60 procedure lvwLogChange(Sender: TObject; Item: TListItem;
62 procedure lvwLogDblClick(Sender: TObject);
63 procedure lvwLogKeyPress(Sender: TObject; var Key: Char);
64 procedure FormDestroy(Sender: TObject);
65 procedure lvwLogClick(Sender: TObject);
66 procedure mnSaveLogClick(Sender: TObject);
67 procedure lvwLogColumnClick(Sender: TObject; Column: TListColumn);
68 procedure mnPopUpCopyScriptClick(Sender: TObject);
69 procedure mnSaveLogChannelClick(Sender: TObject);
70 procedure mnSaveLogScriptClick(Sender: TObject);
71 procedure mnSaveLogXMLClick(Sender: TObject);
72 procedure lvwLogData(Sender: TObject; Item: TListItem);
73 procedure PopupMenuListViewPopup(Sender: TObject);
74 procedure lvwLogCustomDrawItem(Sender: TCustomListView;
75 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
76 procedure lvwLogCustomDrawSubItem(Sender: TCustomListView;
77 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
78 var DefaultDraw: Boolean);
79 procedure PopupMenuPreviewStylePopup(Sender: TObject);
80 procedure mnPreviewStyleClick(Sender: TObject);
81 procedure tbtnPreviewStyleClick(Sender: TObject);
82 procedure tabBottleLogChange(Sender: TObject);
83 procedure tabBottleLogChanging(Sender: TObject;
84 var AllowChange: Boolean);
85 procedure tabBottleLogContextPopup(Sender: TObject; MousePos: TPoint;
86 var Handled: Boolean);
87 procedure mnCloseTabClick(Sender: TObject);
88 procedure tbtnFindBottleClick(Sender: TObject);
89 procedure tbtnOpenLogClick(Sender: TObject);
90 procedure tabBottleLogMouseDown(Sender: TObject; Button: TMouseButton;
91 Shift: TShiftState; X, Y: Integer);
92 procedure tabBottleLogDragOver(Sender, Source: TObject; X, Y: Integer;
93 State: TDragState; var Accept: Boolean);
94 procedure tabBottleLogDragDrop(Sender, Source: TObject; X, Y: Integer);
95 procedure tabBottleLogEndDrag(Sender, Target: TObject; X, Y: Integer);
98 FLastScript: String; //
\83X
\83N
\83\8a\83v
\83g
\8dÄ
\95`
\89æ
\97}
\90§
\97p
99 FBottleLogList: TObjectList;
101 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
102 FDragTabDest: integer; //
\83h
\83\8d\83b
\83v
\82·
\82é
\88Ê
\92u(
\82·
\82®
\89E
\82É
\82
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X)
103 procedure UpdateScript(const Script: String);
104 procedure UpdateScriptConversationColor(const Script: String);
105 procedure UpdateScriptConversationNoColor(const Script: String);
106 procedure UpdateScriptScript(const Script: String);
107 procedure mnURLClick(Sender: TObject);
108 procedure ExtractURLs(Script: String; Result: TStrings);
109 function GetDefaultFileName(const Name: String; const Ext: String): String;
110 function BottleLogTitled(const LogName: String): TBottleLogList;
112 procedure CreateParams(var Params: TCreateParams); override;
115 function SelectedBottleLog: TBottleLogList;
116 property BottleLogList: TObjectList read FBottleLogList;
117 procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
118 procedure AddCurrentSystemLog(const LogName, MessageString: String);
119 procedure VoteLog(const MID: String; const Vote: integer);
120 procedure AgreeLog(const MID: String; const Agree: integer);
121 procedure SetBottleState(const MID: String; State: TLogState);
122 procedure AllBottleOpened;
123 procedure LogLoaded(Sender: TObject);
124 procedure LogLoadFailure(Sender: TObject; const Message: String);
125 procedure LogLoadWork(Sender: TObject);
127 procedure UpdateWindow;
128 procedure SelAndFocusMessage(const MID: String);
148 uses MainForm, StrUtils;
154 procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
157 BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost);
158 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
159 lvwLog.OnChange := nil; //
\83C
\83x
\83\93\83g
\94
\90¶(
\82¢
\82ë
\82¢
\82ë
\8dÄ
\95`
\89æ
\82ª
\8bN
\82«
\82é)
\82Ì
\97}
\90§
160 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
161 lvwLog.Items.Count := SelectedBottleLog.Count;
163 if Sel >= 0 then begin
164 lvwLog.Selected := lvwLog.Items[Sel + 1];
165 lvwLog.Selected.Focused := true;
167 if not lvwLog.Focused then
168 ListView_Scroll(lvwLog.Handle, 0, High(integer));
169 lvwLog.OnChange := lvwLogChange;
172 procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String);
175 BottleLogTitled(LogName).AddSystemLog(MessageString);
176 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
177 lvwLog.OnChange := nil;
178 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
179 lvwLog.Items.Count := SelectedBottleLog.Count;
181 if Sel >= 0 then begin
182 lvwLog.Selected := lvwLog.Items[Sel + 1];
183 lvwLog.Selected.Focused := true;
185 if not lvwLog.Focused then
186 ListView_Scroll(lvwLog.Handle, 0, High(integer));
187 lvwLog.OnChange := lvwLogChange;
192 procedure TfrmLog.tbtnClearClick(Sender: TObject);
194 if SelectedBottleLog = nil then Exit;
195 FBottleLogList.Delete(tabBottleLog.TabIndex);
196 tabBottleLog.TabIndex := 0;
199 lvwLogChange(Self, nil, ctState);
202 procedure TfrmLog.FormCreate(Sender: TObject);
205 FBottleLogList := TObjectList.Create;
207 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
208 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
210 with Pref.LogWindowPosition do begin
213 Self.Width := Right - Left + 1;
214 Self.Height := Bottom - Top + 1;
216 lvwLog.DoubleBuffered := true;
217 edtScript.Height := Pref.LogWindowDividerPos;
220 while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin
221 lvwLog.Columns[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100);
225 UpdateWindow; // Reset window color and enabled status of some buttons
228 procedure TfrmLog.FormDestroy(Sender: TObject);
233 for i := 0 to lvwLog.Columns.Count-1 do begin
234 if i > 0 then WidthStr := WidthStr + ',';
235 WidthStr := WidthStr + IntToStr(lvwLog.Column[i].Width);
237 Pref.LogWindowColumnWidth := WidthStr;
239 with Pref.LogWindowPosition do begin
242 Right := Self.Left + Self.Width - 1;
243 Bottom := Self.Top + Self.Height - 1;
245 Pref.LogWindowDividerPos := edtScript.Height;
247 FreeAndNil(FBottleLogList);
250 procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem;
251 Change: TItemChange);
255 if SelectedBottleLog <> nil then begin
256 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
257 if Change = ctState then begin
259 if lvwLog.Selected <> nil then begin
260 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
261 if (Log.LogType = ltBottle) and not frmSender.Connecting then begin
262 Script := Log.Script;
263 frmSender.actVoteMessage.Enabled := true;
264 frmSender.actAgreeMessage.Enabled := true;
265 frmSender.actInsertCue.Enabled := true;
266 mnPopUpCopyScript.Enabled := true;
267 UpdateScript(Script);
269 frmSender.actVoteMessage.Enabled := false;
270 frmSender.actAgreeMessage.Enabled := false;
271 frmSender.actInsertCue.Enabled := false;
272 mnPopUpCopyScript.Enabled := false;
273 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\82ð
\83N
\83\8a\83A
276 frmSender.actVoteMessage.Enabled := false;
277 frmSender.actAgreeMessage.Enabled := false;
278 frmSender.actInsertCue.Enabled := false;
279 mnPopUpCopyScript.Enabled := false;
280 UpdateScript(Script); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
283 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
285 StatusBar.Panels[0].Text := '
\83\8d\83O
\82ª
\82 \82è
\82Ü
\82¹
\82ñ';
286 frmSender.actVoteMessage.Enabled := false;
287 frmSender.actAgreeMessage.Enabled := false;
288 mnPopUpCopyScript.Enabled := false;
289 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
293 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
295 Opt: TScriptTransOptions;
296 SOpt: TSstpSendOptions;
300 if lvwLog.Selected = nil then Exit;
301 //Log := TLogItem(lvwLog.Selected.Data);
302 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
303 if Log = nil then Exit;
304 if Log.LogType <> ltBottle then Exit;
305 Script := Log.Script;
306 Opt := [toConvertURL, toWaitScriptEnd];
307 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
308 if Pref.IgnoreFrequentYenS then Opt := Opt + [toIgnoreFrequentYenS];
309 if Pref.FixMessySurface then Opt := Opt + [toFixMessySurface];
310 if Pref.HUTagTo01Tag then Opt := Opt + [toHUTagTo01Tag];
311 frmSender.DoTrans(Script, Opt);
313 if ChannelList.Channel[Log.Channel] <> nil then
314 Ghost := ChannelList.Channel[Log.Channel].Ghost;
315 //
\96Ú
\95W
\83S
\81[
\83X
\83g
\8c\88\92è
316 if Log.Ghost <> '' then Ghost := Log.Ghost;
317 //
\83^
\81[
\83Q
\83b
\83g
\83S
\81[
\83X
\83g
\8am
\92è
318 Ghost := frmSender.SetHWndToFavoriteGhost(Ghost);
319 frmSender.DirectSstp.SstpSender := 'SSTP Bottle -
\81y
\83\8d\83O
\8dÄ
\90¶
\81z';
320 if Pref.NoTranslate then SOpt := [soNoTranslate] else SOpt := [];
321 frmSender.DirectSstp.SstpSEND(Script, SOpt, frmSender.GhostNameToSetName(Ghost));
324 procedure TfrmLog.UpdateScriptConversationColor(const Script: String);
327 UnyuTalking, Talked, InSynchronized: boolean;
330 frmSender.DoTrans(scr, [toConvertURL]);
331 SsParser.LeaveEscape := false;
332 SsParser.InputString := scr;
333 SsParser.LeaveEscape := true;
334 UnyuTalking := false;
335 Talked := false; //'\h\u\h\u'
\82Ì
\82æ
\82¤
\82È
\83X
\83N
\83\8a\83v
\83g
\82Å
\8bó
\82«
\8ds
\82ð
\8dì
\82ç
\82È
\82¢
\82½
\82ß
\82Ì
\91[
\92u
336 InSynchronized := false;
337 edtScript.Text := '';
338 edtScript.Color := Pref.BgColor;
339 for i := 0 to SsParser.Count-1 do begin
340 if (SsParser[i] = '\_s') and not InSynchronized then begin
341 InSynchronized := true;
343 edtScript.SelText := #13#10;
346 end else if (SsParser[i] = '\_s') and InSynchronized then begin
347 InSynchronized := false;
349 edtScript.SelText := #13#10;
353 if (SsParser[i] = '\u') and not UnyuTalking then begin
356 edtScript.SelText := #13#10;
360 if (SsParser[i] = '\h') and UnyuTalking then begin
361 UnyuTalking := false;
363 edtScript.SelText := #13#10;
367 if SsParser.MarkUpType[i] = mtStr then begin
368 if InSynchronized then
369 edtScript.SelAttributes.Color := Pref.TalkColorS
370 else if UnyuTalking then
371 edtScript.SelAttributes.Color := Pref.TalkColorU
373 edtScript.SelAttributes.Color := Pref.TalkColorH;
374 edtScript.SelText := SsParser[i];
377 if SsParser.MarkUpType[i] = mtMeta then begin
378 edtScript.SelAttributes.Color := Pref.MetaWordColor;
379 edtScript.SelText := SsParser[i];
385 procedure TfrmLog.UpdateScriptConversationNoColor(const Script: String);
388 UnyuTalking, Talked, LastUnyuTalked, InSynchronize, LastInSynchronize: boolean;
391 frmSender.DoTrans(Scr, [toConvertURL]);
392 SsParser.LeaveEscape := false;
393 SsParser.InputString := Scr;
394 SsParser.LeaveEscape := true;
395 edtScript.Text := '';
396 edtScript.Color := clWindow;
397 edtScript.DefAttributes.Color := clWindowText;
398 edtScript.SelAttributes.Color := clWindowText;
400 UnyuTalking := false;
401 LastUnyuTalked := false;
402 InSynchronize := false;
403 LastInSynchronize := false;
404 for i := 0 to SsParser.Count-1 do begin
405 if SsParser[i] = '\u' then UnyuTalking := true;
406 if SsParser[i] = '\h' then UnyuTalking := false;
407 if SsParser[i] = '\_s' then InSynchronize := not InSynchronize;
408 if SsParser.MarkUpType[i] in [mtStr, mtMeta] then begin
409 if not Talked then begin //
\83X
\83N
\83\8a\83v
\83g
\8dÅ
\8f\89\82Ì
\83Z
\83\8a\83t
410 if InSynchronize then Scr := '
\97¼
\81F'
411 else if UnyuTalking then Scr := '
\82¤:' else Scr := '
\82³:';
413 if Talked and ((UnyuTalking <> LastUnyuTalked) or (InSynchronize <> LastInSynchronize)) then begin
415 if InSynchronize then Scr := Scr + '
\97¼
\81F'
416 else if UnyuTalking then Scr := Scr + '
\82¤:' else Scr := Scr + '
\82³:';
418 Scr := Scr + SsParser[i];
420 LastInSynchronize := InSynchronize;
421 LastUnyuTalked := UnyuTalking;
424 edtScript.Text := Scr;
427 procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char);
429 if Key = #13 then lvwLogDblClick(Sender);
432 procedure TfrmLog.CreateParams(var Params: TCreateParams);
435 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
438 procedure TfrmLog.lvwLogClick(Sender: TObject);
440 //
\89E
\83N
\83\8a\83b
\83N
\82Å
\83\81\83j
\83\85\81[
\8fo
\82·
\82Æ
\82«
\82É
\94
\90¶
\82·
\82é
\95s
\8bï
\8d\87\91Î
\8dô
442 Selected := Selected;
445 procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn);
446 var SortType: TBottleLogSortType;
450 if lvwLog.Selected <> nil then
451 SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID;
453 SortColumn := Column.Index;
455 -1: SortType := stLogTime;
456 subChannel: SortType := stChannel;
457 subGhost: SortType := stGhost;
458 subVotes: SortType := stVote;
459 subAgrees: SortType := stAgree;
460 subScript: SortType := stScript;
461 else SortType := stLogTime;
464 SelectedBottleLog.SortBottles(SortType);
466 SelAndFocusMessage(SelectedMID);
470 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
475 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.Selected.Index];
476 if Log = nil then Exit;
478 Clip.SetTextBuf(PChar(Log.Script));
481 procedure TfrmLog.SetBottleState(const MID: String; State: TLogState);
485 for i := 0 to FBottleLogList.Count-1 do begin
486 Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID);
487 if Bottle <> nil then begin
488 Bottle.State := State;
489 lvwLog.OnChange := nil;
491 lvwLog.OnChange := lvwLogChange;
496 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
498 if SelectedBottleLog = nil then Exit;
499 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
500 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
501 SaveDialog.DefaultExt := 'log';
502 SaveDialog.FilterIndex := 1;
503 if SaveDialog.Execute then
504 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false);
507 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
509 if SelectedBottleLog = nil then Exit;
510 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
511 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
512 SaveDialog.DefaultExt := 'log';
513 SaveDialog.FilterIndex := 1;
514 if SaveDialog.Execute then
515 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, true);
518 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
520 if SelectedBottleLog = nil then Exit;
521 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt');
522 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
523 SaveDialog.DefaultExt := 'txt';
524 SaveDialog.FilterIndex := 2;
525 if SaveDialog.Execute then
526 SelectedBottleLog.SaveToText(SaveDialog.FileName);
529 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
531 if SelectedBottleLog = nil then Exit;
532 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.xml');
533 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
534 SaveDialog.DefaultExt := 'xml';
535 SaveDialog.FilterIndex := 3;
536 if SaveDialog.Execute then
537 SelectedBottleLog.SaveToXmlFile(SaveDialog.FileName, XMLDocument);
540 procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem);
544 if Item = nil then Exit;
546 Log := SelectedBottleLog.Bottles[i];
548 Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime);
550 SubItems.Add(Log.Channel);
551 SubItems.Add(Log.Ghost);
552 if Log.LogType = ltBottle then begin
553 if Log.Votes > 0 then
554 SubItems.Add(IntToStr(Log.Votes))
557 if Log.Agrees > 0 then
558 SubItems.Add(IntToStr(Log.Agrees))
562 //
\83V
\83X
\83e
\83\80\83\8d\83O
\82È
\82Ç
\82Í
\93\8a\95[
\81E
\93¯
\88Ó
\82ð
\95\
\8e¦
\82µ
\82È
\82¢
566 SubItems.Add(Log.Script);
568 if Log.LogType = ltBottle then begin
570 lsUnopened: ImageIndex := IconBottle;
571 lsPlaying: ImageIndex := IconPlaying;
572 lsOpened: ImageIndex := IconOpened;
575 ImageIndex := IconSystemLog;
579 procedure TfrmLog.UpdateWindow;
580 var EnabledFlag: boolean;
582 if Pref.ColorScript then begin
583 if lvwLog.Color <> Pref.BgColor then lvwLog.Color := Pref.BgColor;
584 if lvwLog.Font.Color <> Pref.TalkColorH then lvwLog.Font.Color := Pref.TalkColorH;
586 if lvwLog.Color <> clWindow then lvwLog.Color := clWindow;
587 if lvwLog.Font.Color <> clWindowText then lvwLog.Font.Color := clWindowText;
589 if SelectedBottleLog <> nil then begin
590 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
591 lvwLog.Items.Count := SelectedBottleLog.Count;
593 StatusBar.Panels[0].Text := '
\83\8d\83O
\82ª
\82 \82è
\82Ü
\82¹
\82ñ';
594 lvwLog.Items.Count := 0;
597 EnabledFlag := SelectedBottleLog <> nil;
598 tbtnClear.Enabled := EnabledFlag;
599 tbtnSaveLog.Enabled := EnabledFlag;
600 tbtnFindBottle.Enabled := EnabledFlag;
605 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
611 for i := mnJumpURL.Count-1 downto 0 do begin
612 mnJumpURL.Items[i].Free;
614 mnJumpURL.Enabled := false;
615 if lvwLog.Selected = nil then Exit;
616 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
617 if Log = nil then Exit;
620 Urls := TStringList.Create;
621 ExtractURLs(Log.Script, Urls);
622 for i := 0 to Urls.Count-1 do begin
623 Child := TMenuItem.Create(Self);
625 Caption := Format('(&%d) %s', [i+1, Urls[i]]);
626 OnClick := mnURLClick;
627 AutoHotkeys := maManual;
628 mnJumpURL.Add(Child);
631 mnJumpURL.Enabled := Urls.Count > 0;
637 procedure TfrmLog.mnURLClick(Sender: TObject);
640 URL := (Sender as TMenuItem).Caption;
641 RegExp.Subst('s/^\(&?\d\) //', URL);
642 ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW);
645 procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings);
646 var i, u, j: integer;
650 SsParser.LeaveEscape := false;
651 SsParser.InputString := Script;
652 SsParser.LeaveEscape := true;
653 for i := 0 to SsParser.Count-1 do begin
654 if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
655 for u := 7 downto 1 do begin
656 if (SsParser.Match(SsParser[i],
657 '\URL%b'+StringReplace(StringOfChar('-', u*2),
658 '-', '%b', [rfReplaceAll]))) > 0 then begin
659 for j := 1 to u do begin
660 s := SsParser.GetParam(SsParser[i], j*2);
661 if Pos('http://', s) > 0 then Result.Add(s);
666 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
667 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
668 s := SsParser.GetParam(SsParser[i], 1);
669 if Pos('http://', s) > 0 then Result.Add(s);
675 procedure TfrmLog.SelAndFocusMessage(const MID: String);
679 for i := 0 to SelectedBottleLog.Count-1 do begin
680 Log := SelectedBottleLog.Items[i] as TLogItem;
681 if Log.MID = MID then begin
682 lvwLog.Items[i].Selected := true;
683 lvwLog.Items[i].Focused := true;
688 procedure TfrmLog.lvwLogCustomDrawItem(Sender: TCustomListView;
689 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
694 procedure TfrmLog.lvwLogCustomDrawSubItem(Sender: TCustomListView;
695 Item: TListItem; SubItem: Integer; State: TCustomDrawState;
696 var DefaultDraw: Boolean);
702 Mark: TSsMarkUpType;}
705 {if (SubItem <> SubScript+1) or (not Pref.ColorScript) then Exit; // DefaultDraw = true
706 // Custom Script Coloring
707 DefaultDraw := false;
708 SavedDC := SaveDC(lvwLog.Canvas.Handle);
710 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript+1, LVIR_BOUNDS, @DestRect);
712 lvwLog.Canvas.Brush.Style := bsSolid;
713 if cdsSelected in State then begin
714 lvwLog.Canvas.Brush.Color := clHighlight
716 lvwLog.Canvas.Brush.Color := Pref.BgColor;
718 lvwLog.Canvas.FillRect(DestRect);
719 lvwLog.Canvas.Brush.Style := bsClear;
721 Script := Item.SubItems[SubScript];
722 // DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, DestRect, DT_END_ELLIPSIS, nil);
723 SsParser.InputString := Script;
725 for i := 0 to SsParser.Count - 1 do begin
726 Mark := SsParser.MarkUpType[i];
728 mtMeta: lvwLog.Canvas.Font.Color := Pref.MetaWordColor;
729 mtTag: lvwLog.Canvas.Font.Color := Pref.MarkUpColor;
730 mtTagErr: lvwLog.Canvas.Font.Color := Pref.MarkErrorColor;
732 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
735 w := lvwLog.Canvas.TextWidth(SsParser[i]);
736 lvwLog.Canvas.TextRect(DestRect, DestRect.Left + x, DestRect.Top + 2, SsParser[i]);
738 if DestRect.Right - DestRect.Left < x then Break;
741 RestoreDC(lvwLog.Canvas.Handle, SavedDC);
745 procedure TfrmLog.UpdateScript(const Script: String);
747 if Script <> FLastScript then begin
748 if Pref.LogWindowPreviewStyle = psConversation then begin
749 if Pref.ColorScript then begin
750 UpdateScriptConversationColor(Script);
752 UpdateScriptConversationNoColor(Script);
755 UpdateScriptScript(Script);
757 SendMessage(edtScript.Handle, EM_LINESCROLL, Low(integer), Low(integer)); //
\83X
\83N
\83\8d\81[
\83\8b\96ß
\82µ
758 FLastScript := Script;
762 procedure TfrmLog.PopupMenuPreviewStylePopup(Sender: TObject);
765 with PopupMenuPreviewStyle do
766 for i := 0 to Items.Count-1 do
767 Items[i].Checked := Items[i].Tag = Ord(Pref.LogWindowPreviewStyle)
770 procedure TfrmLog.mnPreviewStyleClick(Sender: TObject);
773 with PopupMenuPreviewStyle do
774 for i := 0 to Items.Count-1 do
775 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
776 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag);
778 lvwLogChange(self, lvwLog.Selected, ctState);
781 procedure TfrmLog.UpdateScriptScript(const Script: String);
783 UnyuTalking, InSynchronized: boolean;
786 if Pref.ColorScript then begin
787 edtScript.Color := Pref.BgColor;
789 edtScript.Color := clWindow;
790 edtScript.DefAttributes.Color := clWindowText;
791 edtScript.SelAttributes.Color := clWindowText;
793 SsParser.LeaveEscape := true;
794 SsParser.InputString := Script;
795 edtScript.Text := '';
796 edtScript.SelAttributes.Color := clWindowText;
797 UnyuTalking := false;
798 InSynchronized := false;
799 for i := 0 to SsParser.Count-1 do begin
800 if Pref.ColorScript then begin
801 case SsParser.MarkUpType[i] of
803 if InSynchronized then
804 edtScript.SelAttributes.Color := Pref.TalkColorS
805 else if UnyuTalking then
806 edtScript.SelAttributes.Color := Pref.TalkColorU
808 edtScript.SelAttributes.Color := Pref.TalkColorH;
811 edtScript.SelAttributes.Color := Pref.MarkUpColor;
812 if SsParser[i] = '\h' then
814 else if SsParser[i] = '\u' then
816 else if SsParser[i] = '\_s' then
817 InSynchronized := not InSynchronized;
819 mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor;
820 mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor;
823 edtScript.SelText := SsParser[i];
824 if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then
825 edtScript.SelText := #13#10;
829 procedure TfrmLog.tbtnPreviewStyleClick(Sender: TObject);
832 sel := Ord(Pref.LogWindowPreviewStyle);
834 if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0;
835 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel);
837 lvwLogChange(self, lvwLog.Selected, ctState);
840 function TfrmLog.SelectedBottleLog: TBottleLogList;
842 if tabBottleLog.TabIndex >= 0 then
843 Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList
848 procedure TfrmLog.tabBottleLogChange(Sender: TObject);
851 if SelectedBottleLog.SelectedIndex >= 0 then begin
852 lvwLog.Items[SelectedBottleLog.SelectedIndex].Selected := true;
853 if lvwLog.Focused then lvwLog.Selected.Focused := true;
855 lvwLogChange(Self, nil, ctState);
858 procedure TfrmLog.LogLoaded(Sender: TObject);
860 if SelectedBottleLog = Sender then begin
865 procedure TfrmLog.UpdateTab;
868 cur := tabBottleLog.tabIndex;
869 tabBottleLog.Tabs.Clear;
870 for i := 0 to FBottleLogList.Count - 1 do begin
871 tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title);
873 if FBottleLogList.Count > 0 then begin
874 if cur < FBottleLogList.Count then
875 tabBottleLog.TabIndex := cur
877 tabBottleLog.TabIndex := FBottleLogList.Count-1;
881 procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String);
884 ShowMessage(Message);
885 (Sender as TBottleLogList).AddSystemLog(Message);
889 procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer);
894 for i := 0 to FBottleLogList.Count - 1 do begin
895 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
896 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Agrees := Agree;
900 if flag then lvwLog.Invalidate;
903 procedure TfrmLog.VoteLog(const MID: String; const Vote: integer);
908 for i := 0 to FBottleLogList.Count - 1 do begin
909 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
910 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Votes := Vote;
914 if flag then lvwLog.Invalidate;
917 procedure TfrmLog.tabBottleLogChanging(Sender: TObject;
918 var AllowChange: Boolean);
920 //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83\8d\83O
\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95Û
\91¶
921 if SelectedBottleLog = nil then Exit;
922 if lvwLog.Selected <> nil then
923 SelectedBottleLog.SelectedIndex := lvwLog.Selected.Index
925 SelectedBottleLog.SelectedIndex := -1;
928 procedure TfrmLog.tabBottleLogContextPopup(Sender: TObject;
929 MousePos: TPoint; var Handled: Boolean);
931 with tabBottleLog do begin
932 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
933 if Tag < 0 then Handled := true;
937 procedure TfrmLog.mnCloseTabClick(Sender: TObject);
939 FBottleLogList.Delete(tabBottleLog.Tag);
942 lvwLogChange(Self, nil, ctState);
945 procedure TfrmLog.tbtnFindBottleClick(Sender: TObject);
947 ResultLog: TBottleLogList;
948 Item1, Item2: TLogItem;
951 if SelectedBottleLog = nil then Exit;
952 if SelectedBottleLog.Count = 0 then begin
953 ShowMessage('
\8c\9f\8dõ
\91Î
\8fÛ
\82ª
\8bó
\82Å
\82·
\81B');
958 if InputQuery('
\83X
\83N
\83\8a\83v
\83g
\96{
\95¶
\82ð
\8c\9f\8dõ', '
\8c\9f\8dõ
\95¶
\8e\9a\97ñ', Query) then begin
959 if Query = '' then Exit;
960 ResultLog := TBottleLogList.Create('
\8c\9f\8dõ
\8c\8b\89Ê');
961 for i := 0 to SelectedBottleLog.Count-1 do begin
962 Item1 := SelectedBottleLog.Items[i] as TLogItem;
963 if AnsiContainsText(Item1.Script, Query) and (Item1.LogType = ltBottle) then begin
964 matched := matched + 1;
965 Item2 := TLogItem.Create(ltBottle, Item1.MID, Item1.Channel,
966 Item1.Script, Item1.Ghost, Item1.LogTime);
967 Item2.State := lsOpened;
968 Item2.Votes := Item1.Votes;
969 Item2.Agrees := Item1.Agrees;
970 ResultLog.Add(Item2);
974 ResultLog.AddSystemLog('
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½');
975 BottleLogList.Add(ResultLog);
977 tabBottleLog.TabIndex := BottleLogList.Count-1;
982 procedure TfrmLog.tbtnOpenLogClick(Sender: TObject);
983 var BottleLog: TBottleLogList;
987 if OpenDialog.Execute then begin
988 for i := 0 to OpenDialog.Files.Count-1 do begin
989 BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i]));
991 BottleLog.LoadFromXMLFile(OpenDialog.Files[i], XMLDocument);
993 on E: EXMLFileOpenException do begin
995 ShowMessage(E.Message);
996 FreeAndNil(BottleLog);
999 if BottleLog <> nil then Index := BottleLogList.Add(BottleLog); //
\8dÅ
\8cã
\82É
\8aJ
\82¢
\82½
\83\8d\83O
\82Ì
\88Ê
\92u
\82ð
\8bL
\89¯
1002 if Index >= 0 then tabBottleLog.TabIndex := Index;
1007 function TfrmLog.GetDefaultFileName(const Name, Ext: String): String;
1009 Result := StringReplace(Name, '/', '', [rfReplaceAll]);
1010 Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
1011 Result := ChangeFileExt(Result, Ext);
1014 function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList;
1017 for i := 0 to FBottleLogList.Count-1 do begin
1018 if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin
1019 Result := (FBottleLogList[i] as TBottleLogList);
1023 //
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\8fê
\8d\87
1024 Result := TBottleLogList.Create(LogName); //
\90V
\82µ
\82
\8dì
\82é
1025 FBottleLogList.Add(Result);
1027 if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0;
1030 procedure TfrmLog.AllBottleOpened;
1032 Log: TBottleLogList;
1034 for i := 0 to FBottleLogList.Count-1 do begin
1035 Log := FBottleLogList[i] as TBottleLogList;
1036 for j := 0 to Log.Count-1 do begin
1037 Log.Bottles[j].State := lsOpened;
1042 procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject;
1043 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1046 with tabBottleLog do begin
1047 Index := IndexOfTabAt(X, Y);
1048 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1049 if Button = mbLeft then begin
1050 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1052 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1057 procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X,
1058 Y: Integer; State: TDragState; var Accept: Boolean);
1059 var TargetRect: TRect;
1062 Accept := Source = tabBottleLog;
1063 if not Accept then Exit;
1064 with tabBottleLog do begin
1065 OldDest := FDragTabDest;
1066 FDragTabDest := IndexOfTabAt(X, Y);
1067 if FDragTabDest = -1 then begin
1068 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1071 with Canvas do begin
1075 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1076 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1077 TargetRect := TabRect(OldDest);
1078 with Canvas do begin
1079 Brush.Style := bsClear;
1080 Rectangle(TargetRect.Left, TargetRect.Top,
1081 TargetRect.Right, TargetRect.Bottom);
1084 if (OldDest <> FDragTabDest) then begin
1085 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1086 TargetRect := TabRect(FDragTabDest);
1087 with Canvas do begin
1088 Brush.Style := bsClear;
1089 Rectangle(TargetRect.Left, TargetRect.Top,
1090 TargetRect.Right, TargetRect.Bottom);
1096 procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X,
1098 var DestIndex: integer;
1100 with tabBottleLog do begin
1101 DestIndex := IndexOfTabAt(X, Y);
1102 Tabs.Move(FDragTabIndex, DestIndex);
1103 FBottleLogList.Move(FDragTabIndex, DestIndex);
1107 procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X,
1110 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1111 tabBottleLog.Tabs.BeginUpdate;
1112 tabBottleLog.Tabs.EndUpdate;
1115 procedure TfrmLog.LogLoadWork(Sender: TObject);
1117 if Sender = SelectedBottleLog then lvwLog.Invalidate;