OSDN Git Service

Cookie確認でIPアドレス(ホスト名)が変わっているときに、
[gikonavigoeson/gikonavi.git] / BoardGroup.pas
index c4f13f5..4b3d7f7 100644 (file)
@@ -3,19 +3,20 @@ unit BoardGroup;
 interface
 
 uses
-       Windows, SysUtils, Classes, ComCtrls, IniFiles, {HTTPApp,} YofUtils, IdGlobal,
-       ExternalBoardManager, ExternalBoardPlugInMain, StrUtils, DateUtils;
+       Windows, SysUtils, Classes, ComCtrls, {HTTPApp,} YofUtils, IdGlobal,
+       ExternalBoardManager, ExternalBoardPlugInMain, StrUtils;
 
 type
        //\83\8a\83X\83g\82Ì\95\\8e¦\83A\83C\83e\83\80\91I\91ð
-       TGikoViewType = (gvtAll, gvtLog, gvtNew, gvtUser);
+       TGikoViewType = (gvtAll, gvtLog, gvtNew, gvtLive, gvtArch, gvtUser);
        //\83\8a\83X\83g\82Ì\8fã\82°\89º\82°
-       TGikoAgeSage = (gasNone, gasAge, gasSage, gasNew, gasNull);
+       TGikoAgeSage = (gasNone, gasAge, gasSage, gasNew, gasArch, gasNull);
 
        TCategory = class;
        TBoard = class;
        TThreadItem = class;
 
+
        // BBS \82Ì\83\8b\81[\83g
        TBBS = class(TList)
        private
@@ -58,7 +59,6 @@ type
        end;
 
        // \83J\83e\83S\83\8a(\94 URL \82Ì\83\8a\83X\83g)
-//     TCategory = class(THashedStringList)
        TCategory = class(TStringList)
        private
                FNo: Integer;
@@ -90,9 +90,10 @@ type
                property NodeExpand: Boolean read FExpand write FExpand;
        end;
 
-       
+       //! \83X\83\8c\83b\83h\90\94\83J\83E\83\93\83g\8fð\8c\8f\95
+       TThreadCount = function(Item : TThreadItem): Boolean;
+
        // \94Â(\83X\83\8c\83b\83h URL \82Ì\83\8a\83X\83g)
-//     TBoard = class(THashedStringList)
        TBoard = class(TStringList)
        private
                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é)
@@ -103,7 +104,6 @@ type
                FURL: string;                                                                   //\83{\81[\83hURL
                FRound: Boolean;                                                        //\83X\83\8c\83b\83h\88ê\97\97\8f\84\89ñ\97\\96ñ
                FRoundName: string;                                             //\8f\84\89ñ\96¼
-               //FRoundName: PChar;                                            //\8f\84\89ñ\96¼
                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
                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
                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
@@ -138,7 +138,8 @@ type
                FNewThreadCount: Integer;       //\90V\92\85\83X\83\8c\83b\83h\82Ì\90\94
                FLogThreadCount: Integer;       //\83\8d\83O\97L\82è\83X\83\8c\83b\83h\82Ì\90\94
                FUserThreadCount: Integer;      //\81H
-
+               FLiveThreadCount: Integer;      //\90\91\83X\83\8c\83b\83h\90\94
+               FArchiveThreadCount: Integer;   //DAT\97\8e\82¿\83X\83\8c\83b\83h\90\94
                function GetThreadItem(index: integer): TThreadItem;
                procedure SetThreadItem(index: integer; value: TThreadItem);
                procedure SetRound(b: Boolean);
@@ -200,12 +201,16 @@ type
 
                function GetNewThreadCount: Integer;
                function GetLogThreadCount: Integer;
+               function GetArchiveThreadCount: Integer;
+               function GetLiveThreadCount: Integer;
                function GetUserThreadCount: Integer;
                function GetNewThread(Index: Integer): TThreadItem;
                function GetLogThread(Index: Integer): TThreadItem; overload;
