OSDN Git Service

スレたてをsubbbs.cgiからbbs.cgiに変更を2ちゃんねるに限定
[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, StrUtils, DateUtils;
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, gasNull);
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         // BBS \82Ì\83\8b\81[\83g
74         TBBS = class(TList)
75         private
76                 FTitle: string;
77                 FFilePath : string;                                             // \94Â\83\8a\83X\83g\82Ì\83p\83X
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                 FIsBoardFileRead : Boolean;             // \94Â\83\8a\83X\83g\82Í\93Ç\82Ý\8d\9e\82Ü\82ê\82Ä\82¢\82é\82©\81H
83
84                 function GetCategory(index: integer): TCategory;
85                 procedure SetCategory(index: integer; value: TCategory);
86                 procedure SetSelectText(s: string);
87         public
88                 constructor Create( boardFilePath : string );
89                 destructor Destroy; override;
90
91                 function Add(item: TCategory): integer;
92                 procedure Delete(index: integer);
93                 procedure Clear; override;
94                 function Find(key: string): TCategory;
95                 function FindBBSID(const BBSID: string): TBoard;
96                 function FindBoardFromTitle(const Title: string): TBoard;
97                 function FindBoardFromURL(const inURL: string): TBoard;
98                 function FindThreadFromURL(const inURL : string ) : TThreadItem;
99                 function FindThreadItem(const BBSID, FileName: string): TThreadItem;
100                 function FindCategoryFromTitle(const inTitle : string ) : TCategory;
101                 property FilePath : string read FFilePath write FFilePath;
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
111                 property        IsBoardFileRead : Boolean read FIsBoardFileRead write FIsBoardFileRead;
112         end;
113
114         // \83J\83e\83S\83\8a(\94 URL \82Ì\83\8a\83X\83g)
115 //      TCategory = class(THashedStringList)
116         TCategory = class(TStringList)
117         private
118                 FNo: Integer;
119                 FTitle: string;
120                 FParenTBBS: TBBS;
121                 FExpand: Boolean;
122
123                 function GetBoard(index: integer): TBoard;
124                 procedure SetBoard(index: integer; value: TBoard);
125         public
126                 constructor Create;
127                 destructor Destroy; override;
128
129                 property No: Integer read FNo write FNo;
130                 property Title: string read FTitle write FTitle;
131                 property Items[index: integer]: TBoard read GetBoard write SetBoard;
132                 property ParenTBBS: TBBS read FParenTBBS write FParenTBBS;
133
134                 function Add(item: TBoard): integer;
135                 procedure Delete(index: integer);
136                 procedure Clear; override;
137                 function FindName(const key: string): TBoard;
138                 function FindBBSID(const BBSID: string): TBoard;
139                 function FindBoardFromTitle(const Title: string): TBoard;
140                 function FindBoardFromURL(const inURL: string): TBoard;
141                 function FindThreadFromURL(const inURL : string ) : TThreadItem;
142                 function IsMidoku: Boolean;
143
144                 property NodeExpand: Boolean read FExpand write FExpand;
145         end;
146
147         // \94Â(\83X\83\8c\83b\83h URL \82Ì\83\8a\83X\83g)
148 //      TBoard = class(THashedStringList)
149         TBoard = class(TStringList)
150         private
151                 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é)
152
153                 FNo: Integer;                                                                   //\94Ô\8d\86
154                 FTitle: string;                                                         //\83{\81[\83h\83^\83C\83g\83\8b
155                 FBBSID: string;                                                         //BBSID
156                 FURL: string;                                                                   //\83{\81[\83hURL
157                 FRound: Boolean;                                                        //\83X\83\8c\83b\83h\88ê\97\97\8f\84\89ñ\97\\96ñ
158                 FRoundName: string;                                             //\8f\84\89ñ\96¼
159                 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
160                 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
161                 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
162                 FIsThreadDatRead: Boolean;              //\83X\83\8c\83b\83h\83\8a\83X\83g\82Í\93Ç\82Ý\8d\9e\82Ü\82ê\82Ä\82¢\82é\82©\81H
163                 FUnRead: Integer;                                                       //\83X\83\8c\83b\83h\96¢\93Ç\90\94
164                 FParentCategory: TCategory;             //\90e\83J\83e\83S\83\8a
165                 FModified: Boolean;                                             //\8fC\90³\83t\83\89\83O
166                 FBoolData: Boolean;                                             //\82¢\82ë\82ñ\82È\97p\93r\82É\8eg\82¤yo
167                 FSPID: string;                                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
168                 FPON: string;                                                                   //\8f\91\82«\8d\9e\82Ý\97pPON
169                 FKotehanName: string;                                   //\83R\83e\83n\83\93\96¼\91O
170                 FKotehanMail: string;                                   //\83R\83e\83n\83\93\83\81\81[\83\8b
171
172                 FUpdate: Boolean;
173                 FExpand: Boolean;
174
175                 FBoardPlugIn    : TBoardPlugIn; // \82±\82Ì\94Â\82ð\83T\83|\81[\83g\82·\82é\83v\83\89\83O\83C\83\93
176                 FFilePath                       : string;                               // \82±\82Ì\83X\83\8c\88ê\97\97\82ª\95Û\91\82³\82ê\82Ä\82¢\82é\83p\83X
177                 FIsLogFile              : Boolean;                      // \83\8d\83O\91\8dÝ\83t\83\89\83O
178                 FIntData                        : Integer;                      // \8dD\82«\82É\82¢\82\82Á\82Ä\82æ\82µ\81B\82¢\82ë\82ñ\82È\97p\93r\82É\8eg\82¤yo
179                 FListData                       : TList;                                // \8dD\82«\82É\82¢\82\82Á\82Ä\82æ\82µ\81B\82¢\82ë\82ñ\82È\97p\93r\82É\8eg\82¤yo
180
181                 FSETTINGTXTTime: TDateTime;     //SETTING.TXT\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e
182                 FIsSETTINGTXT:          boolean;        //SETTING.TXT\82ð\8eæ\93¾\82µ\82Ä\82¢\82é\82©
183                 FHEADTXTTime: TDateTime;                //HEAD.TXT\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e
184                 FIsHEADTXT:             boolean;        //HEAD.TXT\82ð\8eæ\93¾\82µ\82Ä\82¢\82é\82©
185         FTitlePictureURL:       string; //top\8aG\82ÌURL
186                 FMultiplicity : Integer; //\8fd\95¡\82µ\82Ä\82¢\82é\82©\82Ç\82¤\82©\81H
187                 function GetThreadItem(index: integer): TThreadItem;
188                 procedure SetThreadItem(index: integer; value: TThreadItem);
189                 procedure SetRound(b: Boolean);
190                 procedure SetRoundName(s: string);
191                 procedure SetLastModified(d: TDateTime);
192                 procedure SetLastGetTime(d: TDateTime);
193                 procedure SetUnRead(i: Integer);
194                 procedure SetKotehanName(s: string);
195                 procedure SetKotehanMail(s: string);
196                 procedure Init;
197         public
198                 constructor Create( inPlugIn : TBoardPlugIn; inURL : string );
199                 destructor Destroy; override;
200
201                 property Context: DWORD read FContext write FContext;
202
203                 property Items[index: integer]: TThreadItem read GetThreadItem write SetThreadItem;
204                 property No: Integer read FNo write FNo;
205                 property Title: string read FTitle write FTitle;
206                 property BBSID: string read FBBSID write FBBSID;
207                 property URL: string read FURL write FURL;
208                 property Round: Boolean read FRound write SetRound;
209                 property RoundName: string read FRoundName write SetRoundName;
210                 property RoundDate: TDateTime read FRoundDate write FRoundDate;
211                 property LastModified: TDateTime read FLastModified write SetLastModified;
212                 property LastGetTime: TDateTime read FLastGetTime write SetLastGetTime;
213                 property UnRead: Integer read FUnRead write SetUnRead;
214                 property Modified: Boolean read FModified write FModified;
215                 property IsThreadDatRead: Boolean read FIsThreadDatRead write FIsThreadDatRead;
216                 property ParentCategory: TCategory read FParentCategory write FParentCategory;
217
218                 property        BoardPlugIn     : TBoardPlugIn  read FBoardPlugIn;
219                 property        FilePath                : string                                read FFilePath write FFilePath;
220                 property        IsLogFile               : Boolean                               read FIsLogFile write FIsLogFile;
221                 property        IntData                 : Integer                               read FIntData write FIntData;
222                 property        ListData                : TList                                 read FListData write FListData;
223                 function        IsBoardPlugInAvailable : Boolean;
224
225                 function Add(item: TThreadItem): integer;
226                 procedure Insert(Index: Integer; Item: TThreadItem);
227                 procedure Delete(index: integer);
228                 procedure DeleteList(index: integer);
229                 procedure Clear; override;
230                 function FindThreadFromFileName(const ItemFileName: string): TThreadItem;
231                 function FindThreadFromURL(const inURL : string ) : TThreadItem;
232                 function GetIndexFromFileName(const ItemFileName: string): Integer;
233                 function GetIndexFromURL(const URL: string): Integer;
234                 procedure LoadSettings;
235                 procedure SaveSettings;
236                 function GetReadCgiURL: string;
237                 function GetSubjectFileName: string;
238                 function GetFolderIndexFileName: string;
239                 function GetSETTINGTXTFileName: string;
240                 function GETHEADTXTFileName: string;
241                 function GetTitlePictureFileName: string;
242                 function GetSendURL: string;
243
244                 function GetNewThreadCount: Integer;
245                 function GetLogThreadCount: Integer;
246                 function GetUserThreadCount: Integer;
247                 function GetNewThread(Index: Integer): TThreadItem;
248                 function GetLogThread(Index: Integer): TThreadItem;
249                 function GetUserThread(Index: Integer): TThreadItem;
250
251                 procedure BeginUpdate;
252                 procedure EndUpdate;
253                 property NodeExpand: Boolean read FExpand write FExpand;
254                 property BoolData: Boolean read FBoolData write FBoolData;
255                 property SPID: string read FSPID write FSPID;
256                 property PON: string read FPON write FPON;
257                 property KotehanName: string read FKotehanName write SetKotehanName;
258                 property KotehanMail: string read FKotehanMail write SetKotehanMail;
259
260                 property SETTINGTXTTime: TDateTime read FSETTINGTXTTime write FSETTINGTXTTime;
261                 property IsSETTINGTXT:  boolean read FIsSETTINGTXT write FIsSETTINGTXT;
262                 property HEADTXTTime: TDateTime read FHEADTXTTime write FHEADTXTTime;
263                 property IsHEADTXT:     boolean read FIsHEADTXT write FIsHEADTXT;
264         property TitlePictureURL: string read FTitlePictureURL write FTitlePictureURL;
265                 property Multiplicity: Integer read FMultiplicity write FMultiplicity;
266         end;
267
268         //\83X\83\8c
269         TThreadItem = class(TObject)
270         private
271                 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é)
272
273                 FNo: Integer;                                                   //\94Ô\8d\86
274                 FFileName: string;                              //\83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
275                 FTitle: string;                                         //\83X\83\8c\83b\83h\83^\83C\83g\83\8b
276                 FShortTitle: string;                    //\92Z\82¢\83X\83\8c\83b\83h\83^\83C\83g\83\8b\81i\8c\9f\8dõ\97p\81j
277                 FRoundDate: TDateTime;          //\83X\83\8c\83b\83h\82ð\8eæ\93¾\82µ\82½\93ú\8e\9e\81i\8f\84\89ñ\93ú\8e\9e\81j
278                 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
279                 FCount: Integer;                                        //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83\8d\81[\83J\83\8b\81j
280                 FAllResCount: Integer;          //\83X\83\8c\83b\83h\83J\83E\83\93\83g\81i\83T\81[\83o\81j
281                 FNewResCount: Integer;          //\83X\83\8c\83b\83h\90V\92\85\90\94
282                 FSize: Integer;                                         //\83X\83\8c\83b\83h\83T\83C\83Y
283                 FRound: Boolean;                                        //\8f\84\89ñ\83t\83\89\83O
284                 FRoundName: string;                             //\8f\84\89ñ\96¼
285                 FIsLogFile: Boolean;                    //\83\8d\83O\91\8dÝ\83t\83\89\83O
286                 FParentBoard: TBoard;                   //\90e\83{\81[\83h
287                 FKokomade: Integer;                             //\83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
288                 FNewReceive: Integer;           //\83R\83R\82©\82ç\90V\8bK\8eó\90M
289                 FNewArrival: Boolean;                   //\90V\92\85
290                 FUnRead: Boolean;                                       //\96¢\93Ç\83t\83\89\83O
291                 FScrollTop: Integer;                    //\83X\83N\83\8d\81[\83\8b\88Ê\92u
292                 FDownloadHost: string;          //\8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
293                 FAgeSage: TGikoAgeSage;         //\83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
294 //              FSPID: string;                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
295
296                 FUpdate: Boolean;
297                 FExpand: Boolean;
298                 FURL                                    : string;                               // \82±\82Ì\83X\83\8c\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
299                 FBoardPlugIn    : TBoardPlugIn; // \82±\82Ì\83X\83\8c\82ð\83T\83|\81[\83g\82·\82é\83v\83\89\83O\83C\83\93
300                 FFilePath                       : string;                               // \82±\82Ì\83X\83\8c\82ª\95Û\91\82³\82ê\82Ä\82¢\82é\83p\83X
301
302                 procedure SetLastModified(d: TDateTime);
303                 procedure SetRound(b: Boolean);
304                 procedure SetRoundName(const s: string);
305                 procedure SetKokomade(i: Integer);
306                 procedure SetUnRead(b: Boolean);
307                 procedure SetScrollTop(i: Integer);
308                 procedure Init;
309                 function GetCreateDate: TDateTime;
310         public
311                 constructor Create( inPlugIn : TBoardPlugIn; inURL : string );
312                 destructor Destroy; override;
313
314                 function GetDatURL: string;
315                 function GetDatgzURL: string;
316 //              function GetOldDatgzURL: string;
317                 function GetOfflawCgiURL(const SessionID: string): string;
318                 function GetSendURL: string;
319                 procedure DeleteLogFile;
320                 function GetThreadFileName: string;
321                 procedure BeginUpdate;
322                 procedure EndUpdate;
323
324                 property Context: DWORD read FContext write FContext;
325
326                 property No: Integer read FNo write FNo;
327                 property FileName: string read FFileName write FFileName;
328                 property Title: string read FTitle write FTitle;
329                 property ShortTitle: string read FShortTitle write FShortTitle;
330                 property RoundDate: TDateTime read FRoundDate write FRoundDate;
331                 property LastModified: TDateTime read FLastModified write SetLastModified;
332                 property Count: Integer read FCount write FCount;
333                 property AllResCount: Integer read FAllResCount write FAllResCount;
334                 property NewResCount: Integer read FNewResCount write FNewResCount;
335                 property Size: Integer read FSize write FSize;
336                 property Round: Boolean read FRound write SetRound;
337                 property RoundName: string read FRoundName write SetRoundName;
338
339                 property IsLogFile: Boolean read FIsLogFile write FIsLogFile;
340                 property ParentBoard: TBoard read FParentBoard write FParentBoard;
341                 property Kokomade: Integer read FKokomade write SetKokomade;
342                 property NewReceive: Integer read FNewReceive write FNewReceive;
343                 property NewArrival: Boolean read FNewArrival write FNewArrival;
344                 property UnRead: Boolean read FUnRead write SetUnRead;
345                 property ScrollTop: Integer read FScrollTop write SetScrollTop;
346                 property Expand: Boolean read FExpand write FExpand;
347                 property DownloadHost: string read FDownloadHost write FDownloadHost;
348                 property AgeSage: TGikoAgeSage read FAgeSage write FAgeSage;
349 //              property SPID: string read FSPID write FSPID;
350                 property CreateDate: TDateTime read GetCreateDate;
351                 property        URL                                     : string                                read FURL write FURL;
352                 property        BoardPlugIn     : TBoardPlugIn  read FBoardPlugIn;
353                 property        FilePath                : string                                read FFilePath write FFilePath;
354                 function        IsBoardPlugInAvailable : Boolean;
355         end;
356
357
358
359         //\8c\9f\8dõ\8c\8b\89Ê\83\8a\83X\83g
360 {       TSearchList = class(TList)
361         private
362                 function GetThreadItem(index: integer): TThreadItem;
363                 procedure SetThreadItem(index: integer; value: TThreadItem);
364         public
365                 constructor Create;
366                 destructor Destroy; override;
367
368                 property Items[index: integer]: TThreadItem read GetThreadItem write SetThreadItem;
369
370                 function Add(item: TThreadItem): integer;
371                 procedure Delete(index: integer);
372                 procedure Clear; override;
373         end;}
374
375         function        BBSsFindBoardFromBBSID( inBBSID : string ) : TBoard;
376         function        BBSsFindBoardFromURL( inURL : string ) : TBoard;
377         function        BBSsFindBoardFromTitle( inTitle : string ) : TBoard;
378         function        BBSsFindThreadFromURL(const inURL : string ) : TThreadItem;
379         function        ConvertDateTimeString( inDateTimeString : string) : TDateTime;
380
381 var
382         BBSs            : array of TBBS;
383
384 implementation
385
386 uses
387         GikoSystem, RoundData, MojuUtils;
388
389 const
390         BBS2CH_NAME:                                     string = '\82Q\82¿\82á\82ñ\82Ë\82é';
391         BBS2CH_LOG_FOLDER:               string = '2ch';
392         EXTERNAL_LOG_FOLDER:            string  = 'exboard';
393
394         FOLDER_INI_FILENAME:     string = 'Folder.ini';
395         FOLDER_INDEX_FILENAME: string   = 'Folder.idx';
396         SUBJECT_FILENAME:                       string  = 'subject.txt';
397         PATH_DELIM:                                             string  = '\';
398         SETTINGTXT_FILENAME:            string = 'SETTING.TXT';
399     HEADTXT_FILENAME:           string = 'head.html';
400         //DEFAULT_LIST_COUNT:           Integer = 100;
401
402 //      COLUMN_CATEGORY:         array[0..0] of string = ('\83J\83e\83S\83\8a\96¼');
403 //      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');
404 //      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');
405
406 // BBSID \82ð\97p\82¢\82é 2 \82¿\82á\82ñ\82Ë\82é\82Ì\82Ý\92T\82µ\8fo\82µ\82Ü\82·
407 // BBSID \82Ì\8eg\97p\82Í\8bÉ\97Í\94ð\82¯\82Ä\82­\82¾\82³\82¢\81B
408 // \89Â\94\\82È\8fê\8d\87\82Í URL \82ð\8eg\97p\82µ\82Ä\82­\82¾\82³\82¢\81B
409 function        BBSsFindBoardFromBBSID(
410         inBBSID : string
411 ) : TBoard;
412 begin
413
414         Result := BBSs[ 0 ].FindBBSID( inBBSID );
415
416 end;
417
418 function        BBSsFindBoardFromURL(
419         inURL   : string
420 ) : TBoard;
421 var
422         i                       : Integer;
423 begin
424
425         for i := Length( BBSs ) - 1 downto 0 do begin
426                 Result := BBSs[ i ].FindBoardFromURL( inURL );
427                 if Result <> nil then
428                         Exit;
429         end;
430
431         Result := nil;
432
433 end;
434
435 function        BBSsFindBoardFromTitle(
436         inTitle : string
437 ) : TBoard;
438 var
439         i                               : Integer;
440 begin
441
442         for i := Length( BBSs ) - 1 downto 0 do begin
443                 Result := BBSs[ i ].FindBoardFromTitle( inTitle );
444                 if Result <> nil then
445                         Exit;
446         end;
447
448         Result := nil;
449
450 end;
451
452 function        BBSsFindThreadFromURL(
453         const inURL                     : string
454 ) : TThreadItem;
455 var
456         board                   : TBoard;
457         boardURL        : string;
458 begin
459
460         boardURL        := GikoSys.GetThreadURL2BoardURL( inURL );
461         board                   := BBSsFindBoardFromURL( boardURL );
462         if board = nil then
463                 Result := nil
464         else
465                 Result := board.FindThreadFromURL( inURL );
466
467 end;
468
469 (*************************************************************************
470  *\8b@\94\\96¼\81FTBBS\83R\83\93\83X\83g\83\89\83N\83^
471  *Public
472  *************************************************************************)
473 constructor TBBS.Create( boardFilePath : string );
474 begin
475         inherited Create;
476         Title := BBS2CH_NAME;
477         FFilePath := boardFilePath;
478 end;
479
480 (*************************************************************************
481  *\8b@\94\\96¼\81FTBBS\83f\83X\83g\83\89\83N\83^
482  *Public
483  *************************************************************************)
484 destructor TBBS.Destroy;
485 begin
486         Clear;
487         inherited;
488 end;
489
490 (*************************************************************************
491  *\8b@\94\\96¼\81F
492  *Public
493  *************************************************************************)
494 function TBBS.GetCategory(index: integer): TCategory;
495 begin
496         Result := TCategory(inherited Items[index]);
497 end;
498
499 procedure TBBS.SetCategory(index: integer; value: TCategory);
500 begin
501         inherited Items[index] := value;
502 end;
503
504 function TBBS.Add(item: TCategory): integer;
505 begin
506         Item.ParenTBBS := self;
507         Result := inherited Add(item);
508 end;
509
510 procedure TBBS.Delete(index: integer);
511 begin
512         if Items[index] <> nil then
513                 TCategory(Items[index]).Free;
514         Items[index] := nil;
515         inherited Delete(index);
516 end;
517
518 procedure TBBS.Clear;
519 var
520         i: integer;
521 begin
522         for i := Count - 1 downto 0 do
523                 Delete(i);
524     Capacity := Count;
525 end;
526
527 function TBBS.Find(key: string): TCategory;
528 begin
529         Result := nil;
530 end;
531
532 function TBBS.FindBBSID(const BBSID: string): TBoard;
533 var
534         i       : Integer;
535 begin
536         if not IsBoardFileRead then
537         GikoSys.ReadBoardFile( Self );
538         for i := Count - 1 downto 0 do begin
539                 Result := Items[ i ].FindBBSID(BBSID);
540                 if Result <> nil then
541                         Exit;
542         end;
543         Result := nil;
544 end;
545
546 //*************************************************************************
547 // \83^\83C\83g\83\8b\82Ì\88ê\92v\82·\82é\94Â\82ð\92T\82·
548 //*************************************************************************)
549 function TBBS.FindBoardFromTitle(const Title: string): TBoard;
550 var
551         i: Integer;
552 begin
553         if not IsBoardFileRead then
554         GikoSys.ReadBoardFile( Self );
555         for i := Count - 1 downto 0 do begin
556                 Result := Items[ i ].FindBoardFromTitle(Title);
557                 if Result <> nil then
558                         Exit;
559         end;
560         Result := nil;
561 end;
562
563 //*************************************************************************
564 // URL \82ð\8eó\82¯\95t\82¯\82é\94Â\82ð\92T\82·
565 //*************************************************************************)
566 function TBBS.FindBoardFromURL(const inURL: string): TBoard;
567 var
568         i                                       : Integer;
569 begin
570         if not IsBoardFileRead then
571         GikoSys.ReadBoardFile( Self );
572         for i := Count - 1 downto 0 do begin
573                 Result := Items[ i ].FindBoardFromURL( inURL );
574                 if Result <> nil then
575                         Exit;
576         end;
577         Result := nil;
578 end;
579
580 //*************************************************************************
581 // URL \82ð\8eó\82¯\95t\82¯\82é\83X\83\8c\83b\83h\82ð\92T\82·
582 //*************************************************************************)
583 function TBBS.FindThreadFromURL(const inURL: string): TThreadItem;
584 var
585         board                   : TBoard;
586         boardURL        : string;
587 begin
588
589         boardURL        := GikoSys.GetThreadURL2BoardURL( inURL );
590         board                   := FindBoardFromURL( boardURL );
591         if board = nil then
592                 Result := nil
593         else
594                 Result := board.FindThreadFromURL( inURL );
595
596 end;
597
598 function TBBS.FindThreadItem(const BBSID, FileName: string): TThreadItem;
599 var
600         Board: TBoard;
601 begin
602         Result := nil;
603         Board := FindBBSID(BBSID);
604         if Board = nil then
605                 Exit;
606         Result := Board.FindThreadFromFileName(FileName);
607 end;
608
609 function TBBS.FindCategoryFromTitle(const inTitle : string ) : TCategory;
610 var
611         i : Integer;
612 begin
613
614         for i := Count - 1 downto 0 do begin
615                 if AnsiCompareStr(Items[ i ].Title, inTitle) = 0 then begin
616                         Result := Items[ i ];
617                         Exit;
618                 end;
619         end;
620
621         Result := nil;
622
623 end;
624
625 procedure TBBS.SetSelectText(s: string);
626 begin
627         FSelectText := s;
628         ShortSelectText := CustomStringReplace(ZenToHan(s), ' ', '');
629 end;
630
631 {class function TBBS.GetColumnName(Index: Integer): string;
632 begin
633         Result := COLUMN_CATEGORY[Index];
634 end;
635
636 class function TBBS.GetColumnCount: Integer;
637 begin
638         Result := Length(COLUMN_CATEGORY);
639 end;}
640
641 //===================
642 //TCategory
643 //===================
644 constructor TCategory.Create;
645 begin
646         inherited;
647
648         Duplicates              := dupIgnore;
649         CaseSensitive   := False;
650         //Sorted                                := True;
651 end;
652
653 destructor TCategory.Destroy;
654 begin
655         Clear;
656         inherited;
657 end;
658
659 function TCategory.GetBoard(index: integer): TBoard;
660 begin
661         Result := TBoard( Objects[index] );
662 end;
663
664 procedure TCategory.SetBoard(index: integer; value: TBoard);
665 begin
666         Objects[index] := value;
667         Strings[index] := value.URL
668 end;
669
670 function TCategory.Add(item: TBoard): integer;
671 begin
672         Item.ParentCategory := self;
673         Result := AddObject( item.URL, item );
674 end;
675
676 procedure TCategory.Delete(index: integer);
677 begin
678         if (Items[index] <> nil) then begin
679                 try
680                         if TBoard(Items[index]).Multiplicity = 0 then
681                                 TBoard(Items[index]).Free
682                         else
683                                 TBoard(Items[index]).Multiplicity := TBoard(Items[index]).Multiplicity - 1;
684                 except
685                 end;
686         end;
687         inherited Delete(index);
688 end;
689
690 procedure TCategory.Clear;
691 var
692         i: integer;
693 begin
694         for i := Count - 1 downto 0 do
695                 Delete(i);
696         Capacity := Count;
697 end;
698
699 function TCategory.FindName(const key: string): TBoard;
700 begin
701         Result := nil;
702 end;
703
704 function TCategory.FindBBSID(const BBSID: string): TBoard;
705 var
706         i       : integer;
707 begin
708         for i := Count - 1 downto 0 do begin
709                 if AnsiCompareStr(Items[i].FBBSID, BBSID) = 0 then begin
710                         Result := Items[i];
711                         Exit;
712                 end;
713         end;
714         Result := nil;
715 end;
716
717 //*************************************************************************
718 // \83^\83C\83g\83\8b\82Ì\88ê\92v\82·\82é\94Â\82ð\92T\82·
719 //*************************************************************************)
720 function TCategory.FindBoardFromTitle(const Title: string): TBoard;
721 var
722         i       : integer;
723 begin
724         for i := Count - 1 downto 0 do begin
725                 if AnsiCompareStr(Items[i].FTitle, Title) = 0 then begin
726                         Result := Items[i];
727                         Exit;
728                 end;
729         end;
730         Result := nil;
731 end;
732
733 //*************************************************************************
734 // URL \82ð\8eó\82¯\95t\82¯\82é\94Â\82ð\92T\82·
735 //*************************************************************************)
736 function TCategory.FindBoardFromURL(const inURL: string): TBoard;
737 var
738         i       : Integer;
739 begin
740         i := IndexOf( inURL );
741         if i >= 0 then
742                 Result := TBoard( Objects[ i ] )
743         else
744                 Result := nil;
745 end;
746
747 //*************************************************************************
748 // URL \82ð\8eó\82¯\95t\82¯\82é\83X\83\8c\83b\83h\82ð\92T\82·
749 //*************************************************************************)
750 function TCategory.FindThreadFromURL(const inURL: string): TThreadItem;
751 var
752         board                   : TBoard;
753         boardURL        : string;
754 begin
755
756         boardURL        := GikoSys.GetThreadURL2BoardURL( inURL );
757         board                   := FindBoardFromURL( boardURL );
758         if board = nil then
759                 Result := nil
760         else
761                 Result := board.FindThreadFromURL( inURL );
762
763 end;
764
765 function TCategory.IsMidoku: Boolean;
766 var
767         i: Integer;
768         j: Integer;
769 begin
770         Result := False;
771         for i := 0 to Count - 1 do begin
772                 if Items[i] <> nil then begin
773                         for j := 0 to Items[i].Count - 1 do begin
774                                 if Items[i].Items[j] <> nil then begin
775 //                                      if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].Count > Items[i].Items[j].Kokomade) then begin
776                                         if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].UnRead) then begin
777                                                 Result := True;
778                                                 Exit;
779                                         end;
780                                 end;
781                         end;
782                 end;
783         end;
784 end;
785
786 {class function TCategory.GetColumnName(Index: Integer): string;
787 begin
788         Result := COLUMN_BOARD[Index];
789 end;
790
791 class function TCategory.GetColumnCount: Integer;
792 begin
793         Result := Length(COLUMN_BOARD);
794 end;}
795
796 //===================
797 //TBoard
798 //===================
799 procedure TBoard.Init;
800 begin
801         Duplicates              := dupIgnore;
802         CaseSensitive   := False;
803         //Sorted                                := True;
804
805         FNo := 0;
806         FTitle := '';
807         FBBSID := '';
808         FURL := '';
809         FRound := False;
810         FRoundDate := ZERO_DATE;
811         FLastModified := ZERO_DATE;
812         FLastGetTime := ZERO_DATE;
813         FIsThreadDatRead := False;
814         FUnRead := 0;
815 //      FListStyle := vsReport;
816 //      FItemNoVisible := True;
817
818         FUpdate := True;
819 end;
820
821 // *************************************************************************
822 // \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^
823 // *************************************************************************
824 constructor TBoard.Create(
825         inPlugIn        : TBoardPlugIn;
826         inURL                   : string
827 );
828 var
829         protocol, host, path, document, port, bookmark  : string;
830 begin
831
832         inherited Create;
833         Init;
834
835         FBoardPlugIn    := inPlugIn;
836         URL                                             := inURL;
837         BBSID                                   := GikoSys.UrlToID( inURL );
838
839         if inPlugIn = nil then begin
840                 // subject.txt \82Ì\95Û\91\83p\83X\82ð\90Ý\92è
841                 GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
842                 if GikoSys.Is2chHost( host ) then
843                         FilePath :=
844                                 IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
845                                 BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME
846                 else
847                         FilePath :=
848                                 IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
849                                 EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME
850         end else begin
851                 // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
852                 inPlugIn.CreateBoardItem( DWORD( Self ) );
853         end;
854
855 end;
856
857 // *************************************************************************
858 // \83f\83X\83g\83\89\83N\83^
859 // *************************************************************************
860 destructor TBoard.Destroy;
861 begin
862         if FModified then begin
863                 GikoSys.WriteThreadDat(Self);
864                 SaveSettings;
865         end;
866
867         // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
868         if IsBoardPlugInAvailable then
869                 BoardPlugIn.DisposeBoardItem( DWORD( Self ) );
870
871         Clear;
872         inherited;
873 end;
874
875 // *************************************************************************
876 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
877 // *************************************************************************
878 function        TBoard.IsBoardPlugInAvailable : Boolean;
879 begin
880
881         repeat
882                 if BoardPlugIn = nil then
883                         Break;
884                         
885                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
886                         Break;
887
888                 Result := True;
889                 Exit;
890         until True;
891
892         Result := False;
893
894 end;
895
896 function TBoard.GetThreadItem(index: integer): TThreadItem;
897 begin
898         Result := TThreadItem( Objects[index] );
899 end;
900
901 procedure TBoard.SetThreadItem(index: integer; value: TThreadItem);
902 begin
903         Objects[index] := value;
904         Strings[index] := value.URL;
905 end;
906
907 function TBoard.Add(Item: TThreadItem): Integer;
908 begin
909         Item.ParentBoard := Self;
910         Result := inherited AddObject(Item.URL, Item);
911 end;
912
913 procedure TBoard.Insert(Index: Integer; Item: TThreadItem);
914 begin
915         Item.ParentBoard := Self;
916         inherited InsertObject(Index, Item.URL, Item);
917
918 end;
919
920 //Index\82Å\8ew\92è\82³\82ê\82½\83X\83\8c\83b\83h\83I\83u\83W\83F\83N\83g\82ð\94j\8aü
921 procedure TBoard.Delete(index: Integer);
922 begin
923         if Items[index] <> nil then
924                 TThreadItem(Items[index]).Free;
925         inherited Delete(index);
926 end;
927
928 //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
929 procedure TBoard.DeleteList(index: integer);
930 begin
931         inherited Delete(index);
932 end;
933
934 procedure TBoard.Clear;
935 var
936         i: integer;
937 begin
938 //      FUnRead := 0;
939         for i := Count - 1 downto 0 do
940                 Delete(i);
941          Capacity := Count;
942 end;
943
944 function TBoard.FindThreadFromFileName(const ItemFileName: string): TThreadItem;
945 var
946         i: integer;
947 begin
948         Result := nil;
949         for i := 0 to Count - 1 do begin
950                 if AnsiCompareStr(Items[i].FileName, ItemFileName) = 0 then begin
951                         Result := Items[i];
952                         Exit;
953                 end;
954         end;
955 end;
956
957 function TBoard.GetIndexFromFileName(const ItemFileName: string): Integer;
958 var
959         i: integer;
960 begin
961         Result := -1;
962         for i := 0 to Count - 1 do begin
963                 if Items[i].FileName = ItemFileName then begin
964                         Result := i;
965                         Exit;
966                 end;
967         end;
968 end;
969
970 function TBoard.GetIndexFromURL(const URL: string): Integer;
971 begin
972         Result := IndexOf( URL );
973 end;
974
975 function TBoard.FindThreadFromURL(const inURL : string ) : TThreadItem;
976 var
977         i : Integer;
978 begin
979
980         if not IsThreadDatRead then
981                 GikoSys.ReadSubjectFile( Self );
982
983         i := IndexOf( inURL );
984         if i >= 0 then
985                 Result := TThreadItem( Objects[ i ] )
986         else
987                 Result := nil;
988
989 end;
990
991 {function TBoard.GetMidokuCount: Integer;
992 var
993         i: integer;
994 begin
995         Result := 0;
996         for i := 0 to Count- 1 do begin
997                 if Items[i] <> nil then begin
998                         if (Items[i].IsLogFile) and (Items[i].Count > Items[i].Kokomade) then
999                                 inc(Result);
1000                 end;
1001         end;
1002 end;
1003 }
1004
1005 procedure TBoard.LoadSettings;
1006 var
1007         ini: TMemIniFile;
1008         FileName: string;
1009         tmp: string;
1010 begin
1011         if Length( FilePath ) > 0 then
1012                 FileName := ExtractFilePath( FilePath ) + FOLDER_INI_FILENAME
1013         else
1014                 FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1015                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INI_FILENAME;
1016
1017         if not FileExists(FileName) then
1018                 Exit;
1019         ini := TMemIniFile.Create(FileName);
1020         try
1021 //              Round := ini.ReadBool('Status', 'Round', False);
1022                 tmp := ini.ReadString('Status', 'RoundDate', DateTimeToStr(ZERO_DATE));
1023                 FRoundDate := ConvertDateTimeString(tmp);
1024                 tmp := ini.ReadString('Status', 'LastModified', DateTimeToStr(ZERO_DATE));
1025                 FLastModified := ConvertDateTimeString(tmp);
1026                 tmp := ini.ReadString('Status', 'LastGetTime', DateTimeToStr(ZERO_DATE));
1027                 FLastGetTime := ConvertDateTimeString(tmp);
1028
1029                 tmp := ini.ReadString('BoardInformation', 'SETTINGTXTTime', DateTimeToStr(ZERO_DATE));
1030                 FSETTINGTXTTime := ConvertDateTimeString(tmp);
1031                 tmp := ini.ReadString('BoardInformation', 'HEADTXTTime', DateTimeToStr(ZERO_DATE));
1032                 FHEADTXTTime := ConvertDateTimeString(tmp);
1033
1034                 FIsSETTINGTXT := ini.ReadBool('BoardInformation', 'IsSETTINGTXT', false);
1035                 FIsHEADTXT := ini.ReadBool('BoardInformation', 'IsHEADTXT', false);
1036                 FTitlePictureURL := ini.ReadString('BoardInformation', 'TitlePictureURL', '');
1037
1038                 FUnRead := ini.ReadInteger('Status', 'UnRead', 0);
1039                 FSPID := ini.ReadString('Cookie', 'SPID', '');
1040                 FPON := ini.ReadString('Cookie', 'PON', '');
1041                 FKotehanName := ini.ReadString('Kotehan', 'Name', '');
1042                 FKotehanMail := ini.ReadString('Kotehan', 'Mail', '');
1043
1044                 if UnRead < 0 then
1045                         UnRead := 0;
1046         finally
1047                 ini.Free;
1048         end;
1049 end;
1050
1051 procedure TBoard.SaveSettings;
1052 var
1053         ini: TMemIniFile;
1054         FileName: string;
1055 begin
1056         if Length( FilePath ) > 0 then
1057                 FileName := ExtractFilePath( FilePath )
1058         else
1059                 FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1060                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM;
1061         if not GikoSys.DirectoryExistsEx(FileName) then
1062                 GikoSys.ForceDirectoriesEx(FileName);
1063         FileName := FileName + FOLDER_INI_FILENAME;
1064         ini := TMemIniFile.Create(FileName);
1065         try
1066                 if UnRead < 0 then
1067                         UnRead := 0;
1068 //              ini.WriteBool('Status', 'Round', Round);
1069                 ini.WriteDateTime('Status', 'RoundDate', FRoundDate);
1070                 ini.WriteDateTime('Status', 'LastModified', FLastModified);
1071                 ini.WriteDateTime('Status', 'LastGetTime', FLastGetTime);
1072                 ini.WriteInteger('Status', 'UnRead', FUnRead);
1073                 ini.WriteString('Cookie', 'SPID', FSPID);
1074                 ini.WriteString('Cookie', 'PON', FPON);
1075                 ini.WriteString('Kotehan', 'Name', FKotehanName);
1076                 ini.WriteString('Kotehan', 'Mail', FKotehanMail);
1077
1078                 ini.WriteDateTime('BoardInformation', 'SETTINGTXTTime', FSETTINGTXTTime);
1079                 ini.WriteDateTime('BoardInformation', 'HEADTXTTime', FHEADTXTTime);
1080
1081                 ini.WriteBool('BoardInformation', 'IsSETTINGTXT', FIsSETTINGTXT);
1082                 ini.WriteBool('BoardInformation', 'IsHEADTXT', FIsHEADTXT);
1083                 ini.WriteString('BoardInformation', 'TitlePictureURL', FTitlePictureURL);
1084 //              ini.WriteInteger('Status', 'ListStyle', Ord(ListStyle));
1085 //              ini.WriteBool('Status', 'ItemNoVisible', ItemNoVisible);
1086 //              ini.WriteInteger('Status', 'ViewType', Ord(ViewType));
1087                 ini.UpdateFile;
1088         finally
1089                 ini.Free;
1090         end;
1091 end;
1092 //\82Æ\82«\82½\82Ü2003 02 08 0:32:13\82±\82ñ\82È\8c`\8e®\82Ì\93ú\95t\82ª\82 \82é\82Ì\82Å\82»\82ê\82ð
1093 //        2003/02/08 0:32:13\82É\95Ï\8a·\82·\82é
1094 function        ConvertDateTimeString( inDateTimeString : string) : TDateTime;
1095 const
1096         ZERO_DATE_STRING : string = '1970/01/01 0:00:00';
1097 var
1098         i : Integer;
1099     y: Integer;
1100     m: Integer;
1101     d: Integer;
1102     hour: Integer;
1103     min: Integer;
1104     sec: Integer;
1105 begin
1106     if inDateTimeString = '' then
1107         inDateTimeString := ZERO_DATE_STRING;
1108
1109     if ( AnsiPos('/', inDateTimeString ) = 0 ) and
1110         ( AnsiCompareStr( DateTimeToStr(ZERO_DATE), inDateTimeString) <> 0 ) then begin
1111                 for i := 0 to 1 do begin
1112                 Insert('/',inDateTimeString, AnsiPos(' ', inDateTimeString) + 1 );
1113                 Delete(inDateTimeString, AnsiPos(' ', inDateTimeString), 1);
1114         end;
1115     end;
1116     try
1117         Result := StrToDateTime( inDateTimeString );
1118     except
1119         if( inDateTimeString[5] = '/' ) and ( inDateTimeString[8] = '/' ) then begin
1120             y := StrToIntDef( Copy(inDateTimeString, 1, 4), 1970 );
1121                         m := StrToIntDef( Copy(inDateTimeString, 6, 2), 1 );
1122             d := StrToIntDef( Copy(inDateTimeString, 9, 2), 1 );
1123             hour := 0; min  := 0; sec  := 0;
1124
1125                 if Length(inDateTimeString) > 11 then begin
1126                 if( inDateTimeString[13] = ':' ) and ( inDateTimeString[16] = ':' ) then begin
1127                         hour := StrToIntDef( Copy(inDateTimeString, 12, 1), 0 );
1128                     min  := StrToIntDef( Copy(inDateTimeString, 14, 2), 0 );
1129                     sec  := StrToIntDef( Copy(inDateTimeString, 17, 2), 0 );
1130                 end else if( inDateTimeString[14] = ':' ) and ( inDateTimeString[17] = ':' ) then begin
1131                         hour := StrToIntDef( Copy(inDateTimeString, 12, 2), 0 );
1132                     min  := StrToIntDef( Copy(inDateTimeString, 15, 2), 0 );
1133                     sec  := StrToIntDef( Copy(inDateTimeString, 18, 2), 0 );
1134                 end;
1135             end;
1136             try
1137                 Result := EncodeDateTime(y ,m, d, hour, min, sec, 0);
1138             except
1139                 Result := ZERO_DATE;
1140             end;
1141         end else
1142                 Result := ZERO_DATE;
1143     end;
1144
1145
1146    // Result := inDateTimeString;
1147 end;
1148 // \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
1149 function TBoard.GetReadCgiURL: string;
1150 begin
1151         //Result := URL + SUBJECT_FILENAME;
1152         //Result := GikoSys.UrlToServer(URL)
1153         //                              + 'test/read.cgi/' + BBSID + '/?raw=0.0';
1154         Result := URL + SUBJECT_FILENAME;
1155
1156 end;
1157
1158 // \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
1159 function TBoard.GetSubjectFileName: string;
1160 begin
1161         if Length( FilePath ) > 0 then
1162                 Result := FilePath
1163         else
1164                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1165                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME;
1166 end;
1167
1168 // \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
1169 function TBoard.GetFolderIndexFileName: string;
1170 begin
1171         if Length( FilePath ) > 0 then
1172                 Result := ExtractFilePath( FilePath ) + FOLDER_INDEX_FILENAME
1173         else
1174                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1175                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME;
1176 end;
1177 //SETTING.TXT\82Ì\83t\83@\83C\83\8b\96¼\8eæ\93¾
1178 function TBoard.GetSETTINGTXTFileName: string;
1179 begin
1180         if Length( FilePath ) > 0 then
1181                 Result := ExtractFilePath( FilePath ) + SETTINGTXT_FILENAME
1182         else
1183                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1184                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SETTINGTXT_FILENAME;
1185 end;
1186
1187 function TBoard.GETHEADTXTFileName: string;
1188 begin
1189         if Length( FilePath ) > 0 then
1190                 Result := ExtractFilePath( FilePath ) + HEADTXT_FILENAME
1191         else
1192                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1193                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + HEADTXT_FILENAME;
1194 end;
1195 function TBoard.GetTitlePictureFileName: string;
1196 var
1197         tmpName: string;
1198 begin
1199         if FTitlePictureURL = '' then
1200                 Result := ''
1201         else begin
1202                 tmpName := Copy(FTitlePictureURL, LastDelimiter('/', FTitlePictureURL) + 1, Length(FTitlePictureURL));
1203                 if Length( FilePath ) > 0 then
1204                         Result := ExtractFilePath( FilePath ) + tmpName
1205                 else
1206                         Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1207                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + tmpName;
1208         end;
1209 end;
1210
1211 // \83X\83\8c\97§\82Ä\91\97\90MURL
1212 function TBoard.GetSendURL: string;
1213 var
1214         Protocol, Host, Path, Document, Port, Bookmark : string;
1215 begin
1216     Result := GikoSys.UrlToServer(URL);
1217     GikoSys.ParseURI( URL, Protocol,Host, Path, Document, Port, Bookmark );
1218     if GikoSys.Is2chHost(Host) then
1219         Result := Result + 'test/bbs.cgi'
1220     else
1221         Result := Result + 'test/subbbs.cgi';
1222
1223 end;
1224
1225 procedure TBoard.SetRound(b: Boolean);
1226 begin
1227         if b then
1228                 RoundList.Add(Self)
1229         else
1230                 RoundList.Delete(Self);
1231         if FRound = b then Exit;
1232         FRound := b;
1233         if FUpdate then
1234                 FModified := True;
1235 end;
1236
1237 procedure TBoard.SetRoundName(s: string);
1238 begin
1239         if FRoundName = s then Exit;
1240         FRoundName := s;
1241         if FUpdate then
1242                 FModified := True;
1243 end;
1244
1245 procedure TBoard.SetLastModified(d: TDateTime);
1246 begin
1247         if FLastModified = d then Exit;
1248         FLastModified := d;
1249         if FUpdate then
1250                 FModified := True;
1251 end;
1252
1253 procedure TBoard.SetLastGetTime(d: TDateTime);
1254 begin
1255         if FLastGetTime = d then Exit;
1256         FLastGetTime := d;
1257         if FUpdate then
1258                 FModified := True;
1259 end;
1260
1261 procedure TBoard.SetUnRead(i: Integer);
1262 begin
1263         if FUnRead = i then Exit;
1264         if i < 0 then i := 0;
1265         FUnRead := i;
1266         if FUpdate then
1267                 FModified := True;
1268 end;
1269
1270 procedure TBoard.SetKotehanName(s: string);
1271 begin
1272         if FKotehanName = s then Exit;
1273         FKotehanName := s;
1274         if FUpdate then
1275                 FModified := True;
1276 end;
1277
1278 procedure TBoard.SetKotehanMail(s: string);
1279 begin
1280         if FKotehanMail = s then Exit;
1281         FKotehanMail := s;
1282         if FUpdate then
1283                 FModified := True;
1284 end;
1285
1286 function TBoard.GetNewThreadCount: Integer;
1287 var
1288         i: Integer;
1289 begin
1290         Result := 0;
1291         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1292         begin
1293                 for i := 0 to Count - 1 do begin
1294                         if Items[i].NewArrival then
1295                                 inc(Result);
1296                 end;
1297         end else begin
1298                 for i := 0 to Count - 1 do begin
1299                         if Items[i].NewArrival then
1300                         begin
1301                                 if Items[i].ShortTitle = '' then
1302                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1303                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1304                                         inc(Result);
1305                         end;
1306                 end;
1307         end;
1308 end;
1309
1310 function TBoard.GetLogThreadCount: Integer;
1311 var
1312         i: Integer;
1313 begin
1314         Result := 0;
1315         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1316         begin
1317                 for i := 0 to Count - 1 do begin
1318                         if Items[i].IsLogFile then
1319                                 inc(Result);
1320                 end;
1321         end else begin
1322                 for i := 0 to Count - 1 do begin
1323                         if Items[i].IsLogFile then
1324                         begin
1325                                 if Items[i].ShortTitle = '' then
1326                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1327                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1328                                         inc(Result);
1329                         end;
1330                 end;
1331         end;
1332 end;
1333
1334 function TBoard.GetUserThreadCount: Integer;
1335 var
1336         i: Integer;
1337 begin
1338         Result := 0;
1339         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1340                 Result := Count
1341         else
1342                 for i := 0 to Count - 1 do begin
1343                         if Items[i].ShortTitle = '' then
1344                                 Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1345                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1346                                 inc(Result);
1347                 end;
1348 end;
1349
1350 function TBoard.GetNewThread(Index: Integer): TThreadItem;
1351 var
1352         i: Integer;
1353         Cnt: Integer;
1354 begin
1355         Result := nil;
1356         Cnt := 0;
1357         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1358         begin
1359                 for i := 0 to Count - 1 do begin
1360                         if Items[i].NewArrival then
1361                                                                         begin
1362                                 if Index = Cnt then begin
1363                                         Result := Items[i];
1364                                         Exit;
1365                                 end;
1366                                 inc(Cnt);
1367                         end;
1368                 end;
1369         end else begin
1370                 for i := 0 to Count - 1 do begin
1371                         if Items[i].NewArrival then
1372                         begin
1373                                 if Items[i].ShortTitle = '' then
1374                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1375                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1376                                         if Index = Cnt then begin
1377                                                 Result := Items[i];
1378                                                 Exit;
1379                                         end;
1380                                         inc(Cnt);
1381                                 end;
1382                         end;
1383                 end;
1384         end;
1385 end;
1386
1387 function TBoard.GetLogThread(Index: Integer): TThreadItem;
1388 var
1389         i: Integer;
1390         Cnt: Integer;
1391 begin
1392         Cnt := 0;
1393         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1394         begin
1395                 for i := 0 to Count - 1 do begin
1396                         if Items[i].IsLogFile then
1397                                                                         begin
1398                                 if Index = Cnt then begin
1399                                         Result := Items[i];
1400                                         Exit;
1401                                 end;
1402                                 inc(Cnt);
1403                         end;
1404                 end;
1405         end else begin
1406                 for i := 0 to Count - 1 do begin
1407                         if Items[i].IsLogFile then
1408                                 begin
1409                                         if Items[i].ShortTitle = '' then
1410                                                 Items[i].ShortTitle := ZenToHan(Items[i].Title);
1411                                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1412                                                 if Index = Cnt then begin
1413                                                         Result := Items[i];
1414                                                         Exit;
1415                                         end;
1416                                         inc(Cnt);
1417                                 end;
1418                         end;
1419                 end;
1420         end;
1421         Result := nil;
1422 end;
1423
1424 function TBoard.GetUserThread(Index: Integer): TThreadItem;
1425 var
1426         i: Integer;
1427         Cnt: Integer;
1428 begin
1429         Result := nil;
1430         Cnt := 0;
1431         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1432         begin
1433                 for i := 0 to Count - 1 do begin
1434                         if Index = Cnt then
1435                         begin
1436                                 Result := Items[ i ];
1437                                 Exit;
1438                         end;
1439                         inc( Cnt );
1440                 end;
1441         end else begin
1442                 for i := 0 to Count - 1 do begin
1443                         if Items[i].ShortTitle = '' then
1444                                 Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1445                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1446                                 if Index = Cnt then begin
1447                                         Result := Items[i];
1448                                         Exit;
1449                                 end;
1450                                 inc(Cnt);
1451                         end;
1452                 end;
1453         end;
1454 end;
1455
1456 procedure TBoard.BeginUpdate;
1457 begin
1458         FUpdate := False;
1459 end;
1460
1461 procedure TBoard.EndUpdate;
1462 begin
1463         FUpdate := True;
1464 end;
1465
1466 {class function TBoard.GetColumnName(Index: Integer): string;
1467 begin
1468         Result := COLUMN_THREADITEM[Index];
1469 end;
1470
1471 class function TBoard.GetColumnCount: Integer;
1472 begin
1473         Result := Length(COLUMN_THREADITEM);
1474 end;}
1475
1476 //constructor TThreadItem.Create(AOwner: TComponent);
1477 procedure TThreadItem.Init;
1478 begin
1479         FNo := 0;
1480         FFileName := '';
1481         FTitle := '';
1482         FRoundDate := ZERO_DATE;
1483         FLastModified := ZERO_DATE;
1484         FCount := 0;
1485         FAllResCount := 0;
1486         FNewResCount := 0;
1487         FSize := 0;
1488         FRound := False;
1489         FIsLogFile := False;
1490         FParentBoard := nil;
1491         FKokomade := -1;
1492         FNewReceive := 0;
1493         FNewArrival := False;
1494
1495         FUpdate := True;
1496         FURL := '';
1497         FBoardPlugIn := nil;
1498 end;
1499
1500 // *************************************************************************
1501 // \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^
1502 // *************************************************************************
1503 constructor TThreadItem.Create(
1504         inPlugIn        : TBoardPlugIn;
1505         inURL                   : string
1506 );
1507 var
1508         foundPos                        : Integer;
1509         protocol, host, path, document, port, bookmark  : string;
1510         BBSID, BBSKey   : string;
1511 const
1512         READ_PATH                                                       = '/test/read.cgi';
1513 begin
1514
1515         inherited Create;
1516         Init;
1517
1518         FBoardPlugIn    := inPlugIn;
1519         URL                                             := inURL;
1520
1521         if inPlugIn = nil then begin
1522                 foundPos := Pos( READ_PATH, inURL );
1523                 if foundPos > 0 then begin
1524                         // dat \82Ì\95Û\91\83p\83X\82ð\90Ý\92è
1525                         GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
1526                         GikoSys.Parse2chURL( inURL, path, document, BBSID, BBSKey );
1527                         if GikoSys.Is2chHost( host ) then
1528                                 FilePath :=
1529                                         IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
1530                                         BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat'
1531                         else
1532                                 FilePath :=
1533                                         IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
1534                                         EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat';
1535                         FileName        := BBSKey + '.dat';
1536                         IsLogFile       := FileExists( FilePath );
1537                         URL                             := GikoSys.Get2chBrowsableThreadURL( inURL );
1538                 end;
1539         end else begin
1540                 // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1541                 inPlugIn.CreateThreadItem( DWORD( Self ) );
1542         end;
1543
1544 end;
1545
1546 // *************************************************************************
1547 // \83f\83X\83g\83\89\83N\83^
1548 // *************************************************************************
1549 destructor TThreadItem.Destroy;
1550 begin
1551
1552         // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1553         if IsBoardPlugInAvailable then
1554                 FBoardPlugIn.DisposeThreadItem( DWORD( Self ) );
1555
1556         inherited;
1557
1558 end;
1559
1560 // *************************************************************************
1561 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
1562 // *************************************************************************
1563 function        TThreadItem.IsBoardPlugInAvailable : Boolean;
1564 begin
1565
1566         repeat
1567                 if BoardPlugIn = nil then
1568                         Break;
1569
1570                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
1571                         Break;
1572
1573                 Result := True;
1574                 Exit;
1575         until True;
1576
1577         Result := False;
1578
1579 end;
1580
1581 function TThreadItem.GetDatURL: string;
1582 var
1583         Protocol, Host, Path, Document, Port, Bookmark: string;
1584 begin
1585         Result := ParentBoard.URL
1586                                         + 'dat/'
1587                                         + FileName;
1588         if FDownloadHost <> '' then begin
1589                 GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1590                 Result := Format('%s://%s%s%s', [Protocol,
1591                                                                                                                                                  FDownloadHost,
1592                                                                                                                                                  Path,
1593                                                                                                                                                  Document]);
1594         end;
1595 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1596 //                                      + 'test/read.cgi/' + ParentBoard.BBSID + '/'
1597 //                                      + ChangeFileExt(FileName, '') + '/?raw='
1598 //                                      + IntToStr(ResNum) + '.' + IntToStr(ResSize);
1599 end;
1600
1601 function TThreadItem.GetDatgzURL: string;
1602         function isOldKako(s: string): Boolean;
1603         begin
1604                 Result := False;
1605                 if AnsiPos('piza.', s) <> 0 then
1606                         Result := True
1607                 else if AnsiPos('www.bbspink.', s) <> 0 then
1608                         Result := True
1609                 else if AnsiPos('tako.', s) <> 0 then
1610                         Result := True;
1611         end;
1612 var
1613         Protocol, Host, Path, Document, Port, Bookmark: string;
1614         DatNo: string;
1615 begin
1616         if FDownloadHost = '' then begin
1617                 DatNo := ChangeFileExt(FileName, '');
1618                 if isOldKako(ParentBoard.URL) then begin
1619                         Result := Format('%s%s/%.3s/%s.dat', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1620                 end else begin
1621                         if Length(DatNo) > 9 then begin
1622                                 //http://xxx.2ch.net/xxx/kako/9999/99999/999999999.dat.gz
1623                                 Result := Format('%s%s/%.4s/%.5s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo, DatNo]);
1624                         end else begin
1625                                 //http://xxx.2ch.net/xxx/kako/999/999999999.dat.gz
1626                                 Result := Format('%s%s/%.3s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1627                         end;
1628                 end;
1629         end else begin
1630                 Gikosys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1631                 DatNo := ChangeFileExt(Document, '');
1632                 if isOldKako(DownloadHost) then begin
1633                         Result := Format('%s://%s/%s/kako/%.3s/%s.dat', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1634                 end else begin
1635                         if Length(DatNo) > 9 then begin
1636                                 Result := Format('%s://%s/%s/kako/%.4s/%.5s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo, DatNo]);
1637                         end else begin
1638                                 Result := Format('%s://%s/%s/kako/%.3s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1639                         end;
1640                 end;
1641         end;
1642 end;
1643
1644 {function TThreadItem.GetOldDatgzURL: string;
1645 var
1646         Protocol, Host, Path, Document, Port, Bookmark: string;
1647 begin
1648         Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL,
1649                                                                                                                                                          'kako',
1650                                                                                                                                                          FileName,
1651                                                                                                                                                          FileName]);
1652         if FDownloadHost <> '' then begin
1653                 ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1654                 Result := Format('%s://%s%s%s', [Protocol,
1655                                                                                                                                                  DownloadHost,
1656                                                                                                                                                  Path,
1657                                                                                                                                                  Document]);
1658
1659         end;
1660 end;}
1661
1662 function TThreadItem.GetOfflawCgiURL(const SessionID: string): string;
1663 //var
1664 //      Protocol, Host, Path, Document, Port, Bookmark: string;
1665 begin
1666 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1667 //                                      + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1668 //                                      + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1669         if FDownloadHost = '' then begin
1670                 Result := GikoSys.UrlToServer(ParentBoard.URL)
1671                                                 + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1672                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1673         end else begin
1674                 //http://news.2ch.net/test/offlaw.cgi/newsplus/1014038577/?raw=.196928&sid=
1675                 //GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1676                 Result := 'http://' + FDownloadHost
1677                                                 + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1678                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1679 //              Result := Format('%s://%s%s%s', [Protocol,
1680 //                                                                                                                                               DownloadHost,
1681 //                                                                                                                                               Path,
1682 //                                                                                                                                               Document]);
1683         end;
1684 end;
1685
1686 function TThreadItem.GetSendURL: string;
1687 begin
1688         Result := GikoSys.UrlToServer(ParentBoard.URL)
1689                                         + 'test/bbs.cgi';
1690 end;
1691
1692 procedure TThreadItem.DeleteLogFile;
1693 begin
1694         ParentBoard.BeginUpdate;
1695
1696         if FUnRead then
1697                 ParentBoard.UnRead := ParentBoard.UnRead - 1;
1698         DeleteFile(GetThreadFileName);
1699         if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1700                 DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
1701         FRoundDate := ZERO_DATE;
1702         FLastModified := ZERO_DATE;
1703         FSize := 0;
1704         FIsLogFile := False;
1705         FKokomade := -1;
1706         FNewReceive := 0;
1707         FNewArrival := False;
1708         FUnRead := False;
1709         FScrollTop := 0;
1710         FRound := False;
1711         FDownloadHost := '';
1712         FAgeSage := gasNone;
1713
1714         FCount := 0;
1715         FNewResCount := 0;
1716         FRoundName := '';
1717
1718         ParentBoard.EndUpdate;
1719         ParentBoard.Modified := True;
1720 end;
1721
1722 function TThreadItem.GetThreadFileName: string;
1723 begin
1724         if Length( FilePath ) > 0 then
1725                 Result := FilePath
1726         else
1727                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1728                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + ParentBoard.BBSID + PATH_DELIM + FileName;
1729 end;
1730
1731 procedure TThreadItem.SetLastModified(d: TDateTime);
1732 begin
1733         if FLastModified = d then Exit;
1734         FLastModified := d;
1735         if FUpdate and (ParentBoard <> nil) then
1736                 ParentBoard.FModified := True;
1737 end;
1738
1739 {procedure TThreadItem.SetRoundNo(i: Integer);
1740 begin
1741         if FRoundNo = i then Exit;
1742         FRoundNo := i;
1743         if FUpdate and (ParentBoard <> nil) then
1744                 ParentBoard.FModified := True;
1745 end;}
1746
1747 procedure TThreadItem.SetRound(b: Boolean);
1748 begin
1749         if b then
1750                 RoundList.Add(Self)
1751         else
1752                 RoundList.Delete(Self);
1753         if FRound = b then Exit;
1754         FRound := b;
1755         if FUpdate and (ParentBoard <> nil) then
1756                 ParentBoard.FModified := True;
1757 end;
1758
1759 procedure TThreadItem.SetRoundName(const s: string);
1760 begin
1761         if FRoundName = s then Exit;
1762         FRoundName := s;
1763         if FUpdate and (ParentBoard <> nil) then
1764                 ParentBoard.FModified := True;
1765 end;
1766
1767 procedure TThreadItem.SetKokomade(i: Integer);
1768 begin
1769         if FKokomade = i then Exit;
1770         FKokomade := i;
1771         if FUpdate and (ParentBoard <> nil) then
1772                 ParentBoard.FModified := True;
1773 end;
1774
1775 procedure TThreadItem.SetUnRead(b: Boolean);
1776 begin
1777         if FUnRead = b then Exit;
1778         FUnRead := b;
1779         if FUpdate and (ParentBoard <> nil) then
1780                 ParentBoard.FModified := True;
1781 end;
1782
1783 procedure TThreadItem.SetScrollTop(i: Integer);
1784 begin
1785         if FScrollTop = i then Exit;
1786         FScrollTop := i;
1787         if FUpdate and (ParentBoard <> nil) then
1788                 ParentBoard.FModified := True;
1789 end;
1790
1791 procedure TThreadItem.BeginUpdate;
1792 begin
1793         FUpdate := False;
1794 end;
1795
1796 procedure TThreadItem.EndUpdate;
1797 begin
1798         FUpdate := True;
1799 end;
1800
1801 {initialization
1802         BBS2ch := TBBS.Create;
1803
1804 finalization
1805         if BBS2ch <> nil then
1806                 BBS2ch.Free;}
1807 function TThreadItem.GetCreateDate: TDateTime;
1808 var
1809         unixtime: Int64;
1810     tmp: string;
1811 begin
1812         // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\8dì\90¬\93ú\8e\9e\82ð\8b\81\82ß\82é
1813         try
1814                 if ( GikoSys.Setting.CreationTimeLogs ) and not IsLogFile  then
1815             Result := ZERO_DATE
1816         else begin
1817             // \83\8d\83O\83t\83@\83C\83\8b\82Ì\8ag\92£\8eq\82ð\82Í\82¸\82µ\82½\82à\82Ì\82ª\83X\83\8c\8dì\90¬\93ú\8e\9e
1818                         tmp := ChangeFileExt(FFileName, '');
1819                         if AnsiPos('_', tmp) <> 0 then
1820                                 if AnsiPos('_', tmp) > 9 then
1821                                         tmp := Copy(tmp, 1, AnsiPos('_', tmp)-1)
1822                                 else
1823                                         Delete(tmp, AnsiPos('_', tmp), 1);
1824
1825                         if ( Length(tmp) = 9) and ( tmp[1] = '0' ) then
1826                                 Insert('1', tmp, 1);
1827
1828                         unixtime := StrToInt64Def(tmp, ZERO_DATE);
1829                         Result := UnixToDateTime(unixtime) + OffsetFromUTC;
1830                         if GikoSys.Setting.FutureThread then begin
1831                         if CompareDateTime(Result, Now) = 1 then
1832                         Result := ZERO_DATE;
1833                 end;
1834         end;
1835
1836         except
1837                 on E: Exception do
1838                         Result := ZERO_DATE;
1839         end;
1840 end;
1841
1842 end.
1843