OSDN Git Service

1.52.1.658
[gikonavigoeson/gikonavi.git] / Favorite.pas
index 79663d7..0e58ba2 100644 (file)
@@ -4,42 +4,44 @@ interface
 
 uses
        Messages, SysUtils, Classes, Contnrs, ComCtrls, {HttpApp,} YofUtils,
-       GikoSystem{, XMLIntf, XMLDoc}, GikoXMLDoc, BoardGroup, windows,
-    MojuUtils;
+       GikoSystem{, XMLIntf, XMLDoc}, GikoXMLDoc, BoardGroup, windows;
        {SAX, SAXHelpers, SAXComps, SAXKW;}
 
 type
        TFavoriteFolder = class
        end;
 
-       TFavoriteBoardItem = class
+       TFavoriteItem = class(TObject)
        private
-               FItem                           : TBoard;
                FURL                            : string;
                FTitle                  : string;
+       public
+               function GetItemTitle : string; virtual;abstract;
+               property URL                            : string        read FURL write FURL;   // Item \82ª\8eæ\93¾\82Å\82«\82È\82­\82Ä\82à URL \82Í\8fí\82É\95Û\8e\9d\82³\82ê\82é
+               property Title                  : string        read FTitle write FTitle;
+       end;
+       TFavoriteBoardItem = class(TFavoriteItem)
+       private
+               FItem                           : TBoard;
                function        GetItem : TBoard;
        public
                constructor Create( inURL : string; inTitle : string = ''; inItem : TBoard = nil );
                constructor CreateWithItem( inItem : TBoard );
-        destructor Destory;
+               destructor Destory;
+               function GetItemTitle : string; override;
                property Item                           : TBoard        read GetItem write FItem;
-               property URL                            : string        read FURL write FURL;   // Item \82ª\8eæ\93¾\82Å\82«\82È\82­\82Ä\82à URL \82Í\8fí\82É\95Û\8e\9d\82³\82ê\82é
-               property Title                  : string        read FTitle write FTitle;
        end;
 
-       TFavoriteThreadItem = class
+       TFavoriteThreadItem = class(TFavoriteItem)
        private
                FItem                           : TThreadItem;
-               FURL                            : string;
-               FTitle                  : string;
                function        GetItem : TThreadItem;
        public
                constructor Create( inURL : string; inTitle : string = ''; inItem : TThreadItem = nil );
                constructor CreateWithItem( inItem : TThreadItem );
-        destructor Destory;
+               destructor Destory;
+               function GetItemTitle : string; override;
                property Item                           : TThreadItem   read GetItem write FItem;
-               property URL                            : string                        read FURL write FURL;   // Item \82ª\8eæ\93¾\82Å\82«\82È\82­\82Ä\82à URL \82Í\8fí\82É\95Û\8e\9d\82³\82ê\82é
-               property Title                  : string                        read FTitle write FTitle;
        end;
 
        TFavoriteDM = class(TDataModule)
@@ -48,7 +50,7 @@ type
                { Private \90é\8c¾ }
                FStack: TStack;
                FTreeView: TTreeView;
-
+               FModified: boolean;
                procedure ReadNode(Node: IXMLNode);
                procedure AddSaveString(Node: TTreeNode; SaveList: TStringList);
 //             procedure AddSaveString(Node: TTreeNode; XMLNode: IXMLNode);
@@ -59,14 +61,15 @@ type
 //             procedure SAXCharacters(Sender: TObject; const PCh: SAXString);
        public
                { Public \90é\8c¾ }
-        procedure Clear;
-                               function GetFavoriteFilePath() : String;
-                               function SaveFavoriteFile(FileName: String) : Boolean;
+               procedure Clear;
+               function GetFavoriteFilePath() : String;
+               function SaveFavoriteFile(FileName: String) : Boolean;
                procedure SetFavTreeView(TreeView: TTreeView);
                procedure ReadFavorite;
                procedure WriteFavorite;
-        procedure URLReplace(oldURLs: TStringList; newURLs: TStringList);
+               procedure URLReplace(oldURLs: TStringList; newURLs: TStringList);
                property TreeView: TTreeView read FTreeView;
+               property Modified: boolean read FModified write FModified;
        end;
 
 var
@@ -76,7 +79,7 @@ const
 
 implementation
 