-               function GetLogThread(Index: Integer; Base: Integer): TThreadItem; overload;
+               function GetArchiveThread(Index: Integer): TThreadItem;
+               function GetLiveThread(Index: Integer): TThreadItem;
                function GetUserThread(Index: Integer): TThreadItem;
-
+               function GetThreadCount(func :TThreadCount ): Integer;
+               function GetThread(func :TThreadCount;const Index :Integer ): TThreadItem;
                procedure BeginUpdate;
                procedure EndUpdate;
                property NodeExpand: Boolean read FExpand write FExpand;
@@ -225,6 +230,9 @@ type
                property NewThreadCount: Integer        read FNewThreadCount write FNewThreadCount;     //\90V\92\85\83X\83\8c\83b\83h\82Ì\90\94
                property LogThreadCount: Integer        read FLogThreadCount write FLogThreadCount;             //\83\8d\83O\97L\82è\83X\83\8c\83b\83h\82Ì\90\94
                property UserThreadCount: Integer       read FUserThreadCount write FUserThreadCount;   //\81H
+               property LiveThreadCount: Integer       read FLiveThreadCount write     FLiveThreadCount;
+               property ArchiveThreadCount: Integer read FArchiveThreadCount write FArchiveThreadCount;
+
                property Cookie: string                         read FCookie write FCookie;
                property Expires: TDateTime                     read FExpires write FExpires;
        end;
@@ -233,7 +241,6 @@ type
        TThreadItem = class(TObject)
        private
                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é)
-
                FNo: Integer;                                                   //\94Ô\8d\86
                FFileName: string;                              //\83X\83\8c\83b\83h\83t\83@\83C\83\8b\96¼
                FTitle: string;                                         //\83X\83\8c\83b\83h\83^\83C\83g\83\8b
@@ -246,7 +253,6 @@ type
                FSize: Integer;                                         //\83X\83\8c\83b\83h\83T\83C\83Y
                FRound: Boolean;                                        //\8f\84\89ñ\83t\83\89\83O
                FRoundName: string;                             //\8f\84\89ñ\96¼
-               //FRoundName: PChar;                            //\8f\84\89ñ\96¼
                FIsLogFile: Boolean;                    //\83\8d\83O\91\8dÝ\83t\83\89\83O
                FParentBoard: TBoard;                   //\90e\83{\81[\83h
                FKokomade: Integer;                             //\83R\83R\82Ü\82Å\93Ç\82ñ\82¾\94Ô\8d\86
@@ -256,14 +262,10 @@ type
                FScrollTop: Integer;                    //\83X\83N\83\8d\81[\83\8b\88Ê\92u
                FDownloadHost: string;          //\8d¡\82Ì\83z\83X\83g\82Æ\88á\82¤\8fê\8d\87\82Ì\83z\83X\83g
                FAgeSage: TGikoAgeSage;         //\83A\83C\83e\83\80\82Ì\8fã\82°\89º\82°
-//             FSPID: string;                                          //\8f\91\82«\8d\9e\82Ý\97pSPID
-
                FUpdate: Boolean;
                FExpand: Boolean;
                FURL                                    : string;                               // \82±\82Ì\83X\83\8c\82ð\83u\83\89\83E\83U\82Å\95\\8e¦\82·\82é\8dÛ\82Ì URL
-               //FBoardPlugIn  : TBoardPlugIn; // \82±\82Ì\83X\83\8c\82ð\83T\83|\81[\83g\82·\82é\83v\83\89\83O\83C\83\93
-               //FFilePath                     : string;                               // \82±\82Ì\83X\83\8c\82ª\95Û\91\82³\82ê\82Ä\82¢\82é\83p\83X
-
+               FJumpAddress : Integer;         //\83\8c\83X\94Ô\8d\86\8ew\92èURL\82ð\93¥\82ñ\82¾\82Æ\82«\82É\8ew\92è\82³\82ê\82é\83\8c\83X\82Ì\94Ô\8d\86\82ª\93ü\82é
                procedure SetLastModified(d: TDateTime);
                procedure SetRound(b: Boolean);
                procedure SetRoundName(const s: string);
