OSDN Git Service

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