-uses   ExternalBoardManager, ExternalBoardPlugInMain;
+uses   ExternalBoardManager, ExternalBoardPlugInMain,  MojuUtils;
 
 const
        FAVORITE_ROOT_NAME = '\82¨\8bC\82É\93ü\82è';
@@ -110,15 +113,33 @@ end;
 destructor TFavoriteBoardItem.Destory;
 begin
        if FItem <> nil then
-       FItem.Free;
-    inherited;
+               FItem.Free;
+       inherited;
+end;
+//! \95Û\8e\9d\82µ\82Ä\82¢\82é\94Â\82Ì\83^\83C\83g\83\8b\82ð\95Ô\82·
+function TFavoriteBoardItem.GetItemTitle : string;
+begin
+       Result := '';
+       //\88ê\93x\82à\94Â\82ð\8aJ\82¢\82Ä\82¢\82È\82¢\82Æ\82«\81i\8bN\93®\8e\9e\82É\83L\83\83\83r\83l\83b\83g\82ð\82¨\8bC\82É\93ü\82è\82Æ\82©\81j
+       //\82Ì\82Æ\82«\82ÉFItem\82ªnil\82È\82Ì\82Å\82»\82Ì\82Æ\82«\82Í\82×\82Á\82Æ\8c\9f\8dõ
+       if FItem = nil then begin
+               FItem := BBSsFindBoardFromURL(URL);
+       end;
+       if FItem <> nil then begin
+               try
+                       if not FItem.IsThreadDatRead then begin
+                               GikoSys.ReadSubjectFile(FItem);
+                       end;
+               except
+               end;
+               Result := FItem.Title;
+       end;
 end;
 function       TFavoriteBoardItem.GetItem : TBoard;
 var
        protocol, host, path, document, port, bookmark : string;
-       BBSID{, BBSKey} : string;
-       tmpURL                          : string;
-//     category : TCategory;
+       BBSID   : string;
+       tmpURL  : string;
 begin
 
        if FItem = nil then begin
@@ -140,7 +161,7 @@ begin
                end;
        end;
 
-       Result := FItem;
+       Result := FItem;
 
 end;
 
@@ -152,8 +173,8 @@ constructor TFavoriteThreadItem.Create(
 begin
 
        inherited Create;
-
        URL             := inURL;
+
        Title   := inTitle;
        Item    := inItem;
 
@@ -173,6 +194,17 @@ begin
        FItem.Free;
     inherited;
 end;
+//! \95Û\8e\9d\82µ\82Ä\82¢\82é\83X\83\8c\82Ì\83^\83C\83g\83\8b\82ð\95Ô\82·
+function TFavoriteThreadItem.GetItemTitle : string;
+begin
+       Result := '';
+       if FItem = nil then begin
+               FItem := BBSsFindThreadFromURL(URL);
+       end;
+       if FItem <> nil then begin
+               Result := FItem.Title;
+       end;
+end;
 
 function       TFavoriteThreadItem.GetItem : TThreadItem;
 var
@@ -219,7 +251,7 @@ begin
                end;
 
                if FItem = nil then begin
-                       FItem := TThreadItem.Create( board.BoardPlugIn, browsableURL );
+                       FItem := TThreadItem.Create( board.BoardPlugIn, board, browsableURL );
 
                        FItem.Title := Title;
                        board.Add( FItem );
@@ -256,7 +288,8 @@ begin
        end;
                TreeView.Items.Clear;
                TreeView.Items.EndUpdate;
-    //TreeView.Free;
+
+    FavoriteDM.Modified := true;
 end;
 
 procedure TFavoriteDM.SetFavTreeView(TreeView: TTreeView);
@@ -274,11 +307,11 @@ var
        FavFolder: TFavoriteFolder;
        LinkExists: Boolean;
 begin
-
+       FavoriteDM.Modified := true;
        FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
 
        FavFolder := TFavoriteFolder.Create;
-       Node := FTreeView.Items.AddChildObject(nil, FAVORITE_ROOT_NAME, FavFolder);
+       Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
        Node.ImageIndex := 14;
        Node.SelectedIndex := 14;
 
@@ -294,7 +327,7 @@ begin
                                FStack.Push(Node);
                                LinkExists := False;
                                if XMLNode.NodeName = 'favorite' then begin
-                                       for i := 0 to XMLNode.ChildNodes.Count - 1 do begin
+                                       for i := XMLNode.ChildNodes.Count - 1 downto 0 do begin
                                                ReadNode(XMLNode.ChildNodes[i]);
                                                if (XMLNode.ChildNodes[i].NodeName = 'folder') and
                                                         (XMLNode.ChildNodes[i].Attributes['title'] = FAVORITE_LINK_NAME) then begin
@@ -304,7 +337,7 @@ begin
                                end;
                                if not LinkExists then begin
                                        FavFolder := TFavoriteFolder.Create;
-                                       Node := FTreeView.Items.AddChildObject(Node, FAVORITE_LINK_NAME, FavFolder);
+                                       Node := FTreeView.Items.AddChildObjectFirst(Node, FAVORITE_LINK_NAME, FavFolder);
                                        Node.ImageIndex := 14;
                                        Node.SelectedIndex := 14;
                                end;
@@ -318,7 +351,7 @@ begin
 
 {
        FavFolder := TFavoriteFolder.Create;
-       Node := FTreeView.Items.AddChildObject(nil, FAVORITE_ROOT_NAME, FavFolder);
+       Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
        Node.ImageIndex := 12;
        Node.SelectedIndex := 13;
 
@@ -354,15 +387,16 @@ begin
                ParentNode := FStack.Peek;
                if TObject(ParentNode.Data) is TFavoriteFolder then begin
                        FavFolder := TFavoriteFolder.Create;
-                       CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavFolder);
+                       CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavFolder);
                        CurrentNode.ImageIndex := 14;
                        CurrentNode.SelectedIndex := 14;
