OSDN Git Service

コンパイル時に[警告][ヒント]がなるべく出ないように修正。
[gikonavigoeson/gikonavi.git] / BoardGroup.pas
1 unit BoardGroup;
2
3 interface
4
5 uses
6         SysUtils, Classes, ComCtrls, IniFiles, {HTTPApp,} YofUtils, IdGlobal;
7
8 type
9         //\83\8a\83X\83g\82Ì\95\\8e¦\83A\83C\83e\83\80\91I\91ð
10         TGikoViewType = (gvtAll, gvtLog, gvtNew, gvtUser);
11         //\83\8a\83X\83g\82Ì\8eæ\93¾\8c\8f\90\94
12         //TGikoListCount = (glc50, glc100, glc200, glc500, glc1000, glcAll);
13         //\8f\84\89ñ\94Ô\8d\86
14         //TGikoRoundNo = (grnNone, grn1, grn2, grn3, grn4, grn5, grnOnce);
15         //\83\8a\83X\83g\82Ì\8fã\82°\89º\82°
16         TGikoAgeSage = (gasNone, gasAge, gasSage, gasNew);
17
18 {       TFolder = class
19         private
20                 FItemList: TList;       //\8eq\83A\83C\83e\83\80\83\8a\83X\83g
21                 FLeaf: Boolean;         //\89º\82É\83t\83H\83\8b\83_\82ð\8e\9d\82Â\82±\82Æ\82ª\8fo\97\88\82é\82©
22         public
23                 function Add(Item: TFolder): Integer;
24                 procedure Clear;
25                 procedure Delete(Index: Integer);
26                 procedure Exchange(Index1, Index2: Integer);
27                 procedure Insert(Index: Integer; Item: TFolder);
28                 procedure Move(CurIndex, NewIndex: Integer);
29                 function Remove(Item: TFolder): Integer;
30                 procedure Sort(Compare: TListSortCompare);
31                 property Capacity: Integer read FCapacity write SetCapacity;
32                 property Count: Integer read FCount write SetCount;
33                 property Items[Index: Integer]: TFolder read Get write Put; default;
34
35                 property Leaf: Boolean read FLeaf;
36         end;
37
38         TBBS = class(TFolder)
39         end;
40         TCategory class(TFolder)
41         end;
42         TBoard = class(TFolder)
43         end;
44         TThreadItem = class(TFolder)
45         end;
46 }
47
48 {
49         TBBS2ch = class(TBBS)
50         end;
51         TBoard2ch = class(TBoard)
52         end;
53         TThreadItem2ch = class(TThreadItem)
54         end;
55 }
56
57 //      ITest = interface
58 //      end;
59 //      IBBS = interface
60 //      end;
61 //      ICategory = interface
62 //      end;
63 //      IBoard = interface
64 //      end;
65 //      IThreadItem = interface
66 //      end;
67
68         TCategory = class;
69         TBoard = class;
70         TThreadItem = class;
71
72         //\82Æ\82è\82 \82¦\82¸\82Q\82¿\82á\82ñ\82Ë\82é\82Ì\83\8b\81[\83g
73         TBBS2ch = class(TList)
74         private
75                 FTitle: string;
76                 FLogFolder: string;
77                 FExpand: Boolean;
78                 FKubetsuChk: Boolean;                                   //\8di\8d\9e\82Ý\8e\9e\91å\95\8e\9a\8f¬\95\8e\9a\8bæ\95Ê
79                 FSelectText: string;                                    //\8di\8d\9e\82Ý\95\8e\9a\97ñ
80                 FShortSelectText: string;
81
82                 function GetCategory(index: integer): TCategory;
83                 procedure SetCategory(index: integer; value: TCategory);
84                 procedure SetSelectText(s: string);
85         public
86                 constructor Create(LogFolder: string);
87                 destructor Destroy; override;
88
89                 procedure ReadBoardFile;
90
91                 function GetBoardFromBBSID(BBSID: string): TBoard;
92
93                 function Add(item: TCategory): integer;
94                 procedure Delete(index: integer);
95                 procedure Clear; override;
96                 function Find(key: string): TCategory;
97                 function FindBBSID(BBSID: string): TBoard;
98                 function FindBoardFromTitle(Title: string): TBoard;
99                 function FindThreadItem(BBSID: string; FileName: string): TThreadItem;
100                 function GetLogFolder: string;
101
102                 property Items[index: integer]: TCategory read GetCategory write SetCategory;
103                 property Title: string read FTitle write FTitle;
104                 property NodeExpand: Boolean read FExpand write FExpand;
105
106                 property KubetsuChk: Boolean read FKubetsuChk write FKubetsuChk;
107                 property SelectText: string read FSelectText write SetSelectText;
108                 property ShortSelectText: string read FShortSelectText write FShortSelectText;
109         end;
110
111         //\83J\83e\83S\83\8a
112         TCategory = class(TList)
113         private
114                 FNo: Integer;
115                 FTitle: string;
116                 FParentBBS2ch: TBBS2ch;
117                 FExpand: Boolean;
118
119                 function GetBoard(index: integer): TBoard;
120                 procedure SetBoard(index: integer; value: TBoard);
121         public
122                 constructor Create;
123                 destructor Destroy; override;
124
125                 property No: Integer read FNo write FNo;
126                 property Title: string read FTitle write FTitle;
127                 property Items[index: integer]: TBoard read GetBoard write SetBoard;
128                 property ParentBBS2ch: TBBS2ch read FParentBBS2ch write FParentBBS2ch;
129
130                 function Add(item: TBoard): integer;
131                 procedure Delete(index: integer);
132                 procedure Clear; override;
133                 function FindName(key: string): TBoard;
134                 function FindBBSID(BBSID: string): TBoard;
135                 function FindBoardFromTitle(Title: string): TBoard;
136                 function IsMidoku: Boolean;
137
138                 property NodeExpand: Boolean read FExpand write FExpand;
139         end;
140
141         //\94Â
142         TBoard = class(TList)
143         private
144                 FNo: Integer;                                                                   //\94Ô\8d\86
145                 FTitle: string;                                                         //\83{\81[\83h\83^\83C\83g\83\8b
146                 FBBSID: string;                                                         //BBSID
147                 FURL: string;                                                                   //\83{\81[\83hURL
148                 FRound: Boolean;                                                        //\83X\83\8c\83b\83h\88ê\97\97\8f\84\89ñ\97\\96ñ
149                 FRoundName: string;                                             //\8f\84\89ñ\96¼
150                 FRoundDate: TDateTime;                          //\83X\83\8c\83b\83h\88ê\97\97\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
151                 FLastModified: TDateTime;                       //\83X\83\8c\83b\83h\88ê\97\97\82ª\8dX\90V\82³\82ê\82Ä\82¢\82é\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81j
152                 FLastGetTime: TDateTime;                        //\83X\83\8c\83b\83h\82Ü\82½\82Í\83X\83\8c\83b\83h\88ê\97\97\82ð\8dÅ\8cã\82É\8dX\90V\82µ\82½\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81E\8f\91\82«\8d\9e\82Ý\8e\9e\82É\8eg\97p\82·\82é\81j
153                 FIsThreadDatRead: Boolean;              //\83X\83\8c\83b\83h\83\8a\83X\83g\82Í\93Ç\82Ý\8d\9e\82Ü\82ê\82Ä\82¢\82é\82©\81H
154                 FUnRead: Integer;                                                       //\83X\83\8c\83b\83h\96¢\93Ç\90\94
155                 FParentCategory: TCategory;   //\90e\83J\83e\83S\83\8a
156                 FModified: Boolean;                                             //\8fC\90³\83t\83\89\83O
157                 FBoolData: Boolean;                                             //\82¢\82ë\82ñ\82È\97p\93r\82É\8eg\82¤yo
158                 FSPID: string;                                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
159                 FPON: string;                                                                   //\8f\91\82«\8d\9e\82Ý\97pPON
160                 FKotehanName: string;                                   //\83R\83e\83n\83\93\96¼\91O
161                 FKotehanMail: string;                                   //\83R\83e\83n\83\93\83\81\81[\83\8b
162
163                 FUpdate: Boolean;
164                 FExpand: Boolean;
165
166                 function GetThreadItem(index: integer): TThreadItem;
167                 procedure SetThreadItem(index: integer; value: TThreadItem);
168                 procedure SetRound(b: Boolean);
169                 procedure SetRoundName(s: string);
170                 procedure SetLastModified(d: TDateTime);
171                 procedure SetLastGetTime(d: TDateTime);
172                 procedure SetUnRead(i: Integer);
173                 procedure SetKotehanName(s: string);
174                 procedure SetKotehanMail(s: string);
175         public
176                 constructor Create;
177                 destructor Destroy; override;
178
179                 property Items[index: integer]: TThreadItem read GetThreadItem write SetThreadItem;
180                 property No: Integer read FNo write FNo;
181                 property Title: string read FTitle write FTitle;
182                 property BBSID: string read FBBSID write FBBSID;
183                 property URL: string read FURL write FURL;
184                 property Round: Boolean read FRound write SetRound;
185                 property RoundName: string read FRoundName write SetRoundName;
186                 property RoundDate: TDateTime read FRoundDate write FRoundDate;
187                 property LastModified: TDateTime read FLastModified write SetLastModified;
188                 property LastGetTime: TDateTime read FLastGetTime write SetLastGetTime;
189                 property UnRead: Integer read FUnRead write SetUnRead;
190                 property Modified: Boolean read FModified write FModified;
191                 property IsThreadDatRead: Boolean read FIsThreadDatRead write FIsThreadDatRead;
192                 property ParentCategory: TCategory read FParentCategory write FParentCategory;
193
194                 function Add(item: TThreadItem): integer;
195                 procedure Insert(Index: Integer; Item: TThreadItem);
196                 procedure Delete(index: integer);
197                 procedure DeleteList(index: integer);
198                 procedure Clear; override;
199                 function Find(ItemFileName: string): TThreadItem;
200                 function GetIndex(ItemFileName: string): Integer;
201                 procedure LoadSettings;
202                 procedure SaveSettings;
203                 function GetReadCgiURL: string;
204                 function GetSubjectFileName: string;
205                 function GetFolderIndexFileName: string;
206                 function GetSendURL: string;
207
208                 function GetNewThreadCount: Integer;
209                 function GetLogThreadCount: Integer;
210                 function GetUserThreadCount: Integer;
211                 function GetNewThread(Index: Integer): TThreadItem;
212                 function GetLogThread(Index: Integer): TThreadItem;
213                 function GetUserThread(Index: Integer): TThreadItem;
214
215                 procedure BeginUpdate;
216                 procedure EndUpdate;
217                 property NodeExpand: Boolean read FExpand write FExpand;
218                 property BoolData: Boolean read FBoolData write FBoolData;
219                 property SPID: string read FSPID write FSPID;
220                 property PON: string read FPON write FPON;
221                 property KotehanName: string read FKotehanName write SetKotehanName;
222                 property KotehanMail: string read FKotehanMail write SetKotehanMail;
223         end;
224
225         //\83X\83\8c
226         TThreadItem = class(TObject)
227         private
228                 FNo: Integer;                                                   //\94Ô\8d\86
229                 FFileName: string;                              //\83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
230                 FTitle: string;                                         //\83X\83\8c\83b\83h\83^\83C\83g\83\8b
231                 FShortTitle: string;                    //\92Z\82¢\83X\83\8c\83b\83h\83^\83C\83g\83\8b\81i\8c\9f\8dõ\97p\81j
232                 FRoundDate: TDateTime;          //\83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
233                 FLastModified: TDateTime; //\83X\83\8c\83b\83h\82ª\8dX\90V\82³\82ê\82Ä\82¢\82é\93ú\8e\9e\81i\83T\81[\83o\91¤\93ú\8e\9e\81j
234                 FCount: Integer;                                        //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
235                 FAllResCount: Integer;          //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
236                 FNewResCount: Integer;          //\83X\83\8c\83b\83h\90V\92\85\90\94
237                 FSize: Integer;                                         //\83X\83\8c\83b\83h\83T\83C\83Y
238                 FRound: Boolean;                                        //\8f\84\89ñ\83t\83\89\83O
239                 FRoundName: string;                             //\8f\84\89ñ\96¼
240                 FIsLogFile: Boolean;                    //\83\8d\83O\91\8dÝ\83t\83\89\83O
241                 FParentBoard: TBoard;                   //\90e\83{\81[\83h
242                 FKokomade: Integer;                             //\83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
243                 FNewReceive: Integer;           //\83R\83R\82©\82ç\90V\8bK\8eó\90M
244                 FNewArrival: Boolean;                   //\90V\92\85
245                 FUnRead: Boolean;                                       //\96¢\93Ç\83t\83\89\83O
246                 FScrollTop: Integer;                    //\83X\83N\83\8d\81[\83\8b\88Ê\92u
247                 FDownloadHost: string;          //\8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
248                 FAgeSage: TGikoAgeSage;         //\83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
249 //              FSPID: string;                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
250
251                 FUpdate: Boolean;
252                 FExpand: Boolean;
253
254                 procedure SetLastModified(d: TDateTime);
255                 procedure SetRound(b: Boolean);
256                 procedure SetRoundName(s: string);
257                 procedure SetKokomade(i: Integer);
258                 procedure SetUnRead(b: Boolean);
259                 procedure SetScrollTop(i: Integer);
260         public
261                 constructor Create;
262                 destructor Destroy; override;
263
264                 function GetDatURL: string;
265                 function GetDatgzURL: string;
266 //              function GetOldDatgzURL: string;
267                 function GetOfflawCgiURL(SessionID: string): string;
268                 function GetSendURL: string;
269                 procedure DeleteLogFile;
270                 function GetThreadFileName: string;
271                 procedure BeginUpdate;
272                 procedure EndUpdate;
273
274                 property No: Integer read FNo write FNo;
275                 property FileName: string read FFileName write FFileName;
276                 property Title: string read FTitle write FTitle;
277                 property ShortTitle: string read FShortTitle write FShortTitle;
278                 property RoundDate: TDateTime read FRoundDate write FRoundDate;
279                 property LastModified: TDateTime read FLastModified write SetLastModified;
280                 property Count: Integer read FCount write FCount;
281                 property AllResCount: Integer read FAllResCount write FAllResCount;
282                 property NewResCount: Integer read FNewResCount write FNewResCount;
283                 property Size: Integer read FSize write FSize;
284                 property Round: Boolean read FRound write SetRound;
285                 property RoundName: string read FRoundName write SetRoundName;
286
287                 property IsLogFile: Boolean read FIsLogFile write FIsLogFile;
288                 property ParentBoard: TBoard read FParentBoard write FParentBoard;
289                 property Kokomade: Integer read FKokomade write SetKokomade;
290                 property NewReceive: Integer read FNewReceive write FNewReceive;
291                 property NewArrival: Boolean read FNewArrival write FNewArrival;
292                 property UnRead: Boolean read FUnRead write SetUnRead;
293                 property ScrollTop: Integer read FScrollTop write SetScrollTop;
294                 property Expand: Boolean read FExpand write FExpand;
295                 property DownloadHost: string read FDownloadHost write FDownloadHost;
296                 property AgeSage: TGikoAgeSage read FAgeSage write FAgeSage;
297 //              property SPID: string read FSPID write FSPID;
298         end;
299
300
301
302         //\8c\9f\8dõ\8c\8b\89Ê\83\8a\83X\83g
303 {       TSearchList = class(TList)
304         private
305                 function GetThreadItem(index: integer): TThreadItem;
306                 procedure SetThreadItem(index: integer; value: TThreadItem);
307         public
308                 constructor Create;
309                 destructor Destroy; override;
310
311                 property Items[index: integer]: TThreadItem read GetThreadItem write SetThreadItem;
312
313                 function Add(item: TThreadItem): integer;
314                 procedure Delete(index: integer);
315                 procedure Clear; override;
316         end;}
317
318 var
319         BBS2ch: TBBS2ch;
320
321 implementation
322
323 uses
324         GikoSystem, RoundData;
325
326 const
327         BBS2CH_NAME:           string  = '\82Q\82¿\82á\82ñ\82Ë\82é';
328         BBS2CH_LOG_FOLDER:     string  = '2ch';
329
330         FOLDER_INI_FILENAME:   string  = 'Folder.ini';
331         FOLDER_INDEX_FILENAME: string  = 'Folder.idx';
332         SUBJECT_FILENAME:      string  = 'subject.txt';
333         PATH_DELIM:            string  = '\';
334         //DEFAULT_LIST_COUNT:    Integer = 100;
335
336 //      COLUMN_CATEGORY:   array[0..0] of string = ('\83J\83e\83S\83\8a\96¼');
337 //      COLUMN_BOARD:      array[0..3] of string = ('\94Â\96¼', '\8eæ\93¾\90\94', '\8f\84\89ñ\97\\96ñ', '\91O\89ñ\8f\84\89ñ\93ú\8e\9e');
338 //      COLUMN_THREADITEM: array[0..3] of string = ('\83X\83\8c\83b\83h\96¼', '\83J\83E\83\93\83g', '\8f\84\89ñ\97\\96ñ', '\91O\89ñ\8f\84\89ñ\93ú\8e\9e');
339
340 (*************************************************************************
341  *\8b@\94\\96¼\81FTBBS\83R\83\93\83X\83g\83\89\83N\83^
342  *Public
343  *************************************************************************)
344 constructor TBBS2ch.Create(LogFolder: string);
345 begin
346         Title := BBS2CH_NAME;
347         FLogFolder := LogFolder;
348 end;
349
350 (*************************************************************************
351  *\8b@\94\\96¼\81FTBBS\83f\83X\83g\83\89\83N\83^
352  *Public
353  *************************************************************************)
354 destructor TBBS2ch.Destroy;
355 begin
356         Clear;
357         inherited;
358 end;
359
360 (*************************************************************************
361  *\8b@\94\\96¼\81F
362  *Public
363  *************************************************************************)
364 function TBBS2ch.GetCategory(index: integer): TCategory;
365 begin
366         Result := TCategory(inherited Items[index]);
367 end;
368
369 procedure TBBS2ch.SetCategory(index: integer; value: TCategory);
370 begin
371         inherited Items[index] := value;
372 end;
373
374 function TBBS2ch.Add(item: TCategory): integer;
375 begin
376         Item.ParentBBS2ch := self;
377         Result := inherited Add(item);
378 end;
379
380 procedure TBBS2ch.Delete(index: integer);
381 begin
382         if Items[index] <> nil then
383                 TCategory(Items[index]).Free;
384         Items[index] := nil;
385         inherited Delete(index);
386 end;
387
388 procedure TBBS2ch.Clear;
389 var
390         i: integer;
391 begin
392         for i := Count - 1 downto 0 do
393                 Delete(i);
394 end;
395
396 function TBBS2ch.Find(key: string): TCategory;
397 begin
398         Result := nil;
399 end;
400
401 function TBBS2ch.FindBBSID(BBSID: string): TBoard;
402 var
403         i: Integer;
404         Category: TCategory;
405         Board: TBoard;
406 begin
407         Result := nil;
408         for i := 0 to Count - 1 do begin
409                 Category := Items[i];
410                 Board := Category.FindBBSID(BBSID);
411                 if Board <> nil then begin
412                         Result := Board;
413                         Exit;
414                 end;
415         end;
416 end;
417
418 function TBBS2ch.FindBoardFromTitle(Title: string): TBoard;
419 var
420         i: Integer;
421         Category: TCategory;
422         Board: TBoard;
423 begin
424         Result := nil;
425         for i := 0 to Count - 1 do begin
426                 Category := Items[i];
427                 Board := Category.FindBoardFromTitle(Title);
428                 if Board <> nil then begin
429                         Result := Board;
430                         Exit;
431                 end;
432         end;
433 end;
434
435 function TBBS2ch.FindThreadItem(BBSID: string; FileName: string): TThreadItem;
436 var
437         Board: TBoard;
438 begin
439         Result := nil;
440         Board := FindBBSID(BBSID);
441         if Board = nil then
442                 Exit;
443         Result := Board.Find(FileName);
444 end;
445
446 (*************************************************************************
447  *\8b@\94\\96¼\81@\81@\81F\83{\81[\83h\83t\83@\83C\83\8b\93Ç\82Ý\8d\9e\82Ý
448  *\89Â\8e\8b\81@\81@\81@\81FPublic
449  *\97\9a\97ð\82P\81@\81@\81F\90V\8bK\8dì\90¬
450  *************************************************************************)
451 procedure TBBS2ch.ReadBoardFile;
452 var
453         i, j: integer;
454         idx: Integer;
455         ini: TMemIniFile;
456         CategoryList: TStringList;
457         BoardList: TStringList;
458         Category: TCategory;
459         Board: TBoard;
460         inistr: string;
461         RoundItem: TRoundItem;
462         BBSList: TStringList;
463         CustomList: TStringList;
464 begin
465         ini := TMemIniFile.Create('');
466         BBSList := TStringList.Create;
467         CustomList := TStringList.Create;
468         try
469                 if FileExists(GikoSys.GetBoardFileName) then
470                         BBSList.LoadFromFile(GikoSys.GetBoardFileName);
471                 if FileExists(GikoSys.GetCustomBoardFileName) then
472                         CustomList.LoadFromFile(GikoSys.GetCustomBoardFileName);
473                 BBSList.AddStrings(CustomList);
474                 ini.SetStrings(BBSList);
475
476                 CategoryList := TStringList.Create;
477                 BoardList := TStringList.Create;
478                 try
479                         ini.ReadSections(CategoryList);
480                         for i := 0 to CategoryList.Count - 1 do begin
481
482                                 ini.ReadSection(CategoryList[i], BoardList);
483                                 Category := TCategory.Create;
484                                 Category.No := i + 1;
485                                 Category.Title := CategoryList[i];
486
487                                 for j := 0 to BoardList.Count - 1 do begin
488                                         inistr := ini.ReadString(CategoryList[i], BoardList[j], '');
489                                         Board := TBoard.Create;
490                                         Board.BeginUpdate;
491                                         Board.No := j + 1;
492                                         Board.Title := BoardList[j];
493                                         Board.BBSID := GikoSys.UrlToID(inistr);
494                                         Board.URL := inistr;
495                                         Board.RoundDate := ZERO_DATE;
496
497                                         idx := RoundList.Find(Board);
498                                         if idx <> -1 then begin
499                                                 RoundItem := RoundList.Items[idx, grtBoard];
500                                                 Board.Round := True;
501                                                 Board.RoundName := RoundItem.RoundName;
502                                         end;
503                                         Category.Add(Board);
504                                         Board.EndUpdate;
505                                 end;
506                                 BBS2ch.Add(Category);
507                         end;
508                 finally
509                         BoardList.Free;
510                         CategoryList.Free;
511                 end;
512         finally
513                 BBSList.Free;
514                 CustomList.Free;
515                 ini.Free;
516         end;
517 end;
518
519 function TBBS2ch.GetBoardFromBBSID(BBSID: string): TBoard;
520 var
521         i: integer;
522 begin
523         Result := nil;
524         for i := 0 to BBS2ch.Count - 1 do begin
525                 Result := BBS2ch.Items[i].FindBBSID(BBSID);
526                 if Result <> nil then
527                         Exit;
528         end;
529 end;
530
531 (*************************************************************************
532  *\83\8d\83O\83t\83H\83\8b\83_\8eæ\93¾
533  *
534  *************************************************************************)
535 function TBBS2ch.GetLogFolder: string;
536 begin
537         Result := IncludeTrailingPathDelimiter(FLogFolder)
538                                         + BBS2CH_LOG_FOLDER + PATH_DELIM;
539 end;
540
541 procedure TBBS2ch.SetSelectText(s: string);
542 begin
543         FSelectText := s;
544         ShortSelectText := GikoSys.ZenToHan(s);
545 end;
546
547 {class function TBBS2ch.GetColumnName(Index: Integer): string;
548 begin
549         Result := COLUMN_CATEGORY[Index];
550 end;
551
552 class function TBBS2ch.GetColumnCount: Integer;
553 begin
554         Result := Length(COLUMN_CATEGORY);
555 end;}
556
557 //===================
558 //TCategory
559 //===================
560 constructor TCategory.Create;
561 begin
562 end;
563
564 destructor TCategory.Destroy;
565 begin
566         Clear;
567         inherited;
568 end;
569
570 function TCategory.GetBoard(index: integer): TBoard;
571 begin
572         Result := TBoard(inherited Items[index]);
573 end;
574
575 procedure TCategory.SetBoard(index: integer; value: TBoard);
576 begin
577         inherited Items[index] := value;
578 end;
579
580 function TCategory.Add(item: TBoard): integer;
581 begin
582         Item.ParentCategory := self;
583         Result := inherited Add(item);
584 end;
585
586 procedure TCategory.Delete(index: integer);
587 begin
588         if Items[index] <> nil then
589                 TBoard(Items[index]).Free;
590         Items[index] := nil;
591         inherited Delete(index);
592 end;
593
594 procedure TCategory.Clear;
595 var
596         i: integer;
597 begin
598         for i := Count - 1 downto 0 do
599                 Delete(i);
600 end;
601
602 function TCategory.FindName(key: string): TBoard;
603 begin
604         Result := nil;
605 end;
606
607 function TCategory.FindBBSID(BBSID: string): TBoard;
608 var
609         i: integer;
610 begin
611         Result := nil;
612         for i := 0 to Count - 1 do begin
613                 if Items[i].FBBSID = BBSID then begin
614                         Result := Items[i];
615                         Exit;
616                 end;
617         end;
618 end;
619
620 function TCategory.FindBoardFromTitle(Title: string): TBoard;
621 var
622         i: integer;
623 begin
624         Result := nil;
625         for i := 0 to Count - 1 do begin
626                 if Items[i].FTitle = Title then begin
627                         Result := Items[i];
628                         Exit;
629                 end;
630         end;
631 end;
632
633 function TCategory.IsMidoku: Boolean;
634 var
635         i: Integer;
636         j: Integer;
637 begin
638         Result := False;
639         for i := 0 to Count - 1 do begin
640                 if Items[i] <> nil then begin
641                         for j := 0 to Items[i].Count - 1 do begin
642                                 if Items[i].Items[j] <> nil then begin
643 //                                      if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].Count > Items[i].Items[j].Kokomade) then begin
644                                         if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].UnRead) then begin
645                                                 Result := True;
646                                                 Exit;
647                                         end;
648                                 end;
649                         end;
650                 end;
651         end;
652 end;
653
654 {class function TCategory.GetColumnName(Index: Integer): string;
655 begin
656         Result := COLUMN_BOARD[Index];
657 end;
658
659 class function TCategory.GetColumnCount: Integer;
660 begin
661         Result := Length(COLUMN_BOARD);
662 end;}
663
664 //===================
665 //TBoard
666 //===================
667 constructor TBoard.Create;
668 begin
669         FNo := 0;
670         FTitle := '';
671         FBBSID := '';
672         FURL := '';
673         FRound := False;
674         FRoundDate := ZERO_DATE;
675         FLastModified := ZERO_DATE;
676         FLastGetTime := ZERO_DATE;
677         FIsThreadDatRead := False;
678         FUnRead := 0;
679 //      FListStyle := vsReport;
680 //      FItemNoVisible := True;
681
682         FUpdate := True;
683 end;
684
685 destructor TBoard.Destroy;
686 begin
687         if FModified then begin
688                 GikoSys.WriteThreadDat(Self);
689                 SaveSettings;
690         end;
691
692         Clear;
693         inherited;
694 end;
695
696 function TBoard.GetThreadItem(index: integer): TThreadItem;
697 begin
698         Result := TThreadItem(inherited Items[index]);
699 end;
700
701 procedure TBoard.SetThreadItem(index: integer; value: TThreadItem);
702 begin
703         inherited Items[index] := value;
704 end;
705
706 function TBoard.Add(Item: TThreadItem): Integer;
707 begin
708         Item.ParentBoard := Self;
709         Result := inherited Add(Item);
710 end;
711
712 procedure TBoard.Insert(Index: Integer; Item: TThreadItem);
713 begin
714         Item.ParentBoard := Self;
715         inherited Insert(Index, Item);
716 end;
717
718 //Index\82Å\8ew\92è\82³\82ê\82½\83X\83\8c\83b\83h\83I\83u\83W\83F\83N\83g\82ð\94j\8aü
719 procedure TBoard.Delete(index: Integer);
720 begin
721         if Items[index] <> nil then
722                 TThreadItem(Items[index]).Free;
723         Items[index] := nil;
724         inherited Delete(index);
725 end;
726
727 //Index\82Å\8ew\92è\82³\82ê\82½\83X\83\8c\83b\83h\82ð\83\8a\83X\83g\82©\82ç\8dí\8f\9c\81i\83X\83\8c\83I\83u\83W\83F\83N\83g\82Í\82Ì\82±\82·\81j
728 procedure TBoard.DeleteList(index: integer);
729 begin
730         inherited Delete(index);
731 end;
732
733 procedure TBoard.Clear;
734 var
735         i: integer;
736 begin
737 //      FUnRead := 0;
738         for i := Count - 1 downto 0 do
739                 Delete(i);
740 end;
741
742 function TBoard.Find(ItemFileName: string): TThreadItem;
743 var
744         i: integer;
745 begin
746         Result := nil;
747         for i := 0 to Count - 1 do begin
748                 if Items[i].FileName = ItemFileName then begin
749                         Result := Items[i];
750                         Exit;
751                 end;
752         end;
753 end;
754
755 function TBoard.GetIndex(ItemFileName: string): Integer;
756 var
757         i: integer;
758 begin
759         Result := -1;
760         for i := 0 to Count - 1 do begin
761                 if Items[i].FileName = ItemFileName then begin
762                         Result := i;
763                         Exit;
764                 end;
765         end;
766 end;
767
768 {function TBoard.GetMidokuCount: Integer;
769 var
770         i: integer;
771 begin
772         Result := 0;
773         for i := 0 to Count- 1 do begin
774                 if Items[i] <> nil then begin
775                         if (Items[i].IsLogFile) and (Items[i].Count > Items[i].Kokomade) then
776                                 inc(Result);
777                 end;
778         end;
779 end;
780 }
781
782 procedure TBoard.LoadSettings;
783 var
784         ini: TMemIniFile;
785         FileName: string;
786 begin
787         FileName := ParentCategory.ParentBBS2ch.GetLogFolder
788                                                 + BBSID + PATH_DELIM + FOLDER_INI_FILENAME;
789
790         if not FileExists(FileName) then
791                 Exit;
792         ini := TMemIniFile.Create(FileName);
793         try
794 //              Round := ini.ReadBool('Status', 'Round', False);
795                 FRoundDate := ini.ReadDateTime('Status', 'RoundDate', ZERO_DATE);
796                 FLastModified := ini.ReadDateTime('Status', 'LastModified', ZERO_DATE);
797                 FLastGetTime := ini.ReadDateTime('Status', 'LastGetTime', ZERO_DATE);
798                 FUnRead := ini.ReadInteger('Status', 'UnRead', 0);
799                 FSPID := ini.ReadString('Cookie', 'SPID', '');
800                 FPON := ini.ReadString('Cookie', 'PON', '');
801                 FKotehanName := ini.ReadString('Kotehan', 'Name', '');
802                 FKotehanMail := ini.ReadString('Kotehan', 'Mail', '');
803 //              ListStyle := TViewStyle(Ord(ini.ReadInteger('Status', 'ListStyle', 3)));
804 //              ItemNoVisible := ini.ReadBool('Status', 'ItemNoVisible', True);
805 //              ViewType := TGikoViewType(Ord(ini.ReadInteger('Status', 'ViewType', 0)));
806                 if UnRead < 0 then
807                         UnRead := 0;
808         finally
809                 ini.Free;
810         end;
811 end;
812
813 procedure TBoard.SaveSettings;
814 var
815         ini: TMemIniFile;
816         FileName: string;
817 begin
818         FileName := ParentCategory.ParentBBS2ch.GetLogFolder
819                                                 + BBSID + PATH_DELIM;
820         if not GikoSys.DirectoryExistsEx(FileName) then
821                 GikoSys.ForceDirectoriesEx(FileName);
822         FileName := FileName + FOLDER_INI_FILENAME;
823         ini := TMemIniFile.Create(FileName);
824         try
825                 if UnRead < 0 then
826                         UnRead := 0;
827 //              ini.WriteBool('Status', 'Round', Round);
828                 ini.WriteDateTime('Status', 'RoundDate', FRoundDate);
829                 ini.WriteDateTime('Status', 'LastModified', FLastModified);
830                 ini.WriteDateTime('Status', 'LastGetTime', FLastGetTime);
831                 ini.WriteInteger('Status', 'UnRead', FUnRead);
832                 ini.WriteString('Cookie', 'SPID', FSPID);
833                 ini.WriteString('Cookie', 'PON', FPON);
834                 ini.WriteString('Kotehan', 'Name', FKotehanName);
835                 ini.WriteString('Kotehan', 'Mail', FKotehanMail);
836 //              ini.WriteInteger('Status', 'ListStyle', Ord(ListStyle));
837 //              ini.WriteBool('Status', 'ItemNoVisible', ItemNoVisible);
838 //              ini.WriteInteger('Status', 'ViewType', Ord(ViewType));
839                 ini.UpdateFile;
840         finally
841                 ini.Free;
842         end;
843 end;
844
845 // \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
846 function TBoard.GetReadCgiURL: string;
847 begin
848         //Result := URL + SUBJECT_FILENAME;
849         //Result := GikoSys.UrlToServer(URL)
850         //                              + 'test/read.cgi/' + BBSID + '/?raw=0.0';
851         Result := URL + SUBJECT_FILENAME;
852
853 end;
854
855 // \83T\83u\83W\83F\83N\83g\83t\83@\83C\83\8b\96¼\8eæ\93¾\81i\83p\83X\81{\83t\83@\83C\83\8b\96¼\81j
856 function TBoard.GetSubjectFileName: string;
857 begin
858         Result := ParentCategory.ParentBBS2ch.GetLogFolder
859                                         + BBSID + PATH_DELIM + SUBJECT_FILENAME;
860 end;
861
862 // \83C\83\93\83f\83b\83N\83X\83t\83@\83C\83\8b\96¼(folder.idx)\8eæ\93¾\81i\83p\83X\81{\83t\83@\83C\83\8b\96¼\81j
863 function TBoard.GetFolderIndexFileName: string;
864 begin
865         Result := ParentCategory.ParentBBS2ch.GetLogFolder
866                                         + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME;
867 end;
868
869 // \83X\83\8c\97§\82Ä\91\97\90MURL
870 function TBoard.GetSendURL: string;
871 begin
872         Result := GikoSys.UrlToServer(URL) + 'test/subbbs.cgi';
873 end;
874
875 procedure TBoard.SetRound(b: Boolean);
876 begin
877         if b then
878                 RoundList.Add(Self)
879         else
880                 RoundList.Delete(Self);
881         if FRound = b then Exit;
882         FRound := b;
883         if FUpdate then
884                 FModified := True;
885 end;
886
887 procedure TBoard.SetRoundName(s: string);
888 begin
889         if FRoundName = s then Exit;
890         FRoundName := s;
891         if FUpdate then
892                 FModified := True;
893 end;
894
895 procedure TBoard.SetLastModified(d: TDateTime);
896 begin
897         if FLastModified = d then Exit;
898         FLastModified := d;
899         if FUpdate then
900                 FModified := True;
901 end;
902
903 procedure TBoard.SetLastGetTime(d: TDateTime);
904 begin
905         if FLastGetTime = d then Exit;
906         FLastGetTime := d;
907         if FUpdate then
908                 FModified := True;
909 end;
910
911 procedure TBoard.SetUnRead(i: Integer);
912 begin
913         if FUnRead = i then Exit;
914         if i < 0 then i := 0;
915         FUnRead := i;
916         if FUpdate then
917                 FModified := True;
918 end;
919
920 procedure TBoard.SetKotehanName(s: string);
921 begin
922         if FKotehanName = s then Exit;
923         FKotehanName := s;
924         if FUpdate then
925                 FModified := True;
926 end;
927
928 procedure TBoard.SetKotehanMail(s: string);
929 begin
930         if FKotehanMail = s then Exit;
931         FKotehanMail := s;
932         if FUpdate then
933                 FModified := True;
934 end;
935
936 function TBoard.GetNewThreadCount: Integer;
937 var
938         i: Integer;
939 begin
940         Result := 0;
941         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
942         begin
943                 for i := 0 to Count - 1 do begin
944                         if Items[i].NewArrival then
945                                 inc(Result);
946                 end;
947         end else begin
948                 for i := 0 to Count - 1 do begin
949                         if Items[i].NewArrival then
950                         begin
951                                 if Items[i].ShortTitle = '' then
952                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
953                                 if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then
954                                         inc(Result);
955                         end;
956                 end;
957         end;
958 end;
959
960 function TBoard.GetLogThreadCount: Integer;
961 var
962         i: Integer;
963 begin
964         Result := 0;
965         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
966         begin
967                 for i := 0 to Count - 1 do begin
968                         if Items[i].IsLogFile then
969                                 inc(Result);
970                 end;
971         end else begin
972                 for i := 0 to Count - 1 do begin
973                         if Items[i].IsLogFile then
974                         begin
975                                 if Items[i].ShortTitle = '' then
976                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
977                                 if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then
978                                         inc(Result);
979                         end;
980                 end;
981         end;
982 end;
983
984 function TBoard.GetUserThreadCount: Integer;
985 var
986         i: Integer;
987 begin
988         Result := 0;
989         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
990                 Result := Count
991         else
992         for i := 0 to Count - 1 do begin
993                 if Items[i].ShortTitle = '' then
994                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
995                 if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then
996                         inc(Result);
997         end;
998 end;
999
1000 function TBoard.GetNewThread(Index: Integer): TThreadItem;
1001 var
1002         i: Integer;
1003         Cnt: Integer;
1004 begin
1005         Result := nil;
1006         Cnt := 0;
1007         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
1008         begin
1009                 for i := 0 to Count - 1 do begin
1010                         if Items[i].NewArrival then
1011                         begin
1012                                 if Index = Cnt then begin
1013                                         Result := Items[i];
1014                                         Exit;
1015                                 end;
1016                                 inc(Cnt);
1017                         end;
1018                 end;
1019         end else begin
1020                 for i := 0 to Count - 1 do begin
1021                         if Items[i].NewArrival then
1022                         begin
1023                                 if Items[i].ShortTitle = '' then
1024                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1025                                 if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1026                                         if Index = Cnt then begin
1027                                                 Result := Items[i];
1028                                                 Exit;
1029                                         end;
1030                                         inc(Cnt);
1031                                 end;
1032                         end;
1033                 end;
1034         end;
1035 end;
1036
1037 function TBoard.GetLogThread(Index: Integer): TThreadItem;
1038 var
1039         i: Integer;
1040         Cnt: Integer;
1041 begin
1042         Cnt := 0;
1043         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
1044         begin
1045                 for i := 0 to Count - 1 do begin
1046                         if Items[i].IsLogFile then
1047                         begin
1048                                 if Index = Cnt then begin
1049                                         Result := Items[i];
1050                                         Exit;
1051                                 end;
1052                                 inc(Cnt);
1053                         end;
1054                 end;
1055         end else begin
1056                 for i := 0 to Count - 1 do begin
1057                         if Items[i].IsLogFile then
1058                         begin
1059                                 if Items[i].ShortTitle = '' then
1060                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1061                                 if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1062                                         if Index = Cnt then begin
1063                                                 Result := Items[i];
1064                                                 Exit;
1065                                         end;
1066                                         inc(Cnt);
1067                                 end;
1068                         end;
1069                 end;
1070         end;
1071         Result := nil;
1072 end;
1073
1074 function TBoard.GetUserThread(Index: Integer): TThreadItem;
1075 var
1076         i: Integer;
1077         Cnt: Integer;
1078 begin
1079         Result := nil;
1080         Cnt := 0;
1081         if Length( ParentCategory.ParentBBS2ch.ShortSelectText ) = 0 then
1082         begin
1083                 for i := 0 to Count - 1 do begin
1084                         if Index = Cnt then
1085                         begin
1086                                 Result := Items[ i ];
1087                                 Exit;
1088                         end;
1089                         inc( Cnt );
1090                 end;
1091         end else begin
1092                 for i := 0 to Count - 1 do begin
1093                         if Items[i].ShortTitle = '' then
1094                                 Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1095                         if AnsiPos(ParentCategory.ParentBBS2ch.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1096                                 if Index = Cnt then begin
1097                                         Result := Items[i];
1098                                         Exit;
1099                                 end;
1100                                 inc(Cnt);
1101                         end;
1102                 end;
1103         end;
1104 end;
1105
1106 procedure TBoard.BeginUpdate;
1107 begin
1108         FUpdate := False;
1109 end;
1110
1111 procedure TBoard.EndUpdate;
1112 begin
1113         FUpdate := True;
1114 end;
1115
1116 {class function TBoard.GetColumnName(Index: Integer): string;
1117 begin
1118         Result := COLUMN_THREADITEM[Index];
1119 end;
1120
1121 class function TBoard.GetColumnCount: Integer;
1122 begin
1123         Result := Length(COLUMN_THREADITEM);
1124 end;}
1125
1126 //constructor TThreadItem.Create(AOwner: TComponent);
1127 constructor TThreadItem.Create;
1128 begin
1129         FNo := 0;
1130         FFileName := '';
1131         FTitle := '';
1132         FRoundDate := ZERO_DATE;
1133         FLastModified := ZERO_DATE;
1134         FCount := 0;
1135         FAllResCount := 0;
1136         FNewResCount := 0;
1137         FSize := 0;
1138         FRound := False;
1139         FIsLogFile := False;
1140         FParentBoard := nil;
1141         FKokomade := -1;
1142         FNewReceive := 0;
1143         FNewArrival := False;
1144
1145         FUpdate := True;
1146 end;
1147
1148 destructor TThreadItem.Destroy;
1149 begin
1150         inherited;
1151 end;
1152
1153 function TThreadItem.GetDatURL: string;
1154 var
1155         Protocol, Host, Path, Document, Port, Bookmark: string;
1156 begin
1157         Result := ParentBoard.URL
1158                                         + 'dat/'
1159                                         + FileName;
1160         if FDownloadHost <> '' then begin
1161                 GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1162                 Result := Format('%s://%s%s%s', [Protocol,
1163                                                                                                                                                  FDownloadHost,
1164                                                                                                                                                  Path,
1165                                                                                                                                                  Document]);
1166         end;
1167 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1168 //                                      + 'test/read.cgi/' + ParentBoard.BBSID + '/'
1169 //                                      + ChangeFileExt(FileName, '') + '/?raw='
1170 //                                      + IntToStr(ResNum) + '.' + IntToStr(ResSize);
1171 end;
1172
1173 function TThreadItem.GetDatgzURL: string;
1174         function isOldKako(s: string): Boolean;
1175         begin
1176                 Result := False;
1177                 if AnsiPos('piza.', s) <> 0 then
1178                         Result := True
1179                 else if AnsiPos('www.bbspink.', s) <> 0 then
1180                         Result := True
1181                 else if AnsiPos('tako.', s) <> 0 then
1182                         Result := True;
1183         end;
1184 var
1185         Protocol, Host, Path, Document, Port, Bookmark: string;
1186         DatNo: string;
1187 begin
1188         if FDownloadHost = '' then begin
1189                 DatNo := ChangeFileExt(FileName, '');
1190                 if isOldKako(ParentBoard.URL) then begin
1191                         Result := Format('%s%s/%.3s/%s.dat', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1192                 end else begin
1193                         if Length(DatNo) > 9 then begin
1194                                 //http://xxx.2ch.net/xxx/kako/9999/99999/999999999.dat.gz
1195                                 Result := Format('%s%s/%.4s/%.5s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo, DatNo]);
1196                         end else begin
1197                                 //http://xxx.2ch.net/xxx/kako/999/999999999.dat.gz
1198                                 Result := Format('%s%s/%.3s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1199                         end;
1200                 end;
1201         end else begin
1202                 Gikosys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1203                 DatNo := ChangeFileExt(Document, '');
1204                 if isOldKako(DownloadHost) then begin
1205                         Result := Format('%s://%s/%s/kako/%.3s/%s.dat', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1206                 end else begin
1207                         if Length(DatNo) > 9 then begin
1208                                 Result := Format('%s://%s/%s/kako/%.4s/%.5s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo, DatNo]);
1209                         end else begin
1210                                 Result := Format('%s://%s/%s/kako/%.3s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1211                         end;
1212                 end;
1213         end;
1214 end;
1215
1216 {function TThreadItem.GetOldDatgzURL: string;
1217 var
1218         Protocol, Host, Path, Document, Port, Bookmark: string;
1219 begin
1220         Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL,
1221                                                                                                                                                          'kako',
1222                                                                                                                                                          FileName,
1223                                                                                                                                                          FileName]);
1224         if FDownloadHost <> '' then begin
1225                 ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1226                 Result := Format('%s://%s%s%s', [Protocol,
1227                                                                                                                                                  DownloadHost,
1228                                                                                                                                                  Path,
1229                                                                                                                                                  Document]);
1230
1231         end;
1232 end;}
1233
1234 function TThreadItem.GetOfflawCgiURL(SessionID: string): string;
1235 //var
1236 //      Protocol, Host, Path, Document, Port, Bookmark: string;
1237 begin
1238 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1239 //                                      + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1240 //                                      + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1241         if FDownloadHost = '' then begin
1242                 Result := GikoSys.UrlToServer(ParentBoard.URL)
1243                                                 + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1244                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1245         end else begin
1246                 //http://news.2ch.net/test/offlaw.cgi/newsplus/1014038577/?raw=.196928&sid=
1247                 //GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1248                 Result := 'http://' + FDownloadHost
1249                                                 + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1250                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1251 //              Result := Format('%s://%s%s%s', [Protocol,
1252 //                                                                                                                                               DownloadHost,
1253 //                                                                                                                                               Path,
1254 //                                                                                                                                               Document]);
1255         end;
1256 end;
1257
1258 function TThreadItem.GetSendURL: string;
1259 begin
1260         Result := GikoSys.UrlToServer(ParentBoard.URL)
1261                                         + 'test/bbs.cgi';
1262 end;
1263
1264 procedure TThreadItem.DeleteLogFile;
1265 begin
1266         DeleteFile(GetThreadFileName);
1267     if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1268         DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
1269         FRoundDate := ZERO_DATE;
1270         FLastModified := ZERO_DATE;
1271         FSize := 0;
1272         FIsLogFile := False;
1273         FKokomade := -1;
1274         FNewReceive := 0;
1275         FNewArrival := False;
1276         FUnRead := False;
1277         FScrollTop := 0;
1278         FRound := False;
1279         FDownloadHost := '';
1280         FAgeSage := gasNone;
1281
1282         FCount := 0;
1283         FNewResCount := 0;
1284         FRoundName := '';
1285 end;
1286
1287 function TThreadItem.GetThreadFileName: string;
1288 begin
1289         Result := ParentBoard.ParentCategory.ParentBBS2ch.GetLogFolder
1290                                         + ParentBoard.BBSID + PATH_DELIM + FileName;
1291 end;
1292
1293 procedure TThreadItem.SetLastModified(d: TDateTime);
1294 begin
1295         if FLastModified = d then Exit;
1296         FLastModified := d;
1297         if FUpdate and (ParentBoard <> nil) then
1298                 ParentBoard.FModified := True;
1299 end;
1300
1301 {procedure TThreadItem.SetRoundNo(i: Integer);
1302 begin
1303         if FRoundNo = i then Exit;
1304         FRoundNo := i;
1305         if FUpdate and (ParentBoard <> nil) then
1306                 ParentBoard.FModified := True;
1307 end;}
1308
1309 procedure TThreadItem.SetRound(b: Boolean);
1310 begin
1311         if b then
1312                 RoundList.Add(Self)
1313         else
1314                 RoundList.Delete(Self);
1315         if FRound = b then Exit;
1316         FRound := b;
1317         if FUpdate and (ParentBoard <> nil) then
1318                 ParentBoard.FModified := True;
1319 end;
1320
1321 procedure TThreadItem.SetRoundName(s: string);
1322 begin
1323         if FRoundName = s then Exit;
1324         FRoundName := s;
1325         if FUpdate and (ParentBoard <> nil) then
1326                 ParentBoard.FModified := True;
1327 end;
1328
1329 procedure TThreadItem.SetKokomade(i: Integer);
1330 begin
1331         if FKokomade = i then Exit;
1332         FKokomade := i;
1333         if FUpdate and (ParentBoard <> nil) then
1334                 ParentBoard.FModified := True;
1335 end;
1336
1337 procedure TThreadItem.SetUnRead(b: Boolean);
1338 begin
1339         if FUnRead = b then Exit;
1340         FUnRead := b;
1341         if FUpdate and (ParentBoard <> nil) then
1342                 ParentBoard.FModified := True;
1343 end;
1344
1345 procedure TThreadItem.SetScrollTop(i: Integer);
1346 begin
1347         if FScrollTop = i then Exit;
1348         FScrollTop := i;
1349         if FUpdate and (ParentBoard <> nil) then
1350                 ParentBoard.FModified := True;
1351 end;
1352
1353 procedure TThreadItem.BeginUpdate;
1354 begin
1355         FUpdate := False;
1356 end;
1357
1358 procedure TThreadItem.EndUpdate;
1359 begin
1360         FUpdate := True;
1361 end;
1362
1363 {initialization
1364         BBS2ch := TBBS2ch.Create;
1365
1366 finalization
1367         if BBS2ch <> nil then
1368                 BBS2ch.Free;}
1369 end.
1370