OSDN Git Service

ReadSubjectでの検索用タイトルの作成を止めた。(読み込みの高速化のために)
[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
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
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
679                 TBoard(Items[index]).Free;
680         inherited Delete(index);
681 end;
682
683 procedure TCategory.Clear;
684 var
685         i: integer;
686 begin
687         for i := Count - 1 downto 0 do
688                 Delete(i);
689         Capacity := Count;
690 end;
691
692 function TCategory.FindName(const key: string): TBoard;
693 begin
694         Result := nil;
695 end;
696
697 function TCategory.FindBBSID(const BBSID: string): TBoard;
698 var
699         i       : integer;
700 begin
701         for i := Count - 1 downto 0 do begin
702                 if AnsiCompareStr(Items[i].FBBSID, BBSID) = 0 then begin
703                         Result := Items[i];
704                         Exit;
705                 end;
706         end;
707         Result := nil;
708 end;
709
710 //*************************************************************************
711 // \83^\83C\83g\83\8b\82Ì\88ê\92v\82·\82é\94Â\82ð\92T\82·
712 //*************************************************************************)
713 function TCategory.FindBoardFromTitle(const Title: string): TBoard;
714 var
715         i       : integer;
716 begin
717         for i := Count - 1 downto 0 do begin
718                 if AnsiCompareStr(Items[i].FTitle, Title) = 0 then begin
719                         Result := Items[i];
720                         Exit;
721                 end;
722         end;
723         Result := nil;
724 end;
725
726 //*************************************************************************
727 // URL \82ð\8eó\82¯\95t\82¯\82é\94Â\82ð\92T\82·
728 //*************************************************************************)
729 function TCategory.FindBoardFromURL(const inURL: string): TBoard;
730 var
731         i       : Integer;
732 begin
733         i := IndexOf( inURL );
734         if i >= 0 then
735                 Result := TBoard( Objects[ i ] )
736         else
737                 Result := nil;
738 end;
739
740 //*************************************************************************
741 // URL \82ð\8eó\82¯\95t\82¯\82é\83X\83\8c\83b\83h\82ð\92T\82·
742 //*************************************************************************)
743 function TCategory.FindThreadFromURL(const inURL: string): TThreadItem;
744 var
745         board                   : TBoard;
746         boardURL        : string;
747 begin
748
749         boardURL        := GikoSys.GetThreadURL2BoardURL( inURL );
750         board                   := FindBoardFromURL( boardURL );
751         if board = nil then
752                 Result := nil
753         else
754                 Result := board.FindThreadFromURL( inURL );
755
756 end;
757
758 function TCategory.IsMidoku: Boolean;
759 var
760         i: Integer;
761         j: Integer;
762 begin
763         Result := False;
764         for i := 0 to Count - 1 do begin
765                 if Items[i] <> nil then begin
766                         for j := 0 to Items[i].Count - 1 do begin
767                                 if Items[i].Items[j] <> nil then begin
768 //                                      if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].Count > Items[i].Items[j].Kokomade) then begin
769                                         if (Items[i].Items[j].IsLogFile) and (Items[i].Items[j].UnRead) then begin
770                                                 Result := True;
771                                                 Exit;
772                                         end;
773                                 end;
774                         end;
775                 end;
776         end;
777 end;
778
779 {class function TCategory.GetColumnName(Index: Integer): string;
780 begin
781         Result := COLUMN_BOARD[Index];
782 end;
783
784 class function TCategory.GetColumnCount: Integer;
785 begin
786         Result := Length(COLUMN_BOARD);
787 end;}
788
789 //===================
790 //TBoard
791 //===================
792 procedure TBoard.Init;
793 begin
794         Duplicates              := dupIgnore;
795         CaseSensitive   := False;
796         //Sorted                                := True;
797
798         FNo := 0;
799         FTitle := '';
800         FBBSID := '';
801         FURL := '';
802         FRound := False;
803         FRoundDate := ZERO_DATE;
804         FLastModified := ZERO_DATE;
805         FLastGetTime := ZERO_DATE;
806         FIsThreadDatRead := False;
807         FUnRead := 0;
808 //      FListStyle := vsReport;
809 //      FItemNoVisible := True;
810
811         FUpdate := True;
812 end;
813
814 // *************************************************************************
815 // \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^
816 // *************************************************************************
817 constructor TBoard.Create(
818         inPlugIn        : TBoardPlugIn;
819         inURL                   : string
820 );
821 var
822         protocol, host, path, document, port, bookmark  : string;
823 begin
824
825         inherited Create;
826         Init;
827
828         FBoardPlugIn    := inPlugIn;
829         URL                                             := inURL;
830         BBSID                                   := GikoSys.UrlToID( inURL );
831
832         if inPlugIn = nil then begin
833                 // subject.txt \82Ì\95Û\91\83p\83X\82ð\90Ý\92è
834                 GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
835                 if GikoSys.Is2chHost( host ) then
836                         FilePath :=
837                                 IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
838                                 BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME
839                 else
840                         FilePath :=
841                                 IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
842                                 EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME
843         end else begin
844                 // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
845                 inPlugIn.CreateBoardItem( DWORD( Self ) );
846         end;
847
848 end;
849
850 // *************************************************************************
851 // \83f\83X\83g\83\89\83N\83^
852 // *************************************************************************
853 destructor TBoard.Destroy;
854 begin
855         if FModified then begin
856                 GikoSys.WriteThreadDat(Self);
857                 SaveSettings;
858         end;
859
860         // \83v\83\89\83O\83C\83\93\82É TBoardItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
861         if IsBoardPlugInAvailable then
862                 BoardPlugIn.DisposeBoardItem( DWORD( Self ) );
863
864         Clear;
865         inherited;
866 end;
867
868 // *************************************************************************
869 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
870 // *************************************************************************
871 function        TBoard.IsBoardPlugInAvailable : Boolean;
872 begin
873
874         repeat
875                 if BoardPlugIn = nil then
876                         Break;
877                         
878                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
879                         Break;
880
881                 Result := True;
882                 Exit;
883         until True;
884
885         Result := False;
886
887 end;
888
889 function TBoard.GetThreadItem(index: integer): TThreadItem;
890 begin
891         Result := TThreadItem( Objects[index] );
892 end;
893
894 procedure TBoard.SetThreadItem(index: integer; value: TThreadItem);
895 begin
896         Objects[index] := value;
897         Strings[index] := value.URL;
898 end;
899
900 function TBoard.Add(Item: TThreadItem): Integer;
901 begin
902         Item.ParentBoard := Self;
903         Result := inherited AddObject(Item.URL, Item);
904 end;
905
906 procedure TBoard.Insert(Index: Integer; Item: TThreadItem);
907 begin
908         Item.ParentBoard := Self;
909         inherited InsertObject(Index, Item.URL, Item);
910
911 end;
912
913 //Index\82Å\8ew\92è\82³\82ê\82½\83X\83\8c\83b\83h\83I\83u\83W\83F\83N\83g\82ð\94j\8aü
914 procedure TBoard.Delete(index: Integer);
915 begin
916         if Items[index] <> nil then
917                 TThreadItem(Items[index]).Free;
918         inherited Delete(index);
919 end;
920
921 //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
922 procedure TBoard.DeleteList(index: integer);
923 begin
924         inherited Delete(index);
925 end;
926
927 procedure TBoard.Clear;
928 var
929         i: integer;
930 begin
931 //      FUnRead := 0;
932         for i := Count - 1 downto 0 do
933                 Delete(i);
934          Capacity := Count;
935 end;
936
937 function TBoard.FindThreadFromFileName(const ItemFileName: string): TThreadItem;
938 var
939         i: integer;
940 begin
941         Result := nil;
942         for i := 0 to Count - 1 do begin
943                 if AnsiCompareStr(Items[i].FileName, ItemFileName) = 0 then begin
944                         Result := Items[i];
945                         Exit;
946                 end;
947         end;
948 end;
949
950 function TBoard.GetIndexFromFileName(const ItemFileName: string): Integer;
951 var
952         i: integer;
953 begin
954         Result := -1;
955         for i := 0 to Count - 1 do begin
956                 if Items[i].FileName = ItemFileName then begin
957                         Result := i;
958                         Exit;
959                 end;
960         end;
961 end;
962
963 function TBoard.GetIndexFromURL(const URL: string): Integer;
964 begin
965         Result := IndexOf( URL );
966 end;
967
968 function TBoard.FindThreadFromURL(const inURL : string ) : TThreadItem;
969 var
970         i : Integer;
971 begin
972
973         if not IsThreadDatRead then
974                 GikoSys.ReadSubjectFile( Self );
975
976         i := IndexOf( inURL );
977         if i >= 0 then
978                 Result := TThreadItem( Objects[ i ] )
979         else
980                 Result := nil;
981
982 end;
983
984 {function TBoard.GetMidokuCount: Integer;
985 var
986         i: integer;
987 begin
988         Result := 0;
989         for i := 0 to Count- 1 do begin
990                 if Items[i] <> nil then begin
991                         if (Items[i].IsLogFile) and (Items[i].Count > Items[i].Kokomade) then
992                                 inc(Result);
993                 end;
994         end;
995 end;
996 }
997
998 procedure TBoard.LoadSettings;
999 var
1000         ini: TMemIniFile;
1001         FileName: string;
1002     tmp: string;
1003 begin
1004         if Length( FilePath ) > 0 then
1005                 FileName := ExtractFilePath( FilePath ) + FOLDER_INI_FILENAME
1006         else
1007                 FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1008                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INI_FILENAME;
1009
1010         if not FileExists(FileName) then
1011                 Exit;
1012         ini := TMemIniFile.Create(FileName);
1013         try
1014 //              Round := ini.ReadBool('Status', 'Round', False);
1015                 tmp := ini.ReadString('Status', 'RoundDate', DateTimeToStr(ZERO_DATE));
1016                 FRoundDate := ConvertDateTimeString(tmp);
1017                 tmp := ini.ReadString('Status', 'LastModified', DateTimeToStr(ZERO_DATE));
1018                 FLastModified := ConvertDateTimeString(tmp);
1019                 tmp := ini.ReadString('Status', 'LastGetTime', DateTimeToStr(ZERO_DATE));
1020                 FLastGetTime := ConvertDateTimeString(tmp);
1021
1022                 tmp := ini.ReadString('BoardInformation', 'SETTINGTXTTime', DateTimeToStr(ZERO_DATE));
1023                 FSETTINGTXTTime := ConvertDateTimeString(tmp);
1024                 tmp := ini.ReadString('BoardInformation', 'HEADTXTTime', DateTimeToStr(ZERO_DATE));
1025                 FHEADTXTTime := ConvertDateTimeString(tmp);
1026
1027                 FIsSETTINGTXT := ini.ReadBool('BoardInformation', 'IsSETTINGTXT', false);
1028                 FIsHEADTXT := ini.ReadBool('BoardInformation', 'IsHEADTXT', false);
1029                 FTitlePictureURL := ini.ReadString('BoardInformation', 'TitlePictureURL', '');
1030
1031                 FUnRead := ini.ReadInteger('Status', 'UnRead', 0);
1032                 FSPID := ini.ReadString('Cookie', 'SPID', '');
1033                 FPON := ini.ReadString('Cookie', 'PON', '');
1034                 FKotehanName := ini.ReadString('Kotehan', 'Name', '');
1035                 FKotehanMail := ini.ReadString('Kotehan', 'Mail', '');
1036
1037                 if UnRead < 0 then
1038                         UnRead := 0;
1039         finally
1040                 ini.Free;
1041         end;
1042 end;
1043
1044 procedure TBoard.SaveSettings;
1045 var
1046         ini: TMemIniFile;
1047         FileName: string;
1048 begin
1049         if Length( FilePath ) > 0 then
1050                 FileName := ExtractFilePath( FilePath )
1051         else
1052                 FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1053                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM;
1054         if not GikoSys.DirectoryExistsEx(FileName) then
1055                 GikoSys.ForceDirectoriesEx(FileName);
1056         FileName := FileName + FOLDER_INI_FILENAME;
1057         ini := TMemIniFile.Create(FileName);
1058         try
1059                 if UnRead < 0 then
1060                         UnRead := 0;
1061 //              ini.WriteBool('Status', 'Round', Round);
1062                 ini.WriteDateTime('Status', 'RoundDate', FRoundDate);
1063                 ini.WriteDateTime('Status', 'LastModified', FLastModified);
1064                 ini.WriteDateTime('Status', 'LastGetTime', FLastGetTime);
1065                 ini.WriteInteger('Status', 'UnRead', FUnRead);
1066                 ini.WriteString('Cookie', 'SPID', FSPID);
1067                 ini.WriteString('Cookie', 'PON', FPON);
1068                 ini.WriteString('Kotehan', 'Name', FKotehanName);
1069                 ini.WriteString('Kotehan', 'Mail', FKotehanMail);
1070
1071                 ini.WriteDateTime('BoardInformation', 'SETTINGTXTTime', FSETTINGTXTTime);
1072                 ini.WriteDateTime('BoardInformation', 'HEADTXTTime', FHEADTXTTime);
1073
1074                 ini.WriteBool('BoardInformation', 'IsSETTINGTXT', FIsSETTINGTXT);
1075                 ini.WriteBool('BoardInformation', 'IsHEADTXT', FIsHEADTXT);
1076                 ini.WriteString('BoardInformation', 'TitlePictureURL', FTitlePictureURL);
1077 //              ini.WriteInteger('Status', 'ListStyle', Ord(ListStyle));
1078 //              ini.WriteBool('Status', 'ItemNoVisible', ItemNoVisible);
1079 //              ini.WriteInteger('Status', 'ViewType', Ord(ViewType));
1080                 ini.UpdateFile;
1081         finally
1082                 ini.Free;
1083         end;
1084 end;
1085 //\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ð
1086 //        2003/02/08 0:32:13\82É\95Ï\8a·\82·\82é
1087 function        ConvertDateTimeString( inDateTimeString : string) : TDateTime;
1088 const
1089         ZERO_DATE_STRING : string = '1970/01/01 0:00:00';
1090 var
1091         i : Integer;
1092     y: Integer;
1093     m: Integer;
1094     d: Integer;
1095     hour: Integer;
1096     min: Integer;
1097     sec: Integer;
1098 begin
1099     if inDateTimeString = '' then
1100         inDateTimeString := ZERO_DATE_STRING;
1101
1102     if ( AnsiPos('/', inDateTimeString ) = 0 ) and
1103         ( AnsiCompareStr( DateTimeToStr(ZERO_DATE), inDateTimeString) <> 0 ) then begin
1104                 for i := 0 to 1 do begin
1105                 Insert('/',inDateTimeString, AnsiPos(' ', inDateTimeString) + 1 );
1106                 Delete(inDateTimeString, AnsiPos(' ', inDateTimeString), 1);
1107         end;
1108     end;
1109     try
1110         Result := StrToDateTime( inDateTimeString );
1111     except
1112         if( inDateTimeString[5] = '/' ) and ( inDateTimeString[8] = '/' ) then begin
1113             y := StrToIntDef( Copy(inDateTimeString, 1, 4), 1970 );
1114             m := StrToIntDef( Copy(inDateTimeString, 6, 2), 1 );
1115             d := StrToIntDef( Copy(inDateTimeString, 9, 2), 1 );
1116             hour := 0; min  := 0; sec  := 0;
1117
1118                 if Length(inDateTimeString) > 11 then begin
1119                 if( inDateTimeString[13] = ':' ) and ( inDateTimeString[16] = ':' ) then begin
1120                         hour := StrToIntDef( Copy(inDateTimeString, 12, 1), 0 );
1121                     min  := StrToIntDef( Copy(inDateTimeString, 14, 2), 0 );
1122                     sec  := StrToIntDef( Copy(inDateTimeString, 17, 2), 0 );
1123                 end else if( inDateTimeString[14] = ':' ) and ( inDateTimeString[17] = ':' ) then begin
1124                         hour := StrToIntDef( Copy(inDateTimeString, 12, 2), 0 );
1125                     min  := StrToIntDef( Copy(inDateTimeString, 15, 2), 0 );
1126                     sec  := StrToIntDef( Copy(inDateTimeString, 18, 2), 0 );
1127                 end;
1128             end;
1129             try
1130                 Result := EncodeDateTime(y ,m, d, hour, min, sec, 0);
1131             except
1132                 Result := ZERO_DATE;
1133             end;
1134         end else
1135                 Result := ZERO_DATE;
1136     end;
1137
1138
1139    // Result := inDateTimeString;
1140 end;
1141 // \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
1142 function TBoard.GetReadCgiURL: string;
1143 begin
1144         //Result := URL + SUBJECT_FILENAME;
1145         //Result := GikoSys.UrlToServer(URL)
1146         //                              + 'test/read.cgi/' + BBSID + '/?raw=0.0';
1147         Result := URL + SUBJECT_FILENAME;
1148
1149 end;
1150
1151 // \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
1152 function TBoard.GetSubjectFileName: string;
1153 begin
1154         if Length( FilePath ) > 0 then
1155                 Result := FilePath
1156         else
1157                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1158                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME;
1159 end;
1160
1161 // \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
1162 function TBoard.GetFolderIndexFileName: string;
1163 begin
1164         if Length( FilePath ) > 0 then
1165                 Result := ExtractFilePath( FilePath ) + FOLDER_INDEX_FILENAME
1166         else
1167                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1168                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME;
1169 end;
1170 //SETTING.TXT\82Ì\83t\83@\83C\83\8b\96¼\8eæ\93¾
1171 function TBoard.GetSETTINGTXTFileName: string;
1172 begin
1173         if Length( FilePath ) > 0 then
1174                 Result := ExtractFilePath( FilePath ) + SETTINGTXT_FILENAME
1175         else
1176                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1177                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SETTINGTXT_FILENAME;
1178 end;
1179
1180 function TBoard.GETHEADTXTFileName: string;
1181 begin
1182         if Length( FilePath ) > 0 then
1183                 Result := ExtractFilePath( FilePath ) + HEADTXT_FILENAME
1184         else
1185                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1186                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + HEADTXT_FILENAME;
1187 end;
1188 function TBoard.GetTitlePictureFileName: string;
1189 var
1190         tmpName: string;
1191 begin
1192         if FTitlePictureURL = '' then
1193                 Result := ''
1194         else begin
1195                 tmpName := Copy(FTitlePictureURL, LastDelimiter('/', FTitlePictureURL) + 1, Length(FTitlePictureURL));
1196                 if Length( FilePath ) > 0 then
1197                         Result := ExtractFilePath( FilePath ) + tmpName
1198                 else
1199                         Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1200                                                         + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + tmpName;
1201         end;
1202 end;
1203
1204 // \83X\83\8c\97§\82Ä\91\97\90MURL
1205 function TBoard.GetSendURL: string;
1206 begin
1207         Result := GikoSys.UrlToServer(URL) + 'test/subbbs.cgi';
1208 end;
1209
1210 procedure TBoard.SetRound(b: Boolean);
1211 begin
1212         if b then
1213                 RoundList.Add(Self)
1214         else
1215                 RoundList.Delete(Self);
1216         if FRound = b then Exit;
1217         FRound := b;
1218         if FUpdate then
1219                 FModified := True;
1220 end;
1221
1222 procedure TBoard.SetRoundName(s: string);
1223 begin
1224         if FRoundName = s then Exit;
1225         FRoundName := s;
1226         if FUpdate then
1227                 FModified := True;
1228 end;
1229
1230 procedure TBoard.SetLastModified(d: TDateTime);
1231 begin
1232         if FLastModified = d then Exit;
1233         FLastModified := d;
1234         if FUpdate then
1235                 FModified := True;
1236 end;
1237
1238 procedure TBoard.SetLastGetTime(d: TDateTime);
1239 begin
1240         if FLastGetTime = d then Exit;
1241         FLastGetTime := d;
1242         if FUpdate then
1243                 FModified := True;
1244 end;
1245
1246 procedure TBoard.SetUnRead(i: Integer);
1247 begin
1248         if FUnRead = i then Exit;
1249         if i < 0 then i := 0;
1250         FUnRead := i;
1251         if FUpdate then
1252                 FModified := True;
1253 end;
1254
1255 procedure TBoard.SetKotehanName(s: string);
1256 begin
1257         if FKotehanName = s then Exit;
1258         FKotehanName := s;
1259         if FUpdate then
1260                 FModified := True;
1261 end;
1262
1263 procedure TBoard.SetKotehanMail(s: string);
1264 begin
1265         if FKotehanMail = s then Exit;
1266         FKotehanMail := s;
1267         if FUpdate then
1268                 FModified := True;
1269 end;
1270
1271 function TBoard.GetNewThreadCount: Integer;
1272 var
1273         i: Integer;
1274 begin
1275         Result := 0;
1276         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1277         begin
1278                 for i := 0 to Count - 1 do begin
1279                         if Items[i].NewArrival then
1280                                 inc(Result);
1281                 end;
1282         end else begin
1283                 for i := 0 to Count - 1 do begin
1284                         if Items[i].NewArrival then
1285                         begin
1286                                 if Items[i].ShortTitle = '' then
1287                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1288                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1289                                         inc(Result);
1290                         end;
1291                 end;
1292         end;
1293 end;
1294
1295 function TBoard.GetLogThreadCount: Integer;
1296 var
1297         i: Integer;
1298 begin
1299         Result := 0;
1300         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1301         begin
1302                 for i := 0 to Count - 1 do begin
1303                         if Items[i].IsLogFile then
1304                                 inc(Result);
1305                 end;
1306         end else begin
1307                 for i := 0 to Count - 1 do begin
1308                         if Items[i].IsLogFile then
1309                         begin
1310                                 if Items[i].ShortTitle = '' then
1311                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1312                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1313                                         inc(Result);
1314                         end;
1315                 end;
1316         end;
1317 end;
1318
1319 function TBoard.GetUserThreadCount: Integer;
1320 var
1321         i: Integer;
1322 begin
1323         Result := 0;
1324         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1325                 Result := Count
1326         else
1327                 for i := 0 to Count - 1 do begin
1328                         if Items[i].ShortTitle = '' then
1329                                 Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1330                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
1331                                 inc(Result);
1332                 end;
1333 end;
1334
1335 function TBoard.GetNewThread(Index: Integer): TThreadItem;
1336 var
1337         i: Integer;
1338         Cnt: Integer;
1339 begin
1340         Result := nil;
1341         Cnt := 0;
1342         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1343         begin
1344                 for i := 0 to Count - 1 do begin
1345                         if Items[i].NewArrival then
1346                                                                         begin
1347                                 if Index = Cnt then begin
1348                                         Result := Items[i];
1349                                         Exit;
1350                                 end;
1351                                 inc(Cnt);
1352                         end;
1353                 end;
1354         end else begin
1355                 for i := 0 to Count - 1 do begin
1356                         if Items[i].NewArrival then
1357                         begin
1358                                 if Items[i].ShortTitle = '' then
1359                                         Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1360                                 if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1361                                         if Index = Cnt then begin
1362                                                 Result := Items[i];
1363                                                 Exit;
1364                                         end;
1365                                         inc(Cnt);
1366                                 end;
1367                         end;
1368                 end;
1369         end;
1370 end;
1371
1372 function TBoard.GetLogThread(Index: Integer): TThreadItem;
1373 var
1374         i: Integer;
1375         Cnt: Integer;
1376 begin
1377         Cnt := 0;
1378         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1379         begin
1380                 for i := 0 to Count - 1 do begin
1381                         if Items[i].IsLogFile then
1382                                                                         begin
1383                                 if Index = Cnt then begin
1384                                         Result := Items[i];
1385                                         Exit;
1386                                 end;
1387                                 inc(Cnt);
1388                         end;
1389                 end;
1390         end else begin
1391                 for i := 0 to Count - 1 do begin
1392                         if Items[i].IsLogFile then
1393                                 begin
1394                                         if Items[i].ShortTitle = '' then
1395                                                 Items[i].ShortTitle := ZenToHan(Items[i].Title);
1396                                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1397                                                 if Index = Cnt then begin
1398                                                         Result := Items[i];
1399                                                         Exit;
1400                                         end;
1401                                         inc(Cnt);
1402                                 end;
1403                         end;
1404                 end;
1405         end;
1406         Result := nil;
1407 end;
1408
1409 function TBoard.GetUserThread(Index: Integer): TThreadItem;
1410 var
1411         i: Integer;
1412         Cnt: Integer;
1413 begin
1414         Result := nil;
1415         Cnt := 0;
1416         if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
1417         begin
1418                 for i := 0 to Count - 1 do begin
1419                         if Index = Cnt then
1420                         begin
1421                                 Result := Items[ i ];
1422                                 Exit;
1423                         end;
1424                         inc( Cnt );
1425                 end;
1426         end else begin
1427                 for i := 0 to Count - 1 do begin
1428                         if Items[i].ShortTitle = '' then
1429                                 Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
1430                         if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
1431                                 if Index = Cnt then begin
1432                                         Result := Items[i];
1433                                         Exit;
1434                                 end;
1435                                 inc(Cnt);
1436                         end;
1437                 end;
1438         end;
1439 end;
1440
1441 procedure TBoard.BeginUpdate;
1442 begin
1443         FUpdate := False;
1444 end;
1445
1446 procedure TBoard.EndUpdate;
1447 begin
1448         FUpdate := True;
1449 end;
1450
1451 {class function TBoard.GetColumnName(Index: Integer): string;
1452 begin
1453         Result := COLUMN_THREADITEM[Index];
1454 end;
1455
1456 class function TBoard.GetColumnCount: Integer;
1457 begin
1458         Result := Length(COLUMN_THREADITEM);
1459 end;}
1460
1461 //constructor TThreadItem.Create(AOwner: TComponent);
1462 procedure TThreadItem.Init;
1463 begin
1464         FNo := 0;
1465         FFileName := '';
1466         FTitle := '';
1467         FRoundDate := ZERO_DATE;
1468         FLastModified := ZERO_DATE;
1469         FCount := 0;
1470         FAllResCount := 0;
1471         FNewResCount := 0;
1472         FSize := 0;
1473         FRound := False;
1474         FIsLogFile := False;
1475         FParentBoard := nil;
1476         FKokomade := -1;
1477         FNewReceive := 0;
1478         FNewArrival := False;
1479
1480         FUpdate := True;
1481         FURL := '';
1482         FBoardPlugIn := nil;
1483 end;
1484
1485 // *************************************************************************
1486 // \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^
1487 // *************************************************************************
1488 constructor TThreadItem.Create(
1489         inPlugIn        : TBoardPlugIn;
1490         inURL                   : string
1491 );
1492 var
1493         foundPos                        : Integer;
1494         protocol, host, path, document, port, bookmark  : string;
1495         BBSID, BBSKey   : string;
1496 const
1497         READ_PATH                                                       = '/test/read.cgi';
1498 begin
1499
1500         inherited Create;
1501         Init;
1502
1503         FBoardPlugIn    := inPlugIn;
1504         URL                                             := inURL;
1505
1506         if inPlugIn = nil then begin
1507                 foundPos := Pos( READ_PATH, inURL );
1508                 if foundPos > 0 then begin
1509                         // dat \82Ì\95Û\91\83p\83X\82ð\90Ý\92è
1510                         GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
1511                         GikoSys.Parse2chURL( inURL, path, document, BBSID, BBSKey );
1512                         if GikoSys.Is2chHost( host ) then
1513                                 FilePath :=
1514                                         IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
1515                                         BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat'
1516                         else
1517                                 FilePath :=
1518                                         IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) +
1519                                         EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat';
1520                         FileName        := BBSKey + '.dat';
1521                         IsLogFile       := FileExists( FilePath );
1522                         URL                             := GikoSys.Get2chBrowsableThreadURL( inURL );
1523                 end;
1524         end else begin
1525                 // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\8dì\90¬\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1526                 inPlugIn.CreateThreadItem( DWORD( Self ) );
1527         end;
1528
1529 end;
1530
1531 // *************************************************************************
1532 // \83f\83X\83g\83\89\83N\83^
1533 // *************************************************************************
1534 destructor TThreadItem.Destroy;
1535 begin
1536
1537         // \83v\83\89\83O\83C\83\93\82É TThreadItem \82ª\94j\8aü\82³\82ê\82½\82±\82Æ\82ð\93`\82¦\82é
1538         if IsBoardPlugInAvailable then
1539                 FBoardPlugIn.DisposeThreadItem( DWORD( Self ) );
1540
1541         inherited;
1542
1543 end;
1544
1545 // *************************************************************************
1546 // \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
1547 // *************************************************************************
1548 function        TThreadItem.IsBoardPlugInAvailable : Boolean;
1549 begin
1550
1551         repeat
1552                 if BoardPlugIn = nil then
1553                         Break;
1554
1555                 if not Assigned( Pointer( BoardPlugIn.Module ) ) then
1556                         Break;
1557
1558                 Result := True;
1559                 Exit;
1560         until True;
1561
1562         Result := False;
1563
1564 end;
1565
1566 function TThreadItem.GetDatURL: string;
1567 var
1568         Protocol, Host, Path, Document, Port, Bookmark: string;
1569 begin
1570         Result := ParentBoard.URL
1571                                         + 'dat/'
1572                                         + FileName;
1573         if FDownloadHost <> '' then begin
1574                 GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1575                 Result := Format('%s://%s%s%s', [Protocol,
1576                                                                                                                                                  FDownloadHost,
1577                                                                                                                                                  Path,
1578                                                                                                                                                  Document]);
1579         end;
1580 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1581 //                                      + 'test/read.cgi/' + ParentBoard.BBSID + '/'
1582 //                                      + ChangeFileExt(FileName, '') + '/?raw='
1583 //                                      + IntToStr(ResNum) + '.' + IntToStr(ResSize);
1584 end;
1585
1586 function TThreadItem.GetDatgzURL: string;
1587         function isOldKako(s: string): Boolean;
1588         begin
1589                 Result := False;
1590                 if AnsiPos('piza.', s) <> 0 then
1591                         Result := True
1592                 else if AnsiPos('www.bbspink.', s) <> 0 then
1593                         Result := True
1594                 else if AnsiPos('tako.', s) <> 0 then
1595                         Result := True;
1596         end;
1597 var
1598         Protocol, Host, Path, Document, Port, Bookmark: string;
1599         DatNo: string;
1600 begin
1601         if FDownloadHost = '' then begin
1602                 DatNo := ChangeFileExt(FileName, '');
1603                 if isOldKako(ParentBoard.URL) then begin
1604                         Result := Format('%s%s/%.3s/%s.dat', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1605                 end else begin
1606                         if Length(DatNo) > 9 then begin
1607                                 //http://xxx.2ch.net/xxx/kako/9999/99999/999999999.dat.gz
1608                                 Result := Format('%s%s/%.4s/%.5s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo, DatNo]);
1609                         end else begin
1610                                 //http://xxx.2ch.net/xxx/kako/999/999999999.dat.gz
1611                                 Result := Format('%s%s/%.3s/%s.dat.gz', [ParentBoard.URL, 'kako', DatNo, DatNo]);
1612                         end;
1613                 end;
1614         end else begin
1615                 Gikosys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1616                 DatNo := ChangeFileExt(Document, '');
1617                 if isOldKako(DownloadHost) then begin
1618                         Result := Format('%s://%s/%s/kako/%.3s/%s.dat', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1619                 end else begin
1620                         if Length(DatNo) > 9 then begin
1621                                 Result := Format('%s://%s/%s/kako/%.4s/%.5s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo, DatNo]);
1622                         end else begin
1623                                 Result := Format('%s://%s/%s/kako/%.3s/%s.dat.gz', [Protocol, DownloadHost, ParentBoard.FBBSID, DatNo, DatNo]);
1624                         end;
1625                 end;
1626         end;
1627 end;
1628
1629 {function TThreadItem.GetOldDatgzURL: string;
1630 var
1631         Protocol, Host, Path, Document, Port, Bookmark: string;
1632 begin
1633         Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL,
1634                                                                                                                                                          'kako',
1635                                                                                                                                                          FileName,
1636                                                                                                                                                          FileName]);
1637         if FDownloadHost <> '' then begin
1638                 ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1639                 Result := Format('%s://%s%s%s', [Protocol,
1640                                                                                                                                                  DownloadHost,
1641                                                                                                                                                  Path,
1642                                                                                                                                                  Document]);
1643
1644         end;
1645 end;}
1646
1647 function TThreadItem.GetOfflawCgiURL(const SessionID: string): string;
1648 //var
1649 //      Protocol, Host, Path, Document, Port, Bookmark: string;
1650 begin
1651 //      Result := GikoSys.UrlToServer(ParentBoard.URL)
1652 //                                      + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1653 //                                      + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1654         if FDownloadHost = '' then begin
1655                 Result := GikoSys.UrlToServer(ParentBoard.URL)
1656                                                 + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1657                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1658         end else begin
1659                 //http://news.2ch.net/test/offlaw.cgi/newsplus/1014038577/?raw=.196928&sid=
1660                 //GikoSys.ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
1661                 Result := 'http://' + FDownloadHost
1662                                                 + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/'
1663                                                 + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
1664 //              Result := Format('%s://%s%s%s', [Protocol,
1665 //                                                                                                                                               DownloadHost,
1666 //                                                                                                                                               Path,
1667 //                                                                                                                                               Document]);
1668         end;
1669 end;
1670
1671 function TThreadItem.GetSendURL: string;
1672 begin
1673         Result := GikoSys.UrlToServer(ParentBoard.URL)
1674                                         + 'test/bbs.cgi';
1675 end;
1676
1677 procedure TThreadItem.DeleteLogFile;
1678 begin
1679         ParentBoard.BeginUpdate;
1680
1681         if FUnRead then
1682                 ParentBoard.UnRead := ParentBoard.UnRead - 1;
1683         DeleteFile(GetThreadFileName);
1684         if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1685                 DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
1686         FRoundDate := ZERO_DATE;
1687         FLastModified := ZERO_DATE;
1688         FSize := 0;
1689         FIsLogFile := False;
1690         FKokomade := -1;
1691         FNewReceive := 0;
1692         FNewArrival := False;
1693         FUnRead := False;
1694         FScrollTop := 0;
1695         FRound := False;
1696         FDownloadHost := '';
1697         FAgeSage := gasNone;
1698
1699         FCount := 0;
1700         FNewResCount := 0;
1701         FRoundName := '';
1702
1703         ParentBoard.EndUpdate;
1704         ParentBoard.Modified := True;
1705 end;
1706
1707 function TThreadItem.GetThreadFileName: string;
1708 begin
1709         if Length( FilePath ) > 0 then
1710                 Result := FilePath
1711         else
1712                 Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder )
1713                                                 + BBS2CH_LOG_FOLDER + PATH_DELIM + ParentBoard.BBSID + PATH_DELIM + FileName;
1714 end;
1715
1716 procedure TThreadItem.SetLastModified(d: TDateTime);
1717 begin
1718         if FLastModified = d then Exit;
1719         FLastModified := d;
1720         if FUpdate and (ParentBoard <> nil) then
1721                 ParentBoard.FModified := True;
1722 end;
1723
1724 {procedure TThreadItem.SetRoundNo(i: Integer);
1725 begin
1726         if FRoundNo = i then Exit;
1727         FRoundNo := i;
1728         if FUpdate and (ParentBoard <> nil) then
1729                 ParentBoard.FModified := True;
1730 end;}
1731
1732 procedure TThreadItem.SetRound(b: Boolean);
1733 begin
1734         if b then
1735                 RoundList.Add(Self)
1736         else
1737                 RoundList.Delete(Self);
1738         if FRound = b then Exit;
1739         FRound := b;
1740         if FUpdate and (ParentBoard <> nil) then
1741                 ParentBoard.FModified := True;
1742 end;
1743
1744 procedure TThreadItem.SetRoundName(const s: string);
1745 begin
1746         if FRoundName = s then Exit;
1747         FRoundName := s;
1748         if FUpdate and (ParentBoard <> nil) then
1749                 ParentBoard.FModified := True;
1750 end;
1751
1752 procedure TThreadItem.SetKokomade(i: Integer);
1753 begin
1754         if FKokomade = i then Exit;
1755         FKokomade := i;
1756         if FUpdate and (ParentBoard <> nil) then
1757                 ParentBoard.FModified := True;
1758 end;
1759
1760 procedure TThreadItem.SetUnRead(b: Boolean);
1761 begin
1762         if FUnRead = b then Exit;
1763         FUnRead := b;
1764         if FUpdate and (ParentBoard <> nil) then
1765                 ParentBoard.FModified := True;
1766 end;
1767
1768 procedure TThreadItem.SetScrollTop(i: Integer);
1769 begin
1770         if FScrollTop = i then Exit;
1771         FScrollTop := i;
1772         if FUpdate and (ParentBoard <> nil) then
1773                 ParentBoard.FModified := True;
1774 end;
1775
1776 procedure TThreadItem.BeginUpdate;
1777 begin
1778         FUpdate := False;
1779 end;
1780
1781 procedure TThreadItem.EndUpdate;
1782 begin
1783         FUpdate := True;
1784 end;
1785
1786 {initialization
1787         BBS2ch := TBBS.Create;
1788
1789 finalization
1790         if BBS2ch <> nil then
1791                 BBS2ch.Free;}
1792 function TThreadItem.GetCreateDate: TDateTime;
1793 var
1794         unixtime: Int64;
1795     tmp: string;
1796 begin
1797         // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\8dì\90¬\93ú\8e\9e\82ð\8b\81\82ß\82é
1798         try
1799                 if ( GikoSys.Setting.CreationTimeLogs ) and not IsLogFile  then
1800             Result := ZERO_DATE
1801         else begin
1802             // \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
1803                         tmp := ChangeFileExt(FFileName, '');
1804                         if AnsiPos('_', tmp) <> 0 then
1805                                 if AnsiPos('_', tmp) > 9 then
1806                                         tmp := Copy(tmp, 1, AnsiPos('_', tmp)-1)
1807                                 else
1808                                         Delete(tmp, AnsiPos('_', tmp), 1);
1809
1810                         if ( Length(tmp) = 9) and ( tmp[1] = '0' ) then
1811                                 Insert('1', tmp, 1);
1812
1813                         unixtime := StrToInt64Def(tmp, ZERO_DATE);
1814                         Result := UnixToDateTime(unixtime) + OffsetFromUTC;
1815                         if GikoSys.Setting.FutureThread then begin
1816                         if CompareDateTime(Result, Now) = 1 then
1817                         Result := ZERO_DATE;
1818                 end;
1819         end;
1820
1821         except
1822                 on E: Exception do
1823                         Result := ZERO_DATE;
1824         end;
1825 end;
1826
1827 end.
1828