@@ -320,6 +322,7 @@ type
                property CreateDate: TDateTime read GetCreateDate;
                property        URL                                     : string                                read FURL write FURL;
                property        FilePath                : string        read GetFilePath;
+               property JumpAddress : Integer read FJumpAddress write FJumpAddress;
        end;
 
        TBoardGroup = class(TStringList)
@@ -331,6 +334,12 @@ type
         property       BoardPlugIn     : TBoardPlugIn  read FBoardPlugIn write FBoardPlugIn;
     end;
 
+    // \93Á\8eê\97p\93r\97pTBoard
+    TSpecialBoard = class(TBoard)
+    public
+        function Add(item: TThreadItem): integer; overload;
+        procedure Clear; overload;
+    end;
 
        function        BBSsFindBoardFromBBSID( inBBSID : string ) : TBoard;
        function        BBSsFindBoardFromURL( inURL : string ) : TBoard;
@@ -338,14 +347,18 @@ type
        function        BBSsFindThreadFromURL(const inURL : string ) : TThreadItem;
        function        ConvertDateTimeString( inDateTimeString : string) : TDateTime;
 
+    procedure    DestorySpecialBBS( inBBS : TBBS );
+
 var
        BBSs            : array of TBBS;
     BoardGroups : array of TBoardGroup;
+    SpecialBBS  : TBBS;
+    SpecialBoard: TSpecialBoard;
 
 implementation
 
 uses
-       GikoSystem, RoundData, MojuUtils;
+       GikoSystem, RoundData, MojuUtils, DateUtils, IniFiles;
 
 const
        BBS2CH_NAME:                                     string = '\82Q\82¿\82á\82ñ\82Ë\82é';
@@ -360,9 +373,34 @@ const
     HEADTXT_FILENAME:          string = 'head.html';
        //DEFAULT_LIST_COUNT:           Integer = 100;
 
-//     COLUMN_CATEGORY:         array[0..0] of string = ('\83J\83e\83S\83\8a\96¼');
-//     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');
-//     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');
+//! \83\8d\83O\82ð\8e\9d\82Á\82Ä\82¢\82é\82È\82ç\90^\82ð\95Ô\82·
+function CountLog(Item: TThreadItem): Boolean;
+begin
+       Result := Item.IsLogFile;
+end;
+//! \90V\92\85\82È\82ç\90^\82ð\95Ô\82·
+function CountNew(Item: TThreadItem): Boolean;
+begin
+       Result := Item.NewArrival;
+end;
+//! DAT\97\8e\82¿\82È\82ç\90^\82ð\95Ô\82·
+function CountDat(Item: TThreadItem): Boolean;
+begin
+       Result := (Item.AgeSage = gasArch);
+end;
+//! \90\91\83X\83\8c\82È\82ç\90^\82ð\95Ô\82·
+function CountLive(Item: TThreadItem): Boolean;
+begin
+       Result := (Item.AgeSage <> gasArch);
+end;
+
+//! \8fí\82É\90^
+function CountAll(Item: TThreadItem): Boolean;
+begin
+    Result := True;
+end;
+
+
 
 // BBSID \82ð\97p\82¢\82é 2 \82¿\82á\82ñ\82Ë\82é\82Ì\82Ý\92T\82µ\8fo\82µ\82Ü\82·
 // BBSID \82Ì\8eg\97p\82Í\8bÉ\97Í\94ð\82¯\82Ä\82­\82¾\82³\82¢\81B
@@ -501,6 +539,28 @@ begin
        end;
 
 end;
