6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ComCtrls, ToolWin, StdCtrls, ExtCtrls, SsParser, BottleDef, Menus,
8 Clipbrd, Logs, ShellAPI, Commctrl, DirectSstp, Contnrs, StrUtils;
11 TSaveLogType = (stLog, stLogWithChannels, stText, stXML);
13 TfrmLog = class(TForm)
15 tbtnClear: TToolButton;
18 StatusBar: TStatusBar;
19 tbtnSaveLog: TToolButton;
20 PopupMenuPreview: TPopupMenu;
22 tbtnVoteMessage: TToolButton;
23 PopupMenuListView: TPopupMenu;
24 mnPopUpVoteMessage: TMenuItem;
25 SaveDialog: TSaveDialog;
29 mnPopUpCopyScript: TMenuItem;
30 PopupMenuSaveLog: TPopupMenu;
32 mnSaveLogChannel: TMenuItem;
33 mnSaveLogScript: TMenuItem;
34 mnSaveLogXML: TMenuItem;
35 ToolButton1: TToolButton;
37 mnPopUpAgreeMessage: TMenuItem;
38 tbtnAgreeMessage: TToolButton;
39 ToolButton2: TToolButton;
40 tbtnPreviewStyle: TToolButton;
41 PopupMenuPreviewStyle: TPopupMenu;
42 mnPreviewStyleConversation: TMenuItem;
43 mnPreviewStyleScript: TMenuItem;
44 mnPreviewStyleScriptWithLineBreak: TMenuItem;
46 tabBottleLog: TTabControl;
48 tbtnDownloadLog: TToolButton;
49 PopupMenuTab: TPopupMenu;
50 mnCloseTab: TMenuItem;
51 tbtnFindBottle: TToolButton;
52 tbtnOpenLog: TToolButton;
53 OpenDialog: TOpenDialog;
54 tbtnInsertCue: TToolButton;
55 mnInsertCue: TMenuItem;
56 PopupMenuListPreviewStyle: TPopupMenu;
57 mnListPreviewStyleNormal: TMenuItem;
58 mnListPreviewStyleTagStripped: TMenuItem;
59 tbtnListPreviewStyle: TToolButton;
60 mnListPreviewStyleNoColor: TMenuItem;
61 procedure tbtnClearClick(Sender: TObject);
62 procedure FormCreate(Sender: TObject);
63 procedure lvwLogChange(Sender: TObject; Item: TListItem;
65 procedure lvwLogDblClick(Sender: TObject);
66 procedure lvwLogKeyPress(Sender: TObject; var Key: Char);
67 procedure FormDestroy(Sender: TObject);
68 procedure lvwLogClick(Sender: TObject);
69 procedure mnSaveLogClick(Sender: TObject);
70 procedure lvwLogColumnClick(Sender: TObject; Column: TListColumn);
71 procedure mnPopUpCopyScriptClick(Sender: TObject);
72 procedure mnSaveLogChannelClick(Sender: TObject);
73 procedure mnSaveLogScriptClick(Sender: TObject);
74 procedure mnSaveLogXMLClick(Sender: TObject);
75 procedure lvwLogData(Sender: TObject; Item: TListItem);
76 procedure PopupMenuListViewPopup(Sender: TObject);
77 procedure lvwLogCustomDrawItem(Sender: TCustomListView;
78 Item: TListItem; State: TCustomDrawState; 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);
96 procedure lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
97 Rect: TRect; State: TOwnerDrawState);
98 procedure mnListPreviewStyleClick(Sender: TObject);
99 procedure tbtnListPreviewStyleClick(Sender: TObject);
100 procedure PopupMenuListPreviewStylePopup(Sender: TObject);
103 FLastScript: String; //
\83X
\83N
\83\8a\83v
\83g
\8dÄ
\95`
\89æ
\97}
\90§
\97p
104 FBottleLogList: TObjectList;
106 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
107 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)
109 procedure UpdateScript(const Script: String);
110 procedure UpdateScriptConversationColor(const Script: String);
111 procedure UpdateScriptScript(const Script: String);
112 procedure mnURLClick(Sender: TObject);
113 procedure ExtractURLs(Script: String; Result: TStrings);
114 function GetDefaultFileName(const Name: String; const Ext: String): String;
115 function BottleLogTitled(const LogName: String): TBottleLogList;
116 procedure DrawSingleLineScript(const Script: String; Rect: TRect;
119 procedure CreateParams(var Params: TCreateParams); override;
122 function SelectedBottleLog: TBottleLogList;
123 property BottleLogList: TObjectList read FBottleLogList;
124 procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
125 procedure AddCurrentSystemLog(const LogName, MessageString: String);
126 procedure VoteLog(const MID: String; const Vote: integer);
127 procedure AgreeLog(const MID: String; const Agree: integer);
128 procedure SetBottleState(const MID: String; State: TLogState);
129 procedure AllBottleOpened;
130 procedure LogLoaded(Sender: TObject);
131 procedure LogLoadFailure(Sender: TObject; const Message: String);
132 procedure LogLoadWork(Sender: TObject);
134 procedure UpdateWindow;
135 procedure SelAndFocusMessage(const MID: String);
161 procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
164 BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost);
165 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
166 lvwLog.OnChange := nil; //
\83C
\83x
\83\93\83g
\94
\90¶(
\82¢
\82ë
\82¢
\82ë
\8dÄ
\95`
\89æ
\82ª
\8bN
\82«
\82é)
\82Ì
\97}
\90§
167 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
168 lvwLog.Items.Count := SelectedBottleLog.Count;
170 if Sel >= 0 then begin
171 lvwLog.Selected := lvwLog.Items[Sel + 1];
172 lvwLog.Selected.Focused := true;
174 if not lvwLog.Focused then
175 ListView_Scroll(lvwLog.Handle, 0, High(integer));
176 lvwLog.OnChange := lvwLogChange;
179 procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String);
182 BottleLogTitled(LogName).AddSystemLog(MessageString);
183 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
184 lvwLog.OnChange := nil;
185 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
186 lvwLog.Items.Count := SelectedBottleLog.Count;
188 if Sel >= 0 then begin
189 lvwLog.Selected := lvwLog.Items[Sel + 1];
190 lvwLog.Selected.Focused := true;
192 if not lvwLog.Focused then
193 ListView_Scroll(lvwLog.Handle, 0, High(integer));
194 lvwLog.OnChange := lvwLogChange;
199 procedure TfrmLog.tbtnClearClick(Sender: TObject);
201 if SelectedBottleLog = nil then Exit;
202 FBottleLogList.Delete(tabBottleLog.TabIndex);
203 tabBottleLog.TabIndex := 0;
206 lvwLogChange(Self, nil, ctState);
209 procedure TfrmLog.FormCreate(Sender: TObject);
212 FBottleLogList := TObjectList.Create;
214 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
215 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
217 with Pref.LogWindowPosition do begin
220 Self.Width := Right - Left + 1;
221 Self.Height := Bottom - Top + 1;
223 lvwLog.DoubleBuffered := true;
224 edtScript.Height := Pref.LogWindowDividerPos;
227 while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin
228 lvwLog.Columns[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100);
232 UpdateWindow; // Reset window color and enabled status of some buttons
235 procedure TfrmLog.FormDestroy(Sender: TObject);
240 for i := 0 to lvwLog.Columns.Count-1 do begin
241 if i > 0 then WidthStr := WidthStr + ',';
242 WidthStr := WidthStr + IntToStr(lvwLog.Column[i].Width);
244 Pref.LogWindowColumnWidth := WidthStr;
246 with Pref.LogWindowPosition do begin
249 Right := Self.Left + Self.Width - 1;
250 Bottom := Self.Top + Self.Height - 1;
252 Pref.LogWindowDividerPos := edtScript.Height;
254 FreeAndNil(FBottleLogList);
257 procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem;
258 Change: TItemChange);
262 if SelectedBottleLog <> nil then begin
263 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
264 if Change = ctState then begin
266 if lvwLog.Selected <> nil then begin
267 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
268 if (Log.LogType = ltBottle) and not frmSender.Connecting then begin
269 Script := Log.Script;
270 frmSender.actVoteMessage.Enabled := true;
271 frmSender.actAgreeMessage.Enabled := true;
272 frmSender.actInsertCue.Enabled := true;
273 mnPopUpCopyScript.Enabled := true;
274 StatusBar.Panels[1].Text := Format('%d
\83o
\83C
\83g -
\83_
\83u
\83\8b\83N
\83\8a\83b
\83N
\82Å
\8dÄ
\90¶', [Length(Log.Script)]);
275 UpdateScript(Script);
277 frmSender.actVoteMessage.Enabled := false;
278 frmSender.actAgreeMessage.Enabled := false;
279 frmSender.actInsertCue.Enabled := false;
280 mnPopUpCopyScript.Enabled := false;
281 StatusBar.Panels[1].Text := '';
282 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\82ð
\83N
\83\8a\83A
285 frmSender.actVoteMessage.Enabled := false;
286 frmSender.actAgreeMessage.Enabled := false;
287 frmSender.actInsertCue.Enabled := false;
288 mnPopUpCopyScript.Enabled := false;
289 StatusBar.Panels[1].Text := '';
290 UpdateScript(Script); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
293 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
295 frmSender.actVoteMessage.Enabled := false;
296 frmSender.actAgreeMessage.Enabled := false;
297 frmSender.actInsertCue.Enabled := false;
298 mnPopUpCopyScript.Enabled := false;
299 StatusBar.Panels[0].Text := '';
300 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
304 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
306 Log, CueItem: TLogItem;
308 if lvwLog.Selected = nil then
310 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
311 if Log = nil then Exit;
312 if Log.LogType <> ltBottle then
314 Script := frmSender.ScriptTransForSSTP(Log.Script);
315 if Script = '' then begin
316 ShowMessage('
\96â
\91è
\82Ì
\82 \82é
\83X
\83N
\83\8a\83v
\83g
\82Å
\82·
\81B
\8dÄ
\90¶
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'+
317 '
\83N
\83\89\83C
\83A
\83\93\83g
\82ð
\8dÅ
\90V
\94Å
\82É
\82µ
\82Ä
\82Ý
\82Ä
\82
\82¾
\82³
\82¢
\81B');
321 CueItem := TLogItem.Create(Log);
323 CueItem.Script := Script;
324 frmSender.BottleSstp.Unshift(CueItem);
330 procedure TfrmLog.UpdateScriptConversationColor(const Script: String);
333 UnyuTalking, Talked, InSynchronized: boolean;
336 frmSender.DoTrans(scr, [toConvertURL]);
337 SsParser.LeaveEscape := false;
338 SsParser.InputString := scr;
339 UnyuTalking := false;
340 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
341 InSynchronized := false;
342 edtScript.Text := '';
343 edtScript.Color := Pref.BgColor;
344 for i := 0 to SsParser.Count-1 do begin
345 if (SsParser[i] = '\_s') and not InSynchronized then begin
346 InSynchronized := true;
348 edtScript.SelText := #13#10;
351 end else if (SsParser[i] = '\_s') and InSynchronized then begin
352 InSynchronized := false;
354 edtScript.SelText := #13#10;
358 if (SsParser[i] = '\u') and not UnyuTalking then begin
361 edtScript.SelText := #13#10;
365 if (SsParser[i] = '\h') and UnyuTalking then begin
366 UnyuTalking := false;
368 edtScript.SelText := #13#10;
372 if SsParser.MarkUpType[i] = mtStr then begin
373 if InSynchronized then
374 edtScript.SelAttributes.Color := Pref.TalkColorS
375 else if UnyuTalking then
376 edtScript.SelAttributes.Color := Pref.TalkColorU
378 edtScript.SelAttributes.Color := Pref.TalkColorH;
379 edtScript.SelText := SsParser[i];
382 if SsParser.MarkUpType[i] = mtMeta then begin
383 edtScript.SelAttributes.Color := Pref.MetaWordColor;
384 edtScript.SelText := SsParser[i];
390 procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char);
392 if Key = #13 then lvwLogDblClick(Sender);
395 procedure TfrmLog.CreateParams(var Params: TCreateParams);
398 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
401 procedure TfrmLog.lvwLogClick(Sender: TObject);
403 //
\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ô
405 Selected := Selected;
408 procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn);
409 var SortType: TBottleLogSortType;
413 if SelectedBottleLog = nil then
415 if lvwLog.Selected <> nil then
416 SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID
420 SortColumn := Column.Index;
422 -1: SortType := stLogTime;
423 subChannel: SortType := stChannel;
424 subGhost: SortType := stGhost;
425 subVotes: SortType := stVote;
426 subAgrees: SortType := stAgree;
427 subScript: SortType := stScript;
429 SortType := stLogTime;
432 SelectedBottleLog.SortBottles(SortType);
434 if Length(SelectedMID) > 0 then
435 SelAndFocusMessage(SelectedMID);
439 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
444 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.Selected.Index];
445 if Log = nil then Exit;
447 Clip.SetTextBuf(PChar(Log.Script));
450 procedure TfrmLog.SetBottleState(const MID: String; State: TLogState);
454 for i := 0 to FBottleLogList.Count-1 do begin
455 Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID);
456 if Bottle <> nil then begin
457 Bottle.State := State;
458 lvwLog.OnChange := nil;
460 lvwLog.OnChange := lvwLogChange;
465 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
467 if SelectedBottleLog = nil then Exit;
468 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
469 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
470 SaveDialog.DefaultExt := 'log';
471 SaveDialog.FilterIndex := 1;
472 if SaveDialog.Execute then
473 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false);
476 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
478 if SelectedBottleLog = nil then Exit;
479 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
480 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
481 SaveDialog.DefaultExt := 'log';
482 SaveDialog.FilterIndex := 1;
483 if SaveDialog.Execute then
484 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, true);
487 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
489 if SelectedBottleLog = nil then Exit;
490 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt');
491 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
492 SaveDialog.DefaultExt := 'txt';
493 SaveDialog.FilterIndex := 2;
494 if SaveDialog.Execute then
495 SelectedBottleLog.SaveToText(SaveDialog.FileName);
498 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
500 if SelectedBottleLog = nil then Exit;
501 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.xml');
502 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
503 SaveDialog.DefaultExt := 'xml';
504 SaveDialog.FilterIndex := 3;
505 if SaveDialog.Execute then
506 SelectedBottleLog.SaveToXmlFile(SaveDialog.FileName);
509 procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem);
513 if Item = nil then Exit;
515 Log := SelectedBottleLog.Bottles[i];
517 Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime);
519 SubItems.Add(Log.Channel);
520 SubItems.Add(Log.Ghost);
521 if Log.LogType = ltBottle then begin
522 if Log.Votes > 0 then
523 SubItems.Add(IntToStr(Log.Votes))
526 if Log.Agrees > 0 then
527 SubItems.Add(IntToStr(Log.Agrees))
531 //
\83V
\83X
\83e
\83\80\83\8d\83O
\82È
\82Ç
\82Í
\93\8a\95[
\81E
\93¯
\88Ó
\82ð
\95\
\8e¦
\82µ
\82È
\82¢
535 SubItems.Add(Log.Script);
537 if Log.LogType = ltBottle then begin
539 lsUnopened: ImageIndex := IconBottle;
540 lsPlaying: ImageIndex := IconPlaying;
541 lsOpened: ImageIndex := IconOpened;
544 ImageIndex := IconSystemLog;
548 procedure TfrmLog.UpdateWindow;
549 var EnabledFlag: boolean;
551 if true then begin // ColorScript
552 if lvwLog.Color <> Pref.BgColor then lvwLog.Color := Pref.BgColor;
553 if lvwLog.Font.Color <> Pref.TalkColorH then lvwLog.Font.Color := Pref.TalkColorH;
555 if lvwLog.Color <> clWindow then lvwLog.Color := clWindow;
556 if lvwLog.Font.Color <> clWindowText then lvwLog.Font.Color := clWindowText;
558 if SelectedBottleLog <> nil then begin
559 Caption := '
\83\8d\83O - ' + SelectedBottleLog.Title;
560 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
561 lvwLog.Items.Count := SelectedBottleLog.Count;
563 Caption := '
\83\8d\83O';
564 StatusBar.Panels[0].Text := '';
565 StatusBar.Panels[1].Text := '';
566 lvwLog.Items.Count := 0;
569 EnabledFlag := SelectedBottleLog <> nil;
570 tbtnClear.Enabled := EnabledFlag;
571 tbtnSaveLog.Enabled := EnabledFlag;
572 tbtnFindBottle.Enabled := EnabledFlag;
577 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
583 for i := mnJumpURL.Count-1 downto 0 do begin
584 mnJumpURL.Items[i].Free;
586 mnJumpURL.Enabled := false;
587 if lvwLog.Selected = nil then Exit;
588 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
589 if Log = nil then Exit;
590 Urls := TStringList.Create;
592 ExtractURLs(Log.Script, Urls);
593 for i := 0 to Urls.Count-1 do begin
594 Child := TMenuItem.Create(Self);
596 Caption := Format('(&%d) %s', [i+1, StringReplace(Urls[i], '&', '&&', [rfReplaceAll])]);
598 OnClick := mnURLClick;
599 AutoHotkeys := maManual;
600 mnJumpURL.Add(Child);
603 mnJumpURL.Enabled := Urls.Count > 0;
609 procedure TfrmLog.mnURLClick(Sender: TObject);
610 var LogItem: TLogItem;
614 if (lvwLog.Selected = nil) or (SelectedBottleLog = nil) then Exit;
615 LogItem := SelectedBottleLog[lvwLog.Selected.Index] as TLogItem;
616 Urls := TStringList.Create;
618 ExtractURLs(LogItem.Script, Urls);
619 URL := Urls[(Sender as TMenuItem).Tag];
620 ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW);
626 procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings);
627 var i, u, j: integer;
631 SsParser.InputString := Script;
632 for i := 0 to SsParser.Count-1 do begin
633 if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
634 for u := 7 downto 1 do begin
635 if (SsParser.Match(SsParser[i],
636 '\URL%b'+StringReplace(StringOfChar('-', u*2),
637 '-', '%b', [rfReplaceAll]))) > 0 then begin
638 for j := 1 to u do begin
639 s := SsParser.GetParam(SsParser[i], j*2);
640 if Pos('http://', s) > 0 then Result.Add(s);
645 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
646 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
647 s := SsParser.GetParam(SsParser[i], 1);
648 if Pos('http://', s) > 0 then Result.Add(s);
654 procedure TfrmLog.SelAndFocusMessage(const MID: String);
658 for i := 0 to SelectedBottleLog.Count-1 do begin
659 Log := SelectedBottleLog.Items[i] as TLogItem;
660 if Log.MID = MID then begin
661 lvwLog.Items[i].Selected := true;
662 lvwLog.Items[i].Focused := true;
667 procedure TfrmLog.lvwLogCustomDrawItem(Sender: TCustomListView;
668 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
673 procedure TfrmLog.UpdateScript(const Script: String);
675 if Script <> FLastScript then begin
676 if Pref.LogWindowPreviewStyle = psConversation then begin
677 UpdateScriptConversationColor(Script);
679 UpdateScriptScript(Script);
681 SendMessage(edtScript.Handle, EM_LINESCROLL, Low(integer), Low(integer)); //
\83X
\83N
\83\8d\81[
\83\8b\96ß
\82µ
682 FLastScript := Script;
686 procedure TfrmLog.PopupMenuPreviewStylePopup(Sender: TObject);
689 with PopupMenuPreviewStyle do
690 for i := 0 to Items.Count-1 do
691 Items[i].Checked := Items[i].Tag = Ord(Pref.LogWindowPreviewStyle)
694 procedure TfrmLog.mnPreviewStyleClick(Sender: TObject);
697 with PopupMenuPreviewStyle do
698 for i := 0 to Items.Count-1 do
699 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
700 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag);
702 lvwLogChange(self, lvwLog.Selected, ctState);
705 procedure TfrmLog.UpdateScriptScript(const Script: String);
707 UnyuTalking, InSynchronized: boolean;
710 edtScript.Color := Pref.BgColor;
711 SsParser.LeaveEscape := true;
712 SsParser.InputString := Script;
713 edtScript.Text := '';
714 edtScript.SelAttributes.Color := clWindowText;
715 UnyuTalking := false;
716 InSynchronized := false;
717 for i := 0 to SsParser.Count-1 do begin
718 case SsParser.MarkUpType[i] of
720 if InSynchronized then
721 edtScript.SelAttributes.Color := Pref.TalkColorS
722 else if UnyuTalking then
723 edtScript.SelAttributes.Color := Pref.TalkColorU
725 edtScript.SelAttributes.Color := Pref.TalkColorH;
728 edtScript.SelAttributes.Color := Pref.MarkUpColor;
729 if SsParser[i] = '\h' then
731 else if SsParser[i] = '\u' then
733 else if SsParser[i] = '\_s' then
734 InSynchronized := not InSynchronized;
736 mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor;
737 mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor;
739 edtScript.SelText := SsParser[i];
740 if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then
741 edtScript.SelText := #13#10;
745 procedure TfrmLog.tbtnPreviewStyleClick(Sender: TObject);
748 sel := Ord(Pref.LogWindowPreviewStyle);
750 if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0;
751 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel);
753 lvwLogChange(self, lvwLog.Selected, ctState);
756 function TfrmLog.SelectedBottleLog: TBottleLogList;
758 if tabBottleLog.TabIndex >= 0 then
759 Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList
764 procedure TfrmLog.tabBottleLogChange(Sender: TObject);
767 if SelectedBottleLog.SelectedIndex >= 0 then begin
768 lvwLog.Items[SelectedBottleLog.SelectedIndex].Selected := true;
769 if lvwLog.Focused then lvwLog.Selected.Focused := true;
771 lvwLogChange(Self, nil, ctState);
774 procedure TfrmLog.LogLoaded(Sender: TObject);
776 if SelectedBottleLog = Sender then begin
781 procedure TfrmLog.UpdateTab;
784 cur := tabBottleLog.tabIndex;
785 tabBottleLog.Tabs.Clear;
786 for i := 0 to FBottleLogList.Count - 1 do begin
787 tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title);
789 if FBottleLogList.Count > 0 then begin
790 if cur < FBottleLogList.Count then
791 tabBottleLog.TabIndex := cur
793 tabBottleLog.TabIndex := FBottleLogList.Count-1;
797 procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String);
800 ShowMessage(Message);
801 if Sender = SelectedBottleLog then UpdateWindow;
804 procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer);
809 for i := 0 to FBottleLogList.Count - 1 do begin
810 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
811 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Agrees := Agree;
815 if flag then lvwLog.Invalidate;
818 procedure TfrmLog.VoteLog(const MID: String; const Vote: integer);
823 for i := 0 to FBottleLogList.Count - 1 do begin
824 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
825 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Votes := Vote;
829 if flag then lvwLog.Invalidate;
832 procedure TfrmLog.tabBottleLogChanging(Sender: TObject;
833 var AllowChange: Boolean);
835 //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83\8d\83O
\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95Û
\91¶
836 if SelectedBottleLog = nil then Exit;
837 if lvwLog.Selected <> nil then
838 SelectedBottleLog.SelectedIndex := lvwLog.Selected.Index
840 SelectedBottleLog.SelectedIndex := -1;
843 procedure TfrmLog.tabBottleLogContextPopup(Sender: TObject;
844 MousePos: TPoint; var Handled: Boolean);
846 with tabBottleLog do begin
847 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
848 if Tag < 0 then Handled := true;
852 procedure TfrmLog.mnCloseTabClick(Sender: TObject);
854 FBottleLogList.Delete(tabBottleLog.Tag);
857 lvwLogChange(Self, nil, ctState);
860 procedure TfrmLog.tbtnFindBottleClick(Sender: TObject);
862 ResultLog: TBottleLogList;
863 Item1, Item2: TLogItem;
866 if SelectedBottleLog = nil then Exit;
867 if SelectedBottleLog.Count = 0 then begin
868 ShowMessage('
\8c\9f\8dõ
\91Î
\8fÛ
\82ª
\8bó
\82Å
\82·
\81B');
873 if InputQuery('
\83X
\83N
\83\8a\83v
\83g
\96{
\95¶
\82ð
\8c\9f\8dõ', '
\8c\9f\8dõ
\95¶
\8e\9a\97ñ', Query) then begin
874 if Query = '' then Exit;
875 ResultLog := TBottleLogList.Create('
\8c\9f\8dõ
\8c\8b\89Ê');
876 for i := 0 to SelectedBottleLog.Count-1 do begin
877 Item1 := SelectedBottleLog.Items[i] as TLogItem;
878 if AnsiContainsText(Item1.Script, Query) and (Item1.LogType = ltBottle) then begin
879 matched := matched + 1;
880 Item2 := TLogItem.Create(ltBottle, Item1.MID, Item1.Channel,
881 Item1.Script, Item1.Ghost, Item1.LogTime);
882 Item2.State := lsOpened;
883 Item2.Votes := Item1.Votes;
884 Item2.Agrees := Item1.Agrees;
885 ResultLog.Add(Item2);
889 ResultLog.AddSystemLog('
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½');
890 BottleLogList.Add(ResultLog);
892 tabBottleLog.TabIndex := BottleLogList.Count-1;
897 procedure TfrmLog.tbtnOpenLogClick(Sender: TObject);
898 var BottleLog: TBottleLogList;
902 if OpenDialog.Execute then begin
903 for i := 0 to OpenDialog.Files.Count-1 do begin
904 BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i]));
908 OnLoaded := LogLoaded;
909 OnLoadFailure := LogLoadFailure;
910 OnLoadWork := LogLoadWork;
911 BottleLog.LoadFromXMLFile(OpenDialog.Files[i]);
913 Index := BottleLogList.Add(BottleLog); //
\8dÅ
\8cã
\82É
\8aJ
\82¢
\82½
\83\8d\83O
\82Ì
\88Ê
\92u
\82ð
\8bL
\89¯
919 if Index >= 0 then tabBottleLog.TabIndex := Index;
924 function TfrmLog.GetDefaultFileName(const Name, Ext: String): String;
926 Result := StringReplace(Name, '/', '', [rfReplaceAll]);
927 Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
928 Result := ChangeFileExt(Result, Ext);
931 function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList;
934 for i := 0 to FBottleLogList.Count-1 do begin
935 if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin
936 Result := (FBottleLogList[i] as TBottleLogList);
940 //
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\8fê
\8d\87
941 Result := TBottleLogList.Create(LogName); //
\90V
\82µ
\82
\8dì
\82é
942 FBottleLogList.Add(Result);
944 if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0;
947 procedure TfrmLog.AllBottleOpened;
951 for i := 0 to FBottleLogList.Count-1 do begin
952 Log := FBottleLogList[i] as TBottleLogList;
953 for j := 0 to Log.Count-1 do begin
954 Log.Bottles[j].State := lsOpened;
959 procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject;
960 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
963 with tabBottleLog do begin
964 Index := IndexOfTabAt(X, Y);
965 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
966 if Button = mbLeft then begin
967 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
969 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
974 procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X,
975 Y: Integer; State: TDragState; var Accept: Boolean);
976 var TargetRect: TRect;
979 Accept := Source = tabBottleLog;
980 if not Accept then Exit;
981 with tabBottleLog do begin
982 OldDest := FDragTabDest;
983 FDragTabDest := IndexOfTabAt(X, Y);
984 if FDragTabDest = -1 then begin
985 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
992 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
993 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
994 TargetRect := TabRect(OldDest);
996 Brush.Style := bsClear;
997 Rectangle(TargetRect.Left, TargetRect.Top,
998 TargetRect.Right, TargetRect.Bottom);
1001 if (OldDest <> FDragTabDest) then begin
1002 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1003 TargetRect := TabRect(FDragTabDest);
1004 with Canvas do begin
1005 Brush.Style := bsClear;
1006 Rectangle(TargetRect.Left, TargetRect.Top,
1007 TargetRect.Right, TargetRect.Bottom);
1013 procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X,
1015 var DestIndex: integer;
1017 with tabBottleLog do begin
1018 DestIndex := IndexOfTabAt(X, Y);
1019 Tabs.Move(FDragTabIndex, DestIndex);
1020 FBottleLogList.Move(FDragTabIndex, DestIndex);
1024 procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X,
1027 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1028 tabBottleLog.Tabs.BeginUpdate;
1029 tabBottleLog.Tabs.EndUpdate;
1032 procedure TfrmLog.LogLoadWork(Sender: TObject);
1034 if Sender = SelectedBottleLog then lvwLog.Invalidate;
1037 procedure TfrmLog.lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
1038 Rect: TRect; State: TOwnerDrawState);
1045 //
\94w
\8ci
\8fÁ
\8b\8e
1046 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_BOUNDS);
1048 lvwLog.Canvas.Brush.Style := bsSolid;
1049 if Item.Selected then begin
1050 if lvwLog.Focused then
1051 lvwLog.Canvas.Brush.Color := clHighlight
1053 lvwLog.Canvas.Brush.Color := clBtnFace;
1055 lvwLog.Canvas.Brush.Color := Pref.BgColor;
1057 lvwLog.Canvas.FillRect(DestRect);
1058 lvwLog.Canvas.Brush.Style := bsClear;
1059 if Item.Focused and lvwLog.Focused then
1060 lvwLog.Canvas.DrawFocusRect(DestRect);
1062 if Item.Selected then
1064 if lvwLog.Focused then
1065 lvwLog.Canvas.Font.Color := clHighlightText
1067 lvwLog.Canvas.Font.Color := clWindowText;
1069 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1070 lvwLog.Canvas.Refresh;
1072 //
\83L
\83\83\83v
\83V
\83\87\83\93(
\93ú
\95t)
1073 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_LABEL);
1074 Inc(DestRect.Left, 2);
1075 Inc(DestRect.Top, 2);
1076 Dec(DestRect.Right, 2);
1077 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.Caption), -1, DestRect,
1078 DT_SINGLELINE or DT_END_ELLIPSIS, nil);
1079 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_ICON);
1080 Ico := TIcon.Create;
1082 lvwLog.SmallImages.GetIcon(Item.ImageIndex, Ico);
1083 lvwLog.Canvas.Draw(DestRect.Left, DestRect.Top, Ico);
1087 //
\83L
\83\83\83v
\83V
\83\87\83\93\82Å
\82à
\83X
\83N
\83\8a\83v
\83g
\82Å
\82à
\82È
\82¢
\82à
\82Ì
1088 for sub := 0 to Item.SubItems.Count-1 do
1090 if sub = SubScript then Continue;
1091 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, sub + 1,
1092 LVIR_BOUNDS, @DestRect);
1093 Inc(DestRect.Left, 2);
1094 Inc(DestRect.Top, 2);
1095 Dec(DestRect.Right, 2);
1096 Ex := DT_NOPREFIX or DT_SINGLELINE or DT_END_ELLIPSIS;
1097 if lvwLog.Columns[sub+1].Alignment = taRightJustify then
1098 Ex := Ex or DT_RIGHT;
1099 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.SubItems[sub]), -1, DestRect,
1102 //
\83X
\83N
\83\8a\83v
\83g
1103 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript + 1,
1104 LVIR_BOUNDS, @DestRect);
1105 Script := Item.SubItems[SubScript];
1106 DrawSingleLineScript(Script, DestRect, Item);
1109 procedure TfrmLog.DrawSingleLineScript(const Script: String;
1110 Rect: TRect; Item: TListItem);
1113 UnyuTalking, Synchronized, Spaced: boolean;
1114 Mark: TSsMarkUpType;
1115 procedure ScopeChange;
1117 if (not Spaced) and (Pref.LogListPreviewStyle = psTagStripped) then
1124 if Pref.LogListPreviewStyle = psNoColor then
1129 DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, Rect,
1130 DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX, nil);
1134 SsParser.LeaveEscape := false;
1135 SsParser.InputString := Script;
1138 UnyuTalking := false;
1139 Synchronized := false;
1140 Spaced := true; //
\83^
\83O
\8fÈ
\97ª
\95\
\8e¦
\8e\9e\82É
\95s
\95K
\97v
\82É
\83X
\83R
\81[
\83v
\95Ï
\8a·
\8e\9e\82Ì
\83X
\83y
\81[
\83X
\82ð
\8bó
\82¯
\82È
\82¢
1141 //
\82½
\82ß
\82Ì
\83t
\83\89\83O
1142 for i := 0 to SsParser.Count - 1 do begin
1143 if SsParser[i] = '\h' then
1145 UnyuTalking := false;
1147 end else if SsParser[i] = '\u' then
1149 UnyuTalking := true;
1151 end else if SsParser[i] = '\_s' then
1153 Synchronized := not Synchronized;
1155 end else if (Pos('\n', SsParser[i]) = 1) or (SsParser[i] = '\c') then
1159 Mark := SsParser.MarkUpType[i];
1163 lvwLog.Canvas.Font.Color := Pref.MetaWordColor;
1167 if Pref.LogListPreviewStyle = psNormal then
1168 lvwLog.Canvas.Font.Color := Pref.MarkUpColor
1174 lvwLog.Canvas.Font.Color := Pref.MarkErrorColor;
1177 if Synchronized then
1178 lvwLog.Canvas.Font.Color := Pref.TalkColorS
1179 else if UnyuTalking then
1180 lvwLog.Canvas.Font.Color := Pref.TalkColorU
1182 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1185 if Item.Selected then
1187 if lvwLog.Focused then
1188 lvwLog.Canvas.Font.Color := clHighlightText
1190 lvwLog.Canvas.Font.Color := clWindowText;
1192 lvwLog.Canvas.Refresh;
1193 w := lvwLog.Canvas.TextWidth(SsParser[i]);
1194 lvwLog.Canvas.TextRect(Rect, Rect.Left + x, Rect.Top + 2, SsParser[i]);
1196 if Rect.Right - Rect.Left < x then Break;
1200 procedure TfrmLog.mnListPreviewStyleClick(Sender: TObject);
1203 with PopupMenuListPreviewStyle do
1204 for i := 0 to Items.Count-1 do
1205 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
1206 Pref.LogListPreviewStyle := TLogListPreviewStyle((Sender as TMenuItem).Tag);
1210 procedure TfrmLog.tbtnListPreviewStyleClick(Sender: TObject);
1213 sel := Ord(Pref.LogListPreviewStyle);
1215 if sel > Ord(High(TLogListPreviewStyle)) then sel := 0;
1216 Pref.LogListPreviewStyle := TLogListPreviewStyle(sel);
1220 procedure TfrmLog.PopupMenuListPreviewStylePopup(Sender: TObject);
1223 with PopupMenuListPreviewStyle do
1224 for i := 0 to Items.Count-1 do
1225 Items[i].Checked := Items[i].Tag = Ord(Pref.LogListPreviewStyle)