• R/O
  • HTTP
  • SSH
  • HTTPS

gikonavi: Commit


Commit MetaInfo

Revisionb5fb9adb797384161110609455e5bc963acc4ddb (tree)
Time2004-10-08 14:44:53
Authoryoffy <yoffy>
Commiteryoffy

Log Message

b49 にマージ。

Change Summary

Incremental Difference

--- a/AbonUnit.pas
+++ b/AbonUnit.pas
@@ -824,58 +824,62 @@ begin
824824 end;
825825 end;
826826 end;
827- Result := false;
827+ Result := false;
828828
829829 end;
830830 //シリア語ブラクラ対策
831831 function TAbon.TreatSyria(AString: string): string;
832832 var
833833 //count: Integer; //(&#1792~&#1871)
834- pos: Integer;
835- tmp: string;
834+ pos: Integer;
835+ tmp: string;
836836 begin
837- pos := AnsiPos('&#18', AString);
837+ pos := AnsiPos('&#18', AString);
838838 while pos <> 0 do begin
839- if AString[pos+6] = ';' then begin
840- if StrToIntDef(Copy(AString, pos+4, 2), 0) <= 71 then begin
841- tmp := tmp + Copy(AString, 1, pos - 1);
842- Delete(AString, 1, pos+6);
843- end else begin
844- tmp := tmp + Copy(AString, 1, pos + 6);
845- Delete(AString, 1, pos+6);
846- end;
847- end else begin
848- tmp := tmp + Copy(AString, 1, pos + 3);
849- Delete(AString, 1, pos+3);
850- end;
851- pos := AnsiPos('&#18', AString);
852- end;
853- if Length(AString) > 0 then
854- tmp := tmp + AString;
855- AString := tmp;
856- tmp := '';
839+ if StrToIntDef(Copy(AString, pos+4, 2), -1) > 0 then begin
840+ if (AString[pos+6] = ';' ) or (AString[pos+6] = ' ') then begin
841+ tmp := tmp + Copy(AString, 1, pos - 1);
842+ Delete(AString, 1, pos+6);
843+ end else if StrToIntDef(AString[pos+6], -1) = -1 then begin
844+ tmp := tmp + Copy(AString, 1, pos - 1);
845+ Delete(AString, 1, pos+5);
846+ end else begin
847+ tmp := tmp + Copy(AString, 1, pos + 5);
848+ Delete(AString, 1, pos+5);
849+ end;
850+ end else begin
851+ tmp := tmp + Copy(AString, 1, pos + 5);
852+ Delete(AString, 1, pos+5);
853+ end;
854+ pos := AnsiPos('&#18', AString);
855+ end;
856+ if Length(AString) > 0 then
857+ tmp := tmp + AString;
858+ AString := tmp;
859+ tmp := '';
857860
858- pos := AnsiPos('&#179', AString);
861+ pos := AnsiPos('&#179', AString);
859862 while pos <> 0 do begin
860- if AString[pos+6] = ';' then begin
861- if StrToIntDef(Copy(AString, pos+5, 1), 0) > 2 then begin
862- tmp := tmp + Copy(AString, 1, pos - 1);
863- Delete(AString, 1, pos+6);
864- end else begin
865- tmp := tmp + Copy(AString, 1, pos + 6);
866- Delete(AString, 1, pos+6);
867- end;
868- tmp := tmp + Copy(AString, 1, pos - 1);
869- Delete(AString, 1, pos+6);
870- end else begin
871- tmp := tmp + Copy(AString, 1, pos + 4);
872- Delete(AString, 1, pos+4);
873- end;
874- pos := AnsiPos('&#179', AString);
875- end;
876- if Length(AString) > 0 then
877- tmp := tmp + AString;
878- Result := tmp;
863+ if StrToIntDef(Copy(AString, pos+5, 1), 0) > 2 then begin
864+ if (AString[pos+6] = ';') or (AString[pos+6] = ' ') then begin
865+ tmp := tmp + Copy(AString, 1, pos - 1);
866+ Delete(AString, 1, pos+6);
867+ end else if StrToIntDef(AString[pos+6], -1) = -1 then begin
868+ tmp := tmp + Copy(AString, 1, pos - 1);
869+ Delete(AString, 1, pos+5);
870+ end else begin
871+ tmp := tmp + Copy(AString, 1, pos + 5);
872+ Delete(AString, 1, pos+5);
873+ end;
874+ end else begin
875+ tmp := tmp + Copy(AString, 1, pos + 5);
876+ Delete(AString, 1, pos+5);
877+ end;
878+ pos := AnsiPos('&#179', AString);
879+ end;
880+ if Length(AString) > 0 then
881+ tmp := tmp + AString;
882+ Result := tmp;
879883 end;
880884 end.
881885
--- a/BoardGroup.pas
+++ b/BoardGroup.pas
@@ -394,7 +394,7 @@ const
394394 SUBJECT_FILENAME: string = 'subject.txt';
395395 PATH_DELIM: string = '\';
396396 SETTINGTXT_FILENAME: string = 'SETTING.TXT';
397- HEADTXT_FILENAME: string = 'head.txt';
397+ HEADTXT_FILENAME: string = 'head.html';
398398 //DEFAULT_LIST_COUNT: Integer = 100;
399399
400400 // COLUMN_CATEGORY: array[0..0] of string = ('カテゴリ名');
@@ -1668,9 +1668,11 @@ procedure TThreadItem.DeleteLogFile;
16681668 begin
16691669 ParentBoard.BeginUpdate;
16701670
1671+ if FUnRead then
1672+ ParentBoard.UnRead := ParentBoard.UnRead - 1;
16711673 DeleteFile(GetThreadFileName);
1672- if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1673- DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
1674+ if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then
1675+ DeleteFile(ChangeFileExt(GetThreadFileName,'.NG'));
16741676 FRoundDate := ZERO_DATE;
16751677 FLastModified := ZERO_DATE;
16761678 FSize := 0;
--- a/Editor.dfm
+++ b/Editor.dfm
@@ -105,7 +105,7 @@ object EditorForm: TEditorForm
105105 Width = 149
106106 Height = 20
107107 DropDownCount = 20
108- ItemHeight = 12
108+ ItemHeight = 0
109109 TabOrder = 0
110110 end
111111 object MailComboBox: TComboBox
@@ -114,7 +114,7 @@ object EditorForm: TEditorForm
114114 Width = 149
115115 Height = 20
116116 DropDownCount = 20
117- ItemHeight = 12
117+ ItemHeight = 0
118118 TabOrder = 1
119119 OnChange = MailComboBoxChange
120120 end
@@ -383,6 +383,9 @@ object EditorForm: TEditorForm
383383 object SETTINGTXT2: TMenuItem
384384 Action = GetSETTINGTXTAction
385385 end
386+ object HeadTXT1: TMenuItem
387+ Action = GetHeadTXTAction
388+ end
386389 object OP1: TMenuItem
387390 Action = GetTitlePictureAction
388391 end
@@ -1109,6 +1112,12 @@ object EditorForm: TEditorForm
11091112 OnExecute = GetTitlePictureActionExecute
11101113 OnUpdate = GetTitlePictureActionUpdate
11111114 end
1115+ object GetHeadTXTAction: TAction
1116+ Category = #26495#24773#22577
1117+ Caption = #12525#12540#12459#12523#12523#12540#12523#12398#21462#24471
1118+ Hint = #12525#12540#12459#12523#12523#12540#12523#12398#21462#24471
1119+ OnExecute = GetHeadTXTActionExecute
1120+ end
11121121 end
11131122 object IdLogDebug: TIdLogDebug
11141123 OnReceive = IdLogDebugReceive
--- a/Editor.pas
+++ b/Editor.pas
@@ -107,6 +107,8 @@ type
107107 SETTINGTXT2: TMenuItem;
108108 GetTitlePictureAction: TAction;
109109 OP1: TMenuItem;
110+ GetHeadTXTAction: TAction;
111+ HeadTXT1: TMenuItem;
110112
111113 procedure EditorPageChange(Sender: TObject);
112114 procedure FormCreate(Sender: TObject);
@@ -151,6 +153,7 @@ type
151153 procedure GetSETTINGTXTActionExecute(Sender: TObject);
152154 procedure GetTitlePictureActionUpdate(Sender: TObject);
153155 procedure GetTitlePictureActionExecute(Sender: TObject);
156+ procedure GetHeadTXTActionExecute(Sender: TObject);
154157 private
155158 FThreadItem: TThreadItem;
156159 FBoard: TBoard;
@@ -387,7 +390,7 @@ begin
387390 MailComboBox.Text := FBoard.KotehanMail;
388391 SageCheckBox.Checked := AnsiPos('sage', MailComboBox.Text) <> 0;
389392 TitlePanel.Visible := True;
390- SetSamba24('');
393+ SetSamba24(FBoard.URL);
391394 ShowBoardInformation(FBoard, BoardInformationMemo);
392395 ShowTitlePicture();
393396 end;
@@ -407,8 +410,11 @@ end;
407410
408411 function TEditorForm.GetBody : string;
409412 var
410- body : string;
411- regexp : TAWKStr;
413+ body, tmp : string;
414+ p, tail : PChar;
415+ len : Integer;
416+const
417+ TAB_LENGTH = 4;
412418 begin
413419
414420 body := BodyEdit.Text;
@@ -416,16 +422,65 @@ begin
416422 // & の置換は一番最初にやること
417423 body := CustomStringReplace( body, '&', '&amp;' );
418424 if SpaceToNBSPAction.Checked then begin
419- body := CustomStringReplace( body, #09, '&nbsp;&nbsp;&nbsp;&nbsp;' );
420- body := CustomStringReplace( body, ' ', '&nbsp;&nbsp;' );
421- body := CustomStringReplace( body, '&nbsp; ', '&nbsp;&nbsp;' );
422- regexp := TAWKStr.Create( nil );
423- try
424- regexp.RegExp := '^ ';
425- regexp.GSub( '\&nbsp;', body );
426- finally
427- regexp.Free;
425+ p := PChar( body );
426+ tail := p + Length( body );
427+ len := 0;
428+ while p < tail do begin
429+ case p^ of
430+ #09:
431+ begin
432+ Inc( p );
433+ repeat
434+ Inc( len );
435+ tmp := tmp + '&nbsp;';
436+ until (len mod TAB_LENGTH) = 0;
437+ end;
438+
439+ #10, #13:
440+ begin
441+ tmp := tmp + p^; Inc( p );
442+ len := 0;
443+ end;
444+
445+ ' ':
446+ begin
447+ tmp := tmp + '&nbsp;';
448+ Inc( p );
449+ Inc( len );
450+ end;
451+
452+ '&':
453+ // 実体参照は 1 文字分
454+ begin
455+ tmp := tmp + '&';
456+ Inc( p );
457+ Inc( len );
458+ while p < tail do begin
459+ if p^ in ['a'..'z', 'A'..'Z', '0'..'9', '#'] then begin
460+ tmp := tmp + p^;
461+ end else if p^ = ';' then begin
462+ tmp := tmp + p^;
463+ Inc( p );
464+ Break;
465+ end else begin
466+ Break;
467+ end;
468+ Inc( p );
469+ end;
470+ end;
471+
472+ else
473+ if p^ in kYofKanji then begin
474+ tmp := tmp + p^; Inc( p );
475+ tmp := tmp + p^; Inc( p );
476+ len := len + 2;
477+ end else begin
478+ tmp := tmp + p^; Inc( p );
479+ Inc( len );
480+ end;
481+ end;
428482 end;
483+ body := tmp;
429484 end;
430485
431486 Result := body;
@@ -1619,7 +1674,7 @@ begin
16191674 tmpBoard := FBoard
16201675 else
16211676 tmpBoard := FThreadItem.ParentBoard;
1622-
1677+
16231678 Indy.Request.Referer := tmpBoard.URL;
16241679 if tmpBoard.TitlePictureURL <> '' then begin
16251680 StatusBar.Panels[0].Text := '板トップ画像ダウンロード中';
@@ -1674,4 +1729,65 @@ begin
16741729 end;
16751730 end;
16761731
1732+procedure TEditorForm.GetHeadTXTActionExecute(Sender: TObject);
1733+var
1734+ URL, RefURL: string;
1735+ settingBody: TStringList;
1736+ tmpBoard: TBoard;
1737+
1738+begin
1739+ InitIdHTTP(Indy);
1740+ if FThreadItem = nil then
1741+ tmpBoard := FBoard
1742+ else
1743+ tmpBoard := FThreadItem.ParentBoard;
1744+
1745+ if tmpBoard = nil then Exit;
1746+
1747+ RefURL := tmpBoard.URL;
1748+ if RefURL[Length(RefURL)] <> '/' then
1749+ URL := RefURL + '/' + 'head.txt'
1750+ else
1751+ URL := RefURL + 'head.txt';
1752+
1753+ if FileExists(tmpBoard.GETHEADTXTFileName) then
1754+ Indy.Request.LastModified := tmpBoard.HEADTXTTime
1755+ else
1756+ Indy.Request.LastModified := ZERO_DATE;
1757+
1758+ Indy.Request.Referer := RefURL;
1759+ Screen.Cursor := crHourGlass;
1760+ settingBody := TStringList.Create;
1761+ try
1762+ StatusBar.Panels[0].Text := 'ローカルルール(head.txt)ダウンロード中';
1763+ try
1764+ settingBody.Text := Indy.Get(URL);
1765+ if( Indy.ResponseCode = 200 ) then begin
1766+ settingBody.Insert(0, '<HTML lang="ja"><HEAD>');
1767+ settingBody.Insert(1, '<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">');
1768+ settingBody.Insert(2, '<TITLE>' + tmpBoard.Title + '</TITLE>');
1769+ settingBody.Insert(3, '<base href="' + RefURL + '"></HEAD><BODY>');
1770+ settingBody.Add('</BODY></HTML>');
1771+ settingBody.SaveToFile(tmpBoard.GETHEADTXTFileName);
1772+ tmpBoard.HEADTXTTime := Indy.Response.LastModified;
1773+ tmpBoard.IsHEADTXT := true;
1774+ tmpBoard.Modified := true;
1775+ StatusBar.Panels[0].Text := 'ローカルルール取得完了(' + IntToStr(Indy.ResponseCode) + ')';
1776+ end;
1777+ except
1778+ on E: EIdException do begin
1779+ if( AnsiPos('304', E.Message) > 0 ) then
1780+ StatusBar.Panels[0].Text := 'ローカルルール更新無し(' + IntToStr(Indy.ResponseCode) + ')'
1781+ else
1782+ StatusBar.Panels[0].Text := 'ローカルルール取得エラー(' + IntToStr(Indy.ResponseCode) + ')';
1783+ end;
1784+ end;
1785+ finally
1786+ settingBody.Free;
1787+ Screen.Cursor := crDefault;
1788+ end;
1789+ if tmpBoard.IsHEADTXT then
1790+ GikoSys.OpenBrowser(tmpBoard.GETHEADTXTFileName, gbtUserApp);
1791+end;
1792+
16771793 end.
--- a/ExternalBoardPlugInMain.pas
+++ b/ExternalBoardPlugInMain.pas
@@ -229,7 +229,8 @@ var
229229 // httpSocket : TIdHTTP;
230230 resStream : TMemoryStream;
231231 content : string;
232-
232+const
233+ LIVEDOOR_URL = 'http://jbbs.livedoor.jp/';
233234 begin
234235
235236 {$IFDEF DEBUG}
@@ -270,7 +271,12 @@ begin
270271 Result := socket.ResponseCode;
271272 if (Length( content ) = 0) and (Result = 206) then
272273 Result := 304;
273-
274+ //したらばJBBSはヘッダにエラー情報が載るらしいので、ここでチェック
275+ if ( AnsiPos(LIVEDOOR_URL, inURL) > 0 ) and (Result = 200) then begin
276+ if( AnsiPos('STORAGE IN', socket.Response.RawHeaders.Text) > 0 ) then begin
277+ Result := 302;
278+ end;
279+ end;
274280 outResultData := CreateResultString( content );
275281 except
276282 on E: EIdSocketError do begin
--- a/Favorite.pas
+++ b/Favorite.pas
@@ -117,13 +117,50 @@ function TFavoriteBoardItem.GetItem : TBoard;
117117 var
118118 protocol, host, path, document, port, bookmark : string;
119119 BBSID{, BBSKey} : string;
120- tmpURL : string;
120+ tmpURL, boardURL : string;
121121 // category : TCategory;
122+ i, bi: Integer;
123+ tmpThread: TThreadItem;
124+ tmpBoard: TBoard;
122125 begin
123126
124127 if FItem = nil then begin
125128 FItem := BBSsFindBoardFromURL( URL );
126129 if FItem = nil then begin
130+ //===== プラグイン
131+ try
132+ //作業中//
133+ bi := High( BoardPlugIns );
134+ for i := Low( BoardPlugIns ) to bi do begin
135+ if Assigned( Pointer( BoardPlugIns[ i ].Module ) ) then begin
136+ case BoardPlugIns[ i ].AcceptURL( URL ) of
137+ atThread:
138+ begin
139+ tmpThread := TThreadItem.Create( BoardPlugIns[ i ], URL );
140+ boardURL := tmpThread.BoardPlugIn.GetBoardURL( DWORD( tmpThread ) );
141+ FItem := BBSsFindBoardFromURL( boardURL );
142+ URL := FItem.URL;
143+ tmpThread.Free;
144+ break;
145+ end;
146+ atBoard:
147+ begin
148+ tmpBoard := TBoard.Create(BoardPlugIns[ i ], URL);
149+ FItem := BBSsFindBoardFromURL( tmpBoard.URL );
150+ tmpBoard.Free;
151+ if FItem <> nil then begin
152+ URL := FItem.URL;
153+ end;
154+ break;
155+ end;
156+ end;
157+ end;
158+ end;
159+ except
160+ // exception が発生した場合は内部処理に任せたいのでここでは何もしない
161+ end;
162+ end;
163+ if FItem = nil then begin
127164 tmpURL := URL;
128165 GikoSys.ParseURI( tmpURL, protocol, host, path, document, port, bookmark );
129166 if GikoSys.Is2chHost( host ) then begin
@@ -131,12 +168,6 @@ begin
131168 FItem := BBSs[ 0 ].FindBBSID( BBSID );
132169 if FItem <> nil then
133170 URL := FItem.URL;
134- end else if AnsiPos('jbbs.shitaraba.com', host) <> 0 then begin
135- // したらばJBBSのhttp://jbbs.shitaraba.com/ → http://jbbs.livedoor.com/ 置換
136- URL := CustomStringReplace(URL, 'http://jbbs.shitaraba.com/', 'http://jbbs.livedoor.com/', false);
137- FItem := BBSsFindBoardFromURL( URL );
138- if FItem <> nil then
139- URL := FItem.URL;
140171 end;
141172 {
142173 // ※作っても、追加するカテゴリが無いので激しく保留
@@ -284,7 +315,7 @@ begin
284315 FileName := GikoSys.GetConfigDir + FAVORITE_FILE_NAME;
285316
286317 FavFolder := TFavoriteFolder.Create;
287- Node := FTreeView.Items.AddChildObject(nil, FAVORITE_ROOT_NAME, FavFolder);
318+ Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
288319 Node.ImageIndex := 14;
289320 Node.SelectedIndex := 14;
290321
@@ -300,7 +331,7 @@ begin
300331 FStack.Push(Node);
301332 LinkExists := False;
302333 if XMLNode.NodeName = 'favorite' then begin
303- for i := 0 to XMLNode.ChildNodes.Count - 1 do begin
334+ for i := XMLNode.ChildNodes.Count - 1 downto 0 do begin
304335 ReadNode(XMLNode.ChildNodes[i]);
305336 if (XMLNode.ChildNodes[i].NodeName = 'folder') and
306337 (XMLNode.ChildNodes[i].Attributes['title'] = FAVORITE_LINK_NAME) then begin
@@ -310,7 +341,7 @@ begin
310341 end;
311342 if not LinkExists then begin
312343 FavFolder := TFavoriteFolder.Create;
313- Node := FTreeView.Items.AddChildObject(Node, FAVORITE_LINK_NAME, FavFolder);
344+ Node := FTreeView.Items.AddChildObjectFirst(Node, FAVORITE_LINK_NAME, FavFolder);
314345 Node.ImageIndex := 14;
315346 Node.SelectedIndex := 14;
316347 end;
@@ -324,7 +355,7 @@ begin
324355
325356 {
326357 FavFolder := TFavoriteFolder.Create;
327- Node := FTreeView.Items.AddChildObject(nil, FAVORITE_ROOT_NAME, FavFolder);
358+ Node := FTreeView.Items.AddChildObjectFirst(nil, FAVORITE_ROOT_NAME, FavFolder);
328359 Node.ImageIndex := 12;
329360 Node.SelectedIndex := 13;
330361
@@ -360,15 +391,16 @@ begin
360391 ParentNode := FStack.Peek;
361392 if TObject(ParentNode.Data) is TFavoriteFolder then begin
362393 FavFolder := TFavoriteFolder.Create;
363- CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavFolder);
394+ CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavFolder);
364395 CurrentNode.ImageIndex := 14;
365396 CurrentNode.SelectedIndex := 14;
366- CurrentNode.Expanded := Node.Attributes[ 'expanded' ] = 'true';
367397 FStack.Push(CurrentNode);
368398 end;
369- for i := 0 to Node.ChildNodes.Count - 1 do begin
399+ for i := Node.ChildNodes.Count - 1 downto 0 do begin
370400 ReadNode(Node.ChildNodes[i]);
371401 end;
402+ if TObject(ParentNode.Data) is TFavoriteFolder then
403+ CurrentNode.Expanded := Node.Attributes[ 'expanded' ] = 'true';
372404 if FStack.Count <> 0 then
373405 FStack.Pop;
374406 end else if Node.NodeName = 'favitem' then begin
@@ -387,7 +419,7 @@ begin
387419 FavBoard := TFavoriteBoardItem.Create(
388420 Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
389421 end;
390- CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavBoard);
422+ CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavBoard);
391423 CurrentNode.ImageIndex := 15;
392424 CurrentNode.SelectedIndex := 15;
393425 end else if Node.Attributes['favtype'] = 'thread' then begin
@@ -414,7 +446,7 @@ begin
414446 FavThread := TFavoriteThreadItem.Create(
415447 Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
416448 end;
417- CurrentNode := FTreeView.Items.AddChildObject(ParentNode, Node.Attributes['title'], FavThread);
449+ CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavThread);
418450 CurrentNode.ImageIndex := 16;
419451 CurrentNode.SelectedIndex := 16;
420452 end;
--- a/Giko.dfm
+++ b/Giko.dfm
@@ -1,11 +1,11 @@
11 object GikoForm: TGikoForm
2- Left = 205
3- Top = 186
2+ Left = 246
3+ Top = 188
44 HorzScrollBar.Visible = False
55 VertScrollBar.Visible = False
66 AutoScroll = False
77 Caption = '-'
8- ClientHeight = 545
8+ ClientHeight = 404
99 ClientWidth = 854
1010 Color = clBtnFace
1111 Font.Charset = SHIFTJIS_CHARSET
@@ -16,11 +16,9 @@ object GikoForm: TGikoForm
1616 KeyPreview = True
1717 OldCreateOrder = False
1818 Visible = True
19- OnClose = FormClose
2019 OnCloseQuery = FormCloseQuery
2120 OnCreate = FormCreate
2221 OnDestroy = FormDestroy
23- OnKeyUp = FormKeyUp
2422 OnMouseWheel = FormMouseWheel
2523 OnResize = FormResize
2624 OnShortCut = FormShortCut
@@ -29,7 +27,7 @@ object GikoForm: TGikoForm
2927 TextHeight = 12
3028 object StatusBar: TStatusBar
3129 Left = 0
32- Top = 525
30+ Top = 384
3331 Width = 854
3432 Height = 20
3533 Panels = <
@@ -40,11 +38,7 @@ object GikoForm: TGikoForm
4038 Width = 500
4139 end
4240 item
43- Style = psOwnerDraw
4441 Width = 50
45- end
46- item
47- Width = 100
4842 end>
4943 SimplePanel = False
5044 OnResize = StatusBarResize
@@ -53,13 +47,13 @@ object GikoForm: TGikoForm
5347 Left = 0
5448 Top = 77
5549 Width = 854
56- Height = 448
50+ Height = 307
5751 Align = alClient
5852 BevelOuter = bvNone
5953 TabOrder = 1
6054 object MessageSplitter: TSplitter
6155 Left = 0
62- Top = 409
56+ Top = 268
6357 Width = 854
6458 Height = 5
6559 Cursor = crVSplit
@@ -72,7 +66,7 @@ object GikoForm: TGikoForm
7266 Left = 0
7367 Top = 0
7468 Width = 854
75- Height = 409
69+ Height = 268
7670 Align = alClient
7771 BevelOuter = bvNone
7872 TabOrder = 0
@@ -80,7 +74,7 @@ object GikoForm: TGikoForm
8074 Left = 145
8175 Top = 0
8276 Width = 5
83- Height = 409
77+ Height = 268
8478 Cursor = crHSplit
8579 AutoSnap = False
8680 ResizeStyle = rsUpdate
@@ -89,7 +83,7 @@ object GikoForm: TGikoForm
8983 Left = 0
9084 Top = 0
9185 Width = 145
92- Height = 409
86+ Height = 268
9387 Align = alLeft
9488 BevelOuter = bvNone
9589 TabOrder = 0
@@ -276,7 +270,7 @@ object GikoForm: TGikoForm
276270 Left = 150
277271 Top = 0
278272 Width = 704
279- Height = 409
273+ Height = 268
280274 Align = alClient
281275 BevelOuter = bvNone
282276 TabOrder = 1
@@ -315,13 +309,13 @@ object GikoForm: TGikoForm
315309 OwnerData = True
316310 ReadOnly = True
317311 RowSelect = True
318- PopupMenu = ListPopupMenu
319312 SmallImages = ItemIcon16
320313 StateImages = StateIconImageList
321314 TabOrder = 0
322315 ViewStyle = vsReport
323316 OnAdvancedCustomDrawItem = ListViewAdvancedCustomDrawItem
324317 OnColumnClick = ListViewColumnClick
318+ OnColumnRightClick = ListViewColumnRightClick
325319 OnCustomDraw = ListViewCustomDraw
326320 OnData = ListViewData
327321 OnDataFind = ListViewDataFind
@@ -554,7 +548,7 @@ object GikoForm: TGikoForm
554548 Left = 0
555549 Top = 194
556550 Width = 704
557- Height = 215
551+ Height = 74
558552 Align = alClient
559553 BevelOuter = bvNone
560554 TabOrder = 1
@@ -562,7 +556,7 @@ object GikoForm: TGikoForm
562556 Left = 0
563557 Top = 46
564558 Width = 704
565- Height = 149
559+ Height = 8
566560 Align = alClient
567561 BevelOuter = bvNone
568562 UseDockManager = False
@@ -572,7 +566,7 @@ object GikoForm: TGikoForm
572566 Left = 0
573567 Top = 0
574568 Width = 704
575- Height = 149
569+ Height = 8
576570 Align = alClient
577571 TabOrder = 0
578572 OnEnter = BrowserEnter
@@ -581,7 +575,7 @@ object GikoForm: TGikoForm
581575 OnNewWindow2 = BrowserNewWindow2
582576 OnDocumentComplete = BrowserDocumentComplete
583577 ControlData = {
584- 4C000000C3480000660F00000000000000000000000000000000000000000000
578+ 4C000000C3480000D40000000000000000000000000000000000000000000000
585579 000000004C000000000000000000000001000000E0D057007335CF11AE690800
586580 2B2E12620A000000000000004C0000000114020000000000C000000000000046
587581 8000000000000000000000000000000000000000000000000000000000000000
@@ -590,7 +584,7 @@ object GikoForm: TGikoForm
590584 end
591585 object BrowserBottomPanel: TGikoPanel
592586 Left = 0
593- Top = 195
587+ Top = 54
594588 Width = 704
595589 Height = 20
596590 Align = alBottom
@@ -868,7 +862,7 @@ object GikoForm: TGikoForm
868862 end
869863 object MessagePanel: TPanel
870864 Left = 0
871- Top = 414
865+ Top = 273
872866 Width = 854
873867 Height = 34
874868 Align = alBottom
@@ -6015,7 +6009,7 @@ object GikoForm: TGikoForm
60156009 end
60166010 object ActionList: TActionList
60176011 Images = ToobarImageList
6018- Left = 8
6012+ Left = 5
60196013 Top = 372
60206014 object OnlyAHundredResAction: TAction
60216015 Category = #12473#12524#12483#12489
@@ -7032,8 +7026,8 @@ object GikoForm: TGikoForm
70327026 end
70337027 object LogFolderOpenAction: TAction
70347028 Category = #26495
7035- Caption = 'Explore'#12391'Log'#12501#12457#12523#12480#12434#38283#12367
7036- Hint = 'Explore'#12391'Log'#12501#12457#12523#12480#12434#38283#12367
7029+ Caption = 'Explorer'#12391'Log'#12501#12457#12523#12480#12434#38283#12367
7030+ Hint = 'Explorer'#12391'Log'#12501#12457#12523#12480#12434#38283#12367
70377031 OnExecute = LogFolderOpenActionExecute
70387032 OnUpdate = LogFolderOpenActionUpdate
70397033 end
@@ -7071,6 +7065,20 @@ object GikoForm: TGikoForm
70717065 Hint = #12479#12502#12398#38918#30058#12434#33258#21205#24489#20803
70727066 OnExecute = TabAutoLoadActionExecute
70737067 end
7068+ object JumpToNumOfResAction: TAction
7069+ Category = #12473#12524#12483#12489
7070+ Caption = #25351#23450#12375#12383#30058#21495#12398#12524#12473#12395#39131#12406
7071+ Hint = #25351#23450#12375#12383#30058#21495#12398#12524#12473#12395#39131#12406
7072+ ShortCut = 16455
7073+ OnExecute = JumpToNumOfResActionExecute
7074+ OnUpdate = JumpToNumOfResActionUpdate
7075+ end
7076+ object FavoriteTreeViewCollapseAction: TAction
7077+ Category = #12362#27671#12395#20837#12426
7078+ Caption = #12362#27671#12395#20837#12426#12484#12522#12540#12434#12377#12409#12390#38281#12376#12427
7079+ Hint = #12362#27671#12395#20837#12426#12484#12522#12540#12434#12377#12409#12390#38281#12376#12427
7080+ OnExecute = FavoriteTreeViewCollapseActionExecute
7081+ end
70747082 end
70757083 object BrowserPopupMenu: TPopupMenu
70767084 Left = 68
@@ -7566,4 +7574,8 @@ object GikoForm: TGikoForm
75667574 AutoCheck = True
75677575 end
75687576 end
7577+ object ListColumnPopupMenu: TPopupMenu
7578+ Left = 37
7579+ Top = 403
7580+ end
75697581 end
--- a/Giko.pas
+++ b/Giko.pas
@@ -28,6 +28,7 @@ type
2828 TGikoTreeType = (gttNone, gtt2ch, gttHistory, gttFavorite);
2929 TToolBarSettingSenderType = (tssNone, tssMain, tssList, tssBrowser);
3030 TMinimizeType = (mtNone, mtMinimizing, mtMinimized);
31+ TResizeType = (rtNone, rtResizing);
3132
3233 TBrowserRecord = class;
3334
@@ -527,7 +528,7 @@ type
527528 N65: TMenuItem;
528529 BBSSelectPopupMenu: TPopupMenu;
529530 PlugInMenu: TMenuItem;
530- TmpToolBar: TToolBar;
531+ TmpToolBar: TToolBar;
531532 TreeSelectNameCopy: TAction;
532533 TreeSelectNamePupupMenu: TMenuItem;
533534 BrowserPanel: TPanel;
@@ -550,7 +551,7 @@ type
550551 OpenLogFolder: TMenuItem;
551552 Browser: TWebBrowser;
552553 TabSave: TMenuItem;
553- TabOpen: TMenuItem;
554+ TabOpen: TMenuItem;
554555 TabsSaveAction: TAction;
555556 TabsOpenAction: TAction;
556557 ResRangePopupMenu: TPopupMenu;
@@ -573,12 +574,14 @@ type
573574 N69: TMenuItem;
574575 S7: TMenuItem;
575576 ThreadRangeButton: TToolButton;
576- TabAutoSaveAction: TAction;
577+ TabAutoSaveAction: TAction;
577578 TabAutoLoadAction: TAction;
579+ ListColumnPopupMenu: TPopupMenu;
580+ JumpToNumOfResAction: TAction;
581+ FavoriteTreeViewCollapseAction: TAction;
578582 procedure FormCreate(Sender: TObject);
579583 procedure FormDestroy(Sender: TObject);
580584 procedure CabinetPanelHide(Sender: TObject);
581- procedure FormClose(Sender: TObject; var Action: TCloseAction);
582585 procedure ListViewData(Sender: TObject; Item: TListItem);
583586 procedure ListViewDataFind(Sender: TObject; Find: TItemFind;
584587 const FindString: String; const FindPosition: TPoint;
@@ -806,8 +809,6 @@ type
806809 procedure SelectComboBoxExit(Sender: TObject);
807810 procedure SelectResActionExecute(Sender: TObject);
808811 procedure SelectResActionUpdate(Sender: TObject);
809- procedure FormKeyUp(Sender: TObject; var Key: Word;
810- Shift: TShiftState);
811812 procedure AllResActionExecute(Sender: TObject);
812813 procedure AllResActionUpdate(Sender: TObject);
813814 procedure ReloadClick(Sender: TObject);
@@ -872,7 +873,7 @@ type
872873 var Handled: Boolean);
873874 procedure KoreCopyExecute(Sender: TObject);
874875 procedure BrowserTabPopupMenuPopup(Sender: TObject);
875- procedure MenuToolBarResize(Sender: TObject);
876+ procedure MenuToolBarResize(Sender: TObject);
876877 procedure StdToolBarResize(Sender: TObject);
877878 procedure LinkToolBarResize(Sender: TObject);
878879 procedure ListNameToolBarResize(Sender: TObject);
@@ -895,7 +896,7 @@ type
895896 procedure SetFocusForBrowserActionUpdate(Sender: TObject);
896897 procedure SetFocusForThreadListActionExecute(Sender: TObject);
897898 procedure SetFocusForCabinetActionExecute(Sender: TObject);
898- procedure BrowserMaxAndFocusActionExecute(Sender: TObject);
899+ procedure BrowserMaxAndFocusActionExecute(Sender: TObject);
899900 procedure BrowserMaxAndFocusActionUpdate(Sender: TObject);
900901 procedure ThreadlistMaxAndFocusActionExecute(Sender: TObject);
901902 procedure ListViewExit(Sender: TObject);
@@ -918,13 +919,18 @@ type
918919 procedure OnlyAHundredResActionExecute(Sender: TObject);
919920 procedure OnlyKokoResActionExecute(Sender: TObject);
920921 procedure OnlyNewResActionExecute(Sender: TObject);
921- procedure BrowsBoradHeadActionExecute(Sender: TObject);
922+ procedure BrowsBoradHeadActionExecute(Sender: TObject);
922923 procedure BrowsBoradHeadActionUpdate(Sender: TObject);
923924 procedure EditNGActionExecute(Sender: TObject);
924925 procedure ThreadRangeActionUpdate(Sender: TObject);
925926 procedure ThreadRangeActionExecute(Sender: TObject);
926- procedure TabAutoSaveActionExecute(Sender: TObject);
927+ procedure TabAutoSaveActionExecute(Sender: TObject);
927928 procedure TabAutoLoadActionExecute(Sender: TObject);
929+ procedure ListViewColumnRightClick(Sender: TObject;
930+ Column: TListColumn; Point: TPoint);
931+ procedure JumpToNumOfResActionExecute(Sender: TObject);
932+ procedure JumpToNumOfResActionUpdate(Sender: TObject);
933+ procedure FavoriteTreeViewCollapseActionExecute(Sender: TObject);
928934 private
929935 { Private 宣言 }
930936 //RoundList : TRoundList;
@@ -972,22 +978,24 @@ type
972978
973979 FDropSpaceNode: TTreeNode;
974980
975- FDragTime : Cardinal; //リンクのD&D用
976- FDragButton : TToolButton; //リンクのD&D用にDragしてるButton保存
977- FDragWFirst : Boolean; //WebTabのD&D用
981+ FDragTime : Cardinal; ///< リンクのD&D用
982+ FDragButton : TToolButton; ///< リンクのD&D用にDragしてるButton保存
983+ FDragWFirst : Boolean; ///< WebTabのD&D用
978984
979- FListViewBackGroundColor : TColor; //ListViewのBackGroundColor
980- FUseOddResOddColor : Boolean; //取得レス数とスレッドのレス数が違ったときに他の色で表示
981- FOddColor : TColor; //その色
985+ FListViewBackGroundColor : TColor; ///< ListViewのBackGroundColor
986+ FUseOddResOddColor : Boolean; ///< 取得レス数とスレッドのレス数が違ったときに他の色で表示
987+ FOddColor : TColor; ///< その色
982988
983- FSelectResWord : string; // レス絞込ワード
984- FIsIgnoreResize : Boolean; // リサイズイベントを無視するかどうか
985- FIsMinimize : TMinimizeType; // 最小化している最中か
986- FOldFormWidth : Integer; // 直前のウィンドウの幅
987- FToolBarSettingSender : TToolBarSettingSenderType; // ツールバー設定をクリックしたクールバー
988- FMouseDownPos : TPoint; // ブラウザタブでマウスを押したときの座標
989+ FSelectResWord : string; ///< レス絞込ワード
990+ FIsIgnoreResize : TResizeType; ///< リサイズイベントを無視するかどうか
991+ FIsMinimize : TMinimizeType; ///< 最小化している最中か
992+ FOldFormWidth : Integer; ///< 直前のウィンドウの幅
993+ FToolBarSettingSender : TToolBarSettingSenderType; ///< ツールバー設定をクリックしたクールバー
994+ FMouseDownPos : TPoint; ///< ブラウザタブでマウスを押したときの座標
989995 FBrowsers: TList;
990- FResRangeMenuSelect : Longint; ///< ResRangeButton で選択されている項目 (フォーマットは ResRange 互換)
996+ FResRangeMenuSelect : Longint; ///< ResRangeButton で選択されている項目 (フォーマットは ResRange 互換)
997+ FStartUp : Boolean;
998+ FIsHandledWheel : Boolean; ///< 既に受け取った WM_MOUSEWHEEL かどうか
991999 procedure SetBoardTreeNode( inBBS : TBBS );
9921000 function SetCategoryListItem(ABBS2ch: TBBS): Integer;
9931001 function SetBoardListItem(Category: TCategory): Integer;
@@ -1000,7 +1008,7 @@ type
10001008 procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode; Number: Integer);
10011009 procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer; Number: Integer);
10021010
1003- procedure SetActiveList(Obj: TObject);
1011+
10041012 procedure ListClick;
10051013 procedure ListDoubleClick(Shift: TShiftState);
10061014 procedure BrowserMovement(const AName: string); overload;
@@ -1051,37 +1059,41 @@ type
10511059 procedure BBSMenuItemOnClick( Sender : TObject );
10521060 //
10531061 procedure KonoresCopy(Number: Integer; ReplaceTag : Boolean);
1054- // CoolBar の設定を変数に保存
1062+ /// CoolBar の設定を変数に保存
10551063 procedure SaveCoolBarSettings;
1056- // CoolBar の設定を変数から復元
1064+ /// CoolBar の設定を変数から復元
10571065 procedure LoadCoolBarSettings;
1058- // 最小化される
1066+ /// 最小化される
10591067 procedure OnMinimize;
1060- // 最小化された
1068+ /// 最小化された
10611069 procedure OnMinimized;
1062- // CoolBar がサイズ変更された
1070+ /// CoolBar がサイズ変更された
10631071 procedure CoolBarResized(Sender: TObject; CoolBar: TCoolBar);
1064- // TreeView がクリックされた
1072+ /// TreeView がクリックされた
10651073 procedure TreeClick( Node : TTreeNode );
1066- // TreeView がダブルクリックされた
1074+ /// TreeView がダブルクリックされた
10671075 procedure TreeDoubleClick( Node : TTreeNode );
1068- // ギコナビのメッセージループを横取りします
1076+ /// ギコナビのメッセージループを横取りします
10691077 procedure HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
1070- // ブラウザのキーダウンイベント
1071- // イベントを取り扱った場合は True を返す
1078+ /// ブラウザのキーダウンイベント
1079+ /// イベントを取り扱った場合は True を返す
10721080 function BrowserKeydown(var Msg: TMsg; Key: Word; State:TShiftState) : Boolean;
1073- // 各所にあるキャビネット・ BBS メニューをセット/更新
1081+ /// 各所にあるキャビネット・ BBS メニューをセット/更新
10741082 procedure SetBBSMenu;
10751083 function WebBrowserClick(Sender: TObject): WordBool;
10761084 procedure SkinorCSSFilesCopy(path: string);
1077- // タブ取得
1085+ /// タブ取得
10781086 function GetTabURLs(AStringList: TStringList) : Boolean;
1079- // タブ保存
1087+ /// タブ保存
10801088 function SaveTabURLs : Boolean;
1081- // タブ読み出し
1089+ /// タブ読み出し
10821090 function LoadTabURLs : Boolean;
1083- // バンド幅を再計算・再設定する
1091+ /// バンド幅を再計算・再設定する
10841092 procedure ResetBandInfo( bar : TGikoCoolBar; band : TToolBar );
1093+ /// ListView の Column を真のカラムに変換
1094+ function ActiveListTrueColumn( column : TListColumn ) : TListColumn;
1095+ /// ListColumnPopupMenu アイテムのクリックイベント
1096+ procedure ListColumnPopupMenuOnClick( Sender : TObject );
10851097 protected
10861098 procedure CreateParams(var Params: TCreateParams); override;
10871099 procedure WndProc(var Message: TMessage); override;
@@ -1093,8 +1105,11 @@ type
10931105 { Public 宣言 }
10941106 // FDownload: TDownload;
10951107 FControlThread: TThreadControl;
1096- procedure MoveToURL(URL: string);
1097- procedure InsertBrowserTab(ThreadItem: TThreadItem; ActiveTab: Boolean = True);
1108+ procedure MoveToURL(const inURL: string);
1109+ function InsertBrowserTab(
1110+ ThreadItem : TThreadItem;
1111+ ActiveTab : Boolean = True
1112+ ) : TBrowserRecord;
10981113 procedure ReloadBBS;
10991114 function GetHttpState: Boolean;
11001115 procedure SetEnabledCloseButton(Enabled: Boolean);
@@ -1114,7 +1129,7 @@ type
11141129 function GetActiveContent: TThreadItem;
11151130 function GetActiveList: TObject;
11161131
1117- property ActiveList: TObject read GetActiveList write SetActiveList;
1132+
11181133 // property LastRoundTime: TDateTime read FLastRoundTime write FLastRoundTime;
11191134
11201135 procedure SetListViewType(AViewType: TGikoViewType); overload;
@@ -1138,16 +1153,19 @@ type
11381153 // property Favorite: TFavorite read FFavorite write FFavorite;
11391154 procedure SetToolBarPopup;
11401155 procedure ShowFavoriteAddDialog( Item : TObject );
1141- procedure FavoritesURLReplace(oldURLs: TStringList; newURLs: TStringList);
1142- procedure RoundListURLReplace(oldURLs: TStringList; newURLs: TStringList);
1156+ procedure FavoritesURLReplace(oldURLs: TStringList; newURLs: TStringList);
1157+ procedure RoundListURLReplace(oldURLs: TStringList; newURLs: TStringList);
11431158 property ListViewBackGroundColor: TColor read FListViewBackGroundColor write SetListViewBackGroundColor;
11441159 property UseOddResOddColor : Boolean read FUseOddResOddColor write FUseOddResOddColor;
11451160 property OddColor : TColor read FOddColor write FOddColor;
11461161
11471162 function FindToolBarButton( bar : TToolBar; action : TAction ) : TToolButton;
11481163 procedure OnPlugInMenuItem( Sender : TObject );
1149- procedure TabFileURLReplace(oldURLs: TStringList; newURLs: TStringList);
1150-
1164+ procedure TabFileURLReplace(oldURLs: TStringList; newURLs: TStringList);
1165+ /// ListView のカラム幅および位置の保存 KuroutSettingからよびだしたいので
1166+ procedure ActiveListColumnSave;
1167+ procedure SetActiveList(Obj: TObject);
1168+ property ActiveList: TObject read GetActiveList write SetActiveList;
11511169 published
11521170 property EnabledCloseButton: Boolean read FEnabledCloseButton write SetEnabledCloseButton;
11531171 end;
@@ -1176,18 +1194,18 @@ type
11761194 TBrowserRecord = class( TObject )
11771195 private
11781196 FBrowser : TWebBrowser;
1179- FEvent: THTMLDocumentEventSink;//ブラウザドキュメントイベント
1197+ FEvent: THTMLDocumentEventSink; //!< ブラウザドキュメントイベント
11801198 FThread : TThreadItem;
11811199 FLastSize : Integer;
11821200 FRepaint : Boolean;
1183- // FOnlyHundred: Boolean;
1201+ FMovement : string; //!< スクロール先アンカー
11841202 public
11851203 destructor Destroy; override;
11861204 property Browser : TWebBrowser read FBrowser write FBrowser;
11871205 property Thread : TThreadItem read FThread write FThread;
11881206 property LastSize : Integer read FLastSize write FLastSize;
11891207 property Repaint : Boolean read FRepaint write FRepaint;
1190-// property OnlyHundred : Boolean read FOnlyHundred write FOnlyHundred;
1208+ property Movement : string read FMovement write FMovement;
11911209 end;
11921210
11931211 var
@@ -1248,6 +1266,7 @@ const
12481266 USER_RESIZED = WM_USER + 2001;
12491267 USER_MINIMIZED = WM_USER + 2002;
12501268 USER_SETLINKBAR = WM_USER + 2003;
1269+ USER_DOCUMENTCOMPLETE = WM_USER + 2004; ///< wParam : TWebBrowser
12511270 SELECTTIME_INTERBAL = 110;
12521271
12531272 BROWSER_COUNT = 5; //ブラウザの数
@@ -1285,11 +1304,12 @@ begin
12851304 Writeln(' 終了時は、ギコナビウィンドウを閉じてください');
12861305 Writeln('============================================================');
12871306 {$ENDIF}
1307+ FStartUp := false;
12881308 Application.OnDeactivate := AppFormDeactivate;
12891309 Self.OnDeactivate := AppFormDeactivate;
12901310 Application.HookMainWindow(Hook);
12911311 Application.OnMessage := HandleAppMessage; //なんか無くても大丈夫になった by もじゅ
1292- Self.DoubleBuffered := true;
1312+// Self.DoubleBuffered := true;
12931313 FTreeType := gttNone;
12941314
12951315 FSearchDialog := nil;
@@ -1304,13 +1324,14 @@ begin
13041324 newBrowser.Align := alNone;
13051325 newBrowser.Left := 0;
13061326 newBrowser.Top := 0;
1307- //newBrowser.DoubleBuffered := true;
1327+ newBrowser.StatusBar := false;
1328+ newBrowser.MenuBar := false;
1329+ newBrowser.AddressBar := false;
13081330 newBrowser.OnDocumentComplete := BrowserDocumentComplete;
13091331 newBrowser.OnBeforeNavigate2 := BrowserBeforeNavigate2;
13101332 newBrowser.OnEnter := BrowserEnter;
13111333 newBrowser.OnNewWindow2 := BrowserNewWindow2;
13121334 newBrowser.OnStatusTextChange := BrowserStatusTextChange;
1313- //newBrowser.OnTitleChange := BrowserTitleChange;
13141335 newBrowser.Navigate(BLANK_HTML);
13151336 ShowWindow(newBrowser.Handle, SW_HIDE);
13161337
@@ -1319,7 +1340,7 @@ begin
13191340 ShowWindow(BrowserNullTab.Browser.Handle, SW_SHOW);
13201341
13211342 // 起動時に保存されてしまう対策
1322- FIsIgnoreResize := True;
1343+ FIsIgnoreResize := rtResizing;
13231344
13241345 //手のカーソル
13251346 Screen.Cursors[5] := LoadCursor(HInstance, 'GIKOHAND');
@@ -1328,38 +1349,8 @@ begin
13281349 //アドレス履歴読み込み
13291350 AddressHistoryDM.ReadHistory(AddressComboBox.Items, GikoSys.Setting.AddressHistoryCount);
13301351
1331- // 外部板プラグインをロード(ReadBoardFile, LoadHistory より先に行うこと)
1332- InitializeBoardPlugIns;
1333-
13341352 EnabledCloseButton := True;
13351353
1336-
1337- //巡回データ読み込み
1338- RoundList := TRoundList.Create;
1339- RoundList.LoadRoundBoardFile;
1340-
1341- // ボードファイル列挙(ReadFavorite より先に行うこと)
1342- GikoSys.ListBoardFile;
1343-
1344- RoundList.LoadRoundThreadFile;
1345-
1346- if RoundList.OldFileRead or ( RoundList.Count[grtItem] > 0 ) then
1347- GikoSys.ListBoardFile;
1348-
1349- // メニューに追加
1350- SetBBSMenu;
1351-
1352- // ヒストリリスト(LoadHistory よりも先に行うこと)
1353- FHistoryList := TList.Create;
1354-
1355- // 履歴読み込み
1356- LoadHistory;
1357-
1358- //お気に入り読み込み
1359-// FFavorite := TFavorite.Create(FavoriteTreeView);
1360- FavoriteDM.SetFavTreeView(FavoriteTreeView);
1361- FavoriteDM.ReadFavorite;
1362-
13631354 //リストスタイル
13641355 ListView.ViewStyle := GikoSys.Setting.ListStyle;
13651356
@@ -1403,8 +1394,8 @@ begin
14031394 ListView.Font.Name := GikoSys.Setting.ListFontName;
14041395 ListView.Font.Size := GikoSys.Setting.ListFontSize;
14051396 ListView.Font.Color := GikoSys.Setting.ListFontColor;
1406- //ListView.Color := GikoSys.Setting.ListBackColor;
1407- ListViewBackGroundColor := GikoSys.Setting.ListBackColor;
1397+ ListViewBackGroundColor := clWhite; // デフォルトに設定したのち
1398+ ListViewBackGroundColor := GikoSys.Setting.ListBackColor; // ユーザ定義に変更
14081399 FUseOddResOddColor := GikoSys.Setting.UseOddColorOddResNum;
14091400 FOddColor := GikoSys.Setting.OddColor;
14101401
@@ -1472,6 +1463,35 @@ begin
14721463 FBrowserSizeHeight := GikoSys.Setting.ListHeight;
14731464 FBrowserSizeWidth := GikoSys.Setting.ListWidth;
14741465
1466+ // 外部板プラグインをロード(ReadBoardFile, LoadHistory より先に行うこと)
1467+ InitializeBoardPlugIns;
1468+
1469+ //巡回データ読み込み
1470+ RoundList := TRoundList.Create;
1471+ RoundList.LoadRoundBoardFile;
1472+
1473+ // ボードファイル列挙(ReadFavorite より先に行うこと)
1474+ GikoSys.ListBoardFile;
1475+
1476+ RoundList.LoadRoundThreadFile;
1477+
1478+ if RoundList.OldFileRead or ( RoundList.Count[grtItem] > 0 ) then
1479+ GikoSys.ListBoardFile;
1480+
1481+ // メニューに追加
1482+ SetBBSMenu;
1483+
1484+ // ヒストリリスト(LoadHistory よりも先に行うこと)
1485+ FHistoryList := TList.Create;
1486+
1487+ // 履歴読み込み
1488+ LoadHistory;
1489+
1490+ //お気に入り読み込み
1491+// FFavorite := TFavorite.Create(FavoriteTreeView);
1492+ FavoriteDM.SetFavTreeView(FavoriteTreeView);
1493+ FavoriteDM.ReadFavorite;
1494+
14751495 ArrangeAction.Checked := not (GikoSys.Setting.ListOrientation = gloVertical);
14761496 ArrangeAction.Execute;
14771497
@@ -1668,7 +1688,7 @@ begin
16681688 if GikoSys.Setting.CabinetIndex < Length( BBSs ) then
16691689 ShowBBSTree( BBSs[ GikoSys.Setting.CabinetIndex ] );
16701690 // 起動時に保存されてしまう対策 2
1671- FIsIgnoreResize := True;
1691+ FIsIgnoreResize := rtResizing;
16721692 CabinetBBSAction.Execute;
16731693 end;
16741694 end else begin
@@ -1677,7 +1697,7 @@ begin
16771697 end;
16781698
16791699 // 起動時に保存されてしまう対策 3
1680- FIsIgnoreResize := True;
1700+ FIsIgnoreResize := rtResizing;
16811701
16821702 //オートログイン
16831703 if GikoSys.Setting.AutoLogin then
@@ -1701,7 +1721,7 @@ begin
17011721 //Samba24のファイルチェック
17021722 GikoSys.SambaFileExists();
17031723
1704- //タブ自動読み込み (AV発生のため一時封印)
1724+ //にちゃん語ファイル読み出し
17051725 end;
17061726
17071727 // CoolBar の設定を変数に保存
@@ -1711,7 +1731,7 @@ var
17111731 CoolSet : TCoolSet;
17121732 begin
17131733
1714- if IsIconic( Handle ) or FIsIgnoreResize then
1734+ if IsIconic( Handle ) or (FIsIgnoreResize <> rtNone) then
17151735 Exit;
17161736
17171737 //クールバー保存(Main)
@@ -1752,7 +1772,7 @@ begin
17521772 for i := MAIN_COOLBAND_COUNT - 1 downto 0 do begin
17531773 CoolSet := GikoSys.Setting.MainCoolSet[i];
17541774 if (CoolSet.FCoolID = -1) or (CoolSet.FCoolWidth = -1) then begin
1755- FIsIgnoreResize := False;
1775+ FIsIgnoreResize := rtNone;
17561776 SaveCoolBarSettings;
17571777 Exit;
17581778 end;
@@ -1771,7 +1791,7 @@ begin
17711791 for i := LIST_COOLBAND_COUNT - 1 downto 0 do begin
17721792 CoolSet := GikoSys.Setting.ListCoolSet[i];
17731793 if (CoolSet.FCoolID = -1) or (CoolSet.FCoolWidth = -1) then begin
1774- FIsIgnoreResize := False;
1794+ FIsIgnoreResize := rtNone;
17751795 SaveCoolBarSettings;
17761796 Exit;
17771797 end;
@@ -1790,7 +1810,7 @@ begin
17901810 for i := BROWSER_COOLBAND_COUNT - 1 downto 0 do begin
17911811 CoolSet := GikoSys.Setting.BrowserCoolSet[i];
17921812 if (CoolSet.FCoolID = -1) or (CoolSet.FCoolWidth = -1) then begin
1793- FIsIgnoreResize := False;
1813+ FIsIgnoreResize := rtNone;
17941814 SaveCoolBarSettings;
17951815 Exit;
17961816 end;
@@ -1809,59 +1829,70 @@ end;
18091829 //
18101830 procedure TGikoForm.FormShow(Sender: TObject);
18111831 begin
1812- ShowWindow(Application.Handle, SW_HIDE);
1813-
1814- //FormCreateでやると可視設定が反映されない場合があるのでFormShowでやることにした
1815- //ツールバー表示
1816- StdToolBarVisibleAction.Checked := GikoSys.Setting.StdToolBarVisible;
1817- StdToolBarVisibleActionExecute( nil );
1818- AddressBarVisibleAction.Checked := GikoSys.Setting.AddressBarVisible;
1819- AddressBarVisibleActionExecute( nil );
1820- LinkBarVisibleAction.Checked := GikoSys.Setting.LinkBarVisible;
1821- LinkBarVisibleActionExecute( nil );
1822- ListToolBarVisibleAction.Checked := GikoSys.Setting.ListToolBarVisible;
1823- ListToolBarVisibleActionExecute( nil );
1824- ListNameBarVisibleAction.Checked := GikoSys.Setting.ListNameBarVisible;
1825- ListNameBarVisibleActionExecute( nil );
1826- BrowserToolBarVisibleAction.Checked := GikoSys.Setting.BrowserToolBarVisible;
1827- BrowserToolBarVisibleActionExecute( nil );
1828- BrowserNameBarVisibleAction.Checked := GikoSys.Setting.BrowserNameBarVisible;
1829- BrowserNameBarVisibleActionExecute( nil );
1830-
1831- //ブラウザタブ
1832- BrowserTabVisibleAction.Checked := GikoSys.Setting.BrowserTabVisible;
1833- BrowserTabVisibleActionExecute(nil);
1834-
1835- if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
1836- BrowserTabTopAction.Checked := True;
1837- BrowserTabTopActionExecute(nil);
1838- end else begin
1839- BrowserTabBottomAction.Checked := True;
1840- BrowserTabBottomActionExecute(nil);
1841- end;
1832+ if not FStartUp then begin
1833+ ShowWindow(Application.Handle, SW_HIDE);
1834+
1835+ //FormCreateでやると可視設定が反映されない場合があるのでFormShowでやることにした
1836+ //ツールバー表示
1837+ StdToolBarVisibleAction.Checked := GikoSys.Setting.StdToolBarVisible;
1838+ StdToolBarVisibleActionExecute( nil );
1839+ AddressBarVisibleAction.Checked := GikoSys.Setting.AddressBarVisible;
1840+ AddressBarVisibleActionExecute( nil );
1841+ LinkBarVisibleAction.Checked := GikoSys.Setting.LinkBarVisible;
1842+ LinkBarVisibleActionExecute( nil );
1843+ ListToolBarVisibleAction.Checked := GikoSys.Setting.ListToolBarVisible;
1844+ ListToolBarVisibleActionExecute( nil );
1845+ ListNameBarVisibleAction.Checked := GikoSys.Setting.ListNameBarVisible;
1846+ ListNameBarVisibleActionExecute( nil );
1847+ BrowserToolBarVisibleAction.Checked := GikoSys.Setting.BrowserToolBarVisible;
1848+ BrowserToolBarVisibleActionExecute( nil );
1849+ BrowserNameBarVisibleAction.Checked := GikoSys.Setting.BrowserNameBarVisible;
1850+ BrowserNameBarVisibleActionExecute( nil );
1851+
1852+ //ブラウザタブ
1853+ BrowserTabVisibleAction.Checked := GikoSys.Setting.BrowserTabVisible;
1854+ BrowserTabVisibleActionExecute(nil);
18421855
1843- if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
1844- BrowserTabTabStyleAction.Checked := True;
1845- BrowserTabTabStyleActionExecute(nil);
1846- end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
1847- BrowserTabButtonStyleAction.Checked := True;
1848- BrowserTabButtonStyleActionExecute(nil);
1849- end else begin
1850- BrowserTabFlatStyleAction.Checked := True;
1851- BrowserTabFlatStyleActionExecute(nil);
1852- end;
1856+ if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
1857+ BrowserTabTopAction.Checked := True;
1858+ BrowserTabTopActionExecute(nil);
1859+ end else begin
1860+ BrowserTabBottomAction.Checked := True;
1861+ BrowserTabBottomActionExecute(nil);
1862+ end;
18531863
1854- // CoolBar 復元
1855- LoadCoolBarSettings;
1864+ if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
1865+ BrowserTabTabStyleAction.Checked := True;
1866+ BrowserTabTabStyleActionExecute(nil);
1867+ end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
1868+ BrowserTabButtonStyleAction.Checked := True;
1869+ BrowserTabButtonStyleActionExecute(nil);
1870+ end else begin
1871+ BrowserTabFlatStyleAction.Checked := True;
1872+ BrowserTabFlatStyleActionExecute(nil);
1873+ end;
18561874
1857- FIsIgnoreResize := False;
1875+ // ListView のヘッダドラッグ
1876+// ListView.FullDrag := True;
18581877
1859- //TabAutoLoad
1860- //FormCreteから移動。
1861- if GikoSys.Setting.TabAutoLoadSave then begin
1862- TabAutoLoadAction.Execute;
1863- end;
1878+ // CoolBar 復元
1879+ LoadCoolBarSettings;
1880+
1881+ FIsIgnoreResize := rtNone;
1882+
1883+ //TabAutoLoad
1884+ //FormCreteから移動。
1885+ if GikoSys.Setting.TabAutoLoadSave then begin
1886+ TabAutoLoadAction.Execute;
1887+ end;
1888+ //にちゃん語案内サポート機能
1889+ if GikoSys.Setting.GengoSupport then begin
1890+ //予定地
1891+ //Test向け
1892+ end;
18641893
1894+ FStartUp := true;
1895+ end;
18651896 end;
18661897
18671898 procedure TGikoForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
@@ -1893,17 +1924,7 @@ begin
18931924 // Application.OnDeactivate := nil;
18941925 // Self.OnDeactivate := nil;
18951926 try
1896- //column幅
1897- if GetActiveList is TBBS then begin
1898- for i := 0 to ListView.Columns.Count - 1 do
1899- GikoSys.Setting.BBSColumnWidth[i] := ListView.Column[i].Width;
1900- end else if GetActiveList is TCategory then begin
1901- for i := 0 to ListView.Columns.Count - 1 do
1902- GikoSys.Setting.CategoryColumnWidth[i] := ListView.Column[i].Width;
1903- end else if GetActiveList is TBoard then begin
1904- for i := 0 to ListView.Columns.Count - 1 do
1905- GikoSys.Setting.BoardColumnWidth[i] := ListView.Column[i].Width;
1906- end;
1927+ ActiveListColumnSave;
19071928 except
19081929 end;
19091930 try
@@ -2080,10 +2101,6 @@ begin
20802101
20812102 end;
20822103
2083-//フォームクローズ
2084-procedure TGikoForm.FormClose(Sender: TObject; var Action: TCloseAction);
2085-begin
2086-end;
20872104 //キャビネット×ボタンクリック
20882105 procedure TGikoForm.CabinetPanelHide(Sender: TObject);
20892106 begin
@@ -2221,9 +2238,9 @@ begin
22212238 Root.ImageIndex := ITEM_ICON_2CH1;
22222239 Root.SelectedIndex := ITEM_ICON_2CH2;
22232240 Root.Data := inBBS;
2224- for i := 0 to inBBS.Count - 1 do begin
2241+ for i := inBBS.Count - 1 downto 0 do begin
22252242 Category := TCategory(inBBS.Items[i]);
2226- CategoryNode := TreeView.Items.AddChild(Root, Category.Title);
2243+ CategoryNode := TreeView.Items.AddChildFirst(Root, Category.Title);
22272244 CategoryNode.Data := Category;
22282245 CategoryNode.ImageIndex := ITEM_ICON_CATEGORY1;
22292246 CategoryNode.SelectedIndex := ITEM_ICON_CATEGORY2;
@@ -2236,10 +2253,10 @@ begin
22362253 Category.CustomSort(BoardSortProc);
22372254 end;
22382255
2239- for j := 0 to Category.Count - 1 do begin
2256+ for j := Category.Count - 1 downto 0 do begin
22402257 Board := TBoard(Category.Items[j]);
22412258 Board.BeginUpdate;
2242- BoardNode := TreeView.Items.AddChild(CategoryNode, Board.Title);
2259+ BoardNode := TreeView.Items.AddChildFirst(CategoryNode, Board.Title);
22432260 BoardNode.Data := Board;
22442261 //if (Board.LastGetTime = 0) or (Board.LastGetTime = ZERO_DATE) then begin
22452262 if not Board.IsLogFile then begin
@@ -2273,22 +2290,37 @@ begin
22732290 end;
22742291
22752292 function TGikoForm.SetCategoryListItem(ABBS2ch: TBBS): Integer;
2276-const
2277- COLUMN: array[0..0] of string = ('カテゴリ名');
22782293 var
2279- ListColumn: TListColumn;
2280- i: Integer;
2294+ TitleColumn : TListColumn;
2295+ ListColumn : TListColumn;
2296+ i, id, idx : Integer;
22812297 begin
22822298 ListView.Items.BeginUpdate;
22832299 try
22842300 Screen.Cursor := crHourGlass;
22852301
22862302 ListView.Columns.Clear;
2287- for i := 0 to Length(COLUMN) - 1 do begin
2288- ListColumn := ListView.Columns.Add;
2289- ListColumn.Caption := COLUMN[i];
2290- ListColumn.Width := GikoSys.Setting.BBSColumnWidth[i];
2303+ TitleColumn := ListView.Columns.Add;
2304+ TitleColumn.Caption := GikoBBSColumnCaption[ Ord( gbbscTitle ) ];
2305+ TitleColumn.Width := GikoSys.Setting.BBSColumnWidth[ Ord( gbbscTitle ) ];
2306+ idx := 0;
2307+ for i := 0 to GikoSys.Setting.BBSColumnOrder.Count - 1 do begin
2308+ if GikoSys.Setting.BBSColumnOrder[ i ] = gbbscTitle then begin
2309+ TitleColumn.Tag := i;
2310+ idx := i;
2311+ end else begin
2312+ id := Ord( GikoSys.Setting.BBSColumnOrder[ i ] );
2313+ if (Integer( Low( TGikoBBSColumnID ) ) <= id) and
2314+ (id <= Integer( High( TGikoBBSColumnID ) )) then begin
2315+ ListColumn := ListView.Columns.Add;
2316+ // ListColumn.Tag := id;
2317+ ListColumn.Tag := i;
2318+ ListColumn.Caption := GikoBBSColumnCaption[ id ];
2319+ ListColumn.Width := GikoSys.Setting.BBSColumnWidth[ id ];
2320+ end;
2321+ end;
22912322 end;
2323+ TitleColumn.Index := idx;
22922324
22932325 ListView.Items.Count := 0;
22942326 ListView.Items.Clear;
@@ -2309,8 +2341,11 @@ begin
23092341
23102342 FSortIndex := GikoSys.Setting.BBSSortIndex;
23112343 FSortOrder := GikoSys.Setting.BBSSortOrder;
2312- if (FSortIndex >= 0) and (FSortIndex < Length(COLUMN)) then
2313- ListViewSort(nil, ListView.Column[FSortIndex]);
2344+ for i := ListView.Columns.Count - 1 downto 0 do begin
2345+ idx := ListView.Column[ i ].Tag;
2346+ if FSortIndex = Ord( GikoSys.Setting.BBSColumnOrder[ idx ] ) then
2347+ ListViewSort( nil, ListView.Column[ i ] );
2348+ end;
23142349
23152350 Result := ABBS2ch.Count;
23162351 finally
@@ -2320,22 +2355,37 @@ begin
23202355 end;
23212356
23222357 function TGikoForm.SetBoardListItem(Category: TCategory): Integer;
2323-const
2324- COLUMN: array[0..2] of string = ('板名', '巡回予約', '取得日時');
23252358 var
2326- ListColumn: TListColumn;
2327- i: Integer;
2359+ TitleColumn : TListColumn;
2360+ ListColumn : TListColumn;
2361+ i, id, idx : Integer;
23282362 begin
23292363 ListView.Items.BeginUpdate;
23302364 try
23312365 Screen.Cursor := crHourGlass;
23322366
23332367 ListView.Columns.Clear;
2334- for i := 0 to Length(COLUMN) - 1 do begin
2335- ListColumn := ListView.Columns.Add;
2336- ListColumn.Caption := COLUMN[i];
2337- ListColumn.Width := GikoSys.Setting.CategoryColumnWidth[i];
2368+ TitleColumn := ListView.Columns.Add;
2369+ TitleColumn.Caption := GikoCategoryColumnCaption[ Ord( gccTitle ) ];
2370+ TitleColumn.Width := GikoSys.Setting.CategoryColumnWidth[ Ord( gccTitle ) ];
2371+ idx := 0;
2372+ for i := 0 to GikoSys.Setting.CategoryColumnOrder.Count - 1 do begin
2373+ if GikoSys.Setting.CategoryColumnOrder[ i ] = gccTitle then begin
2374+ TitleColumn.Tag := i;
2375+ idx := i;
2376+ end else begin
2377+ id := Ord( GikoSys.Setting.CategoryColumnOrder[ i ] );
2378+ if (Integer( Low( TGikoCategoryColumnID ) ) <= id) and
2379+ (id <= Integer( High( TGikoCategoryColumnID ) )) then begin
2380+ ListColumn := ListView.Columns.Add;
2381+// ListColumn.Tag := id;
2382+ ListColumn.Tag := i;
2383+ ListColumn.Caption := GikoCategoryColumnCaption[ id ];
2384+ ListColumn.Width := GikoSys.Setting.CategoryColumnWidth[ id ];
2385+ end;
2386+ end;
23382387 end;
2388+ TitleColumn.Index := idx;
23392389
23402390 ListView.Items.Count := 0;
23412391 ListView.Items.Clear;
@@ -2356,8 +2406,11 @@ begin
23562406
23572407 FSortIndex := GikoSys.Setting.CategorySortIndex;
23582408 FSortOrder := GikoSys.Setting.CategorySortOrder;
2359- if (FSortIndex >= 0) and (FSortIndex < Length(COLUMN)) then
2360- ListViewSort(nil, ListView.Column[FSortIndex]);
2409+ for i := ListView.Columns.Count - 1 downto 0 do begin
2410+ idx := ListView.Column[ i ].Tag;
2411+ if FSortIndex = Ord( GikoSys.Setting.CategoryColumnOrder[ idx ] ) then
2412+ ListViewSort( nil, ListView.Column[ i ] );
2413+ end;
23612414
23622415 Result := Category.Count;
23632416 finally
@@ -2367,39 +2420,45 @@ begin
23672420 end;
23682421
23692422 function TGikoForm.SetThreadListItem(Board: TBoard): Integer;
2370-const
2371- COLUMN: array[0..7] of string = ('スレッド名', 'カウント', '取得', '新着',
2372- '未読', '巡回予約', '取得日時', 'スレ作成日時');
2373- COLUMN_NONACQUIREDCOUNT: string = '未取得';
2374- COLUMN_ALIGNMENT: array[0..7] of TAlignment = (taLeftJustify, taRightJustify,
2375- taRightJustify, taRightJustify,
2376- taRightJustify, taLeftJustify,
2377- taLeftJustify, taLeftJustify);
2378- //No, スレッド名, カウント, 巡回予約, 取得日時
2379-var
2380- ListColumn: TListColumn;
2381- i: Integer;
2423+var
2424+ TitleColumn : TListColumn;
2425+ ListColumn : TListColumn;
2426+ i, id, idx : Integer;
23822427 begin
23832428 ListView.Items.BeginUpdate;
23842429 try
23852430 Screen.Cursor := crHourGlass;
23862431
2432+{*
23872433 // チラつき防止のため、変更されている場合のみ
23882434 // ※名称は違うがカラム数が同じ、といった場合に対処できないので注意
2389- if ListView.Columns.Count <> (High( COLUMN ) - Low( COLUMN ) + 1) then
2435+ if ListView.Columns.Count <> GikoSys.Setting.BoardColumnOrder.Count then
2436+*}
23902437 begin
23912438 ListView.Columns.Clear;
2392- for i := 0 to Length(COLUMN) - 1 do begin
2393- ListColumn := ListView.Columns.Add;
2394- ListColumn.Caption := COLUMN[i];
2395- ListColumn.Width := GikoSys.Setting.BoardColumnWidth[i];
2396- ListColumn.Alignment := COLUMN_ALIGNMENT[i];
2439+ TitleColumn := ListView.Columns.Add;
2440+ TitleColumn.Caption := GikoBoardColumnCaption[ Ord( gbcTitle ) ];
2441+ TitleColumn.Width := GikoSys.Setting.BoardColumnWidth[ Ord( gbcTitle ) ];
2442+ idx := 0;
2443+ for i := 0 to GikoSys.Setting.BoardColumnOrder.Count - 1 do begin
2444+ if GikoSys.Setting.BoardColumnOrder[ i ] = gbcTitle then begin
2445+ TitleColumn.Tag := i;
2446+ idx := i;
2447+ end else begin
2448+ id := Ord( GikoSys.Setting.BoardColumnOrder[ i ] );
2449+ if (Integer( Low( TGikoBoardColumnID ) ) <= id) and
2450+ (id <= Integer( High( TGikoBoardColumnID ) )) then begin
2451+ ListColumn := ListView.Columns.Add;
2452+ ListColumn.Caption := GikoBoardColumnCaption[ id ];
2453+ // ListColumn.Tag := id;
2454+ ListColumn.Tag := i;
2455+ ListColumn.Width := GikoSys.Setting.BoardColumnWidth[ id ];
2456+ ListColumn.Alignment := GikoBoardColumnAlignment[ id ];
2457+ end;
2458+ end;
23972459 end;
2460+ TitleColumn.Index := idx;
23982461 end;
2399- if GikoSys.Setting.NonAcquiredCount then
2400- ListView.Columns[2].Caption := COLUMN_NONACQUIREDCOUNT
2401- else
2402- ListView.Columns[2].Caption := COLUMN[2];
24032462
24042463 ListView.Items.Count := 0;
24052464 ListView.Items.Clear;
@@ -2417,8 +2476,11 @@ begin
24172476
24182477 FSortIndex := GikoSys.Setting.BoardSortIndex;
24192478 FSortOrder := GikoSys.Setting.BoardSortOrder;
2420- if (FSortIndex >= 0) and (FSortIndex < Length(COLUMN)) then
2421- ListViewSort(nil, ListView.Column[FSortIndex]);
2479+ for i := ListView.Columns.Count - 1 downto 0 do begin
2480+ idx := ListView.Column[ i ].Tag;
2481+ if FSortIndex = Ord( GikoSys.Setting.BoardColumnOrder[ idx ] ) then
2482+ ListViewSort( nil, ListView.Column[ i ] );
2483+ end;
24222484
24232485 Result := Board.Count;
24242486 finally
@@ -2438,9 +2500,11 @@ var
24382500 ThreadItem: TThreadItem;
24392501 RepStr: string;
24402502 ActivListObj : TObject;
2503+ i, idx : Integer;
24412504 begin
24422505 ActivListObj := ActiveList;
24432506 if ActivListObj is TBBS then begin
2507+ //===== カテゴリリスト =====
24442508 BBS := TBBS(ActivListObj);
24452509
24462510 ListView.StateImages := nil;
@@ -2463,7 +2527,10 @@ begin
24632527
24642528 Item.ImageIndex := ITEM_ICON_CATEGORY1;
24652529 Item.Data := Category;
2530+
24662531 end else if ActivListObj is TCategory then begin
2532+
2533+ //===== 板リスト =====
24672534 Category := TCategory(ActivListObj);
24682535
24692536 ListView.StateImages := nil;
@@ -2484,25 +2551,44 @@ begin
24842551 else
24852552 Item.Caption := Board.Title;
24862553
2487- if Item.SubItems.Count <> 2 then begin
2554+ if Item.SubItems.Count <> ListView.Columns.Count then begin
24882555 Item.SubItems.Clear;
2489- Item.SubItems.Add('');
2490- Item.SubItems.Add('');
2556+ for i := GikoSys.Setting.CategoryColumnOrder.Count - 1 downto 1 do
2557+ Item.SubItems.Add('');
24912558 end;
24922559
24932560 Item.ImageIndex := ITEM_ICON_BOARD1;
24942561
2495- if Board.Round then
2496- Item.SubItems[0] := Board.RoundName // '予約'
2497- else
2498- Item.SubItems[0] := '';
2562+ idx := 0;
2563+ for i := 0 to ListView.Columns.Count - 1 do begin
2564+ if GikoSys.Setting.CategoryColumnOrder.Count <= i then
2565+ Break;
2566+// case TGikoCategoryColumnID( ListView.Column[ i ].Tag ) of
2567+ case GikoSys.Setting.CategoryColumnOrder[ i ] of
2568+ gccTitle:
2569+ // Item.Caption は SubItems に含まれ無いので
2570+ Dec( idx );
2571+
2572+ gccRoundName:
2573+ if Board.Round then
2574+ Item.SubItems[ idx ] := Board.RoundName // '予約'
2575+ else
2576+ Item.SubItems[ idx ] := '';
2577+
2578+ gccLastModified:
2579+ if Board.RoundDate = ZERO_DATE then begin
2580+ Item.SubItems[ idx ] := '';
2581+ end else
2582+ Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', Board.RoundDate);
2583+ end;
2584+ Inc( idx );
2585+ end;
24992586
2500- if Board.RoundDate = ZERO_DATE then begin
2501- Item.SubItems[1] := '';
2502- end else
2503- Item.SubItems[1] := FormatDateTime('yyyy/mm/dd hh:mm:ss', Board.RoundDate);
25042587 Item.Data := Board;
2588+
25052589 end else if ActivListObj is TBoard then begin
2590+
2591+ //===== スレリスト =====
25062592 Board := TBoard(ActivListObj);
25072593
25082594 if GikoSys.Setting.ListIconVisible then
@@ -2548,15 +2634,10 @@ begin
25482634 RepStr := CustomStringReplace(RepStr, '&amp;', '&' );
25492635 //RepStr := StringReplace(RepStr, '@`', ',', [rfReplaceAll]);
25502636
2551- if Item.SubItems.Count <> 7 then begin
2637+ if Item.SubItems.Count <> ListView.Columns.Count then begin
25522638 Item.SubItems.Clear;
2553- Item.SubItems.Add('');
2554- Item.SubItems.Add('');
2555- Item.SubItems.Add('');
2556- Item.SubItems.Add('');
2557- Item.SubItems.Add('');
2558- Item.SubItems.Add('');
2559- Item.SubItems.Add('');
2639+ for i := GikoSys.Setting.BoardColumnOrder.Count - 1 downto 1 do
2640+ Item.SubItems.Add('');
25602641 end;
25612642
25622643 if ListNumberVisibleAction.Checked then
@@ -2572,49 +2653,105 @@ begin
25722653 end;
25732654
25742655 if ThreadItem.IsLogFile then begin
2575- Item.ImageIndex := ITEM_ICON_THREADLOG1;
2576- Item.SubItems[0] := IntToStr(ThreadItem.AllResCount);
2577- if GikoSys.Setting.NonAcquiredCount then
2578- Item.SubItems[1] := IntToStr(ThreadItem.AllResCount - ThreadItem.Count)
2579- else
2580- Item.SubItems[1] := IntToStr(ThreadItem.Count);
2581- if ThreadItem.NewResCount = 0 then
2582- Item.SubItems[2] := ''
2583- else
2584- Item.SubItems[2] := IntToStr(ThreadItem.NewResCount);
2585- Item.SubItems[3] := '';
2586- if ThreadItem.Round then
2587- Item.SubItems[4] := ThreadItem.RoundName
2588- else
2589- Item.SubItems[4] := '';
2590- if ThreadItem.RoundDate = ZERO_DATE then begin
2591- Item.SubItems[5] := '';
2592- end else
2593- Item.SubItems[5] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.RoundDate);
2594- if ThreadItem.NewArrival then
2595- Item.ImageIndex := ITEM_ICON_THREADNEW1;
2596- if ThreadItem.CreateDate = ZERO_DATE then begin
2597- Item.SubItems[6] := '';
2598- end else
2599- Item.SubItems[6] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.CreateDate);
2656+ idx := 0;
2657+ for i := 0 to ListView.Columns.Count - 1 do begin
2658+ if GikoSys.Setting.BoardColumnOrder.Count <= i then
2659+ Break;
2660+// case TGikoBoardColumnID( ListView.Column[ i ].Tag ) of
2661+ case GikoSys.Setting.BoardColumnOrder[ i ] of
2662+ gbcTitle:
2663+ // Item.Caption は SubItems に含まれ無いので
2664+ Dec( idx );
2665+
2666+ gbcAllCount:
2667+ Item.SubItems[ idx ] := IntToStr(ThreadItem.AllResCount);
2668+
2669+ gbcLocalCount:
2670+ Item.SubItems[ idx ] := IntToStr(ThreadItem.Count);
2671+
2672+ gbcNonAcqCount:
2673+ Item.SubItems[ idx ] := IntToStr(ThreadItem.AllResCount - ThreadItem.Count);
2674+
2675+ gbcNewCount:
2676+ if ThreadItem.NewResCount = 0 then
2677+ Item.SubItems[ idx ] := ''
2678+ else
2679+ Item.SubItems[ idx ] := IntToStr(ThreadItem.NewResCount);
2680+
2681+ gbcUnReadCount:
2682+ Item.SubItems[ idx ] := '';
2683+
2684+ gbcRoundName:
2685+ if ThreadItem.Round then
2686+ Item.SubItems[ idx ] := ThreadItem.RoundName
2687+ else
2688+ Item.SubItems[ idx ] := '';
26002689
2690+ gbcRoundDate://gbcLastModified:
2691+ if (ThreadItem.RoundDate = ZERO_DATE) then begin
2692+ Item.SubItems[ idx ] := '';
2693+ end else
2694+ Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.RoundDate);
2695+
2696+ gbcCreated:
2697+ if ThreadItem.CreateDate = ZERO_DATE then begin
2698+ Item.SubItems[ idx ] := '';
2699+ end else
2700+ Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.CreateDate);
2701+
2702+ gbcLastModified:
2703+ if (ThreadItem.LastModified = ZERO_DATE) then begin
2704+ Item.SubItems[ idx ] := '';
2705+ end else
2706+ Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.LastModified);
2707+
2708+
2709+ end;
2710+ Inc( idx );
2711+ end;
2712+
2713+ if ThreadItem.NewArrival then
2714+ Item.ImageIndex := ITEM_ICON_THREADNEW1
2715+ else
2716+ Item.ImageIndex := ITEM_ICON_THREADLOG1;
26012717 end else begin
2602- Item.ImageIndex := ITEM_ICON_THREAD1;
2603- Item.SubItems[0] := IntToStr(ThreadItem.AllResCount);
2604- Item.SubItems[1] := '';
2605- Item.SubItems[2] := '';
2606- Item.SubItems[3] := '';
2607- Item.SubItems[4] := '';
2608- Item.SubItems[5] := '';
2609- if not GikoSys.Setting.CreationTimeLogs then
2610- if ThreadItem.CreateDate = ZERO_DATE then
2611- Item.SubItems[6] := ''
2612- else
2613- Item.SubItems[6] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.CreateDate);
2718+ idx := 0;
2719+ for i := 0 to GikoSys.Setting.BoardColumnOrder.Count - 1 do begin
2720+// case TGikoBoardColumnID( ListView.Column[ i ].Tag ) of
2721+ case GikoSys.Setting.BoardColumnOrder[ i ] of
2722+ gbcTitle:
2723+ // Item.Caption は SubItems に含まれ無いので
2724+ Dec( idx );
2725+
2726+ gbcAllCount:
2727+ Item.SubItems[ idx ] := IntToStr(ThreadItem.AllResCount);
2728+
2729+ gbcRoundDate://gbcLastModified:
2730+ Item.SubItems[ idx ] := '';
2731+
2732+ gbcCreated:
2733+ if ThreadItem.CreateDate = ZERO_DATE then begin
2734+ Item.SubItems[ idx ] := '';
2735+ end else
2736+ Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', ThreadItem.CreateDate);
2737+
2738+ gbcLastModified:
2739+ Item.SubItems[ idx ] := '';
2740+
2741+ else
2742+ Item.SubItems[ idx ] := '';
2743+ end;
2744+ Inc( idx );
2745+ end;
26142746
2747+ if ThreadItem.NewArrival then
2748+ Item.ImageIndex := ITEM_ICON_THREADNEW1
2749+ else
2750+ Item.ImageIndex := ITEM_ICON_THREAD1;
26152751 end;
26162752
26172753 Item.Data := ThreadItem;
2754+
26182755 end;
26192756 end;
26202757
@@ -2657,7 +2794,7 @@ var
26572794 ActiveFileName: string;
26582795 e: IHTMLElement;
26592796 Ext: string;
2660- buf: string;
2797+// buf, buf2: string;
26612798 PathRec: TPathRec;
26622799 begin
26632800 if not( TObject(Sender) is TWebBrowser )then
@@ -2740,30 +2877,43 @@ begin
27402877 end else begin
27412878 threadItem := GetActiveContent;
27422879 if Pos('about:blank..', Text) = 1 then begin
2743- if (AnsiPos('http://jbbs.livedoor.com/', threadItem.URL) <> 0) then begin
2744- URL := Copy(threadItem.URL, 1, LastDelimiter('/',threadItem.URL));
2745- Gikosys.GetPopupResNumber(Text,PathRec.FSt,PathRec.FTo);
2746- if ( PathRec.FSt <> 0 ) and ( PathRec.FTo <> 0 ) then
2747- buf := IntToStr(PathRec.FSt) + '-' + IntToStr(PathRec.FTo)
2748- else if( PathRec.FSt <> 0 ) then
2749- buf := IntToStr(PathRec.FSt);
2750- end else if AnsiPos('machi.to/bbs/', threadItem.URL) <> 0 then begin
2751- URL := threaditem.URL;
2752- buf := Copy(Text,AnsiPos('&st=',Text),Length(Text)-AnsiPos('&st=',Text) + 1);
2880+ wkInt := LastDelimiter( '/', threadItem.URL );
2881+ if Pos( '?', Copy( threadItem.URL, wkInt, MaxInt ) ) = 0 then begin
2882+ // Thread.URL は PATH_INFO 渡し
2883+ URL := Copy( threadItem.URL, 1, LastDelimiter( '/', threadItem.URL ) );
2884+ wkInt := LastDelimiter( '/', Text );
2885+ if Pos( '?', Copy( Text, wkInt, MaxInt ) ) = 0 then
2886+ // Text も PATH_INFO 渡し
2887+ URL := URL + Copy( Text, LastDelimiter( '/', Text ) + 1, MaxInt )
2888+ else
2889+ // Text は QUERY_STRING 渡し
2890+ URL := URL + Copy( Text, LastDelimiter( '?', Text ) + 1, MaxInt );
27532891 end else begin
2754- URL := Copy(threadItem.URL, 1, LastDelimiter('/',threadItem.URL));
2755- buf := Copy(Text,LastDelimiter('/',Text)+1,Length(Text)-LastDelimiter('/',Text));
2892+ // Thread.URL は QUERY_STRING 渡し
2893+ URL := Copy( threadItem.URL, 1, LastDelimiter( '?', threadItem.URL ) );
2894+ wkInt := LastDelimiter( '/', Text );
2895+ if Pos( '?', Copy( Text, wkInt, MaxInt ) ) = 0 then begin
2896+ // Text は PATH_INFO 渡し
2897+ // URL に板とキーが足らないので Text から頂戴する
2898+ wkInt := LastDelimiter( '/', Copy( Text, 1, wkInt - 1 ) );
2899+ wkInt := LastDelimiter( '/', Copy( Text, 1, wkInt - 1 ) );
2900+ URL := Copy( URL, 1, Length( URL ) - 1 ) + Copy( Text, wkInt, MaxInt );
2901+ end else begin
2902+ // Text も QUERY_STRING 渡し
2903+ URL := URL + Copy( Text, LastDelimiter( '?', Text ) + 1, MaxInt )
2904+ end;
27562905 end;
2757- URL := URL + buf;
27582906 end else begin
27592907 URL := Text;
27602908 end;
2909+
27612910 PathRec := Gikosys.Parse2chURL2(URL);
27622911 if (PathRec.FNoParam) then begin
27632912 PathRec.FSt := 1;
27642913 PathRec.FTo := 1;
2765- end else
2914+ end else begin
27662915 Gikosys.GetPopupResNumber(URL,PathRec.FSt,PathRec.FTo);
2916+ end;
27672917 GikoSys.ParseURI( URL, Protocol, Host, Path, Document, Port, Bookmark );
27682918
27692919 if PathRec.FDone or (not GikoSys.Is2chHost( Host )) then begin
@@ -2790,10 +2940,10 @@ begin
27902940 // wkIntTo := 1;
27912941 //if PathRec.FFirst then
27922942 // wkIntSt := 1;
2793- if PathRec.FStBegin then
2794- wkIntSt := 1;
2795- if PathRec.FToEnd then
2796- wkIntTo := 9999;
2943+ //if PathRec.FStBegin then //http://〜〜〜〜/-50というとき
2944+ // wkIntSt := 1; //
2945+ //if PathRec.FToEnd then //http://〜〜〜〜/50-というとき
2946+ // wkIntTo := 9999; // どちらの場合も、GetPopupResNumberでうまく番号を調整するのでふよう。
27972947
27982948 //ATitle := ActiveFileName <> PathRec.FKey;
27992949 if (FActiveContent <> nil) and (FActiveContent.Thread.URL = URL) then
@@ -2863,22 +3013,44 @@ end;
28633013
28643014 procedure TGikoForm.ListViewKeyDown(Sender: TObject; var Key: Word;
28653015 Shift: TShiftState);
3016+var
3017+ pos : TPoint;
28663018 begin
28673019 if GetActiveList is TBoard then begin
2868- if Key = VK_BACK then begin
2869-// UpFolderButtonClick(Sender);
2870- end else if Key = VK_SPACE then begin
2871- ListDoubleClick(Shift);
2872- end else if Key = VK_RETURN then begin
2873- ListClick;
3020+ case Key of
3021+ VK_BACK:; // UpFolderButtonClick(Sender);
3022+ VK_SPACE: ListDoubleClick(Shift);
3023+ VK_RETURN: ListClick;
3024+ VK_APPS:
3025+ begin
3026+ if ListView.Selected <> nil then begin
3027+ pos.X := ListView.Column[ 0 ].Width;
3028+ pos.Y := ListView.Selected.Top;
3029+ end else begin
3030+ pos.X := ListView.Left;
3031+ pos.Y := ListView.Top;
3032+ end;
3033+ Windows.ClientToScreen( ListView.Handle, pos );
3034+ ListPopupMenu.Popup( pos.X, pos.Y );
3035+ end;
28743036 end;
28753037 end else begin // TBBS, TCategory
2876- if Key = VK_BACK then begin
2877-// UpFolderButtonClick(Sender);
2878- end else if Key = VK_SPACE then begin
2879- ListClick;
2880- end else if Key = VK_RETURN then begin
2881- ListDoubleClick(Shift);
3038+ case Key of
3039+ VK_BACK:; // UpFolderButtonClick(Sender);
3040+ VK_SPACE: ListClick;
3041+ VK_RETURN: ListDoubleClick(Shift);
3042+ VK_APPS:
3043+ begin
3044+ if ListView.Selected <> nil then begin
3045+ pos.X := ListView.Column[ 0 ].Width;
3046+ pos.Y := ListView.Selected.Top;
3047+ end else begin
3048+ pos.X := ListView.Left;
3049+ pos.Y := ListView.Top;
3050+ end;
3051+ Windows.ClientToScreen( ListView.Handle, pos );
3052+ ListPopupMenu.Popup( pos.X, pos.Y );
3053+ end;
28823054 end;
28833055 end;
28843056 end;
@@ -2888,29 +3060,95 @@ begin
28883060 Result := FHttpState;
28893061 end;
28903062
3063+{*!
3064+\brief ListView の Column を真のカラムに変換
3065+
3066+Delphi 6 Personal での ListView では ListViewColumnClick イベントで
3067+正しいカラムが渡されないため、正しいカラムに変換します。
3068+*}
3069+function TGikoForm.ActiveListTrueColumn( column : TListColumn ) : TListColumn;
3070+{*
3071+var
3072+ i, idx : Integer;
3073+ orderList : TList;
3074+*}
3075+begin
3076+
3077+ // 正しく変換する方法が分からないので保留
3078+ Result := column;
3079+ Exit;
3080+{*
3081+ Result := column;
3082+
3083+ if TObject( FActiveList ) is TBBS then
3084+ orderList := GikoSys.Setting.BBSColumnOrder
3085+ else if TObject( FActiveList ) is TCategory then
3086+ orderList := GikoSys.Setting.CategoryColumnOrder
3087+ else if TObject( FActiveList ) is TBoard then
3088+ orderList := GikoSys.Setting.BoardColumnOrder
3089+ else
3090+ Exit;
3091+
3092+ idx := column.Tag;
3093+
3094+ for i := 0 to ListView.Columns.Count - 1 do begin
3095+ if Integer( orderList[ ListView.Column[ i ].Tag ] ) = 0 then begin
3096+ if idx = 0 then
3097+ Result := ListView.Column[ i ]
3098+ else if idx <= i then
3099+ Result := ListView.Column[ idx - 1 ];
3100+ Exit;
3101+ end;
3102+ end;
3103+*}
3104+
3105+end;
3106+
28913107 procedure TGikoForm.ListViewColumnClick(Sender: TObject;
28923108 Column: TListColumn);
3109+var
3110+ id, idx : Integer;
3111+ orderList : TList;
28933112 begin
2894- if FSortIndex = Column.Index then
3113+ idx := ActiveListTrueColumn( Column ).Tag;
3114+
3115+ if TObject( FActiveList ) is TBBS then
3116+ orderList := GikoSys.Setting.BBSColumnOrder
3117+ else if TObject( FActiveList ) is TCategory then
3118+ orderList := GikoSys.Setting.CategoryColumnOrder
3119+ else if TObject( FActiveList ) is TBoard then
3120+ orderList := GikoSys.Setting.BoardColumnOrder
3121+ else
3122+ Exit;
3123+
3124+ id := Integer( orderList[ idx ] );
3125+
3126+ if FSortIndex = id then
28953127 FSortOrder := not FSortOrder
28963128 else
28973129 FSortOrder := False;
3130+
28983131 ListViewSort(Sender, Column);
28993132 end;
29003133
29013134 procedure TGikoForm.ListViewSort(Sender: TObject; Column: TListColumn);
29023135 var
2903- i: Integer;
3136+ i, id, idx : Integer;
3137+ orderList : TList;
29043138 wkBBS: TBBS;
29053139 wkCategory: TCategory;
29063140 wkBoard: TBoard;
29073141 begin
2908- for i := 0 to ListView.Columns.Count - 1 do
3142+ idx := ActiveListTrueColumn( Column ).Tag;
3143+
3144+ for i := 0 to ListView.Columns.Count - 1 do begin
29093145 ListView.Column[i].ImageIndex := -1;
3146+ end;
3147+
29103148 if FSortOrder then
2911- ListView.Column[Column.Index].ImageIndex := ITEM_ICON_SORT1
3149+ ListView.Column[ idx ].ImageIndex := ITEM_ICON_SORT1
29123150 else
2913- ListView.Column[Column.Index].ImageIndex := ITEM_ICON_SORT2;
3151+ ListView.Column[ idx ].ImageIndex := ITEM_ICON_SORT2;
29143152
29153153 Sort.SortNoFlag := ListNumberVisibleAction.Checked;
29163154
@@ -2918,35 +3156,41 @@ begin
29183156 if TObject( FActiveList ) is TBBS then begin
29193157 //wkBBS := TBBS(TreeView.Selected.Data);
29203158 wkBBS := TBBS( FActiveList );
3159+ orderList := GikoSys.Setting.BBSColumnOrder;
3160+ id := Integer( orderList[ idx ] );
29213161 Sort.SortOrder := FSortOrder;
2922- Sort.SortIndex := Column.Index;
2923- GikoSys.Setting.BBSSortIndex := Column.Index;
3162+ Sort.SortIndex := id;
3163+ GikoSys.Setting.BBSSortIndex := id;
29243164 GikoSys.Setting.BBSSortOrder := FSortOrder;
29253165 wkBBS.Sort(CategorySortProc);
2926- ListView.Refresh;
29273166 //end else if TObject(TreeView.Selected.Data) is TCategory then begin
29283167 end else if TObject( FActiveList ) is TCategory then begin
29293168 //wkCategory := TCategory(TreeView.Selected.Data);
29303169 wkCategory := TCategory( FActiveList );
3170+ orderList := GikoSys.Setting.CategoryColumnOrder;
3171+ id := Integer( orderList[ idx ] );
29313172 Sort.SortOrder := FSortOrder;
2932- Sort.SortIndex := Column.Index;
2933- GikoSys.Setting.CategorySortIndex := Column.Index;
3173+ Sort.SortIndex := id;
3174+ GikoSys.Setting.CategorySortIndex := id;
29343175 GikoSys.Setting.CategorySortOrder := FSortOrder;
29353176 wkCategory.CustomSort(BoardSortProc);
2936- ListView.Refresh;
29373177 //end else if TObject(TreeView.Selected.Data) is TBoard then begin
29383178 end else if TObject( FActiveList ) is TBoard then begin
29393179 //wkBoard := TBoard(TreeView.Selected.Data);
29403180 wkBoard := TBoard( FActiveList );
3181+ orderList := GikoSys.Setting.BoardColumnOrder;
3182+ id := Integer( orderList[ idx ] );
29413183 Sort.SortOrder := FSortOrder;
2942- Sort.SortIndex := Column.Index;
2943- Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
2944- GikoSys.Setting.BoardSortIndex := Column.Index;
3184+ Sort.SortIndex := id;
3185+ GikoSys.Setting.BoardSortIndex := id;
29453186 GikoSys.Setting.BoardSortOrder := FSortOrder;
29463187 wkBoard.CustomSort(ThreadItemSortProc);
2947- ListView.Refresh;
3188+ end else begin
3189+ id := 0;
29483190 end;
2949- FSortIndex := Column.Index;
3191+
3192+ ListView.Refresh;
3193+ FSortIndex := id;
29503194 end;
29513195
29523196 procedure TGikoForm.MenuToolBarCustomDrawButton(Sender: TToolBar;
@@ -3020,10 +3264,10 @@ begin
30203264 if TObject(Item.Data) is TThreadItem then begin
30213265 ThreadItem := TThreadItem(Item.Data);
30223266 if ( FUseOddResOddColor ) and ( ThreadItem.Count <> 0 ) and ( ThreadItem.AllResCount <> ThreadItem.Count) then begin
3023- ListView.Canvas.Brush.Color := FOddColor;
3024- end else begin
3025- ListView.Canvas.Brush.Color := FListViewBackGroundColor;
3026- end;
3267+ ListView.Canvas.Brush.Color := FOddColor;
3268+ end else begin
3269+ ListView.Canvas.Brush.Color := FListViewBackGroundColor;
3270+ end;
30273271 // if (ThreadItem.Kokomade <> ThreadItem.Count) and (ThreadItem.IsLogFile) then
30283272 if ThreadItem.UnRead then
30293273 TListView(Sender).Canvas.Font.Style := [fsBold];
@@ -3215,6 +3459,7 @@ var
32153459 s: string;
32163460 boardPlugIn : TBoardPlugIn;
32173461 i: Integer;
3462+ browserRec : TBrowserRecord;
32183463 begin
32193464 try
32203465 if Item.DownType = gdtBoard then
@@ -3249,21 +3494,27 @@ begin
32493494 ATitle := GikoSys.DivideStrLine(GikoSys.ReadThreadFile(Item.ThreadItem.GetThreadFileName, 1)).FTitle;
32503495 end;
32513496 for i := BrowserTab.Tabs.Count - 1 downto 0 do begin
3252- if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Thread = Item.ThreadItem then
3497+ if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Thread = Item.ThreadItem then begin
32533498 TBrowserRecord(BrowserTab.Tabs.Objects[i]).Repaint := true;
3499+ break;
3500+ end;
32543501 end;
32553502 if GikoSys.Setting.BrowserTabVisible then begin
32563503 if GetActiveContent = Item.ThreadItem then
3257- InsertBrowserTab(Item.ThreadItem)
3504+ browserRec := InsertBrowserTab(Item.ThreadItem)
32583505 else if (ListView.Selected <> nil ) and ( TObject(ListView.Selected.Data) is TThreadItem ) and ( Item.ThreadItem = TThreadItem(ListView.Selected.Data)) then
3259- InsertBrowserTab(Item.ThreadItem, True)
3506+ browserRec := InsertBrowserTab(Item.ThreadItem, True)
32603507 else
3261- InsertBrowserTab(Item.ThreadItem, False);
3508+ browserRec := InsertBrowserTab(Item.ThreadItem, False);
3509+ if browserRec.Thread = BrowserNullTab.Thread then begin
3510+ browserRec.Movement := BrowserNullTab.Movement;
3511+ BrowserNullTab.Movement := '';
3512+ end;
32623513 end else begin
32633514 if (GetActiveContent = Item.ThreadItem) or (FActiveContent = nil) or(FActiveContent.Browser = BrowserNullTab.Browser) then
32643515 InsertBrowserTab(Item.ThreadItem);
32653516 end;
3266-
3517+ Application.ProcessMessages;
32673518 if Item.State = gdsComplete then begin
32683519 PlaySound('New');
32693520 AddMessageList(ATitle + ' [スレ取得完了]', nil, gmiOK);
@@ -3391,14 +3642,17 @@ begin
33913642 end;
33923643 end;}
33933644
3394-procedure TGikoForm.InsertBrowserTab(ThreadItem: TThreadItem; ActiveTab: Boolean = True);
3395-
3645+function TGikoForm.InsertBrowserTab(
3646+ ThreadItem : TThreadItem;
3647+ ActiveTab : Boolean = True
3648+) : TBrowserRecord;
33963649 var
3397- i, j, idx: Integer;
3398- favItem : TFavoriteThreadItem;
3650+ i, j, idx : Integer;
3651+ favItem : TFavoriteThreadItem;
33993652 newBrowser : TBrowserRecord;
34003653 begin
34013654
3655+ Result := nil;
34023656 if Threaditem = nil then Exit;
34033657
34043658 if ThreadItem.IsLogFile then begin
@@ -3417,6 +3671,7 @@ begin
34173671 for i := 0 to BrowserTab.Tabs.Count - 1 do begin
34183672 if TObject(BrowserTab.Tabs.Objects[i]) is TBrowserRecord then begin
34193673 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Thread = ThreadItem then begin
3674+ Result := TBrowserRecord( BrowserTab.Tabs.Objects[i] );
34203675 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).FBrowser = nil then begin
34213676 for j := BrowserTab.Tabs.Count - 1 downto 0 do begin
34223677 if TBrowserRecord(BrowserTab.Tabs.Objects[j]).FBrowser = TWebBrowser(FBrowsers[BROWSER_COUNT - 1]) then begin
@@ -3503,6 +3758,7 @@ begin
35033758 BrowserTab.TabIndex := i;
35043759 end;
35053760 end;
3761+ Result := newBrowser;
35063762 if(ActiveTab) or (idx = -1) then begin
35073763 BrowserTab.OnChange(nil);
35083764 end;
@@ -3512,6 +3768,7 @@ begin
35123768 BrowserNullTab.Browser := Browser;
35133769 end;
35143770 BrowserNullTab.thread := ThreadItem;
3771+ Result := BrowserNullTab;
35153772 BrowserTab.TabIndex := -1;
35163773 SetContent(BrowserNullTab);
35173774 end;
@@ -3531,7 +3788,6 @@ var
35313788 s: string;
35323789 // OldCursor: TCursor;
35333790 i: Integer;
3534- url: OleVariant;
35353791 idx: Integer;
35363792 ThreadItem: TThreadItem;
35373793 Thread: TBrowserRecord;
@@ -3539,6 +3795,7 @@ var
35393795 ThreadScrollTop: Integer;
35403796 ThreadIsLog, ThreadUnRead, ThreadNewArraical: boolean;
35413797 begin
3798+// AddMessageList('SetContent', nil, gmiWhat);
35423799 Thread := inThread;
35433800 idx := BrowserTab.TabIndex;
35443801 if (FActiveContent <> nil) and
@@ -3602,18 +3859,19 @@ begin
36023859
36033860
36043861 try
3862+ {
36053863 if ThreadItem.UnRead then begin
36063864 ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead - 1;
36073865 if ThreadItem.ParentBoard.UnRead < 0 then ThreadItem.ParentBoard.UnRead := 0;
36083866 TreeView.Refresh;
36093867 end;
3610- // LockWindowUpdate(Self.Handle);
3868+ }
36113869 if(FActiveContent <> nil) and (FActiveContent <> Thread) then begin
36123870 if (FActiveContent.Browser <> BrowserNullTab.Browser) then
36133871 ShowWindow(FActiveContent.Browser.Handle, SW_HIDE);
36143872 end;
3873+
36153874 ShowWindow(Thread.FBrowser.Handle, SW_SHOW);
3616- //LockWindowUpdate(0);
36173875 if (not Assigned(Thread.Browser.Document)) then begin
36183876 Thread.Browser.Navigate('about:blank');
36193877 end;
@@ -3640,55 +3898,21 @@ begin
36403898 Self.Caption := CAPTION_NAME + ' - [' + ThreadTitle + ']';
36413899 //Thread.Repaintは、スキン等の設定を変更したとき、Threadをダウンロードしたとき
36423900 //新規にThreadを開いたときに真になっている。
3643-// if(Thread.Repaint) or (Thread.OnlyHundred <> GikoSys.OnlyAHundredRes)then begin
36443901 if Thread.Repaint then begin
36453902 //Thread.LastSize := ThreadItem.Size;
36463903 Thread.Repaint := false;
3647- try
3648- Thread.Browser.OnStatusTextChange := nil;
3649- doc := Idispatch( olevariant(Thread.Browser.ControlInterface).Document) as IHTMLDocument2;
3650- GikoSys.CreateHTML2(doc, ThreadItem, sTitle);
3651-
3652- // if (Assigned(Thread.Browser)) and (Thread.Browser <> nil) then
3653- Thread.Browser.OnStatusTextChange := BrowserStatusTextChange;
3654- //なぜかここで明示的にDocumentCompleteを呼ばないとうまくいかない
3655- //追記 200406/19
3656- //VisibleのときしかDocumentCompleteは呼ばれないらしい
3657- Thread.FBrowser.OnDocumentComplete(Thread.FBrowser, Thread.FBrowser.Parent, url);
3658-// Thread.OnlyHundred := GikoSys.OnlyAHundredRes;
3659- Application.ProcessMessages;
3660- //ここでApplication.ProcessMessagesを呼ぶことによってWebBrowserを更新させる。
3661- //相しないと一画面分しか描画できてないのでそれ以上のスクロール量を指定しても無効になる
3662- // byもじゅ(2004/01/20)
3663- try
3664- //if (Assigned(Thread)) and (Assigned(ThreadItem))then begin
3665- if(Thread <> nil) and (ThreadItem <>nil) then begin
3666- if ThreadUnRead then
3667- BrowserMovement('new', Thread)
3668- else if ThreadScrollTop <> 0 then begin
3669- try
3670- doc.Body.ScrollTop := ThreadScrollTop;
3671- except
3672- on E: Exception do
3673- MsgBox(Handle, E.Message, 'SetContent[ScrollTop<-]', 0);
3674- end;
3675- end;
3676- // end;
3677- end else begin
3678- FActiveContent := nil;
3679- BrowserTab.Repaint;
3680- Exit;
3681- end;
3682- except
3683- FActiveContent := nil;
3684- BrowserTab.Repaint;
3685- Exit;
3686- end;
3687- finally
3688- // Application.ProcessMessages;
3904+
3905+ Thread.Browser.OnStatusTextChange := nil;
3906+ doc := Idispatch( olevariant(Thread.Browser.ControlInterface).Document) as IHTMLDocument2;
3907+ GikoSys.CreateHTML2(doc, ThreadItem, sTitle);
3908+ Thread.Browser.OnStatusTextChange := BrowserStatusTextChange;
3909+ PostMessage( Handle, USER_DOCUMENTCOMPLETE, Integer( Thread.Browser ), 0 );
3910+ if ThreadItem = nil then begin
3911+ FActiveContent := nil;
3912+ BrowserTab.Repaint;
3913+ Exit;
36893914 end;
36903915 end;
3691- ThreadItem.UnRead := False;
36923916 ListView.Refresh;
36933917 end;
36943918 if (Assigned(Thread)) and (Assigned(Thread.Thread)) and (Thread <> nil) and (ThreadItem <>nil) then begin
@@ -3734,7 +3958,6 @@ end;
37343958
37353959 procedure TGikoForm.SetActiveList(Obj: TObject);
37363960 var
3737- i : Integer;
37383961 idx : Integer;
37393962 begin
37403963 // if FActiveList <> Obj then begin
@@ -3748,17 +3971,18 @@ begin
37483971 ListView.Items.Clear;
37493972 ListView.Selected := nil;
37503973 // ListView.Columns.Clear;
3751-
3752- Self.Caption := CAPTION_NAME;
3974+ if (FActiveContent <> nil) and (FActiveContent.Thread <> nil)
3975+ and (FActiveContent.Thread.IsLogFile) then
3976+ Self.Caption := CAPTION_NAME + ' - [' + FActiveContent.Thread.Title + ']'
3977+ else
3978+ Self.Caption := CAPTION_NAME;
37533979 //Application.Title := CAPTION_NAME;
37543980
3981+// ActiveListColumnSave;
3982+
37553983 if Obj is TBBS then begin
3756- for i := 0 to ListView.Columns.Count - 1 do
3757- ListView.Column[i].Width := GikoSys.Setting.BBSColumnWidth[i];
37583984 SetCategoryListItem(TBBS(Obj));
37593985 end else if Obj is TCategory then begin
3760- for i := 0 to ListView.Columns.Count - 1 do
3761- ListView.Column[i].Width := GikoSys.Setting.CategoryColumnWidth[i];
37623986 SetBoardListItem(TCategory(Obj));
37633987 end else if Obj is TBoard then begin
37643988 SetThreadListItem(TBoard(Obj));
@@ -3787,12 +4011,16 @@ end;
37874011 procedure TGikoForm.SetListViewType(AViewType: TGikoViewType; SelectText: string; KubetsuChk: Boolean);
37884012 var
37894013 Board: TBoard;
4014+ i: Integer;
37904015 begin
37914016 if ActiveList is TBoard then begin
4017+ for i := Length( BBSs ) - 1 downto 0 do begin
4018+ BBSs[i].SelectText := SelectText;
4019+ BBSs[i].KubetsuChk := KubetsuChk;
4020+ end;
37924021 Board := TBoard(ActiveList);
3793-
3794- Board.ParentCategory.ParenTBBS.SelectText := SelectText;
3795- Board.ParentCategory.ParenTBBS.KubetsuChk := KubetsuChk;
4022+// Board.ParentCategory.ParenTBBS.SelectText := SelectText;
4023+// Board.ParentCategory.ParenTBBS.KubetsuChk := KubetsuChk;
37964024 // Board.SelectText := SelectText;
37974025 // Board.KubetsuChk := KubetsuChk;
37984026 ViewType := AViewType;
@@ -4297,75 +4525,70 @@ begin
42974525 bbs := nil;
42984526
42994527 if (FTreeType = gtt2ch) and (FActiveBBS = bbs) then begin
4300- ChangeEvent := nil;
4301- ChangingEvent := nil;
4528+ if Item <> FActiveList then begin
4529+ ChangeEvent := nil;
4530+ ChangingEvent := nil;
43024531
4303- if not CallEvent then begin
4304- ChangeEvent := TreeView.OnChange;
4305- ChangingEvent := TreeView.OnChanging;
4306- end;
4307- try
43084532 if not CallEvent then begin
4309- TreeView.OnChange := nil;
4310- TreeView.OnChanging := nil;
4533+ ChangeEvent := TreeView.OnChange;
4534+ ChangingEvent := TreeView.OnChanging;
43114535 end;
4312- //Application.ProcessMessages;
4313- for i := 0 to TreeView.Items.Count - 1 do begin
4314- if TreeView.Items[i].Data = Item then begin
4315- TreeView.Items[i].Selected := True;
4316- if CallEvent then
4317- TreeClick(TreeView.Items[i]);
4318- Break;
4536+ try
4537+ if not CallEvent then begin
4538+ TreeView.OnChange := nil;
4539+ TreeView.OnChanging := nil;
4540+ end;
4541+ //Application.ProcessMessages;
4542+ for i := 0 to TreeView.Items.Count - 1 do begin
4543+ if TreeView.Items[i].Data = Item then begin
4544+ TreeView.Items[i].Selected := True;
4545+ if CallEvent then
4546+ TreeClick(TreeView.Items[i]);
4547+ Break;
4548+ end;
4549+ end;
4550+ //Application.ProcessMessages;
4551+ finally
4552+ if not CallEvent then begin
4553+ TreeView.OnChange := ChangeEvent;
4554+ TreeView.OnChanging := ChangingEvent;
43194555 end;
4320- end;
4321- //Application.ProcessMessages;
4322- finally
4323- if not CallEvent then begin
4324- TreeView.OnChange := ChangeEvent;
4325- TreeView.OnChanging := ChangingEvent;
43264556 end;
43274557 end;
43284558 end else begin
4329- if GetActiveList is TBBS then begin
4330- for i := 0 to ListView.Columns.Count - 1 do
4331- GikoSys.Setting.BBSColumnWidth[i] := ListView.Column[i].Width;
4332- end else if GetActiveList is TCategory then begin
4333- for i := 0 to ListView.Columns.Count - 1 do
4334- GikoSys.Setting.CategoryColumnWidth[i] := ListView.Column[i].Width;
4335- end else if GetActiveList is TBoard then begin
4336- for i := 0 to ListView.Columns.Count - 1 do
4337- GikoSys.Setting.BoardColumnWidth[i] := ListView.Column[i].Width;
4338- end;
4339-
4340- if (Item is TBBS) or (Item is TCategory) then begin
4341- ListView.Columns.Clear;
4342- SetActiveList( Item );
4343- end else if Item is TBoard then begin
4344- if not TBoard( Item ).IsThreadDatRead then begin
4345- Screen.Cursor := crHourGlass;
4346- try
4347- if not TBoard( Item ).IsThreadDatRead then
4348- GikoSys.ReadSubjectFile(TBoard( Item ));
4349- finally
4350- Screen.Cursor := crDefault;
4559+ if Item <> FActiveList then begin
4560+ ActiveListColumnSave;
4561+
4562+ if (Item is TBBS) or (Item is TCategory) then begin
4563+ ListView.Columns.Clear;
4564+ SetActiveList( Item );
4565+ end else if Item is TBoard then begin
4566+ if not TBoard( Item ).IsThreadDatRead then begin
4567+ Screen.Cursor := crHourGlass;
4568+ try
4569+ if not TBoard( Item ).IsThreadDatRead then
4570+ GikoSys.ReadSubjectFile(TBoard( Item ));
4571+ finally
4572+ Screen.Cursor := crDefault;
4573+ end;
43514574 end;
4575+ SetActiveList( Item );
43524576 end;
4353- SetActiveList( Item );
43544577 end;
4578+ end;
43554579
4356- if Item is TBoard then begin // not TCategory
4357- if GikoSys.Setting.ListOrientation = gloHorizontal then begin
4358- if GikoSys.Setting.ListWidthState = glsMax then begin
4359- BrowserMinAction.Execute;
4360- if GikoForm.Visible then
4361- ListView.SetFocus;
4362- end;
4363- end else begin
4364- if GikoSys.Setting.ListHeightState = glsMax then begin
4365- BrowserMinAction.Execute;
4366- if GikoForm.Visible then
4367- ListView.SetFocus;
4368- end;
4580+ if Item is TBoard then begin // not TCategory
4581+ if GikoSys.Setting.ListOrientation = gloHorizontal then begin
4582+ if GikoSys.Setting.ListWidthState = glsMax then begin
4583+ BrowserMinAction.Execute;
4584+ if GikoForm.Visible then
4585+ ListView.SetFocus;
4586+ end;
4587+ end else begin
4588+ if GikoSys.Setting.ListHeightState = glsMax then begin
4589+ BrowserMinAction.Execute;
4590+ if GikoForm.Visible then
4591+ ListView.SetFocus;
43694592 end;
43704593 end;
43714594 end;
@@ -4376,6 +4599,7 @@ procedure TGikoForm.ListViewMouseDown(Sender: TObject;
43764599 var
43774600 listItem : TListItem;
43784601 threadItem : TThreadItem;
4602+ pos : TPoint;
43794603 // t: Cardinal;
43804604 begin
43814605 case Button of
@@ -4399,6 +4623,13 @@ begin
43994623 else
44004624 ListClick;
44014625 end;
4626+ mbRight:
4627+ begin
4628+ pos.X := X;
4629+ pos.Y := Y;
4630+ Windows.ClientToScreen( ListView.Handle, pos );
4631+ ListPopupMenu.Popup( pos.X, pos.Y );
4632+ end;
44024633 end;
44034634 { if ssDouble in Shift then begin
44044635 DoubleClickOccurred[Button] := True;
@@ -4525,11 +4756,11 @@ begin
45254756 top := 0;
45264757 nm := AName;
45274758 item := OleVariant( activeBrower.Document as IHTMLDocument2).anchors.item(nm);
4759+ item.focus();
45284760 repeat
45294761 top := top + item.offsetTop;
45304762 item := item.offsetParent;
45314763 until AnsiCompareText(item.tagName, 'body' ) = 0;
4532-
45334764 OleVariant(activeBrower.Document as IHTMLDocument2).body.scrollTop := top;
45344765 except
45354766 end;
@@ -4557,6 +4788,7 @@ begin
45574788 top := 0;
45584789 nm := AName;
45594790 item := OleVariant( activeBrower.Document as IHTMLDocument2).anchors.item(nm);
4791+ item.focus();
45604792 repeat
45614793 top := top + item.offsetTop;
45624794 item := item.offsetParent;
@@ -5028,15 +5260,23 @@ begin
50285260 case GikoSys.Setting.ListWidthState of
50295261 glsMax: begin
50305262 //通常表示にする
5263+ if FActiveContent <> nil then
5264+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50315265 ViewPanel.Width := FBrowserSizeWidth;
50325266 BrowserMaxAction.ImageIndex := TOOL_ICON_WIDTH_MAX;
50335267 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_MIN;
50345268 GikoSys.Setting.ListWidthState := glsNormal;
5269+ if FActiveContent <> nil then
5270+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50355271 end;
50365272 glsMin, glsNormal: begin
50375273 //最大表示にする
5274+ if FActiveContent <> nil then
5275+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50385276 if GikoSys.Setting.ListWidthState = glsNormal then
50395277 FBrowserSizeWidth := ViewPanel.Width;
5278+ if FActiveContent <> nil then
5279+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50405280 ViewPanel.Width := 1;
50415281 BrowserMaxAction.ImageIndex := TOOL_ICON_WIDTH_NORMAL;
50425282 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_MIN;
@@ -5047,15 +5287,23 @@ begin
50475287 case GikoSys.Setting.ListHeightState of
50485288 glsMax: begin
50495289 //通常表示にする
5290+ if FActiveContent <> nil then
5291+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50505292 ViewPanel.Height := FBrowserSizeHeight;
50515293 BrowserMaxAction.ImageIndex := TOOL_ICON_HEIGHT_MAX;
50525294 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_MIN;
50535295 GikoSys.Setting.ListHeightState := glsNormal;
5296+ if FActiveContent <> nil then
5297+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50545298 end;
50555299 glsMin, glsNormal: begin
50565300 //最大表示にする
5301+ if FActiveContent <> nil then
5302+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50575303 if GikoSys.Setting.ListHeightState = glsNormal then
50585304 FBrowserSizeHeight := ViewPanel.Height;
5305+ if FActiveContent <> nil then
5306+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50595307 ViewPanel.Height := 1;
50605308 BrowserMaxAction.ImageIndex := TOOL_ICON_HEIGHT_NORMAL;
50615309 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_MIN;
@@ -5076,8 +5324,12 @@ begin
50765324 case GikoSys.Setting.ListWidthState of
50775325 glsMax, glsNormal: begin
50785326 //最小表示にする
5327+ if FActiveContent <> nil then
5328+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50795329 if GikoSys.Setting.ListWidthState = glsNormal then
50805330 FBrowserSizeWidth := ViewPanel.Width;
5331+ if FActiveContent <> nil then
5332+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50815333 ViewPanel.Width := ThreadMainPanel.Width - 80;
50825334 BrowserMaxAction.ImageIndex := TOOL_ICON_WIDTH_MAX;
50835335 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_NORMAL;
@@ -5085,29 +5337,41 @@ begin
50855337 end;
50865338 glsMin: begin
50875339 //通常表示にする
5340+ if FActiveContent <> nil then
5341+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50885342 ViewPanel.Width := FBrowserSizeWidth;
50895343 BrowserMaxAction.ImageIndex := TOOL_ICON_WIDTH_MAX;
50905344 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_MIN;
50915345 GikoSys.Setting.ListWidthState := glsNormal;
5346+ if FActiveContent <> nil then
5347+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
50925348 end;
50935349 end;
50945350 end else begin
50955351 case GikoSys.Setting.ListHeightState of
50965352 glsMax, glsNormal: begin
50975353 //最小表示にする
5354+ if FActiveContent <> nil then
5355+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
50985356 if GikoSys.Setting.ListHeightState = glsNormal then
50995357 FBrowserSizeHeight := ViewPanel.Height;
51005358 ViewPanel.Height := ThreadMainPanel.Height - BrowserCoolBar.Height - 7;
51015359 BrowserMaxAction.ImageIndex := TOOL_ICON_HEIGHT_MAX;
51025360 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_NORMAL;
51035361 GikoSys.Setting.ListHeightState := glsMin;
5362+ if FActiveContent <> nil then
5363+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
51045364 end;
51055365 glsMin: begin
51065366 //通常表示にする
5367+ if FActiveContent <> nil then
5368+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 0, 0); //描画停止
51075369 ViewPanel.Height := FBrowserSizeHeight;
51085370 BrowserMaxAction.ImageIndex := TOOL_ICON_HEIGHT_MAX;
51095371 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_MIN;
51105372 GikoSys.Setting.ListHeightState := glsNormal;
5373+ if FActiveContent <> nil then
5374+ SendMessage(FActiveContent.FBrowser.Handle, WM_SETREDRAW, 1, 0); //描画
51115375 end;
51125376 end;
51135377 end;
@@ -5328,9 +5592,8 @@ begin
53285592 end;
53295593
53305594 procedure TGikoForm.FormResize(Sender: TObject);
5331-var
5332- doc : Variant;
53335595 begin
5596+
53345597 MessageListView.Column[0].Width := MessageListView.ClientWidth - 32;
53355598 MainCoolBar.Width := TopPanel.Width - TopRightPanel.Width;
53365599
@@ -5346,17 +5609,10 @@ begin
53465609 end;
53475610 end;
53485611
5349- if FIsMinimize = mtMinimized then begin
5350- if FActiveContent <> nil then begin
5351- //Application.ProcessMessages;
5352- doc := Idispatch( olevariant(FActiveContent.Browser.ControlInterface).Document) as IHTMLDocument2;
5353- doc.Body.ScrollTop := FActiveContent.Thread.ScrollTop;
5354- FIsMinimize := mtNone;
5355- end;
5356- end;
5357-
5358- FIsIgnoreResize := True;
5612+ FIsIgnoreResize := rtResizing;
53595613 PostMessage( Handle, USER_RESIZED, 0, 0 );
5614+
5615+
53605616 end;
53615617
53625618 procedure TGikoForm.ScrollTopActionUpdate(Sender: TObject);
@@ -5444,8 +5700,8 @@ end;
54445700
54455701 procedure TGikoForm.LogDeleteActionExecute(Sender: TObject);
54465702 const
5447- DEL_MSG = '“^0”のログをを削除します。よろしいですか?';
5448- DEL_SAME_MSG = 'これら ^0 個のスレッドのログをを削除します。よろしいですか?';
5703+ DEL_MSG = '“^0”のログを削除します。よろしいですか?';
5704+ DEL_SAME_MSG = 'これら ^0 個のスレッドのログを削除します。よろしいですか?';
54495705 DEL_TITLE = '削除確認';
54505706 var
54515707 ThreadItem: TThreadItem;
@@ -5482,6 +5738,8 @@ begin
54825738 DeleteHistory(ThreadItem);
54835739 DeleteTab(ThreadItem);
54845740 ThreadItem.DeleteLogFile;
5741+
5742+ TreeView.Refresh; // UnRead の表示を更新
54855743 end;
54865744 ListView.Refresh;
54875745 finally
@@ -5667,6 +5925,7 @@ begin
56675925
56685926 Editor := TEditorForm.Create(Self);
56695927 Editor.SetThreadItem(Item);
5928+ GikoSys.LoadEditorKeySetting(Editor.ActionList);
56705929 Editor.BodyEdit.Text := '>>' + IntToStr(Number) + #13#10;
56715930 Editor.Show;
56725931 Editor.BodyEdit.SetFocus;
@@ -6402,11 +6661,13 @@ var
64026661 FDispHtmlDocument: DispHTMLDocument;
64036662 BrowserRecord :TBrowserRecord;
64046663 i :Integer;
6664+ doc : Variant;
6665+ threadItem : TThreadItem;
64056666 begin
6406-// AddMessageList('DocumentComplete', nil);
6667+// AddMessageList('DocumentComplete', nil, gmiWhat);
64076668 if TObject(Sender) is TWebBrowser then begin
6669+ BrowserRecord := nil;
64086670 if TWebBrowser(Sender) <> Browser then begin
6409- BrowserRecord := nil;
64106671 for i := BrowserTab.Tabs.Count - 1 downto 0 do begin
64116672 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser = TWebBrowser(Sender) then begin
64126673 BrowserRecord := TBrowserRecord(BrowserTab.Tabs.Objects[i]);
@@ -6422,7 +6683,7 @@ begin
64226683 BrowserRecord.FEvent.OnClick := WebBrowserClick; //追加したOnClickイベント
64236684 end;
64246685 end else begin
6425- if GetActiveContent <> nil then begin
6686+ if GetActiveContent <> nil then begin
64266687 FDispHtmlDocument := Idispatch(OleVariant(Browser.ControlInterface).Document) as DispHTMLDocument;
64276688 if FEvent <> nil then
64286689 FEvent.Free;
@@ -6431,6 +6692,38 @@ begin
64316692 FEvent.OnClick := WebBrowserClick; //追加したOnClickイベント
64326693 end;
64336694 end;
6695+
6696+ if (BrowserRecord <> nil) and
6697+ Assigned( BrowserRecord.Thread ) then begin
6698+ threadItem := BrowserRecord.Thread;
6699+
6700+ if (BrowserRecord <> nil) and (Length( BrowserRecord.Movement ) > 0) then begin
6701+ if threadItem.UnRead then begin
6702+ threadItem.UnRead := False;
6703+ threadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead - 1;
6704+ if threadItem.ParentBoard.UnRead < 0 then threadItem.ParentBoard.UnRead := 0;
6705+ TreeView.Refresh;
6706+ ListView.Refresh;
6707+ end;
6708+ BrowserMovement( BrowserRecord.Movement, BrowserRecord );
6709+ BrowserRecord.Movement := '';
6710+ end else if threadItem.UnRead then begin
6711+ threadItem.UnRead := False;
6712+ threadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead - 1;
6713+ if threadItem.ParentBoard.UnRead < 0 then threadItem.ParentBoard.UnRead := 0;
6714+ TreeView.Refresh;
6715+ BrowserMovement( 'new', BrowserRecord );
6716+ ListView.Refresh;
6717+ end else if threadItem.ScrollTop <> 0 then begin
6718+ try
6719+ doc := Idispatch( OleVariant( BrowserRecord.Browser.ControlInterface ).Document ) as IHTMLDocument2;
6720+ doc.Body.ScrollTop := threadItem.ScrollTop;
6721+ except
6722+ on E: Exception do
6723+ MsgBox(Handle, E.Message, 'SetContent[ScrollTop<-]', 0);
6724+ end;
6725+ end;
6726+ end;
64346727 end;
64356728 end;
64366729
@@ -6786,7 +7079,7 @@ end;
67867079
67877080 procedure TGikoForm.ActiveLogDeleteActionExecute(Sender: TObject);
67887081 const
6789- DEL_MSG = '“^0”のログをを削除します。よろしいですか?';
7082+ DEL_MSG = '“^0”のログを削除します。よろしいですか?';
67907083 DEL_TITLE = '削除確認';
67917084 var
67927085 idx: Integer;
@@ -7204,14 +7497,13 @@ begin
72047497 end;
72057498 end;
72067499
7207-procedure TGikoForm.MoveToURL(URL: string);
7208-
7500+procedure TGikoForm.MoveToURL(const inURL: string);
72097501 var
72107502 protocol, host, path, document, port, bookmark : string;
7211- URL2, protocol2, host2, path2, document2, port2, bookmark2 : string;
7503+ URL, protocol2, host2, path2, document2, port2, bookmark2 : string;
72127504 tmp1, tmp2: string;
72137505 BBSID, BBSKey: string;
7214- Board: TBoard;
7506+ tmpBoard, Board: TBoard;
72157507 ThreadItem: TThreadItem;
72167508 i, bi : Integer;
72177509 boardURL : string;
@@ -7221,20 +7513,22 @@ var
72217513 // boardNode : TTreeNode;
72227514 shiftDown : Boolean;
72237515 ctrlDown : Boolean;
7516+ stRes, edRes : Int64;
7517+ browserRec : TBrowserRecord;
72247518 begin
72257519
7226- GikoSys.ParseURI( URL, protocol, host, path, document, port, bookmark );
7227- GikoSys.Parse2chURL( URL, path, document, BBSID, BBSKey );
7520+ GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
7521+ GikoSys.Parse2chURL( inURL, path, document, BBSID, BBSKey );
72287522
72297523
72307524 shiftDown := GetAsyncKeyState(VK_SHIFT) = Smallint($8001);
7231- ctrlDown := GetAsyncKeyState(VK_CONTROL) = Smallint($8001);
7232- if shiftDown then begin
7233- GikoSys.OpenBrowser(URL, gbtUserApp);
7234- Exit;
7235- end else if ctrlDown then begin
7236- GikoSys.OpenBrowser(URL, gbtIE);
7237- Exit;
7525+ ctrlDown := GetAsyncKeyState(VK_CONTROL) = Smallint($8001);
7526+ if shiftDown then begin
7527+ GikoSys.OpenBrowser(inURL, gbtUserApp);
7528+ Exit;
7529+ end else if ctrlDown then begin
7530+ GikoSys.OpenBrowser(inURL, gbtIE);
7531+ Exit;
72387532 end;
72397533
72407534 //===== プラグイン
@@ -7243,15 +7537,16 @@ begin
72437537 bi := High( BoardPlugIns );
72447538 for i := Low( BoardPlugIns ) to bi do begin
72457539 if Assigned( Pointer( BoardPlugIns[ i ].Module ) ) then begin
7246- case BoardPlugIns[ i ].AcceptURL( URL ) of
7540+ case BoardPlugIns[ i ].AcceptURL( inURL ) of
72477541 atThread:
72487542 begin
7249- tmpThread := TThreadItem.Create( BoardPlugIns[ i ], URL );
7543+ tmpThread := TThreadItem.Create( BoardPlugIns[ i ], inURL );
72507544 boardURL := tmpThread.BoardPlugIn.GetBoardURL( DWORD( tmpThread ) );
72517545 Board := BBSsFindBoardFromURL( boardURL );
72527546 if Board = nil then begin
7547+ //break;
72537548 // ※作っても追加するところが無いので激しく保留
7254- //GikoSys.OpenBrowser(URL, gbtUserApp);
7549+ //GikoSys.OpenBrowser(inURL, gbtUserApp);
72557550 //Exit;
72567551 {
72577552 Board := GikoSys.GetUnknownBoard( tmpThread.BoardPlugIn, boardURL );
@@ -7263,34 +7558,42 @@ begin
72637558 GikoSys.ReadSubjectFile( Board );
72647559 Exit;
72657560 end;
7266- end;
7267-
7268- ThreadItem := Board.FindThreadFromFileName( tmpThread.FileName );
7269- if ThreadItem = nil then begin
7270- ThreadItem := tmpThread;
7271- Board.Insert( 0, ThreadItem );
7272- if ActiveList is TBoard then begin
7273- if TBoard(ActiveList) = Board then
7274- ListView.Items.Count := ListView.Items.Count + 1;
7275- end;
7276- InsertBrowserTab( ThreadItem );
7277- DownloadContent( ThreadItem );
7278- Exit;
7279- end else begin
7280- tmpThread.Free;
7281- InsertBrowserTab( ThreadItem );
7282- if not ThreadItem.IsLogFile then begin
7561+ ThreadItem := Board.FindThreadFromFileName( tmpThread.FileName );
7562+ if ThreadItem = nil then begin
7563+ ThreadItem := tmpThread;
7564+ Board.Insert( 0, ThreadItem );
7565+ if ActiveList is TBoard then begin
7566+ if TBoard(ActiveList) = Board then
7567+ ListView.Items.Count := ListView.Items.Count + 1;
7568+ end;
7569+ GikoSys.GetPopupResNumber( inURL, stRes, edRes );
7570+ browserRec := InsertBrowserTab( ThreadItem );
7571+ if (browserRec <> nil) and (stRes > 0) then
7572+ browserRec.Movement := IntToStr( stRes );
72837573 DownloadContent( ThreadItem );
7574+ Exit;
7575+ end else begin
7576+ tmpThread.Free;
7577+ GikoSys.GetPopupResNumber( inURL, stRes, edRes );
7578+ browserRec := InsertBrowserTab( ThreadItem );
7579+ if ThreadItem.IsLogFile then begin
7580+ if (browserRec <> nil) and (stRes > 0) then
7581+ BrowserMovement( IntToStr( stRes ), browserRec );
7582+ end else begin
7583+ if (browserRec <> nil) and (stRes > 0) then
7584+ browserRec.Movement := IntToStr( stRes );
7585+ DownloadContent( ThreadItem );
7586+ end;
7587+ Exit;
72847588 end;
7285- Exit;
72867589 end;
7287-
7288- //Exit;
72897590 end;
72907591
72917592 atBoard:
72927593 begin
7293- Board := BBSsFindBoardFromURL( URL );
7594+ tmpBoard := TBoard.Create(BoardPlugIns[ i ], inURL);
7595+ Board := BBSsFindBoardFromURL( tmpBoard.URL );
7596+ tmpBoard.Free;
72947597 if Board <> nil then begin
72957598 if FActiveBBS <> Board.ParentCategory.ParenTBBS then
72967599 ShowBBSTree( Board.ParentCategory.ParenTBBS );
@@ -7307,7 +7610,7 @@ begin
73077610
73087611
73097612 if (Length( Trim(BBSKey) ) > 0) and (Length( Trim(BBSID) ) > 0) then begin
7310- boardURL := GikoSys.Get2chThreadURL2BoardURL( URL );
7613+ boardURL := GikoSys.Get2chThreadURL2BoardURL( inURL );
73117614 Board := BBSsFindBoardFromURL( boardURL );
73127615 if Board = nil then
73137616 Board := BBSsFindBoardFromBBSID( BBSID );
@@ -7319,23 +7622,23 @@ begin
73197622 end;
73207623 if Board = nil then begin
73217624 // 入るべき板が見つからなかったので、普通のブラウザで開く
7322- GikoSys.OpenBrowser(URL, gbtUserApp);
7625+ GikoSys.OpenBrowser(inURL, gbtUserApp);
73237626 Exit;
73247627 end else begin
73257628 // 外部の板なのに2chのURLにされてしまった奴をここで確認する
7326- URL2 := Board.URL;
7327- GikoSys.ParseURI(URL2 , protocol2, host2, path2, document2, port2, bookmark2 );
7629+ URL := Board.URL;
7630+ GikoSys.ParseURI(URL , protocol2, host2, path2, document2, port2, bookmark2 );
73287631 tmp1 := Copy(host, AnsiPos('.', host) + 1, Length(host));
73297632 tmp2 := Copy(host2, AnsiPos('.', host2) + 1, Length(host2));
7330- if (tmp1 <> tmp2) then begin
7331- GikoSys.OpenBrowser(URL, gbtUserApp);
7633+ if ( not GikoSys.Is2chHost(tmp1)) and (tmp1 <> tmp2) then begin
7634+ GikoSys.OpenBrowser(inURL, gbtUserApp);
73327635 Exit;
73337636 end;
73347637 end;
73357638
73367639 if not Board.IsThreadDatRead then
73377640 GikoSys.ReadSubjectFile(Board);
7338- URL := GikoSys.Get2chBrowsableThreadURL( URL );
7641+ URL := GikoSys.Get2chBrowsableThreadURL( inURL );
73397642 ThreadItem := Board.FindThreadFromURL( URL );
73407643 // 過去ログ倉庫から、ダウソしたスレが発見できないのでここで探すようにする (2004/01/22)
73417644 if ThreadItem = nil then begin
@@ -7348,9 +7651,9 @@ begin
73487651 {shiftDown := GetAsyncKeyState(VK_SHIFT) = Smallint($8001);
73497652 ctrlDown := GetAsyncKeyState(VK_CONTROL) = Smallint($8001);
73507653 if shiftDown then
7351- GikoSys.OpenBrowser(URL, gbtUserApp)
7654+ GikoSys.OpenBrowser(URL1, gbtUserApp)
73527655 else if ctrlDown then
7353- GikoSys.OpenBrowser(URL, gbtIE)
7656+ GikoSys.OpenBrowser(URL1, gbtIE)
73547657 else begin
73557658 }
73567659 ThreadItem := TThreadItem.Create( nil, URL );
@@ -7364,25 +7667,34 @@ begin
73647667 if TBoard(ActiveList) = Board then
73657668 ListView.Items.Count := ListView.Items.Count + 1;
73667669 end;
7367- InsertBrowserTab(ThreadItem);
7670+ GikoSys.GetPopupResNumber( inURL, stRes, edRes );
7671+ browserRec := InsertBrowserTab(ThreadItem);
7672+ if (browserRec <> nil) and (stRes > 0) then
7673+ browserRec.Movement := IntToStr( stRes );
73687674 DownloadContent(ThreadItem);
73697675 {end;}
73707676 end else begin
7371- if ThreadItem.IsLogFile then
7372- InsertBrowserTab(ThreadItem)
7373- else begin
7677+ if ThreadItem.IsLogFile then begin
7678+ GikoSys.GetPopupResNumber( inURL, stRes, edRes );
7679+ browserRec := InsertBrowserTab(ThreadItem);
7680+ if (browserRec <> nil) and (stRes > 0) then
7681+ browserRec.Movement := IntToStr( stRes );
7682+ end else begin
73747683 if AnsiPos(Host, Board.URL) = 0 then
73757684 ThreadItem.DownloadHost := Host
73767685 else
73777686 ThreadItem.DownloadHost := '';
7378- InsertBrowserTab(ThreadItem);
7687+ GikoSys.GetPopupResNumber( inURL, stRes, edRes );
7688+ browserRec := InsertBrowserTab(ThreadItem);
7689+ if (browserRec <> nil) and (stRes > 0) then
7690+ browserRec.Movement := IntToStr( stRes );
73797691 DownloadContent(ThreadItem);
73807692 end;
73817693 end;
73827694 end else begin
7383- Board := BBSsFindBoardFromURL( URL );
7695+ Board := BBSsFindBoardFromURL( inURL );
73847696 if Board = nil then begin
7385- GikoSys.OpenBrowser(URL, gbtAuto);
7697+ GikoSys.OpenBrowser(inURL, gbtAuto);
73867698 end else begin
73877699 if FActiveBBS <> Board.ParentCategory.ParenTBBS then
73887700 ShowBBSTree( Board.ParentCategory.ParenTBBS );
@@ -7428,6 +7740,9 @@ begin
74287740 end;
74297741
74307742 procedure TGikoForm.WndProc(var Message: TMessage);
7743+var
7744+ senderBrowser : TWebBrowser;
7745+ url : OleVariant;
74317746 begin
74327747 try
74337748 case Message.Msg of
@@ -7445,6 +7760,12 @@ begin
74457760 OnMinimized;
74467761 USER_SETLINKBAR:
74477762 SetLinkBar;
7763+ USER_DOCUMENTCOMPLETE:
7764+ if (Message.WParam <> 0) and
7765+ (TObject(Message.WParam) is TWebBrowser) then begin
7766+ senderBrowser := TWebBrowser( Message.WParam );
7767+ BrowserDocumentComplete( senderBrowser, senderBrowser.Parent, url );
7768+ end;
74487769 end;
74497770
74507771 inherited;
@@ -7899,10 +8220,10 @@ var
78998220 j: Integer;
79008221 ToolButton: TLinkToolButton;
79018222 MenuItem: TMenuItem;
7902- oldIgnoreResize : Boolean;
8223+ oldIgnoreResize : TResizeType;
79038224 begin
79048225 oldIgnoreResize := FIsIgnoreResize;
7905- FIsIgnoreResize := True;
8226+ FIsIgnoreResize := rtResizing;
79068227 MainCoolBar.Bands.BeginUpdate;
79078228 try
79088229 LinkBarPopupMenu.Items.Clear;
@@ -7995,7 +8316,7 @@ begin
79958316 if FDropSpaceNode <> nil then
79968317 FDropSpaceNode.Free;
79978318
7998- FDropSpaceNode := FavoriteDM.TreeView.Items.AddChildObject(Node.Parent, '', nil );
8319+ FDropSpaceNode := FavoriteDM.TreeView.Items.AddChildObjectFirst(Node.Parent, '', nil );
79998320 FDropSpaceNode.MoveTo( Node, naInsert );
80008321 FDropSpaceNode.ImageIndex := -1;
80018322 FDropSpaceNode.SelectedIndex := -1;
@@ -8361,7 +8682,7 @@ begin
83618682 end;
83628683 end;
83638684 // 設定
8364- lResult := SendMessage( bar.Handle, RB_SETBANDINFO, i, Integer( pBandInfo ) );
8685+ lResult := SendMessage( bar.Handle, RB_SETBANDINFO, idx, Integer( pBandInfo ) );
83658686
83668687 end;
83678688
@@ -8606,12 +8927,11 @@ procedure TGikoForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
86068927 var
86078928 Wnd: THandle;
86088929 delta: Integer;
8609-// msg: TMessage;
8930+// browserPos : TPoint;
86108931 const
86118932 ICON_SIZE = 16;
86128933 begin
8613- Handled := False;
8614- Wnd := WindowFromPoint(MousePos);
8934+ Wnd := WindowFromPoint(Mouse.CursorPos);
86158935 Handled := True;
86168936 if WheelDelta > 0 then
86178937 Delta := -1
@@ -8621,13 +8941,42 @@ begin
86218941 if (Wnd = BrowserTab.Handle) or
86228942 (Wnd = BrowserTab.Parent.Handle) then begin
86238943 BrowserTab.ScrollTabs(Delta);
8624- end else if Wnd = ListView.Handle then begin
8625- if ListView.ViewStyle = vsList then
8626- ListView.Scroll( Delta * Mouse.WheelScrollLines * Abs( ListView.Font.Height ) + Delta * ICON_SIZE, 0 )
8627- else
8628- ListView.Scroll( 0, Delta * Mouse.WheelScrollLines * Abs( ListView.Font.Height ) + Delta * ICON_SIZE );
86298944 end else begin
8630- Handled := False;
8945+ if FIsHandledWheel then begin
8946+ FIsHandledWheel := False;
8947+ Handled := False;
8948+ end else begin
8949+ FIsHandledWheel := True;
8950+ if (Wnd = TreeView.Handle) or (Wnd = FavoriteTreeView.Handle)
8951+ or (Wnd = ListView.Handle) or (Wnd = MessageListView.Handle)
8952+ then
8953+ SendMessage( Wnd, WM_MOUSEWHEEL, WheelDelta shl 16, (Mouse.CursorPos.X shl 16) or Mouse.CursorPos.Y )
8954+ else
8955+ Handled := False;
8956+
8957+{
8958+// if (FActiveContent <> nil) and (FActiveContent.Browser <> nil) then begin
8959+ // TWebBrowser の Handle と比較しても一致しないので座標で TWebBrowser かどうか判定
8960+ browserPos.X := 0;
8961+ browserPos.Y := 0;
8962+ Windows.ClientToScreen( Browser.Handle, browserPos );
8963+ if (Longword(Mouse.CursorPos.X - browserPos.X) >= Browser.Width)
8964+ or (Longword(Mouse.CursorPos.Y - browserPos.Y) >= Browser.Height)
8965+ or (Longword(Mouse.CursorPos.Y - browserPos.Y) < 0)
8966+ or (Longword(Mouse.CursorPos.Y - browserPos.Y) < 0) then begin
8967+// or not FActiveContent.Browser.Focused then
8968+ // TWebBrowser は無限ループするのでそれ以外ならコントロールに送信
8969+ if (Wnd <> BrowserToolBar.Handle) and (Wnd <> BrowserNameToolBar.Handle) then
8970+ SendMessage( Wnd, WM_MOUSEWHEEL, WheelDelta shl 16, (Mouse.CursorPos.X shl 16) or Mouse.CursorPos.Y )
8971+ else
8972+ Handled := False;
8973+ end else begin
8974+ Handled := False;
8975+ end;
8976+// end else begin
8977+// SendMessage( Wnd, WM_MOUSEWHEEL, WheelDelta shl 16, (MousePos.X shl 16) or MousePos.Y );
8978+// end;
8979+} end;
86318980 end;
86328981 end;
86338982
@@ -8664,9 +9013,10 @@ begin
86649013 ModifySelectList;
86659014 end else if Length( SelectComboBox.Text ) = 0 then
86669015 begin
8667- AllItemAction.Checked := True;
8668- LogItemAction.Checked := False;
8669- NewItemAction.Checked := False;
9016+ {* SelectComboBox.Textが空でも、入力途中でEscしたとか
9017+ * 空のときにDelキーを押したとかなので、スレの絞込みを維持する。
9018+ * (ここでは何もしない)
9019+ *}
86709020 end else begin
86719021 // チラつくと嫌だから、一応押してあるときだけ処理する
86729022 if AllItemAction.Checked then
@@ -8797,11 +9147,6 @@ begin
87979147 SelectResAction.Enabled := (GetActiveContent <> nil) and (GetActiveContent.IsLogFile);
87989148 end;
87999149
8800-procedure TGikoForm.FormKeyUp(Sender: TObject; var Key: Word;
8801- Shift: TShiftState);
8802-begin
8803-end;
8804-
88059150 // 全てのレスを表示
88069151 procedure TGikoForm.AllResActionExecute(Sender: TObject);
88079152 var
@@ -9306,25 +9651,26 @@ end;
93069651 procedure TGikoForm.FavoriteTreeViewKeyDown(Sender: TObject; var Key: Word;
93079652 Shift: TShiftState);
93089653 begin
9309-
9310- Case Key of
9311- VK_F2:
9312- begin
9313- FClickNode := FavoriteTreeView.Selected;
9314- FavoriteTreeViewRenameActionExecute( Sender );
9315- end;
9316- VK_DELETE:
9317- begin
9318- FClickNode := FavoriteTreeView.Selected;
9319- FavoriteTreeViewDeleteActionExecute( Sender );
9320- end;
9321- VK_RETURN:
9322- begin
9323- FavoriteClick( FavoriteTreeView.Selected );
9324- FavoriteTreeView.Selected.Expanded := not FavoriteTreeView.Selected.Expanded;
9654+ if not TTreeView(Sender).IsEditing then begin
9655+ Case Key of
9656+ VK_F2:
9657+ begin
9658+ FClickNode := FavoriteTreeView.Selected;
9659+ FavoriteTreeViewRenameActionExecute( Sender );
9660+ end;
9661+ VK_DELETE:
9662+ begin
9663+ FClickNode := FavoriteTreeView.Selected;
9664+ FavoriteTreeViewDeleteActionExecute( Sender );
9665+ end;
9666+ VK_RETURN:
9667+ begin
9668+ FavoriteClick( FavoriteTreeView.Selected );
9669+ FavoriteTreeView.Selected.Expanded := not FavoriteTreeView.Selected.Expanded;
9670+ end;
9671+ VK_SPACE:
9672+ FavoriteTreeViewDblClick( Sender );
93259673 end;
9326- VK_SPACE:
9327- FavoriteTreeViewDblClick( Sender );
93289674 end;
93299675
93309676 end;
@@ -9576,7 +9922,7 @@ end;
95769922 procedure TGikoForm.FavoriteTreeViewLogDeleteActionExecute(
95779923 Sender: TObject);
95789924 const
9579- DEL_MSG = '“^0”のログをを削除します。よろしいですか?';
9925+ DEL_MSG = '“^0”のログを削除します。よろしいですか?';
95809926 DEL_TITLE = '削除確認';
95819927 var
95829928 ThreadItem: TThreadItem;
@@ -9719,7 +10065,7 @@ begin
971910065 ThreadItem := FavThread.Item;
972010066
972110067 try
9722- s := ThreadItem.URL + #13#10 + ThreadItem.Title + #13#10;
10068+ s := ThreadItem.Title + #13#10 + ThreadItem.URL + #13#10;
972310069 if s <> '' then
972410070 Clipboard.AsText := s;
972510071 finally
@@ -9734,7 +10080,7 @@ begin
973410080 GikoSys.ReadSubjectFile(Board);
973510081
973610082 try
9737- s := Board.URL + #13#10 + Board.Title + #13#10;
10083+ s := Board.Title + #13#10 + Board.URL + #13#10;
973810084 if s <> '' then
973910085 Clipboard.AsText := s;
974010086 finally
@@ -9791,7 +10137,12 @@ procedure TGikoForm.BrowserTabMouseUp(Sender: TObject;
979110137 begin
979210138 if FDragWFirst <> true then begin
979310139 FDragWFirst := false;
9794- end else if (X = FMouseDownPos.X) and (Y = FMouseDownPos.Y) then begin
10140+{
10141+ end else if (abs( X - FMouseDownPos.X ) < Mouse.DragThreshold)
10142+ and (abs( Y - FMouseDownPos.Y ) < Mouse.DragThreshold) then begin
10143+(*}
10144+ end else begin
10145+//*)
979510146 if GikoSys.Setting.ListOrientation = gloHorizontal then begin
979610147 if GikoSys.Setting.ListWidthState = glsMin then begin
979710148 BrowserMaxAndFocusAction.Execute;
@@ -9875,9 +10226,9 @@ end;
987510226 procedure TGikoForm.SetListViewBackGroundColor(value: TColor);
987610227 begin
987710228 if FListViewBackGroundColor <> value then begin
9878- FListViewBackGroundColor := value;
9879- ListView.Color := FListViewBackGroundColor;
9880- end;
10229+ FListViewBackGroundColor := value;
10230+ ListView.Color := FListViewBackGroundColor;
10231+ end;
988110232 end;
988210233 procedure TGikoForm.ExportFavoriteFileBeforeExecute(Sender: TObject);
988310234 begin
@@ -10064,63 +10415,62 @@ end;
1006410415 procedure TGikoForm.TabFileURLReplace(oldURLs: TStringList; newURLs: TStringList);
1006510416 var
1006610417 i: Integer;
10067- j: Integer;
10068- tempString: string;
10069- tmpURL: string;
10070- oldHost: string;
10071- oldBoardName: string;
10072- newHost: string;
10073- newBoardName: string;
10074- TabList: TStringList;
10075-begin
10076- TabList := TStringList.Create;
10077- if oldURLs.Count <> newURLs.Count then
10078- Exit;
10079- //ここから、BoardのURLの変更
10080- for j :=0 to oldURLs.Count - 1 do begin
10418+ j: Integer;
10419+ tempString: string;
10420+ tmpURL: string;
10421+ oldHost: string;
10422+ oldBoardName: string;
10423+ newHost: string;
10424+ newBoardName: string;
10425+ TabList: TStringList;
10426+begin
10427+ TabList := TStringList.Create;
10428+ if oldURLs.Count <> newURLs.Count then
10429+ Exit;
10430+ //ここから、BoardのURLの変更
10431+ for j :=0 to oldURLs.Count - 1 do begin
1008110432 for i :=0 to TabList.Count - 1 do begin
1008210433 if TabList.Text = oldURLs[j] then
10083- TabList.Text := newURLs[j];
10084- end;
10085- end;
10086- //ここまで、BoardのURLの変更
10087-
10088- //ここから、ThreadのURLの変更
10089- //面倒だけどthreadはそれぞれURLをチャックしながらやってかなきゃいけない。
10090- for i := 0 to oldURLs.Count - 1 do begin
10091- tmpURL := Copy(oldURLs[i], 1, Length(oldURLs[i]) -1);
10092- oldHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
10093- oldBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
10094- tmpURL := Copy(newURLs[i], 1, Length(newURLs[i]) -1);
10095- newHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
10096- newBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
10097-
10098- for j := 0 to TabList.Count - 1 do begin
10099- tempString := TabList.Text;
10100- if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
10101- tempString := StringReplace(tempString, oldHost, newHost,[]);
10102- TabList.Text := tempString;
10103- end;
10104- end;
10434+ TabList.Text := newURLs[j];
10435+ end;
10436+ end;
10437+ //ここまで、BoardのURLの変更
10438+
10439+ //ここから、ThreadのURLの変更
10440+ //面倒だけどthreadはそれぞれURLをチャックしながらやってかなきゃいけない。
10441+ for i := 0 to oldURLs.Count - 1 do begin
10442+ tmpURL := Copy(oldURLs[i], 1, Length(oldURLs[i]) -1);
10443+ oldHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
10444+ oldBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
10445+ tmpURL := Copy(newURLs[i], 1, Length(newURLs[i]) -1);
10446+ newHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
10447+ newBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
10448+
10449+ for j := 0 to TabList.Count - 1 do begin
10450+ tempString := TabList.Text;
10451+ if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
10452+ tempString := StringReplace(tempString, oldHost, newHost,[]);
10453+ TabList.Text := tempString;
10454+ end;
10455+ end;
1010510456 end;
10106- //ここまで、ThreadのURLの変更
10457+ //ここまで、ThreadのURLの変更
1010710458
1010810459 end;
1010910460
10110-// 最小化される
10461+/// 最小化される
1011110462 procedure TGikoForm.OnMinimize;
1011210463 begin
10113- FIsMinimize := mtMinimizing;
10114- if FActiveContent <> nil then
10464+ if FActiveContent <> nil then begin
10465+ FIsMinimize := mtMinimizing;
1011510466 FActiveContent.Thread.ScrollTop := OleVariant(IHTMLDocument2(FActiveContent.Browser.Document)).Body.ScrollTop;
10116- PostMessage( Handle, USER_MINIMIZED, 0, 0 );
10467+ end;
1011710468 end;
1011810469
10119-// 最小化された
10470+/// 最小化された (OnResized から呼ばれる)
1012010471 procedure TGikoForm.OnMinimized;
1012110472 begin
1012210473 FIsMinimize := mtMinimized;
10123- FIsIgnoreResize := False;
1012410474 end;
1012510475
1012610476 procedure TGikoForm.CoolBarResized(Sender: TObject; CoolBar: TCoolBar);
@@ -10131,8 +10481,8 @@ var
1013110481 affectedBand : TCoolBand;
1013210482 i : Integer;
1013310483 begin
10134- if (FOldFormWidth = Width) and not IsIconic( Handle ) and not FIsIgnoreResize then begin
10135- FIsIgnoreResize := True;
10484+ if (FOldFormWidth = Width) and not IsIconic( Handle ) and (FIsIgnoreResize = rtNone) then begin
10485+ FIsIgnoreResize := rtResizing;
1013610486 PostMessage( Handle, USER_RESIZED, 0, 0 );
1013710487 if not (Sender is TToolBar) or (CoolBar = nil) then
1013810488 Exit;
@@ -10273,8 +10623,6 @@ begin
1027310623 end;
1027410624 // TreeView がクリックされた
1027510625 procedure TGikoForm.TreeClick( Node : TTreeNode );
10276-var
10277- i: Integer;
1027810626 begin
1027910627
1028010628 if Node = nil then
@@ -10288,16 +10636,7 @@ begin
1028810636 Exit;
1028910637 end;
1029010638
10291- if GetActiveList is TBBS then begin
10292- for i := 0 to ListView.Columns.Count - 1 do
10293- GikoSys.Setting.BBSColumnWidth[i] := ListView.Column[i].Width;
10294- end else if GetActiveList is TCategory then begin
10295- for i := 0 to ListView.Columns.Count - 1 do
10296- GikoSys.Setting.CategoryColumnWidth[i] := ListView.Column[i].Width;
10297- end else if GetActiveList is TBoard then begin
10298- for i := 0 to ListView.Columns.Count - 1 do
10299- GikoSys.Setting.BoardColumnWidth[i] := ListView.Column[i].Width;
10300- end;
10639+ ActiveListColumnSave;
1030110640
1030210641 if TObject(Node.Data) is TBBS then begin
1030310642 SetActiveList(Node.data);
@@ -10412,7 +10751,6 @@ end;
1041210751
1041310752 // ギコナビのメッセージループを横取りします
1041410753 procedure TGikoForm.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
10415-
1041610754 //var
1041710755 // key : Word;
1041810756 begin
@@ -10478,7 +10816,7 @@ end;
1047810816 procedure TGikoForm.MessagePanelResize(Sender: TObject);
1047910817 begin
1048010818
10481- if FIsIgnoreResize then
10819+ if FIsIgnoreResize <> rtNone then
1048210820 Exit;
1048310821
1048410822 if GikoSys.Setting.ListOrientation = gloVertical then begin
@@ -10491,10 +10829,30 @@ begin
1049110829 end;
1049210830
1049310831 procedure TGikoForm.OnResized;
10832+var
10833+ doc : Variant;
1049410834 begin
1049510835
1049610836 FOldFormWidth := Width;
10497- FIsIgnoreResize := False;
10837+ FIsIgnoreResize := rtNone;
10838+
10839+ case FIsMinimize of
10840+ mtMinimizing:
10841+ begin
10842+ // 最小化中である
10843+ PostMessage( Handle, USER_MINIMIZED, 0, 0 );
10844+ end;
10845+
10846+ mtMinimized:
10847+ begin
10848+ // 最小化は既に完了している (つまりタスクバーからウィンドウを復元中)
10849+ if FActiveContent <> nil then begin
10850+ doc := Idispatch( olevariant(FActiveContent.Browser.ControlInterface).Document) as IHTMLDocument2;
10851+ doc.Body.ScrollTop := FActiveContent.Thread.ScrollTop;
10852+ end;
10853+ FIsMinimize := mtNone;
10854+ end;
10855+ end;
1049810856
1049910857 end;
1050010858
@@ -10810,12 +11168,16 @@ begin
1081011168 SelectListItem(List);
1081111169 for i := 0 to List.Count - 1 do begin
1081211170 if TObject(List[i]) is TThreadItem then begin
10813- TThreadItem(List[i]).UnRead := false;
10814- TThreadItem(List[i]).ParentBoard.UnRead := TThreadItem(List[i]).ParentBoard.UnRead - 1;
11171+ if (TThreadItem(List[i]).UnRead) then begin
11172+ TThreadItem(List[i]).UnRead := false;
11173+ TThreadItem(List[i]).ParentBoard.UnRead := TThreadItem(List[i]).ParentBoard.UnRead - 1;
11174+ end;
1081511175 end;
1081611176 end;
1081711177 if TreeView.Visible then
1081811178 TreeView.Refresh;
11179+ if ListView.Visible then
11180+ ListView.Refresh;
1081911181 finally
1082011182 List.Free;
1082111183 end;
@@ -10831,12 +11193,16 @@ begin
1083111193 SelectListItem(List);
1083211194 for i := 0 to List.Count - 1 do begin
1083311195 if TObject(List[i]) is TThreadItem then begin
10834- TThreadItem(List[i]).UnRead := true;
10835- TThreadItem(List[i]).ParentBoard.UnRead := TThreadItem(List[i]).ParentBoard.UnRead + 1;
11196+ if (TThreadItem(List[i]).IsLogFile) and (not TThreadItem(List[i]).UnRead) then begin
11197+ TThreadItem(List[i]).UnRead := true;
11198+ TThreadItem(List[i]).ParentBoard.UnRead := TThreadItem(List[i]).ParentBoard.UnRead + 1;
11199+ end;
1083611200 end;
1083711201 end;
1083811202 if TreeView.Visible then
1083911203 TreeView.Refresh;
11204+ if ListView.Visible then
11205+ ListView.Refresh;
1084011206 finally
1084111207 List.Free;
1084211208 end;
@@ -10847,11 +11213,8 @@ procedure TGikoForm.BrowserPanelCanResize(Sender: TObject; var NewWidth,
1084711213 var
1084811214 i: Integer;
1084911215 begin
10850- for i := 0 to BROWSER_COUNT - 1 do
11216+ for i := BROWSER_COUNT - 1 downto 0 do begin
1085111217 SetWindowPos(TWebBrowser(FBrowsers[i]).Handle, HWND_NOTOPMOST, 0, 0, NewWidth, NewHeight, SWP_NOMOVE + SWP_NOZORDER);
10852-
10853- if (FActiveContent <> nil) and (FActiveContent.Browser <> nil) then begin
10854- SetWindowPos(FActiveContent.Browser.Handle, HWND_NOTOPMOST, 0, 0, NewWidth, NewHeight, SWP_NOMOVE + SWP_NOZORDER);
1085511218 end;
1085611219 end;
1085711220
@@ -10918,14 +11281,24 @@ end;
1091811281
1091911282 function TGikoForm.SaveTabURLs : Boolean;
1092011283 var
10921- SaveStringList: TStringList;
11284+ SaveStringList, BackStrList: TStringList;
1092211285 begin
1092311286 SaveStringList := TStringList.Create;
11287+ BackStrList := TStringList.Create;
11288+
11289+ //バックアップ
11290+ BackStrList.LoadFromFile(ExtractFilePath(Application.ExeName) + 'tab.sav');
11291+ BackStrList.SaveToFile(ExtractFilePath(Application.ExeName) + '~tab.sav');
11292+ BackStrList.Free;
11293+ //バックアップを作る。
1092411294 try
1092511295 Result := GetTabURLs(SaveStringList);
11296+ if not Result then begin
11297+ Exit; //逃げ
11298+ end;
1092611299 SaveStringList.SaveToFile(ExtractFilePath(Application.ExeName) + 'tab.sav');
1092711300 finally
10928- SaveStringList.Free
11301+ SaveStringList.Free;
1092911302 end;
1093011303 end;
1093111304
@@ -10990,7 +11363,7 @@ end;
1099011363 procedure TGikoForm.TabsSaveToFileActionExecute(Sender: TObject);
1099111364 var
1099211365 SaveTabList: TStringList;
10993- Result: Boolean;
11366+ Result: Boolean;
1099411367 begin
1099511368 SaveTabList := TStringList.Create;
1099611369 try
@@ -11211,6 +11584,225 @@ begin
1121111584 LoadTabURLs;
1121211585 end;
1121311586
11587+/// ListView のカラム幅および位置の保存
11588+procedure TGikoForm.ActiveListColumnSave;
11589+var
11590+ ActivListObj : TObject;
11591+ i, id, idx : Integer;
11592+ BBSOrder : TGikoBBSColumnList;
11593+ CategoryOrder : TGikoCategoryColumnList;
11594+ BoardOrder : TGikoBoardColumnList;
11595+begin
11596+
11597+ ActivListObj := ActiveList;
11598+ if ActivListObj is TBBS then begin
11599+ //===== カテゴリリスト =====
11600+ BBSOrder := TGikoBBSColumnList.Create;
11601+ try
11602+ for i := 0 to ListView.Columns.Count - 1 do begin
11603+ // 順序の取得
11604+ idx := ListView.Column[ i ].Tag;
11605+ id := Ord( GikoSys.Setting.BBSColumnOrder[ idx ] );
11606+ BBSOrder.Add( TGikoBBSColumnID( id ) );
11607+ // 幅の保存
11608+ GikoSys.Setting.BBSColumnWidth[ id ] := ListView.Column[ i ].Width;
11609+ end;
11610+ for i := 0 to ListView.Columns.Count - 1 do
11611+ // 順序の保存
11612+ GikoSys.Setting.BBSColumnOrder[ i ] := BBSOrder[ i ];
11613+ finally
11614+ BBSOrder.Free;
11615+ end;
11616+ end else if ActivListObj is TCategory then begin
11617+ //===== 板リスト =====
11618+ CategoryOrder := TGikoCategoryColumnList.Create;
11619+ try
11620+ for i := 0 to ListView.Columns.Count - 1 do begin
11621+ // 順序の取得
11622+ idx := ListView.Column[ i ].Tag;
11623+ id := Ord( GikoSys.Setting.CategoryColumnOrder[ idx ] );
11624+ CategoryOrder.Add( TGikoCategoryColumnID( id ) );
11625+ // 幅の保存
11626+ GikoSys.Setting.CategoryColumnWidth[ id ] := ListView.Column[ i ].Width;
11627+ end;
11628+ for i := 0 to ListView.Columns.Count - 1 do
11629+ // 順序の保存
11630+ GikoSys.Setting.CategoryColumnOrder[ i ] := CategoryOrder[ i ];
11631+ finally
11632+ CategoryOrder.Free;
11633+ end;
11634+ end else if ActivListObj is TBoard then begin
11635+ //===== スレリスト =====
11636+ BoardOrder := TGikoBoardColumnList.Create;
11637+ try
11638+ for i := 0 to ListView.Columns.Count - 1 do begin
11639+ // 順序の取得
11640+ idx := ListView.Column[ i ].Tag;
11641+ id := Ord( GikoSys.Setting.BoardColumnOrder[ idx ] );
11642+ BoardOrder.Add( TGikoBoardColumnID( id ) );
11643+ // 幅の保存
11644+ GikoSys.Setting.BoardColumnWidth[ id ] := ListView.Column[ i ].Width;
11645+ end;
11646+ for i := 0 to ListView.Columns.Count - 1 do
11647+ // 順序の保存
11648+ GikoSys.Setting.BoardColumnOrder[ i ] := BoardOrder[ i ];
11649+ finally
11650+ BoardOrder.Free;
11651+ end;
11652+ end;
11653+
11654+end;
11655+
11656+procedure TGikoForm.ListViewColumnRightClick(Sender: TObject;
11657+ Column: TListColumn; Point: TPoint);
11658+var
11659+ i, j : Integer;
11660+ item : TMenuItem;
11661+begin
11662+
11663+ // ポップアップメニューをクリア
11664+ for i := ListColumnPopupMenu.Items.Count - 1 downto 0 do
11665+ ListColumnPopupMenu.Items.Items[ i ].Free;
11666+
11667+ // メニューの作成 (メインカラムは必須なのでメニューに含めない)
11668+ if TObject( FActiveList ) is TBBS then begin
11669+
11670+ //===== カテゴリリスト =====
11671+ for i := 1 to Length( GikoBBSColumnCaption ) - 1 do begin
11672+ item := TMenuItem.Create( ListColumnPopupMenu );
11673+ item.Caption := GikoBBSColumnCaption[ i ];
11674+ item.Tag := i;
11675+ item.OnClick := ListColumnPopupMenuOnClick;
11676+ for j := GikoSys.Setting.BBSColumnOrder.Count - 1 downto 0 do begin
11677+ if GikoSys.Setting.BBSColumnOrder[ j ] = TGikoBBSColumnID( i ) then begin
11678+ item.Checked := True;
11679+ Break;
11680+ end;
11681+ end;
11682+ ListColumnPopupMenu.Items.Add( item );
11683+ end;
11684+
11685+ end else if TObject( FActiveList ) is TCategory then begin
11686+
11687+ //===== 板リスト =====
11688+ for i := 1 to Length( GikoCategoryColumnCaption ) - 1 do begin
11689+ item := TMenuItem.Create( ListColumnPopupMenu );
11690+ item.Caption := GikoCategoryColumnCaption[ i ];
11691+ item.Tag := i;
11692+ item.OnClick := ListColumnPopupMenuOnClick;
11693+ for j := GikoSys.Setting.CategoryColumnOrder.Count - 1 downto 0 do begin
11694+ if GikoSys.Setting.CategoryColumnOrder[ j ] = TGikoCategoryColumnID( i ) then begin
11695+ item.Checked := True;
11696+ Break;
11697+ end;
11698+ end;
11699+ ListColumnPopupMenu.Items.Add( item );
11700+ end;
11701+
11702+ end else if TObject( FActiveList ) is TBoard then begin
11703+
11704+ //===== スレリスト =====
11705+ for i := 1 to Length( GikoBoardColumnCaption ) - 1 do begin
11706+ item := TMenuItem.Create( ListColumnPopupMenu );
11707+ item.Caption := GikoBoardColumnCaption[ i ];
11708+ item.Tag := i;
11709+ item.OnClick := ListColumnPopupMenuOnClick;
11710+ for j := GikoSys.Setting.BoardColumnOrder.Count - 1 downto 0 do begin
11711+ if GikoSys.Setting.BoardColumnOrder[ j ] = TGikoBoardColumnID( i ) then begin
11712+ item.Checked := True;
11713+ Break;
11714+ end;
11715+ end;
11716+ ListColumnPopupMenu.Items.Add( item );
11717+ end;
11718+
11719+ end;
11720+
11721+ // メニューの表示
11722+ Point := ListView.ClientToScreen( Point );
11723+ if ListColumnPopupMenu.Items.Count > 0 then
11724+ ListColumnPopupMenu.Popup( Point.X, Point.Y );
11725+
11726+end;
11727+
11728+/// ListColumnPopupMenu アイテムのクリックイベント
11729+procedure TGikoForm.ListColumnPopupMenuOnClick( Sender : TObject );
11730+var
11731+ i : Integer;
11732+ orderList : TList;
11733+ item : TMenuItem;
11734+begin
11735+
11736+ if not (Sender is TMenuItem) then
11737+ Exit;
11738+
11739+ ActiveListColumnSave;
11740+ item := TMenuItem( Sender );
11741+
11742+ if TObject( FActiveList ) is TBBS then
11743+ orderList := GikoSys.Setting.BBSColumnOrder
11744+ else if TObject( FActiveList ) is TCategory then
11745+ orderList := GikoSys.Setting.CategoryColumnOrder
11746+ else if TObject( FActiveList ) is TBoard then
11747+ orderList := GikoSys.Setting.BoardColumnOrder
11748+ else
11749+ Exit;
11750+
11751+ if item.Checked then begin
11752+ // カラムの削除
11753+ for i := orderList.Count - 1 downto 0 do begin
11754+ if Integer( orderList[ i ] ) = item.Tag then begin
11755+ orderList.Delete( i );
11756+ Break;
11757+ end;
11758+ end;
11759+ end else begin
11760+ // カラムの追加
11761+ orderList.Add( Pointer( item.Tag ) );
11762+ end;
11763+
11764+ SetActiveList( FActiveList );
11765+
11766+end;
11767+//指定した番号のレスにjumpするAction
11768+procedure TGikoForm.JumpToNumOfResActionExecute(Sender: TObject);
11769+var
11770+ str: string;
11771+ res: integer;
11772+begin
11773+ str := '1';
11774+ if( InputQuery('指定した番号のレスに飛ぶ', '番号を入力してください', str) ) then begin
11775+ str := ZenToHan(str);
11776+ res := StrToIntDef(str, -1);
11777+ if (res > 0) and (res <= GetActiveContent.Count) then begin
11778+ BrowserMovement(IntToStr(res), FActiveContent);
11779+ SetFocusForBrowserAction.Execute;
11780+ end else if res > GetActiveContent.Count then begin
11781+ BrowserMovement(IntToStr(GetActiveContent.Count), FActiveContent);
11782+ SetFocusForBrowserAction.Execute;
11783+ end;
11784+ end;
11785+end;
11786+
11787+procedure TGikoForm.JumpToNumOfResActionUpdate(Sender: TObject);
11788+begin
11789+ JumpToNumOfResAction.Enabled := (GetActiveContent <> nil) and (GetActiveContent.IsLogFile);
11790+end;
11791+
11792+procedure TGikoForm.FavoriteTreeViewCollapseActionExecute(Sender: TObject);
11793+var
11794+ node : TTreeNode;
11795+begin
11796+
11797+ node := FavoriteTreeView.Items.GetFirstNode;
11798+ while node <> nil do begin
11799+ if node.HasChildren then
11800+ node.Expanded := False;
11801+ node := node.GetNext;
11802+ end;
11803+
11804+end;
11805+
1121411806 initialization
1121511807 OleInitialize(nil);
1121611808 finalization
--- a/GikoSystem.pas
+++ b/GikoSystem.pas
@@ -187,7 +187,7 @@ type
187187 function Is2chHost(Host: string): Boolean;
188188 function Parse2chURL(const url: string; const path: string; const document: string; var BBSID: string; var BBSKey: string): Boolean;
189189 function Parse2chURL2(URL: string): TPathRec;
190- procedure ParseURI(var URL, Protocol, Host, Path, Document, Port, Bookmark: string);
190+ procedure ParseURI(const URL : string; var Protocol, Host, Path, Document, Port, Bookmark: string);
191191 function GetVersionBuild: Integer;
192192 function GetBrowsableThreadURL( inURL : string ) : string;
193193 function GetThreadURL2BoardURL( inURL : string ) : string;
@@ -218,7 +218,7 @@ const
218218 ZERO_DATE: Integer = 25569;
219219 BETA_VERSION_NAME_E = 'beta';
220220 BETA_VERSION_NAME_J = 'バタ';
221- BETA_VERSION = 48;
221+ BETA_VERSION = 49;
222222 BETA_VERSION_BUILD = ''; //debug版など
223223 APP_NAME = 'gikoNavi';
224224
@@ -2999,7 +2999,8 @@ begin
29992999 OutputDebugString(pchar(HOST_NAME[0]));
30003000 for i := 0 to Length(HOST_NAME) - 1 do begin
30013001 // Len := Length(HOST_NAME[i]);
3002- if AnsiPos(HOST_NAME[i], Host) = (Length(Host) - Length(HOST_NAME[i]) + 1) then begin
3002+ if (AnsiPos(HOST_NAME[i], Host) > 0) and
3003+ (AnsiPos(HOST_NAME[i], Host) = (Length(Host) - Length(HOST_NAME[i]) + 1)) then begin
30033004 Result := True;
30043005 Exit;
30053006 end;
@@ -3423,7 +3424,7 @@ begin
34233424 end;
34243425 end;
34253426
3426-procedure TGikoSys.ParseURI(var URL, Protocol, Host, Path, Document, Port, Bookmark: string);
3427+procedure TGikoSys.ParseURI(const URL : string; var Protocol, Host, Path, Document, Port, Bookmark: string);
34273428 var
34283429 URI: TIdURI;
34293430 begin
--- a/GikoXMLDoc.pas
+++ b/GikoXMLDoc.pas
@@ -10,7 +10,7 @@ interface
1010 uses
1111 //==================================================
1212
13- Classes, SysUtils,
13+ Classes, SysUtils, Windows,
1414 YofUtils;
1515
1616 //==================================================
@@ -26,6 +26,7 @@ type
2626 IXMLNode = class
2727 private
2828 FNodeName : string;
29+ FCapacity : Integer;
2930 FCount : Integer;
3031 FAttributeCount : Integer;
3132 FChildNodes : IXMLNode;
@@ -54,15 +55,16 @@ type
5455 end;
5556
5657 function XMLCloseCheck(
57- var f : TFileStream;
58+ var p : PChar;
59+ const tail : PChar;
5860 var node : IXMLNode;
59- ch : char;
6061 out tag : string;
6162 out closed : boolean // 呼び出したルーチンが node を閉じるべきなら true
6263 ) : boolean; // ch をこのルーチンが処理したなら true
6364
6465 function XMLReadNode(
65- var f : TFileStream;
66+ var p : PChar;
67+ const tail : PChar;
6668 var node : IXMLNode
6769 ) : string; // node 以外のノードが閉じられた場合のノード名
6870
@@ -75,6 +77,8 @@ procedure LoadXMLDocument(
7577 const
7678 //==================================================
7779 kXMLWhite : TSysCharSet = [#0..#$20];
80+ kXMLNodeNameStop : TSysCharSet = [#0..#$20, '/', '>'];
81+ kXMLAttributeNameStop : TSysCharSet = [#0..#$20, '=', '/', '>'];
7882 kXMLDQuote : TSysCharSet = ['"'];
7983 kXMLTagStart : TSysCharSet = ['<'];
8084 kXMLTagEnd : TSysCharSet = ['>'];
@@ -90,6 +94,7 @@ begin
9094
9195 inherited;
9296
97+ FCapacity := 0;
9398 FCount := 0;
9499
95100 end;
@@ -138,7 +143,11 @@ procedure IXMLNode.Add( node : IXMLNode );
138143 begin
139144
140145 Inc( FCount );
141- SetLength( FNodes, FCount );
146+ if FCount > FCapacity then begin
147+ FCapacity := FCapacity + (FCapacity shr 2) + 1;
148+ SetLength( FNodes, FCapacity );
149+ end;
150+
142151 FNodes[ FCount - 1 ] := node;
143152
144153 end;
@@ -154,6 +163,7 @@ begin
154163 index := FAttributeCount;
155164 Inc( FAttributeCount );
156165 SetLength( FAttributes, FAttributeCount );
166+
157167 FAttributes[ index ].Name := Name;
158168 FAttributes[ index ].Value := Value;
159169
@@ -166,116 +176,133 @@ begin
166176
167177 end;
168178
169-// untilSet になるまで飛ばす
170-procedure FileThruUntil(
171- var f : TFileStream;
172- const untilSet : TSysCharSet
173-);
174-var
175- ch : char;
179+{*!
180+\brief tok を探す
181+\param p 探索開始位置
182+\param tail 終了位置 + 1
183+\param tok 探すキャラクタ
184+\return tok が最初に見つかった位置
185+*}
186+function AnsiStrTok(
187+ p : PChar;
188+ const tail : PChar;
189+ const tok : TSysCharSet
190+) : PChar;
176191 begin
177192
178- while f.Position < f.Size do
193+ while p < tail do
179194 begin
180- f.ReadBuffer( ch, 1 );
181- if ch in untilSet then
195+ if p^ in tok then
182196 begin
183- f.Seek( -1, soFromCurrent );
184- exit;
185- end else if ch in kXMLKanji then
186- f.Seek( 1, soFromCurrent );
197+ Break;
198+ end else if p^ in kXMLKanji then
199+ p := p + 2
200+ else
201+ Inc( p );
187202 end;
188203
204+ Result := p;
205+
189206 end;
190207
191-// whileSet の間飛ばす
192-procedure FileThruWhile(
193- var f : TFileStream;
194- const whileSet : TSysCharSet
195-);
196-var
197- ch : char;
208+{*!
209+\brief tok では無いキャラクタを探す
210+\param p 探索開始位置
211+\param tail 終了位置 + 1
212+\param tok 探すキャラクタ
213+\return tok ではないキャラクタが最初に見つかった位置
214+*}
215+function AnsiStrNonTok(
216+ p : PChar;
217+ const tail : PChar;
218+ const tok : TSysCharSet
219+) : PChar;
198220 begin
199221
200- while f.Position < f.Size do
222+ while p < tail do
201223 begin
202- f.ReadBuffer( ch, 1 );
203- if ch in whileSet then
224+ if p^ in tok then
204225 begin
205- if ch in kXMLKanji then
206- f.ReadBuffer( ch, 1 );
226+ if p^ in kXMLKanji then
227+ p := p + 2
228+ else
229+ Inc( p );
207230 end else begin
208- f.Seek( -1, soFromCurrent );
209- exit;
231+ Break;
210232 end;
211233 end;
212234
235+ Result := p;
236+
213237 end;
214238
215239 function XMLCloseCheck(
216- var f : TFileStream;
240+ var p : PChar;
241+ const tail : PChar;
217242 var node : IXMLNode;
218- ch : char;
219243 out tag : string;
220244 out closed : boolean
221245 ) : boolean; // ch をこのルーチンが処理したなら true
222246 var
223- last : Integer;
224- tagLen : Integer;
247+ found : PChar;
225248 begin
226249
227250 closed := false;
228251 Result := false;
229252 tag := '';
230253
231- if ch = '>' then
232- begin
233- // 開始タグの最後まで読んだ
234- Result := true;
235- end else if ch = '?' then
236- begin
237- // <?xml?> みたいなやつ。よって無視
238- FileThruUntil( f, kXMLTagEnd );
239- FileThruUntil( f, kXMLTagStart );
240- f.Seek( 1, soFromCurrent );
241- FileThruWhile( f, kXMLWhite );
242- //closed := true;
243- Result := true;
244- end else if ch = '/' then
245- begin
246- // タグ名を読み込んで返す
247- last := f.Position;
248- FileThruUntil( f, kXMLTagEnd );
249- tagLen := f.Position - last;
250- SetLength( tag, tagLen );
251-
252- f.Seek( last, soFromBeginning );
253- f.ReadBuffer( PChar( tag )^, tagLen );
254-
255- f.Seek( f.Position + 1, soFromBeginning ); // '>' 飛ばし
256- closed := true;
257- Result := true;
254+ case p^ of
255+ '>':
256+ begin
257+ // 開始タグの最後まで読んだ
258+ Inc( p ); // '>' 飛ばし
259+ Result := true;
260+ end;
261+
262+ '?':
263+ begin
264+ // <?xml?> みたいなやつ。よって無視
265+ p := AnsiStrTok( p, tail, kXMLTagEnd );
266+ p := AnsiStrTok( p, tail, kXMLTagStart );
267+ Inc( p ); // '<' 飛ばし
268+ p := AnsiStrNonTok( p, tail, kXMLWhite );
269+ //closed := true;
270+ Result := true;
271+ end;
272+
273+ '/':
274+ begin
275+ // タグ名を読み込んで返す
276+ Inc( p ); // '/' 飛ばし
277+ found := AnsiStrTok( p, tail, kXMLTagEnd );
278+// tag := Copy( p, 0, found - p ); // 何故か激遅
279+ SetLength( tag, found - p );
280+ CopyMemory( PChar( tag ), p, found - p );
281+
282+ p := found + 1; // '>' 飛ばし
283+ closed := true;
284+ Result := true;
285+ end;
258286 end;
259287
260288 end;
261289
262290 function XMLReadNode(
263- var f : TFileStream;
291+ var p : PChar;
292+ const tail : PChar;
264293 var node : IXMLNode
265294 ) : string; // node 以外のノードが閉じられた場合のノード名
266295 var
267296 child : IXMLNode;
268297
269- last : Integer;
298+ found : PChar;
270299 tag : string;
271- tagLen : Integer;
272300
273301 isClosed : boolean;
274302
303+ nodeName : string;
275304 attributeName : string;
276305 attributeValue : string;
277-
278- ch : char;
279306 label
280307 NextNode;
281308 begin
@@ -283,16 +310,14 @@ begin
283310 // node の読み込み(1 ループにつき 1 ノード)
284311 node.ChildNodes := IXMLNode.Create;
285312
286- while f.Position < f.Size do
313+ while p < tail do
287314 begin
288315 // NodeName 読み込み
289- FileThruWhile( f, kXMLWhite );
316+ p := AnsiStrNonTok( p, tail, kXMLWhite );
290317
291- while f.Position < f.Size do
318+ while p < tail do
292319 begin
293- f.ReadBuffer( ch, 1 );
294-
295- if XMLCloseCheck( f, node, ch, tag, isClosed ) then
320+ if XMLCloseCheck( p, tail, node, tag, isClosed ) then
296321 begin
297322 if isClosed then
298323 begin
@@ -301,11 +326,12 @@ begin
301326 end;
302327
303328 goto NextNode;
304- end else if ch = '<' then
329+ end else if p^ = '<' then
305330 begin
306331 // 新規ノード
332+ Inc( p );
307333 child := IXMLNode.Create;
308- tag := XMLReadNode( f, child );
334+ tag := XMLReadNode( p, tail, child );
309335 node.ChildNodes.Add( child );
310336
311337 // タグが閉じられた
@@ -318,35 +344,32 @@ begin
318344 end;
319345
320346 goto NextNode;
321- end else if ch in kXMLWhite then
347+ end else if p^ in kXMLWhite then
322348 begin
323349 // NodeName 完了
324350 break;
325351 end else begin
326- node.NodeName := node.NodeName + ch;
352+ found := AnsiStrTok( p, tail, kXMLNodeNameStop );
353+ SetLength( nodeName, found - p );
354+ CopyMemory( PChar( nodeName ), p, found - p );
355+ node.NodeName := nodeName;
327356
328- if ch in kXMLKanji then
329- begin
330- f.ReadBuffer( ch, 1 );
331- node.NodeName := node.NodeName + ch;
332- end;
357+ p := found;
333358 end;
334359 end;
335360
336361 // Attribute の読み込み
337- while f.Position < f.Size do
362+ while p < tail do
338363 begin
339364 // Attribute の名前を読み込み
340365 attributeName := '';
341366 attributeValue := '';
342367
343- FileThruWhile( f, kXMLWhite );
368+ p := AnsiStrNonTok( p, tail, kXMLWhite );
344369
345- while f.Position < f.Size do
370+ while p < tail do
346371 begin
347- f.ReadBuffer( ch, 1 );
348-
349- if XMLCloseCheck( f, node, ch, tag, isClosed ) then
372+ if XMLCloseCheck( p, tail, node, tag, isClosed ) then
350373 begin
351374 if isClosed then
352375 begin
@@ -358,33 +381,30 @@ begin
358381
359382 // 次のノードへ
360383 goto NextNode;
361- end else if ch = '=' then
384+ end else if p^ = '=' then
362385 begin
363386 // ここからは値が始まるので名前は終了
387+ Inc( p );
364388 break;
365- end else if ch in kXMLWhite then
389+ end else if p^ in kXMLWhite then
366390 begin
367391 // Value が存在しない(規格外)ので次のノードへ
368392 goto NextNode;
369393 end else begin
370- attributeName := attributeName + ch;
394+ found := AnsiStrTok( p, tail, kXMLAttributeNameStop );
395+ SetLength( attributeName, found - p );
396+ CopyMemory( PChar( attributeName ), p, found - p );
371397
372- if ch in kXMLKanji then
373- begin
374- f.ReadBuffer( ch, 1 );
375- attributeName := attributeName + ch;
376- end;
398+ p := found;
377399 end;
378400 end;
379401
380402 // Attribute の値を読み込み
381- FileThruWhile( f, kXMLWhite );
403+ p := AnsiStrNonTok( p, tail, kXMLWhite );
382404
383- while f.Position < f.Size do
405+ while p < tail do
384406 begin
385- f.ReadBuffer( ch, 1 );
386-
387- if XMLCloseCheck( f, node, ch, tag, isClosed ) then
407+ if XMLCloseCheck( p, tail, node, tag, isClosed ) then
388408 begin
389409 if isClosed then
390410 begin
@@ -400,24 +420,22 @@ begin
400420
401421 // 次のノードへ
402422 goto NextNode;
403- end else if ch = '"' then
423+ end else if p^ = '"' then
404424 begin
405425 // 値が "" で括られてるので(ていうか括られてなきゃいけないんだけど)
406426 // 値を一括読み込み
407- last := f.Position;
408- FileThruUntil( f, kXMLDQuote );
409- tagLen := f.Position - last;
410- SetLength( attributeValue, tagLen );
411-
412- f.Seek( last, soFromBeginning );
413- f.ReadBuffer( PChar( attributeValue )^, tagLen );
427+ Inc( p );
428+ found := AnsiStrTok( p, tail, kXMLDQuote );
429+// attributeValue := Copy( p, 0, found - p ); // 何故か激遅
430+ SetLength( attributeValue, found - p );
431+ CopyMemory( PChar( attributeValue ), p, found - p );
414432
415433 node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
416434
417435 // 値を読み終わったので終了
418- f.Seek( f.Position + 1, soFromBeginning ); // '"' 飛ばし
436+ p := found + 1; // '"' 飛ばし
419437 break;
420- end else if ch in kXMLWhite then
438+ end else if p^ in kXMLWhite then
421439 begin
422440 // 規格外だけどね
423441 node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
@@ -425,12 +443,14 @@ begin
425443 goto NextNode;
426444 end else begin
427445 // 規格外だけど一応取っておく
428- attributeValue := attributeValue + ch;
446+ attributeValue := attributeValue + p^;
429447
430- if ch in kXMLKanji then
448+ if p^ in kXMLKanji then
431449 begin
432- f.ReadBuffer( ch, 1 );
433- attributeValue := attributeValue + ch;
450+ attributeValue := attributeValue + (p + 1)^;
451+ p := p + 2;
452+ end else begin
453+ Inc( p );
434454 end;
435455 end;
436456 end;
@@ -449,19 +469,21 @@ procedure LoadXMLDocument(
449469 type
450470 xmlMode = ( xmlHoge );
451471 var
452- xmlFile : TFileStream;
472+ xmlFile : TMappedFile;
473+ p : PChar;
453474 begin
454- //Result := IXMLDocument.Create;
475+ //Result := IXMLDocument.Create;
455476 //doc := IXMLDocument.Create;
456477
457- xmlFile := TFileStream.Create( fileName, fmOpenRead );
478+ xmlFile := TMappedFile.Create( fileName );
458479
459- try
460- XMLReadNode( xmlFile, IXMLNode( doc ) );
461- //XMLReadNode( xmlFile, IXMLNode( Result ) );
462- finally
480+ try
481+ p := xmlFile.Memory;
482+ XMLReadNode( p, p + xmlFile.Size, IXMLNode( doc ) );
483+ //XMLReadNode( xmlFile, IXMLNode( Result ) );
484+ finally
463485 xmlFile.Free;
464- end;
486+ end;
465487
466488 //Result := doc;
467489
--- a/ItemDownload.pas
+++ b/ItemDownload.pas
@@ -156,9 +156,7 @@ var
156156 Idx: Integer;
157157 ATitle: string;
158158 DownloadResult: Boolean;
159- foundPos: Integer;
160159 boardPlugIn : TBoardPlugIn;
161- listContent : string;
162160 lastContent : string;
163161 logFile : TFileStream;
164162 adjustMargin : Integer;
@@ -1177,7 +1175,7 @@ end;
11771175 }
11781176 procedure TDownloadItem.SaveItemFile;
11791177 var
1180- Body: TStringList;
1178+ Body, oldBody: TStringList;
11811179 Cnt: Integer;
11821180 OldCnt: Integer;
11831181 FileName: string;
@@ -1186,11 +1184,11 @@ var
11861184 NewRes: Integer;
11871185 finish : Boolean;
11881186 loopCnt : Integer;
1189- KokoTxt : string;
1190- KokoIdx : Integer;
1191- NewTxt : string;
1192- NewIdx : Integer;
1193- LastTxt : string;
1187+// KokoTxt : string;
1188+// KokoIdx : Integer;
1189+// NewTxt : string;
1190+// NewIdx : Integer;
1191+// LastTxt : string;
11941192 LastIdx : Integer;
11951193 begin
11961194 FileName := ThreadItem.GetThreadFileName;
@@ -1208,10 +1206,6 @@ begin
12081206 try
12091207 // if FileExists(FileName) and (ResponseCode = 206) then begin
12101208 if FileExists(FileName) and (State = gdsDiffComplete) then begin
1211- // Body.Text := Content;
1212- // if Body.Count > 0 then
1213- // Body.Delete(0);
1214- // Content := Body.Text;
12151209 loopCnt := 10;
12161210 repeat
12171211 finish := true;
@@ -1224,53 +1218,55 @@ begin
12241218 except
12251219 on E:EFOpenError do begin
12261220 sleep(10);
1227- finish := false;
12281221 Dec(loopCnt);
1222+ if loopCnt > 0 then
1223+ finish := false;
12291224 end;
12301225 end;
1231- until finish and ( loopCnt > 0 );
1226+ until finish;
12321227 //Cnt := Body.Count;
12331228 end else begin
12341229 if IsAbone then begin
12351230 // あぼーんを検出したのでここまで読んだと新着レス番のつけなおし
1236- loopCnt := 10;
1237- repeat
1238- finish := true;
1239- try
1240- Body.LoadFromFile(FileName);
1241- except
1242- on E:EFOpenError do begin
1243- sleep(10);
1244- finish := false;
1245- Dec(loopCnt);
1231+ oldBody := TStringList.Create;
1232+ try
1233+ loopCnt := 10;
1234+ repeat
1235+ finish := true;
1236+ try
1237+ oldBody.LoadFromFile(FileName);
1238+ except
1239+ on E:EFOpenError do begin
1240+ sleep(10);
1241+ Dec(loopCnt);
1242+ if loopCnt > 0 then
1243+ finish := false
1244+ else
1245+ finish := true;
1246+ end;
12461247 end;
1248+ until finish;
1249+
1250+ Body.Text := Content;
1251+ if (ThreadItem.Kokomade > 0) and (ThreadItem.Kokomade <= oldBody.Count) then begin
1252+ ThreadItem.Kokomade := Body.IndexOf(oldBody.Strings[ ThreadItem.Kokomade - 1 ]);
1253+ if ThreadItem.Kokomade <> -1 then ThreadItem.Kokomade := ThreadItem.Kokomade + 1;
12471254 end;
1248- until finish and ( loopCnt > 0 );
1249- LastTxt := Body.Strings[ Body.Count - 1 ];
1250- if ThreadItem.Kokomade > 0 then begin
1251- KokoTxt := Body.Strings[ ThreadItem.Kokomade - 1 ];
1252- end;
1253- if ThreadItem.NewReceive > 0 then begin
1254- NewTxt := Body.Strings[ ThreadItem.NewReceive - 1 ];
1255- end;
12561255
1257- Body.Text := Content;
1258- Body.Find( LastTxt, LastIdx );
1259- OldCnt := LastIdx + 1;
1260- NewRes := Body.Count - OldCnt;
1256+ LastIdx := oldBody.Count;
1257+ repeat
1258+ Dec(LastIdx);
1259+ OldCnt := Body.IndexOf(oldBody.Strings[ LastIdx ]) + 1;
1260+ until ( OldCnt <> 0 ) or (LastIdx = 0);
12611261
1262- if ThreadItem.Kokomade > 0 then begin
1263- Body.Find( KokoTxt, KokoIdx );
1264- ThreadItem.Kokomade := KokoIdx + 1;
1265- end;
1266- if ThreadItem.NewReceive > 0 then begin
1267- Body.Find( NewTxt, NewIdx );
1268- Inc( NewIdx );
1269- if OldCnt < NewIdx then begin
1270- OldCnt := NewIdx;
1271- NewRes := Body.Count - NewIdx;
1272- end;
1262+ if OldCnt >= Body.Count then OldCnt := Body.Count - 1;
1263+ NewRes := Body.Count - OldCnt;
1264+
1265+
1266+ finally
1267+ oldBody.Free;
12731268 end;
1269+
12741270 end else begin
12751271 Body.Text := Content;
12761272 //ThreadItem.Count := 0;
@@ -1303,8 +1299,10 @@ begin
13031299 ThreadItem.AllResCount := ThreadItem.Count;
13041300 ThreadItem.IsLogFile := True;
13051301 ThreadItem.RoundDate := Now;
1306- ThreadItem.UnRead := True;
1307- ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1302+ if not ThreadItem.UnRead then begin
1303+ ThreadItem.UnRead := True;
1304+ ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1305+ end;
13081306 // if ThreadItem.RoundNo = 6 then
13091307 // ThreadItem.RoundNo := 0;
13101308
--- a/KuroutSetting.dfm
+++ b/KuroutSetting.dfm
@@ -1,6 +1,6 @@
11 object KuroutOption: TKuroutOption
2- Left = 260
3- Top = 167
2+ Left = 43
3+ Top = 114
44 Width = 525
55 Height = 457
66 Caption = #35443#32048#35373#23450
@@ -140,6 +140,182 @@ object KuroutOption: TKuroutOption
140140 TabOrder = 3
141141 end
142142 end
143+ object GroupBox1: TGroupBox
144+ Left = 14
145+ Top = 232
146+ Width = 475
147+ Height = 57
148+ Caption = #12395#12385#12419#12435#35486#26696#20869#27231#33021
149+ TabOrder = 2
150+ Visible = False
151+ object Label5: TLabel
152+ Left = 8
153+ Top = 16
154+ Width = 234
155+ Height = 12
156+ Caption = #12395#12385#12419#12435#35486#12434#20351#12387#12390#12462#12467#12490#12499#12434#12469#12509#12540#12488#12375#12414#12377#12290
157+ end
158+ object GengoSupport: TCheckBox
159+ Left = 8
160+ Top = 32
161+ Width = 201
162+ Height = 17
163+ Caption = #12395#12385#12419#12435#35486#26696#20869#27231#33021#12434#26377#21177#12395#12377#12427
164+ TabOrder = 0
165+ end
166+ end
167+ end
168+ object ColumnTabSheet: TTabSheet
169+ Caption = #35443#32048#35373#23450'2'
170+ ImageIndex = 1
171+ object CategoryColumnGroupBox: TGroupBox
172+ Left = 8
173+ Top = 16
174+ Width = 481
175+ Height = 145
176+ Caption = #34920#31034#12459#12521#12512#35373#23450'('#12459#12486#12468#12522#12540')'
177+ TabOrder = 0
178+ object Label1: TLabel
179+ Left = 80
180+ Top = 16
181+ Width = 60
182+ Height = 12
183+ Caption = #38750#34920#31034#38917#30446
184+ end
185+ object Label2: TLabel
186+ Left = 312
187+ Top = 16
188+ Width = 48
189+ Height = 12
190+ Caption = #34920#31034#38917#30446
191+ end
192+ object CUnVisibledListBox: TListBox
193+ Left = 32
194+ Top = 33
195+ Width = 161
196+ Height = 65
197+ ItemHeight = 12
198+ TabOrder = 0
199+ end
200+ object CVisibledListBox: TListBox
201+ Left = 264
202+ Top = 33
203+ Width = 161
204+ Height = 65
205+ ItemHeight = 12
206+ TabOrder = 1
207+ end
208+ object CAddButton: TButton
209+ Left = 200
210+ Top = 38
211+ Width = 57
212+ Height = 25
213+ Caption = '>>'
214+ TabOrder = 2
215+ OnClick = CAddButtonClick
216+ end
217+ object CDeleteButton: TButton
218+ Left = 200
219+ Top = 70
220+ Width = 57
221+ Height = 25
222+ Caption = '<<'
223+ TabOrder = 3
224+ OnClick = CDeleteButtonClick
225+ end
226+ object CUpButton: TButton
227+ Left = 264
228+ Top = 104
229+ Width = 75
230+ Height = 25
231+ Caption = #19978#12408
232+ TabOrder = 4
233+ OnClick = CUpButtonClick
234+ end
235+ object CDownButton: TButton
236+ Left = 352
237+ Top = 104
238+ Width = 75
239+ Height = 25
240+ Caption = #19979#12504
241+ TabOrder = 5
242+ OnClick = CDownButtonClick
243+ end
244+ end
245+ object BoardColumnGroupBox: TGroupBox
246+ Left = 8
247+ Top = 168
248+ Width = 481
249+ Height = 185
250+ Caption = #34920#31034#12459#12521#12512#35373#23450'('#26495')'
251+ TabOrder = 1
252+ object Label3: TLabel
253+ Left = 80
254+ Top = 16
255+ Width = 60
256+ Height = 12
257+ Caption = #38750#34920#31034#38917#30446
258+ end
259+ object Label4: TLabel
260+ Left = 312
261+ Top = 16
262+ Width = 48
263+ Height = 12
264+ Caption = #34920#31034#38917#30446
265+ end
266+ object BUnVisibledListBox: TListBox
267+ Left = 32
268+ Top = 31
269+ Width = 161
270+ Height = 113
271+ ItemHeight = 12
272+ TabOrder = 0
273+ end
274+ object BVisibledListBox: TListBox
275+ Left = 264
276+ Top = 31
277+ Width = 161
278+ Height = 113
279+ ItemHeight = 12
280+ TabOrder = 1
281+ end
282+ object BAddButton: TButton
283+ Left = 200
284+ Top = 48
285+ Width = 57
286+ Height = 25
287+ Caption = '>>'
288+ TabOrder = 2
289+ OnClick = BAddButtonClick
290+ end
291+ object BDeleteButton: TButton
292+ Left = 200
293+ Top = 80
294+ Width = 57
295+ Height = 25
296+ Caption = '<<'
297+ TabOrder = 3
298+ OnClick = BDeleteButtonClick
299+ end
300+ object BUpButton: TButton
301+ Left = 264
302+ Top = 152
303+ Width = 75
304+ Height = 25
305+ Caption = #19978#12408
306+ TabOrder = 4
307+ OnClick = BUpButtonClick
308+ end
309+ object BDownButton: TButton
310+ Left = 352
311+ Top = 152
312+ Width = 75
313+ Height = 25
314+ Caption = #19979#12504
315+ TabOrder = 5
316+ OnClick = BDownButtonClick
317+ end
318+ end
143319 end
144320 end
145321 object OkBotton: TButton
--- a/KuroutSetting.pas
+++ b/KuroutSetting.pas
@@ -8,35 +8,67 @@ uses
88
99 type
1010 TKuroutOption = class(TForm)
11- PageControl1: TPageControl;
12- TabSheet1: TTabSheet;
13- GroupBox11: TGroupBox;
14- Label17: TLabel;
15- Label18: TLabel;
16- RecvBufferSize: TEdit;
17- ProxyProtocolCheckBox: TCheckBox;
18- ProtocolCheckBox: TCheckBox;
19- GroupBox13: TGroupBox;
20- Label24: TLabel;
21- Label25: TLabel;
22- PostTimeLabel: TLabel;
23- Label27: TLabel;
24- PostTimeCheckBox: TCheckBox;
25- PostTimeEdit: TEdit;
26- PutPostTimeRadioButton: TRadioButton;
27- BackPostTimeRadioButton: TRadioButton;
28- OkBotton: TButton;
29- CancelBotton: TButton;
30- ApplyButton: TButton;
31- procedure OkBottonClick(Sender: TObject);
32- procedure FormCreate(Sender: TObject);
11+ PageControl1: TPageControl;
12+ TabSheet1: TTabSheet;
13+ GroupBox11: TGroupBox;
14+ Label17: TLabel;
15+ Label18: TLabel;
16+ RecvBufferSize: TEdit;
17+ ProxyProtocolCheckBox: TCheckBox;
18+ ProtocolCheckBox: TCheckBox;
19+ GroupBox13: TGroupBox;
20+ Label24: TLabel;
21+ Label25: TLabel;
22+ PostTimeLabel: TLabel;
23+ Label27: TLabel;
24+ PostTimeCheckBox: TCheckBox;
25+ PostTimeEdit: TEdit;
26+ PutPostTimeRadioButton: TRadioButton;
27+ BackPostTimeRadioButton: TRadioButton;
28+ OkBotton: TButton;
29+ CancelBotton: TButton;
30+ ApplyButton: TButton;
31+ ColumnTabSheet: TTabSheet;
32+ CategoryColumnGroupBox: TGroupBox;
33+ CUnVisibledListBox: TListBox;
34+ CVisibledListBox: TListBox;
35+ CAddButton: TButton;
36+ CDeleteButton: TButton;
37+ BoardColumnGroupBox: TGroupBox;
38+ BUnVisibledListBox: TListBox;
39+ BVisibledListBox: TListBox;
40+ BAddButton: TButton;
41+ BDeleteButton: TButton;
42+ Label1: TLabel;
43+ Label2: TLabel;
44+ Label3: TLabel;
45+ Label4: TLabel;
46+ CUpButton: TButton;
47+ CDownButton: TButton;
48+ BUpButton: TButton;
49+ BDownButton: TButton;
50+ GroupBox1: TGroupBox;
51+ GengoSupport: TCheckBox;
52+ Label5: TLabel;
53+ procedure OkBottonClick(Sender: TObject);
54+ procedure FormCreate(Sender: TObject);
55+ procedure CDeleteButtonClick(Sender: TObject);
56+ procedure CAddButtonClick(Sender: TObject);
57+ procedure BAddButtonClick(Sender: TObject);
58+ procedure BDeleteButtonClick(Sender: TObject);
59+ procedure CUpButtonClick(Sender: TObject);
60+ procedure CDownButtonClick(Sender: TObject);
61+ procedure BUpButtonClick(Sender: TObject);
62+ procedure BDownButtonClick(Sender: TObject);
3363 private
34- { Private 宣言 }
64+ { Private 宣言 }
3565 procedure SetValue;
3666 procedure SaveSetting;
3767 procedure RecvBufferSizeExit(Sender: TObject);
3868 procedure PostTimeEditExit(Sender: TObject);
3969 procedure PostTimeCheckBoxClick(Sender: TObject);
70+ procedure SetColumnData();
71+ procedure PostColumnData();
4072 public
4173 { Public 宣言 }
4274 end;
@@ -46,6 +78,9 @@ var
4678
4779 implementation
4880
81+uses
82+ Giko, Setting;
83+
4984 {$R *.dfm}
5085
5186 procedure TKuroutOption.SetValue;
@@ -64,6 +99,10 @@ begin
6499 PutPostTimeRadioButton.Checked := True
65100 else
66101 BackPostTimeRadioButton.Checked := True;
102+
103+ SetColumnData();
104+
105+ PageControl1.ActivePageIndex := GikoSys.Setting.KuroutSettingTabIndex;
67106 end;
68107
69108 procedure TKuroutOption.SaveSetting;
@@ -81,6 +120,10 @@ begin
81120 else
82121 GikoSys.Setting.TimeAdjustSec := 0;
83122 GikoSys.Setting.TimeAdjust := PutPostTimeRadioButton.Checked;
123+
124+ GikoSys.Setting.GengoSupport := GengoSupport.Checked;
125+
126+ GikoSys.Setting.KuroutSettingTabIndex := PageControl1.ActivePageIndex;
84127 end;
85128
86129 procedure TKuroutOption.RecvBufferSizeExit(Sender: TObject);
@@ -109,6 +152,7 @@ procedure TKuroutOption.OkBottonClick(Sender: TObject);
109152 begin
110153 RecvBufferSizeExit(Sender);
111154 PostTimeEditExit(Sender);
155+ PostColumnData();
112156 SaveSetting;
113157 end;
114158
@@ -118,5 +162,191 @@ begin
118162 PostTimeCheckBoxClick(Sender);
119163
120164 end;
165+procedure TKuroutOption.SetColumnData();
166+var
167+ i, j : Integer;
168+ flag : Boolean;
169+begin
170+
171+ //===== 板リスト =====
172+ for i := 0 to GikoSys.Setting.CategoryColumnOrder.Count - 1 do begin
173+ for j := 1 to Length( GikoCategoryColumnCaption ) - 1 do begin
174+ if GikoSys.Setting.CategoryColumnOrder[ i ] = TGikoCategoryColumnID( j ) then begin
175+ CVisibledListBox.AddItem(GikoCategoryColumnCaption[ j ], nil);
176+ break;
177+ end;
178+ end;
179+ end;
180+
181+ for i := 1 to Length( GikoCategoryColumnCaption ) - 1 do begin
182+ flag := false;
183+ for j := 0 to GikoSys.Setting.CategoryColumnOrder.Count - 1 do begin
184+ if GikoSys.Setting.CategoryColumnOrder[ j ] = TGikoCategoryColumnID( i ) then begin
185+ flag := true;
186+ break;
187+ end;
188+ end;
189+ if not flag then
190+ CUnVisibledListBox.AddItem(GikoCategoryColumnCaption[ i ], nil);
191+ end;
192+
193+ //===== スレリスト =====
194+ for i := 0 to GikoSys.Setting.BoardColumnOrder.Count - 1 do begin
195+ for j := 1 to Length( GikoBoardColumnCaption ) - 1 do begin
196+ if GikoSys.Setting.BoardColumnOrder[ i ] = TGikoBoardColumnID( j ) then begin
197+ BVisibledListBox.AddItem(GikoBoardColumnCaption[ j ], nil);
198+ Break;
199+ end;
200+ end;
201+ end;
202+
203+ for i := 1 to Length( GikoBoardColumnCaption ) - 1 do begin
204+ flag := false;
205+ for j := GikoSys.Setting.BoardColumnOrder.Count - 1 downto 0 do begin
206+ if GikoSys.Setting.BoardColumnOrder[ j ] = TGikoBoardColumnID( i ) then begin
207+ flag := true;
208+ Break;
209+ end;
210+ end;
211+ if not flag then
212+ BUnVisibledListBox.AddItem(GikoBoardColumnCaption[ i ], nil);
213+
214+ end;
215+end;
216+procedure TKuroutOption.CDeleteButtonClick(Sender: TObject);
217+var
218+ i: Integer;
219+begin
220+ for i := 0 to CVisibledListBox.Count - 1 do begin
221+ if CVisibledListBox.Selected[i] then begin
222+ CUnVisibledListBox.AddItem( CVisibledListBox.Items.Strings[ i ], nil);
223+ CVisibledListBox.DeleteSelected;
224+ break;
225+ end;
226+ end;
227+end;
228+
229+procedure TKuroutOption.CAddButtonClick(Sender: TObject);
230+var
231+ i: Integer;
232+begin
233+ for i := 0 to CUnVisibledListBox.Count - 1 do begin
234+ if CUnVisibledListBox.Selected[i] then begin
235+ CVisibledListBox.AddItem( CUnVisibledListBox.Items.Strings[ i ], nil);
236+ CUnVisibledListBox.DeleteSelected;
237+ break;
238+ end;
239+ end;
240+end;
241+
242+procedure TKuroutOption.BAddButtonClick(Sender: TObject);
243+var
244+ i: Integer;
245+begin
246+ for i := 0 to BUnVisibledListBox.Count - 1 do begin
247+ if BUnVisibledListBox.Selected[i] then begin
248+ BVisibledListBox.AddItem( BUnVisibledListBox.Items.Strings[ i ], nil);
249+ BUnVisibledListBox.DeleteSelected;
250+ break;
251+ end;
252+ end;
253+end;
254+
255+procedure TKuroutOption.BDeleteButtonClick(Sender: TObject);
256+var
257+ i: Integer;
258+begin
259+ for i := 0 to BVisibledListBox.Count - 1 do begin
260+ if BVisibledListBox.Selected[i] then begin
261+ BUnVisibledListBox.AddItem( BVisibledListBox.Items.Strings[ i ], nil);
262+ BVisibledListBox.DeleteSelected;
263+ break;
264+ end;
265+ end;
266+end;
267+
268+procedure TKuroutOption.CUpButtonClick(Sender: TObject);
269+var
270+ i: Integer;
271+begin
272+ for i := 1 to CVisibledListBox.Count - 1 do begin
273+ if CVisibledListBox.Selected[i] then begin
274+ CVisibledListBox.Items.Exchange(i, i -1);
275+ break;
276+ end;
277+ end;
278+end;
279+
280+procedure TKuroutOption.CDownButtonClick(Sender: TObject);
281+var
282+ i: Integer;
283+begin
284+ for i := 0 to CVisibledListBox.Count - 2 do begin
285+ if CVisibledListBox.Selected[i] then begin
286+ CVisibledListBox.Items.Exchange(i, i + 1);
287+ break;
288+ end;
289+ end;
290+end;
291+
292+procedure TKuroutOption.BUpButtonClick(Sender: TObject);
293+var
294+ i: Integer;
295+begin
296+ for i := 1 to BVisibledListBox.Count - 1 do begin
297+ if BVisibledListBox.Selected[i] then begin
298+ BVisibledListBox.Items.Exchange(i, i -1);
299+ break;
300+ end;
301+ end;
302+end;
303+
304+procedure TKuroutOption.BDownButtonClick(Sender: TObject);
305+var
306+ i: Integer;
307+begin
308+ for i := 0 to BVisibledListBox.Count - 2 do begin
309+ if BVisibledListBox.Selected[i] then begin
310+ BVisibledListBox.Items.Exchange(i, i + 1);
311+ break;
312+ end;
313+ end;
314+end;
315+
316+
317+procedure TKuroutOption.PostColumnData();
318+var
319+ i, j : Integer;
320+begin
321+ GikoForm.ActiveListColumnSave;
322+
323+ //===== 板リスト =====
324+ for i := GikoSys.Setting.CategoryColumnOrder.Count -1 downto 1 do
325+ GikoSys.Setting.CategoryColumnOrder.Delete(i);
326+
327+ for i := 0 to CVisibledListBox.Count - 1 do begin
328+ for j := 1 to Length( GikoCategoryColumnCaption ) - 1 do begin
329+ if CVisibledListBox.Items.Strings[ i ] = GikoCategoryColumnCaption[ j ] then begin
330+ GikoSys.Setting.CategoryColumnOrder.Add( TGikoCategoryColumnID(j) );
331+ break;
332+ end;
333+ end;
334+ end;
335+
336+ //===== スレリスト =====
337+ for i := GikoSys.Setting.BoardColumnOrder.Count - 1 downto 1 do
338+ GikoSys.Setting.BoardColumnOrder.Delete(i);
339+
340+ for i := 0 to BVisibledListBox.Count - 1 do begin
341+ for j := 1 to Length( GikoBoardColumnCaption ) - 1 do begin
342+ if BVisibledListBox.Items.Strings[ i ] = GikoBoardColumnCaption[ j ] then begin
343+ GikoSys.Setting.BoardColumnOrder.Add( TGikoBoardColumnID(j) );
344+ Break;
345+ end;
346+ end;
347+ end;
348+ //スレ一覧の描画の更新
349+ GikoForm.SetActiveList(GikoForm.ActiveList);
350+end;
121351
122352 end.
--- a/Option.dfm
+++ b/Option.dfm
@@ -1,6 +1,6 @@
11 object OptionDialog: TOptionDialog
2- Left = 410
3- Top = 236
2+ Left = 188
3+ Top = 128
44 BorderStyle = bsDialog
55 Caption = #12458#12503#12471#12519#12531
66 ClientHeight = 428
@@ -60,9 +60,9 @@ object OptionDialog: TOptionDialog
6060 Top = 4
6161 Width = 509
6262 Height = 389
63- ActivePage = ThreadSheet
63+ ActivePage = TabSheet3
6464 MultiLine = True
65- TabIndex = 4
65+ TabIndex = 3
6666 TabOrder = 3
6767 OnChange = OptionTabChange
6868 object ConnectSheet: TTabSheet
@@ -252,7 +252,7 @@ object OptionDialog: TOptionDialog
252252 Top = 43
253253 Width = 417
254254 Height = 20
255- ItemHeight = 0
255+ ItemHeight = 12
256256 TabOrder = 0
257257 Text = 'BoardURLComboBox'
258258 end
@@ -654,7 +654,7 @@ object OptionDialog: TOptionDialog
654654 Left = 12
655655 Top = 8
656656 Width = 477
657- Height = 64
657+ Height = 41
658658 Caption = #34920#31034#35373#23450
659659 TabOrder = 0
660660 object ThreadListIconCheckBox: TCheckBox
@@ -665,18 +665,10 @@ object OptionDialog: TOptionDialog
665665 Caption = #12473#12524#12483#12489#26356#26032#12450#12452#12467#12531#12434#34920#31034#12377#12427'(&I)'
666666 TabOrder = 0
667667 end
668- object NonAcquiredCountCheckBox: TCheckBox
669- Left = 12
670- Top = 40
671- Width = 217
672- Height = 17
673- Caption = #21462#24471#25968#12398#20195#12431#12426#12395#26410#21462#24471#25968#12434#34920#31034#12377#12427
674- TabOrder = 1
675- end
676668 end
677669 object GroupBox16: TGroupBox
678670 Left = 12
679- Top = 76
671+ Top = 52
680672 Width = 477
681673 Height = 64
682674 Caption = #12473#12524#20316#25104#26085#26178#34920#31034#35373#23450
@@ -700,7 +692,7 @@ object OptionDialog: TOptionDialog
700692 end
701693 object GroupBox5: TGroupBox
702694 Left = 12
703- Top = 145
695+ Top = 121
704696 Width = 477
705697 Height = 86
706698 Caption = #12502#12521#12454#12470#12398#26368#22823#21270
@@ -728,7 +720,7 @@ object OptionDialog: TOptionDialog
728720 end
729721 object GroupBox17: TGroupBox
730722 Left = 12
731- Top = 236
723+ Top = 212
732724 Width = 477
733725 Height = 63
734726 Caption = #12502#12521#12454#12470#12479#12502#38750#34920#31034#26178#35373#23450
@@ -766,9 +758,9 @@ object OptionDialog: TOptionDialog
766758 end
767759 object GroupBox18: TGroupBox
768760 Left = 12
769- Top = 302
761+ Top = 278
770762 Width = 477
771- Height = 41
763+ Height = 43
772764 Caption = 'dat'#33853#12385#12473#12524#12477#12540#12488#38918
773765 TabOrder = 4
774766 object DatOchiSortCombo: TComboBox
@@ -786,7 +778,9 @@ object OptionDialog: TOptionDialog
786778 #21462#24471#26085#26178'('#26119#38918')'
787779 #21462#24471#26085#26178'('#38477#38918')'
788780 #12473#12524#20316#25104#26085#26178'('#26119#38918')'
789- #12473#12524#20316#25104#26085#26178'('#38477#38918')')
781+ #12473#12524#20316#25104#26085#26178'('#38477#38918')'
782+ #12473#12524#26368#32066#26356#26032#26085#26178#65288#26119#38918#65289
783+ #12473#12524#26368#32066#26356#26032#26085#26178#65288#38477#38918#65289)
790784 end
791785 end
792786 end
--- a/Option.pas
+++ b/Option.pas
@@ -90,7 +90,6 @@ type
9090 TabSheet3: TTabSheet;
9191 GroupBox9: TGroupBox;
9292 ThreadListIconCheckBox: TCheckBox;
93- NonAcquiredCountCheckBox: TCheckBox;
9493 GroupBox16: TGroupBox;
9594 CreationTimeLogsCheckBox: TCheckBox;
9695 FutureThreadCheckBox: TCheckBox;
@@ -766,28 +765,32 @@ begin
766765
767766 //スレッド一覧更新アイコン
768767 ThreadListIconCheckBox.Checked := GikoSys.Setting.ListIconVisible;
769- NonAcquiredCountCheckBox.Checked := GikoSys.Setting.NonAcquiredCount;
770768 CreationTimeLogsCheckBox.Checked := GikoSys.Setting.CreationTimeLogs;
771769 FutureThreadCheckBox.Checked := GikoSys.Setting.FutureThread;
772770 SelectIntervalEdit.Text := IntToStr(GikoSys.Setting.SelectInterval);
773771
774772 //dat落ちスレソート順
775- case GikoSys.Setting.DatOchiSortIndex of
776- 0:
773+ case TGikoBoardColumnID( GikoSys.Setting.DatOchiSortIndex ) of
774+ gbcTitle:
777775 if GikoSys.Setting.DatOchiSortOrder then
778776 DatOchiSortCombo.ItemIndex := 1
779777 else
780778 DatOchiSortCombo.ItemIndex := 2;
781- 6:
779+ gbcRoundDate://gbcLastModified:
782780 if GikoSys.Setting.DatOchiSortOrder then
783781 DatOchiSortCombo.ItemIndex := 3
784782 else
785783 DatOchiSortCombo.ItemIndex := 4;
786- 7:
784+ gbcCreated:
787785 if GikoSys.Setting.DatOchiSortOrder then
788786 DatOchiSortCombo.ItemIndex := 5
789787 else
790788 DatOchiSortCombo.ItemIndex := 6;
789+ gbcLastModified:
790+ if GikoSys.Setting.DatOchiSortOrder then
791+ DatOchiSortCombo.ItemIndex := 7
792+ else
793+ DatOchiSortCombo.ItemIndex := 8;
791794 else
792795 DatOchiSortCombo.ItemIndex := 0;
793796 end;
@@ -802,7 +805,6 @@ begin
802805
803806 //TabAutoLoad
804807 TabLoadSave.Checked := Gikosys.Setting.TabAutoLoadSave;
805-
806808 end;
807809
808810 procedure TOptionDialog.SaveSetting;
@@ -995,11 +997,6 @@ begin
995997 //スレッド一覧更新アイコン
996998 GikoSys.Setting.ListIconVisible := ThreadListIconCheckBox.Checked;
997999
998- //取得数、未取得数
999- if (GikoSys.Setting.NonAcquiredCount <> NonAcquiredCountCheckBox.Checked) and (GikoForm.ActiveList Is TBoard) then
1000- FRepaintList := true;
1001- GikoSys.Setting.NonAcquiredCount := NonAcquiredCountCheckBox.Checked;
1002-
10031000 GikoSys.Setting.CreationTimeLogs := CreationTimeLogsCheckBox.Checked;
10041001 GikoSys.Setting.FutureThread := FutureThreadCheckBox.Checked;
10051002 if StrToIntDef(SelectIntervalEdit.Text, 110) > 55 then
@@ -1012,28 +1009,36 @@ begin
10121009 0: GikoSys.Setting.DatOchiSortIndex := -1; //並び替えしない
10131010 1: begin //スレ番号(昇順)
10141011 GikoSys.Setting.DatOchiSortOrder := true;
1015- GikoSys.Setting.DatOchiSortIndex := 0;
1012+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcTitle );
10161013 end;
10171014 2: begin //スレ番号(降順)
10181015 GikoSys.Setting.DatOchiSortOrder := false;
1019- GikoSys.Setting.DatOchiSortIndex := 0;
1016+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcTitle );
10201017 end;
10211018 3: begin //取得日時(昇順)
10221019 GikoSys.Setting.DatOchiSortOrder := true;
1023- GikoSys.Setting.DatOchiSortIndex := 6;
1020+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcRoundDate );{gbcLastModified}
10241021 end;
10251022 4: begin //取得日時(降順)
10261023 GikoSys.Setting.DatOchiSortOrder := false;
1027- GikoSys.Setting.DatOchiSortIndex := 6;
1024+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcRoundDate );{gbcLastModified}
10281025 end;
10291026 5: begin //スレ作成日時(昇順)
10301027 GikoSys.Setting.DatOchiSortOrder := true;
1031- GikoSys.Setting.DatOchiSortIndex := 7;
1028+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcCreated );
10321029 end;
10331030 6: begin //スレ作成日時(降順)
10341031 GikoSys.Setting.DatOchiSortOrder := false;
1035- GikoSys.Setting.DatOchiSortIndex := 7;
1032+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcCreated );
10361033 end;
1034+ 7: begin //スレ最終更新日時(昇順)
1035+ GikoSys.Setting.DatOchiSortOrder := true;
1036+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcLastModified );{gbcLastModified}
1037+ end;
1038+ 8: begin //スレ最終更新日時(降順)
1039+ GikoSys.Setting.DatOchiSortOrder := false;
1040+ GikoSys.Setting.DatOchiSortIndex := Ord( gbcLastModified );{gbcLastModified}
1041+ end;
10371042 end;
10381043
10391044 GikoSys.Setting.WriteSystemSettingFile;
--- a/Setting.pas
+++ b/Setting.pas
@@ -55,6 +55,62 @@ type
5555 /// スレッド一覧表示範囲
5656 TGikoThreadRange = (gtrAll, gtrSelect, gtrLog, gtrNew);
5757
58+ /// カテゴリリストのカラム ID
59+ type TGikoBBSColumnID = (gbbscTitle);
60+ /// カテゴリリストのカラム名
61+ const GikoBBSColumnCaption : array[0..0] of string =
62+ ( 'カテゴリ名' );
63+ /// カテゴリリストカラム配列
64+ type TGikoBBSColumnList = class( TList )
65+ private
66+ function GetItem( index : integer ) : TGikoBBSColumnID;
67+ procedure SetItem( index : integer; value : TGikoBBSColumnID);
68+ public
69+ constructor Create;
70+ destructor Destroy; override;
71+ function Add( value : TGikoBBSColumnID ) : Integer;
72+ property Items[index : integer]: TGikoBBSColumnID read GetItem write SetItem; default;
73+ end;
74+ /// 板リストのカラム ID
75+ type TGikoCategoryColumnID = (gccTitle, gccRoundName, gccLastModified);
76+ /// 板リストのカラム名
77+ const GikoCategoryColumnCaption : array[0..2] of string =
78+ ( '板名', '巡回予約', '取得日時' );
79+ /// 板リストカラム配列
80+ type TGikoCategoryColumnList = class( TList )
81+ private
82+ function GetItem( index : integer ) : TGikoCategoryColumnID;
83+ procedure SetItem( index : integer; value : TGikoCategoryColumnID);
84+ public
85+ constructor Create;
86+ destructor Destroy; override;
87+ function Add( value : TGikoCategoryColumnID ) : Integer;
88+ property Items[index : integer]: TGikoCategoryColumnID read GetItem write SetItem; default;
89+ end;
90+ /// スレリストのカラム ID
91+ type TGikoBoardColumnID = (gbcTitle, gbcAllCount, gbcLocalCount, gbcNonAcqCount,
92+ gbcNewCount, gbcUnReadCount, gbcRoundName, gbcRoundDate, gbcCreated, gbcLastModified );{gbcLastModified,}
93+ /// スレリストのカラム名
94+ const GikoBoardColumnCaption : array[0..9] of string =
95+ ( 'スレッド名', 'カウント', '取得', '未取得', '新着',
96+ '未読', '巡回予約', '取得日時', 'スレ作成日時', '最終更新日時' );
97+ const GikoBoardColumnAlignment : array[0..9] of TAlignment = (
98+ taLeftJustify, taRightJustify, taRightJustify, taRightJustify,
99+ taRightJustify, taRightJustify, taLeftJustify, taLeftJustify,
100+ taLeftJustify, taLeftJustify);
101+ /// スレリストカラム配列
102+ type TGikoBoardColumnList = class( TList )
103+ private
104+ function GetItem( index : integer ) : TGikoBoardColumnID;
105+ procedure SetItem( index : integer; value : TGikoBoardColumnID);
106+ public
107+ constructor Create;
108+ destructor Destroy; override;
109+ function Add( value : TGikoBoardColumnID ) : Integer;
110+ property Items[index : integer]: TGikoBoardColumnID read GetItem write SetItem; default;
111+ end;
112+
113+type
58114 //CoolBar設定レコード
59115 TCoolSet = record
60116 FCoolID: Integer;
@@ -215,8 +271,15 @@ type
215271
216272 //リストカラムヘッダーサイズ
217273 FBBSColumnWidth: array[0..0] of Integer;
218- FCategoryColumnWidth: array[0..3] of Integer;
219- FBoardColumnWidth: array[0..7] of Integer;
274+ FCategoryColumnWidth: array[0..2] of Integer;
275+ FBoardColumnWidth: array[0..9] of Integer;
276+
277+ /// カテゴリリストカラム順序
278+ FBBSColumnOrder : TGikoBBSColumnList;
279+ /// 板リストカラム順序
280+ FCategoryColumnOrder : TGikoCategoryColumnList;
281+ /// スレリストカラム順序
282+ FBoardColumnOrder : TGikoBoardColumnList;
220283
221284 //ソート順
222285 FBBSSortIndex: Integer;
@@ -283,8 +346,6 @@ type
283346
284347 //スレッド一覧更新アイコン表示
285348 FListIconVisible: Boolean;
286- //取得数ではなく未取得を表示する
287- FNonAcquiredCount: Boolean;
288349
289350 //スレッド一覧でLogのあるスレッドのみスレ作成日を表示するか
290351 FCreationTimeLogs: Boolean;
@@ -329,12 +390,19 @@ type
329390
330391 //Tab自動保存
331392 FTabAutoLoadSave : Boolean;
393+
394+ //にちゃん語案内サポート機能
395+ F2chSupport : Boolean;
396+
332397 // エディタ
333398 FSpaceToNBSP : Boolean; ///< 半角スペース、Tab を &nbsp; に置換
334399 FAmpToCharRef : Boolean; ///< '&' を &amp; に置換
335400
336401 //ブラウザタブ非表示の時のスレ一覧でのカーソルキー移動の無反応時間
337402 FSelectInterval : Integer;
403+
404+ //KuroutSettingTab 詳細設定タブのActiveTab
405+ FKuroutSettingTabIndex: Integer;
338406
339407 function GetMainCoolSet(Index: Integer): TCoolSet;
340408 function GetBoardCoolSet(Index: Integer): TCoolSet;
@@ -526,6 +594,10 @@ type
526594 property CategoryColumnWidth[index: Integer]: Integer read GetCategoryColumnWidth write SetCategoryColumnWidth;
527595 property BoardColumnWidth[index: Integer]: Integer read GetBoardColumnWidth write SetBoardColumnWidth;
528596
597+ property BBSColumnOrder : TGikoBBSColumnList read FBBSColumnOrder write FBBSColumnOrder;
598+ property CategoryColumnOrder : TGikoCategoryColumnList read FCategoryColumnOrder write FCategoryColumnOrder;
599+ property BoardColumnOrder : TGikoBoardColumnList read FBoardColumnOrder write FBoardColumnOrder;
600+
529601 property SoundName[index: Integer]: string read GetSoundName;
530602 property SoundViewName[index: Integer]: string read GetSoundViewName;
531603 property SoundFileName[index: Integer]: string read GetSoundFileName write SetSoundFileName;
@@ -576,7 +648,6 @@ type
576648 property BrowserAutoMaximize: TGikoBrowserAutoMaximize read FBrowserAutoMaximize write FBrowserAutoMaximize;
577649
578650 property ListIconVisible: Boolean read FListIconVisible write FListIconVisible;
579- property NonAcquiredCount: Boolean read FNonAcquiredCount write FNonAcquiredCount;
580651 property CreationTimeLogs: Boolean read FCreationTimeLogs write FCreationTimeLogs;
581652 property FutureThread: Boolean read FFutureThread write FFutureThread;
582653
@@ -614,8 +685,10 @@ type
614685 property AmpToCharRef : Boolean read FAmpToCharRef write FAmpToCharRef;
615686
616687 property SelectInterval : Integer read FSelectInterval write FSelectInterval;
617- //Tab保存
618- property TabAutoLoadSave: Boolean read FTabAutoLoadSave write FTabAutoLoadSave;
688+ //Tab保存
689+ property TabAutoLoadSave: Boolean read FTabAutoLoadSave write FTabAutoLoadSave;
690+ property GengoSupport : Boolean read F2chSupport write F2chSupport;
691+ property KuroutSettingTabIndex: Integer read FKuroutSettingTabIndex write FKuroutSettingTabIndex;
619692 end;
620693
621694
@@ -654,6 +727,81 @@ var
654727 (Name: 'ResEnd'; ViewName: 'レス送信完了'; FileName: ''),
655728 (Name: 'Error'; ViewName: 'エラー'; FileName: ''));
656729
730+constructor TGikoBBSColumnList.Create;
731+begin
732+ inherited;
733+end;
734+
735+destructor TGikoBBSColumnList.Destroy;
736+begin
737+ inherited;
738+end;
739+
740+function TGikoBBSColumnList.GetItem( index : integer ) : TGikoBBSColumnID;
741+begin
742+ Result := TGikoBBSColumnID( inherited Items[ index ] );
743+end;
744+
745+procedure TGikoBBSColumnList.SetItem( index : integer; value : TGikoBBSColumnID);
746+begin
747+ inherited Items[ index ] := Pointer( value );
748+end;
749+
750+function TGikoBBSColumnList.Add( value : TGikoBBSColumnID ) : Integer;
751+begin
752+ Result := inherited Add( Pointer( value ) );
753+end;
754+
755+constructor TGikoCategoryColumnList.Create;
756+begin
757+ inherited;
758+end;
759+
760+destructor TGikoCategoryColumnList.Destroy;
761+begin
762+ inherited;
763+end;
764+
765+function TGikoCategoryColumnList.GetItem( index : integer ) : TGikoCategoryColumnID;
766+begin
767+ Result := TGikoCategoryColumnID( inherited Items[ index ] );
768+end;
769+
770+procedure TGikoCategoryColumnList.SetItem( index : integer; value : TGikoCategoryColumnID);
771+begin
772+ inherited Items[ index ] := Pointer( value );
773+end;
774+
775+function TGikoCategoryColumnList.Add( value : TGikoCategoryColumnID ) : Integer;
776+begin
777+ Result := inherited Add( Pointer( value ) );
778+end;
779+
780+constructor TGikoBoardColumnList.Create;
781+begin
782+ inherited;
783+end;
784+
785+destructor TGikoBoardColumnList.Destroy;
786+begin
787+ inherited;
788+end;
789+
790+function TGikoBoardColumnList.GetItem( index : integer ) : TGikoBoardColumnID;
791+begin
792+ Result := TGikoBoardColumnID( inherited Items[ index ] );
793+end;
794+
795+procedure TGikoBoardColumnList.SetItem( index : integer; value : TGikoBoardColumnID);
796+begin
797+ inherited Items[ index ] := Pointer( value );
798+end;
799+
800+function TGikoBoardColumnList.Add( value : TGikoBoardColumnID ) : Integer;
801+begin
802+ Result := inherited Add( Pointer( value ) );
803+end;
804+
657805 //コンストラクタ
658806 constructor TSetting.Create();
659807 begin
@@ -661,6 +809,9 @@ begin
661809 FMailList := TStringList.Create;
662810 FSelectTextList := TStringList.Create;
663811 FBoardURLs := TStringList.Create;
812+ FBBSColumnOrder := TGikoBBSColumnList.Create;
813+ FCategoryColumnOrder := TGikoCategoryColumnList.Create;
814+ FBoardColumnOrder := TGikoBoardColumnList.Create;
664815 FNameList.Duplicates := dupIgnore;
665816 FMailList.Duplicates := dupIgnore;
666817 FBoardURLs.Duplicates := dupIgnore;
@@ -673,6 +824,9 @@ end;
673824 destructor TSetting.Destroy();
674825 begin
675826 inherited;
827+ FBoardColumnOrder.Free;
828+ FCategoryColumnOrder.Free;
829+ FBBSColumnOrder.Free;
676830 FSelectTextList.Free;
677831 FBoardURLs.Free;
678832 FMailList.Free;
@@ -695,16 +849,17 @@ end;
695849 procedure TSetting.ReadSettingFile();
696850 const
697851 DEFAULT_BBS_WIDTH: array[0..0] of Integer = (140);
698- DEFAULT_CATEGORY_WIDTH: array[0..3] of Integer = (150, 80, 130, 130);
699- DEFAULT_BOARD_WIDTH: array[0..7] of Integer = (350, 60, 60, 60, 60, 80, 130, 130);
852+ DEFAULT_CATEGORY_WIDTH: array[0..2] of Integer = (150, 80, 130);
853+ DEFAULT_BOARD_WIDTH: array[0..9] of Integer = (350, 60, 60, 60, 60, 60, 80, 130, 130, 130);
700854 MAX_WIDTH: Integer = 2000;
701855 var
702856 ini: TMemIniFile;
703857 i: Integer;
858+ id, code : Integer;
704859 wkList: TStringList;
705860 wkStr: string;
706861 Exists: Boolean;
707- s: string;
862+ s: string;
708863 // id: Integer;
709864 CoolSet: TCoolSet;
710865 begin
@@ -851,7 +1006,7 @@ begin
8511006 wkList.Free;
8521007 end;
8531008
854- //リストカラム
1009+ // リストカラム幅
8551010 wkList := TStringList.Create;
8561011 try
8571012 ini.ReadSection('BBSColumnWidth', wkList);
@@ -885,6 +1040,51 @@ begin
8851040 wkList.Free;
8861041 end;
8871042
1043+ // カテゴリリストカラム順序
1044+ wkList := TStringList.Create;
1045+ try
1046+ ini.ReadSection( 'BBSColumnOrder', wkList );
1047+ for i := 0 to wkList.Count - 1 do begin
1048+ wkStr := ini.ReadString( 'BBSColumnOrder', 'ID' + IntToStr( i ), '' );
1049+ Val( wkStr, id, code );
1050+ if code = 0 then
1051+ FBBSColumnOrder.Add( TGikoBBSColumnID( id ) );
1052+ end;
1053+ if FBBSColumnOrder.Count = 0 then begin
1054+ // 設定が無いので作成
1055+ for i := 0 to Integer( High( TGikoBBSColumnID ) ) do
1056+ FBBSColumnOrder.Add( TGikoBBSColumnID( i ) );
1057+ end;
1058+
1059+ ini.ReadSection( 'CategoryColumnOrder', wkList );
1060+ for i := 0 to wkList.Count - 1 do begin
1061+ wkStr := ini.ReadString( 'CategoryColumnOrder', 'ID' + IntToStr( i ), '' );
1062+ Val( wkStr, id, code );
1063+ if code = 0 then
1064+ FCategoryColumnOrder.Add( TGikoCategoryColumnID( id ) );
1065+ end;
1066+ if FCategoryColumnOrder.Count = 0 then begin
1067+ // 設定が無いので作成
1068+ for i := 0 to Integer( High( TGikoCategoryColumnID ) ) do
1069+ FCategoryColumnOrder.Add( TGikoCategoryColumnID( i ) );
1070+ end;
1071+
1072+ ini.ReadSection( 'BoardColumnOrder', wkList );
1073+ for i := 0 to wkList.Count - 1 do begin
1074+ wkStr := ini.ReadString( 'BoardColumnOrder', 'ID' + IntToStr( i ), '' );
1075+ Val( wkStr, id, code );
1076+ if code = 0 then
1077+ FBoardColumnOrder.Add( TGikoBoardColumnID( id ) );
1078+ end;
1079+ if FBoardColumnOrder.Count = 0 then begin
1080+ // 設定が無いので作成
1081+ for i := 0 to Integer( High( TGikoBoardColumnID ) ) do
1082+ FBoardColumnOrder.Add( TGikoBoardColumnID( i ) );
1083+ end;
1084+ finally
1085+ wkList.Free;
1086+ end;
1087+
8881088 //リスト番号
8891089 FListViewNo := ini.ReadBool('Function', 'ListViewNo', True);
8901090 //CSS
@@ -958,7 +1158,6 @@ begin
9581158
9591159 //スレッド一覧更新アイコン
9601160 FListIconVisible := ini.ReadBool('ThreadList', 'StateIconVisible', True);
961- FNonAcquiredCount := ini.ReadBool('ThreadList', 'NonAcquiredCount', False);
9621161 FCreationTimeLogs := ini.ReadBool('ThreadList', 'CreationTimeLogs', True);
9631162 FFutureThread := ini.ReadBool('ThreadList', 'FutureThread', True);
9641163 FSelectInterval := ini.ReadInteger('ThreadList', 'SelectInterval', 110);
@@ -1024,11 +1223,13 @@ begin
10241223 FDeleteSyria := ini.ReadBool('Abon','DeleteSyria',false);
10251224
10261225 // エディタ
1027- FSpaceToNBSP := ini.ReadBool( 'Editor', 'SpaceToNBSP', True );
1226+ FSpaceToNBSP := ini.ReadBool( 'Editor', 'SpaceToNBSP', False );
10281227 FAmpToCharRef := ini.ReadBool( 'Editor', 'AmpToCharRef', False );
10291228
1030- //Tab自動保存、読み込み
1031- FTabAutoLoadSave := ini.ReadBool('TabAuto', 'TabAutoLoadSave', False);
1229+ //Tab自動保存、読み込み
1230+ FTabAutoLoadSave := ini.ReadBool('TabAuto', 'TabAutoLoadSave', False);
1231+
1232+ FKuroutSettingTabIndex := ini.ReadInteger('OptionDialog', 'KuroutTabIndex' , 0);
10321233
10331234
10341235 finally
@@ -1129,6 +1330,7 @@ var
11291330 i: Integer;
11301331 ini: TMemIniFile;
11311332 CoolSet: TCoolSet;
1333+ wkList : TStringList;
11321334 begin
11331335 ini := TMemIniFile.Create(GetFileName());
11341336 try
@@ -1250,11 +1452,11 @@ begin
12501452 ini.WriteBool('Browser', 'PreviewVisible', FPreviewVisible);
12511453 ini.WriteInteger('Browser', 'PreviewSize', Ord(FPreviewSize));
12521454 ini.WriteInteger('Browser', 'PreviewWait', FPreviewWait);
1253- ini.WriteInteger('Browser', 'AutoMaximize', Ord( FBrowserAutoMaximize ) );
1455+
1456+ ini.WriteInteger('Window', 'BrowserAutoMaximize', Ord( BrowserAutoMaximize ) );
12541457
12551458 //スレッド一覧更新アイコン
12561459 ini.WriteBool('ThreadList', 'StateIconVisible', FListIconVisible);
1257- ini.WriteBool('ThreadList', 'NonAcquiredCount', FNonAcquiredCount);
12581460 ini.WriteBool('ThreadList', 'CreationTimeLogs',FCreationTimeLogs);
12591461 ini.WriteBool('ThreadList', 'FutureThread', FFutureThread);
12601462 ini.WriteInteger('ThreadList', 'SelectInterval', FSelectInterval);
@@ -1273,7 +1475,7 @@ begin
12731475 ini.WriteInteger('PostTime', 'TimeAdjustSec', FTimeAdjustSec);
12741476 ini.WriteBool('PostTime', 'TimeAdjust', FTimeAdjust);
12751477
1276- //リストカラム
1478+ // リストカラム幅
12771479 for i := 0 to Length(FBBSColumnWidth) - 1 do begin
12781480 ini.WriteInteger('BBSColumnWidth', 'ID' + IntToStr(i), FBBSColumnWidth[i]);
12791481 end;
@@ -1284,6 +1486,32 @@ begin
12841486 ini.WriteInteger('BoardColumnWidth', 'ID' + IntToStr(i), FBoardColumnWidth[i]);
12851487 end;
12861488
1489+ wkList := TStringList.Create;
1490+ try
1491+ // カテゴリリスト順序
1492+ ini.ReadSection( 'BBSColumnOrder', wkList );
1493+ for i := wkList.Count - 1 downto 0 do
1494+ ini.DeleteKey( 'BBSColumnOrder', wkList[ i ] );
1495+ for i := 0 to FBBSColumnOrder.Count - 1 do
1496+ ini.WriteInteger( 'BBSColumnOrder', 'ID' + IntToStr( i ), Ord( FBBSColumnOrder[ i ] ) );
1497+
1498+ // 板リスト順序
1499+ ini.ReadSection( 'CategoryColumnOrder', wkList );
1500+ for i := wkList.Count - 1 downto 0 do
1501+ ini.DeleteKey( 'CategoryColumnOrder', wkList[ i ] );
1502+ for i := 0 to FCategoryColumnOrder.Count - 1 do
1503+ ini.WriteInteger( 'CategoryColumnOrder', 'ID' + IntToStr( i ), Ord( FCategoryColumnOrder[ i ] ) );
1504+
1505+ // スレリスト順序
1506+ ini.ReadSection( 'BoardColumnOrder', wkList );
1507+ for i := wkList.Count - 1 downto 0 do
1508+ ini.DeleteKey( 'BoardColumnOrder', wkList[ i ] );
1509+ for i := 0 to FBoardColumnOrder.Count - 1 do
1510+ ini.WriteInteger( 'BoardColumnOrder', 'ID' + IntToStr( i ), Ord( FBoardColumnOrder[ i ] ) );
1511+ finally
1512+ wkList.Free;
1513+ end;
1514+
12871515 //サウンド
12881516 for i := 0 to GetSoundCount - 1 do begin
12891517 if not FileExists(SoundFileName[i]) then
@@ -1327,9 +1555,15 @@ begin
13271555 ini.WriteBool( 'Editor', 'SpaceToNBSP', FSpaceToNBSP );
13281556 ini.WriteBool( 'Editor', 'AmpToCharRef', FAmpToCharRef );
13291557
1330- ini.WriteBool('TabAuto', 'TabAutoLoadSave', FTabAutoLoadSave);
1558+ //タブ自動保存
1559+ ini.WriteBool('TabAuto', 'TabAutoLoadSave', FTabAutoLoadSave);
1560+ //詳細設定
1561+ ini.WriteInteger('OptionDialog', 'KuroutTabIndex', FKuroutSettingTabIndex);
13311562
1332- ini.UpdateFile;
1563+ //にちゃん語案内機能
1564+ ini.WriteBool('2chSupport', 'Support', F2chSupport);
1565+
1566+ ini.UpdateFile;
13331567 finally
13341568 ini.Free;
13351569 end;
--- a/Sort.pas
+++ b/Sort.pas
@@ -3,7 +3,8 @@ unit Sort;
33 interface
44 uses
55 Windows, Messages, SysUtils, Classes, Controls, Forms,
6- BoardGroup,DateUtils;
6+ BoardGroup,DateUtils,
7+ Setting;
78
89 function CategorySortProc(Item1, Item2: Pointer): integer;
910 function BoardSortProc(List: TStringList; Item1, Item2: Integer): integer;
@@ -16,7 +17,6 @@ var
1617 SortOrder: Boolean;
1718 SortIndex: Integer;
1819 SortNoFlag: Boolean;
19- SortNonAcquiredCountFlag: Boolean;
2020
2121 implementation
2222
@@ -28,10 +28,15 @@ begin
2828 CategoryItem1 := TCategory(Item1);
2929 CategoryItem2 := TCategory(Item2);
3030
31- if SortNoFlag then
32- Result := CompareInt(CategoryItem1.No, CategoryItem2.No)
31+ case TGikoBBSColumnID( SortIndex ) of
32+ gbbscTitle:
33+ if SortNoFlag then
34+ Result := CompareInt(CategoryItem1.No, CategoryItem2.No)
35+ else
36+ Result := AnsiCompareText(CategoryItem1.Title, CategoryItem2.Title);
3337 else
34- Result := AnsiCompareText(CategoryItem1.Title, CategoryItem2.Title);
38+ Result := CompareInt(CategoryItem1.No, CategoryItem2.No)
39+ end;
3540
3641 if not SortOrder then
3742 Result := Result * -1;
@@ -44,15 +49,21 @@ var
4449 begin
4550 BoardItem1 := TBoard(List.Objects[Item1]);
4651 BoardItem2 := TBoard(List.Objects[Item2]);
47- if SortIndex = 0 then
52+ case TGikoCategoryColumnID( SortIndex ) of
53+ gccTitle:
4854 if SortNoFlag then
4955 Result := CompareInt(BoardItem1.No, BoardItem2.No)
5056 else
51- Result := AnsiCompareText(BoardItem1.Title, BoardItem2.Title)
52- else if SortIndex = 1 then
53- Result := CompareInt(BoardItem1.Count, BoardItem2.Count)
54- else
57+ Result := AnsiCompareText(BoardItem1.Title, BoardItem2.Title);
58+
59+ gccRoundName:
60+ Result := CompareInt(BoardItem1.Count, BoardItem2.Count);
61+
62+ gccLastModified:
5563 Result := CompareDate(BoardItem1.RoundDate, BoardItem2.RoundDate);
64+ else
65+ Result := CompareInt(BoardItem1.No, BoardItem2.No)
66+ end;
5667
5768 if not SortOrder then
5869 Result := Result * -1;
@@ -65,34 +76,35 @@ var
6576 begin
6677 ThreadItem1 := TThreadItem(List.Objects[ Item1 ]);
6778 ThreadItem2 := TThreadItem(List.Objects[ Item2 ]);
68- case SortIndex of
69- 0:
79+ case TGikoBoardColumnID( SortIndex ) of
80+ gbcTitle:
7081 begin
7182 if SortNoFlag then
7283 Result := CompareInt(ThreadItem1.No, ThreadItem2.No)
7384 else
7485 Result := AnsiCompareText(ThreadItem1.Title, ThreadItem2.Title)
7586 end;
76- 1: Result := CompareInt(ThreadItem1.AllResCount, ThreadItem2.AllResCount);
77- 2:
87+
88+ gbcAllCount: Result := CompareInt(ThreadItem1.AllResCount, ThreadItem2.AllResCount);
89+ gbcLocalCount: Result := CompareInt(ThreadItem1.Count, ThreadItem2.Count);
90+ gbcNonAcqCount:
7891 begin
79- if SortNonAcquiredCountFlag then
80- if ThreadItem1.IsLogFile and ThreadItem2.IsLogFile then
81- Result := CompareInt(ThreadItem1.AllResCount - ThreadItem1.Count, ThreadItem2.AllResCount - ThreadItem2.Count)
82- else if ThreadItem1.IsLogFile then
83- Result := 1
84- else if ThreadItem2.IsLogFile then
85- Result := -1
86- else
87- Result := 0
92+ if ThreadItem1.IsLogFile and ThreadItem2.IsLogFile then
93+ Result := CompareInt(ThreadItem1.AllResCount - ThreadItem1.Count, ThreadItem2.AllResCount - ThreadItem2.Count)
94+ else if ThreadItem1.IsLogFile then
95+ Result := 1
96+ else if ThreadItem2.IsLogFile then
97+ Result := -1
8898 else
89- Result := CompareInt(ThreadItem1.Count, ThreadItem2.Count);
99+ Result := 0;
90100 end;
91- 3: Result := CompareInt(ThreadItem1.NewResCount, ThreadItem2.NewResCount);
92- 4: Result := 0;
93- 5: Result := AnsiCompareText(ThreadItem1.RoundName, ThreadItem2.RoundName);
94- 6: Result := CompareDateTime(ThreadItem1.RoundDate, ThreadItem2.RoundDate);
95- 7: Result := CompareDateTime(ThreadItem1.CreateDate, ThreadItem2.CreateDate);
101+
102+ gbcNewCount: Result := CompareInt(ThreadItem1.NewResCount, ThreadItem2.NewResCount);
103+ gbcUnReadCount: Result := 0;
104+ gbcRoundName: Result := AnsiCompareText(ThreadItem1.RoundName, ThreadItem2.RoundName);
105+ gbcRoundDate: Result := CompareDateTime(ThreadItem1.RoundDate, ThreadItem2.RoundDate); {gbcLastModified:}
106+ gbcCreated: Result := CompareDateTime(ThreadItem1.CreateDate, ThreadItem2.CreateDate);
107+ gbcLastModified: Result := CompareDateTime(ThreadItem1.LastModified, ThreadItem2.LastModified); {gbcLastModified:}
96108 else
97109 Result := 0;
98110 end;
--- a/YofUtils.pas
+++ b/YofUtils.pas
@@ -9,7 +9,8 @@ interface
99 uses
1010 //==================================================
1111
12- Classes, SysUtils;
12+ Classes, SysUtils,
13+ Windows;
1314
1415 procedure ExtractHttpFields(
1516 const chrSep : TSysCharSet;
@@ -39,11 +40,61 @@ function MatchesMask(
3940 const filename, mask : string
4041 ) : boolean;
4142
42-// メタキャラクタを正規表現扱いにならないように置換
43+/// メタキャラクタを正規表現扱いにならないように置換
4344 function RegExpEncode(
4445 const text : string
4546 ) : string;
4647
48+{*!
49+\brief 表示メッセージの整形
50+\param msg 表示するメッセージ
51+\param elements 置換単語
52+
53+msg の中の置換される単語は '^番号' で表され、
54+elements は改行によって単語分けされます。<br>
55+
56+<pre><code>
57+elements := IntToStr( 10 ) + #10 + 'hoge';
58+m := MessageStyle(
59+ '^0 個の“^1”を置換しました。',
60+ elements );
61+</code></pre>
62+
63+で出力される m は「10 個の“hoge”を置換しました。」となります。
64+*}
65+function MessageStyle(
66+ const msg : string;
67+ const elements : string
68+) : string; overload;
69+
70+function MessageStyle(
71+ const msg : string;
72+ const elements : TStringList
73+) : string; overload;
74+
75+type
76+ /// Mode 値がおかしい
77+ EMappedFileModeError = class( Exception );
78+ /// マッピングに失敗
79+ EMappedFileMappingError = class( Exception );
80+
81+ /// メモリマップド・ファイル クラス
82+ TMappedFile = class( TObject )
83+ private
84+ FFileHandle : THandle;
85+ FMappingHandle : THandle;
86+ FSize : Longword;
87+ FViewAddress : Pointer;
88+ public
89+ constructor Create( const filePath : string; mode : Longword = fmOpenRead );
90+ destructor Destroy; override;
91+
92+ /// サイズの取得
93+ property Size : Longword read FSize;
94+ /// アドレスの取得
95+ property Memory : Pointer read FViewAddress;
96+ end;
97+
4798 //==================================================
4899 const
49100 //==================================================
@@ -53,6 +104,8 @@ const
53104 implementation
54105 //==================================================
55106
107+uses MojuUtils;
108+
56109 // とりあえずの代用品なので chrWhite を考慮していないことに注意!!!
57110 procedure ExtractHttpFields(
58111 const chrSep : TSysCharSet;
@@ -367,4 +420,97 @@ begin
367420
368421 end;
369422
423+function MessageStyle(
424+ const msg : string;
425+ const elements : string
426+) : string;
427+var
428+ list : TStringList;
429+begin
430+
431+ list := TStringList.Create;
432+ try
433+ list.Text := elements;
434+ Result := MessageStyle( msg, list );
435+ finally
436+ list.Free;
437+ end;
438+
439+end;
440+
441+function MessageStyle(
442+ const msg : string;
443+ const elements : TStringList
444+) : string;
445+var
446+ i : Integer;
447+begin
448+
449+ Result := msg;
450+ for i := elements.Count - 1 downto 0 do
451+ Result := CustomStringReplace( Result, '^' + IntToStr( i ), elements[ i ], false );
452+
453+end;
454+
455+{ TMappedFile }
456+
457+{*!
458+\brief メモリマップドファイルの作成
459+\param filePath 開くファイルのパス
460+\param mode fmOpenRead (デフォルト) または fmOpenReadWrite
461+*}
462+constructor TMappedFile.Create( const filePath : string; mode : Longword = fmOpenRead );
463+var
464+ dwFileDesiredAccess : DWORD;
465+ flProtect : DWORD;
466+ dwViewDesiredAccess : DWORD;
467+begin
468+
469+ case mode of
470+ fmOpenRead:
471+ begin
472+ dwFileDesiredAccess := GENERIC_READ;
473+ flProtect := PAGE_READONLY;
474+ dwViewDesiredAccess := FILE_MAP_READ;
475+ end;
476+
477+ fmOpenReadWrite:
478+ begin
479+ dwFileDesiredAccess := GENERIC_READ or GENERIC_WRITE;
480+ flProtect := PAGE_READWRITE;
481+ dwViewDesiredAccess := FILE_MAP_WRITE;
482+ end;
483+
484+ else
485+ raise EMappedFileModeError.Create( 'ファイルオープンのモードが不正です。' );
486+ end;
487+
488+ FFileHandle := CreateFile(
489+ PChar( filePath ), dwFileDesiredAccess, 0, nil, OPEN_EXISTING,
490+ FILE_ATTRIBUTE_NORMAL, 0 );
491+ if FFileHandle = INVALID_HANDLE_VALUE then
492+ raise EFOpenError.Create( 'ファイルのオープンに失敗しました。' );
493+
494+ FSize := GetFileSize( FFileHandle, nil );
495+
496+ FMappingHandle := CreateFileMapping(
497+ FFileHandle, nil, flProtect, 0, 0, nil );
498+ if FFileHandle = INVALID_HANDLE_VALUE then
499+ raise EMappedFileMappingError.Create( 'ファイルのマッピングに失敗しました。' );
500+
501+ FViewAddress := MapViewOfFile( FMappingHandle, dwViewDesiredAccess, 0, 0, 0 );
502+ if FViewAddress = nil then
503+ raise EMappedFileMappingError.Create( 'ファイルのマッピングに失敗しました。' );
504+
505+end;
506+
507+destructor TMappedFile.Destroy;
508+begin
509+
510+ UnmapViewOfFile( FViewAddress );
511+ CloseHandle( FMappingHandle );
512+ CloseHandle( FFileHandle );
513+
514+end;
515+
370516 end.
Binary files a/gikoNavi.res and b/gikoNavi.res differ
--- a/readme/readme.txt
+++ b/readme/readme.txt
@@ -1,4 +1,4 @@
1-■ギコナビ Version1.00 バタ48 Readme.txt
1+■ギコナビ Version1.00 バタ49 Readme.txt
22
33
44 ------------------------------
@@ -41,7 +41,7 @@
4141 ------------------------------
4242 バグや要望は、ギコナビスレッドで受け付けております。
4343 ギコナビサイト:http://gikonavi.sourceforge.jp/
44-ギコナビスレ:http://pc5.2ch.net/test/read.cgi/software/1079685385/l50
44+ギコナビスレ:http://pc5.2ch.net/test/read.cgi/software/1094289071/l50
4545
4646 ------------------------------
4747 転載について
@@ -89,6 +89,23 @@ Windows Server 2003 Enterprise Edition IE6
8989 ------------------------------
9090 履歴
9191 ------------------------------
92+2004/10/06
93+ Version バタ49
94+ お気に入りの読み込みの高速化による起動時間の短縮
95+ StatusBarにNGワードファイルの名前が出ない不具合の修正
96+ 「指定した番号のレスに飛ぶ」機能追加(キー設定で、スレッドカテゴリの一番最後)
97+ ログを削除した際に未読スレッド数 (UnRead) の表示が更新されないバグを修正
98+ ここにレスだと、レスエディターのショートカットキーが設定されない不具合の修正
99+ あぼーん時にココまで読んだと新着レスを調整するのに不具合があったので修正
100+ スレッド一覧の表示カラムの設定ができるようになった。「オプション」->「詳細設定」->「詳細設定2」
101+ デフォルトでのレスアンカーポップアップが種種の形式に対応
102+ 3ちゃんねる(8ちゃんねる)を登録すると2ちゃんねるの板が表示される不具合の解消
103+ お気に入りで編集中にスペースキー入力の不具合の修正
104+ したらばJBBSのlivedoor.com->livedoor.jpの変更に対応
105+ したらばJBBSの過去ログに関する不具合の修正
106+ スレッドのリンクでレス番があるものを踏んだときに、そのレス番号までスクロールするようにした。
107+ タブの保存でタブ数が0のときは、保存しないようにした。
108+
92109 2004/09/05
93110 Version バタ48
94111 レスポップアップあぼ〜ん有効にしていても、透明あぼ〜んを表示する不具合の解消
--- a/readme/setup.INF
+++ b/readme/setup.INF
@@ -77,13 +77,11 @@ Folder=gikoNavi
7777 74=config\skin\skin30-3G\NewRes.html
7878 75=config\skin\skin30-3G\Res.html
7979 76=config\BoardPlugIn\MachiBBSPlugIn.dll
80-77=config\BoardPlugIn\ShitarabaPlugIn.dll
81-78=config\BoardPlugIn\ShitarabaJBBSPlugIn.dll
82-79=config\Board\まちBBS.txt
83-80=config\Board\したらばBBS.txt
84-81=config\Board\したらばJBBS.txt
85-82=config\Board\ギコナビ.txt
86-83=Samba.default
80+77=config\BoardPlugIn\ShitarabaJBBSPlugIn.dll
81+78=config\Board\まちBBS.txt
82+79=config\Board\したらばJBBS.txt
83+80=config\Board\ギコナビ.txt
84+81=Samba.default
8785
8886 [Group]
8987 1=ギコナビ,gikoNavi.exe
--- a/res/ExternalBoardPlugIn/ShitarabaJBBSPlugIn.dpr
+++ b/res/ExternalBoardPlugIn/ShitarabaJBBSPlugIn.dpr
@@ -3,7 +3,7 @@ library ShitarabaJBBSPlugIn;
33 {
44 ShitarabaJBBSPlugIn
55 したらば処理ユニット
6- $Id: ShitarabaJBBSPlugIn.dpr,v 1.30.2.1 2004/09/09 16:20:34 yoffy Exp $
6+ $Id: ShitarabaJBBSPlugIn.dpr,v 1.30.2.2 2004/10/08 05:44:53 yoffy Exp $
77 }
88
99 uses
@@ -33,7 +33,7 @@ type
3333
3434 private
3535 function Download : TDownloadState;
36- function StorageDownload(Path, Document : string) : TDownloadState;
36+ function StorageDownload(AURL : string) : TDownloadState;
3737 function Write( inName : string; inMail : string; inMessage : string ) : TDownloadState;
3838 function GetRes( inNo : Integer ) : string;
3939 function GetDat( inNo : Integer ) : string;
@@ -281,7 +281,8 @@ var
281281 // i : Integer;
282282 const
283283 BBS_HOST_OLD = 'jbbs.shitaraba.com';
284- BBS_HOST = 'jbbs.livedoor.com';
284+ BBS_HOST_OLD2 = 'jbbs.livedoor.com';
285+ BBS_HOST = 'jbbs.livedoor.jp';
285286 THREAD_MARK = '/bbs/read.cgi';
286287 begin
287288
@@ -290,7 +291,7 @@ begin
290291 uri := TIdURI.Create( inURL );
291292 uriList := TStringList.Create;
292293 try
293- if uri.Host = BBS_HOST_OLD then
294+ if (uri.Host = BBS_HOST_OLD) or (uri.Host = BBS_HOST_OLD2) then
294295 uri.Host := BBS_HOST;
295296
296297 ExtractHttpFields( ['/'], [], uri.Path, uriList );
@@ -349,12 +350,13 @@ var
349350
350351 found : Integer;
351352 found2 : Integer;
353+ pos : Integer;
352354 board : string;
353355 const
354356 CATEGORY_INPUT = 'カテゴリを入力してください';
355357 KEYWORD_INPUT = '検索する板名を入力してください';
356358 SAVEPATH_SELECT = '保存するファイル名を入力してください';
357- BBS_HOST = 'http://jbbs.livedoor.com/';
359+ BBS_HOST = 'http://jbbs.livedoor.jp/';
358360 label
359361 NextBoard;
360362 begin
@@ -437,8 +439,12 @@ begin
437439
438440 saveText.Add( board );
439441 NextBoard:
440- found := AnsiPos( '<a ', downResult );
442+ found := AnsiPos( '<a ', downResult );
441443 end;
444+ pos := saveText.IndexOf('JBBS=/');
445+ if pos > 0 then
446+ saveText.Delete(pos);
447+
442448 saveText.SaveToFile( savepath );
443449 saveText.Free;
444450 end else begin
@@ -499,22 +505,14 @@ begin
499505 uriList := TStringList.Create;
500506 try
501507 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
502- if (AnsiPos('.html', uri.Document) = 0) then begin //通常
503- if uriList[ 5 ] = 'l100' then begin
504- FileName := uriList[ 4 ] + '.dat';
505- FilePath := MyLogFolder + uriList[ 2 ] + '\' + uriList[ 3 ] + '\' + uriList[ 4 ] + '.dat';
506- IsLogFile := FileExists( FilePath );
507- end else begin
508- FileName := uriList[ 5 ] + '.dat';
509- FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
510- IsLogFile := FileExists( FilePath );
511- end;
512- end else begin //過去ログ
513- //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
514- FileName := Copy(uri.Document, 1, Length(uri.Document) - 5) + '.dat';
515- FilePath := MyLogFolder + CustomStringReplace(CustomStringReplace(uri.Path, '/storage', ''), '/', '\') + FileName;
508+ if uriList[ 5 ] = 'l100' then begin
509+ FileName := uriList[ 4 ] + '.dat';
510+ FilePath := MyLogFolder + uriList[ 2 ] + '\' + uriList[ 3 ] + '\' + uriList[ 4 ] + '.dat';
511+ IsLogFile := FileExists( FilePath );
512+ end else begin
513+ FileName := uriList[ 5 ] + '.dat';
514+ FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
516515 IsLogFile := FileExists( FilePath );
517-
518516 end;
519517 finally
520518 uri.Free;
@@ -551,97 +549,109 @@ var
551549 logStream : TFileStream;
552550 uri : TIdURI;
553551 uriList : TStringList;
554- datURL : string;
555- tmpText: string;
552+ datURL, tmpURL : string;
553+ tmpText: string;
556554 begin
557555
558556 Result := dsError;
559557
560558 uri := TIdURI.Create( ReadURL );
561- if(( AnsiPos('.html', uri.Document) >0 ) and ( AnsiPos('/storage/', uri.Path) > 0 )) then begin
562- //過去ログ
563- Result := StorageDownload(uri.Path, uri.Document);
564- uri.Free;
565- end else begin
566- //現在生きてるスレッド
567- uriList := TStringList.Create;
568- try
569- ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
570- FileName := uriList[ 5 ] + '.dat';
571- // http://jbbs.livedoor.com/bbs/rawmode.cgi/game/1578/1067968274/l100
572- // protocol://host/1/2/3/4/5/uriList.Count - 1
573- if MyLogFolder = '' then begin
574- // どこに保存していいのか分からないので一時ファイルに保存
575- FilePath := TemporaryFile;
576- FIsTemporary := True;
577- end else begin
578- FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
579- FIsTemporary := False;
580- end;
581- finally
582- uri.Free;
583- uriList.Free;
559+ uriList := TStringList.Create;
560+ try
561+ ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
562+ FileName := uriList[ 5 ] + '.dat';
563+ // http://jbbs.livedoor.com/bbs/rawmode.cgi/game/1578/1067968274/l100
564+ // protocol://host/1/2/3/4/5/uriList.Count - 1
565+ if MyLogFolder = '' then begin
566+ // どこに保存していいのか分からないので一時ファイルに保存
567+ FilePath := TemporaryFile;
568+ FIsTemporary := True;
569+ end else begin
570+ FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
571+ FIsTemporary := False;
584572 end;
573+ finally
574+ uri.Free;
575+ uriList.Free;
576+ end;
585577
586- // 保存用のディレクトリを掘る
587- ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
578+ // 保存用のディレクトリを掘る
579+ ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
588580
589- // 独自にダウンロードやフィルタリングを行わない場合は
590- // InternalDownload に任せることが出来る
591- modified := LastModified;
592- datURL := ReadURL + IntToStr( Count + 1 ) + '-'; // 新着のみ
593- responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
581+ // 独自にダウンロードやフィルタリングを行わない場合は
582+ // InternalDownload に任せることが出来る
583+ modified := LastModified;
584+ datURL := ReadURL + IntToStr( Count + 1 ) + '-'; // 新着のみ
585+ responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
594586
595- try
596- if (responseCode = 200) or (responseCode = 206) then begin
597- downResult := TStringList.Create;
598- try
599- tmpText := CustomStringReplace( string( tmp ), '。?ョ', ',' );
600- downResult.Text := EUCtoSJIS( tmpText );
601- ArrangeDownloadData(Count, downResult);
602- if downResult.Count > 0 then begin
603- if FileExists( FilePath ) then
604- logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
605- else
606- logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
607- try
608- logStream.Position := logStream.Size;
609- logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
610- finally
611- logStream.Free;
612- end;
587+ try
588+ if (responseCode = 200) or (responseCode = 206) then begin
589+ downResult := TStringList.Create;
590+ try
591+ tmpText := CustomStringReplace( string( tmp ), '。?ョ', ',' );
592+ downResult.Text := EUCtoSJIS( tmpText );
593+ ArrangeDownloadData(Count, downResult);
594+ if downResult.Count > 0 then begin
595+ if FileExists( FilePath ) then
596+ logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
597+ else
598+ logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
599+ try
600+ logStream.Position := logStream.Size;
601+ logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
602+ finally
603+ logStream.Free;
604+ end;
613605
614- if Count = 0 then
615- // 新規
616- Result := dsComplete
617- else
618- // 追記
619- Result := dsDiffComplete;
606+ if Count = 0 then
607+ // 新規
608+ Result := dsComplete
609+ else
610+ // 追記
611+ Result := dsDiffComplete;
620612
621- Size := Size + Length( downResult.Text );
622- // CGI からは正しい日付が得られないので現在に設定
623- LastModified := Now;
613+ Size := Size + Length( downResult.Text );
614+ // CGI からは正しい日付が得られないので現在に設定
615+ LastModified := Now;
624616
625617
626618
627- NewReceive := Count + 1;
628- Count := Count + downResult.Count;
629- NewResCount := downResult.Count;
619+ NewReceive := Count + 1;
620+ Count := Count + downResult.Count;
621+ NewResCount := downResult.Count;
630622
631623
632624
633- end else begin
634- Result := dsNotModify;
635- end;
636- finally
637- downResult.Free;
625+ end else begin
626+ Result := dsNotModify;
638627 end;
639- end else if responseCode = 304 then begin
640- Result := dsNotModify;
628+ finally
629+ downResult.Free;
641630 end;
642- finally
643- DisposeResultString( tmp );
631+ end else if responseCode = 302 then begin
632+ //http://jbbs.shitaraba.com/bbs/read.cgi/game/3477/1077473358/
633+ //http://jbbs.shitaraba.com/game/bbs/read.cgi?BBS=3477&KEY=1077473358
634+ //http://jbbs.shitaraba.com/game/3477/storage/1077473358.html
635+ //過去ログ
636+ //tmpURL := URL;
637+ if Assigned( InternalPrint ) then
638+ InternalPrint( '過去ログ倉庫入り' );
639+ uri := TIdURI.Create( ReadURL );
640+ uriList := TStringList.Create;
641+ try
642+ ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
643+ tmpURL := uri.Protocol + '://' + uri.Host +
644+ '/' + uriList[3] + '/' + uriList[4] + '/storage/' + uriList[ 5 ] + '.html';
645+ finally
646+ uriList.Free;
647+ uri.Free;
648+ end;
649+ Result := StorageDownload(tmpURL);
650+ end else if responseCode = 304 then begin
651+ Result := dsNotModify;
644652 end;
653+ finally
654+ DisposeResultString( tmp );
645655 end;
646656
647657 end;
@@ -681,17 +691,16 @@ end;
681691 // 過去ログ用Download関数
682692 // *************************************************************************
683693 function TShitarabaThreadItem.StorageDownload(
684- Path, Document : string
694+ AURL : string
685695 ) : TDownloadState;
686696 var
687697 modified : Double;
688698 tmp : PChar;
699+ uri : TIdURI;
700+ uriList : TStringList;
689701 downResult : TStringList;
690702 responseCode : Longint;
691703 logStream : TFileStream;
692- //uri : TIdURI;
693- //uriList : TStringList;
694- datURL : string;
695704 tmpText, tmpLine, tmpTitle: string;
696705 tmpHTML: TStringList;
697706
@@ -700,23 +709,24 @@ var
700709 begin
701710
702711 Result := dsError;
703-
704- //uri := TIdURI.Create( ReadURL );
712+ uri := TIdURI.Create( ReadURL );
713+ uriList := TStringList.Create;
705714 try
706- FileName := Copy(Document, 1, Length(Document) - 5) + '.dat';
715+ ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
716+ FileName := uriList[ 5 ] + '.dat';
717+ // http://jbbs.livedoor.com/bbs/rawmode.cgi/game/1578/1067968274/l100
718+ // protocol://host/1/2/3/4/5/uriList.Count - 1
707719 if MyLogFolder = '' then begin
708720 // どこに保存していいのか分からないので一時ファイルに保存
709721 FilePath := TemporaryFile;
710722 FIsTemporary := True;
711723 end else begin
712- FilePath := MyLogFolder
713- + CustomStringReplace(CustomStringReplace(Path, '/storage', ''), '/', '\')
714- + FileName;
715-
724+ FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
716725 FIsTemporary := False;
717726 end;
718727 finally
719- //uri.Free;
728+ uri.Free;
729+ uriList.Free;
720730 end;
721731
722732 // 保存用のディレクトリを掘る
@@ -728,8 +738,7 @@ begin
728738 // InternalDownload に任せることが出来る
729739 modified := LastModified;
730740
731- datURL := ReadURL;
732- responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
741+ responseCode := InternalDownload( PChar( AURL ), modified, tmp, 0 );
733742
734743 try
735744 if (responseCode = 200) or (responseCode = 206) then begin
@@ -794,7 +803,7 @@ begin
794803 end;
795804 tmpHTML.Delete(i);
796805 end;
797- j := 0;
806+ j := 0;
798807 for i := 0 to tmpHTML.Count - 1 do begin
799808 tmpLine := AnsiLowerCase(tmpHTML[i]);
800809 tS := AnsiPos('<dl>', tmpLine);
@@ -915,31 +924,27 @@ begin
915924
916925 if downResult.Count > 0 then begin
917926 if FileExists( FilePath ) then
918- logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
919- else
920- logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
927+ DeleteFile(FilePath);
928+
929+ logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
921930 try
922- logStream.Position := logStream.Size;
931+ logStream.Position := 0;
923932 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
924933 finally
925934 logStream.Free;
926935 end;
927936
928- if Count = 0 then
929- // 新規
930- Result := dsComplete
931- else
932- // 追記
933- Result := dsDiffComplete;
937+ // 新規
938+ Result := dsComplete;
934939
935- Size := Size + Length( downResult.Text );
940+ Size := Length( downResult.Text );
936941 // CGI からは正しい日付が得られないので現在に設定
937942 LastModified := Now;
938943
939944
940945
941- NewReceive := Count + 1;
942- Count := Count + downResult.Count;
946+ NewReceive := 1;
947+ Count := downResult.Count;
943948 NewResCount := downResult.Count;
944949 //http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1086710948/l100
945950 //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
@@ -1144,7 +1149,8 @@ var
11441149 tmphost: String;
11451150 const
11461151 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1147- BBS_HOST = 'jbbs.livedoor.com';
1152+ BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1153+ BBS_HOST = 'jbbs.livedoor.jp';
11481154 begin
11491155
11501156 uri := TIdURI.Create( ReadURL );
@@ -1154,22 +1160,15 @@ begin
11541160
11551161 tmphost := uri.Host;
11561162
1157- if tmphost = BBS_HOST_OLD then
1163+ if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
11581164 tmphost := BBS_HOST;
11591165
1160- if( AnsiPos('.html', uri.Document) = 0 ) then begin //通常
1161- FileName := uriList[ 5 ] + '.dat';
1162- // http://jbbs.livedoor.com/bbs/read.cgi/computer/351/1090404452/l100
1163- // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1164- // http://jbbs.livedoor.com/game/1000/subject.txt
1165- Result := CreateResultString(
1166- uri.Protocol + '://' + tmphost + '/' + uriList[ 3 ] + '/' + uriList[ 4 ] + '/' );
1167- end else begin
1168- //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
1169- Result := CreateResultString(
1170- uri.Protocol + '://' + tmphost + CustomStringReplace(uri.Path, '/storage', ''));
1171- end;
1172-
1166+ FileName := uriList[ 5 ] + '.dat';
1167+ // http://jbbs.livedoor.com/bbs/read.cgi/computer/351/1090404452/l100
1168+ // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1169+ // http://jbbs.livedoor.com/game/1000/subject.txt
1170+ Result := CreateResultString(
1171+ uri.Protocol + '://' + tmphost + '/' + uriList[ 3 ] + '/' + uriList[ 4 ] + '/' );
11731172 finally
11741173 uri.Free;
11751174 uriList.Free;
@@ -1219,7 +1218,8 @@ var
12191218 dir, tmphost : string;
12201219 const
12211220 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1222- BBS_HOST = 'jbbs.livedoor.com';
1221+ BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1222+ BBS_HOST = 'jbbs.livedoor.jp';
12231223 begin
12241224
12251225 foundPos := AnsiPos( '?', URL );
@@ -1232,7 +1232,7 @@ begin
12321232 dir := uriList[ 1 ];
12331233
12341234 tmphost := uri.Host;
1235- if tmphost = BBS_HOST_OLD then
1235+ if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
12361236 tmphost := BBS_HOST;
12371237
12381238 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
@@ -1254,7 +1254,7 @@ begin
12541254 ExtractHttpFields( ['/'], [], uri.Path, uriList );
12551255
12561256 tmphost := uri.Host;
1257- if tmphost = BBS_HOST_OLD then
1257+ if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
12581258 tmphost := BBS_HOST;
12591259
12601260 if( AnsiPos(THREAD_MARK, URL) > 0) and (uriList.Count > 5) then begin
@@ -1265,7 +1265,8 @@ begin
12651265 end else if AnsiPos(THREAD_MARK, URL) = 0 then begin
12661266 //ココで過去ログかどうかチェック?
12671267 if(AnsiPos('.html/', uri.Path) > 0) then begin
1268- Result := uri.Protocol + '://' + tmphost + Copy(uri.Path, 1, Length(uri.Path) - 1);
1268+ Result := uri.Protocol + '://' + tmphost + THREAD_MARK +
1269+ CustomStringReplace(CustomStringReplace(uri.Path, '/storage', ''), '.html/', '/') + 'l100';
12691270 end else
12701271 Result := URL;
12711272 end;
@@ -1290,7 +1291,8 @@ var
12901291 dir, tmphost : string;
12911292 const
12921293 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1293- BBS_HOST = 'jbbs.livedoor.com';
1294+ BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1295+ BBS_HOST = 'jbbs.livedoor.jp';
12941296 begin
12951297
12961298 foundPos := AnsiPos( '?', URL );
@@ -1303,7 +1305,7 @@ begin
13031305 dir := uriList[ 1 ];
13041306
13051307 tmphost := uri.Host;
1306- if tmphost = BBS_HOST_OLD then
1308+ if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
13071309 tmphost := BBS_HOST;
13081310
13091311 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
@@ -1325,19 +1327,13 @@ begin
13251327 ExtractHttpFields( ['/'], [], uri.Path, uriList );
13261328
13271329 tmphost := uri.Host;
1328- if tmphost = BBS_HOST_OLD then
1330+ if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
13291331 tmphost := BBS_HOST;
13301332 // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
13311333 if( AnsiPos(THREAD_MARK, URL) > 0) and (uriList.Count > 5) then begin
13321334 Result :=
13331335 uri.Protocol + '://' + tmphost + '/bbs/rawmode.cgi/' +
13341336 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
1335- end else if AnsiPos(THREAD_MARK, URL) = 0 then begin
1336- //ココで過去ログかどうかチェック?
1337- if(AnsiPos('.html/', uri.Path) > 0) then begin
1338- Result := uri.Protocol + '://' + tmphost + Copy(uri.Path, 1, Length(uri.Path) - 1);
1339- end else
1340- Result := URL;
13411337 end;
13421338 finally
13431339 uri.Free;
@@ -1419,7 +1415,8 @@ var
14191415 uriList : TStringList;
14201416 const
14211417 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1422- BBS_HOST = 'jbbs.livedoor.com';
1418+ BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1419+ BBS_HOST = 'jbbs.livedoor.jp';
14231420 begin
14241421
14251422 inherited;
@@ -1436,7 +1433,7 @@ begin
14361433 uri := TIdURI.Create( SubjectURL );
14371434 uriList := TStringList.Create;
14381435 try
1439- if uri.Host = BBS_HOST_OLD then
1436+ if (uri.Host = BBS_HOST_OLD) or (uri.Host = BBS_HOST_OLD2) then
14401437 uri.Host := BBS_HOST;
14411438 URL := uri.Protocol + '://' + uri.Host + uri.Path;
14421439
--- a/res/skin/skin30-2G/Header.html
+++ b/res/skin/skin30-2G/Header.html
@@ -15,7 +15,7 @@
1515 var start_time = new Date();
1616 //==========グローバル変数
1717 var anchorHead="";
18-var skinName="skin30-2 v3.1.11xx";
18+var skinName="skin30-2 v3.3.09xx";
1919 var browser="ギコナビ";
2020 //==========ギコナビ用アンカーの判定(0:処理無し,1:ポップアップ,2:ボタン挿入)
2121 // ギコナビでは、レスアンカーは相対アドレスで記述される
@@ -27,13 +27,22 @@ function checkAnchor(href){if(!href){return(0)}
2727 //==========リンク設定
2828 function addAnchor(inner,num){
2929 if(!t_url){threadurl()}
30- return('<a href="../test/read.cgi/'+t_bbs+'/'+t_key+'/'+inner+'" target="_blank" onclick="blur()">'+num+'</a>')
30+ var url=document.getElementsByName("ThreadURL")[0].content;
31+ if(url.match(/&/)){
32+ return('<a href="../test/read.cgi?bbs='+t_bbs+'&key='+t_key+'&st='+inner+'&to='+inner+'&nofirst=true" target="_blank" onclick="blur()">'+num+'</a>')
33+ }else{
34+ return('<a href="../test/read.cgi/'+t_bbs+'/'+t_key+'/'+inner+'" target="_blank" onclick="blur()">'+num+'</a>')
35+ }
3136 }
3237 // スレッドURLの取得
3338 var t_url=false,t_domain,t_bbs,t_key;
3439 function threadurl(){
3540 var threadurl=document.getElementsByName("ThreadURL")[0].content;
36- threadurl.match(/^.*\/test\/read.cgi\/(.*)\/(.*)\//);
41+ if(threadurl.match(/&/)){
42+ threadurl.match(/bbs=(.*)&key=(\d*)/);
43+ }else{
44+ threadurl.match(/^.*\/test\/read.cgi\/(.*)\/(.*)\//);
45+ }
3746 t_url=true;
3847 t_bbs=RegExp.$1;
3948 t_key=RegExp.$2;
--- a/res/skin/skin30-2G/chie_event.js
+++ b/res/skin/skin30-2G/chie_event.js
@@ -2,7 +2,8 @@
22 //外部関数:tohan
33 //外部変数:anchorHead,lightmode,getID,skinName,browser,dts
44 //グローバル変数
5-var buffer=1; // 低速回線や低速マシンの場合にはbufferの数値を増やすとより正確にジャンプ(1増やすと0.1秒遅れる)
5+var buffer=1; // 低速回線や低速マシンの場合にはbufferの数値を増やすとより正確にジャンプ(1増やすと0.1秒遅れる)
6+var newResJump=1; // 新着レスジャンプ(0:ブラウザ任せ、1:読了時のみ、2:常時)*かちゅ、OpenJane、twintailのみの設定
67 //========Click処理→search,他
78 document.onclick = clickEvent;
89 function clickEvent(){
@@ -40,10 +41,19 @@ function mouseOverEvent() {
4041 else if(e.innerText.match(/^あぼ〜ん$/)) {abonePopup(e);}
4142 }
4243 if(e.tagName=='A'){
43- e.href=e.href.replace(/>/g,"");
44- e.href=e.href.replace(/\/ime.nu/g,"");
44+ if(!e.innerText.match(/%/)){ // URLエンコードでありがちな%がなければ
45+ e.href=e.href.replace(/>/g,"");
46+ e.href=e.href.replace(/\/ime.nu/g,"");
47+ }else{
48+ try{
49+ e.title=decodeURI(e.innerText);
50+ }catch(err){
51+ // ShiftJIS,EUC-JPのデコードは面倒だからつけない。
52+ }
53+ }
4554 if (checkAnchor(e.href)==2){insButton(e);return;}
4655 else if(checkAnchor(e.href)==1){
56+ if(event.shiftKey){if(e.rel){e.href=e.rel}return}
4757 // 多段ポップアップ
4858 var aNum=parseInt(e.sourceIndex)+1;
4959 if(!document.getElementById("p"+aNum)){
@@ -96,10 +106,10 @@ function scroll_End(){document.getElementsByTagName("DL")[0].lastChild.scrollInt
96106 // IMG
97107 function imgCommand(mode,s){
98108 if(!waited){
99- var nHTML='<div id="command" onclick="clearCommand()"><input type="button" onclick="allImageLoad(\'all\')" value="全レス一括読込"><br><input type="button" onclick="allImageLoad(\'new\')" value="新レス一括読込"><br></div>';
109+ var nHTML='<div id="command" onclick="clearCommand()"><input type="button" onclick="allImageLoad(\'all\')" value="全レス一括読込"><br><input type="button" onclick="allImageLoad(\'new\')" value="新レス一括読込"><br><input type="button" onclick="removeError()" value="Error画像削除"><br></div>';
100110 event.srcElement.parentElement.insertAdjacentHTML('beforeEnd',nHTML);
101111 if(skinName.match(/30-2/)){
102- if(!lightmode){document.getElementById("command").insertAdjacentHTML('afterBegin','<input type="button" onclick="changePanel()" value="パネル切替"><br>')}
112+ //if(!lightmode){document.getElementById("command").insertAdjacentHTML('afterBegin','<input type="button" onclick="changePanel()" value="パネル切替"><br>')}
103113 document.getElementById("command").insertAdjacentHTML('beforeEnd','<input type="button" onclick="changeMode()" value="モード切替">')
104114 }
105115 waited=true;
@@ -109,7 +119,7 @@ function imgCommand(mode,s){
109119 }
110120 function clearCommand(){
111121 waited=false;
112- event.srcElement.parentElement.removeNode(true);
122+ document.getElementById("command").removeNode(true);
113123 }
114124 //=========左長押処理→copyMenu()
115125 document.onmousedown=mousedownEvent;
@@ -122,6 +132,7 @@ function mousedownEvent(){
122132 clickTimer=setTimeout("copyMenu()",500);
123133 }
124134 }
135+
125136 //コピーメニュー→colorChange(),search::copyText()
126137 function copyMenu(){
127138 clickCancel=true; clearTimeout(clickTimer);
@@ -165,27 +176,53 @@ function key(){
165176 }
166177 }
167178
168-//=========Load(代替)処理(各Footerもしくは、Headerでのループから呼出し)
179+//=========新着レス取得後処理(標準スキン未対応ブラウザ用)←Timer又はFooterから呼び出し
180+//=========かちゅ、ABone、ゾヌ2
169181 var newResNum=parseInt(document.getElementsByName("GetRescount")[0].content)+1;
170182 var k=0;
171-function loadEvent(){
172- //GetRescount代替 "数字でなければ"
173- if(isNaN(newResNum)){while(dts[k]){if(dts[k].className=="new"){newResNum=parseInt(dts[k].firstChild.innerText);break;} k++; }}
174- //新着開始ナンバーを設定してジャンプ
183+function loadEvent(num){ // Timer又はFooterから
184+ //====新着レスジャンプ
185+ if(newResJump==0){clearInterval(timerID);return} //「ブラウザ任せ」なら終了
186+ //新着レスの開始番号を取得
187+ if (browser=="かちゅ〜しゃ"){if(isNaN(newResNum)){while(dts[k]){if(dts[k].className=="new"){newResNum=parseInt(dts[k].firstChild.innerText);break;} k++;}}}
188+ else if(browser=="ホットゾヌ2"){newResNum=num+1;}
175189 var anc=document.anchors(anchorHead+newResNum);
176- if(anc && anc.parentElement){
177- if(buffer==0){clearInterval(timerID);moveToNew(newResNum);}
178- else {buffer--;}
179- }
190+ if(!anc || !anc.parentElement){return} // 透明あぼ〜んされてたら終了
191+ //新着レスジャンプ
192+ scr=lightmode ? document.body : document.getElementById("dl");
193+ viewPos=scr.scrollTop+scr.clientHeight;// スクロール後の画面下部位置
194+ endPos =anc.offsetTop+20; // 新レスアンカー位置
195+ //最後まで読了 or 「常に新着ジャンプ」ならジャンプ
196+ if(viewPos>endPos || newResJump==2){clearInterval(timerID);setTimeout("moveToNew("+newResNum+")",buffer*100)}
197+ else{firstNew=document.anchors(anchorHead+newResNum).parentElement.nextSibling;}
198+}
199+//=========新着レス取得後処理(標準スキン対応ブラウザ用)←NewMarkから呼び出し
200+//=========OpenJ、twin
201+var scr,viewPos,endPos=0;
202+function reloadEvent(){
203+ //====既読化
204+ var lastDt=dts[dts.length-2];if(!lastDt){return}// 全部新着なら終了
205+ while(lastDt && lastDt.className=="new"){lastDt.className="";lastDt=lastDt.previousSibling.previousSibling;}
206+ //====新着レスジャンプ
207+ if(newResJump==0){return} //「ブラウザ任せ」なら終了
208+ var ancs=document.anchors;
209+ var newResNum=parseInt(ancs[ancs.length-1].name)+1;
210+ scr=lightmode ? document.body : document.getElementById("dl");
211+ viewPos=scr.scrollTop;
212+ endPos =scr.scrollHeight-scr.clientHeight-20;
213+ //最後まで読了 or 「常に新着ジャンプ」ならジャンプ
214+ if(viewPos>endPos || newResJump==2){setTimeout("moveToNew("+newResNum+")",buffer*100);}
180215 }
216+
181217 // 新着レス移動+新着レスの位置を記憶
182218 var firstNew;
183219 function moveToNew(num){
184220 firstNew=getDTfromAnc(num);
185- if(firstNew){firstNew.scrollIntoView(true);}
221+ while(!firstNew){num--;firstNew=getDTfromAnc(num);} //対象が透明あぼ〜んなら数を減らす
222+ firstNew.scrollIntoView(true);
186223 }
187224
188-//=========DblClick処理→defaultPopup()
225+//=========DoubleClick処理→defaultPopup()
189226 document.ondblclick=defaultPopup;
190227 function defaultPopup(){
191228 var num=document.selection.createRange().text.replace(/\s$/,"");
@@ -200,4 +237,17 @@ function defaultPopup(){
200237 obj.innerText="ID:"+num;
201238 search(obj);
202239 }
203-}
\ No newline at end of file
240+}
241+
242+//=========Copy処理
243+//headから読むとbodyは見えないので、専用ブラウザの特質を利用してbodyの後ろに書き出す
244+//本来どおりheadに書き出すSkinManager対策で判定を一つ入れる
245+ if(document.body) document.write('<script type="text/javascript">document.body.oncopy=copyEvent</script>\n');
246+function copyEvent(){
247+ var textarea=document.createElement("TEXTAREA");
248+ textarea.value=document.selection.createRange().text.replace(/\s(\r\n|$)/g,"\n");
249+ var copyText=textarea.createTextRange();
250+ copyText.execCommand("Copy");
251+ return false;
252+}
253+
--- a/res/skin/skin30-2G/chie_image.js
+++ b/res/skin/skin30-2G/chie_image.js
@@ -2,7 +2,8 @@
22 // 外部関数:addAnchor
33 // 外部変数:cp,tp,vp,dds
44 //======画像読込の設定
5-var onMouseLoad=true; // true:カーソルを合わせただけ、false:LOADボタンをクリックしてから
5+var onMouseLoad=true; // true:カーソルを合わせただけ、false:LOADボタンをクリックしてから
6+var takeArisk=false; // true:画像読み込み時にモード切替、false:手動でモード切替
67 //==========グローバル変数
78 //==========画像処理等
89 var lightmode = true;
@@ -68,12 +69,13 @@ function insButton(a,hRH) {
6869 // 画像読込
6970 function loadImage(btn,href){
7071 if(!panel){changePanel()}
72+ if(takeArisk && lightmode){changeMode()}
7173 if(btn.tagName!="A"){
7274 var thumbs = document.images;
7375 var l=thumbs.length;
7476 for(var i=l;i--;){if(thumbs[i].src==href){
7577 if(lightmode){tp.style.visibility="visible";viewed=true;}
76- thumbs[i].scrollIntoView(true);
78+ //thumbs[i].scrollIntoView(true);
7779 imgOver(thumbs[i],100);
7880 return true;
7981 }}
@@ -103,7 +105,7 @@ function loadImage(btn,href){
103105 function imgResult(img){
104106 var btn=img.parentElement.children.item(2);
105107 if(event.type=="load"){btn.value='___'; img.style.display='block';}
106- else {btn.value='NONE';btn.style.color='#C00';}
108+ else {btn.value='NONE';btn.style.color='#C00';setTimeout("viewed=false",3000)}
107109 }
108110 // サイズの切替
109111 function changeSize(btn){
@@ -122,6 +124,15 @@ function changeSize(btn){
122124 }
123125 // サムネイルの削除
124126 function removeThumb(btn){btn.parentElement.removeNode(true);}
127+function removeError(){
128+ if(tp){
129+ var l=tp.childNodes.length;
130+ for(var i=l;i--;){
131+ var stateBtn=tp.childNodes[i].childNodes[2];
132+ if(stateBtn.tagName=="BUTTON" && stateBtn.innerText=="NONE"){stateBtn.parentElement.removeNode(true);}
133+ }
134+ }
135+}
125136 // 画像表示の切替
126137 function changeView(mode,href){
127138 if(!href){href=event.srcElement.src}
--- a/res/skin/skin30-2G/chie_popup.js
+++ b/res/skin/skin30-2G/chie_popup.js
@@ -15,7 +15,7 @@ var pb;
1515 function namePopup(e,before,num,after){
1616 var hnum=tohan(num);
1717 //3周年、4周年、Socket774、774KB、21禁、[1-30]、などに対応
18- if(before){if(hnum==3 || hnum==774 || hnum==4 || hnum==21 || hnum==1 || hnum==30){return}}
18+ if(before){if(hnum==5 || hnum==774 || hnum==4 || hnum==21 || hnum==1 || hnum==30){return}}
1919 e.outerHTML = "<b>"+before+"</b><b>"+addAnchor(hnum,num)+"</b><b>"+after+"</b>";
2020 }
2121 //=========弱あぼ〜んのポップアップ
--- a/res/skin/skin30-2G/chie_search.js
+++ b/res/skin/skin30-2G/chie_search.js
@@ -110,7 +110,7 @@ function clearResult(obj){
110110 for(var i=l;i--;){
111111 var dt=eval(arrayElement); var dd=dt.nextSibling;
112112 //Live機能追加 - 透明あぼ〜ん
113- if(browser=="Live2ch"){location.href='func:ABONECLEAR?'+dt.firstChild.innerText;continue;}
113+ if(browser=="Live2ch"){location.href='func:ABONECLEAR?'+dt.firstChild.innerText;}
114114 dt.removeNode(true); dd.removeNode(true);
115115 }
116116 }
@@ -144,7 +144,7 @@ function findIt(word){
144144
145145 //==========逆参照
146146 function searchRef(obj){
147- if(obj.name!='reffered'){
147+ if(obj.name!='referred'){
148148 var num=obj.firstChild.innerText;
149149 var l=dds.length;
150150 var found = new Array;
@@ -171,7 +171,7 @@ function searchRef(obj){
171171 if(exist){
172172 var dt=dds[i].previousSibling.cloneNode(true);
173173 found.unshift(dt.outerHTML.replace(/name=.*?>/,">")+dd.outerHTML.replace(/<a name=.*>/i,""));
174- obj.name="reffered";
174+ obj.name="referred";
175175 }
176176 }
177177 if(found.length){returnRef(obj.nextSibling,found)}
@@ -190,13 +190,12 @@ function returnRef(dd,found){
190190 function copyText(target){
191191 var num=event.srcElement.parentElement.name;
192192 var obj=getDTfromAnc(num);
193- var decoy=document.createDocumentFragment();
194193 var textarea=document.createElement("TEXTAREA");
195- if (target=="res") {textarea.value=obj.firstChild.innerText+" :"+obj.childNodes[1].innerText+" :"+obj.lastChild.innerText+"\n"+obj.nextSibling.innerText+"\n";}
194+ var message=obj.nextSibling.innerText.replace(/\s(\r\n|$)/g,"\n");
195+ if (target=="res") {textarea.value=obj.firstChild.innerText+" :"+obj.childNodes[1].innerText+" :"+obj.lastChild.innerText+"\n"+message;}
196196 else if(target=="name"){textarea.value=obj.childNodes[1].innerText+"\n";}
197- else if(target=="id") {textarea.value=obj.lastChild.innerText.substr(15)+"\n";}
198- decoy.appendChild(textarea);
199- var copyText=decoy.getElementsByTagName("TEXTAREA")[0].createTextRange();
197+ else if(target=="id") {textarea.value="ID:"+(obj.lastChild.innerText.split(/ID:/))[1]+"\n";}
198+ var copyText=textarea.createTextRange();
200199 copyText.execCommand("Copy")
201200 event.srcElement.parentElement.removeNode(true);
202201 }
--- a/res/skin/skin30-3G/Header.html
+++ b/res/skin/skin30-3G/Header.html
@@ -15,11 +15,11 @@
1515 var start_time = new Date();
1616 //==========グローバル変数
1717 var anchorHead="";
18-var skinName="skin30-3 v3.1.11xx";
18+var skinName="skin30-3 v3.3.09xx";
1919 var browser="ギコナビ";
2020 //==========ギコナビ用アンカーの判定(0:処理無し,1:ポップアップ,2:ボタン挿入)
2121 // ギコナビでは、レスアンカーは相対アドレスで記述される
22-function checkAnchor(href){
22+function checkAnchor(href){if(!href){return(0)}
2323 if (href.match(/decoy:|about:blank/)){return(1)}
2424 else if(href.match(/menu:|read\.cgi|2ch\.net\/.*\/kako/)){return(0)}
2525 else{return(2)}
@@ -27,13 +27,22 @@ function checkAnchor(href){
2727 //==========リンク設定
2828 function addAnchor(inner,num){
2929 if(!t_url){threadurl()}
30- return('<a href="../test/read.cgi/'+t_bbs+'/'+t_key+'/'+inner+'" target="_blank" onclick="blur()">'+num+'</a>')
30+ var url=document.getElementsByName("ThreadURL")[0].content;
31+ if(url.match(/&/)){
32+ return('<a href="../test/read.cgi?bbs='+t_bbs+'&key='+t_key+'&st='+inner+'&to='+inner+'&nofirst=true" target="_blank" onclick="blur()">'+num+'</a>')
33+ }else{
34+ return('<a href="../test/read.cgi/'+t_bbs+'/'+t_key+'/'+inner+'" target="_blank" onclick="blur()">'+num+'</a>')
35+ }
3136 }
3237 // スレッドURLの取得
3338 var t_url=false,t_domain,t_bbs,t_key;
3439 function threadurl(){
3540 var threadurl=document.getElementsByName("ThreadURL")[0].content;
36- threadurl.match(/^.*\/test\/read.cgi\/(.*)\/(.*)\//);
41+ if(threadurl.match(/&/)){
42+ threadurl.match(/bbs=(.*)&key=(\d*)/);
43+ }else{
44+ threadurl.match(/^.*\/test\/read.cgi\/(.*)\/(.*)\//);
45+ }
3746 t_url=true;
3847 t_bbs=RegExp.$1;
3948 t_key=RegExp.$2;
--- a/res/skin/skin30-3G/chie_event.js
+++ b/res/skin/skin30-3G/chie_event.js
@@ -2,7 +2,8 @@
22 //外部関数:tohan
33 //外部変数:anchorHead,lightmode,getID,skinName,browser,dts
44 //グローバル変数
5-var buffer=1; // 低速回線や低速マシンの場合にはbufferの数値を増やすとより正確にジャンプ(1増やすと0.1秒遅れる)
5+var buffer=1; // 低速回線や低速マシンの場合にはbufferの数値を増やすとより正確にジャンプ(1増やすと0.1秒遅れる)
6+var newResJump=1; // 新着レスジャンプ(0:ブラウザ任せ、1:読了時のみ、2:常時)*かちゅ、OpenJane、twintailのみの設定
67 //========Click処理→search,他
78 document.onclick = clickEvent;
89 function clickEvent(){
@@ -40,10 +41,19 @@ function mouseOverEvent() {
4041 else if(e.innerText.match(/^あぼ〜ん$/)) {abonePopup(e);}
4142 }
4243 if(e.tagName=='A'){
43- e.href=e.href.replace(/>/g,"");
44- e.href=e.href.replace(/\/ime.nu/g,"");
44+ if(!e.innerText.match(/%/)){ // URLエンコードでありがちな%がなければ
45+ e.href=e.href.replace(/>/g,"");
46+ e.href=e.href.replace(/\/ime.nu/g,"");
47+ }else{
48+ try{
49+ e.title=decodeURI(e.innerText);
50+ }catch(err){
51+ // ShiftJIS,EUC-JPのデコードは面倒だからつけない。
52+ }
53+ }
4554 if (checkAnchor(e.href)==2){insButton(e);return;}
4655 else if(checkAnchor(e.href)==1){
56+ if(event.shiftKey){if(e.rel){e.href=e.rel}return}
4757 // 多段ポップアップ
4858 var aNum=parseInt(e.sourceIndex)+1;
4959 if(!document.getElementById("p"+aNum)){
@@ -96,10 +106,10 @@ function scroll_End(){document.getElementsByTagName("DL")[0].lastChild.scrollInt
96106 // IMG
97107 function imgCommand(mode,s){
98108 if(!waited){
99- var nHTML='<div id="command" onclick="clearCommand()"><input type="button" onclick="allImageLoad(\'all\')" value="全レス一括読込"><br><input type="button" onclick="allImageLoad(\'new\')" value="新レス一括読込"><br></div>';
109+ var nHTML='<div id="command" onclick="clearCommand()"><input type="button" onclick="allImageLoad(\'all\')" value="全レス一括読込"><br><input type="button" onclick="allImageLoad(\'new\')" value="新レス一括読込"><br><input type="button" onclick="removeError()" value="Error画像削除"><br></div>';
100110 event.srcElement.parentElement.insertAdjacentHTML('beforeEnd',nHTML);
101111 if(skinName.match(/30-2/)){
102- if(!lightmode){document.getElementById("command").insertAdjacentHTML('afterBegin','<input type="button" onclick="changePanel()" value="パネル切替"><br>')}
112+ //if(!lightmode){document.getElementById("command").insertAdjacentHTML('afterBegin','<input type="button" onclick="changePanel()" value="パネル切替"><br>')}
103113 document.getElementById("command").insertAdjacentHTML('beforeEnd','<input type="button" onclick="changeMode()" value="モード切替">')
104114 }
105115 waited=true;
@@ -109,7 +119,7 @@ function imgCommand(mode,s){
109119 }
110120 function clearCommand(){
111121 waited=false;
112- event.srcElement.parentElement.removeNode(true);
122+ document.getElementById("command").removeNode(true);
113123 }
114124 //=========左長押処理→copyMenu()
115125 document.onmousedown=mousedownEvent;
@@ -122,6 +132,7 @@ function mousedownEvent(){
122132 clickTimer=setTimeout("copyMenu()",500);
123133 }
124134 }
135+
125136 //コピーメニュー→colorChange(),search::copyText()
126137 function copyMenu(){
127138 clickCancel=true; clearTimeout(clickTimer);
@@ -165,27 +176,53 @@ function key(){
165176 }
166177 }
167178
168-//=========Load(代替)処理(各Footerもしくは、Headerでのループから呼出し)
179+//=========新着レス取得後処理(標準スキン未対応ブラウザ用)←Timer又はFooterから呼び出し
180+//=========かちゅ、ABone、ゾヌ2
169181 var newResNum=parseInt(document.getElementsByName("GetRescount")[0].content)+1;
170182 var k=0;
171-function loadEvent(){
172- //GetRescount代替 "数字でなければ"
173- if(isNaN(newResNum)){while(dts[k]){if(dts[k].className=="new"){newResNum=parseInt(dts[k].firstChild.innerText);break;} k++; }}
174- //新着開始ナンバーを設定してジャンプ
183+function loadEvent(num){ // Timer又はFooterから
184+ //====新着レスジャンプ
185+ if(newResJump==0){clearInterval(timerID);return} //「ブラウザ任せ」なら終了
186+ //新着レスの開始番号を取得
187+ if (browser=="かちゅ〜しゃ"){if(isNaN(newResNum)){while(dts[k]){if(dts[k].className=="new"){newResNum=parseInt(dts[k].firstChild.innerText);break;} k++;}}}
188+ else if(browser=="ホットゾヌ2"){newResNum=num+1;}
175189 var anc=document.anchors(anchorHead+newResNum);
176- if(anc && anc.parentElement){
177- if(buffer==0){clearInterval(timerID);moveToNew(newResNum);}
178- else {buffer--;}
179- }
190+ if(!anc || !anc.parentElement){return} // 透明あぼ〜んされてたら終了
191+ //新着レスジャンプ
192+ scr=lightmode ? document.body : document.getElementById("dl");
193+ viewPos=scr.scrollTop+scr.clientHeight;// スクロール後の画面下部位置
194+ endPos =anc.offsetTop+20; // 新レスアンカー位置
195+ //最後まで読了 or 「常に新着ジャンプ」ならジャンプ
196+ if(viewPos>endPos || newResJump==2){clearInterval(timerID);setTimeout("moveToNew("+newResNum+")",buffer*100)}
197+ else{firstNew=document.anchors(anchorHead+newResNum).parentElement.nextSibling;}
198+}
199+//=========新着レス取得後処理(標準スキン対応ブラウザ用)←NewMarkから呼び出し
200+//=========OpenJ、twin
201+var scr,viewPos,endPos=0;
202+function reloadEvent(){
203+ //====既読化
204+ var lastDt=dts[dts.length-2];if(!lastDt){return}// 全部新着なら終了
205+ while(lastDt && lastDt.className=="new"){lastDt.className="";lastDt=lastDt.previousSibling.previousSibling;}
206+ //====新着レスジャンプ
207+ if(newResJump==0){return} //「ブラウザ任せ」なら終了
208+ var ancs=document.anchors;
209+ var newResNum=parseInt(ancs[ancs.length-1].name)+1;
210+ scr=lightmode ? document.body : document.getElementById("dl");
211+ viewPos=scr.scrollTop;
212+ endPos =scr.scrollHeight-scr.clientHeight-20;
213+ //最後まで読了 or 「常に新着ジャンプ」ならジャンプ
214+ if(viewPos>endPos || newResJump==2){setTimeout("moveToNew("+newResNum+")",buffer*100);}
180215 }
216+
181217 // 新着レス移動+新着レスの位置を記憶
182218 var firstNew;
183219 function moveToNew(num){
184220 firstNew=getDTfromAnc(num);
185- if(firstNew){firstNew.scrollIntoView(true);}
221+ while(!firstNew){num--;firstNew=getDTfromAnc(num);} //対象が透明あぼ〜んなら数を減らす
222+ firstNew.scrollIntoView(true);
186223 }
187224
188-//=========DblClick処理→defaultPopup()
225+//=========DoubleClick処理→defaultPopup()
189226 document.ondblclick=defaultPopup;
190227 function defaultPopup(){
191228 var num=document.selection.createRange().text.replace(/\s$/,"");
@@ -200,4 +237,17 @@ function defaultPopup(){
200237 obj.innerText="ID:"+num;
201238 search(obj);
202239 }
203-}
\ No newline at end of file
240+}
241+
242+//=========Copy処理
243+//headから読むとbodyは見えないので、専用ブラウザの特質を利用してbodyの後ろに書き出す
244+//本来どおりheadに書き出すSkinManager対策で判定を一つ入れる
245+ if(document.body) document.write('<script type="text/javascript">document.body.oncopy=copyEvent</script>\n');
246+function copyEvent(){
247+ var textarea=document.createElement("TEXTAREA");
248+ textarea.value=document.selection.createRange().text.replace(/\s(\r\n|$)/g,"\n");
249+ var copyText=textarea.createTextRange();
250+ copyText.execCommand("Copy");
251+ return false;
252+}
253+
--- a/res/skin/skin30-3G/chie_popup.js
+++ b/res/skin/skin30-3G/chie_popup.js
@@ -15,7 +15,7 @@ var pb;
1515 function namePopup(e,before,num,after){
1616 var hnum=tohan(num);
1717 //3周年、4周年、Socket774、774KB、21禁、[1-30]、などに対応
18- if(before){if(hnum==3 || hnum==774 || hnum==4 || hnum==21 || hnum==1 || hnum==30){return}}
18+ if(before){if(hnum==5 || hnum==774 || hnum==4 || hnum==21 || hnum==1 || hnum==30){return}}
1919 e.outerHTML = "<b>"+before+"</b><b>"+addAnchor(hnum,num)+"</b><b>"+after+"</b>";
2020 }
2121 //=========弱あぼ〜んのポップアップ
--- a/res/skin/skin30-3G/chie_search.js
+++ b/res/skin/skin30-3G/chie_search.js
@@ -110,7 +110,7 @@ function clearResult(obj){
110110 for(var i=l;i--;){
111111 var dt=eval(arrayElement); var dd=dt.nextSibling;
112112 //Live機能追加 - 透明あぼ〜ん
113- if(browser=="Live2ch"){location.href='func:ABONECLEAR?'+dt.firstChild.innerText;continue;}
113+ if(browser=="Live2ch"){location.href='func:ABONECLEAR?'+dt.firstChild.innerText;}
114114 dt.removeNode(true); dd.removeNode(true);
115115 }
116116 }
@@ -144,7 +144,7 @@ function findIt(word){
144144
145145 //==========逆参照
146146 function searchRef(obj){
147- if(obj.name!='reffered'){
147+ if(obj.name!='referred'){
148148 var num=obj.firstChild.innerText;
149149 var l=dds.length;
150150 var found = new Array;
@@ -171,7 +171,7 @@ function searchRef(obj){
171171 if(exist){
172172 var dt=dds[i].previousSibling.cloneNode(true);
173173 found.unshift(dt.outerHTML.replace(/name=.*?>/,">")+dd.outerHTML.replace(/<a name=.*>/i,""));
174- obj.name="reffered";
174+ obj.name="referred";
175175 }
176176 }
177177 if(found.length){returnRef(obj.nextSibling,found)}
@@ -190,13 +190,12 @@ function returnRef(dd,found){
190190 function copyText(target){
191191 var num=event.srcElement.parentElement.name;
192192 var obj=getDTfromAnc(num);
193- var decoy=document.createDocumentFragment();
194193 var textarea=document.createElement("TEXTAREA");
195- if (target=="res") {textarea.value=obj.firstChild.innerText+" :"+obj.childNodes[1].innerText+" :"+obj.lastChild.innerText+"\n"+obj.nextSibling.innerText+"\n";}
194+ var message=obj.nextSibling.innerText.replace(/\s(\r\n|$)/g,"\n");
195+ if (target=="res") {textarea.value=obj.firstChild.innerText+" :"+obj.childNodes[1].innerText+" :"+obj.lastChild.innerText+"\n"+message;}
196196 else if(target=="name"){textarea.value=obj.childNodes[1].innerText+"\n";}
197- else if(target=="id") {textarea.value=obj.lastChild.innerText.substr(15)+"\n";}
198- decoy.appendChild(textarea);
199- var copyText=decoy.getElementsByTagName("TEXTAREA")[0].createTextRange();
197+ else if(target=="id") {textarea.value="ID:"+(obj.lastChild.innerText.split(/ID:/))[1]+"\n";}
198+ var copyText=textarea.createTextRange();
200199 copyText.execCommand("Copy")
201200 event.srcElement.parentElement.removeNode(true);
202201 }
Show on old repository browser