OSDN Git Service

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