+{!
+\brief \93Á\8eê\97p\93rBBS\8dí\8f\9c
+\param bbs \8dí\8f\9c\82·\82é\93Á\8eê\97p\93rBBS
+}
+procedure DestorySpecialBBS( inBBS : TBBS );
+var
+    sCategory : TCategory;
+    sBoard    : TSpecialBoard;
+begin
+    if inBBS <> nil then begin
+        sCategory := inBBS.Items[0];
+        if sCategory <> nil then begin
+            sBoard := TSpecialBoard(sCategory.Items[0]);
+            if sBoard <> nil then begin
+                sBoard.Modified := False;
+                sBoard.Clear;
+                FreeAndNil(sBoard);
+            end;
+        end;
+        FreeAndNil(inBBS);
+    end;
+end;
 
 (*************************************************************************
  *\8b@\94\\96¼\81FTBBS\83R\83\93\83X\83g\83\89\83N\83^
@@ -1194,17 +1254,14 @@ begin
 
    // Result := inDateTimeString;
 end;
-// \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
+//! \83T\83u\83W\83F\83N\83gURL\8eæ\93¾
 function TBoard.GetReadCgiURL: string;
 begin
-       //Result := URL + SUBJECT_FILENAME;
-       //Result := GikoSys.UrlToServer(URL)
-       //                              + 'test/read.cgi/' + BBSID + '/?raw=0.0';
        Result := URL + SUBJECT_FILENAME;
 
 end;
 
-// \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
+//! \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
 function TBoard.GetSubjectFileName: string;
 begin
        if Length( FilePath ) > 0 then
@@ -1214,7 +1271,7 @@ begin
                                                + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME;
 end;
 
-// \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
+//! \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
 function TBoard.GetFolderIndexFileName: string;
 begin
        if Length( FilePath ) > 0 then
@@ -1223,7 +1280,7 @@ begin
                Result := GikoSys.Setting.LogFolderP
                                                + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME;
 end;
-//SETTING.TXT\82Ì\83t\83@\83C\83\8b\96¼\8eæ\93¾
+//SETTING.TXT\82Ì\83t\83@\83C\83\8b\96¼\8eæ\93¾
 function TBoard.GetSETTINGTXTFileName: string;
 begin
        if Length( FilePath ) > 0 then
@@ -1259,12 +1316,8 @@ end;
 
 // \83X\83\8c\97§\82Ä\91\97\90MURL
 function TBoard.GetSendURL: string;
-//var
-//     Protocol, Host, Path, Document, Port, Bookmark : string;
 begin
     Result := GikoSys.UrlToServer(URL);
-       //GikoSys.ParseURI( URL, Protocol,Host, Path, Document, Port, Bookmark );
-       //if GikoSys.Is2chHost(Host) then
        if Self.Is2ch then
         Result := Result + 'test/bbs.cgi'
     else
@@ -1291,15 +1344,7 @@ begin
        if FUpdate then
                FModified := True;
 end;
-{
-procedure TBoard.SetRoundName(s: PChar);
-begin
-       if FRoundName = s then Exit;
-       FRoundName := s;
-       if FUpdate then
-               FModified := True;
-end;
-}
+
 procedure TBoard.SetLastModified(d: TDateTime);
 begin
        if FLastModified = d then Exit;
@@ -1340,8 +1385,8 @@ begin
        if FUpdate then
                FModified := True;
 end;
-
-function TBoard.GetNewThreadCount: Integer;
+//! func\82Ì\8fð\8c\8f\82É\88ê\92v\82·\82é\83X\83\8c\83b\83h\82Ì\90\94\82ð\95Ô\82·
+function TBoard.GetThreadCount(func :TThreadCount ): Integer;
 var
        i: Integer;
 begin
@@ -1349,12 +1394,12 @@ begin
        if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
        begin
                for i := 0 to Count - 1 do begin
-                       if Items[i].NewArrival then
+                       if func(Items[i]) then
                                inc(Result);
                end;
        end else begin
                for i := 0 to Count - 1 do begin
-                       if Items[i].NewArrival then
+                       if func(Items[i]) then
                        begin
                                if Items[i].ShortTitle = '' then
                                        Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
@@ -1364,48 +1409,33 @@ begin
                end;
        end;
 end;
-
+//! \90V\92\85\83X\83\8c\83b\83h\82Ì\90\94\82ð\8eæ\93¾\82·\82é
+function TBoard.GetNewThreadCount: Integer;
+begin
+       Result := GetThreadCount(CountNew);
+end;
+//! \83\8d\83O\97L\82è\83X\83\8c\83b\83h\82Ì\90\94\82ð\8eæ\93¾\82·\82é
 function TBoard.GetLogThreadCount: Integer;
-var
-       i: Integer;
 begin
-       Result := 0;
-       if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
-       begin
-               for i := 0 to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                               inc(Result);
-               end;
-       end else begin
-               for i := 0 to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                       begin
-                               if Items[i].ShortTitle = '' then
-                                       Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
-                               if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
-                                       inc(Result);
-                       end;
-               end;
-       end;
+       Result := GetThreadCount(CountLog);
 end;
-
+//! \8di\8d\9e\82Ý\8fð\8c\8f\82É\88ê\92v\82·\82é\83X\83\8c\83b\83h\82Ì\90\94\82ð\8eæ\93¾\82·\82é
 function TBoard.GetUserThreadCount: Integer;
-var
-       i: Integer;
 begin
-       Result := 0;
-       if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
-               Result := Count
-       else
-               for i := 0 to Count - 1 do begin
-                       if Items[i].ShortTitle = '' then
-                               Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
-                       if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then
-                               inc(Result);
-               end;
+       Result := GetThreadCount(CountAll);
 end;
-
-function TBoard.GetNewThread(Index: Integer): TThreadItem;
+//! DAT\97\8e\82¿\83X\83\8c\83b\83h\82Ì\90\94\82ð\8eæ\93¾\82·\82é
+function TBoard.GetArchiveThreadCount: Integer;
+begin
+       Result := GetThreadCount(CountDat);
+end;
+//! \90\91\83X\83\8c\83b\83h\82Ì\90\94\82ð\8eæ\93¾\82·\82é
+function TBoard.GetLiveThreadCount: Integer;
+begin
+       Result := GetThreadCount(CountLive);
+end;
+//! func\82Ì\8fð\8c\8f\82É\93K\8d\87\82·\82éIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
+function TBoard.GetThread(func :TThreadCount;const Index :Integer ): TThreadItem;
 var
        i: Integer;
        Cnt: Integer;
@@ -1415,8 +1445,7 @@ begin
        if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
        begin
                for i := 0 to Count - 1 do begin
-                       if Items[i].NewArrival then
-                                                                       begin
+                       if func(Items[i]) then begin
                                if Index = Cnt then begin
                                        Result := Items[i];
                                        Exit;
@@ -1426,9 +1455,8 @@ begin
                end;
        end else begin
                for i := 0 to Count - 1 do begin
-                       if Items[i].NewArrival then
-                       begin
-                               if Items[i].ShortTitle = '' then
+                       if func(Items[i]) then begin
+                               if Length(Items[i].ShortTitle) = 0 then
                                        Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
                                if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
                                        if Index = Cnt then begin
@@ -1441,109 +1469,30 @@ begin
                end;
        end;
 end;
-
-function TBoard.GetLogThread(Index: Integer): TThreadItem;
-var
-       i: Integer;
-       Cnt: Integer;
+//! DAT\97\8e\82¿\83X\83\8c\83b\83h\82ÅIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
+function TBoard.GetArchiveThread(Index: Integer): TThreadItem;
 begin
-       Cnt := 0;
-       if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
-       begin
-               for i := 0 to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                                                                       begin
-                               if Index = Cnt then begin
-                                       Result := Items[i];
-                                       Exit;
-                               end;
-                               inc(Cnt);
-                       end;
-               end;
-       end else begin
-               for i := 0 to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                               begin
-                                       if Items[i].ShortTitle = '' then
-                                               Items[i].ShortTitle := ZenToHan(Items[i].Title);
-                                       if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
-                                               if Index = Cnt then begin
-                                                       Result := Items[i];
-                                                       Exit;
-                                       end;
-                                       inc(Cnt);
-                               end;
-                       end;
-               end;
-       end;
-       Result := nil;
+       Result := GetThread(CountDat, Index);
 end;
-function TBoard.GetLogThread(Index: Integer; Base: Integer): TThreadItem;
-var
-       i: Integer;
-       Cnt: Integer;
+//! \90\91\83X\83\8c\83b\83h\82ÅIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
+function TBoard.GetLiveThread(Index: Integer): TThreadItem;
 begin
-       Cnt := 0;
-       if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
-       begin
-               for i := Base to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                                                                       begin
-                               if Index = Cnt then begin
-                                       Result := Items[i];
-                                       Exit;
-                               end;
-                               inc(Cnt);
-                       end;
-               end;
-       end else begin
-               for i := Base to Count - 1 do begin
-                       if Items[i].IsLogFile then
-                               begin
-                                       if Items[i].ShortTitle = '' then
-                                               Items[i].ShortTitle := ZenToHan(Items[i].Title);
-                                       if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
-                                               if Index = Cnt then begin
-                                                       Result := Items[i];
-                                                       Exit;
-                                       end;
-                                       inc(Cnt);
-                               end;
-                       end;
-               end;
-       end;
-       Result := nil;
+       Result := GetThread(CountLive, Index);
+end;
+//! \90V\92\85\83X\83\8c\83b\83h\82ÅIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
+function TBoard.GetNewThread(Index: Integer): TThreadItem;
+begin
+       Result := GetThread(CountNew, Index);
 end;
+//! Log\82 \82è\83X\83\8c\83b\83h\82ÌIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
+function TBoard.GetLogThread(Index: Integer): TThreadItem;
+begin
+       Result := GetThread(CountLog, Index);
+end;
+//! \8di\8d\9e\82Ý\82ÅIndex\94Ô\96Ú\82Ì\83X\83\8c\83b\83h\82ð\8eæ\93¾\82·\82é
 function TBoard.GetUserThread(Index: Integer): TThreadItem;
-var
-       i: Integer;
-       Cnt: Integer;
 begin
-       Result := nil;
-       Cnt := 0;
-       if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then
-       begin
-               for i := 0 to Count - 1 do begin
-                       if Index = Cnt then
-                       begin
-                               Result := Items[ i ];
-                               Exit;
-                       end;
-                       inc( Cnt );
-               end;
-       end else begin
-               for i := 0 to Count - 1 do begin
-                       if Items[i].ShortTitle = '' then
-                               Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', '');
-                       if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin
-                               if Index = Cnt then begin
-                                       Result := Items[i];
-                                       Exit;
-                               end;
-                               inc(Cnt);
-                       end;
-               end;
-       end;
+       Result := GetThread(CountAll, Index);
 end;
 
 procedure TBoard.BeginUpdate;
@@ -1556,16 +1505,6 @@ begin
        FUpdate := True;
 end;
 
-{class function TBoard.GetColumnName(Index: Integer): string;
-begin
-       Result := COLUMN_THREADITEM[Index];
-end;
-
-class function TBoard.GetColumnCount: Integer;
-begin
-       Result := Length(COLUMN_THREADITEM);
-end;}
-
 //constructor TThreadItem.Create(AOwner: TComponent);
 procedure TThreadItem.Init;
 begin
@@ -1587,7 +1526,7 @@ begin
 
        FUpdate := True;
        FURL := '';
-       //FBoardPlugIn := nil;
+       FJumpAddress := 0;
 end;
 
 // *************************************************************************
@@ -1671,28 +1610,6 @@ begin
 
 end;
 
-// *************************************************************************
-// \8aO\95\94\94Â\83v\83\89\83O\83C\83\93\82ª\8eg\97p\89Â\94\\82©
-// *************************************************************************
-{
-function       TThreadItem.IsBoardPlugInAvailable : Boolean;
-begin
-
-       repeat
-               if BoardPlugIn = nil then
-                       Break;
-
-               if not Assigned( Pointer( BoardPlugIn.Module ) ) then
-                       Break;
-
-               Result := True;
-               Exit;
-       until True;
-
-       Result := False;
-
-end;
-}
 function TThreadItem.GetDatURL: string;
 var
        Protocol, Host, Path, Document, Port, Bookmark: string;
@@ -1756,31 +1673,8 @@ begin
        end;
 end;
 
-{function TThreadItem.GetOldDatgzURL: string;
-var
-       Protocol, Host, Path, Document, Port, Bookmark: string;
-begin
-       Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL,
-                                                                                                                                                        'kako',
-                                                                                                                                                        FileName,
-                                                                                                                                                        FileName]);
-       if FDownloadHost <> '' then begin
-               ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark);
-               Result := Format('%s://%s%s%s', [Protocol,
-                                                                                                                                                DownloadHost,
-                                                                                                                                                Path,
-                                                                                                                                                Document]);
-
-       end;
-end;}
-
 function TThreadItem.GetOfflawCgiURL(const SessionID: string): string;
