OSDN Git Service

ノートン先生の誤反応対策で「お気に入り」「履歴」「送信ログ」のスレッドタイトルの
[gikonavigoeson/gikonavi.git] / Favorite.pas
1 unit Favorite;
2
3 interface
4
5 uses
6         Messages, SysUtils, Classes, Contnrs, ComCtrls, {HttpApp,} YofUtils,
7         GikoSystem{, XMLIntf, XMLDoc}, GikoXMLDoc, BoardGroup, windows;
8         {SAX, SAXHelpers, SAXComps, SAXKW;}
9
10 type
11         TFavoriteFolder = class
12         end;
13
14         TFavoriteItem = class(TObject)
15         private
16                 FURL                            : string;
17                 FTitle                  : string;
18         public
19                 function GetItemTitle : string; virtual;abstract;
20                 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é
21                 property Title                  : string        read FTitle write FTitle;
22         end;
23         TFavoriteBoardItem = class(TFavoriteItem)
24         private
25                 FItem                           : TBoard;
26                 function        GetItem : TBoard;
27         public
28                 constructor Create( inURL : string; inTitle : string = ''; inItem : TBoard = nil );
29                 constructor CreateWithItem( inItem : TBoard );
30                 destructor Destory;
31                 function GetItemTitle : string; override;
32                 property Item                           : TBoard        read GetItem write FItem;
33         end;
34
35         TFavoriteThreadItem = class(TFavoriteItem)
36         private
37                 FItem                           : TThreadItem;
38                 function        GetItem : TThreadItem;
39         public
40                 constructor Create( inURL : string; inTitle : string = ''; inItem : TThreadItem = nil );
41                 constructor CreateWithItem( inItem : TThreadItem );
42                 destructor Destory;
43                 function GetItemTitle : string; override;
44                 property Item                           : TThreadItem   read GetItem write FItem;
45         end;
46
47         TFavoriteDM = class(TDataModule)
48                 procedure DataModuleDestroy(Sender: TObject);
49         private
50                 { Private \90é\8c¾ }
51                 FStack: TStack;
52                 FTreeView: TTreeView;
53                 FModified: boolean;
54                 procedure ReadNode(Node: IXMLNode);
55                 procedure AddSaveString(Node: TTreeNode; SaveList: TStringList);
56 //              procedure AddSaveString(Node: TTreeNode; XMLNode: IXMLNode);
57 //              procedure SAXStartDocument(Sender: TObject);
58 //              procedure SAXEndDocument(Sender: TObject);
59 //              procedure SAXStartElement(Sender: TObject; const NamespaceURI, LocalName, QName: SAXString; const Atts: IAttributes);
60 //              procedure SAXEndElement(Sender: TObject; const NamespaceURI, LocalName, QName: SAXString);
61 //              procedure SAXCharacters(Sender: TObject; const PCh: SAXString);
62         public
63                 { Public \90é\8c¾ }
64                 procedure Clear;
65                 function GetFavoriteFilePath() : String;
66                 function SaveFavoriteFile(FileName: String) : Boolean;
67                 procedure SetFavTreeView(TreeView: TTreeView);
68                 procedure ReadFavorite;
69                 procedure WriteFavorite;
70                 procedure URLReplace(oldURLs: TStringList; newURLs: TStringList);
71                 property TreeView: TTreeView read FTreeView;
72                 property Modified: boolean read FModified write FModified;
73         end;
74
75 var
76         FavoriteDM: TFavoriteDM;
77 const
78         FAVORITE_LINK_NAME = '\83\8a\83\93\83N';
79
80 implementation
81
82 uses    ExternalBoardManager, ExternalBoardPlugInMain,  MojuUtils;
83
84 const
85         FAVORITE_ROOT_NAME = '\82¨\8bC\82É\93ü\82è';
86         FAVORITE_FILE_NAME = 'Favorite.xml';
87
88 {$R *.dfm}
89
90 constructor TFavoriteBoardItem.Create(
91         inURL           : string;
92         inTitle : string = '';
93         inItem  : TBoard = nil
94 );
95 begin
96
97         inherited Create;
98
99         URL             := inURL;
100         Title   := inTitle;
101         Item    := inItem;
102
103 end;
104
105 constructor TFavoriteBoardItem.CreateWithItem(
106         inItem  : TBoard
107 );
108 begin
109
110         Create( inItem.URL, inItem.Title, inItem );
111
112 end;
113 destructor TFavoriteBoardItem.Destory;
114 begin
115         if FItem <> nil then
116                 FItem.Free;
117         inherited;
118 end;
119 //! \95Û\8e\9d\82µ\82Ä\82¢\82é\94Â\82Ì\83^\83C\83g\83\8b\82ð\95Ô\82·
120 function TFavoriteBoardItem.GetItemTitle : string;
121 begin
122         Result := '';
123         //\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
124         //\82Ì\82Æ\82«\82ÉFItem\82ªnil\82È\82Ì\82Å\82»\82Ì\82Æ\82«\82Í\82×\82Á\82Æ\8c\9f\8dõ
125         if FItem = nil then begin
126                 FItem := BBSsFindBoardFromURL(URL);
127         end;
128         if FItem <> nil then begin
129                 try
130                         if not FItem.IsThreadDatRead then begin
131                                 GikoSys.ReadSubjectFile(FItem);
132                         end;
133                 except
134                 end;
135                 Result := FItem.Title;
136         end;
137 end;
138 function        TFavoriteBoardItem.GetItem : TBoard;
139 var
140         protocol, host, path, document, port, bookmark : string;
141         BBSID   : string;
142         tmpURL  : string;
143 begin
144
145         if FItem = nil then begin
146                 FItem := BBSsFindBoardFromURL( URL );
147                 if FItem = nil then begin
148                         tmpURL := URL;
149                         GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark );
150                         if GikoSys.Is2chHost( host ) then begin
151                                 BBSID := GikoSys.URLToID( tmpURL );
152                                 FItem := BBSs[ 0 ].FindBBSID( BBSID );
153                                 if FItem <> nil then
154                                         URL := FItem.URL;
155                         end;
156                         {
157                         // \81¦\8dì\82Á\82Ä\82à\81A\92Ç\89Á\82·\82é\83J\83e\83S\83\8a\82ª\96³\82¢\82Ì\82Å\8c\83\82µ\82­\95Û\97¯
158                         FItem                           := GikoSys.GetUnknownBoard( nil, URL );
159                         FItem.Title     := Title;
160                         }
161                 end;
162         end;
163
164         Result := FItem;
165
166 end;
167
168 constructor TFavoriteThreadItem.Create(
169         inURL           : string;
170         inTitle : string = '';
171         inItem  : TThreadItem = nil
172 );
173 begin
174
175         inherited Create;
176         URL             := inURL;
177
178         Title   := inTitle;
179         Item    := inItem;
180
181 end;
182
183 constructor TFavoriteThreadItem.CreateWithItem(
184         inItem  : TThreadItem
185 );
186 begin
187
188         Create( inItem.URL, inItem.Title, inItem );
189
190 end;
191 destructor TFavoriteThreadItem.Destory;
192 begin
193         if FItem <> nil then
194         FItem.Free;
195     inherited;
196 end;
197 //! \95Û\8e\9d\82µ\82Ä\82¢\82é\83X\83\8c\82Ì\83^\83C\83g\83\8b\82ð\95Ô\82·
198 function TFavoriteThreadItem.GetItemTitle : string;
199 begin
200         Result := '';
201         if FItem = nil then begin
202                 FItem := BBSsFindThreadFromURL(URL);
203         end;
204         if FItem <> nil then begin
205                 Result := FItem.Title;
206         end;
207 end;
208
209 function        TFavoriteThreadItem.GetItem : TThreadItem;
210 var
211         board                                   : TBoard;
212         boardURL                        : string;
213         browsableURL    : string;
214         protocol, host, path, document, port, bookmark : string;
215         BBSID, BBSKey   : string;
216         tmpURL                          : string;
217 begin
218
219         Result := nil;
220         if FItem = nil then begin
221                 browsableURL    := GikoSys.GetBrowsableThreadURL( URL );
222                 boardURL                        := GikoSys.GetThreadURL2BoardURL( browsableURL );
223                 board                                   := BBSsFindBoardFromURL( boardURL );
224
225                 if board = nil then begin
226                         tmpURL := URL;
227                         GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark );
228                         if GikoSys.Is2chHost( host ) then begin
229                                 GikoSys.Parse2chURL( tmpURL, path, document, BBSID, BBSKey );
230                                 board := BBSs[ 0 ].FindBBSID( BBSID );
231                         end;
232
233                         if board = nil then begin
234                                 Exit;
235                                 // \81¦\8dì\82Á\82Ä\82à\81A\92Ç\89Á\82·\82é\83J\83e\83S\83\8a\82ª\96³\82¢\82Ì\82Å\8c\83\82µ\82­\95Û\97¯
236                                 //board := GikoSys.GetUnknownBoard( nil, boardURL )
237                         end;
238                 end;
239
240                 FItem := board.FindThreadFromURL( browsableURL );
241
242                 if FItem = nil then begin
243                         tmpURL := URL;
244                         GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark );
245                         if GikoSys.Is2chHost( host ) then begin
246                                 GikoSys.Parse2chURL( tmpURL, path, document, BBSID, BBSKey );
247                                 FItem := BBSs[ 0 ].FindThreadItem( BBSID, BBSKey + '.dat' );
248                                 if FItem <> nil then
249                                         URL := FItem.URL;
250                         end;
251                 end;
252
253                 if FItem = nil then begin
254                         FItem := TThreadItem.Create( board.BoardPlugIn, board, browsableURL );
255
256                         FItem.Title := Title;
257                         board.Add( FItem );
258                 end;
259         end;
260
261         Result := FItem;
262
263 end;
264
265 procedure TFavoriteDM.DataModuleDestroy(Sender: TObject);
266 //var
267 //      i: Integer;
268 begin
269 {    TreeView.Items.BeginUpdate;
270         for i := TreeView.Items.Count - 1 downto 0 do begin
271            //   if TObject(TreeView.Items[i].Data) <> nil then
272        //       TObject(TreeView.Items[i].Data).Free;
273         end;
274     TreeView.Items.Clear;
275     TreeView.Items.EndUpdate;
276 }    //TreeView.Free;
277 end;
278 procedure TFavoriteDM.Clear;
279 var
280         Node    : TTreeNode;
281 begin
282         TreeView.Items.BeginUpdate;
283         Node    := TreeView.Items.GetFirstNode;
284         while Node <> nil do begin
285                 if TObject(Node.Data) <> nil then
286                                 TObject(Node.Data).Free;
287                 Node := Node.GetNext;
288         end;
289                 TreeView.Items.Clear;
290                 TreeView.Items.EndUpdate;
291
292     FavoriteDM.Modified := true;
293 end;
294
295 procedure TFavoriteDM.SetFavTreeView(TreeView: TTreeView);
296 begin
297         FTreeView := TreeView;
298 end;
299
300 procedure TFavoriteDM.ReadFavorite;
301 var
302         FileName: string;
303         XMLDoc: IXMLDocument;
304         XMLNode: IXMLNode;
305         Node: TTreeNode;
306         i: Integer;
307         FavFolder: TFavoriteFolder;
308         LinkExists: Boolean;
309 begin
310         FavoriteDM.Modified := true;
311         FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
312
313         FavFolder := TFavoriteFolder.Create;
314         Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
315         Node.ImageIndex := 14;
316         Node.SelectedIndex := 14;
317
318         if FileExists(FileName) then begin
319                 try
320             XMLDoc := IXMLDocument.Create;
321                         //XMLDoc := LoadXMLDocument(FileName);
322             LoadXMLDocument(FileName, XMLDoc);
323                         XMLNode := XMLDoc.DocumentElement;
324
325                         FStack := TStack.Create;
326                         try
327                                 FStack.Push(Node);
328                                 LinkExists := False;
329                                 if XMLNode.NodeName = 'favorite' then begin
330                                         for i := XMLNode.ChildNodes.Count - 1 downto 0 do begin
331                                                 ReadNode(XMLNode.ChildNodes[i]);
332                                                 if (XMLNode.ChildNodes[i].NodeName = 'folder') and
333                                                          (XMLNode.ChildNodes[i].Attributes['title'] = FAVORITE_LINK_NAME) then begin
334                                                         LinkExists := True;
335                                                 end;
336                                         end;
337                                 end;
338                                 if not LinkExists then begin
339                                         FavFolder := TFavoriteFolder.Create;
340                                         Node := FTreeView.Items.AddChildObjectFirst(Node, FAVORITE_LINK_NAME, FavFolder);
341                                         Node.ImageIndex := 14;
342                                         Node.SelectedIndex := 14;
343                                 end;
344                         finally
345                                 FStack.Free;
346                 XMLDoc.Free;
347                         end;
348                 except
349                 end;
350         end;
351
352 {
353         FavFolder := TFavoriteFolder.Create;
354         Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
355         Node.ImageIndex := 12;
356         Node.SelectedIndex := 13;
357
358         FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
359         if not FileExists(FileName) then
360                 Exit;
361
362                 FavSAXHandler.OnStartDocument := SAXStartDocument;
363                 FavSAXHandler.OnEndDocument := SAXEndDocument;
364                 FavSAXHandler.OnStartElement := SAXStartElement;
365                 FavSAXHandler.OnStartElement := SAXStartElement;
366                 FavSAXHandler.OnEndElement := SAXEndElement;
367                 FavSAXHandler.OnCharacters := SAXCharacters;
368
369                 FavSAXReader.Vendor := 'Keith Wood';
370                 FavSAXReader.URL := FileName;
371                 FavSAXReader.Parse;}
372 end;
373
374 procedure TFavoriteDM.ReadNode(Node: IXMLNode);
375 var
376         i: Integer;
377
378         ParentNode: TTreeNode;
379         CurrentNode: TTreeNode;
380         FavFolder: TFavoriteFolder;
381         FavBoard: TFavoriteBoardItem;
382         FavThread: TFavoriteThreadItem;
383         board                           : TBoard;
384         threadItem      : TThreadItem;
385 begin
386         if Node.NodeName = 'folder' then begin
387                 ParentNode := FStack.Peek;
388                 if TObject(ParentNode.Data) is TFavoriteFolder then begin
389                         FavFolder := TFavoriteFolder.Create;
390                         CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavFolder);
391                         CurrentNode.ImageIndex := 14;
392                         CurrentNode.SelectedIndex := 14;
393                         FStack.Push(CurrentNode);
394                 end;
395                 for i := Node.ChildNodes.Count - 1 downto 0 do begin
396                         ReadNode(Node.ChildNodes[i]);
397                 end;
398                 if TObject(ParentNode.Data) is TFavoriteFolder then
399                         CurrentNode.Expanded := Node.Attributes[ 'expanded' ] = 'true';
400                 if FStack.Count <> 0 then
401                         FStack.Pop;
402         end else if Node.NodeName = 'favitem' then begin
403                 try
404                         ParentNode := FStack.Peek;
405                         if TObject(ParentNode.Data) is TFavoriteFolder then begin
406                                 if Node.Attributes['favtype'] = 'board' then begin
407                                         FavBoard := nil;
408                                         // \8b\8c\8e®\82Ì\82¨\8bC\82É\93ü\82è\82Æ\82Ì\8cÝ\8a·\90«\82Ì\82½\82ß
409                                         if Length( Node.Attributes[ 'bbs' ] ) > 0 then begin
410                                                 board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] );
411                                                 if board <> nil then
412                                                         FavBoard := TFavoriteBoardItem.Create(
413                                                                 board.URL, MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), board );
414                                         end else begin
415                                                 FavBoard := TFavoriteBoardItem.Create(
416                                                         Node.Attributes[ 'url' ], MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), nil );
417                                         end;
418                                         CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavBoard);
419                                         CurrentNode.ImageIndex := 15;
420                                         CurrentNode.SelectedIndex := 15;
421                                 end else if Node.Attributes['favtype'] = 'thread' then begin
422                                         // \8b\8c\8e®\82Ì\82¨\8bC\82É\93ü\82è\82Æ\82Ì\8cÝ\8a·\90«\82Ì\82½\82ß
423                                         if Length( Node.Attributes[ 'bbs' ] ) > 0 then begin
424                                                 board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] );
425                                                 if board = nil then
426                                                         Exit;
427
428                                                 if not board.IsThreadDatRead then
429                                                         GikoSys.ReadSubjectFile( board );
430                                                 threadItem := board.FindThreadFromFileName( Node.Attributes[ 'thread' ] );
431                                                 if threadItem = nil then begin
432                                                         threadItem := TThreadItem.Create(
433                                                                 board.BoardPlugIn,
434                                 board,
435                                                                 GikoSys.Get2chBoard2ThreadURL( board, ChangeFileExt( Node.Attributes[ 'thread' ], '' ) ) );
436                                                         threadItem.Title := UnSanitize(Node.Attributes[ 'title' ]);
437                                                         board.Add( threadItem );
438                                                 end;
439                                                 FavThread := TFavoriteThreadItem.Create(
440                                                         threadItem.URL, UnSanitize(Node.Attributes[ 'title' ]), threadItem );
441                         threadItem.Free;
442                                         end else begin
443                                                 FavThread := TFavoriteThreadItem.Create(
444                                                         Node.Attributes[ 'url' ], UnSanitize(Node.Attributes[ 'title' ]), nil );
445                                         end;
446                                         CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavThread);
447                                         CurrentNode.ImageIndex := 16;
448                                         CurrentNode.SelectedIndex := 16;
449                                 end;
450                         end;
451                 except
452                         // \82±\82Ì\83A\83C\83e\83\80\82Å\96â\91è\82ª\8bN\82«\82Ä\82à\91¼\82Ì\83A\83C\83e\83\80\82É\89e\8b¿\82ð\97^\82¦\82½\82­\82È\82¢\82Ì\82Å
453                 end;
454         end;
455 end;
456
457 procedure TFavoriteDM.WriteFavorite;
458 {
459 var
460         FileName: string;
461 //      SaveList: TStringList;
462 //      i: Integer;
463 //      Count: Integer;
464
465         XMLDoc: IXMLDocument;
466         XMLNode: IXMLNode;
467 //      FavoNode: IXMLNode;
468 begin
469         XMLDoc :=       NewXMLDocument;
470         XMLDoc.Encoding := 'Shift_JIS';
471         XMLDoc.StandAlone := 'yes';
472         XMLNode := XMLDoc.AddChild('favorite');
473         FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
474         AddSaveString(TreeView.Items.GetFirstNode, XMLNode);
475         XMLDoc.SaveToFile(FileName);
476 }
477 var
478         FileName, tmpFileName: string;
479         SaveList: TStringList;
480
481 begin
482     FavoriteDM.Modified := true;
483         FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
484         if FileExists(FileName) then begin
485                 tmpFileName := GikoSys.GetConfigDir + '~' + FAVORITE_FILE_NAME;
486                 if FileExists(tmpFileName) then
487                         SysUtils.DeleteFile(tmpFileName); //SysUtils.\82ð\82Â\82¯\82È\82¢\82ÆWinAPI\82Æ\8bæ\95Ê\82Å\82«\82È\82¢\82Ì\82Å
488                 RenameFile(FileName, tmpFileName);
489         end;
490         SaveList := TStringList.Create;
491         try
492                 SaveList.Add('<?xml version="1.0" encoding="Shift_JIS" standalone="yes"?>');
493                 SaveList.Add('<favorite>');
494                 try
495                         AddSaveString(TreeView.Items.GetFirstNode.getFirstChild, SaveList);
496                 except
497                 end;
498                 SaveList.Add('</favorite>');
499                 SaveList.SaveToFile(FileName);
500         finally
501                 SaveList.Free;
502         end;
503 end;
504
505 {
506 procedure TFavoriteDM.AddSaveString(Node: TTreeNode; XMLNode: IXMLNode);
507 var
508         i: Integer;
509 //      s: string;
510         FavBoard: TFavoriteBoardItem;
511         FavThread: TFavoriteThreadItem;
512         FavNode: IXMLNode;
513 begin
514         for i := 0 to Node.Count - 1 do begin
515                 if TObject(Node.Item[i].Data) is TFavoriteFolder then begin
516                         FavNode := XMLNode.AddChild('folder');
517                         FavNode.Attributes['title'] := Node.Item[i].Text;
518                         AddSaveString(Node.Item[i], FavNode);
519                 end else if TObject(Node.Item[i].Data) is TFavoriteBoardItem then begin
520                         FavBoard := TFavoriteBoardItem(Node.Item[i].Data);
521                         FavNode := XMLNode.AddChild('favitem');
522                         FavNode.Attributes['type'] := '2ch';
523                         FavNode.Attributes['favtype'] := 'board';
524                         FavNode.Attributes['bbs'] := FavBoard.BBSID;
525                         FavNode.Attributes['title'] := Node.Item[i].Text;
526                         FavNode.Attributes['boardname'] := FavBoard.BoardName;
527                 end else if TObject(Node.Item[i].Data) is TFavoriteThreadItem then begin
528                         FavThread := TFavoriteThreadItem(Node.Item[i].Data);
529                         FavNode := XMLNode.AddChild('favitem');
530                         FavNode.Attributes['type'] := '2ch';
531                         FavNode.Attributes['favtype'] := 'thread';
532                         FavNode.Attributes['bbs'] := FavThread.BBSID;
533                         FavNode.Attributes['thread'] := FavThread.ThreadID;
534                         FavNode.Attributes['title'] := Node.Item[i].Text;
535                         FavNode.Attributes['threadname'] := FavThread.ThreadName;
536                 end;
537         end;
538 end;
539 }
540
541 procedure TFavoriteDM.AddSaveString(Node: TTreeNode; SaveList: TStringList);
542 var
543         s: string;
544         FavBoard: TFavoriteBoardItem;
545         FavThread: TFavoriteThreadItem;
546         data : Pointer;
547 begin
548         while Node <> nil do begin
549                 data := Node.Data;
550                 if TObject(data) is TFavoriteFolder then begin
551                         if Node.Expanded then
552                                 s := Format('<folder title="%s" expanded="true">', [HtmlEncode(Node.Text)])
553                         else
554                                 s := Format('<folder title="%s" expanded="false">', [HtmlEncode(Node.Text)]);
555                         SaveList.Add(s);
556                         AddSaveString(Node.getFirstChild, SaveList);
557                         SaveList.Add('</folder>');
558                 end else if TObject(data) is TFavoriteBoardItem then begin
559                         FavBoard := TFavoriteBoardItem(data);
560                         s := Format('<favitem type="2ch" favtype="board" url="%s" title="%s"/>',
561                                                                         [HtmlEncode( FavBoard.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
562                         SaveList.Add(s);
563                 end else if TObject(data) is TFavoriteThreadItem then begin
564                         FavThread := TFavoriteThreadItem(data);
565                         s := Format('<favitem type="2ch" favtype="thread" url="%s" title="%s"/>',
566                                                                         [HtmlEncode( FavThread.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
567                         SaveList.Add(s);
568                 end;
569                 Node := Node.getNextSibling;
570         end;
571 end;
572
573 {
574 procedure TFavoriteDM.SAXStartDocument(Sender: TObject);
575 begin
576         FStack := TStack.Create;
577         FStack.Push(FTreeView.Items.GetFirstNode);
578 end;
579
580 procedure TFavoriteDM.SAXEndDocument(Sender: TObject);
581 begin
582         FStack.Free;
583 end;
584
585 procedure TFavoriteDM.SAXStartElement(Sender: TObject; const NamespaceURI, LocalName, QName: SAXString;
586         const Atts: IAttributes);
587 var
588         FavType: string;
589         ParentNode: TTreeNode;
590         CurrentNode: TTreeNode;
591         FavFolder: TFavoriteFolder;
592         FavBoard: TFavoriteBoardItem;
593         FavThread: TFavoriteThreadItem;
594 begin
595         if QName = 'folder' then begin
596                 ParentNode := FStack.Peek;
597                 if TObject(ParentNode.Data) is TFavoriteFolder then begin
598                         FavFolder := TFavoriteFolder.Create;
599                         CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Atts.getValue('title'), FavFolder);
600                         CurrentNode.ImageIndex := 12;
601                         CurrentNode.SelectedIndex := 13;
602                         FStack.Push(CurrentNode);
603                 end;
604         end else if QName = 'favitem' then begin
605                 ParentNode := FStack.Peek;
606                 if TObject(ParentNode.Data) is TFavoriteFolder then begin
607                         FavType := Atts.getValue('favtype');
608                         if FavType = 'board' then begin
609                                 FavBoard := TFavoriteBoardItem.Create;
610                                 FavBoard.BBSID := Atts.getValue('bbs');
611                                 FavBoard.BoardName := Atts.getValue('boardname');
612                                 CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Atts.getValue('title'), FavBoard);
613                                 CurrentNode.ImageIndex := 14;
614                                 CurrentNode.SelectedIndex := 15;
615                         end else if FavType = 'thread' then begin
616                                 FavThread := TFavoriteThreadItem.Create;
617                                 FavThread.BBSID := Atts.getValue('bbs');
618                                 FavThread.ThreadID := Atts.getValue('thread');
619                                 FavThread.ThreadName := Atts.getValue('threadname');
620                                 CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Atts.getValue('title'), FavThread);
621                                 CurrentNode.ImageIndex := 16;
622                                 CurrentNode.SelectedIndex := 17;
623                         end;
624                 end;
625         end;
626 end;
627
628 procedure TFavoriteDM.SAXEndElement(Sender: TObject; const NamespaceURI, LocalName, QName: SAXString);
629 begin
630         if QName = 'folder' then begin
631                 if FStack.Count <> 0 then
632                         FStack.Pop;
633         end;
634 end;
635
636 procedure TFavoriteDM.SAXCharacters(Sender: TObject; const PCh: SAXString);
637 begin
638 //
639 end;
640 }
641 function TFavoriteDM.SaveFavoriteFile(FileName: String) : Boolean;
642 var
643         FavoriteFilePath: string;
644                 tempStringList: TStringList;
645 begin
646         WriteFavorite;
647         FavoriteFilePath := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
648
649         if FileExists( FavoriteFilePath ) then begin
650                 tempStringList := TStringList.Create;
651                 try
652                         tempStringList.LoadFromFile( FavoriteFilePath );
653                         tempStringList.SaveToFile( FileName );
654                 finally
655                         tempStringList.Free;
656                 end;
657                 Result := true;
658         end else begin
659                 Result := false;
660         end;
661 end;
662
663 procedure TFavoriteDM.URLReplace(oldURLs: TStringList; newURLs: TStringList);
664 var
665         i                                       : Integer;
666                 tmpURL: string;
667     oldHost: string;
668     oldBoardName: string;
669     newHost: string;
670     newBoardName: string;
671                 tempString: string;
672         favBoard        : TFavoriteBoardItem;
673         favThread       : TFavoriteThreadItem;
674         favorites       : TTreeNodes;
675         Node                    : TTreeNode;
676 begin
677
678         // \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
679         favorites := FavoriteDM.FTreeView.Items;
680         for i := 0 to oldURLs.Count - 1 do begin
681                 try
682                         tmpURL                  := Copy(oldURLs[i], 1, Length(oldURLs[i]) -1);
683                         oldHost                 := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
684                         oldBoardName    := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
685                         tmpURL                  := Copy(newURLs[i], 1, Length(newURLs[i]) -1);
686                         newHost                 := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
687                         newBoardName    := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
688
689                         Node := favorites.GetFirstNode.getFirstChild;
690                         while Node <> nil do begin
691                                 try
692                                         if TObject( Node.Data ) is TFavoriteBoardItem then begin
693                                                 favBoard := TFavoriteBoardItem( Node.Data );
694                                                 if favBoard = nil then continue;
695                                                 tempString := favBoard.URL;
696                                                 if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
697                                                         tempString              := StringReplace(tempString, oldHost, newHost,[]);
698                                                         favBoard.URL    := tempString;
699                                                 end;
700                                         end else if TObject( Node.Data ) is TFavoriteThreadItem then begin
701                                                 favThread := TFavoriteThreadItem( Node.Data );
702                                                 if favThread = nil then continue;
703                                                 tempString := favThread.URL;
704                                                 if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
705                                                         tempString              := StringReplace(tempString, oldHost, newHost,[]);
706                                                         favThread.URL   := tempString;
707                                                 end;
708                                         end;
709                                 except
710                                 end;
711                                 Node := Node.GetNext;
712                         end;
713                 except
714                 end;
715         end;
716
717 end;
718
719 function TFavoriteDM.GetFavoriteFilePath() : String;
720 begin
721         Result := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
722 end;
723
724 end.