X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=bottleclient%2FLogForm.pas;h=9bb369652e34ec90c4cde9697ff3cb5afeedbec9;hb=436bcfda3d6e14d3e8e060c02bb81c41103acf9f;hp=594388aceded80c7b564bfe6555ce69dd9738d37;hpb=64ae764245ca7d631961307c2cdaaf5ab117a2f4;p=winbottle%2Fwinbottle.git diff --git a/bottleclient/LogForm.pas b/bottleclient/LogForm.pas index 594388a..9bb3696 100755 --- a/bottleclient/LogForm.pas +++ b/bottleclient/LogForm.pas @@ -5,12 +5,17 @@ interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ToolWin, StdCtrls, ExtCtrls, SsParser, BottleDef, Menus, - Clipbrd, Logs, ShellAPI, Commctrl, DirectSstp, Contnrs, xmldom, XMLIntf, - msxmldom, XMLDoc; + Clipbrd, Logs, ShellAPI, Commctrl, DirectSstp, Contnrs, StrUtils, + TalkShowFrame, SppList, HtmlOutputConfig, HtmlOutputProgress, + SearchLog, IniFiles, BRegExp, RegexUtils; type + // ƒƒO‚Ì•Û‘¶•û–@ TSaveLogType = (stLog, stLogWithChannels, stText, stXML); + // ƒŠƒXƒgƒrƒ…[‚̃XƒNƒ[ƒ‹•ûŒü + TLVScrollDir = (lvScrollUp, lvScrollDown); + TfrmLog = class(TForm) ToolBar: TToolBar; tbtnClear: TToolButton; @@ -26,7 +31,6 @@ type SaveDialog: TSaveDialog; pnlPanel: TPanel; Splitter: TSplitter; - edtScript: TRichEdit; mnPopUpCopyScript: TMenuItem; PopupMenuSaveLog: TPopupMenu; mnSaveLog: TMenuItem; @@ -50,7 +54,30 @@ type PopupMenuTab: TPopupMenu; mnCloseTab: TMenuItem; tbtnFindBottle: TToolButton; - XMLDocument: TXMLDocument; + tbtnOpenLog: TToolButton; + OpenDialog: TOpenDialog; + tbtnInsertCue: TToolButton; + mnInsertCue: TMenuItem; + PopupMenuListPreviewStyle: TPopupMenu; + mnListPreviewStyleNormal: TMenuItem; + mnListPreviewStyleTagStripped: TMenuItem; + tbtnListPreviewStyle: TToolButton; + mnListPreviewStyleNoColor: TMenuItem; + SsParserForTalkShow: TSsParser; + mnPreviewStyleConversationImage: TMenuItem; + pnlPreviewArea: TPanel; + TalkShowFrame: TfrmTalkShow; + edtScript: TRichEdit; + tbtnSendEditor: TToolButton; + mnSendEditor: TMenuItem; + timScrollTimer: TTimer; + mnChangeTabName: TMenuItem; + N1: TMenuItem; + N2: TMenuItem; + mnDeleteLogItem: TMenuItem; + mnTabSaveXMLLog: TMenuItem; + mnSaveHTML: TMenuItem; + mnPopupCopyGhost: TMenuItem; procedure tbtnClearClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure lvwLogChange(Sender: TObject; Item: TListItem; @@ -69,9 +96,6 @@ type procedure PopupMenuListViewPopup(Sender: TObject); procedure lvwLogCustomDrawItem(Sender: TCustomListView; Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); - procedure lvwLogCustomDrawSubItem(Sender: TCustomListView; - Item: TListItem; SubItem: Integer; State: TCustomDrawState; - var DefaultDraw: Boolean); procedure PopupMenuPreviewStylePopup(Sender: TObject); procedure mnPreviewStyleClick(Sender: TObject); procedure tbtnPreviewStyleClick(Sender: TObject); @@ -82,77 +106,123 @@ type var Handled: Boolean); procedure mnCloseTabClick(Sender: TObject); procedure tbtnFindBottleClick(Sender: TObject); + procedure tbtnOpenLogClick(Sender: TObject); + procedure tabBottleLogMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure tabBottleLogDragOver(Sender, Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); + procedure tabBottleLogDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure tabBottleLogEndDrag(Sender, Target: TObject; X, Y: Integer); + procedure lvwLogDrawItem(Sender: TCustomListView; Item: TListItem; + Rect: TRect; State: TOwnerDrawState); + procedure mnListPreviewStyleClick(Sender: TObject); + procedure tbtnListPreviewStyleClick(Sender: TObject); + procedure PopupMenuListPreviewStylePopup(Sender: TObject); + procedure lvwLogDragOver(Sender, Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); + procedure lvwLogDragDrop(Sender, Source: TObject; X, Y: Integer); + procedure timScrollTimerTimer(Sender: TObject); + procedure mnChangeTabNameClick(Sender: TObject); + procedure lvwLogStartDrag(Sender: TObject; + var DragObject: TDragObject); + procedure lvwLogEndDrag(Sender, Target: TObject; X, Y: Integer); + procedure mnTabSaveXMLLogClick(Sender: TObject); + procedure mnSaveHTMLClick(Sender: TObject); + procedure mnPopupCopyGhostClick(Sender: TObject); private { Private éŒ¾ } FLastScript: String; //ƒXƒNƒŠƒvƒgÄ•`‰æ—}§—p FBottleLogList: TObjectList; + // + FDragTabIndex: integer; //ƒ^ƒuƒhƒ‰ƒbƒOƒhƒƒbƒvŠÖ˜A + FDragTabDest: integer; //ƒhƒƒbƒv‚·‚éˆÊ’u(‚·‚®‰E‚É‚­‚éƒ^ƒu‚̃Cƒ“ƒfƒbƒNƒX) + // + // ƒŠƒXƒgƒrƒ…[ƒhƒ‰ƒbƒOƒhƒƒbƒvŠÖ˜A + FLVScrollDir: TLVScrollDir; // ƒXƒNƒ[ƒ‹•ûŒü + FLVDragDest: integer; //ƒhƒƒbƒv‚·‚éˆÊ’u(‚·‚®‰º‚É‚­‚éƒAƒCƒeƒ€‚ÌIndex) + // procedure UpdateScript(const Script: String); procedure UpdateScriptConversationColor(const Script: String); - procedure UpdateScriptConversationNoColor(const Script: String); procedure UpdateScriptScript(const Script: String); - procedure DoSaveLog(SaveType: TSaveLogType; Ext: String; - Filter: integer); procedure mnURLClick(Sender: TObject); - procedure ExtractURLs(Script: String; Result: TStrings); - function XmlEntity(S: String): String; - function GetCurrentBottleLog: TBottleLogList; + function ExtractURLs(Script: String; Urls: TStrings; Labels: TStrings): Boolean; + function GetDefaultFileName(const Name: String; const Ext: String): String; + function BottleLogTitled(const LogName: String): TBottleLogList; + procedure DrawSingleLineScript(LogItem: TLogItem; Rect: TRect; + Item: TListItem); + procedure PreviewStyleChange; + procedure DrawListViewDragBorder(const Rect: TRect); + procedure DoSaveLogXML(Log: TBottleLogList); + procedure DoCloseTab(const Index: integer); + function DoSearchLog(Condition: TSearchCond): TBottleLogList; + procedure SearchLogIndivisual(Condition: TSearchCond; + LogList, Result: TBottleLogList; UntilIndex: integer = -1); protected procedure CreateParams(var Params: TCreateParams); override; public { Public éŒ¾ } function SelectedBottleLog: TBottleLogList; - property CurrentBottleLog: TBottleLogList read GetCurrentBottleLog; property BottleLogList: TObjectList read FBottleLogList; - procedure AddCurrentScriptLog(const Script, Channel, MID, Ghost: String); - procedure AddCurrentSystemLog(const MessageString: String); + procedure AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String); + procedure AddCurrentSystemLog(const LogName, MessageString: String); procedure VoteLog(const MID: String; const Vote: integer); procedure AgreeLog(const MID: String; const Agree: integer); - procedure SetBottleStatusToPlaying(const MID: String); - procedure SetBottleStatusToOpened(const MID: String); + procedure SetBottleState(const MID: String; State: TLogState); + procedure AllBottleOpened; procedure LogLoaded(Sender: TObject); procedure LogLoadFailure(Sender: TObject; const Message: String); + procedure LogLoadWork(Sender: TObject); + procedure HTMLOutputWork(Sender: TObject; const Count: integer; + var Canceled: boolean); procedure UpdateTab; procedure UpdateWindow; procedure SelAndFocusMessage(const MID: String); end; + TBottleLogDragObject = class(TDragControlObjectEx) + private + FBottleLogList: TBottleLogList; + FLogItem: TLogItem; + procedure SetBottleLogList(const Value: TBottleLogList); + procedure SetLogItem(const Value: TLogItem); + protected + function GetDragImages: TDragImageList; override; + public + property BottleLogList: TBottleLogList read FBottleLogList write SetBottleLogList; + property LogItem: TLogItem read FLogItem write SetLogItem; + end; var frmLog: TfrmLog; -function CurrentBottleLog: TBottleLogList; - const IconBottle = 17; IconOpened = 30; IconPlaying = 31; IconSystemLog = 26; + IconURL = 43; SubChannel = 0; - SubVotes = 1; - SubAgrees = 2; - SubScript = 3; + SubGhost = 1; + SubVotes = 2; + SubAgrees = 3; + SubScript = 4; implementation -uses MainForm, StrUtils; +uses MainForm; {$R *.DFM} -function CurrentBottleLog: TBottleLogList; -begin - Result := frmLog.CurrentBottleLog; -end; - { TfrmLog } -procedure TfrmLog.AddCurrentScriptLog(const Script, Channel, MID, Ghost: String); +procedure TfrmLog.AddCurrentScriptLog(const LogName, Script, Channel, MID, Ghost: String); var Sel: integer; begin - CurrentBottleLog.AddScriptLog(Script, Channel, MID, Ghost); - if SelectedBottleLog <> CurrentBottleLog then Exit; + BottleLogTitled(LogName).AddScriptLog(Script, Channel, MID, Ghost); + if SelectedBottleLog <> BottleLogTitled(LogName) then Exit; lvwLog.OnChange := nil; //ƒCƒxƒ“ƒg”­¶(‚¢‚ë‚¢‚ëÄ•`‰æ‚ª‹N‚«‚é)‚Ì—}§ if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1; - lvwLog.Items.Count := CurrentBottleLog.Count; + lvwLog.Items.Count := SelectedBottleLog.Count; UpdateWindow; if Sel >= 0 then begin lvwLog.Selected := lvwLog.Items[Sel + 1]; @@ -163,14 +233,14 @@ begin lvwLog.OnChange := lvwLogChange; end; -procedure TfrmLog.AddCurrentSystemLog(const MessageString: String); +procedure TfrmLog.AddCurrentSystemLog(const LogName, MessageString: String); var Sel: integer; begin - CurrentBottleLog.AddSystemLog(MessageString); - if SelectedBottleLog <> CurrentBottleLog then Exit; + BottleLogTitled(LogName).AddSystemLog(MessageString); + if SelectedBottleLog <> BottleLogTitled(LogName) then Exit; lvwLog.OnChange := nil; if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1; - lvwLog.Items.Count := CurrentBottleLog.Count; + lvwLog.Items.Count := SelectedBottleLog.Count; UpdateWindow; if Sel >= 0 then begin lvwLog.Selected := lvwLog.Items[Sel + 1]; @@ -185,24 +255,15 @@ end; procedure TfrmLog.tbtnClearClick(Sender: TObject); begin - if SelectedBottleLog = CurrentBottleLog then begin - CurrentBottleLog.Clear; - lvwLog.Items.Count := 0; - lvwLog.Invalidate; - lvwLogChange(Self, nil, ctState); - end else begin - FBottleLogList.Delete(tabBottleLog.TabIndex); - tabBottleLog.TabIndex := 0; - UpdateTab; - UpdateWindow; - lvwLogChange(Self, nil, ctState); - end; + if SelectedBottleLog = nil then Exit; + DoCloseTab(tabBottleLog.TabIndex); end; procedure TfrmLog.FormCreate(Sender: TObject); +var i: integer; begin + FLVDragDest := -1; // ƒŠƒXƒgƒrƒ…[‚̃hƒ‰ƒbƒO’†‚Å‚Í‚È‚¢ FBottleLogList := TObjectList.Create; - FBottleLogList.Add(TBottleLogList.Create('ƒJƒŒƒ“ƒg')); // CurrentBottleLog SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern); SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern); @@ -214,104 +275,159 @@ begin Self.Height := Bottom - Top + 1; end; lvwLog.DoubleBuffered := true; - edtScript.Height := Pref.LogWindowDividerPos; + pnlPreviewArea.Height := Pref.LogWindowDividerPos; + + i := 0; + while Token(Pref.LogWindowColumnWidth, ',', i) <> '' do begin + lvwLog.Columns[i].Width := StrToIntDef(Token(Pref.LogWindowColumnWidth, ',', i), 100); + Inc(i); + end; + + SsParserForTalkShow.TagPattern.Assign(SsParser.TagPattern); + SsParserForTalkShow.MetaPattern.Assign(SsParser.MetaPattern); + SsParserForTalkShow.EscapeInvalidMeta := false; + SsParserForTalkShow.LeaveEscape := false; + TalkShowFrame.SsParser := self.SsParserForTalkShow; + + TalkShowFrame.SetPreviewFont(edtScript.Font); + TalkShowFrame.PrevControl := lvwLog; + + PreviewStyleChange; UpdateWindow; // Reset window color and enabled status of some buttons end; procedure TfrmLog.FormDestroy(Sender: TObject); +var i: integer; + WidthStr: String; begin + WidthStr := ''; + for i := 0 to lvwLog.Columns.Count-1 do begin + if i > 0 then WidthStr := WidthStr + ','; + WidthStr := WidthStr + IntToStr(lvwLog.Column[i].Width); + end; + Pref.LogWindowColumnWidth := WidthStr; + with Pref.LogWindowPosition do begin Left := Self.Left; Top := Self.Top; Right := Self.Left + Self.Width - 1; Bottom := Self.Top + Self.Height - 1; end; - Pref.LogWindowDividerPos := edtScript.Height; + Pref.LogWindowDividerPos := pnlPreviewArea.Height; FreeAndNil(FBottleLogList); end; procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem; Change: TItemChange); -var Script: String; +var Script, Text: String; Log: TLogItem; + Selected, IsNormalBottle: boolean; begin - StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + 'Œ'; - if Change = ctState then begin - Script := ''; - if lvwLog.Selected <> nil then begin - Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index]; - if (Log.LogType = ltBottle) and not frmSender.Connecting then begin - Script := Log.Script; - frmSender.actVoteMessage.Enabled := true; - frmSender.actAgreeMessage.Enabled := true; - mnPopUpCopyScript.Enabled := true; - UpdateScript(Script); + Selected := false; + IsNormalBottle := false; + if SelectedBottleLog <> nil then begin + if Change = ctState then begin + Script := ''; + if lvwLog.Selected <> nil then begin + Selected := true; + StatusBar.Panels[0].Text := Format('%d/%dŒ', [lvwLog.Selected.Index+1, + SelectedBottleLog.Count]); + Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index]; + if (Log.LogType = ltBottle) and not frmSender.Connecting then begin + IsNormalBottle := true; + Script := Log.Script; + Text := Format('%dƒoƒCƒg/%d•b - ƒ_ƒuƒ‹ƒNƒŠƒbƒN‚ōж', + [Length(Log.Script), frmSender.SsPlayTime.PlayTime(Log.Script) div 1000]); + StatusBar.Panels[1].Text := Text; + if Pref.LogWindowPreviewStyle = psImageConversation then + TalkShowFrame.View(Log) + else + UpdateScript(Script); + end else begin + StatusBar.Panels[1].Text := ''; + UpdateScript(''); // ƒƒOƒvƒŒƒrƒ…[•”‚ðƒNƒŠƒA + end; end else begin - frmSender.actVoteMessage.Enabled := false; - frmSender.actAgreeMessage.Enabled := false; - mnPopUpCopyScript.Enabled := false; - UpdateScript(''); // ƒƒOƒvƒŒƒrƒ…[•”‚ðƒNƒŠƒA + StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + 'Œ'; + StatusBar.Panels[1].Text := ''; + UpdateScript(Script); // ƒƒOƒvƒŒƒrƒ…[•”ƒNƒŠƒA end; - end else begin - frmSender.actVoteMessage.Enabled := false; - frmSender.actAgreeMessage.Enabled := false; - mnPopUpCopyScript.Enabled := false; - UpdateScript(Script); // ƒƒOƒvƒŒƒrƒ…[•”ƒNƒŠƒA end; + tbtnSaveLog.Enabled := lvwLog.Items.Count > 0; + end else begin + StatusBar.Panels[0].Text := ''; + UpdateScript(''); // ƒƒOƒvƒŒƒrƒ…[•”ƒNƒŠƒA end; - tbtnSaveLog.Enabled := lvwLog.Items.Count > 0; + frmSender.actVoteMessage.Enabled := Selected and IsNormalBottle; + frmSender.actAgreeMessage.Enabled := Selected and IsNormalBottle; + frmSender.actSendToEditor.Enabled := Selected and IsNormalBottle; + frmSender.actInsertCue.Enabled := Selected; + frmSender.actDeleteLogItem.Enabled := Selected; + mnPopUpCopyScript.Enabled := Selected and IsNormalBottle; + mnPopupCopyGhost.Enabled := Selected and IsNormalBottle; end; procedure TfrmLog.lvwLogDblClick(Sender: TObject); -var Script: String; - Opt: TScriptTransOptions; - SOpt: TSstpSendOptions; - Ghost: String; - Log: TLogItem; +var Script, ErrorMes: String; + Log, CueItem: TLogItem; + Res: integer; begin - if lvwLog.Selected = nil then Exit; - //Log := TLogItem(lvwLog.Selected.Data); + if lvwLog.Selected = nil then + Exit; Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index]; if Log = nil then Exit; - if Log.LogType <> ltBottle then Exit; - Script := Log.Script; - Opt := [toConvertURL, toWaitScriptEnd]; - if Pref.NoTransUrl then Opt := Opt + [toNoChoice]; - if Pref.IgnoreFrequentYenS then Opt := Opt + [toIgnoreFrequentYenS]; - if Pref.FixMessySurface then Opt := Opt + [toFixMessySurface]; - frmSender.DoTrans(Script, Opt); - - Ghost := frmSender.GetChannelPrefs(Log.Channel).TargetGhost; - if Ghost = '' then //ƒ`ƒƒƒ“ƒlƒ‹Žw’èƒS[ƒXƒg - if frmSender.ChannelList.Channel[Log.Channel] <> nil then - Ghost := frmSender.ChannelList.Channel[Log.Channel].Ghost; - //–Ú•WƒS[ƒXƒgŒˆ’è - if Log.Ghost <> '' then Ghost := Log.Ghost; - if frmSender.GetChannelPrefs(Log.Channel).IgnoreIfGhost then - Ghost := frmSender.GetChannelPrefs(Log.Channel).TargetGhost; - //ƒ^[ƒQƒbƒgƒS[ƒXƒgŠm’è - Ghost := frmSender.SetHWndToFavoriteGhost(Ghost); - frmSender.DirectSstp.SstpSender := 'SSTP Bottle -yƒƒOÄ¶z'; - if Pref.NoTranslate then SOpt := [soNoTranslate] else SOpt := []; - frmSender.DirectSstp.SstpSEND(Script, SOpt, frmSender.GhostNameToSetName(Ghost)); + if Log.LogType <> ltBottle then + Exit; + Script := frmSender.ScriptTransForSSTP(Log.Script, ErrorMes); + if ErrorMes <> '' then + begin + Res := MessageDlg('–â‘è‚Ì‚ ‚éƒXƒNƒŠƒvƒg‚Å‚·BÄ¶‚Å‚«‚Ü‚¹‚ñB'#13#10+ + ErrorMes + #13#10 + + '‹­§“I‚ɍж‚µ‚Ü‚·‚©?'#13#10, + mtWarning, mbOkCancel, 0 + ); + if Res = mrCancel then + Exit; + end; + + CueItem := TLogItem.Create(Log); + try + CueItem.Script := Script; + frmSender.BottleSstp.Unshift(CueItem); + except + CueItem.Free; + end; end; procedure TfrmLog.UpdateScriptConversationColor(const Script: String); var i: integer; scr: String; - UnyuTalking, Talked: boolean; + UnyuTalking, Talked, InSynchronized: boolean; begin scr := Script; frmSender.DoTrans(scr, [toConvertURL]); SsParser.LeaveEscape := false; SsParser.InputString := scr; - SsParser.LeaveEscape := true; UnyuTalking := false; Talked := false; //'\h\u\h\u'‚̂悤‚ȃXƒNƒŠƒvƒg‚ŋ󂫍s‚ðì‚ç‚È‚¢‚½‚ß‚Ì‘[’u + InSynchronized := false; edtScript.Text := ''; edtScript.Color := Pref.BgColor; for i := 0 to SsParser.Count-1 do begin + if (SsParser[i] = '\_s') and not InSynchronized then begin + InSynchronized := true; + if Talked then begin + edtScript.SelText := #13#10; + Talked := false; + end; + end else if (SsParser[i] = '\_s') and InSynchronized then begin + InSynchronized := false; + if Talked then begin + edtScript.SelText := #13#10; + Talked := false; + end; + end; if (SsParser[i] = '\u') and not UnyuTalking then begin UnyuTalking := true; if Talked then begin @@ -327,7 +443,9 @@ begin end; end; if SsParser.MarkUpType[i] = mtStr then begin - if UnyuTalking then + if InSynchronized then + edtScript.SelAttributes.Color := Pref.TalkColorS + else if UnyuTalking then edtScript.SelAttributes.Color := Pref.TalkColorU else edtScript.SelAttributes.Color := Pref.TalkColorH; @@ -342,46 +460,6 @@ begin end; end; -procedure TfrmLog.UpdateScriptConversationNoColor(const Script: String); -var Scr: String; - i: integer; - UnyuTalking, Talked, LastUnyuTalked: boolean; -begin - Scr := Script; - frmSender.DoTrans(Scr, [toConvertURL]); - SsParser.LeaveEscape := false; - SsParser.InputString := Scr; - SsParser.LeaveEscape := true; - edtScript.Text := ''; - edtScript.Color := clWindow; - edtScript.DefAttributes.Color := clWindowText; - edtScript.SelAttributes.Color := clWindowText; - Talked := false; - UnyuTalking := false; - LastUnyuTalked := false; - for i := 0 to SsParser.Count-1 do begin - if (SsParser[i] = '\u') and not UnyuTalking then begin - UnyuTalking := true; - end; - if (SsParser[i] = '\h') and UnyuTalking then begin - UnyuTalking := false; - end; - if SsParser.MarkUpType[i] in [mtStr, mtMeta] then begin - if not Talked then begin - if UnyuTalking then Scr := '‚¤:' else Scr := '‚³:'; - end; - if Talked and (UnyuTalking <> LastUnyuTalked) then begin - Scr := Scr + #13#10; - if UnyuTalking then Scr := Scr + '‚¤:' else Scr := Scr + '‚³:'; - end; - Scr := Scr + SsParser[i]; - Talked := true; - LastUnyuTalked := UnyuTalking; - end; - end; - edtScript.Text := Scr; -end; - procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char); begin if Key = #13 then lvwLogDblClick(Sender); @@ -400,36 +478,34 @@ begin Selected := Selected; end; -procedure TfrmLog.mnSaveLogClick(Sender: TObject); -begin - SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); - SaveDialog.DefaultExt := 'log'; - SaveDialog.FilterIndex := 1; - if SaveDialog.Execute then - SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false); -end; - procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn); var SortType: TBottleLogSortType; SelectedMID: String; SortColumn: integer; begin + if SelectedBottleLog = nil then + Exit; if lvwLog.Selected <> nil then - SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID; + SelectedMID := SelectedBottleLog.Bottles[lvwLog.Selected.Index].MID + else + SelectedMID := ''; SortColumn := Column.Index; case SortColumn-1 of -1: SortType := stLogTime; subChannel: SortType := stChannel; + subGhost: SortType := stGhost; subVotes: SortType := stVote; subAgrees: SortType := stAgree; subScript: SortType := stScript; - else SortType := stLogTime; + else + SortType := stLogTime; end; SelectedBottleLog.SortBottles(SortType); lvwLog.Invalidate; - SelAndFocusMessage(SelectedMID); + if Length(SelectedMID) > 0 then + SelAndFocusMessage(SelectedMID); end; @@ -444,99 +520,36 @@ begin Clip.SetTextBuf(PChar(Log.Script)); end; -procedure TfrmLog.SetBottleStatusToOpened(const MID: String); -begin - if CurrentBottleLog.Bottle(MID) <> nil then begin - CurrentBottleLog.Bottle(MID).State := lsOpened; - lvwLog.OnChange := nil; - lvwLog.Invalidate; - lvwLog.OnChange := lvwLogChange; - end; -end; - -procedure TfrmLog.SetBottleStatusToPlaying(const MID: String); +procedure TfrmLog.SetBottleState(const MID: String; State: TLogState); +var i: integer; + Bottle: TLogItem; begin - if CurrentBottleLog.Bottle(MID) <> nil then begin - CurrentBottleLog.Bottle(MID).State := lsPlaying; - lvwLog.OnChange := nil; - lvwLog.Invalidate; - lvwLog.OnChange := lvwLogChange; + for i := 0 to FBottleLogList.Count-1 do begin + Bottle := (FBottleLogList[i] as TBottleLogList).Bottle(MID); + if Bottle <> nil then begin + Bottle.State := State; + lvwLog.OnChange := nil; + lvwLog.Invalidate; + lvwLog.OnChange := lvwLogChange; + end; end; end; -procedure TfrmLog.DoSaveLog(SaveType: TSaveLogType; Ext: String; Filter: integer); -var i: integer; - Log: TStringList; - LogItem: TLogItem; - Date: String; -const - DayStr: array[1..7] of String = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); +procedure TfrmLog.mnSaveLogClick(Sender: TObject); begin + if SelectedBottleLog = nil then Exit; + SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log'); SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); - SaveDialog.DefaultExt := Ext; - SaveDialog.FilterIndex := Filter; - if SaveDialog.Execute then begin - Log := nil; - try - Log := TStringList.Create; - case SaveType of - stLog, stLogWithChannels: begin - for i := 0 to SelectedBottleLog.Count -1 do begin - LogItem := SelectedBottleLog.Bottles[i]; - if LogItem = nil then Continue; - if LogItem.LogType <> ltBottle then Continue; - Date := FormatDateTime('yyyy/mm/dd hh:nn:ss ', LogItem.LogTime); - Date := Date + '(' + DayStr[DayOfWeek(LogItem.LogTime)] + ')'; - if SaveType = stLogWithChannels then - Date := Date + ',' + LogItem.Channel +',SEND,' + LogItem.Script - else - Date := Date + ',0.0.0.0,SEND,' + LogItem.Script; - Log.Add(Date); - end; - end; - stText: begin - for i := 0 to SelectedBottleLog.Count -1 do begin - LogItem := SelectedBottleLog.Bottles[i]; - if LogItem = nil then Continue; - if LogItem.LogType <> ltBottle then Continue; - Log.Add(LogItem.Script); - end; - end; - stXML: begin - Log.Add(''); - Log.Add(''); - for i := 0 to SelectedBottleLog.Count -1 do begin - LogItem := SelectedBottleLog.Bottles[i]; - if LogItem = nil then Continue; - if LogItem.LogType <> ltBottle then Continue; - Date := FormatDateTime('yyyy/mm/dd hh:nn:ss', LogItem.LogTime); - Log.Add(Format('', [LogItem.MID])); - Log.Add('' + Date + ''); - Log.Add('' + XmlEntity(LogItem.Channel) + ''); - // - Log.Add(''); - Log.Add('' + IntToStr(LogItem.Votes) + ''); - Log.Add('' + IntToStr(LogItem.Agrees) + ''); - // - if LogItem.Ghost = '' then - Log.Add('') - else begin - Log.Add(Format('%s', [XmlEntity(LogItem.Ghost)])); - end; - Log.Add(''); - end; - Log.Add(''); - end; - end; - Log.SaveToFile(SaveDialog.FileName); - finally - Log.Free; - end; - end; + SaveDialog.DefaultExt := 'log'; + SaveDialog.FilterIndex := 1; + if SaveDialog.Execute then + SelectedBottleLog.SaveToSstpLog(SaveDialog.FileName, false); end; procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject); begin + if SelectedBottleLog = nil then Exit; + SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.log'); SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); SaveDialog.DefaultExt := 'log'; SaveDialog.FilterIndex := 1; @@ -546,6 +559,8 @@ end; procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject); begin + if SelectedBottleLog = nil then Exit; + SaveDialog.FileName := GetDefaultFileName(SelectedBottleLog.Title, '.txt'); SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); SaveDialog.DefaultExt := 'txt'; SaveDialog.FilterIndex := 2; @@ -555,11 +570,8 @@ end; procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject); begin - SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); - SaveDialog.DefaultExt := 'xml'; - SaveDialog.FilterIndex := 3; - if SaveDialog.Execute then - SelectedBottleLog.SaveToXmlFile(SaveDialog.FileName, XMLDocument); + if SelectedBottleLog = nil then Exit; + DoSaveLogXML(SelectedBottleLog); end; procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem); @@ -572,17 +584,21 @@ begin with Item do begin Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime); SubItems.Clear; - if Log.Ghost <> '' then - SubItems.Add(Log.Channel + '/' + Log.Ghost) - else - SubItems.Add(Log.Channel); + SubItems.Add(Log.Channel); + SubItems.Add(Log.Ghost); if Log.LogType = ltBottle then begin - SubItems.Add(IntToStr(Log.Votes)); - SubItems.Add(IntToStr(Log.Agrees)); + if Log.Votes > 0 then + SubItems.Add(IntToStr(Log.Votes)) + else + SubItems.Add(''); + if Log.Agrees > 0 then + SubItems.Add(IntToStr(Log.Agrees)) + else + SubItems.Add(''); end else begin // ƒVƒXƒeƒ€ƒƒO‚È‚Ç‚Í“Š•[E“¯ˆÓ‚ð•\Ž¦‚µ‚È‚¢ - SubItems.Add('-'); - SubItems.Add('-'); + SubItems.Add(''); + SubItems.Add(''); end; SubItems.Add(Log.Script); @@ -598,24 +614,36 @@ begin end; procedure TfrmLog.UpdateWindow; +var EnabledFlag: boolean; begin - StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + 'Œ'; - if Pref.ColorScript then begin - if lvwLog.Color <> Pref.BgColor then lvwLog.Color := Pref.BgColor; - if lvwLog.Font.Color <> Pref.TalkColorH then lvwLog.Font.Color := Pref.TalkColorH; + lvwLog.Color := Pref.BgColor; + lvwLog.Font.Color := Pref.TextColor; + if SelectedBottleLog <> nil then begin + Caption := 'ƒƒO - ' + SelectedBottleLog.Title; + StatusBar.Panels[0].Text := IntToStr(SelectedBottleLog.Count) + 'Œ'; + lvwLog.Items.Count := SelectedBottleLog.Count; end else begin - if lvwLog.Color <> clWindow then lvwLog.Color := clWindow; - if lvwLog.Font.Color <> clWindowText then lvwLog.Font.Color := clWindowText; + Caption := 'ƒƒO'; + StatusBar.Panels[0].Text := ''; + StatusBar.Panels[1].Text := ''; + lvwLog.Items.Count := 0; end; - lvwLog.Items.Count := SelectedBottleLog.Count; + + EnabledFlag := SelectedBottleLog <> nil; + tbtnClear.Enabled := EnabledFlag; + tbtnSaveLog.Enabled := EnabledFlag; + tbtnFindBottle.Enabled := EnabledFlag; + lvwLog.Invalidate; - //lvwLogChange(Self, lvwLog.Selected, ctState); end; procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject); var Log: TLogItem; Child: TMenuItem; Urls: TStringList; + Labels: TStringList; + ProcessedUrl: String; + ProcessedLabel: String; i: integer; begin for i := mnJumpURL.Count-1 downto 0 do begin @@ -625,14 +653,21 @@ begin if lvwLog.Selected = nil then Exit; Log := SelectedBottleLog.Bottles[lvwLog.Selected.Index]; if Log = nil then Exit; - Urls := nil; + Urls := TStringList.Create; + Labels := TStringList.Create; try - Urls := TStringList.Create; - ExtractURLs(Log.Script, Urls); + ExtractURLs(Log.Script, Urls, Labels); for i := 0 to Urls.Count-1 do begin Child := TMenuItem.Create(Self); with Child do begin - Caption := Format('(&%d) %s', [i+1, Urls[i]]); + ProcessedUrl := StringReplace(Urls[i], '&', '&&', [rfReplaceAll]); + ProcessedLabel := StringReplace(Labels[i], '&', '&&', [rfReplaceAll]); + if Length(ProcessedLabel) > 0 then begin + Caption := Format('[%s] %s (&%d)', [ProcessedLabel, ProcessedUrl, i+1]); + end else begin + Caption := Format('%s (&%d)', [ProcessedUrl, i+1]); + end; + Tag := i; OnClick := mnURLClick; AutoHotkeys := maManual; mnJumpURL.Add(Child); @@ -641,45 +676,75 @@ begin mnJumpURL.Enabled := Urls.Count > 0; finally Urls.Free; + Labels.Free; end; end; procedure TfrmLog.mnURLClick(Sender: TObject); -var URL: String; +var LogItem: TLogItem; + URL: string; + Urls: TStringList; + begin - URL := (Sender as TMenuItem).Caption; - RegExp.Subst('s/^\(&?\d\) //', URL); - ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW); + if (lvwLog.Selected = nil) or (SelectedBottleLog = nil) then Exit; + LogItem := SelectedBottleLog[lvwLog.Selected.Index] as TLogItem; + Urls := TStringList.Create; + try + ExtractURLs(LogItem.Script, Urls, nil); + URL := Urls[(Sender as TMenuItem).Tag]; + OpenBrowser(URL); + finally + Urls.Free; + end; end; -procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings); -var i, u, j: integer; +function TfrmLog.ExtractURLs(Script: String; Urls: TStrings; Labels: TStrings): Boolean; +var i, u, j, count: integer; s: String; begin - Result.Clear; - SsParser.LeaveEscape := false; + count := 0; SsParser.InputString := Script; SsParser.LeaveEscape := true; for i := 0 to SsParser.Count-1 do begin - if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin + if (SsParser.Match(SsParser[i], '\URL%b') > 0) + and (SsParser.MarkUpType[i] = mtTag) then + begin for u := 7 downto 1 do begin if (SsParser.Match(SsParser[i], '\URL%b'+StringReplace(StringOfChar('-', u*2), '-', '%b', [rfReplaceAll]))) > 0 then begin for j := 1 to u do begin s := SsParser.GetParam(SsParser[i], j*2); - if Pos('http://', s) > 0 then Result.Add(s); + if Pos('http://', s) > 0 then begin + if Urls <> nil then Urls.Add(s); + count := count + 1; + end; + if Labels <> nil then begin + s := SsParser.GetParam(SsParser[i], j*2+1); + Labels.Add(s); + end; end; Break; end; end; - if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //ŠÈˆÕ”ÅURL•ÏŠ· + if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //ŠÈˆÕŒ`Ž®\URLƒ^ƒO•ÏŠ· s := SsParser.GetParam(SsParser[i], 1); - if Pos('http://', s) > 0 then Result.Add(s); + if Pos('http://', s) > 0 then begin + if Urls <> nil then Urls.Add(s); + count := count + 1; + end end; end; end; + + //ƒ‰ƒxƒ‹‚̐”‚ðURL‚̐”‚É‚ ‚킹‚é - ‚¢‚¿‚¢‚¿”»’肵‚È‚­‚Ä‚à‚¢‚¢‚悤‚É + if Urls <> nil then begin + if Labels <> nil then begin + while Urls.Count > Labels.Count do Labels.Add(''); + end; + end; + Result := count > 0; end; procedure TfrmLog.SelAndFocusMessage(const MID: String); @@ -701,66 +766,11 @@ begin // end; -procedure TfrmLog.lvwLogCustomDrawSubItem(Sender: TCustomListView; - Item: TListItem; SubItem: Integer; State: TCustomDrawState; - var DefaultDraw: Boolean); -{var - DestRect: TRect; - Script: String; - i, x, w: integer; - SavedDC: integer; - Mark: TSsMarkUpType;} -begin - Exit // !! - {if (SubItem <> SubScript+1) or (not Pref.ColorScript) then Exit; // DefaultDraw = true - // Custom Script Coloring - DefaultDraw := false; - SavedDC := SaveDC(lvwLog.Canvas.Handle); - try - ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript+1, LVIR_BOUNDS, @DestRect); - - lvwLog.Canvas.Brush.Style := bsSolid; - if cdsSelected in State then begin - lvwLog.Canvas.Brush.Color := clHighlight - end else begin - lvwLog.Canvas.Brush.Color := Pref.BgColor; - end; - lvwLog.Canvas.FillRect(DestRect); - lvwLog.Canvas.Brush.Style := bsClear; - - Script := Item.SubItems[SubScript]; - // DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, DestRect, DT_END_ELLIPSIS, nil); - SsParser.InputString := Script; - x := 6; - for i := 0 to SsParser.Count - 1 do begin - Mark := SsParser.MarkUpType[i]; - case Mark of - mtMeta: lvwLog.Canvas.Font.Color := Pref.MetaWordColor; - mtTag: lvwLog.Canvas.Font.Color := Pref.MarkUpColor; - mtTagErr: lvwLog.Canvas.Font.Color := Pref.MarkErrorColor; - else begin - lvwLog.Canvas.Font.Color := Pref.TalkColorH; - end; - end; - w := lvwLog.Canvas.TextWidth(SsParser[i]); - lvwLog.Canvas.TextRect(DestRect, DestRect.Left + x, DestRect.Top + 2, SsParser[i]); - x := x + w; - if DestRect.Right - DestRect.Left < x then Break; - end; - finally - RestoreDC(lvwLog.Canvas.Handle, SavedDC); - end;} -end; - procedure TfrmLog.UpdateScript(const Script: String); begin if Script <> FLastScript then begin if Pref.LogWindowPreviewStyle = psConversation then begin - if Pref.ColorScript then begin - UpdateScriptConversationColor(Script); - end else begin - UpdateScriptConversationNoColor(Script); - end; + UpdateScriptConversationColor(Script); end else begin UpdateScriptScript(Script); end; @@ -784,46 +794,44 @@ begin for i := 0 to Items.Count-1 do Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag; Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle((Sender as TMenuItem).Tag); + PreviewStyleChange; FLastScript := ''; lvwLogChange(self, lvwLog.Selected, ctState); end; procedure TfrmLog.UpdateScriptScript(const Script: String); var - UnyuTalking: boolean; + UnyuTalking, InSynchronized: boolean; i: integer; begin - if Pref.ColorScript then begin - edtScript.Color := Pref.BgColor; - end else begin - edtScript.Color := clWindow; - edtScript.DefAttributes.Color := clWindowText; - edtScript.SelAttributes.Color := clWindowText; - end; + edtScript.Color := Pref.BgColor; SsParser.LeaveEscape := true; SsParser.InputString := Script; edtScript.Text := ''; edtScript.SelAttributes.Color := clWindowText; UnyuTalking := false; + InSynchronized := false; for i := 0 to SsParser.Count-1 do begin - if Pref.ColorScript then begin - case SsParser.MarkUpType[i] of - mtStr: begin - if UnyuTalking then - edtScript.SelAttributes.Color := Pref.TalkColorU - else - edtScript.SelAttributes.Color := Pref.TalkColorH; - end; - mtTag: begin - edtScript.SelAttributes.Color := Pref.MarkUpColor; - if SsParser[i] = '\h' then - UnyuTalking := false - else if SsParser[i] = '\u' then - UnyuTalking := true; - end; - mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor; - mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor; + case SsParser.MarkUpType[i] of + mtStr: begin + if InSynchronized then + edtScript.SelAttributes.Color := Pref.TalkColorS + else if UnyuTalking then + edtScript.SelAttributes.Color := Pref.TalkColorU + else + edtScript.SelAttributes.Color := Pref.TalkColorH; end; + mtTag: begin + edtScript.SelAttributes.Color := Pref.MarkUpColor; + if SsParser[i] = '\h' then + UnyuTalking := false + else if SsParser[i] = '\u' then + UnyuTalking := true + else if SsParser[i] = '\_s' then + InSynchronized := not InSynchronized; + end; + mtMeta: edtScript.SelAttributes.Color := Pref.MetaWordColor; + mtTagErr: edtScript.SelAttributes.Color := Pref.MarkErrorColor; end; edtScript.SelText := SsParser[i]; if (SsParser[i] = '\n') and (Pref.LogWindowPreviewStyle = psScriptWithLineBreak) then @@ -839,34 +847,29 @@ begin if sel > Ord(High(TLogWindowPreviewStyle)) then sel := 0; Pref.LogWindowPreviewStyle := TLogWindowPreviewStyle(sel); FLastScript := ''; + PreviewStyleChange; lvwLogChange(self, lvwLog.Selected, ctState); end; -function TfrmLog.XmlEntity(S: String): String; -begin - S := StringReplace(S, '&', '&', [rfReplaceAll]); - S := StringReplace(S, '<', '<', [rfReplaceAll]); - S := StringReplace(S, '>', '>', [rfReplaceAll]); - Result := S; -end; - function TfrmLog.SelectedBottleLog: TBottleLogList; begin - Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList; -end; - -function TfrmLog.GetCurrentBottleLog: TBottleLogList; -begin - Result := FBottleLogList.Items[0] as TBottleLogList; + if tabBottleLog.TabIndex >= 0 then + Result := FBottleLogList.Items[tabBottleLog.TabIndex] as TBottleLogList + else + Result := nil; end; procedure TfrmLog.tabBottleLogChange(Sender: TObject); begin + // StatusBar‚ÌŒ”•\Ž¦‚âListView.Items.Count‚ðXV‚·‚é UpdateWindow; - if SelectedBottleLog.SelectedIndex >= 0 then begin - lvwLog.Items[SelectedBottleLog.SelectedIndex].Selected := true; - if lvwLog.Focused then lvwLog.Selected.Focused := true; - end; + // ƒAƒCƒeƒ€‚Ì‘I‘ðó‘Ԃ𕜋A‚·‚é + with SelectedBottleLog do + if (SelectedIndex >= 0) and (Count > SelectedIndex) then + begin + lvwLog.Items[SelectedIndex].Selected := true; + if lvwLog.Focused then lvwLog.Selected.Focused := true; + end; lvwLogChange(Self, nil, ctState); end; @@ -878,23 +881,26 @@ begin end; procedure TfrmLog.UpdateTab; -var i: integer; - cur: TBottleLogList; +var i, cur: integer; begin - cur := SelectedBottleLog; + cur := tabBottleLog.tabIndex; tabBottleLog.Tabs.Clear; for i := 0 to FBottleLogList.Count - 1 do begin tabBottleLog.Tabs.Add((FBottleLogList[i] as TBottleLogList).Title); end; - tabBottleLog.TabIndex := FBottleLogList.IndexOf(cur); + if FBottleLogList.Count > 0 then begin + if cur < FBottleLogList.Count then + tabBottleLog.TabIndex := cur + else + tabBottleLog.TabIndex := FBottleLogList.Count-1; + end; end; procedure TfrmLog.LogLoadFailure(Sender: TObject; const Message: String); begin Beep; ShowMessage(Message); - (Sender as TBottleLogList).AddSystemLog(Message); - lvwLog.Invalidate; + if Sender = SelectedBottleLog then UpdateWindow; end; procedure TfrmLog.AgreeLog(const MID: String; const Agree: integer); @@ -928,6 +934,8 @@ end; procedure TfrmLog.tabBottleLogChanging(Sender: TObject; var AllowChange: Boolean); begin + // Œ»Ý‘I‘ð‚³‚ê‚Ä‚¢‚郍ƒO‚Ì‘I‘ðó‘Ô‚ð•Û‘¶ + if SelectedBottleLog = nil then Exit; if lvwLog.Selected <> nil then SelectedBottleLog.SelectedIndex := lvwLog.Selected.Index else @@ -940,54 +948,883 @@ begin with tabBottleLog do begin Tag := IndexOfTabAt(MousePos.X, MousePos.Y); if Tag < 0 then Handled := true; - mnCloseTab.Enabled := Tag > 0; end; end; procedure TfrmLog.mnCloseTabClick(Sender: TObject); begin - if tabBottleLog.Tag = 0 then Exit; - FBottleLogList.Delete(tabBottleLog.Tag); - tabBottleLog.TabIndex := 0; - UpdateTab; - UpdateWindow; - lvwLogChange(Self, nil, ctState); + DoCloseTab(tabBottleLog.Tag); end; procedure TfrmLog.tbtnFindBottleClick(Sender: TObject); -var Query: String; - ResultLog: TBottleLogList; - Item1, Item2: TLogItem; - i, matched: integer; +var ResultLog: TBottleLogList; + Cond: TSearchCond; + i: integer; + CList, GList: THashedStringList; begin - if SelectedBottleLog.Count = 0 then begin - ShowMessage('ŒŸõ‘Ώۂª‹ó‚Å‚·B'); - Exit; - end; - Query := ''; - matched := 0; - if InputQuery('ƒXƒNƒŠƒvƒg–{•¶‚ðŒŸõ', 'ŒŸõ•¶Žš—ñ', Query) then begin - if Query = '' then Exit; - ResultLog := TBottleLogList.Create('ŒŸõŒ‹‰Ê'); - for i := 0 to SelectedBottleLog.Count-1 do begin - Item1 := SelectedBottleLog.Items[i] as TLogItem; - if AnsiContainsText(Item1.Script, Query) and (Item1.LogType = ltBottle) then begin - matched := matched + 1; - Item2 := TLogItem.Create(ltBottle, Item1.MID, Item1.Channel, - Item1.Script, Item1.Ghost, Item1.LogTime); - Item2.State := lsOpened; - Item2.Votes := Item1.Votes; - Item2.Agrees := Item1.Agrees; - ResultLog.Add(Item2); + Application.CreateForm(TfrmSearchLog, frmSearchLog); + Cond := TSearchCond.Create(nil); + try + try + with frmSearchLog do + begin + // Œ»ÝƒƒO‚É‚ ‚éƒS[ƒXƒg‚ƃ`ƒƒƒ“ƒlƒ‹‚̃ŠƒXƒg‚ðŽæ“¾ + // d‚½‚¢‚©‚à?? + CList := THashedStringList.Create; + GList := THashedStringList.Create; + try + for i := 0 to BottleLogList.Count-1 do + begin + with BottleLogList[i] as TBottleLogList do + begin + ExtractUniqueChannels(CList); + ExtractUniqueGhosts(GList); + end; + end; + CList.Sort; + GList.Sort; + ChannelList := CList; + GhostList := GList; + finally + CList.Free; + GList.Free; + end; + if not Execute then + Exit + else + Cond.Assign(Condition); end; + finally + frmSearchLog.Release; end; - if matched = 0 then - ResultLog.AddSystemLog('Œ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½'); + // ŒŸõŽÀs + ResultLog := DoSearchLog(Cond); + // Vƒ^ƒu‚ðì¬‚µ‚ĉæ–ʍXV BottleLogList.Add(ResultLog); UpdateTab; tabBottleLog.TabIndex := BottleLogList.Count-1; UpdateWindow; + finally + Cond.Free; + end; +end; + +procedure TfrmLog.tbtnOpenLogClick(Sender: TObject); +var BottleLog: TBottleLogList; + i, Index: integer; +begin + Index := -1; + if OpenDialog.Execute then begin + for i := 0 to OpenDialog.Files.Count-1 do begin + BottleLog := TBottleLogList.Create(ExtractFileName(OpenDialog.Files[i])); + try + with BottleLog do + begin + OnLoaded := LogLoaded; + OnLoadFailure := LogLoadFailure; + OnLoadWork := LogLoadWork; + BottleLog.LoadFromXMLFile(OpenDialog.Files[i]); + end; + Index := BottleLogList.Add(BottleLog); // ÅŒã‚ÉŠJ‚¢‚½ƒƒO‚̈ʒu‚ð‹L‰¯ + except + BottleLog.Free; + end; + end; + UpdateTab; + if Index >= 0 then tabBottleLog.TabIndex := Index; + UpdateWindow; + end; +end; + +function TfrmLog.GetDefaultFileName(const Name, Ext: String): String; +begin + Result := StringReplace(Name, '/', '', [rfReplaceAll]); + Result := StringReplace(Result, ' ', '', [rfReplaceAll]); + Result := SafeFileName(Result); + Result := ChangeFileExt(Result, Ext); +end; + +function TfrmLog.BottleLogTitled(const LogName: String): TBottleLogList; +var i: integer; +begin + for i := 0 to FBottleLogList.Count-1 do begin + if (FBottleLogList[i] as TBottleLogList).Title = LogName then begin + Result := (FBottleLogList[i] as TBottleLogList); + Exit; + end; + end; + // Œ©‚‚©‚ç‚È‚¢ê‡ + Result := TBottleLogList.Create(LogName); // V‚µ‚­ì‚é + FBottleLogList.Add(Result); + UpdateTab; + if FBottleLogList.Count = 1 then tabBottleLog.TabIndex := 0; +end; + +procedure TfrmLog.AllBottleOpened; +var i, j: integer; + Log: TBottleLogList; +begin + for i := 0 to FBottleLogList.Count-1 do begin + Log := FBottleLogList[i] as TBottleLogList; + for j := 0 to Log.Count-1 do begin + Log.Bottles[j].State := lsOpened; + end; + end; +end; + +procedure TfrmLog.tabBottleLogMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +var Index: integer; +begin + if Button = mbMiddle then + begin + //’†ƒ{ƒ^ƒ“ƒNƒŠƒbƒN‚Ń^ƒuíœ + DoCloseTab(tabBottleLog.IndexOfTabAt(X, Y)); + end else + begin + with tabBottleLog do begin + Index := IndexOfTabAt(X, Y); + if Index = -1 then Exit; //ƒ^ƒu‚ª‚È‚¢‚̂Ńhƒ‰ƒbƒO‚Å‚«‚È‚¢ + if Button = mbLeft then begin + FDragTabIndex := Index; //ƒhƒ‰ƒbƒO‚·‚éƒ^ƒu‚̃Cƒ“ƒfƒbƒNƒX‚ð•Û‘¶ + BeginDrag(False); + FDragTabDest := -1; //ƒhƒ‰ƒbƒO˜gü•`‰æƒtƒ‰ƒOƒNƒŠƒA‚Ì‚½‚ß + end; + end; + end; +end; + +procedure TfrmLog.tabBottleLogDragOver(Sender, Source: TObject; X, + Y: Integer; State: TDragState; var Accept: Boolean); +var TargetRect: TRect; + OldDest, Index: integer; + dummy: boolean; +begin + // ƒ^ƒu‚̃hƒ‰ƒbƒO(ƒ^ƒu‚̏‡”Ô“ü‚ê‘Ö‚¦)‚Ü‚½‚́A + // ƒƒOƒAƒCƒeƒ€‚̃hƒ‰ƒbƒO(ƒƒO‚ð•Ê‚̃^ƒu‚Ɉړ®)‚Ì + // —¼•û‚̃hƒ‰ƒbƒO‚ðŽó‚¯•t‚¯‚é + Accept := false; + if Source = tabBottleLog then + begin + // ƒ^ƒu‚̏‡”Ô“ü‚ê‘Ö‚¦‚̏ꍇ + Accept := true; + with tabBottleLog do begin + OldDest := FDragTabDest; + FDragTabDest := IndexOfTabAt(X, Y); + if FDragTabDest = -1 then begin + Accept := false; //‚±‚̏ꍇ‚̓hƒƒbƒv‚ð”F‚ß‚È‚¢ + Exit; + end; + with Canvas do begin + Pen.Mode := pmNot; + Pen.Width := 3; + end; + if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin + //ˆÈ‘O‚̘güÁ‹Ž + TargetRect := TabRect(OldDest); + with Canvas do begin + Brush.Style := bsClear; + Rectangle(TargetRect.Left, TargetRect.Top, + TargetRect.Right, TargetRect.Bottom); + end; + end; + if (OldDest <> FDragTabDest) then begin + //V‚µ‚¢˜gü•`‰æ + TargetRect := TabRect(FDragTabDest); + with Canvas do begin + Brush.Style := bsClear; + Rectangle(TargetRect.Left, TargetRect.Top, + TargetRect.Right, TargetRect.Bottom); + end; + end; + end; + end else if Source is TBottleLogDragObject then + begin + // ƒƒO€–ڂ̃hƒ‰ƒbƒO(ƒƒO‚ð•Ê‚̃^ƒu‚Ɉړ®‚·‚é)‚̏ꍇ + Index := tabBottleLog.IndexOfTabAt(X, Y); + if tabBottleLog.TabIndex <> Index then + begin + FLVDragDest := -1; // ˜gü‚Í‚Ü‚¾•\Ž¦‚³‚ê‚È‚¢‚Í‚¸ + // ƒ^ƒu‚ðØ‘Ö‚¦‚é + tabBottleLogChanging(Self, dummy); + tabBottleLog.TabIndex := Index; + UpdateWindow; + end; + end; +end; + +procedure TfrmLog.tabBottleLogDragDrop(Sender, Source: TObject; X, + Y: Integer); +var DestIndex: integer; +begin + with tabBottleLog do begin + DestIndex := IndexOfTabAt(X, Y); + Tabs.Move(FDragTabIndex, DestIndex); + FBottleLogList.Move(FDragTabIndex, DestIndex); + end; +end; + +procedure TfrmLog.tabBottleLogEndDrag(Sender, Target: TObject; X, + Y: Integer); +begin + //‹­§“I‚Ƀ^ƒu‚ðÄ•`‰æ‚³‚¹‚éB˜güÁ‚µ‘΍ô + tabBottleLog.Tabs.BeginUpdate; + tabBottleLog.Tabs.EndUpdate; +end; + +procedure TfrmLog.LogLoadWork(Sender: TObject); +begin + if Sender = SelectedBottleLog then + begin + lvwLog.Invalidate; + lvwLog.Items.Count := SelectedBottleLog.Count; + end; +end; + +procedure TfrmLog.lvwLogDrawItem(Sender: TCustomListView; Item: TListItem; + Rect: TRect; State: TOwnerDrawState); +var + DestRect: TRect; + Script: String; + Ico: TIcon; + sub, Ex: integer; + Bottle: TLogItem; +begin + Bottle := SelectedBottleLog.Bottles[Item.Index]; + if Bottle.HasURL = huUndefined then + begin + try + if ExtractURLs(Bottle.Script, nil, nil) then + Bottle.HasURL := huYes + else + Bottle.HasURL := huNo; + finally + + end; + end; + + // ”wŒiÁ‹Ž + ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_BOUNDS); + + // ”wŒi‚̐F‚Í‘I‘ðó‘ԁE‘I‘ð”ñƒAƒNƒeƒBƒuó‘ԁE’ʏíó‘Ô‚Ì3’Ê‚è + lvwLog.Canvas.Brush.Style := bsSolid; + if Item.Selected then begin + if lvwLog.Focused then + lvwLog.Canvas.Brush.Color := clHighlight + else + lvwLog.Canvas.Brush.Color := clBtnFace; + end else begin + lvwLog.Canvas.Brush.Color := Pref.BgColor; + end; + lvwLog.Canvas.FillRect(DestRect); + lvwLog.Canvas.Brush.Style := bsClear; + // ƒtƒH[ƒJƒX‚ª‚ ‚éê‡‚ɂ̓tƒH[ƒJƒX‚̘gü‚ðˆø‚­ + if Item.Focused and lvwLog.Focused then + lvwLog.Canvas.DrawFocusRect(DestRect); + + // ƒhƒ‰ƒbƒO’†‚È‚ç˜gü‚ð•`‰æ‚·‚é + if FLVDragDest = Item.Index then + begin + DestRect := Item.DisplayRect(drBounds); + DrawListViewDragBorder(DestRect); + end; + + if Item.Selected then + begin + if lvwLog.Focused then + lvwLog.Canvas.Font.Color := clHighlightText + else + lvwLog.Canvas.Font.Color := clWindowText; + end else + lvwLog.Canvas.Font.Color := Pref.TextColor; + lvwLog.Canvas.Refresh; + + // ƒLƒƒƒvƒVƒ‡ƒ“(“ú•t) + ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_LABEL); + Inc(DestRect.Left, 2); + Inc(DestRect.Top, 2); + Dec(DestRect.Right, 2); + DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.Caption), -1, DestRect, + DT_SINGLELINE or DT_RIGHT, nil); + ListView_GetItemRect(lvwLog.Handle, Item.Index, DestRect, LVIR_ICON); + Ico := TIcon.Create; + try + lvwLog.SmallImages.GetIcon(Item.ImageIndex, Ico); + lvwLog.Canvas.Draw(DestRect.Left, DestRect.Top, Ico); + finally + Ico.Free; + end; + // ƒLƒƒƒvƒVƒ‡ƒ“‚Å‚àƒXƒNƒŠƒvƒg‚Å‚à‚È‚¢‚à‚Ì + for sub := 0 to Item.SubItems.Count-1 do + begin + if sub = SubScript then Continue; + ListView_GetSubItemRect(lvwLog.Handle, Item.Index, sub + 1, + LVIR_BOUNDS, @DestRect); + if DestRect.Right - DestRect.Left <= 16 then + begin + // ‹·‚·‚¬‚éê‡‚Í•¶Žš—ñ‚ð•`‰æ‚µ‚È‚¢B + // 16‚Æ‚¢‚¤”Žš‚ÍŽÀ‘ª’lB‰½‚©‚̃oƒO‚Á‚Û + lvwLog.Canvas.FillRect(DestRect); + Continue; + end; + Inc(DestRect.Left, 2); + Inc(DestRect.Top, 2); + Dec(DestRect.Right, 2); + Ex := DT_NOPREFIX or DT_SINGLELINE or DT_END_ELLIPSIS; + if lvwLog.Columns[sub+1].Alignment = taRightJustify then + Ex := Ex or DT_RIGHT; + DrawTextEx(lvwLog.Canvas.Handle, PChar(Item.SubItems[sub]), -1, DestRect, + Ex, nil); + end; + // ƒXƒNƒŠƒvƒg + ListView_GetSubItemRect(lvwLog.Handle, Item.Index, SubScript + 1, + LVIR_BOUNDS, @DestRect); + Script := Item.SubItems[SubScript]; + DrawSingleLineScript(Bottle, DestRect, Item); + +end; + +procedure TfrmLog.DrawSingleLineScript(LogItem: TLogItem; + Rect: TRect; Item: TListItem); +var + i, x, w: integer; + UnyuTalking, Synchronized, Spaced: boolean; + Mark: TSsMarkUpType; + Script: String; + Ico: TIcon; + procedure ScopeChange; + begin + if (not Spaced) and (Pref.LogListPreviewStyle = psTagStripped) then + begin + Inc(x, 7); + Spaced := true; + end; + end; +begin + Script := LogItem.Script; + x := 3; + + if LogItem.HasURL = huYes then + begin + Ico := TIcon.Create; + try + lvwLog.SmallImages.GetIcon(IconURL, Ico); + lvwLog.Canvas.Draw(Rect.Left + x, Rect.Top, Ico); + Inc(x, 20); + finally + Ico.Free; + end; + end; + + if Pref.LogListPreviewStyle = psNoColor then + begin + Inc(Rect.Left, x); + Inc(Rect.Top, 2); + Dec(Rect.Right, 2); + DrawTextEx(lvwLog.Canvas.Handle, PChar(Script), -1, Rect, + DT_SINGLELINE or DT_END_ELLIPSIS or DT_NOPREFIX, nil); + Exit; + end; + + SsParser.LeaveEscape := Pref.LogListPreviewStyle = psNormal; + SsParser.InputString := Script; + + UnyuTalking := false; + Synchronized := false; + Spaced := true; // ƒ^ƒOÈ—ª•\Ž¦Žž‚É•s•K—v‚ɃXƒR[ƒv•ÏŠ·Žž‚̃Xƒy[ƒX‚ð‹ó‚¯‚È‚¢ + // ‚½‚߂̃tƒ‰ƒO + for i := 0 to SsParser.Count - 1 do begin + if SsParser[i] = '\h' then + begin + UnyuTalking := false; + ScopeChange; + end else if SsParser[i] = '\u' then + begin + UnyuTalking := true; + ScopeChange; + end else if SsParser[i] = '\_s' then + begin + Synchronized := not Synchronized; + ScopeChange; + end else if (Pos('\n', SsParser[i]) = 1) or (SsParser[i] = '\c') then + begin + ScopeChange; + end; + Mark := SsParser.MarkUpType[i]; + case Mark of + mtMeta: + begin + lvwLog.Canvas.Font.Color := Pref.MetaWordColor; + Spaced := false; + end; + mtTag: + if Pref.LogListPreviewStyle = psNormal then + lvwLog.Canvas.Font.Color := Pref.MarkUpColor + else + begin + Continue; + end; + mtTagErr: + lvwLog.Canvas.Font.Color := Pref.MarkErrorColor; + else begin + Spaced := false; + if Synchronized then + lvwLog.Canvas.Font.Color := Pref.TalkColorS + else if UnyuTalking then + lvwLog.Canvas.Font.Color := Pref.TalkColorU + else + lvwLog.Canvas.Font.Color := Pref.TalkColorH; + end; + end; + if Item.Selected then + begin + if lvwLog.Focused then + lvwLog.Canvas.Font.Color := clHighlightText + else + lvwLog.Canvas.Font.Color := clWindowText; + end; + lvwLog.Canvas.Refresh; + w := lvwLog.Canvas.TextWidth(SsParser[i]); + lvwLog.Canvas.TextRect(Rect, Rect.Left + x, Rect.Top + 2, SsParser[i]); + x := x + w; + if Rect.Right - Rect.Left < x then Break; + end; +end; + +procedure TfrmLog.mnListPreviewStyleClick(Sender: TObject); +var i: integer; +begin + with PopupMenuListPreviewStyle do + for i := 0 to Items.Count-1 do + Items[i].Checked := (Sender as TMenuItem).Tag = Items[i].Tag; + Pref.LogListPreviewStyle := TLogListPreviewStyle((Sender as TMenuItem).Tag); + lvwLog.Invalidate; +end; + +procedure TfrmLog.tbtnListPreviewStyleClick(Sender: TObject); +var sel: integer; +begin + sel := Ord(Pref.LogListPreviewStyle); + sel := sel + 1; + if sel > Ord(High(TLogListPreviewStyle)) then sel := 0; + Pref.LogListPreviewStyle := TLogListPreviewStyle(sel); + lvwLog.Invalidate; +end; + +procedure TfrmLog.PopupMenuListPreviewStylePopup(Sender: TObject); +var i: integer; +begin + with PopupMenuListPreviewStyle do + for i := 0 to Items.Count-1 do + Items[i].Checked := Items[i].Tag = Ord(Pref.LogListPreviewStyle) +end; + +procedure TfrmLog.PreviewStyleChange; +begin + if Pref.LogWindowPreviewStyle = psImageConversation then + begin + if Spps.Count = 0 then + ShowMessage('ƒT[ƒtƒBƒXƒvƒŒƒrƒ…[—pƒvƒ‰ƒOƒCƒ“‚ª‘¶Ý‚µ‚Ü‚¹‚ñB'); + edtScript.Visible := false; + TalkShowFrame.Visible := true; + end else + begin + edtScript.Visible := true; + TalkShowFrame.Visible := false; + end; +end; + +procedure TfrmLog.lvwLogDragOver(Sender, Source: TObject; X, Y: Integer; + State: TDragState; var Accept: Boolean); +var + Target: TListItem; + OldDest: integer; + Rec: TRect; // ƒ_ƒ~[B +begin + Accept := False; + // ‚Æ‚è‚ ‚¦‚¸Žó‚¯•t‚¯‚é‰Â”\«‚ª‚ ‚é‚Ì‚ÍTBottleLogDragObject‚¾‚¯ + if not (Source is TBottleLogDragObject) then + Exit; + + Target := lvwLog.GetItemAt(X, Y); + + // ‚±‚êˆÈ‘O‚É•`‰æ‚³‚ê‚Ä‚¢‚½˜g‚̃Cƒ“ƒfƒbƒNƒX + OldDest := FLVDragDest; + + // ƒhƒƒbƒvˆÊ’u‚É Item ‚ª‚ ‚ê‚΃hƒƒbƒv‚ð‹–‰Â‚·‚é + if Target <> nil then + begin + Accept := true; + FLVDragDest := Target.Index; + end else + begin + Accept := true; + FLVDragDest := -1; + end; + + // ˆÈ‘O‚̘gü‚ðíœ + if (OldDest > -1) and (FLVDragDest <> OldDest) then + begin + Rec := lvwLog.Items[OldDest].DisplayRect(drBounds); + DrawListViewDragBorder(Rec); + end; + // ƒhƒ‰ƒbƒOæ‚̘gü‚ð•`‰æ + if (Target <> nil) and (FLVDragDest <> OldDest) then + begin + Rec := Target.DisplayRect(drBounds); + DrawListViewDragBorder(Rec); + end; + + // ƒXƒNƒ[ƒ‹ŠÖŒW + if lvwLog.Items.Count > 0 then + begin + if (lvwLog.topItem <> nil) and (Y - lvwLog.TopItem.Top < 10) then + begin + FLVScrollDir := lvScrollDown; + if not timScrollTimer.Enabled then + timScrollTimer.Enabled := true; + end else if (lvwLog.Height - Y) < 10 then + begin + FLVScrollDir := lvScrollUp; + if not timScrollTimer.Enabled then + timScrollTimer.Enabled := true; + end + else + timScrollTimer.Enabled := false; + end else + timScrollTimer.Enabled := false; +end; + +procedure TfrmLog.lvwLogDragDrop(Sender, Source: TObject; X, Y: Integer); +var + TargetItem: integer; + Src: TBottleLogDragObject; + SrcLog: TObject; +begin + timScrollTimer.Enabled := false; + + if not (Source is TBottleLogDragObject) then + Exit; + Src := Source as TBottleLogDragObject; + + if lvwLog.GetItemAt(X, Y) <> nil then + TargetItem := lvwLog.GetItemAt(X, Y).Index + else + TargetItem := -1; + + lvwLog.Items.BeginUpdate; // ƒhƒƒbƒv’†‚Í•\Ž¦‚ð—}Ž~‚·‚é@d—vI + try + // ƒhƒƒbƒvˆÊ’u‚É Item ‚ðˆÚ“®‚·‚é + if (GetAsyncKeyState(VK_CONTROL) and $8000) > 0 then + begin // ƒRƒs[ˆÚ“®‚̏ꍇ + SrcLog := TLogItem.Create(Src.LogItem); + end else // ˆÚ“®‚¾‚¯‚·‚éê‡ + begin + SrcLog := Src.BottleLogList.Extract(Src.LogItem); + end; + if TargetItem >= 0 then + begin + // ‚·‚Å‚É‘¶Ý‚·‚éƒAƒCƒeƒ€‚̏ã‚Ƀhƒƒbƒv‚µ‚½ê‡ + SelectedBottleLog.Insert(TargetItem, SrcLog); + end else + begin + // ListView‚Ì—]”’‚Ƀhƒƒbƒv‚µ‚½ê‡(Insert‚Å‚«‚È‚¢) + TargetItem := SelectedBottleLog.Add(SrcLog); + end; + lvwLog.Items[TargetItem].Selected := true; + lvwLog.Items[TargetItem].Focused := true; + finally + lvwLog.Items.EndUpdate; + UpdateWindow; + end; +end; + +procedure TfrmLog.timScrollTimerTimer(Sender: TObject); +var + ScrollHeight: Integer; +begin + // ƒXƒNƒ[ƒ‹—Ê‚ð‹‚ß‚é + ScrollHeight := 0; + if lvwLog.Items.Count > 2 then + begin + ScrollHeight := lvwLog.Items[1].Top - lvwLog.Items[0].Top; + end; + + case FLVScrollDir of + lvScrollUp: lvwLog.Scroll(0, ScrollHeight); + lvSCrollDown: lvwLog.Scroll(0, -ScrollHeight); + end; + lvwLog.Invalidate; // ÅV‚̏ó‘Ԃɍĕ`‰æ‚·‚é + lvwLog.Update; +end; + +procedure TfrmLog.mnChangeTabNameClick(Sender: TObject); +var Name: String; +begin + Name := (FBottleLogList[tabBottleLog.Tag] as TBottleLogList).Title; + InputQuery('–¼‘O‚̕ύX', 'V‚µ‚¢ƒ^ƒu‚Ì–¼‘O', Name); + (FBottleLogList[tabBottleLog.Tag] as TBottleLogList).Title := Name; + UpdateTab; +end; + +procedure TfrmLog.lvwLogStartDrag(Sender: TObject; + var DragObject: TDragObject); +var Drag: TBottleLogDragObject; +begin + // ’ʏí‚ÌListView—p‚̃hƒ‰ƒbƒOƒIƒuƒWƒFƒNƒg‚Í + // OS‚É‚æ‚Á‚ẮAˆÚ“®‚·‚é‚Æ‚«‚ɃAƒCƒeƒ€‚̃Cƒ[ƒW‚𔼓§–¾‚Å•`‰æ‚µ‚Ä‚µ‚Ü‚¤B + // TDragObject‚©‚ç’¼ÚŒp³‚µ‚½‚¾‚¯‚Ì‚à‚Ì(ƒCƒ[ƒW‚ðŽ‚Á‚Ä‚¢‚È‚¢)‚ðŽg‚¤‚Æ + // ”¼“§–¾ƒCƒ[ƒW‚Ì•`‰æ‚Í—}§‚Å‚«‚éB + Drag := TBottleLogDragObject.Create(lvwLog); + Drag.BottleLogList := SelectedBottleLog; + Drag.LogItem := SelectedBottleLog.Bottles[lvwLog.Selected.Index]; + DragObject := Drag; +end; + +procedure TfrmLog.lvwLogEndDrag(Sender, Target: TObject; X, Y: Integer); +begin + // ˜güÁ‚µ—p‚É‹­§“I‚ɍĕ`‰æ‚³‚¹‚é + timScrollTimer.Enabled := false; + FLVDragDest := -1; + UpdateWindow; +end; + +procedure TfrmLog.DrawListViewDragBorder(const Rect: TRect); +var Rec: TRect; +begin + Rec := Rect; + InflateRect(Rec, -1, -1); + with lvwLog.Canvas do + begin + Pen.Mode := pmNot; + Pen.Width := 3; + Brush.Style := bsClear; + Refresh; // •K—v + Rectangle(Rec); + end; +end; + +procedure TfrmLog.DoSaveLogXML(Log: TBottleLogList); +begin + SaveDialog.FileName := GetDefaultFileName(Log.Title, '.xml'); + SaveDialog.InitialDir := ExtractFileDir(Application.ExeName); + SaveDialog.DefaultExt := 'xml'; + SaveDialog.FilterIndex := 3; + if SaveDialog.Execute then + Log.SaveToXmlFile(SaveDialog.FileName); +end; + +procedure TfrmLog.DoCloseTab(const Index: integer); +var + Confirm: String; + PrevSelection: TBottleLogList; // •Â‚¶‚½‚Æ‚«ƒ^ƒu‚ª‚¸‚ê‚È‚¢‚悤‚É‚·‚鏈——p + i: integer; +begin + if Pref.ConfirmOnTabClose then + begin + Confirm := Format('ƒ^ƒu"%s"‚ð•Â‚¶‚Ü‚·‚©?', [(FBottleLogList[Index] as TBottleLogList).Title]); + if MessageDlg(Confirm, mtConfirmation, mbOkCancel, 0) = mrCancel then + Exit; end; + PrevSelection := SelectedBottleLog; + FBottleLogList.Delete(Index); + UpdateTab; + // ƒ^ƒu‚¸‚ê–hŽ~ˆ— + for i := 0 to FBottleLogList.Count-1 do + if FBottleLogList[i] = PrevSelection then + tabBottleLog.TabIndex := i; + UpdateWindow; + lvwLogChange(Self, nil, ctState); +end; + +procedure TfrmLog.HTMLOutputWork(Sender: TObject; const Count: integer; + var Canceled: boolean); +begin + frmHTMLOutputProgress.ProgressBar.Position := Count; + Application.ProcessMessages; + if frmHTMLOutputProgress.Canceled then + Canceled := true; +end; + +function TfrmLog.DoSearchLog(Condition: TSearchCond): TBottleLogList; +var i, UntilIndex: integer; +begin + Result := TBottleLogList.Create('ŒŸõŒ‹‰Ê'); + if Condition.SearchLogRange in [srSelectedLogList, srAboveSelectedLog] then + begin + if SelectedBottleLog = nil then + begin + ShowMessage('ŒŸõ‘Ώۂª‚ ‚è‚Ü‚¹‚ñ'); + Result.Free; + Result := nil; + Exit; + end else + begin + if Condition.SearchLogRange = srSelectedLogList then + UntilIndex := -1 + else if lvwLog.Selected = nil then + UntilIndex := -1 + else + UntilIndex := lvwLog.Selected.Index; + SearchLogIndivisual(Condition, SelectedBottleLog, Result, UntilIndex); + end; + end else if Condition.SearchLogRange = srAllLogLists then + begin + for i := 0 to BottleLogList.Count-1 do + begin + SearchLogIndivisual(Condition, BottleLogList[i] as TBottleLogList, + Result); + end; + end; + + if Result.Count = 0 then + Result.AddSystemLog('Œ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½B'); +end; + +procedure TfrmLog.SearchLogIndivisual(Condition: TSearchCond; LogList, + Result: TBottleLogList; UntilIndex: integer = -1); +var + i, Max: integer; + Bottle, New: TLogItem; + Ok: boolean; +begin + // 1ŒÂ‚̃ƒOƒ^ƒu‚ɑ΂µ‚ÄŒŸõ‚ð‚©‚¯‚éBUntilIndex‚Ŕ͈͎w’è(È—ªŽž‚»‚̃^ƒu‘S‘Ì) + if UntilIndex >= 0 then + Max := UntilIndex + else + Max := LogList.Count-1; + for i := 0 to Max do + begin + // ðŒ”»’è + Bottle := LogList.Bottles[i]; + if Bottle.LogType <> ltBottle then + Continue; + Ok := true; + // ƒXƒNƒŠƒvƒgƒpƒ^[ƒ“‚ʼnðÍ + if Condition.ScriptPattern <> '' then + begin + if Condition.ScriptRegExp then + begin + try + if not RegExp.Match(Condition.ScriptPattern, Bottle.Script) then + Ok := false; + except + on EBRegExpError do + Ok := false; //–­‚Ȑ³‹K•\Œ»‚ðR‚é + end; + end else + begin + if not AnsiContainsText(Bottle.Script, Condition.ScriptPattern) then + Ok := false; + end; + end; + // ƒ`ƒƒƒ“ƒlƒ‹–¼AƒS[ƒXƒg–¼A“Š•[“¯ˆÓ + if Condition.Channel <> '' then + if not AnsiContainsText(Bottle.Channel, Condition.Channel) then + Ok := false; + if Condition.Ghost <> '' then + if not AnsiContainsText(Bottle.Ghost, Condition.Ghost) then + Ok := false; + if Condition.MinVote > Bottle.Votes then + Ok := false; + if Condition.MinAgree > Bottle.Agrees then + Ok := false; + // ðŒ‚Ɉê’v‚µ‚½‚à‚Ì‚ðŒ‹‰ÊƒŠƒXƒg‚ɒljÁ + if Ok then + begin + New := TLogItem.Create(Bottle); // ƒRƒs[ƒRƒ“ƒXƒgƒ‰ƒNƒ^ + New.State := lsOpened; + Result.Add(New); + end; + end; +end; + +{ TBottleLogDragObject } + +function TBottleLogDragObject.GetDragImages: TDragImageList; +begin + // ’†“r”¼’[‚ȃhƒ‰ƒbƒOƒCƒ[ƒW‚ð•\Ž¦‚µ‚È‚¢‚悤‚É‚·‚é + Result := nil; +end; + +procedure TBottleLogDragObject.SetBottleLogList( + const Value: TBottleLogList); +begin + FBottleLogList := Value; +end; + +procedure TBottleLogDragObject.SetLogItem(const Value: TLogItem); +begin + FLogItem := Value; +end; + +procedure TfrmLog.mnTabSaveXMLLogClick(Sender: TObject); +begin + DoSaveLogXML(FBottleLogList[tabBottleLog.Tag] as TBottleLogList); +end; + +procedure TfrmLog.mnSaveHTMLClick(Sender: TObject); +var + LogList, SB: TBottleLogList; + i: integer; + Options: THTMLOutputOptions; +begin + SB := SelectedBottleLog; + if SB = nil then + Exit; + if SB.Count = 0 then + Exit; + Application.CreateForm(TfrmHTMLOutputConfig, frmHTMLOutputConfig); + with frmHTMLOutputConfig do + try + // Show HTML save option dialog + if not Execute then + Exit; + LogList := TBottleLogList.Create(''); + try + case Range of + orAll: + for i := SB.Count-1 downto 0 do + if SB.Bottles[i].LogType = ltBottle then + LogList.Add(TLogItem.Create(SB.Bottles[i])); + orSelected: + if SB.Bottles[lvwLog.Selected.Index].LogType = ltBottle then + LogList.Add(TLogItem.Create(SB.Bottles[lvwLog.Selected.Index])) + else + ShowMessage('‚±‚̃ƒbƒZ[ƒW‚Í•Û‘¶‚Å‚«‚Ü‚¹‚ñ'); + orUpward: + for i := lvwLog.Selected.Index downto 0 do + if SB.Bottles[i].LogType = ltBottle then + LogList.Add(TLogItem.Create(SB.Bottles[i])); + end; + Options.ImageDir := ImageDir; + Options.UseColor := UseColor; + Options.ImageType := ImageType; + Application.CreateForm(TfrmHTMLOutputProgress, frmHTMLOutputProgress); + try + frmHTMLOutputProgress.Show; + LogList.OnHTMLOutputWork := HTMLOutputWork; + LogList.SaveToHTML(FileName, Options, SsParser); + finally + frmHTMLOutputProgress.Release; + end; + finally + LogList.Free; + end; + finally + Release; + end; +end; + +procedure TfrmLog.mnPopupCopyGhostClick(Sender: TObject); +var + Log: TLogItem; + Clip: TClipBoard; +begin + Log := SelectedBottleLog.Bottles[frmLog.lvwLog.Selected.Index]; + if Log = nil then Exit; + Clip := ClipBoard(); + Clip.SetTextBuf(PChar(Log.Ghost)); end; end.