-//var
-//     Protocol, Host, Path, Document, Port, Bookmark: string;
 begin
-//     Result := GikoSys.UrlToServer(ParentBoard.URL)
-//                                     + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
-//                                     + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
        if FDownloadHost = '' then begin
                Result := GikoSys.UrlToServer(ParentBoard.URL)
                                                + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/'
@@ -1791,10 +1685,6 @@ begin
                Result := 'http://' + FDownloadHost
                                                + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/'
                                                + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID);
-//             Result := Format('%s://%s%s%s', [Protocol,
-//                                                                                                                                              DownloadHost,
-//                                                                                                                                              Path,
-//                                                                                                                                              Document]);
        end;
 end;
 
@@ -1857,14 +1747,6 @@ begin
                ParentBoard.FModified := True;
 end;
 
-{procedure TThreadItem.SetRoundNo(i: Integer);
-begin
-       if FRoundNo = i then Exit;
-       FRoundNo := i;
-       if FUpdate and (ParentBoard <> nil) then
-               ParentBoard.FModified := True;
-end;}
-
 procedure TThreadItem.SetRound(b: Boolean);
 begin
        if b then
@@ -1884,15 +1766,8 @@ begin
        if FUpdate and (ParentBoard <> nil) then
                ParentBoard.FModified := True;
 end;
