X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=Favorite.pas;h=0e58ba29c2c864c05834c186a4cd5b2d995b2457;hb=refs%2Fheads%2FBb52;hp=f991b9ee14bcff0c534bd59d267dba0150da934c;hpb=b925170b0cfa0b549272e9e1658456408e3f80fc;p=gikonavigoeson%2Fgikonavi.git diff --git a/Favorite.pas b/Favorite.pas index f991b9e..0e58ba2 100644 --- a/Favorite.pas +++ b/Favorite.pas @@ -4,41 +4,53 @@ interface uses Messages, SysUtils, Classes, Contnrs, ComCtrls, {HttpApp,} YofUtils, - GikoSystem{, XMLIntf, XMLDoc}, GikoXMLDoc; + GikoSystem{, XMLIntf, XMLDoc}, GikoXMLDoc, BoardGroup, windows; {SAX, SAXHelpers, SAXComps, SAXKW;} type TFavoriteFolder = class end; - TFavoriteBoardItem = class + TFavoriteItem = class(TObject) private - FBBSID: string; - FBoardName: string; + FURL : string; + FTitle : string; public - property BBSID: string read FBBSID write FBBSID; - property BoardName: string read FBoardName write FBoardName; + 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; end; - TFavoriteThreadItem = class + TFavoriteThreadItem = class(TFavoriteItem) private - FBBSID: string; - FThreadID: string; - FThreadName: string; + FItem : TThreadItem; + function GetItem : TThreadItem; public - property BBSID: string read FBBSID write FBBSID; - property ThreadID: string read FThreadID write FThreadID; - property ThreadName: string read FThreadName write FThreadName; + 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; 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); @@ -49,10 +61,15 @@ type // procedure SAXCharacters(Sender: TObject; const PCh: SAXString); public { Public éŒ¾ } + 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 @@ -62,25 +79,217 @@ const implementation +uses ExternalBoardManager, ExternalBoardPlugInMain, MojuUtils; + const FAVORITE_ROOT_NAME = '‚¨‹C‚É“ü‚è'; FAVORITE_FILE_NAME = 'Favorite.xml'; {$R *.dfm} -procedure TFavoriteDM.DataModuleCreate(Sender: TObject); +constructor TFavoriteBoardItem.Create( + inURL : string; + inTitle : string = ''; + inItem : TBoard = nil +); +begin + + inherited Create; + + URL := inURL; + Title := inTitle; + Item := inItem; + +end; + +constructor TFavoriteBoardItem.CreateWithItem( + inItem : TBoard +); +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 + 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; + +end; + +constructor TFavoriteThreadItem.Create( + inURL : string; + inTitle : string = ''; + inItem : TThreadItem = nil +); +begin + + inherited Create; + URL := inURL; + + Title := inTitle; + Item := inItem; + +end; + +constructor TFavoriteThreadItem.CreateWithItem( + inItem : TThreadItem +); +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 - //FTreeView := TreeView; - //FTreeView := GikoForm.FavoriteTreeView; + 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 ); + + 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 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, board, browsableURL ); + + FItem.Title := Title; + board.Add( FItem ); + end; + end; + + Result := FItem; + end; procedure TFavoriteDM.DataModuleDestroy(Sender: TObject); +//var +// i: Integer; +begin +{ 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.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); @@ -98,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; @@ -116,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 @@ -126,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; @@ -139,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; @@ -168,40 +380,76 @@ var FavFolder: TFavoriteFolder; FavBoard: TFavoriteBoardItem; FavThread: TFavoriteThreadItem; + board : TBoard; + threadItem : TThreadItem; begin if Node.NodeName = 'folder' then 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; 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 - ParentNode := FStack.Peek; - if TObject(ParentNode.Data) is TFavoriteFolder then begin - if Node.Attributes['favtype'] = 'board' then begin - FavBoard := TFavoriteBoardItem.Create; - FavBoard.BBSID := Node.Attributes['bbs']; - FavBoard.BoardName := Node.Attributes['boardname']; - CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavBoard); - CurrentNode.ImageIndex := 15; - CurrentNode.SelectedIndex := 15; - end else if Node.Attributes['favtype'] = 'thread' then begin - FavThread := TFavoriteThreadItem.Create; - FavThread.BBSID := Node.Attributes['bbs']; - FavThread.ThreadID := Node.Attributes['thread']; - FavThread.ThreadName := Node.Attributes['threadname']; - CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavThread); - CurrentNode.ImageIndex := 16; - CurrentNode.SelectedIndex := 16; + try + ParentNode := FStack.Peek; + if TObject(ParentNode.Data) is TFavoriteFolder then begin + if Node.Attributes['favtype'] = 'board' then begin + FavBoard := nil; + // ‹ŒŽ®‚Ì‚¨‹C‚É“ü‚è‚Ƃ̌݊·«‚Ì‚½‚ß + if Length( Node.Attributes[ 'bbs' ] ) > 0 then begin + board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] ); + if board <> nil then + FavBoard := TFavoriteBoardItem.Create( + board.URL, MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), board ); + end else begin + FavBoard := TFavoriteBoardItem.Create( + Node.Attributes[ 'url' ], MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), nil ); + end; + 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 + // ‹ŒŽ®‚Ì‚¨‹C‚É“ü‚è‚Ƃ̌݊·«‚Ì‚½‚ß + if Length( Node.Attributes[ 'bbs' ] ) > 0 then begin + board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] ); + if board = nil then + Exit; + + if not board.IsThreadDatRead then + GikoSys.ReadSubjectFile( board ); + 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 := UnSanitize(Node.Attributes[ 'title' ]); + board.Add( threadItem ); + end; + FavThread := TFavoriteThreadItem.Create( + threadItem.URL, UnSanitize(Node.Attributes[ 'title' ]), threadItem ); + threadItem.Free; + end else begin + FavThread := TFavoriteThreadItem.Create( + Node.Attributes[ 'url' ], UnSanitize(Node.Attributes[ 'title' ]), nil ); + end; + CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavThread); + CurrentNode.ImageIndex := 16; + CurrentNode.SelectedIndex := 16; + end; end; + except + // ‚±‚̃AƒCƒeƒ€‚Å–â‘肪‹N‚«‚Ä‚à‘¼‚̃AƒCƒeƒ€‚ɉe‹¿‚ð—^‚¦‚½‚­‚È‚¢‚Ì‚Å end; end; end; @@ -218,7 +466,7 @@ var XMLNode: IXMLNode; // FavoNode: IXMLNode; begin - XMLDoc := NewXMLDocument; + XMLDoc := NewXMLDocument; XMLDoc.Encoding := 'Shift_JIS'; XMLDoc.StandAlone := 'yes'; XMLNode := XMLDoc.AddChild('favorite'); @@ -227,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 @@ -281,28 +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 - 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.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); - s := Format('', - [FavBoard.BBSID, HtmlEncode(Node.Item[i].Text), HtmlEncode(FavBoard.BoardName)]); + end else if TObject(data) is TFavoriteBoardItem then begin + FavBoard := TFavoriteBoardItem(data); + s := Format('', + [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); - s := Format('', - [FavThread.BBSID, FavThread.ThreadID, HtmlEncode(Node.Item[i].Text), HtmlEncode(FavThread.ThreadName)]); + end else if TObject(data) is TFavoriteThreadItem then begin + FavThread := TFavoriteThreadItem(data); + s := Format('', + [HtmlEncode( FavThread.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]); SaveList.Add(s); end; + Node := Node.getNextSibling; end; end; @@ -374,4 +638,87 @@ begin // end; } +function TFavoriteDM.SaveFavoriteFile(FileName: String) : Boolean; +var + FavoriteFilePath: string; + tempStringList: TStringList; +begin + WriteFavorite; + FavoriteFilePath := GikoSys.GetConfigDir + FAVORITE_FILE_NAME; + + if FileExists( FavoriteFilePath ) then begin + tempStringList := TStringList.Create; + try + tempStringList.LoadFromFile( FavoriteFilePath ); + tempStringList.SaveToFile( FileName ); + finally + tempStringList.Free; + end; + Result := true; + end else begin + Result := false; + 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; +end; + end.