コミットメタ情報

リビジョンe7d3dc7047b67639ea6a312e2e4df97f686f5da6 (tree)
日時2014-12-09 21:23:10
作者zako <zako@user...>
コミッターzako

ログメッセージ

・NGワードで特定の板限定、スレ限定ができるよう変更
・NGワード編集画面で板指定、スレ指定をできるよう変更
・まちBBSのスレ一覧取得、スレ取得の新APIに対応
・プラグインを使用するBBS(まちBBS、したらば)で「送信してもウィンドウを閉じない」が機能しない不具合を修正

変更サマリ

差分

--- a/AbonInfo.pas
+++ b/AbonInfo.pas
@@ -2,6 +2,9 @@ unit AbonInfo;
22
33 interface
44
5+uses
6+ SysUtils;
7+
58 type
69 TAbonType = (atStandard, stTransparent);
710 TCompType = (ctStandard, ctRegexp);
@@ -20,8 +23,78 @@ type
2023 procedure Copy(const Src: TLineInfo);
2124 end;
2225
26+ TAbonThread = class(TObject)
27+ public
28+ Is2ch: Boolean;
29+ Board: String;
30+ Thread: String;
31+ constructor Create;
32+ procedure Clear;
33+ function IsTarget(Chk: String): Boolean;
34+ end;
35+
36+const
37+ DEF_REGEXP: String = '{{REGEXP}}';
38+ DEF_THREAD: String = '{{THREAD:';
39+ DEF_BOARD: String = '{{BOARD:';
40+ DEF_END: String = '}}';
41+
2342 implementation
2443
44+constructor TAbonThread.Create;
45+begin
46+ Is2ch := False;
47+end;
48+
49+procedure TAbonThread.Clear;
50+begin
51+ Is2ch := False;
52+ Board := '';
53+ Thread := '';
54+end;
55+
56+function TAbonThread.IsTarget(Chk: String): Boolean;
57+var
58+ Target: String;
59+ EndPos: Integer;
60+ CopyLen: Integer;
61+ DefLen: Integer;
62+begin
63+ EndPos := AnsiPos(DEF_END, Chk);
64+ if (EndPos < 1) then begin
65+ Result := True; // 指定形式と違うので対象
66+ end
67+ else if (AnsiPos(DEF_BOARD, Chk) = 1) then begin
68+ if (Is2ch = False) then begin
69+ Result := False; // 2chでない
70+ end else begin
71+ DefLen := Length(DEF_BOARD);
72+ CopyLen := EndPos - DefLen - 1;
73+ Target := Copy(Chk, DefLen + 1, CopyLen);
74+ if (Target = Board) then
75+ Result := True // 対象の板
76+ else
77+ Result := False; // 対象の板ではない
78+ end;
79+ end
80+ else if (AnsiPos(DEF_THREAD, Chk) = 1) then begin
81+ if (Is2ch = False) then begin
82+ Result := False; // 2chでない
83+ end else begin
84+ DefLen := Length(DEF_THREAD);
85+ CopyLen := EndPos - DefLen - 1;
86+ Target := Copy(Chk, DefLen + 1, CopyLen);
87+ if (Target = Board + '/' + Thread) then
88+ Result := True // 対象のスレ
89+ else
90+ Result := False; // 対象のスレではない
91+ end;
92+ end
93+ else begin
94+ Result := True; // 指定形式と違うので対象
95+ end;
96+end;
97+
2598 constructor TLineInfo.Create;
2699 begin
27100 AbonType := atStandard;
--- a/AbonInfoSet.dfm
+++ b/AbonInfoSet.dfm
@@ -4,7 +4,7 @@ object AbonInfoEdit: TAbonInfoEdit
44 BorderIcons = [biSystemMenu]
55 BorderStyle = bsDialog
66 Caption = 'NG'#12527#12540#12489#35373#23450
7- ClientHeight = 349
7+ ClientHeight = 350
88 ClientWidth = 439
99 Color = clBtnFace
1010 Font.Charset = SHIFTJIS_CHARSET
@@ -64,7 +64,6 @@ object AbonInfoEdit: TAbonInfoEdit
6464 Width = 113
6565 Height = 17
6666 Caption = #12473#12524#25351#23450
67- Enabled = False
6867 TabOrder = 1
6968 OnClick = TargetRadioClick
7069 end
@@ -74,41 +73,62 @@ object AbonInfoEdit: TAbonInfoEdit
7473 Width = 113
7574 Height = 17
7675 Caption = #26495#25351#23450
77- Enabled = False
7876 TabOrder = 2
7977 OnClick = TargetRadioClick
8078 end
8179 object ThrNameEdit: TEdit
82- Left = 32
80+ Left = 24
8381 Top = 60
84- Width = 361
82+ Width = 334
8583 Height = 20
8684 Color = clBtnFace
85+ ReadOnly = True
8786 TabOrder = 3
8887 end
89- object ThrInfoEdit: TEdit
90- Left = 32
88+ object ThrIDEdit: TEdit
89+ Left = 24
9190 Top = 80
92- Width = 361
91+ Width = 334
9392 Height = 20
9493 Color = clBtnFace
94+ ReadOnly = True
9595 TabOrder = 4
9696 end
9797 object BrdNameEdit: TEdit
98- Left = 32
98+ Left = 24
9999 Top = 124
100- Width = 361
100+ Width = 334
101101 Height = 20
102102 Color = clBtnFace
103- TabOrder = 5
103+ ReadOnly = True
104+ TabOrder = 6
104105 end
105- object BrdInfoEdit: TEdit
106- Left = 32
106+ object BrdIDEdit: TEdit
107+ Left = 24
107108 Top = 144
108- Width = 361
109+ Width = 334
109110 Height = 20
110111 Color = clBtnFace
111- TabOrder = 6
112+ ReadOnly = True
113+ TabOrder = 7
114+ end
115+ object ThrSelButton: TButton
116+ Left = 360
117+ Top = 60
118+ Width = 40
119+ Height = 25
120+ Caption = #36984#25246
121+ TabOrder = 5
122+ OnClick = ThrSelButtonClick
123+ end
124+ object BrdSelButton: TButton
125+ Left = 360
126+ Top = 124
127+ Width = 40
128+ Height = 25
129+ Caption = #36984#25246
130+ TabOrder = 8
131+ OnClick = BrdSelButtonClick
112132 end
113133 end
114134 object OkButton: TButton
--- a/AbonInfoSet.pas
+++ b/AbonInfoSet.pas
@@ -15,19 +15,25 @@ type
1515 ThreadRadio: TRadioButton;
1616 BoardRadio: TRadioButton;
1717 ThrNameEdit: TEdit;
18- ThrInfoEdit: TEdit;
18+ ThrIDEdit: TEdit;
1919 BrdNameEdit: TEdit;
20- BrdInfoEdit: TEdit;
20+ BrdIDEdit: TEdit;
2121 OkButton: TButton;
2222 CancelButton: TButton;
23+ ThrSelButton: TButton;
24+ BrdSelButton: TButton;
2325 procedure FormShow(Sender: TObject);
2426 procedure TargetRadioClick(Sender: TObject);
2527 procedure OkButtonClick(Sender: TObject);
2628 procedure FormCreate(Sender: TObject);
2729 procedure FormDestroy(Sender: TObject);
30+ procedure ThrSelButtonClick(Sender: TObject);
31+ procedure BrdSelButtonClick(Sender: TObject);
2832 private
2933 { Private 宣言 }
3034 FInf: TLineInfo;
35+ function GetThreadTitle(SrcID: String): String;
36+ function GetBoardTitle(BrdID: String): String;
3137 public
3238 { Public 宣言 }
3339
@@ -40,6 +46,8 @@ var
4046
4147 implementation
4248
49+uses BoardGroup, BbsThrSel, GikoSystem;
50+
4351 {$R *.dfm}
4452
4553
@@ -87,39 +95,133 @@ begin
8795 end;
8896
8997 case FInf.TargetType of
90- ttAll: AllRadio.Checked := True;
91- ttThread: ThreadRadio.Checked := True;
92- ttBoard: BoardRadio.Checked := True;
98+ ttAll: begin
99+ AllRadio.Checked := True;
100+ end;
101+ ttThread: begin
102+ ThreadRadio.Checked := True;
103+ ThrNameEdit.Text := GetThreadTitle(FInf.TargetThread);
104+ ThrIDEdit.Text := FInf.TargetThread;
105+ end;
106+ ttBoard: begin
107+ BoardRadio.Checked := True;
108+ BrdNameEdit.Text := GetBoardTitle(FInf.TargetBoard);
109+ BrdIDEdit.Text := FInf.TargetBoard;
110+ end;
93111 end;
94112
95- ThrInfoEdit.Text := FInf.TargetThread;
96- BrdInfoEdit.Text := FInf.TargetBoard;
97-
98113 TargetRadioClick(AllRadio);
99114 end;
100115
116+function TAbonInfoEdit.GetThreadTitle(SrcID: String): String;
117+var
118+ ThrID: String;
119+ BrdID: String;
120+ Sep: Integer;
121+ i: Integer;
122+ j: Integer;
123+ Brd: TBoard;
124+begin
125+ Result := '';
126+
127+ if (SrcID = '') then
128+ Exit;
129+
130+ Sep := Pos('/', SrcID);
131+ if (Sep <= 0) then
132+ Exit;
133+
134+ BrdID := Copy(SrcID, 1, Sep - 1);
135+ ThrID := Copy(SrcID, Sep + 1, Length(SrcID) - Sep);
136+
137+ Brd := nil;
138+ if (BBSs[0].IsBoardFileRead = False) then
139+ GikoSys.ReadBoardFile(BBSs[0]);
140+ for i := 0 to BBSs[0].Count - 1 do begin
141+ for j := 0 to BBSs[0].Items[i].Count - 1 do begin
142+ if (BrdID = BBSs[0].Items[i].Items[j].BBSID) then begin
143+ Brd := BBSs[0].Items[i].Items[j];
144+ Result := Brd.Title + '/';
145+ Break;
146+ end;
147+ end;
148+ end;
149+
150+ if (Brd <> nil) then begin
151+ if (Brd.IsThreadDatRead = False) then
152+ GikoSys.ReadSubjectFile(Brd);
153+ for i := 0 to Brd.Count - 1 do begin
154+ if (ThrID = ChangeFileExt(Brd.Items[i].FileName, '')) then begin
155+ Result := Result + Brd.Items[i].Title;
156+ Break;
157+ end;
158+ end;
159+ end;
160+end;
161+
162+
163+function TAbonInfoEdit.GetBoardTitle(BrdID: String): String;
164+var
165+ i: Integer;
166+ j: Integer;
167+begin
168+ Result := '';
169+
170+ if (BrdID = '') then
171+ Exit;
172+
173+ if (BBSs[0].IsBoardFileRead = False) then
174+ GikoSys.ReadBoardFile(BBSs[0]);
175+ for i := 0 to BBSs[0].Count - 1 do begin
176+ for j := 0 to BBSs[0].Items[i].Count - 1 do begin
177+ if (BrdID = BBSs[0].Items[i].Items[j].BBSID) then begin
178+ Result := BBSs[0].Items[i].Items[j].Title;
179+ Break;
180+ end;
181+ end;
182+ end;
183+end;
184+
101185 procedure TAbonInfoEdit.TargetRadioClick(Sender: TObject);
102186 begin
103187 if (ThreadRadio.Checked = True) then begin
104188 ThrNameEdit.Enabled := True;
105- ThrInfoEdit.Enabled := True;
189+ ThrIDEdit.Enabled := True;
190+ ThrSelButton.Enabled := True;
106191 BrdNameEdit.Enabled := False;
107- BrdInfoEdit.Enabled := False;
192+ BrdIDEdit.Enabled := False;
193+ BrdSelButton.Enabled := False;
108194 end else if (BoardRadio.Checked = True) then begin
109195 ThrNameEdit.Enabled := False;
110- ThrInfoEdit.Enabled := False;
196+ ThrIDEdit.Enabled := False;
197+ ThrSelButton.Enabled := False;
111198 BrdNameEdit.Enabled := True;
112- BrdInfoEdit.Enabled := True;
199+ BrdIDEdit.Enabled := True;
200+ BrdSelButton.Enabled := True;
113201 end else begin
114202 ThrNameEdit.Enabled := False;
115- ThrInfoEdit.Enabled := False;
203+ ThrIDEdit.Enabled := False;
204+ ThrSelButton.Enabled := False;
116205 BrdNameEdit.Enabled := False;
117- BrdInfoEdit.Enabled := False;
206+ BrdIDEdit.Enabled := False;
207+ BrdSelButton.Enabled := False;
118208 end;
119209 end;
120210
121211 procedure TAbonInfoEdit.OkButtonClick(Sender: TObject);
122212 begin
213+ if (ThreadRadio.Checked = True) then begin
214+ if (ThrIDEdit.Text = '') then begin
215+ Application.MessageBox('対象のスレッドを指定したください。', PChar(Caption), MB_OK or MB_ICONERROR);
216+ Exit;
217+ end;
218+ end else if (BoardRadio.Checked = True) then begin
219+ if (BrdIDEdit.Text = '') then begin
220+ Application.MessageBox('対象の板を指定したください。', PChar(Caption), MB_OK or MB_ICONERROR);
221+ Exit;
222+ end;
223+ end;
224+
123225 if (AbonTypeRadio.ItemIndex = 1) then
124226 FInf.AbonType := stTransparent
125227 else
@@ -137,10 +239,43 @@ begin
137239 else
138240 FInf.TargetType := ttAll;
139241
140- FInf.TargetThread := ThrInfoEdit.Text;
141- FInf.TargetBoard := BrdInfoEdit.Text;
242+ FInf.TargetThread := ThrIDEdit.Text;
243+ FInf.TargetBoard := BrdIDEdit.Text;
142244
143245 ModalResult := mrOk;
144246 end;
145247
248+procedure TAbonInfoEdit.ThrSelButtonClick(Sender: TObject);
249+var
250+ Dlg: TBbsThreadSel;
251+ Sep: Integer;
252+begin
253+ Dlg := TBbsThreadSel.Create(Self);
254+ Dlg.ThreadMode := True;
255+ Sep := Pos('/', ThrIDEdit.Text);
256+ if (Sep > 0) then begin
257+ Dlg.BoardID := Copy(ThrIDEdit.Text, 1, Sep - 1);
258+ Dlg.ThreadID := Copy(ThrIDEdit.Text, Sep + 1, Length(ThrIDEdit.Text) - Sep);
259+ end;
260+ if (Dlg.ShowModal = mrOk) then begin
261+ ThrNameEdit.Text := Dlg.BoardTitle + '/' + Dlg.ThreadTitle;
262+ ThrIDEdit.Text := Dlg.BoardID + '/' + Dlg.ThreadID;
263+ end;
264+ Dlg.Free;
265+end;
266+
267+procedure TAbonInfoEdit.BrdSelButtonClick(Sender: TObject);
268+var
269+ Dlg: TBbsThreadSel;
270+begin
271+ Dlg := TBbsThreadSel.Create(Self);
272+ Dlg.ThreadMode := False;
273+ Dlg.BoardID := BrdIDEdit.Text;
274+ if (Dlg.ShowModal = mrOk) then begin
275+ BrdNameEdit.Text := Dlg.BoardTitle;
276+ BrdIDEdit.Text := Dlg.BoardID;
277+ end;
278+ Dlg.Free;
279+end;
280+
146281 end.
--- a/AbonUnit.pas
+++ b/AbonUnit.pas
@@ -8,7 +8,7 @@ unit AbonUnit;
88 interface
99 uses
1010 Windows,Messages, ShellAPI, SysUtils, Classes,StdCtrls,StrUtils,
11- Forms, Controls;
11+ Forms, Controls, AbonInfo;
1212
1313 type
1414 TIndiviAbon = class( TObject )
@@ -91,11 +91,11 @@ type
9191 function LoadFromNGwordFile(path :String) : Boolean;
9292 function ReLoadFromNGwordFile() : Boolean;
9393 procedure LoadFromStringList( bufstl : TStringList );
94- function CheckAbonPopupRes(line : String) :Boolean;
95- function FindNGwords(const line : String; var NGwordsLineNum : Integer; var Invisible : Boolean) : Boolean;//1ラインずつ用。
94+ function CheckAbonPopupRes(line : String; ThreadInfo: TAbonThread) :Boolean;
95+ function FindNGwords(const line : String; var NGwordsLineNum : Integer; var Invisible : Boolean; ThreadInfo: TAbonThread) : Boolean;//1ラインずつ用。
9696 //あぼ〜ん処理(NGワードでのフィルタリング)
97- procedure Execute(var ThreadStrings : TStringList); overload;
98- procedure Execute(var ResString : String; ResNumber : Integer); overload; //主にpluginからのDat To HTML 用
97+ procedure Execute(var ThreadStrings : TStringList; ThreadInfo: TAbonThread); overload;
98+ procedure Execute(var ResString : String; ResNumber : Integer; ThreadInfo: TAbonThread); overload; //主にpluginからのDat To HTML 用
9999
100100 {$IFDEF SPAM_FILTER_ENABLED}
101101 //! スパムフィルタの学習
@@ -122,7 +122,6 @@ var
122122 Abon1 :TAbon;
123123 const
124124 NGwordListFileName : String = 'NGwords.list';
125- DEF_REGEXP: String = '{{REGEXP}}';
126125
127126 implementation
128127
@@ -380,6 +379,7 @@ var
380379 pos : Integer;
381380 buftoken : String;
382381 RegExp: Boolean;
382+ Target: String;
383383 begin
384384 bufstl := TStringList.Create;
385385 RegExp := False;
@@ -390,12 +390,17 @@ begin
390390 buftoken := Copy(argline,1,pos-1);
391391 Delete(argline,1,pos);
392392 if Length(buftoken) > 0 then begin
393+ // 正規表現
393394 if (buftoken = DEF_REGEXP) then begin
394395 RegExp := True;
395- end else
396+ // 板・スレ指定
397+ end else if ((AnsiPos(DEF_THREAD, buftoken) = 1) or
398+ (AnsiPos(DEF_BOARD, buftoken) = 1)) and
399+ (AnsiPos(DEF_END, buftoken) > 1) then begin
400+ Target := buftoken;
396401 // >> で始まるトークンはコメント扱いで無視する
397- if AnsiPos('>>', buftoken) <> 1 then begin
398- bufstl.Append(buftoken);
402+ end else if AnsiPos('>>', buftoken) <> 1 then begin
403+ bufstl.Append(buftoken);
399404 end;
400405 end else if ( bufstl.Count = 0 ) then begin
401406 bufstl.Append('');
@@ -408,31 +413,26 @@ begin
408413 bufstl.Append(argline);
409414 end;
410415 end;
416+ // 各種指定の順位:透明→板・スレ→正規表現
417+ if (RegExp = True) then begin
418+ if (bufstl.Count > 0) and (bufstl.Strings[0] = '') then
419+ bufstl.Insert(1, DEF_REGEXP) // 透明指定の後に正規表現指定を置く
420+ else
421+ bufstl.Insert(0, DEF_REGEXP); // 正規表現指定は先頭に置く
422+ end;
423+ if (Target <> '') then begin
424+ if (bufstl.Count > 0) and (bufstl.Strings[0] = '') then
425+ bufstl.Insert(1, Target) // 透明指定の後に板・スレ指定を置く
426+ else
427+ bufstl.Insert(0, Target); // 板・スレ指定は先頭に置く
428+ end;
411429 ret := bufstl.Count;
412- if (RegExp = True) then
413- ret := ret + 1;
414430 SetLength(Ftokens[index],ret);
415431 for i := 0 to ret - 1 do begin
416- if (RegExp = True) then begin
417- if (i = 0) then begin
418- if (bufstl.Strings[0] = '') then
419- Ftokens[index][0] := ''
420- else
421- Ftokens[index][0] := DEF_REGEXP;
422- end else if (i = 1) then begin
423- if (bufstl.Strings[0] = '') then
424- Ftokens[index][1] := DEF_REGEXP
425- else
426- Ftokens[index][1] := bufstl.Strings[0];
427- end else begin
428- Ftokens[index][i] := bufstl.Strings[i - 1];
429- end;
430- end else begin
431- if IgnoreKana then
432- Ftokens[index][i] := ZenToHan(bufstl.Strings[i])
433- else
434- Ftokens[index][i] := bufstl.Strings[i];
435- end;
432+ if IgnoreKana then
433+ Ftokens[index][i] := ZenToHan(bufstl.Strings[i])
434+ else
435+ Ftokens[index][i] := bufstl.Strings[i];
436436 end;
437437 end;
438438 finally
@@ -459,7 +459,7 @@ begin
459459 end;
460460 //NGワードが含まれていたらtrueを返し、そのNGワードの行数をNGwordsLineNumに入れて返す。
461461 //もしも透明あぼ〜んにするならInbisibleをtrueにして返す
462-function TAbon.FindNGwords(const line : String; var NGwordsLineNum : Integer; var Invisible : Boolean) : Boolean; //1ラインずつ用。
462+function TAbon.FindNGwords(const line : String; var NGwordsLineNum : Integer; var Invisible : Boolean; ThreadInfo: TAbonThread) : Boolean; //1ラインずつ用。
463463 var
464464 lines : Integer;
465465 cells : Integer;
@@ -474,6 +474,9 @@ var
474474 AWKStr: TAWKStr;
475475 RStart: Integer;
476476 RLength: Integer;
477+ TokenCnt: Integer;
478+ Chk: Integer;
479+ CheckTarget: Boolean;
477480 begin
478481 hit := false;
479482 if AnsiStrPosEx(PChar(line), PChar(line)+Length(line), FpAbons, FpAbone) = nil then begin
@@ -484,36 +487,47 @@ begin
484487 target := line;
485488
486489 trgLen := Length(target);
487- RegExp := False;
488490 AWKStr := nil;
489491
490492 for lines := 0 to High(Ftokens) do begin
491493 if Length(Ftokens[lines]) = 0 then begin
492494 Continue;
493495 end;
494- hit := true;
496+ hit := False;
495497 bufline := target;
496498 pts := PChar(bufline);
497499 pte := pts + trgLen;
498-
499- if Ftokens[lines][0] <> '' then begin
500- Invisible := false;
501- if (Ftokens[lines][0] = DEF_REGEXP) then begin
502- RegExp := True;
503- start := 1;
500+ RegExp := False;
501+ Invisible := False;
502+ start := 0;
503+ CheckTarget := True;
504+
505+ TokenCnt := Length(Ftokens[lines]);
506+ for Chk := 0 to 2 do begin
507+ if (Chk >= TokenCnt) then
508+ Break;
509+ if (Chk = 0) and (Ftokens[lines][0] = '') then begin
510+ Invisible := True;
511+ start := 1;
512+ end else if ((AnsiPos(DEF_THREAD, Ftokens[lines][Chk]) = 1) or
513+ (AnsiPos(DEF_BOARD, Ftokens[lines][Chk]) = 1))
514+ and (AnsiPos(DEF_END, Ftokens[lines][Chk]) > 1) then begin
515+ CheckTarget := ThreadInfo.IsTarget(Ftokens[lines][Chk]);
516+ if (CheckTarget = False) then
517+ Break;
518+ Inc(start); // 対象の板・スレ
519+ end else if (Ftokens[lines][Chk] = DEF_REGEXP) then begin
520+ RegExp := True; // 正規表現
521+ Inc(start);
504522 end else begin
505- start := 0;
523+ Break;
506524 end;
507- end else begin
508- Invisible := true;
509- if (High(Ftokens) > 0) and (Ftokens[lines][1] = DEF_REGEXP) then begin
510- RegExp := True;
511- start := 2;
512- end else begin
513- start := 1;
514- end;
515- end;
525+ end;
526+ if (CheckTarget = False) then begin // 対象の板・スレではない
527+ Continue;
528+ end;
516529
530+ hit := True;
517531 if (RegExp = True) and (AWKStr = nil) then begin
518532 AWKStr := TAWKStr.Create(nil);
519533 end;
@@ -554,7 +568,7 @@ begin
554568 Result := hit;
555569 end;
556570 //末尾のブール値はtrueだと、NGワードを含むものだけを返す。
557-procedure TAbon.Execute(var ThreadStrings : TStringList);
571+procedure TAbon.Execute(var ThreadStrings : TStringList; ThreadInfo: TAbonThread);
558572 var
559573 i : Integer;
560574 NGwordsLine : Integer;
@@ -563,7 +577,7 @@ var
563577 begin
564578 for i:=0 to ThreadStrings.Count - 1 do begin
565579 NGwordsLine := 0;
566- if FindNGwords(ThreadStrings.Strings[i], NGwordsLine ,invisi) <> Reverse then begin
580+ if FindNGwords(ThreadStrings.Strings[i], NGwordsLine, invisi, ThreadInfo) <> Reverse then begin
567581 if invisi = true then begin
568582 ThreadStrings.Strings[i] := '';
569583 end else begin
@@ -593,14 +607,14 @@ begin
593607 end;
594608 end;
595609 end;
596-procedure TAbon.Execute(var ResString : String; ResNumber : Integer);
610+procedure TAbon.Execute(var ResString : String; ResNumber : Integer; ThreadInfo: TAbonThread);
597611 var
598612 NGwordsLine : Integer;
599613 bufline : String;
600614 invisi : Boolean;
601615 begin
602616 NGwordsLine := 0;
603- if FindNGwords(ResString, NGwordsLine ,invisi) <> Reverse then begin
617+ if FindNGwords(ResString, NGwordsLine, invisi, ThreadInfo) <> Reverse then begin
604618 if invisi = true then begin
605619 ResString := '';
606620 end else begin
@@ -658,13 +672,13 @@ begin
658672 Result := ReLoad;
659673 end;
660674 //ポップアップ用判定関数
661-function TAbon.CheckAbonPopupRes(line : String) :Boolean;
675+function TAbon.CheckAbonPopupRes(line : String; ThreadInfo: TAbonThread) :Boolean;
662676 var
663677 i: Integer;
664678 v: boolean;
665679 begin
666680 if AbonPopupRes = true then begin
667- Result := FindNGwords(line, i ,v);
681+ Result := FindNGwords(line, i, v, ThreadInfo);
668682 end else begin
669683 Result := false;
670684 end;
--- /dev/null
+++ b/BbsThrSel.dfm
@@ -0,0 +1,140 @@
1+object BbsThreadSel: TBbsThreadSel
2+ Left = 192
3+ Top = 133
4+ Width = 800
5+ Height = 554
6+ BorderIcons = [biSystemMenu, biMaximize]
7+ Caption = #26495#36984#25246
8+ Color = clBtnFace
9+ Constraints.MinHeight = 200
10+ Constraints.MinWidth = 550
11+ Font.Charset = SHIFTJIS_CHARSET
12+ Font.Color = clWindowText
13+ Font.Height = -12
14+ Font.Name = #65325#65331' '#65328#12468#12471#12483#12463
15+ Font.Style = []
16+ OldCreateOrder = False
17+ OnShow = FormShow
18+ PixelsPerInch = 96
19+ TextHeight = 12
20+ object PanelLeft: TPanel
21+ Left = 0
22+ Top = 0
23+ Width = 320
24+ Height = 516
25+ Align = alLeft
26+ BevelOuter = bvNone
27+ TabOrder = 0
28+ object PanelCat: TPanel
29+ Left = 0
30+ Top = 0
31+ Width = 140
32+ Height = 516
33+ Align = alLeft
34+ BevelOuter = bvNone
35+ TabOrder = 0
36+ object PanelCatHead: TPanel
37+ Left = 0
38+ Top = 0
39+ Width = 140
40+ Height = 17
41+ Align = alTop
42+ Caption = #12459#12486#12468#12522
43+ TabOrder = 0
44+ end
45+ object ListCat: TListBox
46+ Left = 0
47+ Top = 17
48+ Width = 140
49+ Height = 499
50+ Align = alClient
51+ ItemHeight = 12
52+ TabOrder = 1
53+ OnClick = ListCatClick
54+ end
55+ end
56+ object PanelBrd: TPanel
57+ Left = 140
58+ Top = 0
59+ Width = 180
60+ Height = 516
61+ Align = alClient
62+ BevelOuter = bvNone
63+ TabOrder = 1
64+ object PanelBrdHead: TPanel
65+ Left = 0
66+ Top = 0
67+ Width = 180
68+ Height = 17
69+ Align = alTop
70+ Caption = #26495
71+ TabOrder = 0
72+ end
73+ object ListBrd: TListBox
74+ Left = 0
75+ Top = 17
76+ Width = 180
77+ Height = 499
78+ Align = alClient
79+ ItemHeight = 12
80+ TabOrder = 1
81+ OnClick = ListBrdClick
82+ end
83+ end
84+ end
85+ object PanelRight: TPanel
86+ Left = 320
87+ Top = 0
88+ Width = 464
89+ Height = 516
90+ Align = alClient
91+ BevelOuter = bvNone
92+ TabOrder = 1
93+ object PanelThr: TPanel
94+ Left = 0
95+ Top = 0
96+ Width = 464
97+ Height = 44
98+ Align = alTop
99+ BevelOuter = bvNone
100+ TabOrder = 0
101+ OnResize = PanelThrResize
102+ object EditFilter: TEdit
103+ Left = 2
104+ Top = 21
105+ Width = 276
106+ Height = 20
107+ TabOrder = 0
108+ OnKeyPress = EditFilterKeyPress
109+ end
110+ object ButtonFilter: TButton
111+ Left = 280
112+ Top = 18
113+ Width = 40
114+ Height = 25
115+ Caption = #32094#36796
116+ TabOrder = 1
117+ OnClick = ButtonFilterClick
118+ end
119+ object PanelThrHead: TPanel
120+ Left = 0
121+ Top = 0
122+ Width = 464
123+ Height = 17
124+ Align = alTop
125+ Caption = #12473#12524#12483#12489
126+ TabOrder = 2
127+ end
128+ end
129+ object ListThr: TListBox
130+ Left = 0
131+ Top = 44
132+ Width = 464
133+ Height = 472
134+ Align = alClient
135+ ItemHeight = 12
136+ TabOrder = 1
137+ OnClick = ListThrClick
138+ end
139+ end
140+end
--- /dev/null
+++ b/BbsThrSel.pas
@@ -0,0 +1,245 @@
1+unit BbsThrSel;
2+
3+interface
4+
5+uses
6+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7+ Dialogs, ExtCtrls, StdCtrls;
8+
9+type
10+ TBbsThreadSel = class(TForm)
11+ PanelLeft: TPanel;
12+ PanelCat: TPanel;
13+ PanelCatHead: TPanel;
14+ ListCat: TListBox;
15+ PanelBrd: TPanel;
16+ PanelBrdHead: TPanel;
17+ ListBrd: TListBox;
18+ PanelRight: TPanel;
19+ PanelThr: TPanel;
20+ EditFilter: TEdit;
21+ ButtonFilter: TButton;
22+ PanelThrHead: TPanel;
23+ ListThr: TListBox;
24+ procedure FormShow(Sender: TObject);
25+ procedure ListCatClick(Sender: TObject);
26+ procedure ListBrdClick(Sender: TObject);
27+ procedure ListThrClick(Sender: TObject);
28+ procedure ButtonFilterClick(Sender: TObject);
29+ procedure PanelThrResize(Sender: TObject);
30+ procedure EditFilterKeyPress(Sender: TObject; var Key: Char);
31+ private
32+ { Private 宣言 }
33+ FThreadMode: Boolean; // True:スレ選択、False:板選択
34+ FBoardID: String; // 板ID(例:software)
35+ FBoardTitle: String; // 板タイトル(例:ソフトウェア)
36+ FThreadID: String; // スレID(例:1410888356)
37+ FThreadTitle: String; // スレタイトル(例:2ちゃんねる用ブラウザ「ギコナビ」 Part67)
38+ FInit: Boolean;
39+ public
40+ { Public 宣言 }
41+ property ThreadMode: Boolean write FThreadMode default False;
42+ property BoardID: String read FBoardID write FBoardID;
43+ property BoardTitle: String read FBoardTitle write FBoardTitle;
44+ property ThreadID: String read FThreadID write FThreadID;
45+ property ThreadTitle: String read FThreadTitle write FThreadTitle;
46+ end;
47+
48+var
49+ BbsThreadSel: TBbsThreadSel;
50+
51+implementation
52+
53+uses BoardGroup, GikoSystem, MojuUtils;
54+
55+{$R *.dfm}
56+
57+procedure TBbsThreadSel.FormShow(Sender: TObject);
58+var
59+ CenterForm: TCustomForm;
60+ i: Integer;
61+ j: Integer;
62+ Sel: Integer;
63+begin
64+ FInit := True;
65+
66+ if (FThreadMode = False) then begin
67+ Caption := '板選択';
68+ Self.Constraints.MinWidth := 330;
69+ PanelRight.Visible := False;
70+ Width := 326;
71+ PanelLeft.Align := alClient;
72+ end else begin
73+ Caption := 'スレッド選択';
74+ end;
75+
76+ CenterForm := TCustomForm(Owner);
77+ if Assigned(CenterForm) then begin
78+ Left := ((CenterForm.Width - Width) div 2) + CenterForm.Left;
79+ Top := ((CenterForm.Height - Height) div 2) + CenterForm.Top;
80+ end else begin
81+ Left := (Screen.Width - Width) div 2;
82+ Top := (Screen.Height - Height) div 2;
83+ end;
84+
85+ Sel := -1;
86+ if (BBSs[0].IsBoardFileRead = False) then
87+ GikoSys.ReadBoardFile(BBSs[0]);
88+ for i := 0 to BBSs[0].Count - 1 do begin
89+ ListCat.Items.Add(BBSs[0].Items[i].Title);
90+ if (Sel = -1) and (FBoardID <> '') then begin
91+ for j := 0 to BBSs[0].Items[i].Count - 1 do begin
92+ if (FBoardID = BBSs[0].Items[i].Items[j].BBSID) then begin
93+ Sel := i;
94+ Break;
95+ end;
96+ end;
97+ end;
98+ end;
99+
100+ if (Sel >= 0) then begin
101+ ListCat.ItemIndex := Sel;
102+ ListCatClick(ListCat);
103+ end;
104+
105+ FInit := False;
106+end;
107+
108+procedure TBbsThreadSel.ListCatClick(Sender: TObject);
109+var
110+ i: Integer;
111+ Idx: Integer;
112+ Sel: Integer;
113+ SelBrd: Boolean;
114+begin
115+ Idx := ListCat.ItemIndex;
116+ if (Idx >= 0) and (Idx < ListCat.Count) then begin
117+ if (FInit = True) and (FBoardID <> '') then
118+ SelBrd := True
119+ else
120+ SelBrd := False;
121+ Sel := -1;
122+ ListBrd.Clear;
123+ if (FThreadMode = True) then
124+ ListThr.Clear;
125+ for i := 0 to BBSs[0].Items[Idx].Count - 1 do begin
126+ ListBrd.Items.Add(BBSs[0].Items[Idx].Items[i].Title);
127+ if (SelBrd = True) and (Sel = -1) then begin
128+ if (FBoardID = BBSs[0].Items[Idx].Items[i].BBSID) then
129+ Sel := i;
130+ end;
131+ end;
132+ if (Sel >= 0) then begin
133+ ListBrd.ItemIndex := Sel;
134+ ListBrdClick(ListBrd);
135+ end;
136+ end;
137+end;
138+
139+procedure TBbsThreadSel.ListBrdClick(Sender: TObject);
140+var
141+ i: Integer;
142+ Idx1: Integer;
143+ Idx2: Integer;
144+ Brd: TBoard;
145+ IsFilt: Boolean;
146+ Filt: String;
147+ OldThr: TStringList;
148+begin
149+ Idx1 := ListCat.ItemIndex;
150+ Idx2 := ListBrd.ItemIndex;
151+ if (Idx1 >= 0) and (Idx1 < ListCat.Count) and
152+ (Idx2 >= 0) and (Idx2 < ListBrd.Count) then begin
153+ Brd := BBSs[0].Items[Idx1].Items[Idx2];
154+
155+ if (FThreadMode = False) then begin
156+ if (FInit = False) then begin
157+ FBoardID := Brd.BBSID;
158+ FBoardTitle := Brd.Title;
159+ ModalResult := mrOk;
160+ end;
161+ end else begin
162+ ListThr.Clear;
163+ OldThr := TStringList.Create;
164+ if (EditFilter.Text = '') then begin
165+ IsFilt := False;
166+ end else begin
167+ IsFilt := True;
168+ Filt := ZenToHan(EditFilter.Text);
169+ end;
170+
171+ if (Brd.IsThreadDatRead = False) then
172+ GikoSys.ReadSubjectFile(Brd);
173+ for i := 0 to Brd.Count - 1 do begin
174+ if (IsFilt = False) or
175+ ((IsFilt = True) and (AnsiPos(Filt, ZenToHan(Brd.Items[i].Title)) > 0)) then begin
176+ if (Brd.Items[i].AgeSage = gasArch) then // 過去ログ
177+ OldThr.AddObject(Brd.Items[i].Title, TObject(i))
178+ else
179+ ListThr.Items.AddObject(Brd.Items[i].Title, TObject(i));
180+ end;
181+ end;
182+ for i := OldThr.Count - 1 downto 0 do begin
183+ ListThr.Items.AddObject(OldThr.Strings[i], OldThr.Objects[i]);
184+ end;
185+ OldThr.Free;
186+ if (FInit = True) and (FThreadMode = True) and (FThreadID <> '') then begin
187+ for i := 0 to ListThr.Count - 1 do begin
188+ if (FThreadID = ChangeFileExt(Brd.Items[Integer(ListThr.Items.Objects[i])].FileName, '')) then begin
189+ ListThr.ItemIndex := i;
190+ Break;
191+ end;
192+ end;
193+ end;
194+ end;
195+ end;
196+end;
197+
198+procedure TBbsThreadSel.ListThrClick(Sender: TObject);
199+var
200+ Idx1: Integer;
201+ Idx2: Integer;
202+ Idx3: Integer;
203+ Idx4: Integer;
204+ Brd: TBoard;
205+begin
206+ if (FThreadMode = True) then begin
207+ Idx1 := ListCat.ItemIndex;
208+ Idx2 := ListBrd.ItemIndex;
209+ Idx3 := ListThr.ItemIndex;
210+ if (Idx1 >= 0) and (Idx1 < ListCat.Count) and
211+ (Idx2 >= 0) and (Idx2 < ListBrd.Count) and
212+ (Idx3 >= 0) and (Idx3 < ListThr.Count) then begin
213+ Brd := BBSs[0].Items[Idx1].Items[Idx2];
214+ Idx4 := Integer(ListThr.Items.Objects[Idx3]);
215+ if (Idx4 >= 0) and (Idx4 < Brd.Count) then begin
216+ FBoardID := Brd.BBSID;
217+ FBoardTitle := Brd.Title;
218+ FThreadID := ChangeFileExt(Brd.Items[Idx4].FileName, '');
219+ FThreadTitle := Brd.Items[Idx4].Title;
220+ ModalResult := mrOk;
221+ end;
222+ end;
223+ end;
224+end;
225+
226+procedure TBbsThreadSel.ButtonFilterClick(Sender: TObject);
227+begin
228+ ListBrdClick(ListBrd);
229+end;
230+
231+procedure TBbsThreadSel.PanelThrResize(Sender: TObject);
232+begin
233+ ButtonFilter.Left := PanelThr.Width - ButtonFilter.Width - 2;
234+ EditFilter.Width := ButtonFilter.Left - 4;
235+end;
236+
237+procedure TBbsThreadSel.EditFilterKeyPress(Sender: TObject; var Key: Char);
238+begin
239+ if (Integer(Key) = VK_RETURN) then begin
240+ Key := #0;
241+ ListBrdClick(ListBrd);
242+ end;
243+end;
244+
245+end.
--- a/Editor.pas
+++ b/Editor.pas
@@ -1255,7 +1255,8 @@ begin
12551255 SaveSendFile;
12561256 GikoForm.AddMessageList(FBoard.Title + ' ' + GikoSys.GetGikoMessage(gmNewSure), nil, gmiOK);
12571257 FWork := False;
1258- Close;
1258+ if (not ContinueModeAction.Enabled) or (not ContinueModeAction.Checked) then
1259+ Close;
12591260 end else if State = gdsError then begin
12601261 GikoForm.AddMessageList(FBoard.Title + ' ' + GikoSys.GetGikoMessage(gmSureError), nil, gmiNG);
12611262 end else if State = gdsAbort then begin
@@ -1271,7 +1272,8 @@ begin
12711272 SaveSendFile;
12721273 GikoForm.AddMessageList(FThreadItem.Title + ' ' + GikoSys.GetGikoMessage(gmNewRes), nil, gmiOK);
12731274 FWork := False;
1274- Close;
1275+ if (not ContinueModeAction.Enabled) or (not ContinueModeAction.Checked) then
1276+ Close;
12751277 end else if State = gdsError then begin
12761278 GikoForm.AddMessageList(FThreadItem.Title + ' ' + GikoSys.GetGikoMessage(gmResError), nil, gmiOK);
12771279 end else if State = gdsAbort then begin
--- a/ExternalBoardPlugInMain.pas
+++ b/ExternalBoardPlugInMain.pas
@@ -83,7 +83,7 @@ var
8383 implementation
8484
8585 uses ExternalBoardManager, ExternalThreadItem, GikoSystem, BoardGroup, Giko,
86- ReplaceDataModule;
86+ ReplaceDataModule, AbonInfo;
8787
8888 // *************************************************************************
8989 // 戻り値が PChar である API のメモリを確保する
@@ -418,22 +418,23 @@ function InternalAbon(
418418 var
419419 datList : TStringList;
420420 FileName : String;
421+ ThreadInfo: TAbonThread;
421422 begin
422423
424+ ThreadInfo := TAbonThread.Create;
423425 datList := TStringList.Create;
424426 try
425427 datList.Text := string( inDatText );
426428 FileName := string( inDatPath );
427429 GikoSys.FAbon.IndividualAbon( datList, ChangeFileExt(FileName,'.NG'));
428- GikoSys.FAbon.Execute( datList );
429- GikoSys.FSelectResFilter.Execute( datList );
430-
431- Result := CreateResultString( datList.Text );
430+ GikoSys.FAbon.Execute( datList, ThreadInfo );
431+ GikoSys.FSelectResFilter.Execute( datList, ThreadInfo );
432432 finally
433- datList.Free;
433+ ThreadInfo.Free;
434434 end;
435435
436-
436+ Result := CreateResultString( datList.Text );
437+ datList.Free;
437438 end;
438439 // *************************************************************************
439440 // 2ちゃんねるの dat 形式をローカルあぼ〜んに通す
@@ -448,16 +449,21 @@ function InternalAbonForOne(
448449 var
449450 datString : String;
450451 FileName : String;
452+ ThreadInfo: TAbonThread;
451453 begin
452454
453- datString := string( inDatText );
454- FileName := string( inDatPath );
455- GikoSys.FAbon.IndividualAbon( datString, ChangeFileExt(FileName,'.NG'), inNo);
456- GikoSys.FAbon.Execute( datString , inNo);
457- GikoSys.FSelectResFilter.Execute( datString , inNo );
455+ ThreadInfo := TAbonThread.Create;
456+ try
457+ datString := string( inDatText );
458+ FileName := string( inDatPath );
459+ GikoSys.FAbon.IndividualAbon( datString, ChangeFileExt(FileName,'.NG'), inNo);
460+ GikoSys.FAbon.Execute( datString , inNo, ThreadInfo );
461+ GikoSys.FSelectResFilter.Execute( datString , inNo, ThreadInfo );
462+ finally
463+ ThreadInfo.Free;
464+ end;
458465
459466 Result := CreateResultString( datString );
460-
461467 end;
462468
463469 // *************************************************************************
--- a/HTMLCreate.pas
+++ b/HTMLCreate.pas
@@ -102,7 +102,7 @@ var
102102 implementation
103103
104104 uses
105- Trip;
105+ Trip, AbonInfo;
106106
107107 const
108108 URL_CHAR: string = '0123456789'
@@ -996,6 +996,7 @@ var
996996 FileName: string;
997997 Res: TResRec;
998998 body : TBufferedWebBrowser;
999+ ThreadInfo: TAbonThread;
9991000 {$IFDEF DEBUG}
10001001 st, rt: Cardinal;
10011002 {$ENDIF}
@@ -1019,18 +1020,23 @@ begin
10191020 ReadList := TStringList.Create;
10201021 try
10211022 if ThreadItem.IsLogFile then begin
1023+ ThreadInfo := TAbonThread.Create;
1024+ ThreadInfo.Is2ch := ThreadItem.ParentBoard.Is2ch;
1025+ ThreadInfo.Board := ThreadItem.ParentBoard.BBSID;
1026+ ThreadInfo.Thread := ChangeFileExt(ThreadItem.FileName, '');
10221027 ReadList.BeginUpdate;
10231028 FileName := ThreadItem.GetThreadFileName;
10241029 ReadList.LoadFromFile(FileName);
10251030 ReadList.EndUpdate;
10261031 GikoSys.FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG'));
1027- GikoSys.FAbon.Execute(ReadList); // あぼ〜んして
1028- GikoSys.FSelectResFilter.Execute(ReadList); //レスのフィルタリングをする
1032+ GikoSys.FAbon.Execute(ReadList, ThreadInfo); // あぼ〜んして
1033+ GikoSys.FSelectResFilter.Execute(ReadList, ThreadInfo); //レスのフィルタリングをする
10291034 if ThreadItem.Title = '' then begin
10301035 DivideStrLine(ReadList[0], @Res);
10311036 sTitle := Res.FTitle;
10321037 end else
1033- sTitle := ThreadItem.Title
1038+ sTitle := ThreadItem.Title;
1039+ ThreadInfo.Free;
10341040 end else begin
10351041 sTitle := CustomStringReplace(ThreadItem.Title, '@`', ',');
10361042 end;
@@ -1078,6 +1084,8 @@ var
10781084 tmp, tmp1: string;
10791085 ThreadName: String;
10801086 ResLink : TResLinkRec;
1087+ ThreadInfo: TAbonThread;
1088+
10811089 function LoadSkin( fileName: string ): string;
10821090 begin
10831091 Result := LoadFromSkin( fileName, ThreadItem, ThreadItem.Size );
@@ -1144,14 +1152,19 @@ begin
11441152 ReadList := TStringList.Create;
11451153 try
11461154 if ThreadItem.IsLogFile then begin
1155+ ThreadInfo := TAbonThread.Create;
1156+ ThreadInfo.Is2ch := ThreadItem.ParentBoard.Is2ch;
1157+ ThreadInfo.Board := ThreadItem.ParentBoard.BBSID;
1158+ ThreadInfo.Thread := ChangeFileExt(ThreadItem.FileName, '');
11471159 FileName := ThreadItem.GetThreadFileName;
11481160 ReadList.LoadFromFile(FileName);
11491161 GikoSys.FAbon.IndividualAbon(ReadList, ChangeFileExt(FileName,'.NG'));
1150- GikoSys.FAbon.Execute(ReadList); // あぼ〜んして
1151- GikoSys.FSelectResFilter.Execute(ReadList); //レスのフィルタリングをする
1162+ GikoSys.FAbon.Execute(ReadList, ThreadInfo); // あぼ〜んして
1163+ GikoSys.FSelectResFilter.Execute(ReadList, ThreadInfo); //レスのフィルタリングをする
11521164 DivideStrLine(ReadList[0], @Res);
11531165 //Res.FTitle := CustomStringReplace(Res.FTitle, '@`', ',');
11541166 sTitle := Res.FTitle;
1167+ ThreadInfo.Free;
11551168 end else begin
11561169 sTitle := CustomStringReplace(ThreadItem.Title, '@`', ',');
11571170 end;
@@ -1308,6 +1321,7 @@ var
13081321 boardPlugIn : TBoardPlugIn;
13091322 Html: TStringList;
13101323 ResLink : TResLinkRec;
1324+ ThreadInfo: TAbonThread;
13111325 begin
13121326
13131327 Html := TStringList.Create;
@@ -1325,13 +1339,14 @@ begin
13251339 Hint.Title := '';
13261340 Hint.RawDocument := '';
13271341 Hint.Thread := nil;
1328-
1342+
13291343 //タイトル表示
13301344 if Title then
13311345 if ThreadItem <> nil then
13321346 Hint.Title := ThreadItem.Title;
13331347
13341348 if ThreadItem <> nil then begin
1349+ ThreadInfo := TAbonThread.Create;
13351350 Hint.Thread := ThreadItem;
13361351 ResLink.FBbs := ThreadItem.ParentBoard.BBSID;
13371352 ResLink.FKey := ChangeFileExt(ThreadItem.FileName, '');
@@ -1347,16 +1362,19 @@ begin
13471362 Line := i;
13481363 //ここで2ちゃんねるのdatの形式で1行読み込めれば・・・。↓読めるようになった
13491364 tmp := boardPlugIn.GetDat( DWORD( threadItem ), i );
1350- if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
1365+ if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp, ThreadInfo) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
13511366 Html.Add(GetResString(Line-1, tmp, @ResLink));
13521367 end;
13531368 end;
13541369 end else begin
1370+ ThreadInfo.Is2ch := ThreadItem.ParentBoard.Is2ch;
1371+ ThreadInfo.Board := ThreadItem.ParentBoard.BBSID;
1372+ ThreadInfo.Thread := ChangeFileExt(ThreadItem.FileName, '');
13551373 for i := StNum to ToNum do begin
13561374 Line := i;
13571375 FileName := ThreadItem.FilePath;
13581376 tmp := GikoSys.ReadThreadFile(FileName, Line);
1359- if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
1377+ if (tmp <> '') And ( not GikoSys.FAbon.CheckAbonPopupRes(tmp, ThreadInfo) And( not GikoSys.FAbon.CheckIndividualAbonList(line))) then begin
13601378 Html.Add(GetResString(Line-1, tmp, @ResLink));
13611379 end;
13621380 end;
@@ -1364,6 +1382,7 @@ begin
13641382 if (Html.Count > 0) then begin
13651383 Hint.RawDocument := '<DL>' + Html.Text + '</DL>';
13661384 end;
1385+ ThreadInfo.Free;
13671386 end;
13681387 finally
13691388 Html.Free;
--- a/NgEditor.dfm
+++ b/NgEditor.dfm
@@ -164,16 +164,15 @@ object NgEdit: TNgEdit
164164 end
165165 object MnAllThr: TMenuItem
166166 Caption = #20840#12473#12524#23550#35937
167- Checked = True
168- Enabled = False
167+ OnClick = MnAllThrClick
169168 end
170169 object MnSpcThr: TMenuItem
171170 Caption = #12473#12524#25351#23450'...'
172- Enabled = False
171+ OnClick = MnSpcThrClick
173172 end
174173 object MnSpcBrd: TMenuItem
175174 Caption = #26495#25351#23450'...'
176- Enabled = False
175+ OnClick = MnSpcBrdClick
177176 end
178177 object N3: TMenuItem
179178 Caption = '-'
--- a/NgEditor.pas
+++ b/NgEditor.pas
@@ -66,6 +66,9 @@ type
6666 procedure MnTrnAbnClick(Sender: TObject);
6767 procedure MnStdCmpClick(Sender: TObject);
6868 procedure MnRegexpClick(Sender: TObject);
69+ procedure MnAllThrClick(Sender: TObject);
70+ procedure MnSpcThrClick(Sender: TObject);
71+ procedure MnSpcBrdClick(Sender: TObject);
6972 private
7073 { Private 宣言 }
7174 FInfoList: TList;
@@ -86,12 +89,6 @@ type
8689
8790 var
8891 NgEdit: TNgEdit;
89-const
90- DEF_COMMENT: String = '>>';
91- DEF_REGEXP: String = '{{REGEXP}}';
92- DEF_THREAD: String = '{{THREAD:';
93- DEF_BOARD: String = '{{BOARD:';
94- DEF_END: String = '}}';
9592
9693 implementation
9794
@@ -335,6 +332,7 @@ begin
335332 if (idx > 1) then begin
336333 len := idx - Length(DEF_THREAD) - 1;
337334 inf.TargetThread := Copy(NgWd, Length(DEF_THREAD) + 1, len);
335+ inf.TargetType := ttThread;
338336 end else begin
339337 NgList.Add(NgWd);
340338 end;
@@ -343,6 +341,7 @@ begin
343341 if (idx > 1) then begin
344342 len := idx - Length(DEF_BOARD) - 1;
345343 inf.TargetBoard := Copy(NgWd, Length(DEF_BOARD) + 1, len);
344+ inf.TargetType := ttBoard;
346345 end else begin
347346 NgList.Add(NgWd);
348347 end;
@@ -602,6 +601,23 @@ begin
602601 MnStdAbn.Checked := True;
603602 MnTrnAbn.Checked := False;
604603 end;
604+ case inf.TargetType of
605+ ttThread: begin
606+ MnAllThr.Checked := False;
607+ MnSpcThr.Checked := True;
608+ MnSpcBrd.Checked := False;
609+ end;
610+ ttBoard: begin
611+ MnAllThr.Checked := False;
612+ MnSpcThr.Checked := False;
613+ MnSpcBrd.Checked := True;
614+ end;
615+ else begin
616+ MnAllThr.Checked := True;
617+ MnSpcThr.Checked := False;
618+ MnSpcBrd.Checked := False;
619+ end;
620+ end;
605621 if (inf.CompType = ctRegexp) then begin
606622 MnStdCmp.Checked := False;
607623 MnRegexp.Checked := True;
@@ -674,4 +690,39 @@ begin
674690 end;
675691 end;
676692
693+procedure TNgEdit.MnAllThrClick(Sender: TObject);
694+var
695+ inf: TLineInfo;
696+begin
697+ if (NgWordGrid.Row > 0) and (NgWordGrid.Row < NgWordGrid.RowCount) then begin
698+ inf := TLineInfo(FInfoList.Items[NgWordGrid.Row - 1]);
699+ inf.TargetType := ttAll;
700+ NgWordGrid.Cells[1, NgWordGrid.Row] := inf.ToString;
701+ end;
702+end;
703+
704+procedure TNgEdit.MnSpcThrClick(Sender: TObject);
705+var
706+ inf: TLineInfo;
707+begin
708+ if (NgWordGrid.Row > 0) and (NgWordGrid.Row < NgWordGrid.RowCount) then begin
709+ inf := TLineInfo(FInfoList.Items[NgWordGrid.Row - 1]);
710+ inf.TargetType := ttThread;
711+ NgWordGrid.Cells[1, NgWordGrid.Row] := inf.ToString;
712+ SetInfActionExecute(nil);
713+ end;
714+end;
715+
716+procedure TNgEdit.MnSpcBrdClick(Sender: TObject);
717+var
718+ inf: TLineInfo;
719+begin
720+ if (NgWordGrid.Row > 0) and (NgWordGrid.Row < NgWordGrid.RowCount) then begin
721+ inf := TLineInfo(FInfoList.Items[NgWordGrid.Row - 1]);
722+ inf.TargetType := ttBoard;
723+ NgWordGrid.Cells[1, NgWordGrid.Row] := inf.ToString;
724+ SetInfActionExecute(nil);
725+ end;
726+end;
727+
677728 end.
--- a/gikoNavi.dpr
+++ b/gikoNavi.dpr
@@ -92,7 +92,8 @@ uses
9292 AbonInfo in 'AbonInfo.pas',
9393 AbonInfoSet in 'AbonInfoSet.pas' {AbonInfoEdit},
9494 NgEditor in 'NgEditor.pas' {NgEdit},
95- RegExpTester in 'RegExpTester.pas' {RegExpTest};
95+ RegExpTester in 'RegExpTester.pas' {RegExpTest},
96+ BbsThrSel in 'BbsThrSel.pas' {BbsThreadSel};
9697
9798 {$R *.RES}
9899 {$R gikoResource.res}
Binary files a/gikoNavi.res and b/gikoNavi.res differ
--- a/res/ExternalBoardPlugIn/MachiBBSPlugIn.dpr
+++ b/res/ExternalBoardPlugIn/MachiBBSPlugIn.dpr
@@ -38,7 +38,8 @@ type
3838 function GetFooter( inOptionalFooter : string ) : string;
3939 function GetBoardURL : string;
4040
41- procedure To2chDat( ioHTML : TStringList; inStartNo : Integer = 1 );
41+// procedure To2chDat( ioHTML : TStringList; inStartNo : Integer = 1 );
42+ procedure To2chDat2( var ioDat: TStringList );
4243 procedure LoadDat;
4344 procedure FreeDat;
4445 function ReadURL : string;
@@ -64,6 +65,8 @@ type
6465 procedure EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
6566
6667 function SubjectURL : string;
68+ function SubjectURL2 : string;
69+ procedure ChangeSubjectFormat(var dat: TStringList);
6770 end;
6871
6972 // =========================================================================
@@ -83,7 +86,7 @@ const
8386 MAJOR_VERSION = 1;
8487 MINOR_VERSION = 0;
8588 RELEASE_VERSION = 'beta';
86- REVISION_VERSION = 22;
89+ REVISION_VERSION = 23;
8790
8891 // =========================================================================
8992 // 雑用関数
@@ -268,11 +271,10 @@ var
268271 foundPos : Integer;
269272 const
270273 BBS_HOST = 'machi.to';
271- BBS_HOST2 = 'machibbs.com';
274+ BBS_HOST2 = 'machibbs.com';
272275 THREAD_MARK = '/bbs/read.pl';
273276 THREAD_MARK2= '/bbs/read.cgi';
274277 begin
275-
276278 try
277279 // ホスト名が machi.to で終わる場合は受け付けるようにしている
278280 uri := TIdURI.Create( inURL );
@@ -455,14 +457,14 @@ function TMachiBBSThreadItem.Download : TDownloadState;
455457 var
456458 modified : Double;
457459 tmp : PChar;
458- downResult : TStringList;
460+// downResult : TStringList;
459461 content : TStringList;
460462 responseCode : Longint;
461463 logStream : TFileStream;
462464 uri : TIdURI;
463465 uriList : TStringList;
464466 datURL : string;
465- foundPos : Integer;
467+// foundPos : Integer;
466468 FilePath : String;
467469 procedure downAndParse;
468470 begin
@@ -470,6 +472,10 @@ var
470472
471473 try
472474 if responseCode = 200 then begin
475+ // APIではdat形式で返ってくる
476+ content.Text := string( tmp );
477+ To2chDat2( content ); // 形式変換
478+(* 旧仕様(HTMLで受信しdatに変換する)
473479 downResult := TStringList.Create;
474480 try
475481 downResult.Text := string( tmp );
@@ -497,6 +503,7 @@ var
497503 finally
498504 downResult.Free;
499505 end;
506+*)
500507 end else begin
501508 Result := dsNotModify;
502509 Exit;
@@ -532,6 +539,12 @@ begin
532539 // 独自にダウンロードやフィルタリングを行わない場合は
533540 // InternalDownload に任せることが出来る
534541 modified := LastModified;
542+ // APIのURL
543+ datURL := uri.Protocol + '://' + uri.Host + '/bbs/offlaw.cgi/2/' +
544+ uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/';
545+ if (Count > 0) then
546+ datURL := datURL + IntToStr( Count + 1 ) + '-'; // 新着のみ取得
547+(* 旧形式
535548 if Count = 0 then
536549 // 1〜
537550 datURL :=
@@ -544,6 +557,7 @@ begin
544557 uri.Protocol + '://' + uri.Host + '/bbs/read.cgi?' +
545558 'BBS=' + uriList.Values[ 'BBS' ] + '&KEY=' + uriList.Values[ 'KEY' ] +
546559 '&START=' + IntToStr( Count + 1 ) + '&NOFIRST=TRUE';
560+*)
547561 // ダウンロード
548562 downAndParse;
549563
@@ -774,6 +788,7 @@ begin
774788
775789 end;
776790
791+(*
777792 // *************************************************************************
778793 // まちBBSの HTML を 2ch の dat 形式に
779794 // *************************************************************************
@@ -888,6 +903,62 @@ begin
888903 end;
889904
890905 end;
906+*)
907+
908+// *************************************************************************
909+// まちBBSの dat を 2ch の dat 形式に
910+// *************************************************************************
911+procedure TMachiBBSThreadItem.To2chDat2( var ioDat: TStringList );
912+const
913+ SEP_TAG: String = '<>';
914+ ITEM_NUM: Integer = 7;
915+ IDX_HOST: Integer = 6;
916+ IDX_ID: Integer = 3;
917+ IDX_ADDST: Integer = 1;
918+ IDX_ADDED: Integer = 5;
919+var
920+ ResLine: TStringList;
921+ TmpLine: String;
922+ i: Integer;
923+ j: Integer;
924+ Sep: Integer;
925+begin
926+ ResLine := TStringList.Create;
927+ try
928+ for i := 0 to ioDat.Count - 1 do begin
929+ // 1行を項目別に切り分ける
930+ ResLine.Clear;
931+ TmpLine := ioDat.Strings[i];
932+ while (True) do begin
933+ Sep := Pos(SEP_TAG, TmpLine);
934+ if (Sep > 0) then begin
935+ ResLine.Add(Copy(TmpLine, 1, Sep - 1));
936+ Delete(TmpLine, 1, Sep + 1);
937+ end else begin
938+ ResLine.Add(TmpLine);
939+ Break;
940+ end;
941+ end;
942+ while (ResLine.Count < ITEM_NUM) do
943+ ResLine.Add(''); // 不足項目数だけ追加
944+
945+ // ホスト名をIDの後ろに追加
946+ ResLine.Strings[IDX_ID] := ResLine.Strings[IDX_ID] + ' <font size=1>IP: ' + ResLine.Strings[IDX_HOST] + ' </font>';
947+
948+ // 必要項目だけ再結合
949+ for j := IDX_ADDST to IDX_ADDED do begin
950+ if (j = IDX_ADDST) then
951+ TmpLine := ResLine.Strings[j]
952+ else
953+ TmpLine := TmpLine + SEP_TAG + ResLine.Strings[j];
954+ end;
955+
956+ ioDat.Strings[i] := TmpLine;
957+ end;
958+ finally
959+ ResLine.Free;
960+ end;
961+end;
891962
892963 // *************************************************************************
893964 // FDat の生成
@@ -1069,6 +1140,7 @@ var
10691140 responseCode : Longint;
10701141 uri : TIdURI;
10711142 uriList : TStringList;
1143+ dlURL : String;
10721144 begin
10731145
10741146 Result := dsError;
@@ -1086,7 +1158,9 @@ begin
10861158 // 独自にダウンロードやフィルタリングを行わない場合は
10871159 // InternalDownload に任せることが出来る
10881160 modified := LastModified;
1089- responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
1161+ dlURL := SubjectURL2;
1162+// responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
1163+ responseCode := InternalDownload( PChar( dlURL ), modified, downResult );
10901164 try
10911165 if responseCode = 200 then begin
10921166 try
@@ -1105,6 +1179,8 @@ begin
11051179 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
11061180
11071181 FDat.Text := string( downResult );
1182+ // 形式変換(Ver.2->Ver.1)
1183+ ChangeSubjectFormat(FDat);
11081184 // 保存
11091185 FDat.SaveToFile( FilePath );
11101186
@@ -1124,6 +1200,28 @@ begin
11241200
11251201 end;
11261202
1203+procedure TMachiBBSBoardItem.ChangeSubjectFormat(var dat: TStringList);
1204+var
1205+ i: Integer;
1206+ sep: Integer;
1207+ tmp: String;
1208+begin
1209+ for i := 0 to dat.Count - 1 do begin
1210+ tmp := dat.Strings[i];
1211+ sep := Pos('<>', tmp);
1212+ if (sep > 0) then begin
1213+ Delete(tmp, 1, sep + 1);
1214+ sep := Pos('<>', tmp);
1215+ if (sep > 0) then begin
1216+ Delete(tmp, sep, 2);
1217+ Insert('.cgi,', tmp, sep);
1218+ dat.Strings[i] := tmp;
1219+ end;
1220+ end;
1221+ end;
1222+end;
1223+
1224+
11271225 // *************************************************************************
11281226 // スレ立てを指示された
11291227 // *************************************************************************
@@ -1274,6 +1372,22 @@ begin
12741372 end;
12751373
12761374 // *************************************************************************
1375+// スレ一覧の URL を求める(Ver2)
1376+// *************************************************************************
1377+function TMachiBBSBoardItem.SubjectURL2 : string;
1378+var
1379+ uri: TIdURI;
1380+begin
1381+
1382+ uri := TIdURI.Create( URL );
1383+ try
1384+ Result := uri.Protocol + '://' + uri.Host + '/bbs/offlaw.cgi/2' + uri.Path;
1385+ finally
1386+ uri.Free;
1387+ end;
1388+end;
1389+
1390+// *************************************************************************
12771391 // TBoardItem が生成された場合の処置(TMachiBBSBoardItem を生成する)
12781392 // *************************************************************************
12791393 procedure BoardItemOnCreateOfTMachiBBSBoardItem(
Binary files a/res/ExternalBoardPlugIn/MachiBBSPlugIn.res and b/res/ExternalBoardPlugIn/MachiBBSPlugIn.res differ
旧リポジトリブラウザで表示