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;
63 pnlPreviewArea: TPanel;
64 TalkShowFrame: TfrmTalkShow;
66 tbtnSendEditor: TToolButton;
67 mnSendEditor: TMenuItem;
68 procedure tbtnClearClick(Sender: TObject);
69 procedure FormCreate(Sender: TObject);
70 procedure lvwLogChange(Sender: TObject; Item: TListItem;
72 procedure lvwLogDblClick(Sender: TObject);
73 procedure lvwLogKeyPress(Sender: TObject; var Key: Char);
74 procedure FormDestroy(Sender: TObject);
75 procedure lvwLogClick(Sender: TObject);
76 procedure mnSaveLogClick(Sender: TObject);
77 procedure lvwLogColumnClick(Sender: TObject; Column: TListColumn);
78 procedure mnPopUpCopyScriptClick(Sender: TObject);
79 procedure mnSaveLogChannelClick(Sender: TObject);
80 procedure mnSaveLogScriptClick(Sender: TObject);
81 procedure mnSaveLogXMLClick(Sender: TObject);
82 procedure lvwLogData(Sender: TObject; Item: TListItem);
83 procedure PopupMenuListViewPopup(Sender: TObject);
84 procedure lvwLogCustomDrawItem(Sender: TCustomListView;
85 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
86 procedure PopupMenuPreviewStylePopup(Sender: TObject);
87 procedure mnPreviewStyleClick(Sender: TObject);
88 procedure tbtnPreviewStyleClick(Sender: TObject);
89 procedure tabBottleLogChange(Sender: TObject);
90 procedure tabBottleLogChanging(Sender: TObject;
91 var AllowChange: Boolean);
92 procedure tabBottleLogContextPopup(Sender: TObject; MousePos: TPoint;
93 var Handled: Boolean);
94 procedure mnCloseTabClick(Sender: TObject);
95 procedure tbtnFindBottleClick(Sender: TObject);
96 procedure tbtnOpenLogClick(Sender: TObject);
97 procedure tabBottleLogMouseDown(Sender: TObject; Button: TMouseButton;
98 Shift: TShiftState; X, Y: Integer);
99 procedure tabBottleLogDragOver(Sender, Source: TObject; X, Y: Integer;
100 State: TDragState; var Accept: Boolean);
101 procedure tabBottleLogDragDrop(Sender, Source: TObject; X, Y: Integer);
102 procedure tabBottleLogEndDrag(Sender, Target: TObject; X, Y: Integer);
103 procedure lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
104 Rect: TRect; State: TOwnerDrawState);
105 procedure mnListPreviewStyleClick(Sender: TObject);
106 procedure tbtnListPreviewStyleClick(Sender: TObject);
107 procedure PopupMenuListPreviewStylePopup(Sender: TObject);
110 FLastScript: String; //
\83X
\83N
\83\8a\83v
\83g
\8dÄ
\95`
\89æ
\97}
\90§
\97p
111 FBottleLogList: TObjectList;
113 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
114 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)
116 procedure UpdateScript(const Script: String);
117 procedure UpdateScriptConversationColor(const Script: String);
118 procedure UpdateScriptScript(const Script: String);
119 procedure mnURLClick(Sender: TObject);
120 procedure ExtractURLs(Script: String; Result: TStrings);
121 function GetDefaultFileName(const Name: String; const Ext: String): String;
122 function BottleLogTitled(const LogName: String): TBottleLogList;
123 procedure DrawSingleLineScript(LogItem: TLogItem; Rect: TRect;
125 procedure PreviewStyleChange;
127 procedure CreateParams(var Params: TCreateParams); override;
130 function SelectedBottleLog: TBottleLogList;
131 property BottleLogList: TObjectList read FBottleLogList;
132 procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
133 procedure AddCurrentSystemLog(const LogName, MessageString: String);
134 procedure VoteLog(const MID: String; const Vote: integer);
135 procedure AgreeLog(const MID: String; const Agree: integer);
136 procedure SetBottleState(const MID: String; State: TLogState);
137 procedure AllBottleOpened;
138 procedure LogLoaded(Sender: TObject);
139 procedure LogLoadFailure(Sender: TObject; const Message: String);
140 procedure LogLoadWork(Sender: TObject);
142 procedure UpdateWindow;
143 procedure SelAndFocusMessage(const MID: String);
170 procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
173 BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost);
174 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
175 lvwLog.OnChange := nil; //
\83C
\83x
\83\93\83g
\94
\90¶(
\82¢
\82ë
\82¢
\82ë
\8dÄ
\95`
\89æ
\82ª
\8bN
\82«
\82é)
\82Ì
\97}
\90§
176 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
177 lvwLog.Items.Count := SelectedBottleLog.Count;
179 if Sel >= 0 then begin
180 lvwLog.Selected := lvwLog.Items[Sel + 1];
181 lvwLog.Selected.Focused := true;
183 if not lvwLog.Focused then
184 ListView_Scroll(lvwLog.Handle, 0, High(integer));
185 lvwLog.OnChange := lvwLogChange;
188 procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String);
191 BottleLogTitled(LogName).AddSystemLog(MessageString);
192 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
193 lvwLog.OnChange := nil;
194 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
195 lvwLog.Items.Count := SelectedBottleLog.Count;
197 if Sel >= 0 then begin
198 lvwLog.Selected := lvwLog.Items[Sel + 1];
199 lvwLog.Selected.Focused := true;
201 if not lvwLog.Focused then
202 ListView_Scroll(lvwLog.Handle, 0, High(integer));
203 lvwLog.OnChange := lvwLogChange;
208 procedure TfrmLog.tbtnClearClick(Sender: TObject);
210 if SelectedBottleLog = nil then Exit;
211 FBottleLogList.Delete(tabBottleLog.TabIndex);
212 tabBottleLog.TabIndex := 0;
215 lvwLogChange(Self, nil, ctState);
218 procedure TfrmLog.FormCreate(Sender: TObject);
221 FBottleLogList := TObjectList.Create;
223 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
224 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
226 with Pref.LogWindowPosition do begin
229 Self.Width := Right - Left + 1;
230 Self.Height := Bottom - Top + 1;
232 lvwLog.DoubleBuffered := true;
233 pnlPreviewArea.Height := Pref.LogWindowDividerPos;
236 while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin
237 lvwLog.Columns[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100);
241 SsParserForTalkShow.TagPattern.Assign(SsParser.TagPattern);
242 SsParserForTalkShow.MetaPattern.Assign(SsParser.MetaPattern);
243 SsParserForTalkShow.EscapeInvalidMeta := false;
244 SsParserForTalkShow.LeaveEscape := false;
245 TalkShowFrame.SsParser := self.SsParserForTalkShow;
247 TalkShowFrame.SetPreviewFont(edtScript.Font);
248 TalkShowFrame.PrevControl := lvwLog;
251 UpdateWindow; // Reset window color and enabled status of some buttons
254 procedure TfrmLog.FormDestroy(Sender: TObject);
259 for i := 0 to lvwLog.Columns.Count-1 do begin
260 if i > 0 then WidthStr := WidthStr + ',';
261 WidthStr := WidthStr + IntToStr(lvwLog.Column[i].Width);
263 Pref.LogWindowColumnWidth := WidthStr;
265 with Pref.LogWindowPosition do begin
268 Right := Self.Left + Self.Width - 1;
269 Bottom := Self.Top + Self.Height - 1;
271 Pref.LogWindowDividerPos := pnlPreviewArea.Height;
273 FreeAndNil(FBottleLogList);
276 procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem;
277 Change: TItemChange);
281 if SelectedBottleLog <> nil then begin
282 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
283 if Change = ctState then begin
285 if lvwLog.Selected <> nil then begin
286 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
287 if (Log.LogType = ltBottle) and not frmSender.Connecting then begin
288 Script := Log.Script;
289 frmSender.actVoteMessage.Enabled := true;
290 frmSender.actAgreeMessage.Enabled := true;
291 frmSender.actSendEditor.Enabled := true;
292 frmSender.actInsertCue.Enabled := true;
293 mnPopUpCopyScript.Enabled := true;
294 StatusBar.Panels[1].Text := Format('%d
\83o
\83C
\83g -
\83_
\83u
\83\8b\83N
\83\8a\83b
\83N
\82Å
\8dÄ
\90¶', [Length(Log.Script)]);
295 if Pref.LogWindowPreviewStyle = psImageConversation then
296 TalkShowFrame.View(Log)
298 UpdateScript(Script);
300 frmSender.actVoteMessage.Enabled := false;
301 frmSender.actAgreeMessage.Enabled := false;
302 frmSender.actSendEditor.Enabled := false;
303 frmSender.actInsertCue.Enabled := false;
304 mnPopUpCopyScript.Enabled := false;
305 StatusBar.Panels[1].Text := '';
306 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\82ð
\83N
\83\8a\83A
309 frmSender.actVoteMessage.Enabled := false;
310 frmSender.actAgreeMessage.Enabled := false;
311 frmSender.actSendEditor.Enabled := false;
312 frmSender.actInsertCue.Enabled := false;
313 mnPopUpCopyScript.Enabled := false;
314 StatusBar.Panels[1].Text := '';
315 UpdateScript(Script); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
318 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
320 frmSender.actVoteMessage.Enabled := false;
321 frmSender.actAgreeMessage.Enabled := false;
322 frmSender.actSendEditor.Enabled := false;
323 frmSender.actInsertCue.Enabled := false;
324 mnPopUpCopyScript.Enabled := false;
325 StatusBar.Panels[0].Text := '';
326 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
330 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
331 var Script, ErrorMes: String;
332 Log, CueItem: TLogItem;
335 if lvwLog.Selected = nil then
337 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
338 if Log = nil then Exit;
339 if Log.LogType <> ltBottle then
341 Script := frmSender.ScriptTransForSSTP(Log.Script, ErrorMes);
342 if ErrorMes <> '' then
344 Res := MessageDlg('
\96â
\91è
\82Ì
\82 \82é
\83X
\83N
\83\8a\83v
\83g
\82Å
\82·
\81B
\8dÄ
\90¶
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
346 '
\8b
\90§
\93I
\82É
\8dÄ
\90¶
\82µ
\82Ü
\82·
\82©?'#13#10,
347 mtWarning, mbOkCancel, 0
349 if Res = mrCancel then
353 CueItem := TLogItem.Create(Log);
355 CueItem.Script := Script;
356 frmSender.BottleSstp.Unshift(CueItem);
362 procedure TfrmLog.UpdateScriptConversationColor(const Script: String);
365 UnyuTalking, Talked, InSynchronized: boolean;
368 frmSender.DoTrans(scr, [toConvertURL]);
369 SsParser.LeaveEscape := false;
370 SsParser.InputString := scr;
371 UnyuTalking := false;
372 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
373 InSynchronized := false;
374 edtScript.Text := '';
375 edtScript.Color := Pref.BgColor;
376 for i := 0 to SsParser.Count-1 do begin
377 if (SsParser[i] = '\_s') and not InSynchronized then begin
378 InSynchronized := true;
380 edtScript.SelText := #13#10;
383 end else if (SsParser[i] = '\_s') and InSynchronized then begin
384 InSynchronized := false;
386 edtScript.SelText := #13#10;
390 if (SsParser[i] = '\u') and not UnyuTalking then begin
393 edtScript.SelText := #13#10;
397 if (SsParser[i] = '\h') and UnyuTalking then begin
398 UnyuTalking := false;
400 edtScript.SelText := #13#10;
404 if SsParser.MarkUpType[i] = mtStr then begin
405 if InSynchronized then
406 edtScript.SelAttributes.Color := Pref.TalkColorS
407 else if UnyuTalking then
408 edtScript.SelAttributes.Color := Pref.TalkColorU
410 edtScript.SelAttributes.Color := Pref.TalkColorH;
411 edtScript.SelText := SsParser[i];
414 if SsParser.MarkUpType[i] = mtMeta then begin
415 edtScript.SelAttributes.Color := Pref.MetaWordColor;
416 edtScript.SelText := SsParser[i];
422 procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char);
424 if Key = #13 then lvwLogDblClick(Sender);
427 procedure TfrmLog.CreateParams(var Params: TCreateParams);
430 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
433 procedure TfrmLog.lvwLogClick(Sender: TObject);
435 //
\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ô
437 Selected := Selected;
440 procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn);
441 var SortType: TBottleLogSortType;
445 if SelectedBottleLog = nil then
447 if lvwLog.Selected <> nil then
448 SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID
452 SortColumn := Column.Index;
454 -1: SortType := stLogTime;
455 subChannel: SortType := stChannel;
456 subGhost: SortType := stGhost;
457 subVotes: SortType := stVote;
458 subAgrees: SortType := stAgree;
459 subScript: SortType := stScript;
461 SortType := stLogTime;
464 SelectedBottleLog.SortBottles(SortType);
466 if Length(SelectedMID) > 0 then
467 SelAndFocusMessage(SelectedMID);
471 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
476 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.Selected.Index];
477 if Log = nil then Exit;
479 Clip.SetTextBuf(PChar(Log.Script));
482 procedure TfrmLog.SetBottleState(const MID: String; State: TLogState);
486 for i := 0 to FBottleLogList.Count-1 do begin
487 Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID);
488 if Bottle <> nil then begin
489 Bottle.State := State;
490 lvwLog.OnChange := nil;
492 lvwLog.OnChange := lvwLogChange;
497 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
499 if SelectedBottleLog = nil then Exit;
500 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
501 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
502 SaveDialog.DefaultExt := 'log';
503 SaveDialog.FilterIndex := 1;
504 if SaveDialog.Execute then
505 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false);
508 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
510 if SelectedBottleLog = nil then Exit;
511 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
512 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
513 SaveDialog.DefaultExt := 'log';
514 SaveDialog.FilterIndex := 1;
515 if SaveDialog.Execute then
516 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, true);
519 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
521 if SelectedBottleLog = nil then Exit;
522 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt');
523 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
524 SaveDialog.DefaultExt := 'txt';
525 SaveDialog.FilterIndex := 2;
526 if SaveDialog.Execute then
527 SelectedBottleLog.SaveToText(SaveDialog.FileName);
530 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
532 if SelectedBottleLog = nil then Exit;
533 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.xml');
534 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
535 SaveDialog.DefaultExt := 'xml';
536 SaveDialog.FilterIndex := 3;
537 if SaveDialog.Execute then
538 SelectedBottleLog.SaveToXmlFile(SaveDialog.FileName);
541 procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem);
545 if Item = nil then Exit;
547 Log := SelectedBottleLog.Bottles[i];
549 Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime);
551 SubItems.Add(Log.Channel);
552 SubItems.Add(Log.Ghost);
553 if Log.LogType = ltBottle then begin
554 if Log.Votes > 0 then
555 SubItems.Add(IntToStr(Log.Votes))
558 if Log.Agrees > 0 then
559 SubItems.Add(IntToStr(Log.Agrees))
563 //
\83V
\83X
\83e
\83\80\83\8d\83O
\82È
\82Ç
\82Í
\93\8a\95[
\81E
\93¯
\88Ó
\82ð
\95\
\8e¦
\82µ
\82È
\82¢
567 SubItems.Add(Log.Script);
569 if Log.LogType = ltBottle then begin
571 lsUnopened: ImageIndex := IconBottle;
572 lsPlaying: ImageIndex := IconPlaying;
573 lsOpened: ImageIndex := IconOpened;
576 ImageIndex := IconSystemLog;
580 procedure TfrmLog.UpdateWindow;
581 var EnabledFlag: boolean;
583 if true then begin // ColorScript
584 if lvwLog.Color <> Pref.BgColor then lvwLog.Color := Pref.BgColor;
585 if lvwLog.Font.Color <> Pref.TalkColorH then lvwLog.Font.Color := Pref.TalkColorH;
587 if lvwLog.Color <> clWindow then lvwLog.Color := clWindow;
588 if lvwLog.Font.Color <> clWindowText then lvwLog.Font.Color := clWindowText;
590 if SelectedBottleLog <> nil then begin
591 Caption := '
\83\8d\83O - ' + SelectedBottleLog.Title;
592 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
593 lvwLog.Items.Count := SelectedBottleLog.Count;
595 Caption := '
\83\8d\83O';
596 StatusBar.Panels[0].Text := '';
597 StatusBar.Panels[1].Text := '';
598 lvwLog.Items.Count := 0;
601 EnabledFlag := SelectedBottleLog <> nil;
602 tbtnClear.Enabled := EnabledFlag;
603 tbtnSaveLog.Enabled := EnabledFlag;
604 tbtnFindBottle.Enabled := EnabledFlag;
609 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
615 for i := mnJumpURL.Count-1 downto 0 do begin
616 mnJumpURL.Items[i].Free;
618 mnJumpURL.Enabled := false;
619 if lvwLog.Selected = nil then Exit;
620 Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index];
621 if Log = nil then Exit;
622 Urls := TStringList.Create;
624 ExtractURLs(Log.Script, Urls);
625 for i := 0 to Urls.Count-1 do begin
626 Child := TMenuItem.Create(Self);
628 Caption := Format('(&%d) %s', [i+1, StringReplace(Urls[i], '&', '&&', [rfReplaceAll])]);
630 OnClick := mnURLClick;
631 AutoHotkeys := maManual;
632 mnJumpURL.Add(Child);
635 mnJumpURL.Enabled := Urls.Count > 0;
641 procedure TfrmLog.mnURLClick(Sender: TObject);
642 var LogItem: TLogItem;
646 if (lvwLog.Selected = nil) or (SelectedBottleLog = nil) then Exit;
647 LogItem := SelectedBottleLog[lvwLog.Selected.Index] as TLogItem;
648 Urls := TStringList.Create;
650 ExtractURLs(LogItem.Script, Urls);
651 URL := Urls[(Sender as TMenuItem).Tag];
652 ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW);
658 procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings);
659 var i, u, j: integer;
663 SsParser.InputString := Script;
664 for i := 0 to SsParser.Count-1 do begin
665 if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
666 for u := 7 downto 1 do begin
667 if (SsParser.Match(SsParser[i],
668 '\URL%b'+StringReplace(StringOfChar('-', u*2),
669 '-', '%b', [rfReplaceAll]))) > 0 then begin
670 for j := 1 to u do begin
671 s := SsParser.GetParam(SsParser[i], j*2);
672 if Pos('http://', s) > 0 then Result.Add(s);
677 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
678 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
679 s := SsParser.GetParam(SsParser[i], 1);
680 if Pos('http://', s) > 0 then Result.Add(s);
686 procedure TfrmLog.SelAndFocusMessage(const MID: String);
690 for i := 0 to SelectedBottleLog.Count-1 do begin
691 Log := SelectedBottleLog.Items[i] as TLogItem;
692 if Log.MID = MID then begin
693 lvwLog.Items[i].Selected := true;
694 lvwLog.Items[i].Focused := true;
699 procedure TfrmLog.lvwLogCustomDrawItem(Sender: TCustomListView;
700 Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
705 procedure TfrmLog.UpdateScript(const Script: String);
707 if Script <> FLastScript then begin
708 if Pref.LogWindowPreviewStyle = psConversation then begin
709 UpdateScriptConversationColor(Script);
711 UpdateScriptScript(Script);
713 SendMessage(edtScript.Handle, EM_LINESCROLL, Low(integer), Low(integer)); //
\83X
\83N
\83\8d\81[
\83\8b\96ß
\82µ
714 FLastScript := Script;
718 procedure TfrmLog.PopupMenuPreviewStylePopup(Sender: TObject);
721 with PopupMenuPreviewStyle do
722 for i := 0 to Items.Count-1 do
723 Items[i].Checked := Items[i].Tag = Ord(Pref.LogWindowPreviewStyle)
726 procedure TfrmLog.mnPreviewStyleClick(Sender: TObject);
729 with PopupMenuPreviewStyle do
730 for i := 0 to Items.Count-1 do
731 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
732 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag);
735 lvwLogChange(self, lvwLog.Selected, ctState);
738 procedure TfrmLog.UpdateScriptScript(const Script: String);
740 UnyuTalking, InSynchronized: boolean;
743 edtScript.Color := Pref.BgColor;
744 SsParser.LeaveEscape := true;
745 SsParser.InputString := Script;
746 edtScript.Text := '';
747 edtScript.SelAttributes.Color := clWindowText;
748 UnyuTalking := false;
749 InSynchronized := false;
750 for i := 0 to SsParser.Count-1 do begin
751 case SsParser.MarkUpType[i] of
753 if InSynchronized then
754 edtScript.SelAttributes.Color := Pref.TalkColorS
755 else if UnyuTalking then
756 edtScript.SelAttributes.Color := Pref.TalkColorU
758 edtScript.SelAttributes.Color := Pref.TalkColorH;
761 edtScript.SelAttributes.Color := Pref.MarkUpColor;
762 if SsParser[i] = '\h' then
764 else if SsParser[i] = '\u' then
766 else if SsParser[i] = '\_s' then
767 InSynchronized := not InSynchronized;
769 mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor;
770 mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor;
772 edtScript.SelText := SsParser[i];
773 if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then
774 edtScript.SelText := #13#10;
778 procedure TfrmLog.tbtnPreviewStyleClick(Sender: TObject);
781 sel := Ord(Pref.LogWindowPreviewStyle);
783 if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0;
784 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel);
787 lvwLogChange(self, lvwLog.Selected, ctState);
790 function TfrmLog.SelectedBottleLog: TBottleLogList;
792 if tabBottleLog.TabIndex >= 0 then
793 Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList
798 procedure TfrmLog.tabBottleLogChange(Sender: TObject);
801 if SelectedBottleLog.SelectedIndex >= 0 then begin
802 lvwLog.Items[SelectedBottleLog.SelectedIndex].Selected := true;
803 if lvwLog.Focused then lvwLog.Selected.Focused := true;
805 lvwLogChange(Self, nil, ctState);
808 procedure TfrmLog.LogLoaded(Sender: TObject);
810 if SelectedBottleLog = Sender then begin
815 procedure TfrmLog.UpdateTab;
818 cur := tabBottleLog.tabIndex;
819 tabBottleLog.Tabs.Clear;
820 for i := 0 to FBottleLogList.Count - 1 do begin
821 tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title);
823 if FBottleLogList.Count > 0 then begin
824 if cur < FBottleLogList.Count then
825 tabBottleLog.TabIndex := cur
827 tabBottleLog.TabIndex := FBottleLogList.Count-1;
831 procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String);
834 ShowMessage(Message);
835 if Sender = SelectedBottleLog then UpdateWindow;
838 procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer);
843 for i := 0 to FBottleLogList.Count - 1 do begin
844 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
845 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Agrees := Agree;
849 if flag then lvwLog.Invalidate;
852 procedure TfrmLog.VoteLog(const MID: String; const Vote: integer);
857 for i := 0 to FBottleLogList.Count - 1 do begin
858 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
859 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Votes := Vote;
863 if flag then lvwLog.Invalidate;
866 procedure TfrmLog.tabBottleLogChanging(Sender: TObject;
867 var AllowChange: Boolean);
869 //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83\8d\83O
\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95Û
\91¶
870 if SelectedBottleLog = nil then Exit;
871 if lvwLog.Selected <> nil then
872 SelectedBottleLog.SelectedIndex := lvwLog.Selected.Index
874 SelectedBottleLog.SelectedIndex := -1;
877 procedure TfrmLog.tabBottleLogContextPopup(Sender: TObject;
878 MousePos: TPoint; var Handled: Boolean);
880 with tabBottleLog do begin
881 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
882 if Tag < 0 then Handled := true;
886 procedure TfrmLog.mnCloseTabClick(Sender: TObject);
887 var PrevSelection: TBottleLogList; //
\95Â
\82¶
\82½
\82Æ
\82«
\83^
\83u
\82ª
\82¸
\82ê
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\8f\88\97\9d\97p
890 PrevSelection := SelectedBottleLog;
891 FBottleLogList.Delete(tabBottleLog.Tag);
893 //
\83^
\83u
\82¸
\82ê
\96h
\8e~
\8f\88\97\9d
894 for i := 0 to FBottleLogList.Count-1 do
895 if FBottleLogList[i] = PrevSelection then
896 tabBottleLog.TabIndex := i;
898 lvwLogChange(Self, nil, ctState);
901 procedure TfrmLog.tbtnFindBottleClick(Sender: TObject);
903 ResultLog: TBottleLogList;
904 Item1, Item2: TLogItem;
907 if SelectedBottleLog = nil then Exit;
908 if SelectedBottleLog.Count = 0 then begin
909 ShowMessage('
\8c\9f\8dõ
\91Î
\8fÛ
\82ª
\8bó
\82Å
\82·
\81B');
914 if InputQuery('
\83X
\83N
\83\8a\83v
\83g
\96{
\95¶
\82ð
\8c\9f\8dõ', '
\8c\9f\8dõ
\95¶
\8e\9a\97ñ', Query) then begin
915 if Query = '' then Exit;
916 ResultLog := TBottleLogList.Create('
\8c\9f\8dõ
\8c\8b\89Ê');
917 for i := 0 to SelectedBottleLog.Count-1 do begin
918 Item1 := SelectedBottleLog.Items[i] as TLogItem;
919 if AnsiContainsText(Item1.Script, Query) and (Item1.LogType = ltBottle) then begin
920 matched := matched + 1;
921 Item2 := TLogItem.Create(ltBottle, Item1.MID, Item1.Channel,
922 Item1.Script, Item1.Ghost, Item1.LogTime);
923 Item2.State := lsOpened;
924 Item2.Votes := Item1.Votes;
925 Item2.Agrees := Item1.Agrees;
926 ResultLog.Add(Item2);
930 ResultLog.AddSystemLog('
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½');
931 BottleLogList.Add(ResultLog);
933 tabBottleLog.TabIndex := BottleLogList.Count-1;
938 procedure TfrmLog.tbtnOpenLogClick(Sender: TObject);
939 var BottleLog: TBottleLogList;
943 if OpenDialog.Execute then begin
944 for i := 0 to OpenDialog.Files.Count-1 do begin
945 BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i]));
949 OnLoaded := LogLoaded;
950 OnLoadFailure := LogLoadFailure;
951 OnLoadWork := LogLoadWork;
952 BottleLog.LoadFromXMLFile(OpenDialog.Files[i]);
954 Index := BottleLogList.Add(BottleLog); //
\8dÅ
\8cã
\82É
\8aJ
\82¢
\82½
\83\8d\83O
\82Ì
\88Ê
\92u
\82ð
\8bL
\89¯
960 if Index >= 0 then tabBottleLog.TabIndex := Index;
965 function TfrmLog.GetDefaultFileName(const Name, Ext: String): String;
967 Result := StringReplace(Name, '/', '', [rfReplaceAll]);
968 Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
969 Result := ChangeFileExt(Result, Ext);
972 function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList;
975 for i := 0 to FBottleLogList.Count-1 do begin
976 if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin
977 Result := (FBottleLogList[i] as TBottleLogList);
981 //
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\8fê
\8d\87
982 Result := TBottleLogList.Create(LogName); //
\90V
\82µ
\82
\8dì
\82é
983 FBottleLogList.Add(Result);
985 if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0;
988 procedure TfrmLog.AllBottleOpened;
992 for i := 0 to FBottleLogList.Count-1 do begin
993 Log := FBottleLogList[i] as TBottleLogList;
994 for j := 0 to Log.Count-1 do begin
995 Log.Bottles[j].State := lsOpened;
1000 procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject;
1001 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1004 with tabBottleLog do begin
1005 Index := IndexOfTabAt(X, Y);
1006 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1007 if Button = mbLeft then begin
1008 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1010 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1015 procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X,
1016 Y: Integer; State: TDragState; var Accept: Boolean);
1017 var TargetRect: TRect;
1020 Accept := Source = tabBottleLog;
1021 if not Accept then Exit;
1022 with tabBottleLog do begin
1023 OldDest := FDragTabDest;
1024 FDragTabDest := IndexOfTabAt(X, Y);
1025 if FDragTabDest = -1 then begin
1026 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1029 with Canvas do begin
1033 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1034 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1035 TargetRect := TabRect(OldDest);
1036 with Canvas do begin
1037 Brush.Style := bsClear;
1038 Rectangle(TargetRect.Left, TargetRect.Top,
1039 TargetRect.Right, TargetRect.Bottom);
1042 if (OldDest <> FDragTabDest) then begin
1043 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1044 TargetRect := TabRect(FDragTabDest);
1045 with Canvas do begin
1046 Brush.Style := bsClear;
1047 Rectangle(TargetRect.Left, TargetRect.Top,
1048 TargetRect.Right, TargetRect.Bottom);
1054 procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X,
1056 var DestIndex: integer;
1058 with tabBottleLog do begin
1059 DestIndex := IndexOfTabAt(X, Y);
1060 Tabs.Move(FDragTabIndex, DestIndex);
1061 FBottleLogList.Move(FDragTabIndex, DestIndex);
1065 procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X,
1068 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1069 tabBottleLog.Tabs.BeginUpdate;
1070 tabBottleLog.Tabs.EndUpdate;
1073 procedure TfrmLog.LogLoadWork(Sender: TObject);
1075 if Sender = SelectedBottleLog then lvwLog.Invalidate;
1078 procedure TfrmLog.lvwLogDrawItem(Sender: TCustomListView; Item: TListItem;
1079 Rect: TRect; State: TOwnerDrawState);
1086 DummyStr: TStringList;
1088 Bottle := SelectedBottleLog.Bottles[Item.Index];
1089 if Bottle.HasURL = huUndefined then
1091 DummyStr := TStringList.Create;
1093 ExtractURLs(Bottle.Script, DummyStr);
1094 if DummyStr.Count > 0 then
1095 Bottle.HasURL := huYes
1097 Bottle.HasURL := huNo;
1103 //
\94w
\8ci
\8fÁ
\8b\8e
1104 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_BOUNDS);
1106 lvwLog.Canvas.Brush.Style := bsSolid;
1107 if Item.Selected then begin
1108 if lvwLog.Focused then
1109 lvwLog.Canvas.Brush.Color := clHighlight
1111 lvwLog.Canvas.Brush.Color := clBtnFace;
1113 lvwLog.Canvas.Brush.Color := Pref.BgColor;
1115 lvwLog.Canvas.FillRect(DestRect);
1116 lvwLog.Canvas.Brush.Style := bsClear;
1117 if Item.Focused and lvwLog.Focused then
1118 lvwLog.Canvas.DrawFocusRect(DestRect);
1120 if Item.Selected then
1122 if lvwLog.Focused then
1123 lvwLog.Canvas.Font.Color := clHighlightText
1125 lvwLog.Canvas.Font.Color := clWindowText;
1127 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1128 lvwLog.Canvas.Refresh;
1130 //
\83L
\83\83\83v
\83V
\83\87\83\93(
\93ú
\95t)
1131 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_LABEL);
1132 Inc(DestRect.Left, 2);
1133 Inc(DestRect.Top, 2);
1134 Dec(DestRect.Right, 2);
1135 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.Caption), -1, DestRect,
1136 DT_SINGLELINE or DT_END_ELLIPSIS, nil);
1137 ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_ICON);
1138 Ico := TIcon.Create;
1140 lvwLog.SmallImages.GetIcon(Item.ImageIndex, Ico);
1141 lvwLog.Canvas.Draw(DestRect.Left, DestRect.Top, Ico);
1145 //
\83L
\83\83\83v
\83V
\83\87\83\93\82Å
\82à
\83X
\83N
\83\8a\83v
\83g
\82Å
\82à
\82È
\82¢
\82à
\82Ì
1146 for sub := 0 to Item.SubItems.Count-1 do
1148 if sub = SubScript then Continue;
1149 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, sub + 1,
1150 LVIR_BOUNDS, @DestRect);
1151 Inc(DestRect.Left, 2);
1152 Inc(DestRect.Top, 2);
1153 Dec(DestRect.Right, 2);
1154 Ex := DT_NOPREFIX or DT_SINGLELINE or DT_END_ELLIPSIS;
1155 if lvwLog.Columns[sub+1].Alignment = taRightJustify then
1156 Ex := Ex or DT_RIGHT;
1157 DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.SubItems[sub]), -1, DestRect,
1160 //
\83X
\83N
\83\8a\83v
\83g
1161 ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript + 1,
1162 LVIR_BOUNDS, @DestRect);
1163 Script := Item.SubItems[SubScript];
1164 DrawSingleLineScript(Bottle, DestRect, Item);
1167 procedure TfrmLog.DrawSingleLineScript(LogItem: TLogItem;
1168 Rect: TRect; Item: TListItem);
1171 UnyuTalking, Synchronized, Spaced: boolean;
1172 Mark: TSsMarkUpType;
1175 procedure ScopeChange;
1177 if (not Spaced) and (Pref.LogListPreviewStyle = psTagStripped) then
1184 Script := LogItem.Script;
1187 if LogItem.HasURL = huYes then
1189 Ico := TIcon.Create;
1191 lvwLog.SmallImages.GetIcon(IconURL, Ico);
1192 lvwLog.Canvas.Draw(Rect.Left + x, Rect.Top, Ico);
1199 if Pref.LogListPreviewStyle = psNoColor then
1204 DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, Rect,
1205 DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX, nil);
1209 SsParser.LeaveEscape := Pref.LogListPreviewStyle = psNormal;
1210 SsParser.InputString := Script;
1212 UnyuTalking := false;
1213 Synchronized := false;
1214 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¢
1215 //
\82½
\82ß
\82Ì
\83t
\83\89\83O
1216 for i := 0 to SsParser.Count - 1 do begin
1217 if SsParser[i] = '\h' then
1219 UnyuTalking := false;
1221 end else if SsParser[i] = '\u' then
1223 UnyuTalking := true;
1225 end else if SsParser[i] = '\_s' then
1227 Synchronized := not Synchronized;
1229 end else if (Pos('\n', SsParser[i]) = 1) or (SsParser[i] = '\c') then
1233 Mark := SsParser.MarkUpType[i];
1237 lvwLog.Canvas.Font.Color := Pref.MetaWordColor;
1241 if Pref.LogListPreviewStyle = psNormal then
1242 lvwLog.Canvas.Font.Color := Pref.MarkUpColor
1248 lvwLog.Canvas.Font.Color := Pref.MarkErrorColor;
1251 if Synchronized then
1252 lvwLog.Canvas.Font.Color := Pref.TalkColorS
1253 else if UnyuTalking then
1254 lvwLog.Canvas.Font.Color := Pref.TalkColorU
1256 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1259 if Item.Selected then
1261 if lvwLog.Focused then
1262 lvwLog.Canvas.Font.Color := clHighlightText
1264 lvwLog.Canvas.Font.Color := clWindowText;
1266 lvwLog.Canvas.Refresh;
1267 w := lvwLog.Canvas.TextWidth(SsParser[i]);
1268 lvwLog.Canvas.TextRect(Rect, Rect.Left + x, Rect.Top + 2, SsParser[i]);
1270 if Rect.Right - Rect.Left < x then Break;
1274 procedure TfrmLog.mnListPreviewStyleClick(Sender: TObject);
1277 with PopupMenuListPreviewStyle do
1278 for i := 0 to Items.Count-1 do
1279 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
1280 Pref.LogListPreviewStyle := TLogListPreviewStyle((Sender as TMenuItem).Tag);
1284 procedure TfrmLog.tbtnListPreviewStyleClick(Sender: TObject);
1287 sel := Ord(Pref.LogListPreviewStyle);
1289 if sel > Ord(High(TLogListPreviewStyle)) then sel := 0;
1290 Pref.LogListPreviewStyle := TLogListPreviewStyle(sel);
1294 procedure TfrmLog.PopupMenuListPreviewStylePopup(Sender: TObject);
1297 with PopupMenuListPreviewStyle do
1298 for i := 0 to Items.Count-1 do
1299 Items[i].Checked := Items[i].Tag = Ord(Pref.LogListPreviewStyle)
1302 procedure TfrmLog.PreviewStyleChange;
1304 if Pref.LogWindowPreviewStyle = psImageConversation then
1306 if Spps.Count = 0 then
1307 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');
1308 edtScript.Visible := false;
1309 TalkShowFrame.Visible := true;
1312 edtScript.Visible := true;
1313 TalkShowFrame.Visible := false;