6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ComCtrls, ToolWin, StdCtrls, SsParser, BottleDef, Menus,
8 Clipbrd, Logs, ShellAPI, Commctrl, DirectSstp, Contnrs, StrUtils,
9 TalkShowFrame, SppList, HtmlOutputConfig, HtmlOutputProgress,
10 SearchLog, IniFiles, BRegExp, RegexUtils, ExtCtrls;
13 //
\83\8d\83O
\82Ì
\95Û
\91¶
\95û
\96@
14 TSaveLogType = (stLog, stLogWithChannels, stText, stXML);
16 //
\83\8a\83X
\83g
\83r
\83\85\81[
\82Ì
\83X
\83N
\83\8d\81[
\83\8b\95û
\8cü
17 TLVScrollDir = (lvScrollUp, lvScrollDown);
19 TfrmLog = class(TForm)
21 tbtnClear: TToolButton;
24 StatusBar: TStatusBar;
25 tbtnSaveLog: TToolButton;
26 PopupMenuPreview: TPopupMenu;
28 tbtnVoteMessage: TToolButton;
29 PopupMenuListView: TPopupMenu;
30 mnPopUpVoteMessage: TMenuItem;
31 SaveDialog: TSaveDialog;
34 mnPopUpCopyScript: TMenuItem;
35 PopupMenuSaveLog: TPopupMenu;
37 mnSaveLogChannel: TMenuItem;
38 mnSaveLogScript: TMenuItem;
39 mnSaveLogXML: TMenuItem;
40 ToolButton1: TToolButton;
42 mnPopUpAgreeMessage: TMenuItem;
43 tbtnAgreeMessage: TToolButton;
44 ToolButton2: TToolButton;
45 tbtnPreviewStyle: TToolButton;
46 PopupMenuPreviewStyle: TPopupMenu;
47 mnPreviewStyleConversation: TMenuItem;
48 mnPreviewStyleScript: TMenuItem;
49 mnPreviewStyleScriptWithLineBreak: TMenuItem;
51 tabBottleLog: TTabControl;
52 tbtnDownloadLog: TToolButton;
53 PopupMenuTab: TPopupMenu;
54 mnCloseTab: TMenuItem;
55 tbtnFindBottle: TToolButton;
56 tbtnOpenLog: TToolButton;
57 OpenDialog: TOpenDialog;
58 tbtnInsertCue: TToolButton;
59 mnInsertCue: TMenuItem;
60 PopupMenuListPreviewStyle: TPopupMenu;
61 mnListPreviewStyleNormal: TMenuItem;
62 mnListPreviewStyleTagStripped: TMenuItem;
63 tbtnListPreviewStyle: TToolButton;
64 mnListPreviewStyleNoColor: TMenuItem;
65 SsParserForTalkShow: TSsParser;
66 mnPreviewStyleConversationImage: TMenuItem;
67 pnlPreviewArea: TPanel;
68 TalkShowFrame: TfrmTalkShow;
70 tbtnSendEditor: TToolButton;
71 mnSendEditor: TMenuItem;
72 timScrollTimer: TTimer;
73 mnChangeTabName: TMenuItem;
77 mnDeleteLogItem: TMenuItem;
78 mnTabSaveXMLLog: TMenuItem;
79 mnSaveHTML: TMenuItem;
80 mnPopupCopyGhost: TMenuItem;
81 Header: THeaderControl;
82 procedure tbtnClearClick(Sender: TObject);
83 procedure FormCreate(Sender: TObject);
84 procedure lvwLogDblClick(Sender: TObject);
85 procedure FormDestroy(Sender: TObject);
86 procedure lvwLogClick(Sender: TObject);
87 procedure mnSaveLogClick(Sender: TObject);
88 procedure mnPopUpCopyScriptClick(Sender: TObject);
89 procedure mnSaveLogChannelClick(Sender: TObject);
90 procedure mnSaveLogScriptClick(Sender: TObject);
91 procedure mnSaveLogXMLClick(Sender: TObject);
92 procedure PopupMenuListViewPopup(Sender: TObject);
93 procedure PopupMenuPreviewStylePopup(Sender: TObject);
94 procedure mnPreviewStyleClick(Sender: TObject);
95 procedure tbtnPreviewStyleClick(Sender: TObject);
96 procedure tabBottleLogChange(Sender: TObject);
97 procedure tabBottleLogChanging(Sender: TObject;
98 var AllowChange: Boolean);
99 procedure tabBottleLogContextPopup(Sender: TObject; MousePos: TPoint;
100 var Handled: Boolean);
101 procedure mnCloseTabClick(Sender: TObject);
102 procedure tbtnFindBottleClick(Sender: TObject);
103 procedure tbtnOpenLogClick(Sender: TObject);
104 procedure tabBottleLogMouseDown(Sender: TObject; Button: TMouseButton;
105 Shift: TShiftState; X, Y: Integer);
106 procedure tabBottleLogDragOver(Sender, Source: TObject; X, Y: Integer;
107 State: TDragState; var Accept: Boolean);
108 procedure tabBottleLogDragDrop(Sender, Source: TObject; X, Y: Integer);
109 procedure tabBottleLogEndDrag(Sender, Target: TObject; X, Y: Integer);
110 procedure mnListPreviewStyleClick(Sender: TObject);
111 procedure tbtnListPreviewStyleClick(Sender: TObject);
112 procedure PopupMenuListPreviewStylePopup(Sender: TObject);
113 procedure lvwLogDragOver(Sender, Source: TObject; X, Y: Integer;
114 State: TDragState; var Accept: Boolean);
115 procedure lvwLogDragDrop(Sender, Source: TObject; X, Y: Integer);
116 procedure timScrollTimerTimer(Sender: TObject);
117 procedure mnChangeTabNameClick(Sender: TObject);
118 procedure lvwLogStartDrag(Sender: TObject;
119 var DragObject: TDragObject);
120 procedure lvwLogEndDrag(Sender, Target: TObject; X, Y: Integer);
121 procedure mnTabSaveXMLLogClick(Sender: TObject);
122 procedure mnSaveHTMLClick(Sender: TObject);
123 procedure mnPopupCopyGhostClick(Sender: TObject);
124 procedure lvwLogDrawItem(Control: TWinControl; Index: Integer;
125 Rect: TRect; State: TOwnerDrawState);
126 procedure lvwLogData(Control: TWinControl; Index: Integer;
128 procedure HeaderSectionClick(HeaderControl: THeaderControl;
129 Section: THeaderSection);
130 procedure HeaderSectionTrack(HeaderControl: THeaderControl;
131 Section: THeaderSection; Width: Integer; State: TSectionTrackState);
132 procedure lvwLogMouseDown(Sender: TObject; Button: TMouseButton;
133 Shift: TShiftState; X, Y: Integer);
136 FLastScript: String; //
\83X
\83N
\83\8a\83v
\83g
\8dÄ
\95`
\89æ
\97}
\90§
\97p
137 FBottleLogList: TObjectList;
139 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
140 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)
142 //
\83\8a\83X
\83g
\83r
\83\85\81[
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
143 FLVScrollDir: TLVScrollDir; //
\83X
\83N
\83\8d\81[
\83\8b\95û
\8cü
144 FLVDragDest: integer; //
\83h
\83\8d\83b
\83v
\82·
\82é
\88Ê
\92u(
\82·
\82®
\89º
\82É
\82
\82é
\83A
\83C
\83e
\83\80\82ÌIndex)
145 //
\83\8a\83X
\83g
\83{
\83b
\83N
\83X
\82Ì
\83L
\81[
\83C
\83x
\83\93\83g
\83t
\83b
\83N
\97p
146 FLVWndMethod: TWndMethod;
148 procedure UpdateScript(const Script: String);
149 procedure UpdateScriptConversationColor(const Script: String);
150 procedure UpdateScriptScript(const Script: String);
151 procedure mnURLClick(Sender: TObject);
152 function ExtractURLs(Script: String; Urls: TStrings; Labels: TStrings): Boolean;
153 function GetDefaultFileName(const Name: String; const Ext: String): String;
154 function BottleLogTitled(const LogName: String): TBottleLogList;
155 procedure DrawSingleLineScript(LogItem: TLogItem; Rect: TRect;
156 State: TOwnerDrawState);
157 procedure PreviewStyleChange;
158 procedure DrawListViewDragBorder(const Rect: TRect);
159 procedure DoSaveLogXML(Log: TBottleLogList);
160 procedure DoCloseTab(const Index: integer);
161 function DoSearchLog(Condition: TSearchCond): TBottleLogList;
162 procedure SearchLogIndivisual(Condition: TSearchCond;
163 LogList, Result: TBottleLogList; UntilIndex: integer = -1);
164 procedure DrawListSection(const SectionIndex, Top: Integer;
165 const Text: string; const LeftMargin: Integer = 0);
166 procedure lvwLogWindowProc(var Msg: TMessage);
168 procedure CreateParams(var Params: TCreateParams); override;
171 function SelectedBottleLog: TBottleLogList;
172 property BottleLogList: TObjectList read FBottleLogList;
173 procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
174 procedure AddCurrentSystemLog(const LogName, MessageString: String);
175 procedure VoteLog(const MID: String; const Vote: integer);
176 procedure AgreeLog(const MID: String; const Agree: integer);
177 procedure SetBottleState(const MID: String; State: TLogState);
178 procedure AllBottleOpened;
179 procedure LogLoaded(Sender: TObject);
180 procedure LogLoadFailure(Sender: TObject; const Message: String);
181 procedure LogLoadWork(Sender: TObject);
182 procedure HTMLOutputWork(Sender: TObject; const Count: integer;
183 var Canceled: boolean);
185 procedure UpdateWindow;
186 procedure SelAndFocusMessage(const MID: String);
187 procedure CheckBottleURL(Bottle: TLogItem);
190 TBottleLogDragObject = class(TDragControlObjectEx)
192 FBottleLogList: TBottleLogList;
194 procedure SetBottleLogList(const Value: TBottleLogList);
195 procedure SetLogItem(const Value: TLogItem);
197 function GetDragImages: TDragImageList; override;
199 property BottleLogList: TBottleLogList read FBottleLogList write SetBottleLogList;
200 property LogItem: TLogItem read FLogItem write SetLogItem;
227 procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String);
230 BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost);
231 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
232 if lvwLog.Itemindex <> -1 then
233 Sel := lvwLog.ItemIndex
236 lvwLog.Count := SelectedBottleLog.Count;
238 if Sel >= 0 then begin
239 lvwLog.ItemIndex := Sel + 1;
241 if not lvwLog.Focused then
242 PostMessage(lvwLog.Handle,WM_VSCROLL,SB_TOP,0);
245 procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String);
248 BottleLogTitled(LogName).AddSystemLog(MessageString);
249 if SelectedBottleLog <> BottleLogTitled(LogName) then Exit;
250 if lvwLog.ItemIndex <> -1 then
251 Sel := lvwLog.ItemIndex
254 lvwLog.Count := SelectedBottleLog.Count;
256 if Sel >= 0 then begin
257 lvwLog.ItemIndex := Sel + 1;
260 if not lvwLog.Focused then
261 PostMessage(lvwLog.Handle,WM_VSCROLL,SB_TOP,0);
266 procedure TfrmLog.tbtnClearClick(Sender: TObject);
268 if SelectedBottleLog = nil then Exit;
269 DoCloseTab(tabBottleLog.TabIndex);
272 procedure TfrmLog.FormCreate(Sender: TObject);
275 FLVWndMethod := lvwLog.WindowProc;
276 lvwLog.WindowProc := lvwLogWindowProc;
278 FLVDragDest := -1; //
\83\8a\83X
\83g
\83r
\83\85\81[
\82Ì
\83h
\83\89\83b
\83O
\92\86\82Å
\82Í
\82È
\82¢
279 FBottleLogList := TObjectList.Create;
281 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
282 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
284 with Pref.LogWindowPosition do begin
287 Self.Width := Right - Left + 1;
288 Self.Height := Bottom - Top + 1;
290 lvwLog.DoubleBuffered := true;
291 pnlPreviewArea.Height := Pref.LogWindowDividerPos;
294 while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin
295 Header.Sections[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100);
299 SsParserForTalkShow.TagPattern.Assign(SsParser.TagPattern);
300 SsParserForTalkShow.MetaPattern.Assign(SsParser.MetaPattern);
301 SsParserForTalkShow.EscapeInvalidMeta := false;
302 SsParserForTalkShow.LeaveEscape := false;
303 TalkShowFrame.SsParser := self.SsParserForTalkShow;
305 TalkShowFrame.SetPreviewFont(edtScript.Font);
306 TalkShowFrame.PrevControl := lvwLog;
308 lvwLog.DoubleBuffered := true;
311 UpdateWindow; // Reset window color and enabled status of some buttons
314 procedure TfrmLog.FormDestroy(Sender: TObject);
319 for i := 0 to Header.Sections.Count-1 do begin
320 if i > 0 then WidthStr := WidthStr + ',';
321 WidthStr := WidthStr + IntToStr(Header.Sections[i].Width);
323 Pref.LogWindowColumnWidth := WidthStr;
325 with Pref.LogWindowPosition do begin
328 Right := Self.Left + Self.Width - 1;
329 Bottom := Self.Top + Self.Height - 1;
331 Pref.LogWindowDividerPos := pnlPreviewArea.Height;
333 FreeAndNil(FBottleLogList);
335 lvwLog.WindowProc := FLVWndMethod;
338 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
339 var Script, ErrorMes: String;
340 Log, CueItem: TLogItem;
343 if lvwLog.ItemIndex = -1 then
345 Log := SelectedBottleLog.Bottles[lvwLog.ItemIndex];
346 if Log = nil then Exit;
347 if Log.LogType <> ltBottle then
349 Script := frmSender.ScriptTransForSSTP(Log.Script, ErrorMes);
350 if ErrorMes <> '' then
352 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+
354 '
\8b
\90§
\93I
\82É
\8dÄ
\90¶
\82µ
\82Ü
\82·
\82©?'#13#10,
355 mtWarning, mbOkCancel, 0
357 if Res = mrCancel then
361 CueItem := TLogItem.Create(Log);
363 CueItem.Script := Script;
364 frmSender.BottleSstp.Unshift(CueItem);
370 procedure TfrmLog.UpdateScriptConversationColor(const Script: String);
373 UnyuTalking, Talked, InSynchronized: boolean;
376 frmSender.DoTrans(scr, [toConvertURL]);
377 SsParser.LeaveEscape := false;
378 SsParser.InputString := scr;
379 UnyuTalking := false;
380 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
381 InSynchronized := false;
382 edtScript.Text := '';
383 edtScript.Color := Pref.BgColor;
384 for i := 0 to SsParser.Count-1 do begin
385 if (SsParser[i] = '\_s') and not InSynchronized then begin
386 InSynchronized := true;
388 edtScript.SelText := #13#10;
391 end else if (SsParser[i] = '\_s') and InSynchronized then begin
392 InSynchronized := false;
394 edtScript.SelText := #13#10;
398 if (SsParser[i] = '\u') and not UnyuTalking then begin
401 edtScript.SelText := #13#10;
405 if (SsParser[i] = '\h') and UnyuTalking then begin
406 UnyuTalking := false;
408 edtScript.SelText := #13#10;
412 if SsParser.MarkUpType[i] = mtStr then begin
413 if InSynchronized then
414 edtScript.SelAttributes.Color := Pref.TalkColorS
415 else if UnyuTalking then
416 edtScript.SelAttributes.Color := Pref.TalkColorU
418 edtScript.SelAttributes.Color := Pref.TalkColorH;
419 edtScript.SelText := SsParser[i];
422 if SsParser.MarkUpType[i] = mtMeta then begin
423 edtScript.SelAttributes.Color := Pref.MetaWordColor;
424 edtScript.SelText := SsParser[i];
430 procedure TfrmLog.CreateParams(var Params: TCreateParams);
433 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
436 procedure TfrmLog.lvwLogClick(Sender: TObject);
437 var Script, Text: String;
439 Selected, IsNormalBottle: boolean;
442 IsNormalBottle := false;
443 if SelectedBottleLog <> nil then begin
445 if lvwLog.ItemIndex <> -1 then begin
447 StatusBar.Panels[0].Text := Format('%d/%d
\8c\8f', [lvwLog.ItemIndex+1,
448 SelectedBottleLog.Count]);
449 Log := SelectedBottleLog.Bottles[lvwLog.ItemIndex];
450 if (Log.LogType = ltBottle) and not frmSender.Connecting then begin
451 IsNormalBottle := true;
452 Script := Log.Script;
453 Text := Format('%d
\83o
\83C
\83g/%d
\95b -
\83_
\83u
\83\8b\83N
\83\8a\83b
\83N
\82Å
\8dÄ
\90¶',
454 [Length(Log.Script), frmSender.SsPlayTime.PlayTime(Log.Script) div 1000]);
455 StatusBar.Panels[1].Text := Text;
456 if Pref.LogWindowPreviewStyle = psImageConversation then
457 TalkShowFrame.View(Log)
459 UpdateScript(Script);
461 StatusBar.Panels[1].Text := '';
462 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\82ð
\83N
\83\8a\83A
465 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
466 StatusBar.Panels[1].Text := '';
467 UpdateScript(Script); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
469 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
471 StatusBar.Panels[0].Text := '';
472 UpdateScript(''); //
\83\8d\83O
\83v
\83\8c\83r
\83\85\81[
\95\94\83N
\83\8a\83A
474 frmSender.actVoteMessage.Enabled := Selected and IsNormalBottle;
475 frmSender.actAgreeMessage.Enabled := Selected and IsNormalBottle;
476 frmSender.actSendToEditor.Enabled := Selected and IsNormalBottle;
477 frmSender.actInsertCue.Enabled := Selected;
478 frmSender.actDeleteLogItem.Enabled := Selected;
479 mnPopUpCopyScript.Enabled := Selected and IsNormalBottle;
480 mnPopupCopyGhost.Enabled := Selected and IsNormalBottle;
483 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
488 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.ItemIndex];
489 if Log = nil then Exit;
491 Clip.SetTextBuf(PChar(Log.Script));
494 procedure TfrmLog.SetBottleState(const MID: String; State: TLogState);
498 for i := 0 to FBottleLogList.Count-1 do begin
499 Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID);
500 if Bottle <> nil then begin
501 Bottle.State := State;
502 // lvwLog.OnChange := nil;
504 // lvwLog.OnChange := lvwLogChange;
509 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
511 if SelectedBottleLog = nil then Exit;
512 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
513 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
514 SaveDialog.DefaultExt := 'log';
515 SaveDialog.FilterIndex := 1;
516 if SaveDialog.Execute then
517 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false);
520 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
522 if SelectedBottleLog = nil then Exit;
523 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log');
524 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
525 SaveDialog.DefaultExt := 'log';
526 SaveDialog.FilterIndex := 1;
527 if SaveDialog.Execute then
528 SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, true);
531 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
533 if SelectedBottleLog = nil then Exit;
534 SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt');
535 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
536 SaveDialog.DefaultExt := 'txt';
537 SaveDialog.FilterIndex := 2;
538 if SaveDialog.Execute then
539 SelectedBottleLog.SaveToText(SaveDialog.FileName);
542 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
544 if SelectedBottleLog = nil then Exit;
545 DoSaveLogXML(SelectedBottleLog);
548 procedure TfrmLog.UpdateWindow;
550 EnabledFlag: boolean;
553 lvwLog.Color := Pref.BgColor;
554 lvwLog.Font.Color := Pref.TextColor;
555 if SelectedBottleLog <> nil then begin
556 Caption := '
\83\8d\83O - ' + SelectedBottleLog.Title;
557 StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + '
\8c\8f';
558 Index := lvwLog.ItemIndex;
559 lvwLog.Count := SelectedBottleLog.Count;
561 Caption := '
\83\8d\83O';
562 StatusBar.Panels[0].Text := '';
563 StatusBar.Panels[1].Text := '';
567 EnabledFlag := SelectedBottleLog <> nil;
568 tbtnClear.Enabled := EnabledFlag;
569 tbtnSaveLog.Enabled := EnabledFlag;
570 tbtnFindBottle.Enabled := EnabledFlag;
575 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
580 ProcessedUrl: String;
581 ProcessedLabel: String;
584 for i := mnJumpURL.Count-1 downto 0 do begin
585 mnJumpURL.Items[i].Free;
587 mnJumpURL.Enabled := false;
588 if lvwLog.ItemIndex = -1 then
590 Log := SelectedBottleLog.Bottles[lvwLog.ItemIndex];
593 Urls := TStringList.Create;
594 Labels := TStringList.Create;
596 ExtractURLs(Log.Script, Urls, Labels);
597 for i := 0 to Urls.Count-1 do begin
598 Child := TMenuItem.Create(Self);
600 ProcessedUrl := StringReplace(Urls[i], '&', '&&', [rfReplaceAll]);
601 ProcessedLabel := StringReplace(Labels[i], '&', '&&', [rfReplaceAll]);
602 if Length(ProcessedLabel) > 0 then begin
603 Caption := Format('[%s] %s (&%d)', [ProcessedLabel, ProcessedUrl, i+1]);
605 Caption := Format('%s (&%d)', [ProcessedUrl, i+1]);
608 OnClick := mnURLClick;
609 AutoHotkeys := maManual;
610 mnJumpURL.Add(Child);
613 mnJumpURL.Enabled := Urls.Count > 0;
620 procedure TfrmLog.mnURLClick(Sender: TObject);
621 var LogItem: TLogItem;
626 if (lvwLog.ItemIndex < 0) or (SelectedBottleLog = nil) then Exit;
627 LogItem := SelectedBottleLog[lvwLog.ItemIndex] as TLogItem;
628 Urls := TStringList.Create;
630 ExtractURLs(LogItem.Script, Urls, nil);
631 URL := Urls[(Sender as TMenuItem).Tag];
638 function TfrmLog.ExtractURLs(Script: String; Urls: TStrings; Labels: TStrings): Boolean;
639 var i, u, j, count: integer;
643 SsParser.InputString := Script;
644 SsParser.LeaveEscape := true;
645 for i := 0 to SsParser.Count-1 do begin
646 if (SsParser.Match(SsParser[i], '\URL%b') > 0)
647 and (SsParser.MarkUpType[i] = mtTag) then
649 for u := 7 downto 1 do begin
650 if (SsParser.Match(SsParser[i],
651 '\URL%b'+StringReplace(StringOfChar('-', u*2),
652 '-', '%b', [rfReplaceAll]))) > 0 then begin
653 for j := 1 to u do begin
654 s := SsParser.GetParam(SsParser[i], j*2);
655 //https
\82È
\82Ç
\82ª
\92Ç
\89Á
\82³
\82ê
\82é
\8e\9e\91Î
\8dô
\81c
\81c://
\82ð
\8c\9f\8dõ
\82·
\82ê
\82Î
\82½
\82Ô
\82ñ
\91å
\8fä
\95v
656 if Pos('://', s) > 0 then begin
657 if Urls <> nil then Urls.Add(s);
660 if Labels <> nil then begin
661 s := SsParser.GetParam(SsParser[i], j*2+1);
668 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin
669 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
670 s := SsParser.GetParam(SsParser[i], 1);
671 //https
\82È
\82Ç
\82ª
\92Ç
\89Á
\82³
\82ê
\82é
\8e\9e\91Î
\8dô
\81c
\81c://
\82ð
\8c\9f\8dõ
\82·
\82ê
\82Î
\82½
\82Ô
\82ñ
\91å
\8fä
\95v
672 if Pos('://', s) > 0 then begin
673 if Urls <> nil then Urls.Add(s);
680 //
\83\89\83x
\83\8b\82Ì
\90\94\82ðURL
\82Ì
\90\94\82É
\82 \82í
\82¹
\82é -
\82¢
\82¿
\82¢
\82¿
\94»
\92è
\82µ
\82È
\82
\82Ä
\82à
\82¢
\82¢
\82æ
\82¤
\82É
681 if Urls <> nil then begin
682 if Labels <> nil then begin
683 while Urls.Count > Labels.Count do Labels.Add('');
689 procedure TfrmLog.SelAndFocusMessage(const MID: String);
693 for i := 0 to SelectedBottleLog.Count-1 do begin
694 Log := SelectedBottleLog.Items[i] as TLogItem;
695 if Log.MID = MID then begin
696 lvwLog.ItemIndex := i;
702 procedure TfrmLog.UpdateScript(const Script: String);
704 if Script <> FLastScript then begin
705 if Pref.LogWindowPreviewStyle = psConversation then begin
706 UpdateScriptConversationColor(Script);
708 UpdateScriptScript(Script);
710 SendMessage(edtScript.Handle, EM_LINESCROLL, Low(integer), Low(integer)); //
\83X
\83N
\83\8d\81[
\83\8b\96ß
\82µ
711 FLastScript := Script;
715 procedure TfrmLog.PopupMenuPreviewStylePopup(Sender: TObject);
718 with PopupMenuPreviewStyle do
719 for i := 0 to Items.Count-1 do
720 Items[i].Checked := Items[i].Tag = Ord(Pref.LogWindowPreviewStyle)
723 procedure TfrmLog.mnPreviewStyleClick(Sender: TObject);
726 with PopupMenuPreviewStyle do
727 for i := 0 to Items.Count-1 do
728 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
729 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag);
735 procedure TfrmLog.UpdateScriptScript(const Script: String);
737 UnyuTalking, InSynchronized: boolean;
740 edtScript.Color := Pref.BgColor;
741 SsParser.LeaveEscape := true;
742 SsParser.InputString := Script;
743 edtScript.Text := '';
744 edtScript.SelAttributes.Color := clWindowText;
745 UnyuTalking := false;
746 InSynchronized := false;
747 for i := 0 to SsParser.Count-1 do begin
748 case SsParser.MarkUpType[i] of
750 if InSynchronized then
751 edtScript.SelAttributes.Color := Pref.TalkColorS
752 else if UnyuTalking then
753 edtScript.SelAttributes.Color := Pref.TalkColorU
755 edtScript.SelAttributes.Color := Pref.TalkColorH;
758 edtScript.SelAttributes.Color := Pref.MarkUpColor;
759 if SsParser[i] = '\h' then
761 else if SsParser[i] = '\u' then
763 else if SsParser[i] = '\_s' then
764 InSynchronized := not InSynchronized;
766 mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor;
767 mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor;
769 edtScript.SelText := SsParser[i];
770 if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then
771 edtScript.SelText := #13#10;
775 procedure TfrmLog.tbtnPreviewStyleClick(Sender: TObject);
778 sel := Ord(Pref.LogWindowPreviewStyle);
780 if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0;
781 Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel);
787 function TfrmLog.SelectedBottleLog: TBottleLogList;
789 if tabBottleLog.TabIndex >= 0 then
790 Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList
795 procedure TfrmLog.tabBottleLogChange(Sender: TObject);
797 // StatusBar
\82Ì
\8c\8f\90\94\95\
\8e¦
\82âListView.Items.Count
\82ð
\8dX
\90V
\82·
\82é
799 //
\83A
\83C
\83e
\83\80\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95\9c\8bA
\82·
\82é
800 with SelectedBottleLog do
801 if (SelectedIndex >= 0) and (Count > SelectedIndex) then
803 lvwLog.ItemIndex := SelectedIndex;
807 procedure TfrmLog.LogLoaded(Sender: TObject);
809 if SelectedBottleLog = Sender then begin
814 procedure TfrmLog.UpdateTab;
817 cur := tabBottleLog.tabIndex;
818 tabBottleLog.Tabs.Clear;
819 for i := 0 to FBottleLogList.Count - 1 do begin
820 tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title);
822 if FBottleLogList.Count > 0 then begin
823 if cur < FBottleLogList.Count then
824 tabBottleLog.TabIndex := cur
826 tabBottleLog.TabIndex := FBottleLogList.Count-1;
830 procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String);
833 ShowMessage(Message);
834 if Sender = SelectedBottleLog then UpdateWindow;
837 procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer);
842 for i := 0 to FBottleLogList.Count - 1 do begin
843 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
844 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Agrees := Agree;
848 if flag then lvwLog.Invalidate;
851 procedure TfrmLog.VoteLog(const MID: String; const Vote: integer);
856 for i := 0 to FBottleLogList.Count - 1 do begin
857 if (FBottleLogList[i] as TBottleLogList).Bottle(MID) <> nil then begin
858 (FBottleLogList[i] as TBottleLogList).Bottle(MID).Votes := Vote;
862 if flag then lvwLog.Invalidate;
865 procedure TfrmLog.tabBottleLogChanging(Sender: TObject;
866 var AllowChange: Boolean);
868 //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83\8d\83O
\82Ì
\91I
\91ð
\8fó
\91Ô
\82ð
\95Û
\91¶
869 if SelectedBottleLog = nil then
871 SelectedBottleLog.SelectedIndex := lvwLog.ItemIndex
874 procedure TfrmLog.tabBottleLogContextPopup(Sender: TObject;
875 MousePos: TPoint; var Handled: Boolean);
877 with tabBottleLog do begin
878 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
879 if Tag < 0 then Handled := true;
883 procedure TfrmLog.mnCloseTabClick(Sender: TObject);
885 DoCloseTab(tabBottleLog.Tag);
888 procedure TfrmLog.tbtnFindBottleClick(Sender: TObject);
889 var ResultLog: TBottleLogList;
892 CList, GList: THashedStringList;
894 Application.CreateForm(TfrmSearchLog, frmSearchLog);
895 Cond := TSearchCond.Create(nil);
900 //
\8c»
\8dÝ
\83\8d\83O
\82É
\82 \82é
\83S
\81[
\83X
\83g
\82Æ
\83`
\83\83\83\93\83l
\83\8b\82Ì
\83\8a\83X
\83g
\82ð
\8eæ
\93¾
901 //
\8fd
\82½
\82¢
\82©
\82à??
902 CList := THashedStringList.Create;
903 GList := THashedStringList.Create;
905 for i := 0 to BottleLogList.Count-1 do
907 with BottleLogList[i] as TBottleLogList do
909 ExtractUniqueChannels(CList);
910 ExtractUniqueGhosts(GList);
915 ChannelList := CList;
924 Cond.Assign(Condition);
927 frmSearchLog.Release;
929 //
\8c\9f\8dõ
\8eÀ
\8ds
930 ResultLog := DoSearchLog(Cond);
931 //
\90V
\83^
\83u
\82ð
\8dì
\90¬
\82µ
\82Ä
\89æ
\96Ê
\8dX
\90V
932 BottleLogList.Add(ResultLog);
934 tabBottleLog.TabIndex := BottleLogList.Count-1;
941 procedure TfrmLog.tbtnOpenLogClick(Sender: TObject);
942 var BottleLog: TBottleLogList;
946 if OpenDialog.Execute then begin
947 for i := 0 to OpenDialog.Files.Count-1 do begin
948 BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i]));
952 OnLoaded := LogLoaded;
953 OnLoadFailure := LogLoadFailure;
954 OnLoadWork := LogLoadWork;
955 BottleLog.LoadFromXMLFile(OpenDialog.Files[i]);
957 Index := BottleLogList.Add(BottleLog); //
\8dÅ
\8cã
\82É
\8aJ
\82¢
\82½
\83\8d\83O
\82Ì
\88Ê
\92u
\82ð
\8bL
\89¯
963 if Index >= 0 then tabBottleLog.TabIndex := Index;
968 function TfrmLog.GetDefaultFileName(const Name, Ext: String): String;
970 Result := StringReplace(Name, '/', '', [rfReplaceAll]);
971 Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
972 Result := SafeFileName(Result);
973 Result := ChangeFileExt(Result, Ext);
976 function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList;
979 for i := 0 to FBottleLogList.Count-1 do begin
980 if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin
981 Result := (FBottleLogList[i] as TBottleLogList);
985 //
\8c©
\82Â
\82©
\82ç
\82È
\82¢
\8fê
\8d\87
986 Result := TBottleLogList.Create(LogName); //
\90V
\82µ
\82
\8dì
\82é
987 FBottleLogList.Add(Result);
989 if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0;
992 procedure TfrmLog.AllBottleOpened;
996 for i := 0 to FBottleLogList.Count-1 do begin
997 Log := FBottleLogList[i] as TBottleLogList;
998 for j := 0 to Log.Count-1 do begin
999 Log.Bottles[j].State := lsOpened;
1004 procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject;
1005 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1008 if Button = mbMiddle then
1010 //
\92\86\83{
\83^
\83\93\83N
\83\8a\83b
\83N
\82Å
\83^
\83u
\8dí
\8f\9c
1011 DoCloseTab(tabBottleLog.IndexOfTabAt(X, Y));
1014 with tabBottleLog do begin
1015 Index := IndexOfTabAt(X, Y);
1016 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1017 if Button = mbLeft then begin
1018 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1020 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1026 procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X,
1027 Y: Integer; State: TDragState; var Accept: Boolean);
1028 var TargetRect: TRect;
1029 OldDest, Index: integer;
1032 //
\83^
\83u
\82Ì
\83h
\83\89\83b
\83O(
\83^
\83u
\82Ì
\8f\87\94Ô
\93ü
\82ê
\91Ö
\82¦)
\82Ü
\82½
\82Í
\81A
1033 //
\83\8d\83O
\83A
\83C
\83e
\83\80\82Ì
\83h
\83\89\83b
\83O(
\83\8d\83O
\82ð
\95Ê
\82Ì
\83^
\83u
\82É
\88Ú
\93®)
\82Ì
1034 //
\97¼
\95û
\82Ì
\83h
\83\89\83b
\83O
\82ð
\8eó
\82¯
\95t
\82¯
\82é
1036 if Source = tabBottleLog then
1038 //
\83^
\83u
\82Ì
\8f\87\94Ô
\93ü
\82ê
\91Ö
\82¦
\82Ì
\8fê
\8d\87
1040 with tabBottleLog do begin
1041 OldDest := FDragTabDest;
1042 FDragTabDest := IndexOfTabAt(X, Y);
1043 if FDragTabDest = -1 then begin
1044 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1047 with Canvas do begin
1051 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1052 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1053 TargetRect := TabRect(OldDest);
1054 with Canvas do begin
1055 Brush.Style := bsClear;
1056 Rectangle(TargetRect.Left, TargetRect.Top,
1057 TargetRect.Right, TargetRect.Bottom);
1060 if (OldDest <> FDragTabDest) then begin
1061 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1062 TargetRect := TabRect(FDragTabDest);
1063 with Canvas do begin
1064 Brush.Style := bsClear;
1065 Rectangle(TargetRect.Left, TargetRect.Top,
1066 TargetRect.Right, TargetRect.Bottom);
1070 end else if Source is TBottleLogDragObject then
1072 //
\83\8d\83O
\8d\80\96Ú
\82Ì
\83h
\83\89\83b
\83O(
\83\8d\83O
\82ð
\95Ê
\82Ì
\83^
\83u
\82É
\88Ú
\93®
\82·
\82é)
\82Ì
\8fê
\8d\87
1073 Index := tabBottleLog.IndexOfTabAt(X, Y);
1074 if tabBottleLog.TabIndex <> Index then
1076 FLVDragDest := -1; //
\98g
\90ü
\82Í
\82Ü
\82¾
\95\
\8e¦
\82³
\82ê
\82È
\82¢
\82Í
\82¸
1077 //
\83^
\83u
\82ð
\90Ø
\91Ö
\82¦
\82é
1078 tabBottleLogChanging(Self, dummy);
1079 tabBottleLog.TabIndex := Index;
1085 procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X,
1087 var DestIndex: integer;
1089 with tabBottleLog do begin
1090 DestIndex := IndexOfTabAt(X, Y);
1091 Tabs.Move(FDragTabIndex, DestIndex);
1092 FBottleLogList.Move(FDragTabIndex, DestIndex);
1096 procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X,
1099 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1100 tabBottleLog.Tabs.BeginUpdate;
1101 tabBottleLog.Tabs.EndUpdate;
1104 procedure TfrmLog.LogLoadWork(Sender: TObject);
1106 if Sender = SelectedBottleLog then
1109 lvwLog.Count := SelectedBottleLog.Count;
1113 procedure TfrmLog.DrawSingleLineScript(LogItem: TLogItem;
1114 Rect: TRect; State: TOwnerDrawState);
1117 UnyuTalking, Synchronized, Spaced: boolean;
1118 Mark: TSsMarkUpType;
1121 procedure ScopeChange;
1123 if (not Spaced) and (Pref.LogListPreviewStyle = psTagStripped) then
1130 Script := LogItem.Script;
1133 if LogItem.HasURL = huYes then
1135 Ico := TIcon.Create;
1137 frmSender.imgIcon.GetIcon(IconURL, Ico);
1138 lvwLog.Canvas.Draw(Rect.Left + x, Rect.Top, Ico);
1145 if Pref.LogListPreviewStyle = psNoColor then
1150 DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, Rect,
1151 DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX, nil);
1155 SsParser.LeaveEscape := Pref.LogListPreviewStyle = psNormal;
1156 SsParser.InputString := Script;
1158 UnyuTalking := false;
1159 Synchronized := false;
1160 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¢
1161 //
\82½
\82ß
\82Ì
\83t
\83\89\83O
1162 for i := 0 to SsParser.Count - 1 do begin
1163 if SsParser[i] = '\h' then
1165 UnyuTalking := false;
1167 end else if SsParser[i] = '\u' then
1169 UnyuTalking := true;
1171 end else if SsParser[i] = '\_s' then
1173 Synchronized := not Synchronized;
1175 end else if (Pos('\n', SsParser[i]) = 1) or (SsParser[i] = '\c') then
1179 Mark := SsParser.MarkUpType[i];
1183 lvwLog.Canvas.Font.Color := Pref.MetaWordColor;
1187 if Pref.LogListPreviewStyle = psNormal then
1188 lvwLog.Canvas.Font.Color := Pref.MarkUpColor
1194 lvwLog.Canvas.Font.Color := Pref.MarkErrorColor;
1197 if Synchronized then
1198 lvwLog.Canvas.Font.Color := Pref.TalkColorS
1199 else if UnyuTalking then
1200 lvwLog.Canvas.Font.Color := Pref.TalkColorU
1202 lvwLog.Canvas.Font.Color := Pref.TalkColorH;
1205 if odSelected in State then
1207 if odFocused in State then
1208 lvwLog.Canvas.Font.Color := clHighlightText
1210 lvwLog.Canvas.Font.Color := clWindowText;
1212 w := lvwLog.Canvas.TextWidth(SsParser[i]);
1213 lvwLog.Canvas.TextRect(Rect, Rect.Left + x, Rect.Top + 2, SsParser[i]);
1215 if Rect.Right - Rect.Left < x then
1220 procedure TfrmLog.mnListPreviewStyleClick(Sender: TObject);
1223 with PopupMenuListPreviewStyle do
1224 for i := 0 to Items.Count-1 do
1225 Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag;
1226 Pref.LogListPreviewStyle := TLogListPreviewStyle((Sender as TMenuItem).Tag);
1230 procedure TfrmLog.tbtnListPreviewStyleClick(Sender: TObject);
1233 sel := Ord(Pref.LogListPreviewStyle);
1235 if sel > Ord(High(TLogListPreviewStyle)) then sel := 0;
1236 Pref.LogListPreviewStyle := TLogListPreviewStyle(sel);
1240 procedure TfrmLog.PopupMenuListPreviewStylePopup(Sender: TObject);
1243 with PopupMenuListPreviewStyle do
1244 for i := 0 to Items.Count-1 do
1245 Items[i].Checked := Items[i].Tag = Ord(Pref.LogListPreviewStyle)
1248 procedure TfrmLog.PreviewStyleChange;
1250 if Pref.LogWindowPreviewStyle = psImageConversation then
1252 if Spps.Count = 0 then
1253 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');
1254 edtScript.Visible := false;
1255 TalkShowFrame.Visible := true;
1258 edtScript.Visible := true;
1259 TalkShowFrame.Visible := false;
1263 procedure TfrmLog.lvwLogDragOver(Sender, Source: TObject; X, Y: Integer;
1264 State: TDragState; var Accept: Boolean);
1266 OldDest, Target: Integer;
1267 Rec: TRect; //
\83_
\83~
\81[
\81B
1271 if not Pref.LogItemDragDrop then
1273 //
\82Æ
\82è
\82 \82¦
\82¸
\8eó
\82¯
\95t
\82¯
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
\82Ì
\82ÍTBottleLogDragObject
\82¾
\82¯
1274 if not (Source is TBottleLogDragObject) then
1276 //
\82µ
\82©
\82à
\8d\80\96Ú
\82ª
\82 \82é
\8fê
\8d\87\82Ì
\82Ý
1277 if (Source as TBottleLogDragObject).LogItem = nil then
1280 Target := lvwLog.ItemAtPos(Point(X, Y), true);
1282 //
\82±
\82ê
\88È
\91O
\82É
\95`
\89æ
\82³
\82ê
\82Ä
\82¢
\82½
\98g
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
1283 OldDest := FLVDragDest;
1285 //
\83h
\83\8d\83b
\83v
\88Ê
\92u
\82É Item
\82ª
\82 \82ê
\82Î
\83h
\83\8d\83b
\83v
\82ð
\8b\96\89Â
\82·
\82é
1286 if Target <> -1 then
1289 FLVDragDest := Target;
1296 //
\88È
\91O
\82Ì
\98g
\90ü
\82ð
\8dí
\8f\9c
1297 if (OldDest > -1) and (FLVDragDest <> OldDest) then
1299 Rec := lvwLog.ItemRect(OldDest);
1300 DrawListViewDragBorder(Rec);
1302 //
\83h
\83\89\83b
\83O
\90æ
\82Ì
\98g
\90ü
\82ð
\95`
\89æ
1303 if (Target <> -1) and (FLVDragDest <> OldDest) then
1305 Rec := lvwLog.ItemRect(Target);
1306 DrawListViewDragBorder(Rec);
1309 //
\83X
\83N
\83\8d\81[
\83\8b\8aÖ
\8cW
1310 if lvwLog.Count > 0 then
1314 FLVScrollDir := lvScrollDown;
1315 if not timScrollTimer.Enabled then
1316 timScrollTimer.Enabled := true;
1317 end else if (lvwLog.Height - Y) < 10 then
1319 FLVScrollDir := lvScrollUp;
1320 if not timScrollTimer.Enabled then
1321 timScrollTimer.Enabled := true;
1324 timScrollTimer.Enabled := false;
1326 timScrollTimer.Enabled := false;
1329 procedure TfrmLog.lvwLogDragDrop(Sender, Source: TObject; X, Y: Integer);
1331 TargetItem: integer;
1332 Src: TBottleLogDragObject;
1335 timScrollTimer.Enabled := false;
1337 if not Pref.LogItemDragDrop then
1339 if not (Source is TBottleLogDragObject) then
1341 Src := Source as TBottleLogDragObject;
1342 if Src.LogItem = nil then
1345 TargetItem := lvwLog.ItemAtPos(Point(X, Y), true);
1347 //
\83h
\83\8d\83b
\83v
\88Ê
\92u
\82É Item
\82ð
\88Ú
\93®
\82·
\82é
1348 if (GetAsyncKeyState(VK_CONTROL) and $8000) > 0 then
1349 begin //
\83R
\83s
\81[
\88Ú
\93®
\82Ì
\8fê
\8d\87
1350 SrcLog := TLogItem.Create(Src.LogItem);
1351 end else //
\88Ú
\93®
\82¾
\82¯
\82·
\82é
\8fê
\8d\87
1353 SrcLog := Src.BottleLogList.Extract(Src.LogItem);
1355 if TargetItem >= 0 then
1357 //
\82·
\82Å
\82É
\91¶
\8dÝ
\82·
\82é
\83A
\83C
\83e
\83\80\82Ì
\8fã
\82É
\83h
\83\8d\83b
\83v
\82µ
\82½
\8fê
\8d\87
1358 SelectedBottleLog.Insert(TargetItem, SrcLog);
1361 // ListView
\82Ì
\97]
\94\92\82É
\83h
\83\8d\83b
\83v
\82µ
\82½
\8fê
\8d\87(Insert
\82Å
\82«
\82È
\82¢)
1362 TargetItem := SelectedBottleLog.Add(SrcLog);
1365 lvwLog.ItemIndex := TargetItem;
1368 procedure TfrmLog.timScrollTimerTimer(Sender: TObject);
1370 ScrollHeight: Integer;
1372 //
\83X
\83N
\83\8d\81[
\83\8b\97Ê
\82ð
\8b\81\82ß
\82é
1373 ScrollHeight := lvwLog.ItemHeight;
1375 {TODO:
\83X
\83N
\83\8d\81[
\83\8b\95\9c\8a\88}
1376 case FLVScrollDir of
1378 PostMessage(lvwLog.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
1380 PostMessage(lvwLog.Handle, WM_VSCROLL, SB_LINEUP, 0);
1382 lvwLog.Invalidate; //
\8dÅ
\90V
\82Ì
\8fó
\91Ô
\82É
\8dÄ
\95`
\89æ
\82·
\82é
1386 procedure TfrmLog.mnChangeTabNameClick(Sender: TObject);
1389 Name := (FBottleLogList[tabBottleLog.Tag] as TBottleLogList).Title;
1390 InputQuery('
\96¼
\91O
\82Ì
\95Ï
\8dX', '
\90V
\82µ
\82¢
\83^
\83u
\82Ì
\96¼
\91O', Name);
1391 (FBottleLogList[tabBottleLog.Tag] as TBottleLogList).Title := Name;
1395 procedure TfrmLog.lvwLogStartDrag(Sender: TObject;
1396 var DragObject: TDragObject);
1397 var Drag: TBottleLogDragObject;
1399 // TDragObject
\82©
\82ç
\92¼
\90Ú
\8cp
\8f³
\82µ
\82½
\82¾
\82¯
\82Ì
\82à
\82Ì(
\83C
\83\81\81[
\83W
\82ð
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢)
\82ð
\8eg
\82¤
\82Æ
1400 //
\83h
\83\89\83b
\83O
\83C
\83\81\81[
\83W
\82Ì
\95`
\89æ
\82Í
\97}
\90§
\82Å
\82«
\82é
\81B
1401 Drag := TBottleLogDragObject.Create(lvwLog);
1402 Drag.BottleLogList := SelectedBottleLog;
1403 if lvwLog.ItemIndex <> -1 then
1404 Drag.LogItem := SelectedBottleLog.Bottles[lvwLog.ItemIndex]
1406 Drag.LogItem := nil;
1410 procedure TfrmLog.lvwLogEndDrag(Sender, Target: TObject; X, Y: Integer);
1412 //
\98g
\90ü
\8fÁ
\82µ
\97p
\82É
\8b
\90§
\93I
\82É
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
1413 timScrollTimer.Enabled := false;
1418 procedure TfrmLog.DrawListViewDragBorder(const Rect: TRect);
1422 InflateRect(Rec, -1, -1);
1423 with lvwLog.Canvas do
1427 Brush.Style := bsClear;
1428 Refresh; //
\95K
\97v
1433 procedure TfrmLog.DoSaveLogXML(Log: TBottleLogList);
1435 SaveDialog.FileName := GetDefaultFileName(Log.Title, '.xml');
1436 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
1437 SaveDialog.DefaultExt := 'xml';
1438 SaveDialog.FilterIndex := 3;
1439 if SaveDialog.Execute then
1440 Log.SaveToXmlFile(SaveDialog.FileName);
1443 procedure TfrmLog.DoCloseTab(const Index: integer);
1446 PrevSelection: TBottleLogList; //
\95Â
\82¶
\82½
\82Æ
\82«
\83^
\83u
\82ª
\82¸
\82ê
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\8f\88\97\9d\97p
1449 if Pref.ConfirmOnTabClose then
1451 Confirm := Format('
\83^
\83u"%s"
\82ð
\95Â
\82¶
\82Ü
\82·
\82©?', [(FBottleLogList[Index] as TBottleLogList).Title]);
1452 if MessageDlg(Confirm, mtConfirmation, mbOkCancel, 0) = mrCancel then
1455 PrevSelection := SelectedBottleLog;
1456 FBottleLogList.Delete(Index);
1458 //
\83^
\83u
\82¸
\82ê
\96h
\8e~
\8f\88\97\9d
1459 for i := 0 to FBottleLogList.Count-1 do
1460 if FBottleLogList[i] = PrevSelection then
1461 tabBottleLog.TabIndex := i;
1465 procedure TfrmLog.HTMLOutputWork(Sender: TObject; const Count: integer;
1466 var Canceled: boolean);
1468 frmHTMLOutputProgress.ProgressBar.Position := Count;
1469 Application.ProcessMessages;
1470 if frmHTMLOutputProgress.Canceled then
1474 function TfrmLog.DoSearchLog(Condition: TSearchCond): TBottleLogList;
1475 var i, UntilIndex: integer;
1477 Result := TBottleLogList.Create('
\8c\9f\8dõ
\8c\8b\89Ê');
1478 if Condition.SearchLogRange in [srSelectedLogList, srAboveSelectedLog] then
1480 if SelectedBottleLog = nil then
1482 ShowMessage('
\8c\9f\8dõ
\91Î
\8fÛ
\82ª
\82 \82è
\82Ü
\82¹
\82ñ');
1488 if Condition.SearchLogRange = srSelectedLogList then
1491 UntilIndex := lvwLog.ItemIndex;
1492 SearchLogIndivisual(Condition, SelectedBottleLog, Result, UntilIndex);
1494 end else if Condition.SearchLogRange = srAllLogLists then
1496 for i := 0 to BottleLogList.Count-1 do
1498 SearchLogIndivisual(Condition, BottleLogList[i] as TBottleLogList,
1503 if Result.Count = 0 then
1504 Result.AddSystemLog('
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B');
1507 procedure TfrmLog.SearchLogIndivisual(Condition: TSearchCond; LogList,
1508 Result: TBottleLogList; UntilIndex: integer = -1);
1511 Bottle, New: TLogItem;
1514 // 1
\8cÂ
\82Ì
\83\8d\83O
\83^
\83u
\82É
\91Î
\82µ
\82Ä
\8c\9f\8dõ
\82ð
\82©
\82¯
\82é
\81BUntilIndex
\82Å
\94Í
\88Í
\8ew
\92è(
\8fÈ
\97ª
\8e\9e\82»
\82Ì
\83^
\83u
\91S
\91Ì)
1515 if UntilIndex >= 0 then
1518 Max := LogList.Count-1;
1519 for i := 0 to Max do
1521 //
\8fð
\8c\8f\94»
\92è
1522 Bottle := LogList.Bottles[i];
1523 if Bottle.LogType <> ltBottle then
1526 //
\83X
\83N
\83\8a\83v
\83g
\83p
\83^
\81[
\83\93\82Å
\89ð
\90Í
1527 if Condition.ScriptPattern <> '' then
1529 if Condition.ScriptRegExp then
1532 if not RegExp.Match(Condition.ScriptPattern, Bottle.Script) then
1536 Ok := false; //
\96
\82È
\90³
\8bK
\95\
\8c»
\82ð
\8fR
\82é
1540 if not AnsiContainsText(Bottle.Script, Condition.ScriptPattern) then
1544 //
\83`
\83\83\83\93\83l
\83\8b\96¼
\81A
\83S
\81[
\83X
\83g
\96¼
\81A
\93\8a\95[
\93¯
\88Ó
1545 if Condition.Channel <> '' then
1546 if not AnsiContainsText(Bottle.Channel, Condition.Channel) then
1548 if Condition.Ghost <> '' then
1549 if not AnsiContainsText(Bottle.Ghost, Condition.Ghost) then
1551 if Condition.MinVote > Bottle.Votes then
1553 if Condition.MinAgree > Bottle.Agrees then
1555 //
\8fð
\8c\8f\82É
\88ê
\92v
\82µ
\82½
\82à
\82Ì
\82ð
\8c\8b\89Ê
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1558 New := TLogItem.Create(Bottle); //
\83R
\83s
\81[
\83R
\83\93\83X
\83g
\83\89\83N
\83^
1559 New.State := lsOpened;
1565 procedure TfrmLog.CheckBottleURL(Bottle: TLogItem);
1567 if Bottle.HasURL = huUndefined then
1570 //nil,nil
\82ð
\88ø
\82«
\93n
\82µ
\82Ä
\82àTRUE/FALSE
\82ÅURL
\82ª
\82 \82é
\82©
\82Ç
\82¤
\82©
\82ª
\82«
\82¿
\82ñ
\82Æ
\95Ô
\82é
1571 if ExtractURLs(Bottle.Script, nil, nil) then
1572 Bottle.HasURL := huYes
1574 Bottle.HasURL := huNo;
1580 procedure TfrmLog.DrawListSection(const SectionIndex, Top: Integer;
1581 const Text: string; const LeftMargin: Integer = 0);
1583 Sec: THeaderSection;
1587 MinimumTextWidth = 16; //
\82±
\82ê
\82æ
\82è
\8b·
\82¢
\82È
\82ç
\82»
\82à
\82»
\82à
\95`
\89æ
\82µ
\82È
\82¢
1589 Sec := Header.Sections[SectionIndex];
1591 Rec.Left := Sec.Left + 2 + LeftMargin;
1592 Rec.Right := Sec.Right - 2;
1593 if Rec.Right - Rec.Left < MinimumTextWidth then
1596 Rec.Bottom := Top + lvwLog.ItemHeight;
1598 Ex := DT_NOPREFIX or DT_SINGLELINE or DT_END_ELLIPSIS;
1599 if Sec.Alignment = taRightJustify then
1600 Ex := (Ex or DT_RIGHT) and not (DT_END_ELLIPSIS);
1601 DrawTextEx(lvwLog.Canvas.Handle, PChar(Text), -1, Rec, Ex, nil);
1604 { TBottleLogDragObject }
1606 function TBottleLogDragObject.GetDragImages: TDragImageList;
1608 //
\92\86\93r
\94¼
\92[
\82È
\83h
\83\89\83b
\83O
\83C
\83\81\81[
\83W
\82ð
\95\
\8e¦
\82µ
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
1612 procedure TBottleLogDragObject.SetBottleLogList(
1613 const Value: TBottleLogList);
1615 FBottleLogList := Value;
1618 procedure TBottleLogDragObject.SetLogItem(const Value: TLogItem);
1623 procedure TfrmLog.mnTabSaveXMLLogClick(Sender: TObject);
1625 DoSaveLogXML(FBottleLogList[tabBottleLog.Tag] as TBottleLogList);
1628 procedure TfrmLog.mnSaveHTMLClick(Sender: TObject);
1630 LogList, SB: TBottleLogList;
1632 Options: THTMLOutputOptions;
1634 SB := SelectedBottleLog;
1637 if SB.Count = 0 then
1639 Application.CreateForm(TfrmHTMLOutputConfig, frmHTMLOutputConfig);
1640 with frmHTMLOutputConfig do
1642 // Show HTML save option dialog
1645 LogList := TBottleLogList.Create('');
1649 for i := SB.Count-1 downto 0 do
1650 if SB.Bottles[i].LogType = ltBottle then
1651 LogList.Add(TLogItem.Create(SB.Bottles[i]));
1653 if SB.Bottles[lvwLog.ItemIndex].LogType = ltBottle then
1654 LogList.Add(TLogItem.Create(SB.Bottles[lvwLog.ItemIndex]))
1656 ShowMessage('
\82±
\82Ì
\83\81\83b
\83Z
\81[
\83W
\82Í
\95Û
\91¶
\82Å
\82«
\82Ü
\82¹
\82ñ');
1658 for i := lvwLog.ItemIndex downto 0 do
1659 if SB.Bottles[i].LogType = ltBottle then
1660 LogList.Add(TLogItem.Create(SB.Bottles[i]));
1662 Options.ImageDir := ImageDir;
1663 Options.UseColor := UseColor;
1664 Options.ImageType := ImageType;
1665 Application.CreateForm(TfrmHTMLOutputProgress, frmHTMLOutputProgress);
1667 frmHTMLOutputProgress.Show;
1668 LogList.OnHTMLOutputWork := HTMLOutputWork;
1669 LogList.SaveToHTML(FileName, Options, SsParser);
1671 frmHTMLOutputProgress.Release;
1681 procedure TfrmLog.mnPopupCopyGhostClick(Sender: TObject);
1686 Log := SelectedBottleLog.Bottles[frmLog.lvwLog.ItemIndex];
1687 if Log = nil then Exit;
1688 Clip := ClipBoard();
1689 Clip.SetTextBuf(PChar(Log.Ghost));
1692 procedure TfrmLog.lvwLogDrawItem(Control: TWinControl; Index: Integer;
1693 Rect: TRect; State: TOwnerDrawState);
1699 Bottle := SelectedBottleLog.Bottles[Index];
1700 CheckBottleURL(Bottle);
1702 DestRect := lvwLog.ItemRect(Index);
1704 //
\94w
\8ci
\82Ì
\90F
\82Í
\91I
\91ð
\8fó
\91Ô
\81E
\91I
\91ð
\94ñ
\83A
\83N
\83e
\83B
\83u
\8fó
\91Ô
\81E
\92Ê
\8fí
\8fó
\91Ô
\82Ì3
\92Ê
\82è
1705 lvwLog.Canvas.Brush.Style := bsSolid;
1706 if odSelected in State then
1708 if odFocused in State then
1709 lvwLog.Canvas.Brush.Color := clHighlight
1711 lvwLog.Canvas.Brush.Color := clBtnFace;
1714 lvwLog.Canvas.Brush.Color := Pref.BgColor;
1716 lvwLog.Canvas.FillRect(DestRect);
1717 lvwLog.Canvas.Brush.Style := bsClear;
1719 //
\83h
\83\89\83b
\83O
\92\86\82È
\82ç
\98g
\90ü
\82ð
\95`
\89æ
\82·
\82é
1720 if FLVDragDest = Index then
1722 DrawListViewDragBorder(DestRect);
1725 if odSelected in State then
1727 if odFocused in State then
1728 lvwLog.Canvas.Font.Color := clHighlightText
1730 lvwLog.Canvas.Font.Color := clWindowText;
1732 lvwLog.Canvas.Font.Color := Pref.TextColor;
1734 //lvwLog.Canvas.TextOut(DestRect.Left, DestRect.Top, Bottle.Script);
1736 DrawListSection(SubTime, DestRect.Top,
1737 FormatDateTime('yy/mm/dd hh:nn:ss', Bottle.LogTime), 16);
1738 //
\93ú
\95t
\97\93\83{
\83g
\83\8b\83A
\83C
\83R
\83\93
1739 Ico := TIcon.Create;
1741 if Bottle.LogType = ltSystemLog then
1742 frmSender.imgIcon.GetIcon(IconSystemLog, Ico)
1744 case Bottle.State of
1746 frmSender.imgIcon.GetIcon(IconBottle, Ico);
1748 frmSender.imgIcon.GetIcon(IconOpened, Ico);
1750 frmSender.imgIcon.GetIcon(IconPlaying, Ico);
1752 lvwLog.Canvas.Draw(2, DestRect.Top, Ico);
1757 //
\83`
\83\83\83\93\83l
\83\8b
1758 DrawListSection(SubChannel, DestRect.Top, Bottle.Channel);
1760 DrawListSection(SubGhost, DestRect.Top, Bottle.Ghost);
1761 //
\93\8a\95[
\81E
\93¯
\88Ó
1762 if Bottle.Votes <> 0 then
1763 DrawListSection(SubVotes, DestRect.Top, IntToStr(Bottle.Votes))
1765 DrawListSection(SubVotes, DestRect.Top, '');
1767 if Bottle.Agrees <> 0 then
1768 DrawListSection(SubAgrees, DestRect.Top, IntToStr(Bottle.Agrees))
1770 DrawListSection(SubVotes, DestRect.Top, '');
1772 //
\83X
\83N
\83\8a\83v
\83g
1773 DestRect.Left := Header.Sections[SubScript].Left;
1774 DrawSingleLineScript(Bottle, DestRect, State);
1777 procedure TfrmLog.lvwLogData(Control: TWinControl; Index: Integer;
1783 procedure TfrmLog.HeaderSectionClick(HeaderControl: THeaderControl;
1784 Section: THeaderSection);
1785 var SortType: TBottleLogSortType;
1786 SelectedMID: String;
1788 if SelectedBottleLog = nil then
1790 if lvwLog.ItemIndex <> -1 then
1791 SelectedMID := SelectedBottleLog.Bottles[lvwLog.ItemIndex].MID
1795 case Section.Index of
1796 SubTime: SortType := stLogTime;
1797 SubChannel: SortType := stChannel;
1798 SubGhost: SortType := stGhost;
1799 SubVotes: SortType := stVote;
1800 SubAgrees: SortType := stAgree;
1801 SubScript: SortType := stScript;
1803 SortType := stLogTime;
1806 SelectedBottleLog.SortBottles(SortType);
1808 if Length(SelectedMID) > 0 then
1809 SelAndFocusMessage(SelectedMID);
1812 procedure TfrmLog.HeaderSectionTrack(HeaderControl: THeaderControl;
1813 Section: THeaderSection; Width: Integer; State: TSectionTrackState);
1818 procedure TfrmLog.lvwLogMouseDown(Sender: TObject; Button: TMouseButton;
1819 Shift: TShiftState; X, Y: Integer);
1823 if Button = mbRight then
1825 Index := lvwLog.ItemAtPos(Point(X, Y), true);
1828 lvwLog.ItemIndex := Index;
1834 procedure TfrmLog.lvwLogWindowProc(var Msg: TMessage);
1836 if Msg.Msg = WM_CHAR then begin
1837 if Msg.WParam = 13 then begin
1838 lvwLogDblClick(lvwLog);