OSDN Git Service

・TBoard および TThreadItem のコンストラクタは
[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, ExternalBoardPlugInMain;
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         TBBS = 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         TBBS = 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                 function Add(item: TCategory): integer;
91                 procedure Delete(index: integer);
92                 procedure Clear; override;
93                 function Find(key: string): TCategory;
94                 function FindBBSID(BBSID: string): TBoard;
95                 function FindBoardFromTitle(Title: string): TBoard;
96                 function FindBoardFromURL(inURL: string): TBoard;
97                 function FindThreadFromURL( inURL : string ) : TThreadItem;
98                 function FindThreadItem(BBSID: string; FileName: string): TThreadItem;
99                 function GetLogFolder: string;
100
101                 property Items[index: integer]: TCategory read GetCategory write SetCategory;
102                 property Title: string read FTitle write FTitle;
103                 property NodeExpand: Boolean read FExpand write FExpand;
104                                                                                  
105                 property KubetsuChk: Boolean read FKubetsuChk write FKubetsuChk;
106                 property SelectText: string read FSelectText write SetSelectText;
107                 property ShortSelectText: string read FShortSelectText write FShortSelectText;
108         end;
109
110         //\83J\83e\83S\83\8a
111         TCategory = class(TList)
112         private
113                 FNo: Integer;
114                 FTitle: string;
115                 FParenTBBS: TBBS;
116                 FExpand: Boolean;
117
118                 function GetBoard(index: integer): TBoard;
119                 procedure SetBoard(index: integer; value: TBoard);
120         public
121                 constructor Create;
122                 destructor Destroy; override;
123
124                 property No: Integer read FNo write FNo;
125                 property Title: string read FTitle write FTitle;
126                 property Items[index: integer]: TBoard read GetBoard write SetBoard;
127                 property ParenTBBS: TBBS read FParenTBBS write FParenTBBS;
128
129                 function Add(item: TBoard): integer;
130                 procedure Delete(index: integer);
131                 procedure Clear; override;
132                 function FindName(key: string): TBoard;
133                 function FindBBSID(BBSID: string): TBoard;
134                 function FindBoardFromTitle(Title: string): TBoard;
135                 function FindBoardFromURL(inURL: string): TBoard;
136                 function FindThreadFromURL( inURL : string ) : TThreadItem;
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                 procedure Create; overload;
185         public
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 FindThreadFromURL( inURL : string ) : TThreadItem;
220                 function GetIndex(ItemFileName: string): Integer;
221                 function GetIndexFromURL(URL: string): Integer;
222                 procedure LoadSettings;
223                 procedure SaveSettings;
224                 function GetReadCgiURL: string;
225                 function GetSubjectFileName: string;
226                 function GetFolderIndexFileName: string;
227                 function GetSendURL: string;
228
229                 function GetNewThreadCount: Integer;
230                 function GetLogThreadCount: Integer;
231                 function GetUserThreadCount: Integer;
232                 function GetNewThread(Index: Integer): TThreadItem;
233                 function GetLogThread(Index: Integer): TThreadItem;
234                 function GetUserThread(Index: Integer): TThreadItem;
235
236                 procedure BeginUpdate;
237                 procedure EndUpdate;
238                 property NodeExpand: Boolean read FExpand write FExpand;
239                 property BoolData: Boolean read FBoolData write FBoolData;
240                 property SPID: string read FSPID write FSPID;
241                 property PON: string read FPON write FPON;
242                 property KotehanName: string read FKotehanName write SetKotehanName;
243                 property KotehanMail: string read FKotehanMail write SetKotehanMail;
244         end;
245
246         //\83X\83\8c
247         TThreadItem = class(TObject)
248         private
249                 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é)
250
251                 FNo: Integer;                                                   //\94Ô\8d\86
252                 FFileName: string;                              //\83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
253                 FTitle: string;                                         //\83X\83\8c\83b\83h\83^\83C\83g\83\8b
254                 FShortTitle: string;                    //\92Z\82¢\83X\83\8c\83b\83h\83^\83C\83g\83\8b\81i\8c\9f\8dõ\97p\81j
255                 FRoundDate: TDateTime;          //\83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
256                 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
257                 FCount: Integer;                                        //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
258                 FAllResCount: Integer;          //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
259                 FNewResCount: Integer;          //\83X\83\8c\83b\83h\90V\92\85\90\94
260                 FSize: Integer;                                         //\83X\83\8c\83b\83h\83T\83C\83Y
261                 FRound: Boolean;                                        //\8f\84\89ñ\83t\83\89\83O
262                 FRoundName: string;                             //\8f\84\89ñ\96¼
263                 FIsLogFile: Boolean;                    //\83\8d\83O\91\8dÝ\83t\83\89\83O
264                 FParentBoard: TBoard;                   //\90e\83{\81[\83h
265                 FKokomade: Integer;                             //\83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
266                 FNewReceive: Integer;           //\83R\83R\82©\82ç\90V\8bK\8eó\90M
267                 FNewArrival: Boolean;                   //\90V\92\85
268                 FUnRead: Boolean;                                       //\96¢\93Ç\83t\83\89\83O
269                 FScrollTop: Integer;                    //\83X\83N\83\8d\81[\83\8b\88Ê\92u
270                 FDownloadHost: string;          //\8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
271                 FAgeSage: TGikoAgeSage;         //\83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
272 //              FSPID: string;                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
273
274                 FUpdate: Boolean;
275                 FExpand: Boolean;
276                 FURL                                    : string;                               // \82±\82Ì\83X\83\8c\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
277                 FBoardPlugIn    : TBoardPlugIn; // \82±\82Ì\83X\83\8c\82ð\83T\83|\81[\83g\82·\82é\83v\83\89\83O\83C\83\93
278                 FFilePath                       : string;                               // \82±\82Ì\83X\83\8c\82ª\95Û\91\82³\82ê\82Ä\82¢\82é\83p\83X
279                 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
280
281                 procedure SetLastModified(d: TDateTime);
282                 procedure SetRound(b: Boolean);
283                 procedure SetRoundName(s: string);
284                 procedure SetKokomade(i: Integer);
285                 procedure SetUnRead(b: Boolean);
286                 procedure SetScrollTop(i: Integer);
287                 procedure Create; overload;
288         public
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 FURL 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         function        BBSsFindBoardFromBBSID( inBBSID : string ) : TBoard;
355         function        BBSsFindBoardFromURL( inURL : string ) : TBoard;
356         function        BBSsFindBoardFromTitle( inTitle : string ) : TBoard;
357         function        BBSsFindThreadFromURL( inURL : string ) : TThreadItem;
358
359 var
360         BBSs            : array of TBBS;
361
362 implementation
363
364 uses
365         GikoSystem, RoundData;
366
367 const
368         BBS2CH_NAME:                                     string = '\82Q\82¿\82á\82ñ\82Ë\82é';
369         BBS2CH_LOG_FOLDER:               string = '2ch';
370
371         FOLDER_INI_FILENAME:     string = 'Folder.ini';
372         FOLDER_INDEX_FILENAME: string   = 'Folder.idx';
373         SUBJECT_FILENAME:                       string  = 'subject.txt';
374         PATH_DELIM:                                             string  = '\';
375         //DEFAULT_LIST_COUNT:           Integer = 100;
376
377 //      COLUMN_CATEGORY:         array[0..0] of string = ('\83J\83e\83S\83\8a\96¼');
378 //      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');
379 //      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');
380
381 function        BBSsFindBoardFromBBSID(
382         inBBSID         : string
383 ) : TBoard;
384 var
385         i, bound        : Integer;
386 begin
387
388         bound := Length( BBSs ) - 1;
389         for i := 0 to bound do begin
390                 Result := BBSs[ i ].FindBBSID( inBBSID );
391                 if Result <> nil then
392                         Exit;
393         end;
394
395         Result := nil;
396
397 end;
398
399 function        BBSsFindBoardFromURL(
400         inURL                   : string
401 ) : TBoard;
402 var
403         i, bound        : Integer;
404 begin
405
406         bound := Length( BBSs ) - 1;
407         for i := 0 to bound do begin
408                 Result := BBSs[ i ].FindBoardFromURL( inURL );
409                 if Result <> nil then
410                         Exit;
411         end;
412
413         Result := nil;
414
415 end;
416
417 function        BBSsFindBoardFromTitle(
418         inTitle         : string
419 ) : TBoard;
420 var
421         i, bound        : Integer;
422 begin
423
424         bound := Length( BBSs ) - 1;
425         for i := 0 to bound do begin
426                 Result := BBSs[ i ].FindBoardFromTitle( inTitle );
427                 if Result <> nil then
428                         Exit;
429         end;
430
431         Result := nil;
432
433 end;
434
435 function        BBSsFindThreadFromURL(
436         inURL                   : string
437 ) : TThreadItem;
438 var
439         i, bound        : Integer;
440 begin
441
442         bound := Length( BBSs ) - 1;
443         for i := 0 to bound do begin
444                 Result := BBSs[ i ].FindThreadFromURL( inURL );
445                 if Result <> nil then
446                         Exit;
447         end;
448
449         Result := nil;
450
451 end;
452
453 (*************************************************************************
454  *\8b@\94\\96¼\81FTBBS\83R\83\93\83X\83g\83\89\83N\83^
455  *Public
456  *************************************************************************)
457 constructor TBBS.Create(LogFolder: string);
458 begin
459         Title := BBS2CH_NAME;
460         FLogFolder := LogFolder;
461 end;
462
463 (*************************************************************************
464  *\8b@\94\\96¼\81FTBBS\83f\83X\83g\83\89\83N\83^
465  *Public
466  *************************************************************************)
467 destructor TBBS.Destroy;
468 begin
469         Clear;
470         inherited;
471 end;
472
473 (*************************************************************************
474  *\8b@\94\\96¼\81F
475  *Public
476  *************************************************************************)
477 function TBBS.GetCategory(index: integer): TCategory;
478 begin
479         Result := TCategory(inherited Items[index]);
480 end;
481
482 procedure TBBS.SetCategory(index: integer; value: TCategory);
483 begin
484         inherited Items[index] := value;
485 end;
486
487 function TBBS.Add(item: TCategory): integer;
488 begin
489         Item.ParenTBBS := self;
490         Result := inherited Add(item);
491 end;
492
493 procedure TBBS.Delete(index: integer);
494 begin
495         if Items[index] <> nil then
496                 TCategory(Items[index]).Free;
497         Items[index] := nil;
498         inherited Delete(index);
499 end;
500
501 procedure TBBS.Clear;
502 var
503         i: integer;
504 begin
505         for i := Count - 1 downto 0 do
506                 Delete(i);
507 end;
508
509 function TBBS.Find(key: string): TCategory;
510 begin
511         Result := nil;
512 end;
513
514 function TBBS.FindBBSID(BBSID: string): TBoard;
515 var
516         i: Integer;
517         Category: TCategory;
518         Board: TBoard;
519 begin
520         Result := nil;
521         for i := 0 to Count - 1 do begin
522                 Category := Items[i];
523                 Board := Category.FindBBSID(BBSID);
524                 if Board <> nil then begin
525                         Result := Board;
526                         Exit;
527                 end;
528         end;
529 end;
530
531 //*************************************************************************
532 // \83^\83C\83g\83\8b\82Ì\88ê\92v\82·\82é\94Â\82ð\92T\82·
533 //*************************************************************************)
534 function TBBS.FindBoardFromTitle(Title: string): TBoard;
535 var
536         i: Integer;
537         Category: TCategory;
538         Board: TBoard;
539 begin
540         Result := nil;
541         for i := 0 to Count - 1 do begin
542                 Category := Items[i];
543                 Board := Category.FindBoardFromTitle(Title);
544                 if Board <> nil then begin
545                         Result := Board;
546                         Exit;
547                 end;
548         end;
549 end;
550
551 //*************************************************************************
552 // URL \82ð\8eó\82¯\95t\82¯\82é\94Â\82ð\92T\82·
553 //*************************************************************************)
554 function TBBS.FindBoardFromURL(inURL: string): TBoard;
555 var
556         i: Integer;
557         Category: TCategory;
558         Board: TBoard;
559 begin
560         Result := nil;
561         for i := 0 to Count - 1 do begin
562                 Category := Items[i];
563                 Board := Category.FindBoardFromURL(inURL);
564                 if Board <> nil then begin
565                         Result := Board;
566                         Exit;
567                 end;
568         end;
569 end;
570
571 //*************************************************************************
572 // URL \82ð\8eó\82¯\95t\82¯\82é\83X\83\8c\83b\83h\82ð\92T\82·
573 //*************************************************************************)
574 function TBBS.FindThreadFromURL(inURL: string): TThreadItem;
575 var
576         i: Integer;
577 begin
578         for i := 0 to Count - 1 do begin
579                 Result := Items[ i ].FindThreadFromURL( inURL );
580                 if Result <> nil then
581                         Exit;
582         end;
583         Result := nil;
584 end;
585
586 function TBBS.FindThreadItem(BBSID: string; FileName: string): TThreadItem;
587 var
588         Board: TBoard;
589 begin
590         Result := nil;
591         Board := FindBBSID(BBSID);
592         if Board = nil then
593                 Exit;
594         Result := Board.Find(FileName);
595 end;
596
597 (*************************************************************************
598  *\83\8d\83O\83t\83H\83\8b\83_\8eæ\93¾
599  *
600  *************************************************************************)
601 function TBBS.GetLogFolder: string;
602 begin
603         Result := IncludeTrailingPathDelimiter(FLogFolder)
604                                         + BBS2CH_LOG_FOLDER + PATH_DELIM;
605 end;
606
607 procedure TBBS.SetSelectText(s: string);
608 begin
609         FSelectText := s;
610         ShortSelectText := GikoSys.ZenToHan(s);
611 end;
612
613 {class function TBBS.GetColumnName(Index: Integer): string;
614 begin
615         Result := COLUMN_CATEGORY[Index];
616 end;
617
618 class function TBBS.GetColumnCount: Integer;
619 begin
620         Result := Length(COLUMN_CATEGORY);
621 end;}
622
623 //===================
624 //TCategory
625 //===================
626 constructor TCategory.Create;
627 begin
628 end;
629
630 destructor TCategory.Destroy;
631 begin
632         Clear;
633         inherited;
634 end;
635
636 function TCategory.GetBoard(index: integer): TBoard;
637 begin
638         Result := TBoard(inherited Items[index]);
639 end;
640
641 procedure TCategory.SetBoard(index: integer; value: TBoard);
642 begin
643         inherited Items[index] := value;
644 end;
645
646 function TCategory.Add(item: TBoard): integer;
647 begin
648         Item.ParentCategory := self;
649         Result := inherited Add(item);
650 end;
651
652 procedure TCategory.Delete(index: integer);
653 begin
654         if Items[index] <> nil then
655                 TBoard(Items[index]).Free;
656         Items[index] := nil;
657         inherited Delete(index);
658 end;
659
660 procedure TCategory.Clear;
661 var
662         i: integer;
663 begin
664         for i := Count - 1 downto 0 do
665                 Delete(i);
666 end;
667
668 function TCategory.FindName(key: string): TBoard;
669 begin
670         Result := nil;
671 end;
672
673 function TCategory.FindBBSID(BBSID: string): TBoard;
674 var
675         i: integer;
676 begin
677         Result := nil;
678         for i := 0 to Count - 1 do begin
679                 if Items[i].FBBSID = BBSID then begin
680                         Result := Items[i];
681                         Exit;
682                 end;
683         end;
684 end;
685
686 //*************************************************************************
687 // \83^\83C\83g\83\8b\82Ì\88ê\92v\82·\82é\94Â\82ð\92T\82·
688 //*************************************************************************)
689 function TCategory.FindBoardFromTitle(Title: string): TBoard;
690 var
691         i: integer;
692 begin
693         Result := nil;
694         for i := 0 to Count - 1 do begin
695                 if Items[i].FTitle = Title then begin
696                         Result := Items[i];
697                         Exit;
698                 end;
699         end;
700 end;
701
702 //*************************************************************************
703 // URL \82ð\8eó\82¯\95t\82¯\82é\94Â\82ð\92T\82·
704 //*************************************************************************)
705 function TCategory.FindBoardFromURL(inURL: string): TBoard;
706 var
707         i: integer;
708 begin
709         Result := nil;
710         for i := 0 to Count - 1 do begin
711                 if Pos( Items[i].URL, inURL ) = 1 then begin
712                         Result := Items[i];
713                         Exit;
714                 end;
715         end;
716 end;
717
718 //*************************************************************************
719 // URL \82ð\8eó\82¯\95t\82¯\82é\83X\83\8c\83b\83h\82ð\92T\82·
720 //*************************************************************************)
721 function TCategory.FindThreadFromURL(inURL: string): TThreadItem;
722 var
723         i                                               : Integer;
724 begin
725
726         for i := 0 to Count - 1 do begin
727                 Result := Items[ i ].FindThreadFromURL( inURL );
728                 if Result <> nil then
729                         Exit;
730         end;
731         Result := nil;
732
733 end;
734
735 function TCategory.IsMidoku: Boolean;
736 var
737         i: Integer;
738         j: Integer;
739 begin
740         Result := False;
741         for i := 0 to Count - 1 do begin
742                 if Items[i] <> nil then begin
743                         for j := 0 to Items[i].Count - 1 do begin
744                                 if Items[i].Items[j] <> nil then begin
745 //                                      if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].Count > Items[i].Items[j].Kokomade) then begin
746                                         if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].UnRead) then begin
747                                                 Result := True;
748                                                 Exit;
749                                         end;
750                                 end;
751                         end;
752                 end;
753         end;
754 end;
755
756 {class function TCategory.GetColumnName(Index: Integer): string;
757 begin
758         Result := COLUMN_BOARD[Index];
759 end;
760
761 class function TCategory.GetColumnCount: Integer;
762 begin
763         Result := Length(COLUMN_BOARD);
764 end;}
765
766 //===================
767 //TBoard
768 //===================
769 procedure TBoard.Create;
770 begin
771         FNo := 0;
772         FTitle := '';
773         FBBSID := '';
774         FURL := '';
775         FRound := False;
776         FRoundDate := ZERO_DATE;
777         FLastModified := ZERO_DATE;
778         FLastGetTime := ZERO_DATE;
779         FIsThreadDatRead := False;
780         FUnRead := 0;
781 //      FListStyle := vsReport;
782 //      FItemNoVisible := True;
783
784         FUpdate := True;
785
786         FBoardPlugIn := nil;
787 end;
788
789 // *************************************************************************
790 // \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^
791 // *************************************************************************
792 constructor TBoard.Create(
793         inPlugIn        : TBoardPlugIn;
794         inURL                   : string
795 );
796 begin
797
798         Create;
799
800         FBoardPlugIn    := inPlugIn;
801         URL                                             := inURL;
802         BBSID                                   := GikoSys.UrlToID( inURL );
803
804         // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
805         if inPlugIn <> nil then
806                 inPlugIn.CreateBoardItem( DWORD( Self ) );
807
808 end;
809
810 // *************************************************************************
811 // \83f\83X\83g\83\89\83N\83^
812 // *************************************************************************
813 destructor TBoard.Destroy;
814 begin
815         if FModified then begin
816                 GikoSys.WriteThreadDat(Self);
817                 SaveSettings;
818         end;
819
820         // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
821         if IsBoardPlugInAvailable then
822                 BoardPlugIn.DisposeBoardItem( DWORD( Self ) );
823
824         Clear;
825         inherited;
826 end;
827
828 // *************************************************************************
829 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
830 // *************************************************************************
831 function        TBoard.IsBoardPlugInAvailable : Boolean;
832 begin
833
834         repeat
835                 if BoardPlugIn = nil then
836                         Break;
837                         
838                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
839                         Break;
840
841                 Result := True;
842                 Exit;
843         until True;
844
845         Result := False;
846
847 end;
848
849 function TBoard.GetThreadItem(index: integer): TThreadItem;
850 begin
851         Result := TThreadItem(inherited Items[index]);
852 end;
853
854 procedure TBoard.SetThreadItem(index: integer; value: TThreadItem);
855 begin
856         inherited Items[index] := value;
857 end;
858
859 function TBoard.Add(Item: TThreadItem): Integer;
860 begin
861         Item.ParentBoard := Self;
862         Result := inherited Add(Item);
863 end;
864
865 procedure TBoard.Insert(Index: Integer; Item: TThreadItem);
866 begin
867         Item.ParentBoard := Self;
868         inherited Insert(Index, Item);
869 end;
870
871 //Index\82Å\8ew\92è\82³\82ê\82½\83X\83\8c\83b\83h\83I\83u\83W\83F\83N\83g\82ð\94j\8aü
872 procedure TBoard.Delete(index: Integer);
873 begin
874         if Items[index] <> nil then
875                 TThreadItem(Items[index]).Free;
876         Items[index] := nil;
877         inherited Delete(index);
878 end;
879
880 //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
881 procedure TBoard.DeleteList(index: integer);
882 begin
883         inherited Delete(index);
884 end;
885
886 procedure TBoard.Clear;
887 var
888         i: integer;
889 begin
890 //      FUnRead := 0;
891         for i := Count - 1 downto 0 do
892                 Delete(i);
893 end;
894
895 function TBoard.Find(ItemFileName: string): TThreadItem;
896 var
897         i: integer;
898 begin
899         Result := nil;
900         for i := 0 to Count - 1 do begin
901                 if Items[i].FileName = ItemFileName then begin
902                         Result := Items[i];
903                         Exit;
904                 end;
905         end;
906 end;
907
908 function TBoard.GetIndex(ItemFileName: string): Integer;
909 var
910         i: integer;
911 begin
912         Result := -1;
913         for i := 0 to Count - 1 do begin
914                 if Items[i].FileName = ItemFileName then begin
915                         Result := i;
916                         Exit;
917                 end;
918         end;
919 end;
920
921 function TBoard.GetIndexFromURL(URL: string): Integer;
922 var
923         i: integer;
924 begin
925         Result := -1;
926         for i := 0 to Count - 1 do begin
927                 if Items[i].URL = URL then begin
928                         Result := i;
929                         Exit;
930                 end;
931         end;
932 end;
933
934 function TBoard.FindThreadFromURL( inURL : string ) : TThreadItem;
935 var
936         i : Integer;
937 begin
938
939         if not IsThreadDatRead then
940                 GikoSys.ReadSubjectFile( Self );
941                 
942         for i := 0 to Count - 1 do begin
943                 if Pos( Items[ i ].URL, inURL ) = 1 then begin
944                         Result := Items[ i ];
945                         Exit;
946                 end;
947         end;
948         Result := nil;
949
950 end;
951
952 {function TBoard.GetMidokuCount: Integer;
953 var
954         i: integer;
955 begin
956         Result := 0;
957         for i := 0 to Count- 1 do begin
958                 if Items[i] <> nil then begin
959                         if (Items[i].IsLogFile) and (Items[i].Count > Items[i].Kokomade) then
960                                 inc(Result);
961                 end;
962         end;
963 end;
964 }
965
966 procedure TBoard.LoadSettings;
967 var
968         ini: TMemIniFile;
969         FileName: string;
970 begin
971         if Length( FilePath ) > 0 then
972                 FileName := ExtractFilePath( FilePath ) + FOLDER_INI_FILENAME
973         else
974                 FileName := ParentCategory.ParenTBBS.GetLogFolder
975                                                         + BBSID + PATH_DELIM + FOLDER_INI_FILENAME;
976
977         if not FileExists(FileName) then
978                 Exit;
979         ini := TMemIniFile.Create(FileName);
980         try
981 //              Round := ini.ReadBool('Status', 'Round', False);
982                 FRoundDate := ini.ReadDateTime('Status', 'RoundDate', ZERO_DATE);
983                 FLastModified := ini.ReadDateTime('Status', 'LastModified', ZERO_DATE);
984                 FLastGetTime := ini.ReadDateTime('Status', 'LastGetTime', ZERO_DATE);
985                 FUnRead := ini.ReadInteger('Status', 'UnRead', 0);
986                 FSPID := ini.ReadString('Cookie', 'SPID', '');
987                 FPON := ini.ReadString('Cookie', 'PON', '');
988                 FKotehanName := ini.ReadString('Kotehan', 'Name', '');
989                 FKotehanMail := ini.ReadString('Kotehan', 'Mail', '');
990 //              ListStyle := TViewStyle(Ord(ini.ReadInteger('Status', 'ListStyle', 3)));
991 //              ItemNoVisible := ini.ReadBool('Status', 'ItemNoVisible', True);
992 //              ViewType := TGikoViewType(Ord(ini.ReadInteger('Status', 'ViewType', 0)));
993                 if UnRead < 0 then
994                         UnRead := 0;
995         finally
996                 ini.Free;
997         end;
998 end;
999
1000 procedure TBoard.SaveSettings;
1001 var
1002         ini: TMemIniFile;
1003         FileName: string;
1004 begin
1005         if Length( FilePath ) > 0 then
1006                 FileName := ExtractFilePath( FilePath )
1007         else
1008                 FileName := ParentCategory.ParenTBBS.GetLogFolder
1009                                                         + BBSID + PATH_DELIM;
1010         if not GikoSys.DirectoryExistsEx(FileName) then
1011                 GikoSys.ForceDirectoriesEx(FileName);
1012         FileName := FileName + FOLDER_INI_FILENAME;
1013         ini := TMemIniFile.Create(FileName);
1014         try
1015                 if UnRead < 0 then
1016                         UnRead := 0;
1017 //              ini.WriteBool('Status', 'Round', Round);
1018                 ini.WriteDateTime('Status', 'RoundDate', FRoundDate);
1019                 ini.WriteDateTime('Status', 'LastModified', FLastModified);
1020                 ini.WriteDateTime('Status', 'LastGetTime', FLastGetTime);
1021                 ini.WriteInteger('Status', 'UnRead', FUnRead);
1022                 ini.WriteString('Cookie', 'SPID', FSPID);
1023                 ini.WriteString('Cookie', 'PON', FPON);
1024                 ini.WriteString('Kotehan', 'Name', FKotehanName);
1025                 ini.WriteString('Kotehan', 'Mail', FKotehanMail);
1026 //              ini.WriteInteger('Status', 'ListStyle', Ord(ListStyle));
1027 //              ini.WriteBool('Status', 'ItemNoVisible', ItemNoVisible);
1028 //              ini.WriteInteger('Status', 'ViewType', Ord(ViewType));
1029                 ini.UpdateFile;
1030         finally
1031                 ini.Free;
1032         end;
1033 end;
1034
1035 // \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
1036 function TBoard.GetReadCgiURL: string;
1037 begin
1038         //Result := URL + SUBJECT_FILENAME;
1039         //Result := GikoSys.UrlToServer(URL)
1040         //                              + 'test/read.cgi/' + BBSID + '/?raw=0.0';
1041         Result := URL + SUBJECT_FILENAME;
1042
1043 end;
1044
1045 // \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
1046 function TBoard.GetSubjectFileName: string;
1047 begin
1048         if Length( FilePath ) > 0 then
1049                 Result := FilePath
1050         else
1051                 Result := ParentCategory.ParenTBBS.GetLogFolder
1052                                                 + BBSID + PATH_DELIM + SUBJECT_FILENAME;
1053 end;
1054
1055 // \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
1056 function TBoard.GetFolderIndexFileName: string;
1057 begin
1058         if Length( FilePath ) > 0 then
1059                 Result := ExtractFilePath( FilePath ) + FOLDER_INDEX_FILENAME
1060         else
1061                 Result := ParentCategory.ParenTBBS.GetLogFolder
1062                                                 + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME;
1063 end;
1064
1065 // \83X\83\8c\97§\82Ä\91\97\90MURL
1066 function TBoard.GetSendURL: string;
1067 begin
1068         Result := GikoSys.UrlToServer(URL) + 'test/subbbs.cgi';
1069 end;
1070
1071 procedure TBoard.SetRound(b: Boolean);
1072 begin
1073         if b then
1074                 RoundList.Add(Self)
1075         else
1076                 RoundList.Delete(Self);
1077         if FRound = b then Exit;
1078         FRound := b;
1079         if FUpdate then
1080                 FModified := True;
1081 end;
1082
1083 procedure TBoard.SetRoundName(s: string);
1084 begin
1085         if FRoundName = s then Exit;
1086         FRoundName := s;
1087         if FUpdate then
1088                 FModified := True;
1089 end;
1090
1091 procedure TBoard.SetLastModified(d: TDateTime);
1092 begin
1093         if FLastModified = d then Exit;
1094         FLastModified := d;
1095         if FUpdate then
1096                 FModified := True;
1097 end;
1098
1099 procedure TBoard.SetLastGetTime(d: TDateTime);
1100 begin
1101         if FLastGetTime = d then Exit;
1102         FLastGetTime := d;
1103         if FUpdate then
1104                 FModified := True;
1105 end;
1106
1107 procedure TBoard.SetUnRead(i: Integer);
1108 begin
1109         if FUnRead = i then Exit;
1110         if i < 0 then i := 0;
1111         FUnRead := i;
1112         if FUpdate then
1113                 FModified := True;
1114 end;
1115
1116 procedure TBoard.SetKotehanName(s: string);
1117 begin
1118         if FKotehanName = s then Exit;
1119         FKotehanName := s;
1120         if FUpdate then
1121                 FModified := True;
1122 end;
1123
1124 procedure TBoard.SetKotehanMail(s: string);
1125 begin
1126         if FKotehanMail = s then Exit;
1127         FKotehanMail := s;
1128         if FUpdate then
1129                 FModified := True;
1130 end;
1131
1132 function TBoard.GetNewThreadCount: Integer;
1133 var
1134         i: Integer;
1135 begin
1136         Result := 0;
1137                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1138                                 begin
1139                                         for i := 0 to Count - 1 do begin
1140                                                 if Items[i].NewArrival then
1141                                                         inc(Result);
1142                                         end;
1143                                 end else begin
1144                                         for i := 0 to Count - 1 do begin
1145                                                                                                 if Items[i].NewArrival then
1146                                                                                                 begin
1147                                                                                                                                 if Items[i].ShortTitle = '' then
1148                                                                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1149                                                                                                                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1150                                                                                                                                                                 inc(Result);
1151                                                                                                 end;
1152                                         end;
1153                                 end;
1154 end;
1155
1156 function TBoard.GetLogThreadCount: Integer;
1157 var
1158         i: Integer;
1159 begin
1160         Result := 0;
1161                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1162                                 begin
1163                                         for i := 0 to Count - 1 do begin
1164                                                 if Items[i].IsLogFile then
1165                                                         inc(Result);
1166                                         end;
1167                                 end else begin
1168                                         for i := 0 to Count - 1 do begin
1169                                                 if Items[i].IsLogFile then
1170                                                                                                 begin
1171                                                                                                                                 if Items[i].ShortTitle = '' then
1172                                                                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1173                                                                                                                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1174                                                                                                                                                                 inc(Result);
1175                                                                                                 end;
1176                                         end;
1177                                 end;
1178 end;
1179
1180 function TBoard.GetUserThreadCount: Integer;
1181 var
1182         i: Integer;
1183 begin
1184         Result := 0;
1185                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1186                                                                 Result := Count
1187                                 else
1188         for i := 0 to Count - 1 do begin
1189                 if Items[i].ShortTitle = '' then
1190                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1191                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1192                         inc(Result);
1193         end;
1194 end;
1195
1196 function TBoard.GetNewThread(Index: Integer): TThreadItem;
1197 var
1198         i: Integer;
1199         Cnt: Integer;
1200 begin
1201         Result := nil;
1202         Cnt := 0;
1203                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1204                                 begin
1205                                         for i := 0 to Count - 1 do begin
1206                                                 if Items[i].NewArrival then
1207                                                                                                 begin
1208                                                         if Index = Cnt then begin
1209                                                                 Result := Items[i];
1210                                                                 Exit;
1211                                                         end;
1212                                                         inc(Cnt);
1213                                                 end;
1214                                         end;
1215                                 end else begin
1216                                         for i := 0 to Count - 1 do begin
1217                                                 if Items[i].NewArrival then
1218                                                                                                 begin
1219                                                                                 if Items[i].ShortTitle = '' then
1220                                                                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1221                                                                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1222                                                                                         if Index = Cnt then begin
1223                                                                                                 Result := Items[i];
1224                                                                                                 Exit;
1225                                                                                         end;
1226                                                                                         inc(Cnt);
1227                                                                                                                                 end;
1228                                                                                                 end;
1229                                         end;
1230                                 end;
1231 end;
1232
1233 function TBoard.GetLogThread(Index: Integer): TThreadItem;
1234 var
1235         i: Integer;
1236         Cnt: Integer;
1237 begin
1238                                 Cnt := 0;
1239                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1240                                 begin
1241                                         for i := 0 to Count - 1 do begin
1242                                                 if Items[i].IsLogFile then
1243                                                                                                 begin
1244                                                         if Index = Cnt then begin
1245                                                                 Result := Items[i];
1246                                                                 Exit;
1247                                                         end;
1248                                                         inc(Cnt);
1249                                                 end;
1250                                         end;
1251                                 end else begin
1252                                         for i := 0 to Count - 1 do begin
1253                                                 if Items[i].IsLogFile then
1254                                                                                                 begin
1255                                                                                 if Items[i].ShortTitle = '' then
1256                                                                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1257                                                                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1258                                                                                         if Index = Cnt then begin
1259                                                                                                 Result := Items[i];
1260                                                                                                 Exit;
1261                                                                                         end;
1262                                                                                         inc(Cnt);
1263                                                                                                                                 end;
1264                                                                                                 end;
1265                                         end;
1266                                 end;
1267                                 Result := nil;
1268 end;
1269
1270 function TBoard.GetUserThread(Index: Integer): TThreadItem;
1271 var
1272         i: Integer;
1273         Cnt: Integer;
1274 begin
1275         Result := nil;
1276         Cnt := 0;
1277                                 if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1278                                 begin
1279                                                                 for i := 0 to Count - 1 do begin
1280                                                                                                 if Index = Cnt then
1281                                                                                                 begin
1282                                                                                                                                 Result := Items[ i ];
1283                                                                                                                                 Exit;
1284                                                                                                 end;
1285                                                                                                 inc( Cnt );
1286                                                                 end;
1287                                 end else begin
1288                                         for i := 0 to Count - 1 do begin
1289                                                 if Items[i].ShortTitle = '' then
1290                                                         Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title);
1291                                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1292                                                         if Index = Cnt then begin
1293                                                                 Result := Items[i];
1294                                                                 Exit;
1295                                                         end;
1296                                                         inc(Cnt);
1297                                                 end;
1298                                         end;
1299                                 end;
1300 end;
1301
1302 procedure TBoard.BeginUpdate;
1303 begin
1304         FUpdate := False;
1305 end;
1306
1307 procedure TBoard.EndUpdate;
1308 begin
1309         FUpdate := True;
1310 end;
1311
1312 {class function TBoard.GetColumnName(Index: Integer): string;
1313 begin
1314         Result := COLUMN_THREADITEM[Index];
1315 end;
1316
1317 class function TBoard.GetColumnCount: Integer;
1318 begin
1319         Result := Length(COLUMN_THREADITEM);
1320 end;}
1321
1322 //constructor TThreadItem.Create(AOwner: TComponent);
1323 procedure TThreadItem.Create;
1324 begin
1325         FNo := 0;
1326         FFileName := '';
1327         FTitle := '';
1328         FRoundDate := ZERO_DATE;
1329         FLastModified := ZERO_DATE;
1330         FCount := 0;
1331         FAllResCount := 0;
1332         FNewResCount := 0;
1333         FSize := 0;
1334         FRound := False;
1335         FIsLogFile := False;
1336         FParentBoard := nil;
1337         FKokomade := -1;
1338         FNewReceive := 0;
1339         FNewArrival := False;
1340
1341         FUpdate := True;
1342         FURL := '';
1343         FBoardPlugIn := nil;
1344 end;
1345
1346 // *************************************************************************
1347 // \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^
1348 // *************************************************************************
1349 constructor TThreadItem.Create(
1350         inPlugIn        : TBoardPlugIn;
1351         inURL                   : string
1352 );
1353 begin
1354
1355         Create;
1356
1357         FBoardPlugIn    := inPlugIn;
1358         URL                                             := inURL;
1359
1360         // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1361         if inPlugIn <> nil then
1362                 inPlugIn.CreateThreadItem( DWORD( Self ) );
1363
1364 end;
1365
1366 // *************************************************************************
1367 // \83f\83X\83g\83\89\83N\83^
1368 // *************************************************************************
1369 destructor TThreadItem.Destroy;
1370 begin
1371
1372         // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1373         if IsBoardPlugInAvailable then
1374                 FBoardPlugIn.DisposeThreadItem( DWORD( Self ) );
1375
1376         inherited;
1377
1378 end;
1379
1380 // *************************************************************************
1381 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
1382 // *************************************************************************
1383 function        TThreadItem.IsBoardPlugInAvailable : Boolean;
1384 begin
1385
1386         repeat
1387                 if BoardPlugIn = nil then
1388                         Break;
1389
1390                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
1391                         Break;
1392
1393                 Result := True;
1394                 Exit;
1395         until True;
1396
1397         Result := False;
1398
1399 end;
1400
1401 function TThreadItem.GetDatURL: string;
1402 var
1403         Protocol, Host, Path, Document, Port, Bookmark: string;
1404 begin
1405         Result := ParentBoard.URL
1406                                         + 'dat/'
1407                                         + FileName;
1408         if FDownloadHost <> '' then begin
1409                 GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1410                 Result := Format('%s://%s%s%s', [Protocol,
1411                                                                                                                                                  FDownloadHost,
1412                                                                                                                                                  Path,
1413                                                                                                                                                  Document]);
1414         end;
1415 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1416 //                                      + 'test/read.cgi/' + ParentBoard.BBSID + '/'
1417 //                                      + ChangeFileExt(FileName, '') + '/?raw='
1418 //                                      + IntToStr(ResNum) + '.' + IntToStr(ResSize);
1419 end;
1420
1421 function TThreadItem.GetDatgzURL: string;
1422         function isOldKako(s: string): Boolean;
1423         begin
1424                 Result := False;
1425                 if AnsiPos('piza.', s) <> 0 then
1426                         Result := True
1427                 else if AnsiPos('www.bbspink.', s) <> 0 then
1428                         Result := True
1429                 else if AnsiPos('tako.', s) <> 0 then
1430                         Result := True;
1431         end;
1432 var
1433         Protocol, Host, Path, Document, Port, Bookmark: string;
1434         DatNo: string;
1435 begin
1436         if FDownloadHost = '' then begin
1437                 DatNo := ChangeFileExt(FileName, '');
1438                 if isOldKako(ParentBoard.URL) then begin
1439                         Result := Format('%s%s/%.3s/%s.dat', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1440                 end else begin
1441                         if Length(DatNo) > 9 then begin
1442                                 //http://xxx.2ch.net/xxx/kako/9999/99999/999999999.dat.gz
1443                                 Result := Format('%s%s/%.4s/%.5s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo, DatNo]);
1444                         end else begin
1445                                 //http://xxx.2ch.net/xxx/kako/999/999999999.dat.gz
1446                                 Result := Format('%s%s/%.3s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1447                         end;
1448                 end;
1449         end else begin
1450                 Gikosys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1451                 DatNo := ChangeFileExt(Document, '');
1452                 if isOldKako(DownloadHost) then begin
1453                         Result := Format('%s://%s/%s/kako/%.3s/%s.dat', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1454                 end else begin
1455                         if Length(DatNo) > 9 then begin
1456                                 Result := Format('%s://%s/%s/kako/%.4s/%.5s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo, DatNo]);
1457                         end else begin
1458                                 Result := Format('%s://%s/%s/kako/%.3s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1459                         end;
1460                 end;
1461         end;
1462 end;
1463
1464 {function TThreadItem.GetOldDatgzURL: string;
1465 var
1466         Protocol, Host, Path, Document, Port, Bookmark: string;
1467 begin
1468         Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL,
1469                                                                                                                                                          'kako',
1470                                                                                                                                                          FileName,
1471                                                                                                                                                          FileName]);
1472         if FDownloadHost <> '' then begin
1473                 ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1474                 Result := Format('%s://%s%s%s', [Protocol,
1475                                                                                                                                                  DownloadHost,
1476                                                                                                                                                  Path,
1477                                                                                                                                                  Document]);
1478
1479         end;
1480 end;}
1481
1482 function TThreadItem.GetOfflawCgiURL(SessionID: string): string;
1483 //var
1484 //      Protocol, Host, Path, Document, Port, Bookmark: string;
1485 begin
1486 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1487 //                                      + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1488 //                                      + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1489         if FDownloadHost = '' then begin
1490                 Result := GikoSys.UrlToServer(ParentBoard.URL)
1491                                                 + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1492                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1493         end else begin
1494                 //http://news.2ch.net/test/offlaw.cgi/newsplus/1014038577/?raw=.196928&sid=
1495                 //GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1496                 Result := 'http://' + FDownloadHost
1497                                                 + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1498                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1499 //              Result := Format('%s://%s%s%s', [Protocol,
1500 //                                                                                                                                               DownloadHost,
1501 //                                                                                                                                               Path,
1502 //                                                                                                                                               Document]);
1503         end;
1504 end;
1505
1506 function TThreadItem.GetSendURL: string;
1507 begin
1508         Result := GikoSys.UrlToServer(ParentBoard.URL)
1509                                         + 'test/bbs.cgi';
1510 end;
1511
1512 procedure TThreadItem.DeleteLogFile;
1513 begin
1514         DeleteFile(GetThreadFileName);
1515                 if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1516                         DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
1517         FRoundDate := ZERO_DATE;
1518         FLastModified := ZERO_DATE;
1519         FSize := 0;
1520         FIsLogFile := False;
1521         FKokomade := -1;
1522         FNewReceive := 0;
1523         FNewArrival := False;
1524         FUnRead := False;
1525         FScrollTop := 0;
1526         FRound := False;
1527         FDownloadHost := '';
1528         FAgeSage := gasNone;
1529
1530         FCount := 0;
1531         FNewResCount := 0;
1532         FRoundName := '';
1533 end;
1534
1535 function TThreadItem.GetThreadFileName: string;
1536 begin
1537         if Length( FilePath ) > 0 then
1538                 Result := FilePath
1539         else
1540                 Result := ParentBoard.ParentCategory.ParenTBBS.GetLogFolder
1541                                                 + ParentBoard.BBSID + PATH_DELIM + FileName;
1542 end;
1543
1544 procedure TThreadItem.SetLastModified(d: TDateTime);
1545 begin
1546         if FLastModified = d then Exit;
1547         FLastModified := d;
1548         if FUpdate and (ParentBoard <> nil) then
1549                 ParentBoard.FModified := True;
1550 end;
1551
1552 {procedure TThreadItem.SetRoundNo(i: Integer);
1553 begin
1554         if FRoundNo = i then Exit;
1555         FRoundNo := i;
1556         if FUpdate and (ParentBoard <> nil) then
1557                 ParentBoard.FModified := True;
1558 end;}
1559
1560 procedure TThreadItem.SetRound(b: Boolean);
1561 begin
1562         if b then
1563                 RoundList.Add(Self)
1564         else
1565                 RoundList.Delete(Self);
1566         if FRound = b then Exit;
1567         FRound := b;
1568         if FUpdate and (ParentBoard <> nil) then
1569                 ParentBoard.FModified := True;
1570 end;
1571
1572 procedure TThreadItem.SetRoundName(s: string);
1573 begin
1574         if FRoundName = s then Exit;
1575         FRoundName := s;
1576         if FUpdate and (ParentBoard <> nil) then
1577                 ParentBoard.FModified := True;
1578 end;
1579
1580 procedure TThreadItem.SetKokomade(i: Integer);
1581 begin
1582         if FKokomade = i then Exit;
1583         FKokomade := i;
1584         if FUpdate and (ParentBoard <> nil) then
1585                 ParentBoard.FModified := True;
1586 end;
1587
1588 procedure TThreadItem.SetUnRead(b: Boolean);
1589 begin
1590         if FUnRead = b then Exit;
1591         FUnRead := b;
1592         if FUpdate and (ParentBoard <> nil) then
1593                 ParentBoard.FModified := True;
1594 end;
1595
1596 procedure TThreadItem.SetScrollTop(i: Integer);
1597 begin
1598         if FScrollTop = i then Exit;
1599         FScrollTop := i;
1600         if FUpdate and (ParentBoard <> nil) then
1601                 ParentBoard.FModified := True;
1602 end;
1603
1604 procedure TThreadItem.BeginUpdate;
1605 begin
1606         FUpdate := False;
1607 end;
1608
1609 procedure TThreadItem.EndUpdate;
1610 begin
1611         FUpdate := True;
1612 end;
1613
1614 {initialization
1615         BBS2ch := TBBS.Create;
1616
1617 finalization
1618         if BBS2ch <> nil then
1619                 BBS2ch.Free;}
1620 end.
1621