6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ComCtrls, ToolWin, StdCtrls, ExtCtrls, SsParser, BottleDef, Menus, FastSstp,
8 Clipbrd, Logs, ShellAPI;
11 TSaveLogType = (stLog, stLogWithChannels, stText, stXML);
13 TfrmLog = class(TForm)
15 tbtnClear: TToolButton;
18 StatusBar: TStatusBar;
19 tbtnSaveLog: TToolButton;
20 PopupMenuPreview: TPopupMenu;
22 tbtnVoteMessage: TToolButton;
23 PopupMenuListView: TPopupMenu;
24 mnPopUpVoteMessage: TMenuItem;
25 SaveDialog: TSaveDialog;
30 mnPopUpCopyScript: TMenuItem;
31 PopupMenuSaveLog: TPopupMenu;
33 mnSaveLogChannel: TMenuItem;
34 mnSaveLogScript: TMenuItem;
35 mnSaveLogXML: TMenuItem;
36 ToolButton1: TToolButton;
38 mnPopUpAgreeMessage: TMenuItem;
39 tbtnAgreeMessage: TToolButton;
40 procedure tbtnClearClick(Sender: TObject);
41 procedure FormCreate(Sender: TObject);
42 procedure lvwLogChange(Sender: TObject; Item: TListItem;
44 procedure lvwLogDblClick(Sender: TObject);
45 procedure lvwLogKeyPress(Sender: TObject; var Key: Char);
46 procedure FormDestroy(Sender: TObject);
47 procedure lvwLogClick(Sender: TObject);
48 procedure mnSaveLogClick(Sender: TObject);
49 procedure lvwLogColumnClick(Sender: TObject; Column: TListColumn);
50 procedure mnPopUpCopyScriptClick(Sender: TObject);
51 procedure mnSaveLogChannelClick(Sender: TObject);
52 procedure mnSaveLogScriptClick(Sender: TObject);
53 procedure mnSaveLogXMLClick(Sender: TObject);
54 procedure lvwLogData(Sender: TObject; Item: TListItem);
55 procedure PopupMenuListViewPopup(Sender: TObject);
58 SortColumn: integer; //
\97ñ
\83N
\83\8a\83b
\83N
\83\
\81[
\83g
\97p
59 SortDesc: boolean; //
\97ñ
\83N
\83\8a\83b
\83N
\83\
\81[
\83g
\97p
60 procedure UpdateScriptColor(const Script: String);
61 procedure UpdateScriptNoColor(const Script: String);
62 procedure DoSaveLog(SaveType: TSaveLogType; Ext: String;
64 procedure mnURLClick(Sender: TObject);
65 procedure ExtractURLs(Script: String; Result: TStrings);
67 procedure CreateParams(var Params: TCreateParams); override;
70 procedure AddScriptLog(const Script, Channel, MID, Ghost: String);
71 procedure AddSystemLog(const MessageString: String);
72 procedure SetBottleStatusToPlaying(const MID: String);
73 procedure SetBottleStatusToOpened(const MID: String);
74 procedure UpdateWindow;
99 procedure TfrmLog.AddScriptLog(const Script, Channel, MID, Ghost: String);
100 var LogItem: TLogItem;
103 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
104 LogItem := TLogItem.Create(ltBottle, MID, Channel, Script, Ghost, Now());
105 BottleLog.Insert(0, LogItem);
106 lvwLog.Items.Count := BottleLog.Count;
108 if Sel >= 0 then begin
109 lvwLog.Selected := lvwLog.Items[Sel + 1];
110 lvwLog.Selected.Focused := true;
114 procedure TfrmLog.AddSystemLog(const MessageString: String);
115 var LogItem: TLogItem;
118 if lvwLog.Selected <> nil then Sel := lvwLog.Selected.Index else Sel := -1;
119 LogItem := TLogItem.Create(ltSystemLog, '', '', MessageString, '', Now());
120 BottleLog.Insert(0, LogItem);
121 lvwLog.Items.Count := BottleLog.Count;
123 if Sel >= 0 then begin
124 lvwLog.Selected := lvwLog.Items[Sel + 1];
125 lvwLog.Selected.Focused := true;
129 procedure TfrmLog.tbtnClearClick(Sender: TObject);
132 lvwLog.Items.Count := 0;
134 lvwLogChange(Self, nil, ctState);
137 procedure TfrmLog.FormCreate(Sender: TObject);
139 SsParser.TagPattern.Assign(frmSender.SsParser.TagPattern);
140 SsParser.MetaPattern.Assign(frmSender.SsParser.MetaPattern);
142 with Pref.LogWindowPosition do begin
145 Self.Width := Right - Left + 1;
146 Self.Height := Bottom - Top + 1;
148 edtScript.Height := Pref.LogWindowDividerPos;
151 procedure TfrmLog.FormDestroy(Sender: TObject);
153 with Pref.LogWindowPosition do begin
156 Right := Self.Left + Self.Width - 1;
157 Bottom := Self.Top + Self.Height - 1;
159 Pref.LogWindowDividerPos := edtScript.Height;
162 procedure TfrmLog.lvwLogChange(Sender: TObject; Item: TListItem;
163 Change: TItemChange);
167 StatusBar.Panels[0].Text := IntToStr(lvwLog.Items.Count) + '
\8c\8f';
168 if Change = ctState then begin
170 if lvwLog.Selected <> nil then begin
171 Log := BottleLog.Bottles[Item.Index];
172 if Log.LogType = ltBottle then begin
173 Script := Log.Script;
174 frmSender.actVoteMessage.Enabled := true;
175 frmSender.actAgreeMessage.Enabled := true;
176 mnPopUpCopyScript.Enabled := true;
178 frmSender.actVoteMessage.Enabled := false;
179 frmSender.actAgreeMessage.Enabled := false;
180 mnPopUpCopyScript.Enabled := false;
183 frmSender.actVoteMessage.Enabled := false;
184 frmSender.actAgreeMessage.Enabled := false;
185 mnPopUpCopyScript.Enabled := false;
187 frmSender.DoTrans(Script, [toConvertURL]);
188 if Pref.ColorScript then begin
189 UpdateScriptColor(Script);
191 UpdateScriptNoColor(Script);
194 tbtnSaveLog.Enabled := lvwLog.Items.Count > 0;
197 procedure TfrmLog.lvwLogDblClick(Sender: TObject);
199 Opt: TScriptTransOptions;
200 SOpt: TSstpSendOptions;
204 if lvwLog.Selected = nil then Exit;
205 //Log := TLogItem(lvwLog.Selected.Data);
206 Log := BottleLog.Bottles[lvwLog.Selected.Index];
207 if Log = nil then Exit;
208 if Log.LogType <> ltBottle then Exit;
209 Script := Log.Script;
210 Opt := [toConvertURL, toWaitScriptEnd];
211 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
212 if Pref.IgnoreFrequentYenS then Opt := Opt + [toIgnoreFrequentYenS];
213 frmSender.DoTrans(Script, Opt);
215 Ghost := frmSender.GetChannelPrefs(Log.Channel).TargetGhost;
216 if Ghost = '' then //
\83`
\83\83\83\93\83l
\83\8b\8ew
\92è
\83S
\81[
\83X
\83g
217 if frmSender.ChannelList.Channel[Log.Channel] <> nil then
218 Ghost := frmSender.ChannelList.Channel[Log.Channel].Ghost;
219 //
\96Ú
\95W
\83S
\81[
\83X
\83g
\8c\88\92è
220 if Log.Ghost <> '' then Ghost := Log.Ghost;
221 if frmSender.GetChannelPrefs(Log.Channel).IgnoreIfGhost then
222 Ghost := frmSender.GetChannelPrefs(Log.Channel).TargetGhost;
223 //
\83^
\81[
\83Q
\83b
\83g
\83S
\81[
\83X
\83g
\8am
\92è
224 Ghost := frmSender.SetHWndToFavoriteGhost(Ghost);
225 frmSender.FastSstp.SstpSender := 'SSTP Bottle -
\81y
\83\8d\83O
\8dÄ
\90¶
\81z';
226 if Pref.NoTranslate then SOpt := [soNoTranslate] else SOpt := [];
227 frmSender.FastSstp.SstpSEND(Script, SOpt, frmSender.GhostNameToSetName(Ghost));
230 procedure TfrmLog.UpdateScriptColor(const Script: String);
232 UnyuTalking, Talked: boolean;
234 SsParser.LeaveEscape := false;
235 SsParser.InputString := Script;
236 SsParser.LeaveEscape := true;
237 UnyuTalking := false;
238 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
239 edtScript.Text := '';
240 edtScript.Color := Pref.BgColor;
241 for i := 0 to SsParser.Count-1 do begin
242 if (SsParser[i] = '\u') and not UnyuTalking then begin
245 edtScript.SelText := #13#10;
249 if (SsParser[i] = '\h') and UnyuTalking then begin
250 UnyuTalking := false;
252 edtScript.SelText := #13#10;
256 if SsParser.MarkUpType[i] = mtStr then begin
258 edtScript.SelAttributes.Color := Pref.TalkColorU
260 edtScript.SelAttributes.Color := Pref.TalkColorH;
261 edtScript.SelText := SsParser[i];
264 if SsParser.MarkUpType[i] = mtMeta then begin
265 edtScript.SelAttributes.Color := Pref.MetaWordColor;
266 edtScript.SelText := SsParser[i];
272 procedure TfrmLog.UpdateScriptNoColor(const Script: String);
275 UnyuTalking, Talked, LastUnyuTalked: boolean;
277 SsParser.LeaveEscape := false;
278 SsParser.InputString := Script;
279 SsParser.LeaveEscape := true;
280 edtScript.Text := '';
281 edtScript.Color := clWindow;
282 edtScript.DefAttributes.Color := clWindowText;
283 edtScript.SelAttributes.Color := clWindowText;
285 UnyuTalking := false;
286 LastUnyuTalked := false;
287 for i := 0 to SsParser.Count-1 do begin
288 if (SsParser[i] = '\u') and not UnyuTalking then begin
291 if (SsParser[i] = '\h') and UnyuTalking then begin
292 UnyuTalking := false;
294 if SsParser.MarkUpType[i] in [mtStr, mtMeta] then begin
295 if not Talked then begin
296 if UnyuTalking then Scr := '
\82¤:' else Scr := '
\82³:';
298 if Talked and (UnyuTalking <> LastUnyuTalked) then begin
300 if UnyuTalking then Scr := Scr + '
\82¤:' else Scr := Scr + '
\82³:';
302 Scr := Scr + SsParser[i];
304 LastUnyuTalked := UnyuTalking;
307 edtScript.Text := Scr;
310 procedure TfrmLog.lvwLogKeyPress(Sender: TObject; var Key: Char);
312 if Key = #13 then lvwLogDblClick(Sender);
315 procedure TfrmLog.CreateParams(var Params: TCreateParams);
318 Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
321 procedure TfrmLog.lvwLogClick(Sender: TObject);
324 Selected := Selected;
327 procedure TfrmLog.mnSaveLogClick(Sender: TObject);
329 DoSaveLog(stLog, 'log', 1);
332 procedure TfrmLog.lvwLogColumnClick(Sender: TObject; Column: TListColumn);
333 var SortType: TBottleLogSortType;
335 if SortColumn = Column.Index then
336 SortDesc := not SortDesc
338 SortColumn := Column.Index;
342 -1: SortType := stLogTime;
343 subChannel: SortType := stChannel;
344 subVotes: SortType := stVote;
345 subAgrees: SortType := stAgree;
346 subScript: SortType := stScript;
347 else SortType := stLogTime;
349 BottleLog.SortBottles(SortType, SortDesc);
354 procedure TfrmLog.mnPopUpCopyScriptClick(Sender: TObject);
359 Log := BottleLog.Bottles[frmLog.lvwLog.Selected.Index];
360 if Log = nil then Exit;
362 Clip.SetTextBuf(PChar(Log.Script));
365 procedure TfrmLog.SetBottleStatusToOpened(const MID: String);
367 if BottleLog.Bottle(MID) <> nil then begin
368 BottleLog.Bottle(MID).State := lsOpened;
373 procedure TfrmLog.SetBottleStatusToPlaying(const MID: String);
375 if BottleLog.Bottle(MID) <> nil then begin
376 BottleLog.Bottle(MID).State := lsPlaying;
381 procedure TfrmLog.DoSaveLog(SaveType: TSaveLogType; Ext: String; Filter: integer);
388 DayStr: array[1..7] of String = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
390 SaveDialog.InitialDir := ExtractFileDir(Application.ExeName);
391 SaveDialog.DefaultExt := Ext;
392 SaveDialog.FilterIndex := Filter;
393 if SaveDialog.Execute then begin
396 Log := TStringList.Create;
398 stLog, stLogWithChannels: begin
399 for i := 0 to BottleLog.Count -1 do begin
400 LogItem := BottleLog.Bottles[i];
401 if LogItem = nil then Continue;
402 if LogItem.LogType <> ltBottle then Continue;
403 Date := FormatDateTime('yyyy/mm/dd hh:nn:ss ', LogItem.LogTime);
404 Date := Date + '(' + DayStr[DayOfWeek(LogItem.LogTime)] + ')';
405 if SaveType = stLogWithChannels then
406 Date := Date + ',' + LogItem.Channel +',SEND,' + LogItem.Script
408 Date := Date + ',0.0.0.0,SEND,' + LogItem.Script;
413 for i := 0 to BottleLog.Count -1 do begin
414 LogItem := BottleLog.Bottles[i];
415 if LogItem = nil then Continue;
416 if LogItem.LogType <> ltBottle then Continue;
417 Log.Add(LogItem.Script);
421 Log.Add('<?xml version=''1.0'' encoding=''Shift_JIS''?>');
422 Log.Add('<bottlelog>');
423 for i := 0 to BottleLog.Count -1 do begin
424 LogItem := BottleLog.Bottles[i];
425 if LogItem = nil then Continue;
426 if LogItem.LogType <> ltBottle then Continue;
427 Date := FormatDateTime('yyyy/mm/dd hh:nn:ss', LogItem.LogTime);
428 Log.Add(Format('<message mid=''%s''>', [LogItem.MID]));
429 Log.Add('<date>' + Date + '</date>');
430 Log.Add('<channel>' + LogItem.Channel + '</channel>');
432 TmpScript := LogItem.Script;
433 TmpScript := StringReplace(TmpScript, '<', '<', [rfReplaceAll]);
434 TmpScript := StringReplace(TmpScript, '>', '>', [rfReplaceAll]);
435 Log.Add('<script>' + TmpScript + '</script>');
437 if LogItem.Ghost = '' then
440 TmpScript := LogItem.Ghost;
441 TmpScript := StringReplace(TmpScript, '<', '<', [rfReplaceAll]);
442 TmpScript := StringReplace(TmpScript, '>', '>', [rfReplaceAll]);
443 Log.Add(Format('<ghost>%s</ghost>', [TmpScript]));
445 Log.Add('</message>');
447 Log.Add('</bottlelog>');
450 Log.SaveToFile(SaveDialog.FileName);
457 procedure TfrmLog.mnSaveLogChannelClick(Sender: TObject);
459 DoSaveLog(stLogWithChannels, 'log', 1);
462 procedure TfrmLog.mnSaveLogScriptClick(Sender: TObject);
464 DoSaveLog(stText, 'txt', 2);
467 procedure TfrmLog.mnSaveLogXMLClick(Sender: TObject);
469 DoSaveLog(stXML, 'xml', 3);
472 procedure TfrmLog.lvwLogData(Sender: TObject; Item: TListItem);
477 Log := BottleLog.Bottles[i];
479 Caption := FormatDateTime('yy/mm/dd hh:nn:ss', Log.LogTime);
481 if Log.Ghost <> '' then
482 SubItems.Add(Log.Channel + '/' + Log.Ghost)
484 SubItems.Add(Log.Channel);
485 SubItems.Add(IntToStr(Log.Votes));
486 SubItems.Add(IntToStr(Log.Agrees));
487 SubItems.Add(Log.Script);
489 if Log.LogType = ltBottle then begin
491 lsUnopened: ImageIndex := IconBottle;
492 lsPlaying: ImageIndex := IconPlaying;
493 lsOpened: ImageIndex := IconOpened;
496 ImageIndex := IconSystemLog;
500 procedure TfrmLog.UpdateWindow;
502 lvwLog.Items.Count := BottleLog.Count;
504 lvwLogChange(Self, lvwLog.Selected, ctState);
507 procedure TfrmLog.PopupMenuListViewPopup(Sender: TObject);
513 for i := 0 to mnJumpURL.Count-1 do begin
514 mnJumpURL.Items[i].Free;
516 mnJumpURL.Enabled := false;
517 if lvwLog.Selected = nil then Exit;
518 Log := BottleLog.Bottles[lvwLog.Selected.Index];
519 if Log = nil then Exit;
522 Urls := TStringList.Create;
523 ExtractURLs(Log.Script, Urls);
524 for i := 0 to Urls.Count-1 do begin
525 Child := TMenuItem.Create(Self);
527 Caption := Format('(&%d) %s', [i+1, Urls[i]]);
528 OnClick := mnURLClick;
529 AutoHotkeys := maManual;
530 mnJumpURL.Add(Child);
533 mnJumpURL.Enabled := Urls.Count > 0;
539 procedure TfrmLog.mnURLClick(Sender: TObject);
542 URL := (Sender as TMenuItem).Caption;
543 RegExp.Subst('s/^\(&?\d\) //', URL);
544 ShellExecute(Handle, 'open', PChar(URL), nil, nil, SW_SHOW);
547 procedure TfrmLog.ExtractURLs(Script: String; Result: TStrings);
548 var i, u, j: integer;
552 SsParser.LeaveEscape := false;
553 SsParser.InputString := Script;
554 SsParser.LeaveEscape := true;
555 for i := 0 to SsParser.Count-1 do begin
556 if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
557 for u := 7 downto 1 do begin
558 if (SsParser.Match(SsParser[i],
559 '\URL%b'+StringReplace(StringOfChar('-', u*2),
560 '-', '%b', [rfReplaceAll]))) > 0 then begin
561 for j := 1 to u do begin
562 s := SsParser.GetParam(SsParser[i], j*2);
563 if Pos('http://', s) > 0 then Result.Add(s);
568 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
569 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
570 s := SsParser.GetParam(SsParser[i], 1);
571 if Pos('http://', s) > 0 then Result.Add(s);