-                       CurrentNode.Expanded := Node.Attributes[ 'expanded' ] = 'true';
                        FStack.Push(CurrentNode);
                end;
-               for i := 0 to Node.ChildNodes.Count - 1 do begin
+               for i := Node.ChildNodes.Count - 1 downto 0 do begin
                        ReadNode(Node.ChildNodes[i]);
                end;
+               if TObject(ParentNode.Data) is TFavoriteFolder then
+                       CurrentNode.Expanded := Node.Attributes[ 'expanded' ] = 'true';
                if FStack.Count <> 0 then
                        FStack.Pop;
        end else if Node.NodeName = 'favitem' then begin
@@ -376,12 +410,12 @@ begin
                                                board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] );
                                                if board <> nil then
                                                        FavBoard := TFavoriteBoardItem.Create(
-                                                               board.URL, Node.Attributes[ 'title' ], board );
+                                                               board.URL, MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), board );
                                        end else begin
                                                FavBoard := TFavoriteBoardItem.Create(
-                                                       Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
+                                                       Node.Attributes[ 'url' ], MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), nil );
                                        end;
-                                       CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavBoard);
+                                       CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavBoard);
                                        CurrentNode.ImageIndex := 15;
                                        CurrentNode.SelectedIndex := 15;
                                end else if Node.Attributes['favtype'] = 'thread' then begin
@@ -397,18 +431,19 @@ begin
                                                if threadItem = nil then begin
                                                        threadItem := TThreadItem.Create(
                                                                board.BoardPlugIn,
+                                board,
                                                                GikoSys.Get2chBoard2ThreadURL( board, ChangeFileExt( Node.Attributes[ 'thread' ], '' ) ) );
-                                                       threadItem.Title := Node.Attributes[ 'title' ];
+                                                       threadItem.Title := UnSanitize(Node.Attributes[ 'title' ]);
                                                        board.Add( threadItem );
                                                end;
                                                FavThread := TFavoriteThreadItem.Create(
-                                                       threadItem.URL, Node.Attributes[ 'title' ], threadItem );
+                                                       threadItem.URL, UnSanitize(Node.Attributes[ 'title' ]), threadItem );
                         threadItem.Free;
                                        end else begin
                                                FavThread := TFavoriteThreadItem.Create(
-                                                       Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
+                                                       Node.Attributes[ 'url' ], UnSanitize(Node.Attributes[ 'title' ]), nil );
                                        end;
-                                       CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavThread);
+                                       CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavThread);
                                        CurrentNode.ImageIndex := 16;
                                        CurrentNode.SelectedIndex := 16;
                                end;
@@ -440,15 +475,26 @@ begin
        XMLDoc.SaveToFile(FileName);
 }
 var
-       FileName: string;
+       FileName, tmpFileName: string;
        SaveList: TStringList;
