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,
9 TalkShowFrame, SppList;
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;
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 SsParserForTalkShow: TSsParser;
62 mnPreviewStyleConversationImage: TMenuItem;
64 TalkShowFrame: TfrmTalkShow;
66 procedure tbtnClearClick(Sender: TObject);
67 procedure FormCreate(Sender: TObject);
68 procedure lvwLogChange(Sender: TObject; Item: TListItem;
70 procedure lvwLogDblClick(Sender: TObject);
71 procedure lvwLogKeyPress(Sender: TObject; var Key: Char);
72 procedure FormDestroy(Sender: TObject);
73 procedure lvwLogClick(Sender: TObject);
74 procedure mnSaveLogClick(Sender: TObject);
75 procedure lvwLogColumnClick(Sender: TObject; Column: TListColumn);
76 procedure mnPopUpCopyScriptClick(Sender: TObject);
77 procedure mnSaveLogChannelClick(Sender: TObject);
78 procedure mnSaveLogScriptClick(Sender: TObject);
79 procedure mnSaveLogXMLClick(Sender: TObject);
80 procedure lvwLogData(Sender: TObject; Item: TListItem);
81 procedure PopupMenuListViewPopup(Sender: TObject);
82 procedure lvwLogCustomDrawItem(Sender: TCustomListView;
83 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
84 procedure PopupMenuPreviewStylePopup(Sender: TObject);
85 procedure mnPreviewStyleClick(Sender: TObject);
86 procedure tbtnPreviewStyleClick(Sender: TObject);
87 procedure tabBottleLogChange(Sender: TObject);
88 procedure tabBottleLogChanging(Sender: TObject;
89 var AllowChange: Boolean);
90 procedure tabBottleLogContextPopup(Sender: TObject; MousePos: TPoint;
91 var Handled: Boolean);
92 procedure mnCloseTabClick(Sender: TObject);
93 procedure tbtnFindBottleClick(Sender: TObject);
94 procedure tbtnOpenLogClick(Sender: TObject);
95 procedure tabBottleLogMouseDown(Sender: TObject; Button: TMouseButton;
96 Shift: TShiftState; X, Y: Integer);
97 procedure tabBottleLogDragOver(Sender, Source: TObject; X, Y: Integer;
98 State: TDragState; var Accept: Boolean);
99 procedure tabBottleLogDragDrop(Sender, Source: TObject; X, Y: Integer);
100 procedure tabBottleLogEndDrag(Sender, Target: TObject; X, Y: Integer);
101 procedure lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
102 Rect: TRect; State: TOwnerDrawState);
103 procedure mnListPreviewStyleClick(Sender: TObject);
104 procedure tbtnListPreviewStyleClick(Sender: TObject);
105 procedure PopupMenuListPreviewStylePopup(Sender: TObject);
108 FLastScript: String; //
\83X
\83N
\83\8a\83v
\83g
\8dÄ
\95`
\89æ
\97}
\90§
\97p
109 FBottleLogList: TObjectList;
111 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
112 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)
114 procedure UpdateScript(const Script: String);
115 procedure UpdateScriptConversationColor(const Script: String);
116 procedure UpdateScriptScript(const Script: String);
117 procedure mnURLClick(Sender: TObject);
118 procedure ExtractURLs(Script: String; Result: TStrings);
119 function GetDefaultFileName(const Name: String; const Ext: String): String;
120 function BottleLogTitled(const LogName: String): TBottleLogList;
121 procedure DrawSingleLineScript(const Script: String; Rect: TRect;
123 procedure PreviewStyleChange;
125 procedure CreateParams(var Params: TCreateParams); override;
128 function SelectedBottleLog: TBottleLogList;
129 property BottleLogList: TObjectList read FBottleLogList;
130 procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
131 procedure AddCurrentSystemLog(const LogName, MessageString: String);
132 procedure VoteLog(const MID: String; const Vote: integer);
133 procedure AgreeLog(const MID: String; const Agree: integer);
134 procedure SetBottleState(const MID: String; State: TLogState);
135 procedure AllBottleOpened;
136 procedure LogLoaded(Sender: TObject);
137 procedure LogLoadFailure(Sender: TObject; const Message: String);
138 procedure LogLoadWork(Sender: TObject);
140 procedure UpdateWindow;
141 procedure SelAndFocusMessage(const MID: String);
167 procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
170 BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost);
171 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
172 lvwLog.OnChange := nil; //
\83C
\83x
\83\93\83g
\94
\90¶(
\82¢
\82ë
\82¢
\82ë
\8dÄ
\95`
\89æ
\82ª
\8bN
\82«
\82é)
\82Ì
\97}
\90§
173 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
174 lvwLog.Items.Count := SelectedBottleLog.Count;
176 if Sel >= 0 then begin
177 lvwLog.Selected := lvwLog.Items[Sel + 1];
178 lvwLog.Selected.Focused := true;
180 if not lvwLog.Focused then
181 ListView_Scroll(lvwLog.Handle, 0, High(integer));
182 lvwLog.OnChange := lvwLogChange;
185 procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String);
188 BottleLogTitled(LogName).AddSystemLog(MessageString);
189 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
190 lvwLog.OnChange := nil;
191 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
192 lvwLog.Items.Count := SelectedBottleLog.Count;
194 if Sel >= 0 then begin
195 lvwLog.Selected := lvwLog.Items[Sel + 1];
196 lvwLog.Selected.Focused := true;
198 if not lvwLog.Focused then
199 ListView_Scroll(lvwLog.Handle, 0, High(integer));
200 lvwLog.OnChange := lvwLogChange;
205 procedure TfrmLog.tbtnClearClick(Sender: TObject);
207 if SelectedBottleLog = nil then Exit;
208 FBottleLogList.Delete(tabBottleLog.TabIndex);
209 tabBottleLog.TabIndex := 0;
212 lvwLogChange(Self, nil, ctState);
215 procedure TfrmLog.FormCreate(Sender: TObject);
218 FBottleLogList := TObjectList.Create;
220 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
221 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
223 with Pref.LogWindowPosition do begin
226 Self.Width := Right - Left + 1;
227 Self.Height := Bottom - Top + 1;
229 lvwLog.DoubleBuffered := true;
230 edtScript.Height := Pref.LogWindowDividerPos;
233 while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin
234 lvwLog.Columns[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100);
238 SsParserForTalkShow.TagPattern.Assign(SsParser.TagPattern);
239 SsParserForTalkShow.MetaPattern.Assign(SsParser.MetaPattern);
240 SsParserForTalkShow.EscapeInvalidMeta := false;
241 SsParserForTalkShow.LeaveEscape := false;
242 TalkShowFrame.SsParser := self.SsParserForTalkShow;
245 UpdateWindow; // Reset window color and enabled status of some buttons
248 procedure TfrmLog.FormDestroy(Sender: TObject);
253 for i := 0 to lvwLog.Columns.Count-1 do begin
254 if i > 0 then WidthStr := WidthStr + ',';
255 WidthStr := WidthStr + IntToStr(lvwLog.Column[i].Width);
257 Pref.LogWindowColumnWidth := WidthStr;
259 with Pref.LogWindowPosition do begin
262 Right := Self.Left + Self.Width - 1;
263 Bottom := Self.Top + Self.Height - 1;
265 Pref.LogWindowDividerPos := edtScript.Height;
267 FreeAndNil(FBottleLogList);
270 procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem;
271 Change: TItemChange);
275 if SelectedBottleLog <> nil then begin
276 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
277 if Change = ctState then begin
279 if lvwLog.Selected <> nil then begin
280 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
281 if (Log.LogType = ltBottle) and not frmSender.Connecting then begin
282 Script := Log.Script;
283 frmSender.actVoteMessage.Enabled := true;
284 frmSender.actAgreeMessage.Enabled := true;
285 frmSender.actInsertCue.Enabled := true;
286 mnPopUpCopyScript.Enabled := true;
287 StatusBar.Panels[1].Text := Format('%d
\83o
\83C
\83g -
\83_
\83u
\83\8b\83N
\83\8a\83b
\83N
\82Å
\8dÄ
\90¶', [Length(Log.Script)]);
288 if Pref.LogWindowPreviewStyle = psImageConversation then
289 TalkShowFrame.View(Log)
291 UpdateScript(Script);
293 frmSender.actVoteMessage.Enabled := false;
294 frmSender.actAgreeMessage.Enabled := false;
295 frmSender.actInsertCue.Enabled := false;
296 mnPopUpCopyScript.Enabled := false;
297 StatusBar.Panels[1].Text := '';
298 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\82ð
\83N
\83\8a\83A
301 frmSender.actVoteMessage.Enabled := false;
302 frmSender.actAgreeMessage.Enabled := false;
303 frmSender.actInsertCue.Enabled := false;
304 mnPopUpCopyScript.Enabled := false;
305 StatusBar.Panels[1].Text := '';
306 UpdateScript(Script); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
309 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
311 frmSender.actVoteMessage.Enabled := false;
312 frmSender.actAgreeMessage.Enabled := false;
313 frmSender.actInsertCue.Enabled := false;
314 mnPopUpCopyScript.Enabled := false;
315 StatusBar.Panels[0].Text := '';
316 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
320 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
322 Log, CueItem: TLogItem;
324 if lvwLog.Selected = nil then
326 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
327 if Log = nil then Exit;
328 if Log.LogType <> ltBottle then
330 Script := frmSender.ScriptTransForSSTP(Log.Script);
331 if Script = '' then begin
332 ShowMessage('
\96â
\91è
\82Ì
\82 \82é
\83X
\83N
\83\8a\83v
\83g
\82Å
\82·
\81B
\8dÄ
\90¶
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'+
333 '
\83N
\83\89\83C
\83A
\83\93\83g
\82ð
\8dÅ
\90V
\94Å
\82É
\82µ
\82Ä
\82Ý
\82Ä
\82
\82¾
\82³
\82¢
\81B');
337 CueItem := TLogItem.Create(Log);
339 CueItem.Script := Script;
340 frmSender.BottleSstp.Unshift(CueItem);
346 procedure TfrmLog.UpdateScriptConversationColor(const Script: String);
349 UnyuTalking, Talked, InSynchronized: boolean;
352 frmSender.DoTrans(scr, [toConvertURL]);
353 SsParser.LeaveEscape := false;
354 SsParser.InputString := scr;
355 UnyuTalking := false;
356 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
357 InSynchronized := false;
358 edtScript.Text := '';
359 edtScript.Color := Pref.BgColor;
360 for i := 0 to SsParser.Count-1 do begin
361 if (SsParser[i] = '\_s') and not InSynchronized then begin
362 InSynchronized := true;
364 edtScript.SelText := #13#10;
367 end else if (SsParser[i] = '\_s') and InSynchronized then begin
368 InSynchronized := false;
370 edtScript.SelText := #13#10;
374 if (SsParser[i] = '\u') and not UnyuTalking then begin
377 edtScript.SelText := #13#10;
381 if (SsParser[i] = '\h') and UnyuTalking then begin
382 UnyuTalking := false;
384 edtScript.SelText := #13#10;
388 if SsParser.MarkUpType[i] = mtStr then begin
389 if InSynchronized then
390 edtScript.SelAttributes.Color := Pref.TalkColorS
391 else if UnyuTalking then
392 edtScript.SelAttributes.Color := Pref.TalkColorU
394 edtScript.SelAttributes.Color := Pref.TalkColorH;
395 edtScript.SelText := SsParser[i];
398 if SsParser.MarkUpType[i] = mtMeta then begin
399 edtScript.SelAttributes.Color := Pref.MetaWordColor;
400 edtScript.SelText := SsParser[i];
406 procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char);
408 if Key = #13 then lvwLogDblClick(Sender);
411 procedure TfrmLog.CreateParams(var Params: TCreateParams);
414 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
417 procedure TfrmLog.lvwLogClick(Sender: TObject);
419 //
\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ô
421 Selected := Selected;
424 procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn);
425 var SortType: TBottleLogSortType;
429 if SelectedBottleLog = nil then
431 if lvwLog.Selected <> nil then
432 SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID
436 SortColumn := Column.Index;
438 -1: SortType := stLogTime;
439 subChannel: SortType := stChannel;
440 subGhost: SortType := stGhost;
441 subVotes: SortType := stVote;
442 subAgrees: SortType := stAgree;
443 subScript: SortType := stScript;
445 SortType := stLogTime;
448 SelectedBottleLog.SortBottles(SortType);
450 if Length(SelectedMID) > 0 then
451 SelAndFocusMessage(SelectedMID);
455 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
460 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.Selected.Index];
461 if Log = nil then Exit;
463 Clip.SetTextBuf(PChar(Log.Script));
466 procedure TfrmLog.SetBottleState(const MID: String; State: TLogState);
470 for i := 0 to FBottleLogList.Count-1 do begin
471 Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID);
472 if Bottle <> nil then begin
473 Bottle.State := State;
474 lvwLog.OnChange := nil;
476 lvwLog.OnChange := lvwLogChange;
481 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
483 if SelectedBottleLog = nil then Exit;
484 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
485 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
486 SaveDialog.DefaultExt := 'log';
487 SaveDialog.FilterIndex := 1;
488 if SaveDialog.Execute then
489 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false);
492 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
494 if SelectedBottleLog = nil then Exit;
495 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
496 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
497 SaveDialog.DefaultExt := 'log';
498 SaveDialog.FilterIndex := 1;
499 if SaveDialog.Execute then
500 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, true);
503 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
505 if SelectedBottleLog = nil then Exit;
506 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt');
507 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
508 SaveDialog.DefaultExt := 'txt';
509 SaveDialog.FilterIndex := 2;
510 if SaveDialog.Execute then
511 SelectedBottleLog.SaveToText(SaveDialog.FileName);
514 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
516 if SelectedBottleLog = nil then Exit;
517 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.xml');
518 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
519 SaveDialog.DefaultExt := 'xml';
520 SaveDialog.FilterIndex := 3;
521 if SaveDialog.Execute then
522 SelectedBottleLog.SaveToXmlFile(SaveDialog.FileName);
525 procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem);
529 if Item = nil then Exit;
531 Log := SelectedBottleLog.Bottles[i];
533 Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime);
535 SubItems.Add(Log.Channel);
536 SubItems.Add(Log.Ghost);
537 if Log.LogType = ltBottle then begin
538 if Log.Votes > 0 then
539 SubItems.Add(IntToStr(Log.Votes))
542 if Log.Agrees > 0 then
543 SubItems.Add(IntToStr(Log.Agrees))
547 //
\83V
\83X
\83e
\83\80\83\8d\83O
\82È
\82Ç
\82Í
\93\8a\95[
\81E
\93¯
\88Ó
\82ð
\95\
\8e¦
\82µ
\82È
\82¢
551 SubItems.Add(Log.Script);
553 if Log.LogType = ltBottle then begin
555 lsUnopened: ImageIndex := IconBottle;
556 lsPlaying: ImageIndex := IconPlaying;
557 lsOpened: ImageIndex := IconOpened;
560 ImageIndex := IconSystemLog;
564 procedure TfrmLog.UpdateWindow;
565 var EnabledFlag: boolean;
567 if true then begin // ColorScript
568 if lvwLog.Color <> Pref.BgColor then lvwLog.Color := Pref.BgColor;
569 if lvwLog.Font.Color <> Pref.TalkColorH then lvwLog.Font.Color := Pref.TalkColorH;
571 if lvwLog.Color <> clWindow then lvwLog.Color := clWindow;
572 if lvwLog.Font.Color <> clWindowText then lvwLog.Font.Color := clWindowText;
574 if SelectedBottleLog <> nil then begin
575 Caption := '
\83\8d\83O - ' + SelectedBottleLog.Title;
576 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
577 lvwLog.Items.Count := SelectedBottleLog.Count;
579 Caption := '
\83\8d\83O';
580 StatusBar.Panels[0].Text := '';
581 StatusBar.Panels[1].Text := '';
582 lvwLog.Items.Count := 0;
585 EnabledFlag := SelectedBottleLog <> nil;
586 tbtnClear.Enabled := EnabledFlag;
587 tbtnSaveLog.Enabled := EnabledFlag;
588 tbtnFindBottle.Enabled := EnabledFlag;
593 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
599 for i := mnJumpURL.Count-1 downto 0 do begin
600 mnJumpURL.Items[i].Free;
602 mnJumpURL.Enabled := false;
603 if lvwLog.Selected = nil then Exit;
604 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
605 if Log = nil then Exit;
606 Urls := TStringList.Create;
608 ExtractURLs(Log.Script, Urls);
609 for i := 0 to Urls.Count-1 do begin
610 Child := TMenuItem.Create(Self);
612 Caption := Format('(&%d) %s', [i+1, StringReplace(Urls[i], '&', '&&', [rfReplaceAll])]);
614 OnClick := mnURLClick;
615 AutoHotkeys := maManual;
616 mnJumpURL.Add(Child);
619 mnJumpURL.Enabled := Urls.Count > 0;
625 procedure TfrmLog.mnURLClick(Sender: TObject);
626 var LogItem: TLogItem;
630 if (lvwLog.Selected = nil) or (SelectedBottleLog = nil) then Exit;
631 LogItem := SelectedBottleLog[lvwLog.Selected.Index] as TLogItem;
632 Urls := TStringList.Create;
634 ExtractURLs(LogItem.Script, Urls);
635 URL := Urls[(Sender as TMenuItem).Tag];
636 ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW);
642 procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings);
643 var i, u, j: integer;
647 SsParser.InputString := Script;
648 for i := 0 to SsParser.Count-1 do begin
649 if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
650 for u := 7 downto 1 do begin
651 if (SsParser.Match(SsParser[i],
652 '\URL%b'+StringReplace(StringOfChar('-', u*2),
653 '-', '%b', [rfReplaceAll]))) > 0 then begin
654 for j := 1 to u do begin
655 s := SsParser.GetParam(SsParser[i], j*2);
656 if Pos('http://', s) > 0 then Result.Add(s);
661 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
662 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
663 s := SsParser.GetParam(SsParser[i], 1);
664 if Pos('http://', s) > 0 then Result.Add(s);
670 procedure TfrmLog.SelAndFocusMessage(const MID: String);
674 for i := 0 to SelectedBottleLog.Count-1 do begin
675 Log := SelectedBottleLog.Items[i] as TLogItem;
676 if Log.MID = MID then begin
677 lvwLog.Items[i].Selected := true;
678 lvwLog.Items[i].Focused := true;
683 procedure TfrmLog.lvwLogCustomDrawItem(Sender: TCustomListView;
684 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
689 procedure TfrmLog.UpdateScript(const Script: String);
691 if Script <> FLastScript then begin
692 if Pref.LogWindowPreviewStyle = psConversation then begin
693 UpdateScriptConversationColor(Script);
695 UpdateScriptScript(Script);
697 SendMessage(edtScript.Handle, EM_LINESCROLL, Low(integer), Low(integer)); //
\83X
\83N
\83\8d\81[
\83\8b\96ß
\82µ
698 FLastScript := Script;
702 procedure TfrmLog.PopupMenuPreviewStylePopup(Sender: TObject);
705 with PopupMenuPreviewStyle do
706 for i := 0 to Items.Count-1 do
707 Items[i].Checked := Items[i].Tag = Ord(Pref.LogWindowPreviewStyle)
710 procedure TfrmLog.mnPreviewStyleClick(Sender: TObject);
713 with PopupMenuPreviewStyle do
714 for i := 0 to Items.Count-1 do
715 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
716 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag);
719 lvwLogChange(self, lvwLog.Selected, ctState);
722 procedure TfrmLog.UpdateScriptScript(const Script: String);
724 UnyuTalking, InSynchronized: boolean;
727 edtScript.Color := Pref.BgColor;
728 SsParser.LeaveEscape := true;
729 SsParser.InputString := Script;
730 edtScript.Text := '';
731 edtScript.SelAttributes.Color := clWindowText;
732 UnyuTalking := false;
733 InSynchronized := false;
734 for i := 0 to SsParser.Count-1 do begin
735 case SsParser.MarkUpType[i] of
737 if InSynchronized then
738 edtScript.SelAttributes.Color := Pref.TalkColorS
739 else if UnyuTalking then
740 edtScript.SelAttributes.Color := Pref.TalkColorU
742 edtScript.SelAttributes.Color := Pref.TalkColorH;
745 edtScript.SelAttributes.Color := Pref.MarkUpColor;
746 if SsParser[i] = '\h' then
748 else if SsParser[i] = '\u' then
750 else if SsParser[i] = '\_s' then
751 InSynchronized := not InSynchronized;
753 mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor;
754 mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor;
756 edtScript.SelText := SsParser[i];
757 if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then
758 edtScript.SelText := #13#10;
762 procedure TfrmLog.tbtnPreviewStyleClick(Sender: TObject);
765 sel := Ord(Pref.LogWindowPreviewStyle);
767 if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0;
768 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel);
771 lvwLogChange(self, lvwLog.Selected, ctState);
774 function TfrmLog.SelectedBottleLog: TBottleLogList;
776 if tabBottleLog.TabIndex >= 0 then
777 Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList
782 procedure TfrmLog.tabBottleLogChange(Sender: TObject);
785 if SelectedBottleLog.SelectedIndex >= 0 then begin
786 lvwLog.Items[SelectedBottleLog.SelectedIndex].Selected := true;
787 if lvwLog.Focused then lvwLog.Selected.Focused := true;
789 lvwLogChange(Self, nil, ctState);
792 procedure TfrmLog.LogLoaded(Sender: TObject);
794 if SelectedBottleLog = Sender then begin
799 procedure TfrmLog.UpdateTab;
802 cur := tabBottleLog.tabIndex;
803 tabBottleLog.Tabs.Clear;
804 for i := 0 to FBottleLogList.Count - 1 do begin
805 tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title);
807 if FBottleLogList.Count > 0 then begin
808 if cur < FBottleLogList.Count then
809 tabBottleLog.TabIndex := cur
811 tabBottleLog.TabIndex := FBottleLogList.Count-1;
815 procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String);
818 ShowMessage(Message);
819 if Sender = SelectedBottleLog then UpdateWindow;
822 procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer);
827 for i := 0 to FBottleLogList.Count - 1 do begin
828 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
829 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Agrees := Agree;
833 if flag then lvwLog.Invalidate;
836 procedure TfrmLog.VoteLog(const MID: String; const Vote: integer);
841 for i := 0 to FBottleLogList.Count - 1 do begin
842 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
843 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Votes := Vote;
847 if flag then lvwLog.Invalidate;
850 procedure TfrmLog.tabBottleLogChanging(Sender: TObject;
851 var AllowChange: Boolean);
853 //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83\8d\83O
\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95Û
\91¶
854 if SelectedBottleLog = nil then Exit;
855 if lvwLog.Selected <> nil then
856 SelectedBottleLog.SelectedIndex := lvwLog.Selected.Index
858 SelectedBottleLog.SelectedIndex := -1;
861 procedure TfrmLog.tabBottleLogContextPopup(Sender: TObject;
862 MousePos: TPoint; var Handled: Boolean);
864 with tabBottleLog do begin
865 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
866 if Tag < 0 then Handled := true;
870 procedure TfrmLog.mnCloseTabClick(Sender: TObject);
872 FBottleLogList.Delete(tabBottleLog.Tag);
875 lvwLogChange(Self, nil, ctState);
878 procedure TfrmLog.tbtnFindBottleClick(Sender: TObject);
880 ResultLog: TBottleLogList;
881 Item1, Item2: TLogItem;
884 if SelectedBottleLog = nil then Exit;
885 if SelectedBottleLog.Count = 0 then begin
886 ShowMessage('
\8c\9f\8dõ
\91Î
\8fÛ
\82ª
\8bó
\82Å
\82·
\81B');
891 if InputQuery('
\83X
\83N
\83\8a\83v
\83g
\96{
\95¶
\82ð
\8c\9f\8dõ', '
\8c\9f\8dõ
\95¶
\8e\9a\97ñ', Query) then begin
892 if Query = '' then Exit;
893 ResultLog := TBottleLogList.Create('
\8c\9f\8dõ
\8c\8b\89Ê');
894 for i := 0 to SelectedBottleLog.Count-1 do begin
895 Item1 := SelectedBottleLog.Items[i] as TLogItem;
896 if AnsiContainsText(Item1.Script, Query) and (Item1.LogType = ltBottle) then begin
897 matched := matched + 1;
898 Item2 := TLogItem.Create(ltBottle, Item1.MID, Item1.Channel,
899 Item1.Script, Item1.Ghost, Item1.LogTime);
900 Item2.State := lsOpened;
901 Item2.Votes := Item1.Votes;
902 Item2.Agrees := Item1.Agrees;
903 ResultLog.Add(Item2);
907 ResultLog.AddSystemLog('
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½');
908 BottleLogList.Add(ResultLog);
910 tabBottleLog.TabIndex := BottleLogList.Count-1;
915 procedure TfrmLog.tbtnOpenLogClick(Sender: TObject);
916 var BottleLog: TBottleLogList;
920 if OpenDialog.Execute then begin
921 for i := 0 to OpenDialog.Files.Count-1 do begin
922 BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i]));
926 OnLoaded := LogLoaded;
927 OnLoadFailure := LogLoadFailure;
928 OnLoadWork := LogLoadWork;
929 BottleLog.LoadFromXMLFile(OpenDialog.Files[i]);
931 Index := BottleLogList.Add(BottleLog); //
\8dÅ
\8cã
\82É
\8aJ
\82¢
\82½
\83\8d\83O
\82Ì
\88Ê
\92u
\82ð
\8bL
\89¯
937 if Index >= 0 then tabBottleLog.TabIndex := Index;
942 function TfrmLog.GetDefaultFileName(const Name, Ext: String): String;
944 Result := StringReplace(Name, '/', '', [rfReplaceAll]);
945 Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
946 Result := ChangeFileExt(Result, Ext);
949 function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList;
952 for i := 0 to FBottleLogList.Count-1 do begin
953 if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin
954 Result := (FBottleLogList[i] as TBottleLogList);
958 //
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\8fê
\8d\87
959 Result := TBottleLogList.Create(LogName); //
\90V
\82µ
\82
\8dì
\82é
960 FBottleLogList.Add(Result);
962 if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0;
965 procedure TfrmLog.AllBottleOpened;
969 for i := 0 to FBottleLogList.Count-1 do begin
970 Log := FBottleLogList[i] as TBottleLogList;
971 for j := 0 to Log.Count-1 do begin
972 Log.Bottles[j].State := lsOpened;
977 procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject;
978 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
981 with tabBottleLog do begin
982 Index := IndexOfTabAt(X, Y);
983 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
984 if Button = mbLeft then begin
985 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
987 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
992 procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X,
993 Y: Integer; State: TDragState; var Accept: Boolean);
994 var TargetRect: TRect;
997 Accept := Source = tabBottleLog;
998 if not Accept then Exit;
999 with tabBottleLog do begin
1000 OldDest := FDragTabDest;
1001 FDragTabDest := IndexOfTabAt(X, Y);
1002 if FDragTabDest = -1 then begin
1003 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1006 with Canvas do begin
1010 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1011 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1012 TargetRect := TabRect(OldDest);
1013 with Canvas do begin
1014 Brush.Style := bsClear;
1015 Rectangle(TargetRect.Left, TargetRect.Top,
1016 TargetRect.Right, TargetRect.Bottom);
1019 if (OldDest <> FDragTabDest) then begin
1020 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1021 TargetRect := TabRect(FDragTabDest);
1022 with Canvas do begin
1023 Brush.Style := bsClear;
1024 Rectangle(TargetRect.Left, TargetRect.Top,
1025 TargetRect.Right, TargetRect.Bottom);
1031 procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X,
1033 var DestIndex: integer;
1035 with tabBottleLog do begin
1036 DestIndex := IndexOfTabAt(X, Y);
1037 Tabs.Move(FDragTabIndex, DestIndex);
1038 FBottleLogList.Move(FDragTabIndex, DestIndex);
1042 procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X,
1045 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1046 tabBottleLog.Tabs.BeginUpdate;
1047 tabBottleLog.Tabs.EndUpdate;
1050 procedure TfrmLog.LogLoadWork(Sender: TObject);
1052 if Sender = SelectedBottleLog then lvwLog.Invalidate;
1055 procedure TfrmLog.lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
1056 Rect: TRect; State: TOwnerDrawState);
1063 //
\94w
\8ci
\8fÁ
\8b\8e
1064 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_BOUNDS);
1066 lvwLog.Canvas.Brush.Style := bsSolid;
1067 if Item.Selected then begin
1068 if lvwLog.Focused then
1069 lvwLog.Canvas.Brush.Color := clHighlight
1071 lvwLog.Canvas.Brush.Color := clBtnFace;
1073 lvwLog.Canvas.Brush.Color := Pref.BgColor;
1075 lvwLog.Canvas.FillRect(DestRect);
1076 lvwLog.Canvas.Brush.Style := bsClear;
1077 if Item.Focused and lvwLog.Focused then
1078 lvwLog.Canvas.DrawFocusRect(DestRect);
1080 if Item.Selected then
1082 if lvwLog.Focused then
1083 lvwLog.Canvas.Font.Color := clHighlightText
1085 lvwLog.Canvas.Font.Color := clWindowText;
1087 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1088 lvwLog.Canvas.Refresh;
1090 //
\83L
\83\83\83v
\83V
\83\87\83\93(
\93ú
\95t)
1091 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_LABEL);
1092 Inc(DestRect.Left, 2);
1093 Inc(DestRect.Top, 2);
1094 Dec(DestRect.Right, 2);
1095 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.Caption), -1, DestRect,
1096 DT_SINGLELINE or DT_END_ELLIPSIS, nil);
1097 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_ICON);
1098 Ico := TIcon.Create;
1100 lvwLog.SmallImages.GetIcon(Item.ImageIndex, Ico);
1101 lvwLog.Canvas.Draw(DestRect.Left, DestRect.Top, Ico);
1105 //
\83L
\83\83\83v
\83V
\83\87\83\93\82Å
\82à
\83X
\83N
\83\8a\83v
\83g
\82Å
\82à
\82È
\82¢
\82à
\82Ì
1106 for sub := 0 to Item.SubItems.Count-1 do
1108 if sub = SubScript then Continue;
1109 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, sub + 1,
1110 LVIR_BOUNDS, @DestRect);
1111 Inc(DestRect.Left, 2);
1112 Inc(DestRect.Top, 2);
1113 Dec(DestRect.Right, 2);
1114 Ex := DT_NOPREFIX or DT_SINGLELINE or DT_END_ELLIPSIS;
1115 if lvwLog.Columns[sub+1].Alignment = taRightJustify then
1116 Ex := Ex or DT_RIGHT;
1117 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.SubItems[sub]), -1, DestRect,
1120 //
\83X
\83N
\83\8a\83v
\83g
1121 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript + 1,
1122 LVIR_BOUNDS, @DestRect);
1123 Script := Item.SubItems[SubScript];
1124 DrawSingleLineScript(Script, DestRect, Item);
1127 procedure TfrmLog.DrawSingleLineScript(const Script: String;
1128 Rect: TRect; Item: TListItem);
1131 UnyuTalking, Synchronized, Spaced: boolean;
1132 Mark: TSsMarkUpType;
1133 procedure ScopeChange;
1135 if (not Spaced) and (Pref.LogListPreviewStyle = psTagStripped) then
1142 if Pref.LogListPreviewStyle = psNoColor then
1147 DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, Rect,
1148 DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX, nil);
1152 SsParser.LeaveEscape := Pref.LogListPreviewStyle = psNormal;
1153 SsParser.InputString := Script;
1156 UnyuTalking := false;
1157 Synchronized := false;
1158 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¢
1159 //
\82½
\82ß
\82Ì
\83t
\83\89\83O
1160 for i := 0 to SsParser.Count - 1 do begin
1161 if SsParser[i] = '\h' then
1163 UnyuTalking := false;
1165 end else if SsParser[i] = '\u' then
1167 UnyuTalking := true;
1169 end else if SsParser[i] = '\_s' then
1171 Synchronized := not Synchronized;
1173 end else if (Pos('\n', SsParser[i]) = 1) or (SsParser[i] = '\c') then
1177 Mark := SsParser.MarkUpType[i];
1181 lvwLog.Canvas.Font.Color := Pref.MetaWordColor;
1185 if Pref.LogListPreviewStyle = psNormal then
1186 lvwLog.Canvas.Font.Color := Pref.MarkUpColor
1192 lvwLog.Canvas.Font.Color := Pref.MarkErrorColor;
1195 if Synchronized then
1196 lvwLog.Canvas.Font.Color := Pref.TalkColorS
1197 else if UnyuTalking then
1198 lvwLog.Canvas.Font.Color := Pref.TalkColorU
1200 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1203 if Item.Selected then
1205 if lvwLog.Focused then
1206 lvwLog.Canvas.Font.Color := clHighlightText
1208 lvwLog.Canvas.Font.Color := clWindowText;
1210 lvwLog.Canvas.Refresh;
1211 w := lvwLog.Canvas.TextWidth(SsParser[i]);
1212 lvwLog.Canvas.TextRect(Rect, Rect.Left + x, Rect.Top + 2, SsParser[i]);
1214 if Rect.Right - Rect.Left < x then Break;
1218 procedure TfrmLog.mnListPreviewStyleClick(Sender: TObject);
1221 with PopupMenuListPreviewStyle do
1222 for i := 0 to Items.Count-1 do
1223 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
1224 Pref.LogListPreviewStyle := TLogListPreviewStyle((Sender as TMenuItem).Tag);
1228 procedure TfrmLog.tbtnListPreviewStyleClick(Sender: TObject);
1231 sel := Ord(Pref.LogListPreviewStyle);
1233 if sel > Ord(High(TLogListPreviewStyle)) then sel := 0;
1234 Pref.LogListPreviewStyle := TLogListPreviewStyle(sel);
1238 procedure TfrmLog.PopupMenuListPreviewStylePopup(Sender: TObject);
1241 with PopupMenuListPreviewStyle do
1242 for i := 0 to Items.Count-1 do
1243 Items[i].Checked := Items[i].Tag = Ord(Pref.LogListPreviewStyle)
1246 procedure TfrmLog.PreviewStyleChange;
1248 if Pref.LogWindowPreviewStyle = psImageConversation then
1250 if Spps.Count = 0 then
1251 ShowMessage('
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\97p
\83v
\83\89\83O
\83C
\83\93\82ª
\91¶
\8dÝ
\82µ
\82Ü
\82¹
\82ñ
\81B');
1252 edtScript.Visible := false;
1253 TalkShowFrame.Visible := true;
1256 edtScript.Visible := true;
1257 TalkShowFrame.Visible := false;