-{
-procedure TThreadItem.SetRoundName(const s: PChar);
-begin
-       if FRoundName = s then Exit;
-       FRoundName := s;
-       if FUpdate and (ParentBoard <> nil) then
-               ParentBoard.FModified := True;
-end;
-}
+
+
 procedure TThreadItem.SetKokomade(i: Integer);
 begin
        if FKokomade = i then Exit;
@@ -1933,16 +1808,7 @@ begin
        FUpdate := True;
 end;
 
-{initialization
-       BBS2ch := TBBS.Create;
-
-finalization
-       if BBS2ch <> nil then
-               BBS2ch.Free;}
 function TThreadItem.GetCreateDate: TDateTime;
-var
-       unixtime: Int64;
-    tmp: string;
 begin
        // \83t\83@\83C\83\8b\96¼\82©\82ç\83X\83\8c\8dì\90¬\93ú\8e\9e\82ð\8b\81\82ß\82é
        try
@@ -1950,18 +1816,7 @@ begin
             Result := ZERO_DATE
         else begin
             // \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
-                       tmp := ChangeFileExt(FFileName, '');
-                       if AnsiPos('_', tmp) <> 0 then
-                               if AnsiPos('_', tmp) > 9 then
-                                       tmp := Copy(tmp, 1, AnsiPos('_', tmp)-1)
-                               else
-                                       Delete(tmp, AnsiPos('_', tmp), 1);
-
-                       if ( Length(tmp) = 9) and ( tmp[1] = '0' ) then
-                               Insert('1', tmp, 1);
-
-                       unixtime := StrToInt64Def(tmp, ZERO_DATE);
-                       Result := UnixToDateTime(unixtime) + OffsetFromUTC;
+            Result := GikoSys.GetCreateDateFromName(FFileName);
                        if GikoSys.Setting.FutureThread then begin
                        if CompareDateTime(Result, Now) = 1 then
                        Result := ZERO_DATE;
@@ -2007,6 +1862,19 @@ begin
 
 end;
 
+function TSpecialBoard.Add(item: TThreadItem): integer;
+begin
+    Result := inherited AddObject(Item.URL, Item);
+end;
+
+procedure TSpecialBoard.Clear;
+var
+       i: integer;
+begin
+    for i := Count - 1 downto 0 do
+               DeleteList(i);
+    Capacity := 0;
+end;
 
 end.