X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=Favorite.pas;h=0e58ba29c2c864c05834c186a4cd5b2d995b2457;hb=724c6aafc862ebff07b61328a6dba7398af96bde;hp=a611c27d1411cfa5147ed7d34dac1c94e61e708a;hpb=2b25dd5dec65090721036fbf8a9ed1c4c8636be8;p=gikonavigoeson%2Fgikonavi.git diff --git a/Favorite.pas b/Favorite.pas index a611c27..0e58ba2 100644 --- a/Favorite.pas +++ b/Favorite.pas @@ -11,42 +11,46 @@ 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 ‚ªŽæ“¾‚Å‚«‚È‚­‚Ä‚à URL ‚͏í‚É•ÛŽ‚³‚ê‚é + 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; + function GetItemTitle : string; override; property Item : TBoard read GetItem write FItem; - property URL : string read FURL write FURL; // Item ‚ªŽæ“¾‚Å‚«‚È‚­‚Ä‚à URL ‚͏í‚É•ÛŽ‚³‚ê‚é - 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; + function GetItemTitle : string; override; property Item : TThreadItem read GetItem write FItem; - property URL : string read FURL write FURL; // Item ‚ªŽæ“¾‚Å‚«‚È‚­‚Ä‚à URL ‚͏í‚É•ÛŽ‚³‚ê‚é - property Title : string read FTitle write FTitle; end; TFavoriteDM = class(TDataModule) - procedure DataModuleCreate(Sender: TObject); procedure DataModuleDestroy(Sender: TObject); private { Private éŒ¾ } FStack: TStack; FTreeView: TTreeView; - + FModified: boolean; procedure ReadNode(Node: IXMLNode); procedure AddSaveString(Node: TTreeNode; SaveList: TStringList); // procedure AddSaveString(Node: TTreeNode; XMLNode: IXMLNode); @@ -57,12 +61,15 @@ type // procedure SAXCharacters(Sender: TObject; const PCh: SAXString); public { Public éŒ¾ } - 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); property TreeView: TTreeView read FTreeView; + property Modified: boolean read FModified write FModified; end; var @@ -72,7 +79,7 @@ const implementation -uses ExternalBoardManager, ExternalBoardPlugInMain; +uses ExternalBoardManager, ExternalBoardPlugInMain, MojuUtils; const FAVORITE_ROOT_NAME = '‚¨‹C‚É“ü‚è'; @@ -103,24 +110,58 @@ begin Create( inItem.URL, inItem.Title, inItem ); end; - +destructor TFavoriteBoardItem.Destory; +begin + if FItem <> nil then + FItem.Free; + inherited; +end; +//! •ÛŽ‚µ‚Ä‚¢‚锂̃^ƒCƒgƒ‹‚ð•Ô‚· +function TFavoriteBoardItem.GetItemTitle : string; +begin + Result := ''; + //ˆê“x‚à”‚ðŠJ‚¢‚Ä‚¢‚È‚¢‚Æ‚«i‹N“®Žž‚ɃLƒƒƒrƒlƒbƒg‚ð‚¨‹C‚É“ü‚è‚Æ‚©j + //‚Ì‚Æ‚«‚ÉFItem‚ªnil‚È‚Ì‚Å‚»‚Ì‚Æ‚«‚ׂ͂Á‚ÆŒŸõ + 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 - category : TCategory; + protocol, host, path, document, port, bookmark : string; + BBSID : string; + tmpURL : string; begin if FItem = nil then begin FItem := BBSsFindBoardFromURL( URL ); - { if FItem = nil then begin + tmpURL := URL; + GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark ); + if GikoSys.Is2chHost( host ) then begin + BBSID := GikoSys.URLToID( tmpURL ); + FItem := BBSs[ 0 ].FindBBSID( BBSID ); + if FItem <> nil then + URL := FItem.URL; + end; + { // ¦ì‚Á‚Ä‚àA’ljÁ‚·‚éƒJƒeƒSƒŠ‚ª–³‚¢‚Ì‚ÅŒƒ‚µ‚­•Û—¯ FItem := GikoSys.GetUnknownBoard( nil, URL ); FItem.Title := Title; + } end; - } end; - Result := FItem; + Result := FItem; end; @@ -132,8 +173,8 @@ constructor TFavoriteThreadItem.Create( begin inherited Create; - URL := inURL; + Title := inTitle; Item := inItem; @@ -147,28 +188,70 @@ begin Create( inItem.URL, inItem.Title, inItem ); end; +destructor TFavoriteThreadItem.Destory; +begin + if FItem <> nil then + FItem.Free; + inherited; +end; +//! •ÛŽ‚µ‚Ä‚¢‚éƒXƒŒ‚̃^ƒCƒgƒ‹‚ð•Ô‚· +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 board : TBoard; boardURL : string; browsableURL : string; + protocol, host, path, document, port, bookmark : string; + BBSID, BBSKey : string; + tmpURL : string; begin + Result := nil; if FItem = nil then begin - browsableURL := GikoSys.GetBrowsableThreadURL( URL ); - boardURL := GikoSys.GetThreadURL2BoardURL( browsableURL ); - board := BBSsFindBoardFromURL( boardURL ); + browsableURL := GikoSys.GetBrowsableThreadURL( URL ); + boardURL := GikoSys.GetThreadURL2BoardURL( browsableURL ); + board := BBSsFindBoardFromURL( boardURL ); + + if board = nil then begin + tmpURL := URL; + GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark ); + if GikoSys.Is2chHost( host ) then begin + GikoSys.Parse2chURL( tmpURL, path, document, BBSID, BBSKey ); + board := BBSs[ 0 ].FindBBSID( BBSID ); + end; - if board = nil then - Exit - // ¦ì‚Á‚Ä‚àA’ljÁ‚·‚éƒJƒeƒSƒŠ‚ª–³‚¢‚Ì‚ÅŒƒ‚µ‚­•Û—¯ - //board := GikoSys.GetUnknownBoard( nil, boardURL ) - else - FItem := board.FindThreadFromURL( browsableURL ); + if board = nil then begin + Exit; + // ¦ì‚Á‚Ä‚àA’ljÁ‚·‚éƒJƒeƒSƒŠ‚ª–³‚¢‚Ì‚ÅŒƒ‚µ‚­•Û—¯ + //board := GikoSys.GetUnknownBoard( nil, boardURL ) + end; + end; + + FItem := board.FindThreadFromURL( browsableURL ); + + if FItem = nil then begin + tmpURL := URL; + GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark ); + if GikoSys.Is2chHost( host ) then begin + GikoSys.Parse2chURL( tmpURL, path, document, BBSID, BBSKey ); + FItem := BBSs[ 0 ].FindThreadItem( BBSID, BBSKey + '.dat' ); + if FItem <> nil then + URL := FItem.URL; + end; + 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 ); @@ -179,19 +262,34 @@ begin end; -procedure TFavoriteDM.DataModuleCreate(Sender: TObject); +procedure TFavoriteDM.DataModuleDestroy(Sender: TObject); +//var +// i: Integer; begin - //FTreeView := TreeView; - //FTreeView := GikoForm.FavoriteTreeView; +{ TreeView.Items.BeginUpdate; + for i := TreeView.Items.Count - 1 downto 0 do begin + // if TObject(TreeView.Items[i].Data) <> nil then + // TObject(TreeView.Items[i].Data).Free; + end; + TreeView.Items.Clear; + TreeView.Items.EndUpdate; +} //TreeView.Free; end; - -procedure TFavoriteDM.DataModuleDestroy(Sender: TObject); +procedure TFavoriteDM.Clear; var - i: Integer; + Node : TTreeNode; begin - for i := 0 to TreeView.Items.Count - 1 do begin - TObject(TreeView.Items[i].Data).Free; + TreeView.Items.BeginUpdate; + Node := TreeView.Items.GetFirstNode; + while Node <> nil do begin + if TObject(Node.Data) <> nil then + TObject(Node.Data).Free; + Node := Node.GetNext; end; + TreeView.Items.Clear; + TreeView.Items.EndUpdate; + + FavoriteDM.Modified := true; end; procedure TFavoriteDM.SetFavTreeView(TreeView: TTreeView); @@ -209,17 +307,19 @@ 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; if FileExists(FileName) then begin try - XMLDoc := LoadXMLDocument(FileName); + XMLDoc := IXMLDocument.Create; + //XMLDoc := LoadXMLDocument(FileName); + LoadXMLDocument(FileName, XMLDoc); XMLNode := XMLDoc.DocumentElement; FStack := TStack.Create; @@ -227,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 @@ -237,12 +337,13 @@ 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; finally FStack.Free; + XMLDoc.Free; end; except end; @@ -250,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; @@ -286,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 @@ -308,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 @@ -325,21 +427,23 @@ begin if not board.IsThreadDatRead then GikoSys.ReadSubjectFile( board ); - threadItem := board.Find( Node.Attributes[ 'thread' ] ); + threadItem := board.FindThreadFromFileName( Node.Attributes[ 'thread' ] ); 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; @@ -371,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.‚ð‚‚¯‚È‚¢‚ÆWinAPI‚Æ‹æ•Ê‚Å‚«‚È‚¢‚Ì‚Å + RenameFile(FileName, tmpFileName); + end; SaveList := TStringList.Create; try SaveList.Add(''); SaveList.Add(''); - AddSaveString(TreeView.Items.GetFirstNode, SaveList); + try + AddSaveString(TreeView.Items.GetFirstNode.getFirstChild, SaveList); + except + end; SaveList.Add(''); SaveList.SaveToFile(FileName); finally @@ -425,31 +540,33 @@ end; procedure TFavoriteDM.AddSaveString(Node: TTreeNode; SaveList: TStringList); var - i: Integer; s: string; FavBoard: TFavoriteBoardItem; FavThread: TFavoriteThreadItem; + data : Pointer; begin - for i := 0 to Node.Count - 1 do begin - if TObject(Node.Item[i].Data) is TFavoriteFolder then begin - if Node.Item[ i ].Expanded then - s := Format('', [HtmlEncode(Node.Item[i].Text)]) + while Node <> nil do begin + data := Node.Data; + if TObject(data) is TFavoriteFolder then begin + if Node.Expanded then + s := Format('', [HtmlEncode(Node.Text)]) else - s := Format('', [HtmlEncode(Node.Item[i].Text)]); + s := Format('', [HtmlEncode(Node.Text)]); SaveList.Add(s); - AddSaveString(Node.Item[i], SaveList); + AddSaveString(Node.getFirstChild, SaveList); SaveList.Add(''); - end else if TObject(Node.Item[i].Data) is TFavoriteBoardItem then begin - FavBoard := TFavoriteBoardItem(Node.Item[i].Data); + end else if TObject(data) is TFavoriteBoardItem then begin + FavBoard := TFavoriteBoardItem(data); s := Format('', - [HtmlEncode( FavBoard.URL ), HtmlEncode(Node.Item[ i ].Text)]); + [HtmlEncode( FavBoard.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]); SaveList.Add(s); - end else if TObject(Node.Item[i].Data) is TFavoriteThreadItem then begin - FavThread := TFavoriteThreadItem(Node.Item[i].Data); + end else if TObject(data) is TFavoriteThreadItem then begin + FavThread := TFavoriteThreadItem(data); s := Format('', - [HtmlEncode( FavThread.URL ), HtmlEncode(Node.Item[ i ].Text)]); + [HtmlEncode( FavThread.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]); SaveList.Add(s); end; + Node := Node.getNextSibling; end; end; @@ -526,7 +643,7 @@ var FavoriteFilePath: string; tempStringList: TStringList; begin - + WriteFavorite; FavoriteFilePath := GikoSys.GetConfigDir + FAVORITE_FILE_NAME; if FileExists( FavoriteFilePath ) then begin @@ -543,6 +660,62 @@ begin end; end; +procedure TFavoriteDM.URLReplace(oldURLs: TStringList; newURLs: TStringList); +var + i : Integer; + tmpURL: string; + oldHost: string; + oldBoardName: string; + newHost: string; + newBoardName: string; + tempString: string; + favBoard : TFavoriteBoardItem; + favThread : TFavoriteThreadItem; + favorites : TTreeNodes; + Node : TTreeNode; +begin + + // –Ê“|‚¾‚¯‚Çthread‚Í‚»‚ꂼ‚êURL‚ðƒ`ƒFƒbƒN‚µ‚È‚ª‚ç‚â‚Á‚Ä‚©‚È‚«‚á‚¢‚¯‚È‚¢B + favorites := FavoriteDM.FTreeView.Items; + for i := 0 to oldURLs.Count - 1 do begin + try + tmpURL := Copy(oldURLs[i], 1, Length(oldURLs[i]) -1); + oldHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) ); + oldBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/'; + tmpURL := Copy(newURLs[i], 1, Length(newURLs[i]) -1); + newHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) ); + newBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/'; + + Node := favorites.GetFirstNode.getFirstChild; + while Node <> nil do begin + try + 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( 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 + tempString := StringReplace(tempString, oldHost, newHost,[]); + favThread.URL := tempString; + end; + end; + except + end; + Node := Node.GetNext; + end; + except + end; + end; + +end; + function TFavoriteDM.GetFavoriteFilePath() : String; begin Result := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;