+
 begin
+    FavoriteDM.Modified := true;
        FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
+       if FileExists(FileName) then begin
+               tmpFileName := GikoSys.GetConfigDir + '~' + FAVORITE_FILE_NAME;
+               if FileExists(tmpFileName) then
+                       SysUtils.DeleteFile(tmpFileName); //SysUtils.\82ð\82Â\82¯\82È\82¢\82ÆWinAPI\82Æ\8bæ\95Ê\82Å\82«\82È\82¢\82Ì\82Å
+               RenameFile(FileName, tmpFileName);
+       end;
        SaveList := TStringList.Create;
        try
                SaveList.Add('<?xml version="1.0" encoding="Shift_JIS" standalone="yes"?>');
                SaveList.Add('<favorite>');
-               AddSaveString(TreeView.Items.GetFirstNode.getFirstChild, SaveList);
+               try
+                       AddSaveString(TreeView.Items.GetFirstNode.getFirstChild, SaveList);
+               except
+               end;
                SaveList.Add('</favorite>');
                SaveList.SaveToFile(FileName);
        finally
@@ -512,12 +558,12 @@ begin
                end else if TObject(data) is TFavoriteBoardItem then begin
                        FavBoard := TFavoriteBoardItem(data);
                        s := Format('<favitem type="2ch" favtype="board" url="%s" title="%s"/>',
-                                                                       [HtmlEncode( FavBoard.URL ), HtmlEncode(Node.Text)]);
+                                                                       [HtmlEncode( FavBoard.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
                        SaveList.Add(s);
                end else if TObject(data) is TFavoriteThreadItem then begin
                        FavThread := TFavoriteThreadItem(data);
                        s := Format('<favitem type="2ch" favtype="thread" url="%s" title="%s"/>',
-                                                                       [HtmlEncode( FavThread.URL ), HtmlEncode(Node.Text)]);
+                                                                       [HtmlEncode( FavThread.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
                        SaveList.Add(s);
                end;
                Node := Node.getNextSibling;
@@ -616,7 +662,7 @@ end;
 
 procedure TFavoriteDM.URLReplace(oldURLs: TStringList; newURLs: TStringList);
 var
-       i, j                    : Integer;
+       i                                       : Integer;
                tmpURL: string;
     oldHost: string;
     oldBoardName: string;
@@ -626,6 +672,7 @@ var
        favBoard        : TFavoriteBoardItem;
        favThread       : TFavoriteThreadItem;
        favorites       : TTreeNodes;
+       Node                    : TTreeNode;
 begin
 
        // \96Ê\93|\82¾\82¯\82Çthread\82Í\82»\82ê\82¼\82êURL\82ð\83`\83F\83b\83N\82µ\82È\82ª\82ç\82â\82Á\82Ä\82©\82È\82«\82á\82¢\82¯\82È\82¢\81B
@@ -639,18 +686,19 @@ begin
                        newHost                 := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
                        newBoardName    := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
 
-                       for j := favorites.Count - 1 downto 0 do begin
+                       Node := favorites.GetFirstNode.getFirstChild;
+                       while Node <> nil do begin
                                try
-                                       if TObject( favorites.Item[ j ].Data ) is TFavoriteBoardItem then begin
-                                               favBoard := TFavoriteBoardItem( favorites.Item[ j ].Data );
+                                       if TObject( Node.Data ) is TFavoriteBoardItem then begin
+                                               favBoard := TFavoriteBoardItem( Node.Data );
                                                if favBoard = nil then continue;
                                                tempString := favBoard.URL;
                                                if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
                                                        tempString              := StringReplace(tempString, oldHost, newHost,[]);
                                                        favBoard.URL    := tempString;
                                                end;
-                                       end else if TObject( favorites.Item[ j ].Data ) is TFavoriteThreadItem then begin
-                                               favThread := TFavoriteThreadItem( favorites.Item[ j ].Data );
+                                       end else if TObject( Node.Data ) is TFavoriteThreadItem then begin
+                                               favThread := TFavoriteThreadItem( Node.Data );
                                                if favThread = nil then continue;
                                                tempString := favThread.URL;
                                                if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
@@ -660,6 +708,7 @@ begin
                                        end;
                                except
                                end;
+                               Node := Node.GetNext;
                        end;
                except
                end;