Commit MetaInfo

Revision4d7a93f663f712ea5ea27b16832f62e35a84c352 (tree)
Zeit2006-02-02 00:30:40
Autorcvs2git <cvs2git>
Commitercvs2git

Log Message

This commit was manufactured by cvs2svn to create tag 'v1_52_0_644'.

Ändern Zusammenfassung

Diff

--- a/Editor.dfm
+++ b/Editor.dfm
@@ -1,6 +1,6 @@
11 object EditorForm: TEditorForm
2- Left = 328
3- Top = 257
2+ Left = 432
3+ Top = 258
44 Width = 640
55 Height = 449
66 HorzScrollBar.Visible = False
@@ -58,24 +58,14 @@ object EditorForm: TEditorForm
5858 Top = 30
5959 Width = 632
6060 Height = 354
61- ActivePage = RocalRuleTab
61+ ActivePage = EditorTab
6262 Align = alClient
6363 MultiLine = True
64- TabIndex = 4
64+ TabIndex = 0
6565 TabOrder = 0
6666 OnChange = EditorPageChange
6767 object EditorTab: TTabSheet
6868 Caption = #32232#38598
69- object BodyEdit: TMemo
70- Left = 0
71- Top = 60
72- Width = 624
73- Height = 267
74- Align = alClient
75- ScrollBars = ssBoth
76- TabOrder = 0
77- WordWrap = False
78- end
7969 object NameBasePanel: TPanel
8070 Left = 0
8171 Top = 29
@@ -83,7 +73,7 @@ object EditorForm: TEditorForm
8373 Height = 31
8474 Align = alTop
8575 BevelOuter = bvNone
86- TabOrder = 2
76+ TabOrder = 1
8777 object NameLabel: TLabel
8878 Left = 4
8979 Top = 8
@@ -144,7 +134,7 @@ object EditorForm: TEditorForm
144134 Height = 29
145135 Align = alTop
146136 BevelOuter = bvNone
147- TabOrder = 1
137+ TabOrder = 0
148138 object Label1: TLabel
149139 Left = 4
150140 Top = 8
@@ -161,6 +151,16 @@ object EditorForm: TEditorForm
161151 TabOrder = 0
162152 end
163153 end
154+ object BodyEdit: TMemo
155+ Left = 0
156+ Top = 60
157+ Width = 624
158+ Height = 267
159+ Align = alClient
160+ ScrollBars = ssBoth
161+ TabOrder = 2
162+ WordWrap = False
163+ end
164164 end
165165 object PreviewTab: TTabSheet
166166 Caption = #12503#12524#12499#12517#12540
@@ -1733,6 +1733,12 @@ object EditorForm: TEditorForm
17331733 OnExecute = UpdateSambaActionExecute
17341734 OnUpdate = UpdateSambaActionUpdate
17351735 end
1736+ object InputAssistAction: TAction
1737+ Tag = -1
1738+ Category = #32232#38598
1739+ Caption = #20837#21147#12450#12471#12473#12488
1740+ OnExecute = InputAssistActionExecute
1741+ end
17361742 end
17371743 object IdLogDebug: TIdLogDebug
17381744 OnReceive = IdLogDebugReceive
@@ -1748,4 +1754,16 @@ object EditorForm: TEditorForm
17481754 Left = 233
17491755 Top = 123
17501756 end
1757+ object InputAssistPopupMenu: TPopupMenu
1758+ AutoHotkeys = maManual
1759+ AutoPopup = False
1760+ OwnerDraw = True
1761+ Left = 272
1762+ Top = 128
1763+ end
1764+ object ApplicationEvents1: TApplicationEvents
1765+ OnMessage = ApplicationEvents1Message
1766+ Left = 304
1767+ Top = 128
1768+ end
17511769 end
--- a/Editor.pas
+++ b/Editor.pas
@@ -17,7 +17,7 @@ uses
1717 IdAntiFreezeBase, IdAntiFreeze, IdBaseComponent, IdComponent,
1818 IdTCPConnection, IdTCPClient, IdHTTP, ActnList, StdActns, IdIntercept,
1919 IdLogBase, IdLogDebug, IdException, DateUtils, bmRegExp,
20- Gesture;
20+ Gesture, AppEvnts;
2121
2222 type
2323 // TSetLayeredWindowAttributes = function(wnd: HWND; crKey: DWORD; bAlpha: BYTE; dwFlag: DWORD): Boolean; stdcall;
@@ -44,7 +44,6 @@ type
4444 N02: TMenuItem;
4545 ToolBarImageList: TImageList;
4646 HotToobarImageList: TImageList;
47- BodyEdit: TMemo;
4847 NameBasePanel: TPanel;
4948 NameLabel: TLabel;
5049 MailLabel: TLabel;
@@ -127,6 +126,10 @@ type
127126 UpdateSambaAction: TAction;
128127 Samba241: TMenuItem;
129128 N7: TMenuItem;
129+ InputAssistAction: TAction;
130+ InputAssistPopupMenu: TPopupMenu;
131+ BodyEdit: TMemo;
132+ ApplicationEvents1: TApplicationEvents;
130133
131134 procedure EditorPageChange(Sender: TObject);
132135 procedure FormCreate(Sender: TObject);
@@ -181,6 +184,9 @@ type
181184 procedure BeLogInOutEActionUpdate(Sender: TObject);
182185 procedure UpdateSambaActionUpdate(Sender: TObject);
183186 procedure UpdateSambaActionExecute(Sender: TObject);
187+ procedure InputAssistActionExecute(Sender: TObject);
188+ procedure ApplicationEvents1Message(var Msg: tagMSG;
189+ var Handled: Boolean);
184190 private
185191 FThreadItem: TThreadItem;
186192 FBoard: TBoard;
@@ -195,6 +201,8 @@ type
195201 FHost: string;
196202 FNow: TDateTime;
197203 FGestures : TMouseGesture;
204+ FInputAssistKey: String; ///< 入力アシストのキー
205+ FResistWords: TStringList; ///< 入力アシストの辞書からの検索結果
198206 procedure Preview;
199207 function RepHtml(s: string): string;
200208 function Check: Boolean;
@@ -244,6 +252,8 @@ type
244252 function LFusianaGet(s: String): Boolean;
245253 // Cookieの取得
246254 procedure GetCookie(Rawtext: String; ABoard: TBoard);
255+ //! 入力アシストのポップアップメニューのクリックイベント
256+ procedure InputAssistMenuClick(Sender: TObject);
247257 protected
248258 procedure CreateParams(var Params: TCreateParams); override;
249259 public
@@ -252,13 +262,13 @@ type
252262 procedure SetThreadItem(Item: TThreadItem);
253263 procedure SetBoard(Item: TBoard);
254264 property BBSID: string read FBBSID write FBBSID;
255-
256265 end;
257266
258267 implementation
259268
260269 uses
261- Giko, ItemDownload, MojuUtils, IdGlobal, GikoMessage;
270+ Giko, ItemDownload, MojuUtils, IdGlobal, GikoMessage, Imm,
271+ InputAssistDataModule;
262272 const
263273 CAPTION_NAME_NEW: string = 'ギコナビ スレ立てエディタ';
264274 CAPTION_NAME_RES: string = 'ギコナビ レスエディタ';
@@ -427,7 +437,8 @@ begin
427437 finally
428438 ini.Free;
429439 end;
430-
440+ // キー設定の読み込み
441+ GikoSys.LoadKeySetting(ActionList, GikoSys.GetEditorKeyFileName);
431442 // マウスジェスチャーのインストール
432443 if GikoSys.Setting.GestureEnabled then begin
433444 MouseGesture.UnHook;
@@ -930,33 +941,35 @@ begin
930941
931942 if ABoard = nil then Exit;
932943
933- if FileExists(ABoard.GetSETTINGTXTFileName) then begin
934- body := TStringList.Create;
935- try
936- body.LoadFromFile(ABoard.GetSETTINGTXTFileName);
937- Remote := GetFusianaName(body, ABoard);
938- finally
939- body.Free;
940- end;
941- end;
942-
943- //Setting.txtがなかったら取得
944- //鯖に負荷がかかりそうで怖い・・・
945- if not FileExists(ABoard.GetSETTINGTXTFileName) then begin
946- //GetSETTINGTXTActionを呼び出すとIndyが初期化されるので、
944+ if FileExists(ABoard.GetSETTINGTXTFileName) then begin
945+ body := TStringList.Create;
946+ try
947+ body.LoadFromFile(ABoard.GetSETTINGTXTFileName);
948+ Remote := GetFusianaName(body, ABoard);
949+ finally
950+ body.Free;
951+ end;
952+ end;
953+
954+ //Setting.txtがなかったら取得
955+ //鯖に負荷がかかりそうで怖い・・・
956+ if not FileExists(ABoard.GetSETTINGTXTFileName) then begin
957+ //GetSETTINGTXTActionを呼び出すとIndyが初期化されるので、
947958 //ここでCookieを保存しなくてはいけない
948959 tmpRawheader := Indy.Response.RawHeaders.Text;
949960 GetSETTINGTXTAction.Execute;
950961 body := TStringList.Create;
951962 try
952- body.LoadFromFile(ABoard.GetSETTINGTXTFileName);
953- Remote := GetFusianaName(body, ABoard);
954- finally
955- body.Free;
956- end;
963+ if FileExists(ABoard.GetSETTINGTXTFileName) then begin
964+ body.LoadFromFile(ABoard.GetSETTINGTXTFileName);
965+ Remote := GetFusianaName(body, ABoard);
966+ end;
967+ finally
968+ body.Free;
969+ end;
957970 end;
958971
959- if Remote = 'fusianasan' then begin
972+ if Remote = 'fusianasan' then begin
960973 MsgResult := MsgBox(
961974 Handle,
962975 'リモートホストを表示する機能が使われています' + #13#10 +
@@ -971,8 +984,8 @@ begin
971984 EnableMenuItem(SysMenu, SC_CLOSE, MF_BYCOMMAND or MF_ENABLED);
972985 DrawMenuBar(Handle);
973986 Exit;
974- end;
975- end;
987+ end;
988+ end;
976989 end;
977990
978991 if ResultType = grtOK then begin
@@ -1214,7 +1227,7 @@ begin
12141227 ini.WriteInteger(sDate, 'Status', FStatusCode);
12151228 ini.WriteDateTime(sDate, 'Date', Now);
12161229 if FThreadItem = nil then begin
1217- ini.WriteString(sDate, 'Title', TitleEdit.Text);
1230+ ini.WriteString(sDate, 'Title', MojuUtils.Sanitize(TitleEdit.Text));
12181231 ini.WriteString(sDate, 'BBS', FBoard.BBSID);
12191232 ini.WriteInteger(sDate, 'NewThread', 1);
12201233 end else begin
@@ -1731,9 +1744,6 @@ var
17311744 settingBody: TStringList;
17321745 tmpBoard: TBoard;
17331746 begin
1734- if FWork then
1735- Exit;
1736- FWork := True;
17371747
17381748 InitIdHTTP(Indy);
17391749 if FThreadItem = nil then
@@ -1784,7 +1794,6 @@ begin
17841794 end;
17851795 ShowBoardInformation(tmpBoard, BoardInformationMemo);
17861796
1787- FWork := False;
17881797 end;
17891798
17901799 procedure TEditorForm.ShowBoardInformation(ABoard: TBoard; AMemo: TMemo);
@@ -2211,4 +2220,156 @@ begin
22112220 end;
22122221 end;
22132222
2223+procedure TEditorForm.InputAssistActionExecute(Sender: TObject);
2224+var
2225+ count, i : Integer;
2226+ item : TMenuItem;
2227+ point: TPoint;
2228+ Bitmap : TBitmap;
2229+ TextWidth, ItemWidth, tmpWidth: Integer;
2230+begin
2231+ if FInputAssistKey = '' then Exit;
2232+
2233+ InputAssistPopupMenu.Items.Clear;
2234+
2235+ if (FResistWords = nil) then begin
2236+ FResistWords := TStringList.Create;
2237+ end else begin
2238+ FResistWords.Clear;
2239+ end;
2240+
2241+ if (GetKeyState( VK_SHIFT ) < 0) then begin
2242+ // シフトが押されていれば、キーで始まるカテゴリ
2243+ count :=
2244+ InputAssistDM.GetStartWithCategoryResistWords(
2245+ FInputAssistKey, FResistWords);
2246+ end else begin
2247+ // シフトが無いので、キーで始まるキー
2248+ count :=
2249+ InputAssistDM.GetStartWithKeyResistWords(
2250+ FInputAssistKey, FResistWords);
2251+ end;
2252+ Bitmap := TBitmap.Create;
2253+ try
2254+ Bitmap.Canvas.Font.Assign(BodyEdit.Font);
2255+ // マージン5px
2256+ TextWidth := Bitmap.Canvas.TextWidth(FInputAssistKey) + 5;
2257+ ItemWidth := 0;
2258+ for i := 0 to count - 1 do begin
2259+ item := TMenuItem.Create(nil);
2260+ item.Break := mbNone;
2261+ item.Caption := FResistWords[i];
2262+ item.Tag := i;
2263+ item.OnClick := InputAssistMenuClick;
2264+ InputAssistPopupMenu.Items.Add(item);
2265+
2266+ tmpWidth := Bitmap.Canvas.TextWidth(Item.Caption);
2267+ if (tmpWidth > ItemWidth) then begin
2268+ ItemWidth := tmpWidth;
2269+ end;
2270+ end;
2271+ finally
2272+ Bitmap.Free;
2273+ end;
2274+
2275+ if (count > 0) then begin
2276+ GetCaretpos(point);
2277+ point.X := point.X + Self.Left + (Self.Width - BodyEdit.Width) div 2;
2278+ point.Y := point.Y + Self.Top + (Self.Height - Self.ClientHeight);
2279+
2280+ if Screen.DesktopWidth >
2281+ (point.X + TextWidth + ItemWidth) then begin
2282+ InputAssistPopupMenu.Popup(
2283+ point.X + TextWidth,
2284+ point.Y + EditorPage.Top + EditorPage.TabHeight + BodyEdit.Top);
2285+ end else begin
2286+ InputAssistPopupMenu.Popup(
2287+ point.X - TextWidth - ItemWidth,
2288+ point.Y + EditorPage.Top + EditorPage.TabHeight + BodyEdit.Top);
2289+ end;
2290+ end;
2291+end;
2292+
2293+procedure TEditorForm.InputAssistMenuClick(Sender: TObject);
2294+var
2295+ line, pos, sel : Integer;
2296+ text, left, right : String;
2297+ IMC: HIMC;
2298+begin
2299+ if not (Sender is TMenuItem) then Exit;
2300+
2301+ if (FResistWords <> nil) then begin
2302+ try
2303+ text :=
2304+ TResistWord(FResistWords.Objects[TMenuItem(Sender).Tag]).GetText;
2305+ except
2306+ text := '';
2307+ end;
2308+ IMC := ImmGetContext(BodyEdit.Handle); //コンテキスト取得
2309+ try
2310+ ImmNotifyIME(IMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
2311+ finally
2312+ ImmReleaseContext(BodyEdit.Handle, IMC); //コンテキスト解放
2313+ end;
2314+
2315+ FResistWords.Clear;
2316+ FInputAssistKey := '';
2317+ end;
2318+ BodyEdit.Lines.BeginUpdate;
2319+ line := SendMessage(BodyEdit.Handle,EM_LINEFROMCHAR,-1,0); //行
2320+ sel := BodyEdit.SelStart;
2321+ pos := sel - SendMessage(BodyEdit.Handle, EM_LINEINDEX, -1, 0); //桁
2322+ if (pos > 0) then begin
2323+ left := Copy(BodyEdit.Lines[line], 0, pos);
2324+ end else begin
2325+ left := '';
2326+ end;
2327+ right := Copy(BodyEdit.Lines[line], pos + 1, Length(BodyEdit.Lines[line]));
2328+ BodyEdit.Lines.Strings[line] := left + text + right;
2329+ BodyEdit.Lines.EndUpdate;
2330+ // キャレットの位置を更新する
2331+ BodyEdit.SelStart := sel + Length(text);
2332+ // キャレットの位置までスクロール
2333+ BodyEdit.Perform(EM_SCROLLCARET, 0, 0);
2334+end;
2335+
2336+procedure TEditorForm.ApplicationEvents1Message(var Msg: tagMSG;
2337+ var Handled: Boolean);
2338+var
2339+ wmMsg: TWMKey;
2340+ IMC: HIMC;
2341+ Len: integer;
2342+ Str: string;
2343+begin
2344+ if (Self.Active) then begin
2345+ case Msg.message of
2346+ //キー押下のみ受け取る
2347+ WM_KEYDOWN:
2348+ begin
2349+ // タブが”編集”でCtrlキーが押されているのを確認する
2350+ if (EditorPage.ActivePageIndex = 0)
2351+ and (GetKeyState( VK_CONTROL ) < 0) then begin
2352+ wmMsg.Msg := Msg.message;
2353+ wmMsg.CharCode := Word(Msg.wParam);
2354+ wmMsg.KeyData := Msg.lParam;
2355+ if (wmMsg.CharCode = 229) and (wmMsg.KeyData = 3735553) then begin
2356+ IMC := ImmGetContext(BodyEdit.Handle); //コンテキスト取得
2357+ Len := ImmGetCompositionString(IMC, GCS_COMPSTR, nil, 0); //まず長さを取得
2358+ if (Len > 0) then begin
2359+ SetLength(Str, Len + 1); //Bufferのメモリを設定
2360+ ImmGetCompositionString(IMC, GCS_COMPSTR, PChar(Str), Len + 1); //まず長さを取得
2361+ SetLength(Str, Len);
2362+ FInputAssistKey := Str;
2363+ InputAssistActionExecute(nil);
2364+ Handled := True;
2365+ end;
2366+ ImmReleaseContext(BodyEdit.Handle, IMC); //コンテキスト解放
2367+ end;
2368+ end;
2369+ end;
2370+ end;
2371+
2372+ end;
2373+end;
2374+
22142375 end.
--- a/Favorite.pas
+++ b/Favorite.pas
@@ -410,12 +410,12 @@ begin
410410 board := BBSsFindBoardFromBBSID( Node.Attributes[ 'bbs' ] );
411411 if board <> nil then
412412 FavBoard := TFavoriteBoardItem.Create(
413- board.URL, Node.Attributes[ 'title' ], board );
413+ board.URL, MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), board );
414414 end else begin
415415 FavBoard := TFavoriteBoardItem.Create(
416- Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
416+ Node.Attributes[ 'url' ], MojuUtils.UnSanitize(Node.Attributes[ 'title' ]), nil );
417417 end;
418- CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavBoard);
418+ CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavBoard);
419419 CurrentNode.ImageIndex := 15;
420420 CurrentNode.SelectedIndex := 15;
421421 end else if Node.Attributes['favtype'] = 'thread' then begin
@@ -433,17 +433,17 @@ begin
433433 board.BoardPlugIn,
434434 board,
435435 GikoSys.Get2chBoard2ThreadURL( board, ChangeFileExt( Node.Attributes[ 'thread' ], '' ) ) );
436- threadItem.Title := Node.Attributes[ 'title' ];
436+ threadItem.Title := UnSanitize(Node.Attributes[ 'title' ]);
437437 board.Add( threadItem );
438438 end;
439439 FavThread := TFavoriteThreadItem.Create(
440- threadItem.URL, Node.Attributes[ 'title' ], threadItem );
440+ threadItem.URL, UnSanitize(Node.Attributes[ 'title' ]), threadItem );
441441 threadItem.Free;
442442 end else begin
443443 FavThread := TFavoriteThreadItem.Create(
444- Node.Attributes[ 'url' ], Node.Attributes[ 'title' ], nil );
444+ Node.Attributes[ 'url' ], UnSanitize(Node.Attributes[ 'title' ]), nil );
445445 end;
446- CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, Node.Attributes['title'], FavThread);
446+ CurrentNode := FTreeView.Items.AddChildObjectFirst(ParentNode, UnSanitize(Node.Attributes['title']), FavThread);
447447 CurrentNode.ImageIndex := 16;
448448 CurrentNode.SelectedIndex := 16;
449449 end;
@@ -558,12 +558,12 @@ begin
558558 end else if TObject(data) is TFavoriteBoardItem then begin
559559 FavBoard := TFavoriteBoardItem(data);
560560 s := Format('<favitem type="2ch" favtype="board" url="%s" title="%s"/>',
561- [HtmlEncode( FavBoard.URL ), HtmlEncode(Node.Text)]);
561+ [HtmlEncode( FavBoard.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
562562 SaveList.Add(s);
563563 end else if TObject(data) is TFavoriteThreadItem then begin
564564 FavThread := TFavoriteThreadItem(data);
565565 s := Format('<favitem type="2ch" favtype="thread" url="%s" title="%s"/>',
566- [HtmlEncode( FavThread.URL ), HtmlEncode(Node.Text)]);
566+ [HtmlEncode( FavThread.URL ), HtmlEncode(MojuUtils.Sanitize(Node.Text))]);
567567 SaveList.Add(s);
568568 end;
569569 Node := Node.getNextSibling;
--- a/Giko.dfm
+++ b/Giko.dfm
@@ -1,6 +1,6 @@
11 object GikoForm: TGikoForm
2- Left = 363
3- Top = 92
2+ Left = 97
3+ Top = 51
44 HorzScrollBar.Visible = False
55 VertScrollBar.Visible = False
66 AutoScroll = False
@@ -7959,6 +7959,12 @@ object GikoForm: TGikoForm
79597959 object N43: TMenuItem
79607960 Caption = '-'
79617961 end
7962+ object N22: TMenuItem
7963+ Action = GikoDM.SetInputAssistAction
7964+ end
7965+ object N42: TMenuItem
7966+ Caption = '-'
7967+ end
79627968 object PlugInMenu: TMenuItem
79637969 Caption = #12503#12521#12464#12452#12531'(&P)'
79647970 end
--- a/Giko.pas
+++ b/Giko.pas
@@ -402,6 +402,8 @@ type
402402 N74: TMenuItem;
403403 WikiFAQ: TMenuItem;
404404 GikoApplicationEvents: TApplicationEvents;
405+ N22: TMenuItem;
406+ N42: TMenuItem;
405407 procedure FormCreate(Sender: TObject);
406408 procedure FormDestroy(Sender: TObject);
407409 procedure BrowserStatusTextChange(Sender: TObject;
@@ -541,6 +543,7 @@ type
541543 procedure GikoApplicationEventsException(Sender: TObject; E: Exception);
542544 procedure TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
543545 Shift: TShiftState; X, Y: Integer);
546+ procedure GetResURLMenuClick(Sender: TObject);
544547 private
545548 { Private 宣言 }
546549 FEnabledCloseButton: Boolean;
@@ -588,7 +591,8 @@ type
588591 FIsHandledWheel : Boolean; ///< 既に受け取った WM_MOUSEWHEEL かどうか
589592 DiffComp: Boolean; //Add by Genyakun スレが更新されたときにTrueになる
590593 FOrigenCaption: String; //お気に入りツリーのアイテム編集時の編集前の文字列
591- FPreviewBrowserRect: TRect; ///< プレビューの表示位置を記憶する
594+ FPreviewBrowserRect: TRect; ///< プレビューの表示位置を記憶する
595+ FActionListGroupIndexes: array of Integer; ///<GikoDM上のアクションリストの各アクションに設定されたGroupIndexを保存する配列
592596 procedure DownloadEnd(Sender: TObject; Item: TDownloadItem);
593597 procedure DownloadMsg(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon);
594598 procedure WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer; Number: Integer; const AWorkTitle: string);
@@ -648,12 +652,16 @@ type
648652 function GetScreenCursor(): TCursor;
649653 //カーソルを設定する
650654 procedure SetScreenCursor(Cursor : TCursor);
651- //! アクションのチェック状態の初期化
652- procedure InitActionChecked();
653655 //! ダウンロードコントロールスレッドの生成
654656 procedure CreateControlThread();
655657 //! ブラウザの生成
656658 procedure CreateBrowsers(count: Integer);
659+ //! ActionListのGroupIndexの保存
660+ procedure GetGroupIndex(ActionList: TActionList);
661+ //! ActionListのGroupIndexの設定
662+ procedure SetGroupIndex(ActionList: TActionList);
663+ //! 指定されたスレッドを開く(ログが無いとき or 指定JUMPまで足りないときはDLする)
664+ procedure OpenThreadItem(Thread: TThreadItem; URL: String);
657665 protected
658666 procedure CreateParams(var Params: TCreateParams); override;
659667 procedure WndProc(var Message: TMessage); override;
@@ -783,6 +791,7 @@ type
783791 function WebBrowserClick(Sender: TObject): WordBool;
784792 //! ツールバーにスレ絞込みコンボボックスを設定する
785793 procedure SetSelectComboBox();
794+
786795 published
787796 property EnabledCloseButton: Boolean read FEnabledCloseButton write SetEnabledCloseButton;
788797 end;
@@ -820,7 +829,8 @@ uses
820829 FavoriteArrange, AddressHistory, Preview, Gesture,
821830 About, Option, Round, Splash, Sort, ListSelect, Imm,
822831 NewBoard, MojuUtils, Clipbrd, GikoBayesian,Y_TextConverter,
823- HTMLCreate, ListViewUtils, GikoDataModule, GikoMessage;
832+ HTMLCreate, ListViewUtils, GikoDataModule, GikoMessage,
833+ InputAssistDataModule;
824834
825835 const
826836 BLANK_HTML: string = 'about:blank';
@@ -869,12 +879,18 @@ begin
869879 Writeln(' 終了時は、ギコナビウィンドウを閉じてください');
870880 Writeln('============================================================');
871881 {$ENDIF}
882+//try
883+ Sort.SetSortDate(Now());
884+
872885 FTreeType := gttNone;
873886 // 起動時に保存されてしまう対策
874887 FStartUp := true;
875888 Application.HookMainWindow(Hook);
876889 FIsIgnoreResize := rtResizing;
877-
890+ //ActionListのGuoupIndexを保存して、0にクリアする。
891+ //(起動時にツールボタンのDownプロパティを反映させる都合上GroupIndexは設定できない)
892+ //これ以後Set〜で再設定するまで、ActionのCheckedをいじるときは注意!
893+ GetGroupIndex(GikoDM.GikoFormActionList);
878894 FSearchDialog := nil;
879895 CreateBrowsers(BROWSER_COUNT);
880896
@@ -944,6 +960,49 @@ begin
944960 //ViewNoButton.Down := GikoSys.Setting.ListViewNo;
945961 GikoDM.ListNumberVisibleAction.Checked := GikoSys.Setting.ListViewNo;
946962
963+ //ミュートの状態を設定
964+ GikoDM.MuteAction.Checked := GikoSys.Setting.Mute;
965+
966+ // レス表示範囲
967+ FResRangeMenuSelect := GikoSys.ResRange;
968+ case GikoSys.ResRange of
969+ Ord( grrAll ):
970+ begin
971+ GikoDM.AllResAction.Execute;
972+ end;
973+ Ord( grrSelect ):
974+ begin
975+ SelectComboBox.Text := SelectComboBox.Items[ 1 ];
976+ GikoDM.SelectResAction.Checked := True;
977+ end;
978+ else
979+ case FResRangeMenuSelect of
980+ Ord( grrKoko ): GikoDM.OnlyKokoResAction.Checked := True;
981+ Ord( grrNew ): GikoDM.OnlyNewResAction.Checked := True;
982+ 100: GikoDM.OnlyAHundredResAction.Checked := True;
983+ end;
984+ end;
985+
986+ // スレッド一覧表示範囲
987+ case GikoSys.Setting.ThreadRange of
988+ gtrAll:
989+ begin
990+ GikoDM.AllItemAction.Checked := True;
991+ ViewType := gvtAll;
992+ end;
993+ gtrLog:
994+ begin
995+ GikoDM.LogItemAction.Checked := True;
996+ ViewType := gvtLog;
997+ end;
998+ gtrNew:
999+ begin
1000+ GikoDM.NewItemAction.Checked := True;
1001+ ViewType := gvtNew;
1002+ end;
1003+ end;
1004+
1005+
9471006 //ブラウザタブフォント
9481007 BrowserTab.Font.Name := GikoSys.Setting.BrowserTabFontName;
9491008 BrowserTab.Font.Size := GikoSys.Setting.BrowserTabFontSize;
@@ -952,9 +1011,27 @@ begin
9521011 BrowserTab.Font.Style := [fsBold];
9531012 if GikoSys.Setting.BrowserTabFontItalic then
9541013 BrowserTab.Font.Style := GikoForm.BrowserTab.Font.Style + [fsItalic];
1014+ BrowserTab.DoubleBuffered := True;
9551015 FDragWFirst := false;
9561016 SetContent(BrowserNullTab); //ブラウザを空白表示
9571017
1018+ //ブラウザタブ
1019+ GikoDM.BrowserTabVisibleAction.Checked := GikoSys.Setting.BrowserTabVisible;
1020+
1021+ if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
1022+ GikoDM.BrowserTabTopAction.Checked := True;
1023+ end else begin
1024+ GikoDM.BrowserTabBottomAction.Checked := True;
1025+ end;
1026+
1027+ if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
1028+ GikoDM.BrowserTabTabStyleAction.Checked := True;
1029+ end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
1030+ GikoDM.BrowserTabButtonStyleAction.Checked := True;
1031+ end else begin
1032+ GikoDM.BrowserTabFlatStyleAction.Checked := True;
1033+ end;
1034+
9581035 //プログレスバーの初期化
9591036 ProgressBar.Parent := StatusBar;
9601037 ProgressBar.Top := 2;
@@ -968,10 +1045,14 @@ begin
9681045
9691046 // ボードファイル列挙(ReadFavorite より先に行うこと)
9701047 GikoSys.ListBoardFile;
971-
1048+ // 連続起動時にスプラッシュウィンドウのメモリが不定に
1049+ try
9721050 // スプラッシュウィンドウのプログレスバーの設定
973- SplashWindow.ProgressBar.Max := Length(BBSs) * 20;
974-
1051+ if (SplashWindow <> nil) then begin
1052+ SplashWindow.ProgressBar.Max := Length(BBSs) * 20;
1053+ end;
1054+ except
1055+ end;
9751056 // すべてのBBSを読み込んでおく
9761057 for i := Length(BBSs) - 1 downto 0 do begin
9771058 if not BBSs[i].IsBoardFileRead then
@@ -982,6 +1063,7 @@ begin
9821063 SplashWindow.Update;
9831064 end;
9841065 end;
1066+
9851067 //巡回データ読み込み
9861068 RoundList := TRoundList.Create;
9871069 RoundList.LoadRoundBoardFile;
@@ -1200,7 +1282,8 @@ begin
12001282 FavoriteAddToolButton.Caption := '追加...';
12011283 AntiIndivAbonMenuItem.Caption := '個別あぼ〜ん解除';
12021284
1203-
1285+ //入力アシスト機構の初期化
1286+ InputAssistDM.Init(GikoSys.GetInputAssistFileName);
12041287 end;
12051288
12061289 // CoolBar の設定を変数に保存
@@ -1341,51 +1424,20 @@ begin
13411424 GikoDM.BrowserNameBarVisibleAction.Checked := GikoSys.Setting.BrowserNameBarVisible;
13421425 GikoDM.BrowserNameBarVisibleActionExecute( nil );
13431426
1344- //ブラウザタブ
1345- GikoDM.BrowserTabVisibleAction.Checked := GikoSys.Setting.BrowserTabVisible;
1346- GikoDM.BrowserTabVisibleActionExecute(nil);
1347-
1348- if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
1349- GikoDM.BrowserTabTopAction.Checked := True;
1350- GikoDM.BrowserTabTopActionExecute(nil);
1351- end else begin
1352- GikoDM.BrowserTabBottomAction.Checked := True;
1353- GikoDM.BrowserTabBottomActionExecute(nil);
1354- end;
1355-
1356- if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
1357- GikoDM.BrowserTabTabStyleAction.Checked := True;
1358- GikoDM.BrowserTabTabStyleActionExecute(nil);
1359- end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
1360- GikoDM.BrowserTabButtonStyleAction.Checked := True;
1361- GikoDM.BrowserTabButtonStyleActionExecute(nil);
1362- end else begin
1363- GikoDM.BrowserTabFlatStyleAction.Checked := True;
1364- GikoDM.BrowserTabFlatStyleActionExecute(nil);
1365- end;
1366-
1367- // ListView のヘッダドラッグ
1368-// ListView.FullDrag := True;
1369-
13701427 // CoolBar 復元
13711428 LoadCoolBarSettings;
13721429
13731430 //重要 これがないとツールボタンの更新がおかしくなる
13741431 // ResetBandInfo( ListCoolBar, ListToolBar );
13751432 FIsIgnoreResize := rtNone;
1376- //ツールバーの更新を終えた後にやらないといけないのかも
1377- //アクションのチェック状態を初期化
1378- InitActionChecked();
13791433
13801434 //FormCreteから移動。
13811435 if GikoSys.Setting.TabAutoLoadSave then begin
13821436 GikoDM.TabAutoLoadAction.Execute;
13831437 end;
1384- //にちゃん語案内サポート機能
1385- if GikoSys.Setting.GengoSupport then begin
1386- //予定地
1387- //Test向け
1388- end;
1438+
1439+ //ActionListのGroupIndexを元に戻す
1440+ SetGroupIndex(GikoDM.GikoFormActionList);
13891441
13901442 FStartUp := false;
13911443 end;
@@ -1474,6 +1526,8 @@ begin
14741526 // CoolBar 保存
14751527 //if (GikoForm.WindowState <> wsMinimized) and (GikoForm.WindowState <> wsMaximized) then
14761528
1529+ //入力アシスト機構の設定の保存
1530+ InputAssistDM.SaveToFile(GikoSys.GetInputAssistFileName);
14771531
14781532 //お気に入り保存
14791533 try
@@ -2249,6 +2303,7 @@ begin
22492303 GikoSys.Setting.BoardSortIndex := 0;
22502304 GikoSys.Setting.BoardSortOrder := True;
22512305 end;
2306+ Sort.SetSortDate(Now());
22522307 SetActiveList(Item.Board);
22532308 end;
22542309 Item.Board.Modified := True;
@@ -2667,6 +2722,12 @@ begin
26672722 Exit;
26682723 end;
26692724 PostMessage( Handle, USER_DOCUMENTCOMPLETE, Integer( Thread.Browser ), 0 );
2725+ end else begin
2726+ // JUMPを指定されていたらJUMPする
2727+ if (Thread.Movement <> '') then begin
2728+ Thread.Move(Thread.Movement);
2729+ Thread.Movement := '';
2730+ end;
26702731 end;
26712732 end;
26722733 if (Thread <> nil) and (ThreadItem <>nil) then begin
@@ -3037,7 +3098,7 @@ begin
30373098 // title は今のところ使っていない
30383099 saveList.Add(
30393100 '<history url="' + HtmlEncode( TFavoriteThreadItem( FHistoryList[ i ] ).URL ) + '"' +
3040- ' title="' + HtmlEncode( TFavoriteThreadItem( FHistoryList[ i ] ).Title ) + '"/>');
3101+ ' title="' + HtmlEncode( MojuUtils.Sanitize(TFavoriteThreadItem( FHistoryList[ i ] ).Title )) + '"/>');
30413102 end;
30423103 saveList.Add('</address>');
30433104 saveList.SaveToFile( GikoSys.GetConfigDir + 'History.xml' );
@@ -3056,15 +3117,21 @@ var
30563117 HistoryNode : IXMLNode;
30573118 s : string;
30583119 favItem : TFavoriteThreadItem;
3120+{$IFDEF DEBUG}
3121+ st, rt : Cardinal;
3122+{$ENDIF}
30593123 begin
3124+{$IFDEF DEBUG}
3125+ st := GetTickCount;
3126+{$ENDIF}
30603127
30613128 fileName := GikoSys.GetConfigDir + 'History.xml';
30623129
30633130 if FileExists( fileName ) then begin
30643131 try
3065- XMLDoc := IXMLDocument.Create;
3132+ XMLDoc := IXMLDocument.Create;
30663133 //XMLDoc := LoadXMLDocument(FileName);
3067- LoadXMLDocument(FileName, XMLDoc);
3134+ LoadXMLDocument(FileName, XMLDoc);
30683135 try
30693136 XMLNode := XMLDoc.DocumentElement;
30703137
@@ -3077,9 +3144,9 @@ begin
30773144 s := Trim(HistoryNode.Attributes['url']);
30783145 if s <> '' then begin
30793146 favItem := TFavoriteThreadItem.Create(
3080- s, HistoryNode.Attributes[ 'title' ] );
3147+ s, MojuUtils.UnSanitize(HistoryNode.Attributes[ 'title' ]) );
30813148 if not AddHistory( favItem ) then
3082- favItem.Free;
3149+ favItem.Free;
30833150 end;
30843151 //end;
30853152 end;
@@ -3091,6 +3158,10 @@ begin
30913158 except
30923159 end;
30933160 end;
3161+{$IFDEF DEBUG}
3162+ rt := GetTickCount - st;
3163+ Writeln('Runtime(Load Histroy) : ' + IntToStr(rt) + ' ms');
3164+{$ENDIF}
30943165
30953166 end;
30963167
@@ -3338,7 +3409,6 @@ begin
33383409 end else begin
33393410 if Item <> FActiveList then begin
33403411 ActiveListColumnSave;
3341-
33423412 if (Item is TBBS) or (Item is TCategory) then begin
33433413 ListView.Columns.Clear;
33443414 SetActiveList( Item );
@@ -3352,6 +3422,7 @@ begin
33523422 Screen.Cursor := crDefault;
33533423 end;
33543424 end;
3425+ Sort.SetSortDate(Now());
33553426 SetActiveList( Item );
33563427 end;
33573428 end;
@@ -3560,7 +3631,6 @@ begin
35603631 FTabHintIndex := -1;
35613632 for i := 0 to BrowserTab.Tabs.Count - 1 do begin
35623633 if TBrowserRecord(BrowserTab.Tabs.Objects[i]) = BrowserRecord then begin
3563- BrowserTab.Tabs.BeginUpdate;
35643634 try
35653635 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser <> nil then begin
35663636 doc := TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser.Document;
@@ -3576,15 +3646,25 @@ begin
35763646 if j <> -1 then
35773647 FBrowsers.Move(j, BROWSER_COUNT - 1);
35783648 end;
3579- TBrowserRecord(BrowserTab.Tabs.Objects[i]).Free;
3580- BrowserTab.Tabs.Delete(i);
3581- if idx > i then begin
3582- BrowserTab.TabIndex := idx - 1;
3583- end else begin
3584- if BrowserTab.Tabs.Count -1 >= idx then
3585- BrowserTab.TabIndex := idx
3586- else
3587- BrowserTab.TabIndex := BrowserTab.Tabs.Count - 1;
3649+ BrowserTab.Tabs.BeginUpdate;
3650+ try
3651+ TBrowserRecord(BrowserTab.Tabs.Objects[i]).Free;
3652+ if ( BrowserTab.Tabs.Count - 1 = i ) and
3653+ ( BrowserTab.TabRect(i).Left
3654+ <= BrowserTab.DisplayRect.Left ) then begin
3655+ BrowserTab.ScrollTabs(-1);
3656+ end;
3657+ BrowserTab.Tabs.Delete(i);
3658+ if idx > i then begin
3659+ BrowserTab.TabIndex := idx - 1;
3660+ end else begin
3661+ if BrowserTab.Tabs.Count -1 >= idx then
3662+ BrowserTab.TabIndex := idx
3663+ else
3664+ BrowserTab.TabIndex := BrowserTab.Tabs.Count - 1;
3665+ end;
3666+ finally
3667+ BrowserTab.Tabs.EndUpdate;
35883668 end;
35893669 if BrowserTab.Tabs.Count = 0 then begin
35903670 BrowserNullTab.Thread := nil;
@@ -3604,7 +3684,6 @@ begin
36043684 TBrowserRecord(BrowserTab.Tabs.Objects[BrowserTab.TabIndex]).Repaint := true;
36053685 FBrowsers.Move(BROWSER_COUNT - 1, 0);
36063686 end;
3607- BrowserTab.Tabs.EndUpdate;
36083687 if( FActiveContent = nil) then
36093688 BrowserTab.OnChange(nil);
36103689 Exit;
@@ -3620,7 +3699,6 @@ begin
36203699 FTabHintIndex := -1;
36213700 for i := 0 to BrowserTab.Tabs.Count - 1 do begin
36223701 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Thread = ThreadItem then begin
3623- BrowserTab.Tabs.BeginUpdate;
36243702 try
36253703 if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser <> nil then begin
36263704 doc := TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser.Document;
@@ -3637,15 +3715,25 @@ begin
36373715 if j <> -1 then
36383716 FBrowsers.Move(j, BROWSER_COUNT - 1);
36393717 end;
3640- TBrowserRecord(BrowserTab.Tabs.Objects[i]).Free;
3641- BrowserTab.Tabs.Delete(i);
3642- if idx > i then begin
3643- BrowserTab.TabIndex := idx - 1;
3644- end else begin
3645- if BrowserTab.Tabs.Count -1 >= idx then
3646- BrowserTab.TabIndex := idx
3647- else
3648- BrowserTab.TabIndex := BrowserTab.Tabs.Count - 1;
3718+ BrowserTab.Tabs.BeginUpdate;
3719+ try
3720+ TBrowserRecord(BrowserTab.Tabs.Objects[i]).Free;
3721+ if ( BrowserTab.Tabs.Count - 1 = i ) and
3722+ ( BrowserTab.TabRect(i).Left
3723+ <= BrowserTab.DisplayRect.Left ) then begin
3724+ BrowserTab.ScrollTabs(-1);
3725+ end;
3726+ BrowserTab.Tabs.Delete(i);
3727+ if idx > i then begin
3728+ BrowserTab.TabIndex := idx - 1;
3729+ end else begin
3730+ if BrowserTab.Tabs.Count -1 >= idx then
3731+ BrowserTab.TabIndex := idx
3732+ else
3733+ BrowserTab.TabIndex := BrowserTab.Tabs.Count - 1;
3734+ end;
3735+ finally
3736+ BrowserTab.Tabs.EndUpdate;
36493737 end;
36503738 if(BrowserTab.TabIndex <> -1) and
36513739 ( TBrowserRecord(BrowserTab.Tabs.Objects[BrowserTab.TabIndex]).Browser = nil) then begin
@@ -3663,7 +3751,6 @@ begin
36633751 FBrowsers.Move(BROWSER_COUNT - 1, 0);
36643752 end;
36653753
3666- BrowserTab.Tabs.EndUpdate;
36673754 if( FActiveContent = nil) then
36683755 BrowserTab.OnChange(nil);
36693756 Exit;
@@ -3927,52 +4014,53 @@ var
39274014 i, j: Integer;
39284015 idx: Integer;
39294016 begin
4017+ BrowserTab.Tabs.BeginUpdate;
4018+ try
4019+ if not BrowserTab.Dragging then begin
4020+ FTabHintIndex := -1;
4021+ BrowserTab.Hint := '';
4022+ idx := BrowserTab.TabIndex;
4023+ if idx = -1 then begin
4024+ SetContent(BrowserNullTab);
4025+
4026+ end else if(BrowserTab.Tabs.Objects[idx] <> nil) and (BrowserTab.Tabs.Objects[idx] is TBrowserRecord) then begin
4027+ if TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser <> nil then begin
4028+ j := FBrowsers.IndexOf(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser);
4029+ if j <> -1 then
4030+ FBrowsers.Move(j ,0);
4031+ end else begin
4032+ if( FActiveContent <> nil ) and (FActiveContent.Browser <> nil) and
4033+ (FActiveContent.Browser <> BrowserNullTab.Browser) and
4034+ (FActiveContent.Browser = TWebBrowser(FBrowsers[BROWSER_COUNT - 1])) then
4035+ FBrowsers.Move(BROWSER_COUNT - 1, 0);
39304036
3931- if not BrowserTab.Dragging then begin
3932- FTabHintIndex := -1;
3933- BrowserTab.Hint := '';
3934- idx := BrowserTab.TabIndex;
3935- if idx = -1 then begin
3936- SetContent(BrowserNullTab);
3937-
3938- end else if(BrowserTab.Tabs.Objects[idx] <> nil) and (BrowserTab.Tabs.Objects[idx] is TBrowserRecord) then begin
3939- if TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser <> nil then begin
3940- j := FBrowsers.IndexOf(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser);
3941- if j <> -1 then
3942- FBrowsers.Move(j ,0);
3943- end else begin
3944- if( FActiveContent <> nil ) and (FActiveContent.Browser <> nil) and
3945- (FActiveContent.Browser <> BrowserNullTab.Browser) and
3946- (FActiveContent.Browser = TWebBrowser(FBrowsers[BROWSER_COUNT - 1])) then
3947- FBrowsers.Move(BROWSER_COUNT - 1, 0);
3948-
3949- for i := 0 to BrowserTab.Tabs.Count - 1 do begin
3950- if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser = TWebBrowser(FBrowsers[BROWSER_COUNT - 1]) then begin
3951- ReleaseBrowser(TBrowserRecord(BrowserTab.Tabs.Objects[i]));
3952- break;
4037+ for i := 0 to BrowserTab.Tabs.Count - 1 do begin
4038+ if TBrowserRecord(BrowserTab.Tabs.Objects[i]).Browser = TWebBrowser(FBrowsers[BROWSER_COUNT - 1]) then begin
4039+ ReleaseBrowser(TBrowserRecord(BrowserTab.Tabs.Objects[i]));
4040+ break;
4041+ end;
39534042 end;
4043+ TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser := TWebBrowser(FBrowsers[BROWSER_COUNT - 1]);
4044+ TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Repaint := true;
4045+ FBrowsers.Move(BROWSER_COUNT - 1, 0);
39544046 end;
3955- TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser := TWebBrowser(FBrowsers[BROWSER_COUNT - 1]);
3956- TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Repaint := true;
3957- FBrowsers.Move(BROWSER_COUNT - 1, 0);
3958- end;
3959- MoveWindow(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser.Handle, 0, 0, BrowserPanel.Width, BrowserPanel.Height, false);
3960- TOleControl(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser).BringToFront;
3961- SetContent(TBrowserRecord(BrowserTab.Tabs.Objects[idx]));
4047+ MoveWindow(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser.Handle, 0, 0, BrowserPanel.Width, BrowserPanel.Height, false);
4048+ TOleControl(TBrowserRecord(BrowserTab.Tabs.Objects[idx]).Browser).BringToFront;
4049+ SetContent(TBrowserRecord(BrowserTab.Tabs.Objects[idx]));
39624050
3963- if (GikoSys.Setting.URLDisplay) and (GetActiveContent <> nil) then
3964- AddressComboBox.Text := GetActiveContent.URL;
3965-
3966- if ((TreeView.Visible) and (TreeView.Focused)) or ((FavoriteTreeView.Visible) and (FavoriteTreeView.Focused)) or
3967- (ListView.Focused) or (SelectComboBox.Focused) or (AddressComboBox.Focused)
3968- then
3969- else
3970- GikoDM.SetFocusForBrowserAction.Execute;
4051+ if (GikoSys.Setting.URLDisplay) and (GetActiveContent <> nil) then
4052+ AddressComboBox.Text := GetActiveContent.URL;
39714053
4054+ if ((TreeView.Visible) and (TreeView.Focused)) or ((FavoriteTreeView.Visible) and (FavoriteTreeView.Focused)) or
4055+ (ListView.Focused) or (SelectComboBox.Focused) or (AddressComboBox.Focused)
4056+ then
4057+ else
4058+ GikoDM.SetFocusForBrowserAction.Execute;
4059+ end;
39724060 end;
3973-
4061+ finally
4062+ BrowserTab.Tabs.EndUpdate;
39744063 end;
3975-
39764064 end;
39774065
39784066
@@ -4001,54 +4089,51 @@ end;
40014089
40024090 procedure TGikoForm.SetBrowserTabState;
40034091 var
4004-// i: Integer;
40054092 CoolBand: TCoolBand;
40064093 begin
40074094 BrowserBottomPanel.AutoSize := False;
40084095 if GikoSys.Setting.BrowserTabVisible then begin
4009- if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
4010- BrowserTab.Style := tsTabs;
4011- if GikoSys.Setting.BrowserTabPosition = gtpTop then
4012- BrowserTab.TabPosition := tpTop
4013- else
4014- BrowserTab.TabPosition := tpBottom;
4015- end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
4016- BrowserTab.TabPosition := tpTop;
4017- BrowserTab.Style := tsButtons;
4018- end else begin
4019- BrowserTab.TabPosition := tpTop;
4020- BrowserTab.Style := tsFlatButtons
4021- end;
4022-
4023- if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
4024- BrowserTab.Parent := BrowserTabToolBar;
4025- BrowserBottomPanel.Hide;
4026- CoolBand := GetCoolBand(BrowserCoolBar, BrowserTabToolBar);
4027- if CoolBand <> nil then
4028- CoolBand.Visible := True;
4029-// BrowserTab.Parent := BrowserTopPanel;
4030-// BrowserTab.Parent := BrowserCoolBar;
4031-// BrowserTab.Top := 26;
4032-// BrowserTopPanel.Height := 44;
4096+ BrowserTab.Hide;
4097+ BrowserTab.Tabs.BeginUpdate;
4098+ try
4099+ if GikoSys.Setting.BrowserTabStyle = gtsTab then begin
4100+ BrowserTab.Style := tsTabs;
4101+ if GikoSys.Setting.BrowserTabPosition = gtpTop then
4102+ BrowserTab.TabPosition := tpTop
4103+ else
4104+ BrowserTab.TabPosition := tpBottom;
4105+ end else if GikoSys.Setting.BrowserTabStyle = gtsButton then begin
4106+ BrowserTab.TabPosition := tpTop;
4107+ BrowserTab.Style := tsButtons;
4108+ end else begin
4109+ BrowserTab.TabPosition := tpTop;
4110+ BrowserTab.Style := tsFlatButtons
4111+ end;
40334112
4034- end else begin
4035- BrowserTab.Parent := BrowserBottomPanel;
4036- BrowserTab.Top := 0;
4037- BrowserTab.Left := 0;
4038- BrowserBottomPanel.Show;
4039- CoolBand := GetCoolBand(BrowserCoolBar, BrowserTabToolBar);
4040- if CoolBand <> nil then
4041- CoolBand.Visible := False;
4042-// BrowserTopPanel.Height := 26;
4043- end;
4044- BrowserTab.Show;
4113+ if GikoSys.Setting.BrowserTabPosition = gtpTop then begin
4114+ BrowserTab.Parent := BrowserTabToolBar;
4115+ BrowserBottomPanel.Hide;
4116+ CoolBand := GetCoolBand(BrowserCoolBar, BrowserTabToolBar);
4117+ if CoolBand <> nil then
4118+ CoolBand.Visible := True;
4119+ end else begin
4120+ BrowserTab.Parent := BrowserBottomPanel;
4121+ BrowserTab.Top := 0;
4122+ BrowserTab.Left := 0;
4123+ BrowserBottomPanel.Show;
4124+ CoolBand := GetCoolBand(BrowserCoolBar, BrowserTabToolBar);
4125+ if CoolBand <> nil then
4126+ CoolBand.Visible := False;
4127+ end;
4128+ finally
4129+ BrowserTab.Tabs.EndUpdate;
4130+ BrowserTab.Show;
4131+ end;
40454132 end else begin
40464133 CoolBand := GetCoolBand(BrowserCoolBar, BrowserTabToolBar);
40474134 if CoolBand <> nil then
40484135 CoolBand.Visible := False;
40494136 BrowserBottomPanel.Visible := False;
4050-// BrowserTab.Visible := False;
4051-// BrowserTopPanel.Height := 26;
40524137 GikoDM.AllTabCloseAction.Execute;
40534138 end;
40544139 end;
@@ -4495,6 +4580,45 @@ begin
44954580 TopPanel.Height := Max(MainCoolBar.Height, AnimePanel.Height);
44964581
44974582 end;
4583+//! 指定されたスレッドを開く(ログが無いとき or 指定JUMPまで足りないときはDLする)
4584+procedure TGikoForm.OpenThreadItem(Thread: TThreadItem; URL: String);
4585+var
4586+ stRes, edRes : Int64;
4587+ browserRec : TBrowserRecord;
4588+ threadNumber : String;
4589+begin
4590+ stRes := 0;
4591+ edRes := 0;
4592+ // タブを生成
4593+ browserRec := InsertBrowserTab(Thread);
4594+ if (browserRec <> nil) then begin
4595+ // JUMPすべきレス番号があるかチェックする
4596+ threadNumber := ChangeFileExt(Thread.FileName, '');
4597+ GikoSys.GetPopupResNumber( URL, stRes, edRes );
4598+ // スレの番号をレス番と誤って認識しているのをクリア
4599+ if (StrToInt(threadNumber) = stRes) then begin
4600+ if not (AnsiEndsText(threadNumber + '/' + threadNumber, URL))
4601+ and (Pos('&st=' + threadNumber , URL) = 0) then begin
4602+ stRes := 0;
4603+ end;
4604+ end;
4605+ if ( stRes > 0 ) then begin
4606+ browserRec.Movement := IntToStr( stRes );
4607+ end;
4608+ // ログを持っていないか JUMPすべきレス番号まで取得していないときはDLする
4609+ if (not Thread.IsLogFile) or (stRes > Thread.Count) then begin
4610+ DownloadContent(Thread);
4611+ end else if (not browserRec.Repaint) then begin
4612+ try
4613+ if (browserRec.Movement <> '') then begin
4614+ browserRec.Move(browserRec.Movement);
4615+ browserRec.Movement := '';
4616+ end;
4617+ except
4618+ end;
4619+ end;
4620+ end;
4621+end;
44984622
44994623 procedure TGikoForm.MoveToURL(const inURL: string);
45004624 var
@@ -4507,13 +4631,8 @@ var
45074631 i, bi : Integer;
45084632 boardURL : string;
45094633 tmpThread : TThreadItem;
4510-// category : TCategory;
4511-// categoryNode : TTreeNode;
4512-// boardNode : TTreeNode;
45134634 shiftDown : Boolean;
45144635 ctrlDown : Boolean;
4515- stRes, edRes : Int64;
4516- browserRec : TBrowserRecord;
45174636 begin
45184637
45194638 GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark );
@@ -4569,30 +4688,11 @@ begin
45694688 if TBoard(ActiveList) = Board then
45704689 ListView.Items.Count := ListView.Items.Count + 1;
45714690 end;
4572- GikoSys.GetPopupResNumber( inURL, stRes, edRes );
4573- browserRec := InsertBrowserTab( ThreadItem );
4574- if (browserRec <> nil) and (stRes > 0) then
4575- browserRec.Movement := IntToStr( stRes );
4576- DownloadContent( ThreadItem );
4577- Exit;
45784691 end else begin
45794692 tmpThread.Free;
4580- GikoSys.GetPopupResNumber( inURL, stRes, edRes );
4581- browserRec := InsertBrowserTab( ThreadItem );
4582- if ThreadItem.IsLogFile then begin
4583- if (browserRec <> nil) and (stRes > 0) then begin
4584- browserRec.Movement := IntToStr( stRes );
4585- if (stRes > ThreadItem.Count) then begin
4586- DownloadContent( ThreadItem );
4587- end;
4588- end;
4589- end else begin
4590- if (browserRec <> nil) and (stRes > 0) then
4591- browserRec.Movement := IntToStr( stRes );
4592- DownloadContent( ThreadItem );
4593- end;
4594- Exit;
45954693 end;
4694+ OpenThreadItem(ThreadItem, inURL);
4695+ Exit;
45964696 end;
45974697 end;
45984698
@@ -4619,15 +4719,6 @@ begin
46194719 if (Length( Trim(BBSKey) ) > 0) and (Length( Trim(BBSID) ) > 0) then begin
46204720 boardURL := GikoSys.Get2chThreadURL2BoardURL( inURL );
46214721 Board := BBSsFindBoardFromURL( boardURL );
4622- //if Board = nil then
4623- // Board := BBSsFindBoardFromBBSID( BBSID );
4624- { この部分もBBSsFindBoardFromURLに持たせた 20050523
4625- if Board = nil then begin
4626- // ※作っても追加するところが無いので激しく保留
4627- // 過去ログ倉庫から、ダウソしたスレが発見できないのでここで探すようにする (2004/01/22)
4628- Board := BBSs[ 0 ].FindBBSID( BBSID );
4629- end;
4630- }
46314722 if Board = nil then begin
46324723 // 入るべき板が見つからなかったので、普通のブラウザで開く
46334724 GikoSys.OpenBrowser(inURL, gbtUserApp);
@@ -4652,55 +4743,26 @@ begin
46524743 if ThreadItem = nil then begin
46534744 ThreadItem := Board.FindThreadFromFileName( BBSKey + '.dat' );
46544745 end;
4655- if ThreadItem = nil then begin
4656- //shift -> 設定ブラウザ(無ければIE)
4657- //ctrl -> IE
4658- {shiftDown := GetAsyncKeyState(VK_SHIFT) = Smallint($8001);
4659- ctrlDown := GetAsyncKeyState(VK_CONTROL) = Smallint($8001);
4660- if shiftDown then
4661- GikoSys.OpenBrowser(URL1, gbtUserApp)
4662- else if ctrlDown then
4663- GikoSys.OpenBrowser(URL1, gbtIE)
4664- else begin
4665- }
4666- ThreadItem := TThreadItem.Create( nil, Board, URL );
4667- ThreadItem.FileName := ChangeFileExt(BBSKey, '.dat');
4668- if AnsiPos(Host, Board.URL) = 0 then
4669- ThreadItem.DownloadHost := Host
4670- else
4671- ThreadItem.DownloadHost := '';
4672- Board.Insert(0, ThreadItem);
4673- if ActiveList is TBoard then begin
4674- if TBoard(ActiveList) = Board then
4675- ListView.Items.Count := ListView.Items.Count + 1;
4676- end;
4677- GikoSys.GetPopupResNumber( inURL, stRes, edRes );
4678- browserRec := InsertBrowserTab(ThreadItem);
4679- if (browserRec <> nil) and (stRes > 0) then
4680- browserRec.Movement := IntToStr( stRes );
4681- DownloadContent(ThreadItem);
4682- {end;}
4683- end else begin
4684- if ThreadItem.IsLogFile then begin
4685- GikoSys.GetPopupResNumber( inURL, stRes, edRes );
4686- browserRec := InsertBrowserTab(ThreadItem);
4687- if (browserRec <> nil) and (stRes > 0) then begin
4688- browserRec.Movement := IntToStr( stRes );
4689- if (stRes > ThreadItem.Count) then begin
4690- DownloadContent(ThreadItem);
4691- end;
4746+ try
4747+ // スレッドアイテムがないなら生成する。
4748+ if ThreadItem = nil then begin
4749+ ThreadItem := TThreadItem.Create( nil, Board, URL );
4750+ ThreadItem.FileName := ChangeFileExt(BBSKey, '.dat');
4751+ Board.Insert(0, ThreadItem);
4752+ if ActiveList is TBoard then begin
4753+ if TBoard(ActiveList) = Board then
4754+ ListView.Items.Count := ListView.Items.Count + 1;
46924755 end;
4693- end else begin
4756+ end;
4757+ // ログなしスレッドのときは、ホスト名のチェックをする
4758+ if not ThreadItem.IsLogFile then begin
46944759 if AnsiPos(Host, Board.URL) = 0 then
46954760 ThreadItem.DownloadHost := Host
46964761 else
46974762 ThreadItem.DownloadHost := '';
4698- GikoSys.GetPopupResNumber( inURL, stRes, edRes );
4699- browserRec := InsertBrowserTab(ThreadItem);
4700- if (browserRec <> nil) and (stRes > 0) then
4701- browserRec.Movement := IntToStr( stRes );
4702- DownloadContent(ThreadItem);
47034763 end;
4764+ OpenThreadItem(ThreadItem, inURL);
4765+ except
47044766 end;
47054767 end else begin
47064768 Board := BBSsFindBoardFromURL( inURL );
@@ -4710,7 +4772,7 @@ begin
47104772 if FActiveBBS <> Board.ParentCategory.ParenTBBS then
47114773 ShowBBSTree( Board.ParentCategory.ParenTBBS );
47124774 SelectTreeNode( Board, True );
4713- end;
4775+ end;
47144776 end;
47154777 end;
47164778
@@ -6613,6 +6675,7 @@ begin
66136675 Screen.Cursor := crDefault;
66146676 end;
66156677 end;
6678+ Sort.SetSortDate(Now());
66166679 SetActiveList(Node.data);
66176680 end;
66186681
@@ -6687,7 +6750,8 @@ begin
66876750 (FavoriteTreeView.Selected = FavoriteTreeView.GetNodeAt(X, Y)) then begin
66886751 //マウスがnodeの上にいるか
66896752 rect := FavoriteTreeView.Selected.DisplayRect(true);
6690- if ((rect.Left <= X) and (rect.Right >= X)) and
6753+ // アイコン分左にずらす
6754+ if ((rect.Left - FavoriteTreeView.Indent <= X) and (rect.Right >= X)) and
66916755 ((rect.Bottom >= Y) and (rect.Top <= Y)) then begin
66926756 if ssDouble in Shift then begin
66936757 FClickNode := FavoriteTreeView.Selected;
@@ -7580,61 +7644,6 @@ begin
75807644 MsgBox(Handle, s, '処理されなかった例外', MB_OK or MB_ICONSTOP);
75817645 end;
75827646 // *************************************************************************
7583-//! アクションのチェック状態の初期化 FormのCreateで呼び出しても反映しない
7584-// *************************************************************************
7585-procedure TGikoForm.InitActionChecked();
7586-begin
7587- //ログイン状態を再設定
7588- GikoDM.LoginAction.Checked := GikoDM.LoginAction.Checked;
7589- //ミュートの状態を設定
7590- GikoDM.MuteAction.Checked := GikoSys.Setting.Mute;
7591- //画面の分割の状態を再設定
7592- GikoDM.ArrangeAction.Checked := GikoDM.ArrangeAction.Checked;
7593-
7594- //スレ全部表示ボタンを押された状態にする
7595- GikoDM.AllItemAction.Checked := True;
7596- GikoDM.AllResAction.Checked := True;
7597-
7598- // レス表示範囲
7599- FResRangeMenuSelect := GikoSys.ResRange;
7600- case GikoSys.ResRange of
7601- Ord( grrAll ):
7602- begin
7603- GikoDM.AllResAction.Execute;
7604- end;
7605- Ord( grrSelect ):
7606- begin
7607- SelectComboBox.Text := SelectComboBox.Items[ 1 ];
7608- GikoDM.SelectResAction.Checked := True;
7609- end;
7610- else
7611- case FResRangeMenuSelect of
7612- Ord( grrKoko ): GikoDM.OnlyKokoResAction.Checked := True;
7613- Ord( grrNew ): GikoDM.OnlyNewResAction.Checked := True;
7614- 100: GikoDM.OnlyAHundredResAction.Checked := True;
7615- end;
7616- end;
7617-
7618- // スレッド一覧表示範囲
7619- case GikoSys.Setting.ThreadRange of
7620- gtrAll:
7621- begin
7622- GikoDM.AllItemAction.Checked := True;
7623- ViewType := gvtAll;
7624- end;
7625- gtrLog:
7626- begin
7627- GikoDM.LogItemAction.Checked := True;
7628- ViewType := gvtLog;
7629- end;
7630- gtrNew:
7631- begin
7632- GikoDM.NewItemAction.Checked := True;
7633- ViewType := gvtNew;
7634- end;
7635- end;
7636-end;
7637-// *************************************************************************
76387647 //! ダウンロードコントロールスレッドの生成
76397648 // *************************************************************************
76407649 procedure TGikoForm.CreateControlThread();
@@ -7755,9 +7764,10 @@ begin
77557764 (TreeView.Selected = TreeView.GetNodeAt(X, Y)) then begin
77567765 //マウスがnodeの上にいるか
77577766 rect := TreeView.Selected.DisplayRect(true);
7758- if ((rect.Left <= X) and (rect.Right >= X)) and
7767+ // アイコン分だけ左にずらす
7768+ if ((rect.Left - TreeView.Indent <= X) and (rect.Right >= X)) and
77597769 ((rect.Bottom >= Y) and (rect.Top <= Y)) then begin
7760- // クリックとダブルクリックをココで判定
7770+ // クリックとダブルクリックをココで判定
77617771 if ssDouble in Shift then begin
77627772 TreeDoubleClick( TreeView.Selected );
77637773 end else begin
@@ -7768,6 +7778,50 @@ begin
77687778 end;
77697779 end;
77707780 end;
7781+//! ActionListのGroupIndexの保存
7782+procedure TGikoForm.GetGroupIndex(ActionList: TActionList);
7783+var
7784+ i: Integer;
7785+begin
7786+ if ActionList <> nil then begin
7787+ SetLength(FActionListGroupIndexes, ActionList.ActionCount);
7788+
7789+ for i := 0 to ActionList.ActionCount - 1 do begin
7790+ try
7791+ FActionListGroupIndexes[i] :=
7792+ TCustomAction(ActionList.Actions[i]).GroupIndex;
7793+ TCustomAction(ActionList.Actions[i]).GroupIndex
7794+ := 0;
7795+ except
7796+ ;//Castできないとき対策
7797+ end;
7798+ end;
7799+
7800+ end;
7801+end;
7802+//! ActionListのGroupIndexの設定
7803+procedure TGikoForm.SetGroupIndex(ActionList: TActionList);
7804+var
7805+ i: Integer;
7806+begin
7807+ if ActionList <> nil then begin
7808+ if Length( FActionListGroupIndexes ) = ActionList.ActionCount then begin
7809+ for i := 0 to ActionList.ActionCount - 1 do begin
7810+ try
7811+ TCustomAction(ActionList.Actions[i]).GroupIndex
7812+ := FActionListGroupIndexes[i];
7813+ except
7814+ ;//Castできないとき対策
7815+ end;
7816+ end;
7817+ end;
7818+ end;
7819+end;
7820+//! このレスのURL取得
7821+procedure TGikoForm.GetResURLMenuClick(Sender: TObject);
7822+begin
7823+;
7824+end;
77717825
77727826 initialization
77737827 OleInitialize(nil);
--- a/GikoDataModule.dfm
+++ b/GikoDataModule.dfm
@@ -37,7 +37,7 @@ object GikoDM: TGikoDM
3737 end
3838 object NewBoardAction: TAction
3939 Category = #12501#12449#12452#12523
40- Caption = #26495#26356#26032'(&B)...'
40+ Caption = #26495#19968#35239#26356#26032'(&B)...'
4141 Hint = #12508#12540#12489#26356#26032#12480#12452#12450#12525#12464#12434#34920#31034#12377#12427
4242 OnExecute = NewBoardActionExecute
4343 end
@@ -1201,6 +1201,19 @@ object GikoDM: TGikoDM
12011201 Hint = #12473#12524#12483#12489#12398#23481#37327#12434#12501#12449#12452#12523#12363#12425#20877#35336#31639#12377#12427
12021202 OnExecute = ThreadSizeCalcForFileActionExecute
12031203 end
1204+ object SetInputAssistAction: TAction
1205+ Category = #12484#12540#12523
1206+ Caption = #20837#21147#12450#12471#12473#12488#12398#35373#23450
1207+ Hint = #20837#21147#12450#12471#12473#12488#12398#35373#23450#12501#12457#12540#12512#12434#38283#12367
1208+ OnExecute = SetInputAssistActionExecute
1209+ end
1210+ object OpenFindDialogAction: TAction
1211+ Category = #12473#12524#12483#12489
1212+ Caption = #29694#22312#34920#31034#12375#12390#12356#12427#12473#12524#12483#12489#12398#26908#32034#12480#12452#12450#12525#12464#12434#34920#31034#12377#12427
1213+ Hint = #29694#22312#34920#31034#12375#12390#12356#12427#12473#12524#12483#12489#12398#26908#32034#12480#12452#12450#12525#12464#12434#34920#31034#12377#12427
1214+ ShortCut = 16454
1215+ OnExecute = OpenFindDialogActionExecute
1216+ end
12041217 end
12051218 object ToobarImageList: TImageList
12061219 Left = 44
--- a/GikoDataModule.pas
+++ b/GikoDataModule.pas
@@ -11,7 +11,8 @@ uses
1111 SHDocVw_TLB,
1212 MSHTML_TLB,
1313 {$IFEND}
14- ComCtrls, BrowserRecord, Graphics, Messages, Setting, Dialogs;
14+ ComCtrls, BrowserRecord, Graphics, Messages, Setting, Dialogs,
15+ ActiveX;
1516
1617 const
1718 CAPTION_NAME: string = 'ギコナビ';
@@ -212,6 +213,8 @@ type
212213 ToobarImageList: TImageList;
213214 SaveDialog: TSaveDialog;
214215 ThreadSizeCalcForFileAction: TAction;
216+ SetInputAssistAction: TAction;
217+ OpenFindDialogAction: TAction;
215218 procedure EditNGActionExecute(Sender: TObject);
216219 procedure ReloadActionExecute(Sender: TObject);
217220 procedure GoFowardActionExecute(Sender: TObject);
@@ -394,6 +397,8 @@ type
394397 procedure AllSelectActionExecute(Sender: TObject);
395398 procedure AllSelectActionUpdate(Sender: TObject);
396399 procedure ThreadSizeCalcForFileActionExecute(Sender: TObject);
400+ procedure SetInputAssistActionExecute(Sender: TObject);
401+ procedure OpenFindDialogActionExecute(Sender: TObject);
397402 private
398403 { Private 宣言 }
399404 procedure ClearResFilter;
@@ -434,7 +439,7 @@ uses
434439 ToolBarUtil, NewBoard, HTMLCreate, IndividualAbon,
435440 GikoBayesian, About, ShellAPI,
436441 RoundName, RoundData, Menus, ListViewUtils,
437- ThreadControl, GikoMessage;
442+ ThreadControl, GikoMessage, InputAssist;
438443
439444
440445 {$R *.dfm}
@@ -884,22 +889,16 @@ end;
884889 procedure TGikoDM.SetThreadAreaHorNormal;
885890 begin
886891 //通常表示にする
887- if GikoForm.ActiveContent <> nil then
888- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 0, 0); //描画停止
889892 GikoForm.ViewPanel.Width := GikoForm.BrowserSizeWidth;
890893 BrowserMaxAction.ImageIndex := TOOL_ICON_WIDTH_MAX;
891894 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_MIN;
892895 GikoSys.Setting.ListWidthState := glsNormal;
893- if GikoForm.ActiveContent <> nil then
894- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 1, 0); //描画
895896 end;
896897 // *************************************************************************
897898 //! スレッド表示エリア最大/最小表示にする 注)ListOrientation = gloHorizontal 
898899 // *************************************************************************
899900 procedure TGikoDM.SetThreadAreaHorizontal(gls : TGikoListState);
900901 begin
901- if GikoForm.ActiveContent <> nil then
902- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 0, 0); //描画停止
903902 if GikoSys.Setting.ListWidthState = glsNormal then
904903 GikoForm.BrowserSizeWidth := GikoForm.ViewPanel.Width;
905904 //最大表示
@@ -914,8 +913,6 @@ begin
914913 BrowserMinAction.ImageIndex := TOOL_ICON_WIDTH_NORMAL;
915914 GikoSys.Setting.ListWidthState := glsMin;
916915 end;
917- if GikoForm.ActiveContent <> nil then
918- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 1, 0); //描画
919916 end;
920917 // *************************************************************************
921918 //! スレッド表示エリア通常表示にする 注)ListOrientation = gloVertical
@@ -923,22 +920,16 @@ end;
923920 procedure TGikoDM.SetThreadAreaVerNormal;
924921 begin
925922 //通常表示にする
926- if GikoForm.ActiveContent <> nil then
927- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 0, 0); //描画停止
928923 GikoForm.ViewPanel.Height := GikoForm.BrowserSizeHeight;
929924 BrowserMaxAction.ImageIndex := TOOL_ICON_HEIGHT_MAX;
930925 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_MIN;
931926 GikoSys.Setting.ListHeightState := glsNormal;
932- if GikoForm.ActiveContent <> nil then
933- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 1, 0); //描画
934927 end;
935928 // *************************************************************************
936929 //! スレッド表示エリア最大/最小表示にする 注)ListOrientation = gloVertical
937930 // *************************************************************************
938931 procedure TGikoDM.SetThreadAreaVertical(gls : TGikoListState);
939932 begin
940- if GikoForm.ActiveContent <> nil then
941- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 0, 0); //描画停止
942933 if GikoSys.Setting.ListHeightState = glsNormal then
943934 GikoForm.BrowserSizeHeight := GikoForm.ViewPanel.Height;
944935 if (gls = glsMin) then begin
@@ -952,8 +943,6 @@ begin
952943 BrowserMinAction.ImageIndex := TOOL_ICON_HEIGHT_MIN;
953944 GikoSys.Setting.ListHeightState := glsMax;
954945 end;
955- if GikoForm.ActiveContent <> nil then
956- SendMessage(GikoForm.ActiveContent.Browser.Handle, WM_SETREDRAW, 1, 0); //描画
957946 end;
958947 // *************************************************************************
959948 //! スレッド表示エリアを大きく表示する
@@ -1062,7 +1051,6 @@ begin
10621051 if Item = nil then Exit;
10631052 Editor := TEditorForm.Create(GikoForm.GetMainForm);
10641053 Editor.SetThreadItem(Item);
1065- GikoSys.LoadKeySetting(Editor.ActionList, GikoSys.GetEditorKeyFileName);
10661054 Editor.Show;
10671055 Editor.BodyEdit.SetFocus;
10681056 end;
@@ -1563,7 +1551,7 @@ begin
15631551 try
15641552 if Dlg.ShowModal = mrOk then begin
15651553 GikoSys.SaveKeySetting(GikoFormActionList, Setting.KEY_SETTING_FILE_NAME);
1566- GikoSys.SaveKeySetting(Dlg.EditorForm.ActionList, Setting.KEY_SETTING_FILE_NAME);
1554+ GikoSys.SaveKeySetting(Dlg.EditorForm.ActionList, Setting.EKEY_SETTING_FILE_NAME);
15671555 GikoSys.Setting.Gestures.SaveGesture( GikoSys.Setting.GetGestureFileName );
15681556 end;
15691557
@@ -2227,7 +2215,6 @@ begin
22272215
22282216 Editor := TEditorForm.Create(GikoForm);
22292217 Editor.SetThreadItem(Item);
2230- GikoSys.LoadKeySetting(Editor.ActionList, GikoSys.GetEditorKeyFileName);
22312218 Editor.BodyEdit.Text := '>>' + IntToStr(Number) + #13#10;
22322219 Editor.Show;
22332220 Editor.BodyEdit.SetFocus;
@@ -3782,6 +3769,52 @@ begin
37823769 GikoForm.ProgressBar.Position := 0;
37833770 ShowMessage('計算終了しました。');
37843771 end;
3772+//! 入力アシストの設定フォームを呼び出す
3773+procedure TGikoDM.SetInputAssistActionExecute(Sender: TObject);
3774+var
3775+ form : TInputAssistForm;
3776+begin
3777+ form := TInputAssistForm.Create(GikoForm);
3778+ try
3779+ form.ShowModal;
3780+ finally
3781+ form.Release;
3782+ end;
3783+end;
3784+// WebBrowserの検索ダイアログを呼び出す
3785+procedure OpenFindDialog(Browser: TWebbrowser);
3786+const
3787+ CGID_WebBrowser: TGUID = '{ED016940-BD5B-11cf-BA4E-00C04FD70816}';
3788+ HTMLID_FIND = 1;
3789+var
3790+ CmdTarget : IOleCommandTarget;
3791+ vaIn, vaOut: OleVariant;
3792+ PtrGUID: PGUID;
3793+begin
3794+ if Browser.Document <> nil then begin
3795+ New(PtrGUID);
3796+ PtrGUID^ := CGID_WebBrowser;
3797+ try
3798+ Browser.Document.QueryInterface(IOleCommandTarget, CmdTarget);
3799+ if CmdTarget <> nil then begin
3800+ try
3801+ CmdTarget.Exec(PtrGUID, HTMLID_FIND, 0, vaIn, vaOut);
3802+ finally
3803+ CmdTarget._Release;
3804+ end;
3805+ end;
3806+ except
3807+ end;
3808+ Dispose(PtrGUID);
3809+ end;
3810+end;
3811+//! 現在表示しているスレッドの検索ダイアログを表示する
3812+procedure TGikoDM.OpenFindDialogActionExecute(Sender: TObject);
3813+begin
3814+ if( GikoForm.ActiveContent <> nil) and (GikoForm.ActiveContent.Browser <> nil) then begin
3815+ OpenFindDialog(GikoForm.ActiveContent.Browser);
3816+ end;
3817+end;
37853818
37863819 end.
37873820
--- a/GikoSystem.pas
+++ b/GikoSystem.pas
@@ -152,6 +152,7 @@ type
152152
153153 function GetMainKeyFileName : String;
154154 function GetEditorKeyFileName: String;
155+ function GetInputAssistFileName: String;
155156 procedure ReadSubjectFile(Board: TBoard);
156157 procedure CreateThreadDat(Board: TBoard);
157158 procedure WriteThreadDat(Board: TBoard);
@@ -254,7 +255,7 @@ const
254255 ZERO_DATE: Integer = 25569;
255256 BETA_VERSION_NAME_E = 'beta';
256257 BETA_VERSION_NAME_J = 'バタ';
257- BETA_VERSION = 51;
258+ BETA_VERSION = 52;
258259 BETA_VERSION_BUILD = ''; //!< debug版など
259260 APP_NAME = 'gikoNavi';
260261 BE_PHP_URL = 'http://be.2ch.net/test/p.php?i=';
@@ -3248,7 +3249,11 @@ function TGikoSys.GetEditorKeyFileName: String;
32483249 begin
32493250 Result := Setting.GetEditorKeyFileName;
32503251 end;
3251-
3252+//! 入力アシストの設定ファイル名
3253+function TGikoSys.GetInputAssistFileName: String;
3254+begin
3255+ Result := Setting.GetInputAssistFileName;
3256+end;
32523257 //! ギコナビのメッセージを設定する
32533258 procedure TGikoSys.SetGikoMessage;
32543259 begin
--- a/HTMLCreate.pas
+++ b/HTMLCreate.pas
@@ -970,17 +970,17 @@ const
970970 FORMAT_NOMAIL = '<a name="%s"></a><div class="header"><span class="no"><a href="menu:%s">%s</a></span>'
971971 + '<span class="name_label">名前:</span> <span class="name"><b>%s</b></span>'
972972 + '<span class="date_label">投稿日:</span> <span class="date">%s</span></div>'
973- + '<div class="mes">%s</div>';
973+ + '<div class="mes">%s</div>'#13#10;
974974
975975 FORMAT_SHOWMAIL = '<a name="%s"></a><div class="header"><span class="no"><a href="menu:%s">%s</a></span>'
976976 + '<span class="name_label"> 名前: </span><a class="name_mail" href="mailto:%s">'
977977 + '<b>%s</b></a><span class="mail"> [%s]</span><span class="date_label"> 投稿日:</span>'
978- + '<span class="date"> %s</span></div><div class="mes">%s </div>';
978+ + '<span class="date"> %s</span></div><div class="mes">%s</div>'#13#10;
979979
980980 FORMAT_NOSHOW = '<a name="%s"></a><div class="header"><span class="no"><a href="menu:%s">%s</a></span>'
981981 + '<span class="name_label"> 名前: </span><a class="name_mail" href="mailto:%s">'
982982 + '<b>%s</b></a><span class="date_label"> 投稿日:</span><span class="date"> %s</span></div>'
983- + '<div class="mes">%s </div>';
983+ + '<div class="mes">%s</div>'#13#10;
984984
985985 var
986986 i: integer;
@@ -1045,7 +1045,7 @@ begin
10451045 else if GikoSys.Setting.ShowMail then
10461046 doc.Write(Format(FORMAT_SHOWMAIL, [No, No, No, Res.FMailTo, Res.FName, Res.FMailTo, Res.FDateTime, Res.FBody]))
10471047 else
1048- doc.Write(Format(FORMAT_NOSHOW, [No, No, No, Res.FName, Res.FDateTime, Res.FBody]));
1048+ doc.Write(Format(FORMAT_NOSHOW, [No, No, No, Res.FMailTo, Res.FName, Res.FDateTime, Res.FBody]));
10491049 end;
10501050
10511051 if ThreadItem.Kokomade = (i + 1) then begin
--- /dev/null
+++ b/InputAssist.dfm
@@ -0,0 +1,359 @@
1+object InputAssistForm: TInputAssistForm
2+ Left = 386
3+ Top = 153
4+ Width = 400
5+ Height = 450
6+ Caption = #20837#21147#12450#12471#12473#12488#35373#23450
7+ Color = clBtnFace
8+ Font.Charset = SHIFTJIS_CHARSET
9+ Font.Color = clWindowText
10+ Font.Height = -12
11+ Font.Name = #65325#65331' '#65328#12468#12471#12483#12463
12+ Font.Style = []
13+ OldCreateOrder = False
14+ OnClose = FormClose
15+ OnCreate = FormCreate
16+ PixelsPerInch = 96
17+ TextHeight = 12
18+ object Panel1: TPanel
19+ Left = 0
20+ Top = 0
21+ Width = 392
22+ Height = 177
23+ Align = alTop
24+ BevelOuter = bvLowered
25+ Caption = 'Panel1'
26+ TabOrder = 0
27+ object Panel5: TPanel
28+ Left = 298
29+ Top = 1
30+ Width = 93
31+ Height = 175
32+ Align = alRight
33+ TabOrder = 0
34+ object CloseButton: TButton
35+ Left = 10
36+ Top = 136
37+ Width = 75
38+ Height = 25
39+ Caption = #32066#20102
40+ TabOrder = 0
41+ OnClick = CloseButtonClick
42+ end
43+ object ApplyButton: TButton
44+ Left = 10
45+ Top = 72
46+ Width = 75
47+ Height = 25
48+ Caption = #36969#29992
49+ TabOrder = 1
50+ OnClick = ApplyButtonClick
51+ end
52+ object DeleteButton: TButton
53+ Left = 10
54+ Top = 40
55+ Width = 75
56+ Height = 25
57+ Caption = #21066#38500
58+ TabOrder = 2
59+ OnClick = DeleteButtonClick
60+ end
61+ object AddButton: TButton
62+ Left = 10
63+ Top = 8
64+ Width = 75
65+ Height = 25
66+ Caption = #36861#21152
67+ TabOrder = 3
68+ OnClick = AddButtonClick
69+ end
70+ end
71+ object Panel6: TPanel
72+ Left = 1
73+ Top = 1
74+ Width = 297
75+ Height = 175
76+ Align = alClient
77+ BevelOuter = bvNone
78+ Caption = 'Panel6'
79+ TabOrder = 1
80+ object GikoListView1: TGikoListView
81+ Left = 0
82+ Top = 0
83+ Width = 297
84+ Height = 175
85+ Align = alClient
86+ Columns = <>
87+ ReadOnly = True
88+ RowSelect = True
89+ SmallImages = ColumnImageList
90+ TabOrder = 0
91+ ViewStyle = vsReport
92+ OnColumnClick = GikoListView1ColumnClick
93+ OnCompare = GikoListView1Compare
94+ OnSelectItem = GikoListView1SelectItem
95+ end
96+ end
97+ end
98+ object Panel2: TPanel
99+ Left = 0
100+ Top = 177
101+ Width = 392
102+ Height = 246
103+ Align = alClient
104+ BevelOuter = bvNone
105+ Caption = 'Panel2'
106+ TabOrder = 1
107+ object Panel3: TPanel
108+ Left = 0
109+ Top = 0
110+ Width = 392
111+ Height = 48
112+ Align = alTop
113+ BevelOuter = bvNone
114+ TabOrder = 0
115+ object KeyNameEdit: TLabeledEdit
116+ Left = 8
117+ Top = 21
118+ Width = 161
119+ Height = 20
120+ Hint = #20837#21147#12395#20351#12358#12461#12540#21517
121+ EditLabel.Width = 36
122+ EditLabel.Height = 12
123+ EditLabel.Caption = #12461#12540#21517
124+ LabelPosition = lpAbove
125+ LabelSpacing = 3
126+ TabOrder = 0
127+ end
128+ object CategoryNameEdit: TLabeledEdit
129+ Left = 176
130+ Top = 21
131+ Width = 121
132+ Height = 20
133+ Hint = #20837#21147#12395#20351#12358#12459#12486#12468#12522#21517
134+ EditLabel.Width = 53
135+ EditLabel.Height = 12
136+ EditLabel.Caption = #12459#12486#12468#12522#21517
137+ LabelPosition = lpAbove
138+ LabelSpacing = 3
139+ TabOrder = 1
140+ end
141+ end
142+ object Panel4: TPanel
143+ Left = 0
144+ Top = 48
145+ Width = 392
146+ Height = 198
147+ Align = alClient
148+ BevelOuter = bvNone
149+ TabOrder = 1
150+ object GroupBox1: TGroupBox
151+ Left = 0
152+ Top = 0
153+ Width = 392
154+ Height = 198
155+ Align = alClient
156+ Caption = #25407#20837#25991#23383#21015
157+ TabOrder = 0
158+ object TextMemo: TMemo
159+ Left = 2
160+ Top = 14
161+ Width = 388
162+ Height = 182
163+ Hint = #25407#20837#12377#12427#25991#23383#21015
164+ Align = alClient
165+ ScrollBars = ssBoth
166+ TabOrder = 0
167+ end
168+ end
169+ end
170+ end
171+ object ColumnImageList: TImageList
172+ Left = 312
173+ Top = 192
174+ Bitmap = {
175+ 494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
176+ 0000000000003600000028000000400000001000000001002000000000000010
177+ 0000000000000000000000000000000000000000000000000000000000000000
178+ 0000000000000000000000000000000000000000000000000000000000000000
179+ 0000000000000000000000000000000000000000000000000000000000000000
180+ 0000000000000000000000000000000000000000000000000000000000000000
181+ 0000000000000000000000000000000000000000000000000000000000000000
182+ 0000000000000000000000000000000000000000000000000000000000000000
183+ 0000000000000000000000000000000000000000000000000000000000000000
184+ 0000000000000000000000000000000000000000000000000000000000000000
185+ 0000000000000000000000000000000000000000000000000000000000000000
186+ 0000000000000000000000000000000000000000000000000000000000000000
187+ 0000000000000000000000000000000000000000000000000000000000000000
188+ 0000000000000000000000000000000000000000000000000000000000000000
189+ 0000000000000000000000000000000000000000000000000000000000000000
190+ 0000000000000000000000000000000000000000000000000000000000000000
191+ 0000000000000000000000000000000000000000000000000000000000000000
192+ 0000000000000000000000000000000000000000000000000000000000000000
193+ 0000000000000000000000000000000000000000000000000000000000000000
194+ 0000000000000000000000000000000000000000000000000000000000000000
195+ 0000000000000000000000000000000000000000000000000000000000000000
196+ 0000000000000000000000000000000000000000000000000000000000000000
197+ 0000000000000000000000000000000000000000000000000000000000000000
198+ 0000000000000000000000000000000000000000000000000000000000000000
199+ 0000000000000000000000000000000000000000000000000000000000000000
200+ 0000000000000000000000000000000000000000000000000000000000000000
201+ 0000000000000000000000000000000000000000000000000000000000000000
202+ 0000000000000000000000000000000000000000000000000000000000000000
203+ 0000000000000000000000000000000000000000000000000000000000000000
204+ 0000000000000000000000000000000000000000000000000000000000000000
205+ 0000000000000000000000000000000000000000000000000000000000000000
206+ 0000000000000000000000000000000000000000000000000000000000000000
207+ 0000000000000000000000000000000000000000000000000000000000000000
208+ 0000000000000000000000000000000000000000000000000000000000000000
209+ 000000000000000000000000000000000000000000000000000000000000FFFF
210+ FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
211+ 0000000000000000000000000000000000000000000000000000000000000000
212+ 0000000000000000000080808000FFFFFF000000000000000000000000000000
213+ 0000000000000000000000000000000000000000000000000000000000000000
214+ 0000000000000000000000000000000000000000000000000000000000000000
215+ 0000000000000000000000000000000000000000000000000000000000000000
216+ 0000000000000000000000000000000000000000000000000000000000000000
217+ 0000000000000000000000000000000000000000000000000000000000008080
218+ 80008080800000000000000000000000000000000000FFFFFF00FFFFFF000000
219+ 0000000000000000000000000000000000000000000000000000000000000000
220+ 0000000000008080800080808000FFFFFF00FFFFFF0000000000000000000000
221+ 0000000000000000000000000000000000000000000000000000000000000000
222+ 0000000000000000000000000000000000000000000000000000000000000000
223+ 0000000000000000000000000000000000000000000000000000000000000000
224+ 0000000000000000000000000000000000000000000000000000000000000000
225+ 0000000000000000000000000000000000000000000000000000000000000000
226+ 00008080800000000000000000000000000000000000FFFFFF00000000000000
227+ 0000000000000000000000000000000000000000000000000000000000000000
228+ 000000000000808080000000000000000000FFFFFF0000000000000000000000
229+ 0000000000000000000000000000000000000000000000000000000000000000
230+ 0000000000000000000000000000000000000000000000000000000000000000
231+ 0000000000000000000000000000000000000000000000000000000000000000
232+ 0000000000000000000000000000000000000000000000000000000000000000
233+ 0000000000000000000000000000000000000000000000000000000000000000
234+ 000080808000808080000000000000000000FFFFFF00FFFFFF00000000000000
235+ 0000000000000000000000000000000000000000000000000000000000000000
236+ 000080808000808080000000000000000000FFFFFF00FFFFFF00000000000000
237+ 0000000000000000000000000000000000000000000000000000000000000000
238+ 0000000000000000000000000000000000000000000000000000000000000000
239+ 0000000000000000000000000000000000000000000000000000000000000000
240+ 0000000000000000000000000000000000000000000000000000000000000000
241+ 0000000000000000000000000000000000000000000000000000000000000000
242+ 000000000000808080000000000000000000FFFFFF0000000000000000000000
243+ 0000000000000000000000000000000000000000000000000000000000000000
244+ 00008080800000000000000000000000000000000000FFFFFF00000000000000
245+ 0000000000000000000000000000000000000000000000000000000000000000
246+ 0000000000000000000000000000000000000000000000000000000000000000
247+ 0000000000000000000000000000000000000000000000000000000000000000
248+ 0000000000000000000000000000000000000000000000000000000000000000
249+ 0000000000000000000000000000000000000000000000000000000000000000
250+ 0000000000008080800080808000FFFFFF00FFFFFF0000000000000000000000
251+ 0000000000000000000000000000000000000000000000000000000000008080
252+ 80008080800000000000000000000000000000000000FFFFFF00FFFFFF000000
253+ 0000000000000000000000000000000000000000000000000000000000000000
254+ 0000000000000000000000000000000000000000000000000000000000000000
255+ 0000000000000000000000000000000000000000000000000000000000000000
256+ 0000000000000000000000000000000000000000000000000000000000000000
257+ 0000000000000000000000000000000000000000000000000000000000000000
258+ 0000000000000000000080808000FFFFFF000000000000000000000000000000
259+ 0000000000000000000000000000000000000000000000000000000000008080
260+ 8000808080008080800080808000808080008080800080808000808080000000
261+ 0000000000000000000000000000000000000000000000000000000000000000
262+ 0000000000000000000000000000000000000000000000000000000000000000
263+ 0000000000000000000000000000000000000000000000000000000000000000
264+ 0000000000000000000000000000000000000000000000000000000000000000
265+ 0000000000000000000000000000000000000000000000000000000000000000
266+ 0000000000000000000000000000000000000000000000000000000000000000
267+ 0000000000000000000000000000000000000000000000000000000000000000
268+ 0000000000000000000000000000000000000000000000000000000000000000
269+ 0000000000000000000000000000000000000000000000000000000000000000
270+ 0000000000000000000000000000000000000000000000000000000000000000
271+ 0000000000000000000000000000000000000000000000000000000000000000
272+ 0000000000000000000000000000000000000000000000000000000000000000
273+ 0000000000000000000000000000000000000000000000000000000000000000
274+ 0000000000000000000000000000000000000000000000000000000000000000
275+ 0000000000000000000000000000000000000000000000000000000000000000
276+ 0000000000000000000000000000000000000000000000000000000000000000
277+ 0000000000000000000000000000000000000000000000000000000000000000
278+ 0000000000000000000000000000000000000000000000000000000000000000
279+ 0000000000000000000000000000000000000000000000000000000000000000
280+ 0000000000000000000000000000000000000000000000000000000000000000
281+ 0000000000000000000000000000000000000000000000000000000000000000
282+ 0000000000000000000000000000000000000000000000000000000000000000
283+ 0000000000000000000000000000000000000000000000000000000000000000
284+ 0000000000000000000000000000000000000000000000000000000000000000
285+ 0000000000000000000000000000000000000000000000000000000000000000
286+ 0000000000000000000000000000000000000000000000000000000000000000
287+ 0000000000000000000000000000000000000000000000000000000000000000
288+ 0000000000000000000000000000000000000000000000000000000000000000
289+ 0000000000000000000000000000000000000000000000000000000000000000
290+ 0000000000000000000000000000000000000000000000000000000000000000
291+ 0000000000000000000000000000000000000000000000000000000000000000
292+ 0000000000000000000000000000000000000000000000000000000000000000
293+ 0000000000000000000000000000000000000000000000000000000000000000
294+ 0000000000000000000000000000000000000000000000000000000000000000
295+ 0000000000000000000000000000000000000000000000000000000000000000
296+ 0000000000000000000000000000000000000000000000000000000000000000
297+ 0000000000000000000000000000000000000000000000000000000000000000
298+ 0000000000000000000000000000000000000000000000000000000000000000
299+ 0000000000000000000000000000000000000000000000000000000000000000
300+ 0000000000000000000000000000000000000000000000000000000000000000
301+ 0000000000000000000000000000000000000000000000000000000000000000
302+ 0000000000000000000000000000000000000000000000000000000000000000
303+ 0000000000000000000000000000000000000000000000000000000000000000
304+ 0000000000000000000000000000000000000000000000000000000000000000
305+ 000000000000000000000000000000000000424D3E000000000000003E000000
306+ 2800000040000000100000000100010000000000800000000000000000000000
307+ 000000000000000000000000FFFFFF00FFFFFFFF00000000FFFFFFFF00000000
308+ FFFFFFFF00000000FFFFFFFF00000000E01FFCFF00000000E79FF87F00000000
309+ F7BFFB7F00000000F33FF33F00000000FB7FF7BF00000000F87FE79F00000000
310+ FCFFE01F00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000
311+ FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000
312+ 000000000000}
313+ end
314+ object InputAssistFormActionList: TActionList
315+ Left = 360
316+ Top = 192
317+ object EditCut1: TEditCut
318+ Category = #32232#38598
319+ Caption = #20999#12426#21462#12426'(&T)'
320+ Hint = #20999#12426#21462#12426'|'#36984#25246#37096#20998#12434#20999#12426#21462#12426#12289#12463#12522#12483#12503#12508#12540#12489#12395#36865#12427
321+ ImageIndex = 0
322+ ShortCut = 16472
323+ end
324+ object EditCopy1: TEditCopy
325+ Category = #32232#38598
326+ Caption = #12467#12500#12540'(&C)'
327+ Hint = #12467#12500#12540'|'#36984#25246#37096#20998#12434#12467#12500#12540#12375#12289#12463#12522#12483#12503#12508#12540#12489#12395#36865#12427
328+ ImageIndex = 1
329+ ShortCut = 16451
330+ end
331+ object EditPaste1: TEditPaste
332+ Category = #32232#38598
333+ Caption = #36028#12426#20184#12369'(&P)'
334+ Hint = #36028#12426#20184#12369'|'#12463#12522#12483#12503#12508#12540#12489#12398#20869#23481#12434#36028#12426#20184#12369#12427
335+ ImageIndex = 2
336+ ShortCut = 16470
337+ end
338+ object EditSelectAll1: TEditSelectAll
339+ Category = #32232#38598
340+ Caption = #12377#12409#12390#12434#36984#25246'(&A)'
341+ Hint = #12377#12409#12390#12434#36984#25246'|'#12489#12461#12517#12513#12531#12488#20840#20307#12434#36984#25246#12377#12427
342+ ShortCut = 16449
343+ end
344+ object EditUndo1: TEditUndo
345+ Category = #32232#38598
346+ Caption = #20803#12395#25147#12377'(&U)'
347+ Hint = #20803#12395#25147#12377'|'#30452#21069#12398#22793#26356#12434#20803#12395#25147#12377
348+ ImageIndex = 3
349+ ShortCut = 16474
350+ end
351+ object EditDelete1: TEditDelete
352+ Category = #32232#38598
353+ Caption = #21066#38500'(&D)'
354+ Hint = #21066#38500'|'#36984#25246#37096#20998#12434#21066#38500#12377#12427
355+ ImageIndex = 5
356+ ShortCut = 46
357+ end
358+ end
359+end
--- /dev/null
+++ b/InputAssist.pas
@@ -0,0 +1,217 @@
1+unit InputAssist;
2+
3+interface
4+
5+uses
6+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7+ Dialogs, StdCtrls, ComCtrls, GikoListView, Menus, ExtCtrls, ImgList,
8+ InputAssistDataModule, StdActns, ActnList;
9+
10+type
11+ TInputAssistForm = class(TForm)
12+ Panel1: TPanel;
13+ Panel2: TPanel;
14+ GikoListView1: TGikoListView;
15+ Panel3: TPanel;
16+ KeyNameEdit: TLabeledEdit;
17+ CategoryNameEdit: TLabeledEdit;
18+ Panel4: TPanel;
19+ TextMemo: TMemo;
20+ ColumnImageList: TImageList;
21+ InputAssistFormActionList: TActionList;
22+ EditCut1: TEditCut;
23+ EditCopy1: TEditCopy;
24+ EditPaste1: TEditPaste;
25+ EditSelectAll1: TEditSelectAll;
26+ EditUndo1: TEditUndo;
27+ EditDelete1: TEditDelete;
28+ GroupBox1: TGroupBox;
29+ Panel5: TPanel;
30+ CloseButton: TButton;
31+ ApplyButton: TButton;
32+ DeleteButton: TButton;
33+ AddButton: TButton;
34+ Panel6: TPanel;
35+ procedure FormCreate(Sender: TObject);
36+ procedure GikoListView1SelectItem(Sender: TObject; Item: TListItem;
37+ Selected: Boolean);
38+ procedure AddButtonClick(Sender: TObject);
39+ procedure DeleteButtonClick(Sender: TObject);
40+ procedure ApplyButtonClick(Sender: TObject);
41+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
42+ procedure GikoListView1Compare(Sender: TObject; Item1,
43+ Item2: TListItem; Data: Integer; var Compare: Integer);
44+ procedure GikoListView1ColumnClick(Sender: TObject;
45+ Column: TListColumn);
46+ procedure CloseButtonClick(Sender: TObject);
47+ private
48+ { Private 宣言 }
49+ FSortColumn : Integer;
50+ procedure AddListViewItem(ResWord : TResistWord);
51+ public
52+ { Public 宣言 }
53+ end;
54+
55+var
56+ InputAssistForm: TInputAssistForm;
57+
58+implementation
59+
60+
61+{$R *.dfm}
62+//! フォーム生成のイベント
63+procedure TInputAssistForm.FormCreate(Sender: TObject);
64+var
65+ i : Integer;
66+ column: TListColumn;
67+begin
68+ FSortColumn := 0;
69+ GikoListView1.Columns.Clear;
70+ column := GikoListView1.Columns.Add;
71+ column.ImageIndex := 0;
72+ column.Caption := 'キー';
73+ column.Width := 150;
74+ column := GikoListView1.Columns.Add;
75+ column.Caption := 'カテゴリ';
76+ column.Width := 80;
77+ for i := 0 to InputAssistDM.ResistWordCount - 1 do begin
78+ AddListViewItem(InputAssistDM.GetResistWord(i));
79+ end;
80+ //ソート状態を解除 (解除しないとアイテムのキー名を変更できない)
81+ InputAssistDM.Sorted := False;
82+end;
83+//! 一覧にアイテムを追加する処理
84+procedure TInputAssistForm.AddListViewItem(ResWord : TResistWord);
85+var
86+ item: TListItem;
87+begin
88+ item := GikoListView1.Items.Add;
89+ item.ImageIndex := -1;
90+ item.Caption := resWord.GetKey;
91+ item.SubItems.Add(resWord.GetCategory);
92+ item.Data := resWord;
93+end;
94+//! 登録単語一覧からアイテムを選択したときのイベント
95+procedure TInputAssistForm.GikoListView1SelectItem(Sender: TObject;
96+ Item: TListItem; Selected: Boolean);
97+begin
98+ if (Item <> nil) and (Item.Data <> nil) then begin
99+ KeyNameEdit.Text := TResistWord(Item.Data).GetKey;
100+ CategoryNameEdit.Text := TResistWord(Item.Data).GetCategory;
101+ TextMemo.Lines.Text := TResistWord(Item.Data).GetText;
102+ end else begin
103+ TextMemo.Lines.Text := '';
104+ end;
105+end;
106+//! 追加ボタン押下時のイベント
107+procedure TInputAssistForm.AddButtonClick(Sender: TObject);
108+var
109+ resWord : TResistWord;
110+begin
111+ if (Length(KeyNameEdit.Text) = 0) then begin
112+ ShowMessage('キー名を設定してください。');
113+ end else begin
114+ resWord := InputAssistDM.Add(KeyNameEdit.Text);
115+ resWord.SetCategory(CategoryNameEdit.Text);
116+ resWord.SetText(TextMemo.Text);
117+ AddListViewItem(resWord);
118+ GikoListView1.AlphaSort;
119+ end;
120+end;
121+//! 削除ボタン押下時のイベント
122+procedure TInputAssistForm.DeleteButtonClick(Sender: TObject);
123+begin
124+ if GikoListView1.Selected <> nil then begin
125+ InputAssistDM.DeleteResistWord(GikoListView1.Selected.Data);
126+ GikoListView1.Selected.Data := nil;
127+ GikoListView1.DeleteSelected;
128+ end;
129+end;
130+//! 適用ボタン押下時のイベント
131+procedure TInputAssistForm.ApplyButtonClick(Sender: TObject);
132+var
133+ resWord : TResistWord;
134+begin
135+ if GikoListView1.Selected <> nil then begin
136+ if (Length(KeyNameEdit.Text) = 0) then begin
137+ ShowMessage('キー名を無しにはできません。');
138+ end else begin
139+ resWord := TResistWord(GikoListView1.Selected.Data);
140+ resWord.SetKey(KeyNameEdit.Text);
141+ resWord.SetCategory(CategoryNameEdit.Text);
142+ resWord.SetText(TextMemo.Text);
143+ // 一覧の更新
144+ GikoListView1.Selected.Caption := resWord.GetKey;
145+ GikoListView1.Selected.SubItems[0] := resWord.GetCategory;
146+ GikoListView1.AlphaSort;
147+ end;
148+ end;
149+end;
150+//! フォームを閉じるときのイベント
151+procedure TInputAssistForm.FormClose(Sender: TObject;
152+ var Action: TCloseAction);
153+begin
154+ //ソート状態の設定
155+ InputAssistDM.Sorted := True;
156+end;
157+//! 登録単語一覧のソート用の比較処理
158+procedure TInputAssistForm.GikoListView1Compare(Sender: TObject; Item1,
159+ Item2: TListItem; Data: Integer; var Compare: Integer);
160+begin
161+ if ((FSortColumn and 2) > 0) then begin
162+ // カテゴリでソート
163+ Compare := AnsiCompareStr(Item1.SubItems[0], Item2.SubItems[0]);
164+ if (Compare = 0) then begin
165+ Compare := AnsiCompareStr(Item1.Caption, Item2.Caption);
166+ end;
167+ end else begin
168+ // キーでソート
169+ Compare := AnsiCompareStr(Item1.Caption, Item2.Caption);
170+ if (Compare = 0) then begin
171+ Compare := AnsiCompareStr(Item1.SubItems[0], Item2.SubItems[0]);
172+ end;
173+ end;
174+ // 昇順降順の反転
175+ if ((FSortColumn and 1) > 0) then begin
176+ Compare := Compare * -1;
177+ end;
178+ ;
179+end;
180+//! 登録単語一覧のリストのカラムクリックイベント
181+procedure TInputAssistForm.GikoListView1ColumnClick(Sender: TObject;
182+ Column: TListColumn);
183+var
184+ i : Integer;
185+begin
186+ if Column <> nil then begin
187+ // イメージの削除
188+ for i := 0 to GikoListView1.Columns.Count - 1 do begin
189+ GikoListView1.Column[i].ImageIndex := -1;
190+ end;
191+
192+ // FSortColumn 偶数:昇順 奇数:降順
193+ if Column.Caption = 'キー' then begin
194+ if FSortColumn = 0 then begin
195+ FSortColumn := 1;
196+ end else begin
197+ FSortColumn := 0;
198+ end;
199+ end else begin
200+ if FSortColumn = 2 then begin
201+ FSortColumn := 3;
202+ end else begin
203+ FSortColumn := 2;
204+ end;
205+ end;
206+ Column.ImageIndex := (FSortColumn and 1);
207+ GikoListView1.AlphaSort;
208+ end;
209+
210+end;
211+//! 終了ボタンを押下時のイベント
212+procedure TInputAssistForm.CloseButtonClick(Sender: TObject);
213+begin
214+ Close();
215+end;
216+
217+end.
--- /dev/null
+++ b/InputAssistDataModule.dfm
@@ -0,0 +1,9 @@
1+object InputAssistDM: TInputAssistDM
2+ OldCreateOrder = False
3+ OnCreate = DataModuleCreate
4+ OnDestroy = DataModuleDestroy
5+ Left = 582
6+ Top = 174
7+ Height = 150
8+ Width = 215
9+end
--- /dev/null
+++ b/InputAssistDataModule.pas
@@ -0,0 +1,329 @@
1+unit InputAssistDataModule;
2+
3+interface
4+
5+uses
6+ SysUtils, Classes;
7+
8+type
9+ TResistWord = class;
10+
11+ TInputAssistDM = class(TDataModule)
12+ procedure DataModuleDestroy(Sender: TObject);
13+ procedure DataModuleCreate(Sender: TObject);
14+ private
15+ { Private 宣言 }
16+ FInit : Boolean;
17+ FDictionary : TStringList; ///< 登録単語と定型文の辞書
18+ function GetSorted: Boolean; ///< ソートの状態の取得
19+ procedure SetSorted(Value: Boolean); ///< ソート状態の設定
20+
21+ public
22+ { Public 宣言 }
23+ property Sorted : Boolean read GetSorted write SetSorted;
24+ procedure Init(FilePath: String);
25+ procedure SaveToFile(FilePath: String);
26+ function ResistWordCount : Integer; ///<登録単語数取得
27+ function GetResistWord(Index: Integer): TResistWord; ///< 登録単語取得
28+ procedure DeleteResistWord(ResistWord: TResistWord); ///< 登録単語の削除
29+ function Add(Key: String): TResistWord; ///< 登録単語追加
30+ procedure ChangeKey(ResistWord: TResistWord); ///< 登録単語のキー変更
31+ //! Keyをキーに持つ登録されている単語を取得
32+ function GetStartWithKeyResistWords(Key: String; var list: TStringList): Integer;
33+ //! Keyをカテゴリに持つ登録されている単語を取得
34+ function GetStartWithCategoryResistWords(Key: String; var list: TStringList): Integer;
35+ end;
36+
37+ TResistWord = class(TObject)
38+ private
39+ FKey : String; ///< 変換時のキーになる
40+ FCategory : String; ///< 分類
41+ FText : String; ///< 定型文
42+ public
43+ function GetKey: String;
44+ procedure SetKey(Value: String);
45+ function GetCategory: String;
46+ procedure SetCategory(Value: String);
47+ function GetText: String;
48+ procedure SetText(Value: String);
49+ property Key: String read FKey write FKey;
50+ property Category: String read FCategory write FCategory;
51+ property Text: String read GetText write SetText;
52+ end;
53+
54+ function CategorySort(List: TStringList; Index1, Index2: Integer): Integer;
55+var
56+ InputAssistDM: TInputAssistDM;
57+
58+implementation
59+
60+uses
61+ MojuUtils, IniFiles;
62+
63+{$R *.dfm}
64+//! FKeyに設定されている値を取得する
65+function TResistWord.GetKey: String;
66+begin
67+ //エスケープしている=を復元する
68+ Result := MojuUtils.CustomStringReplace(FKey, '&#61;', '=');
69+end;
70+//! FKeyに値を設定する
71+procedure TResistWord.SetKey(Value: String);
72+begin
73+ //=は保存時に使うのでエスケープする
74+ FKey := MojuUtils.CustomStringReplace(Value, '=', '&#61;');
75+end;
76+//! FCategoryに設定されている値を取得する
77+function TResistWord.GetCategory: String;
78+begin
79+ //エスケープしている=を復元する
80+ Result := MojuUtils.CustomStringReplace(FCategory, '&#61;', '=');
81+end;
82+//! FCategoryに値を設定する
83+procedure TResistWord.SetCategory(Value: String);
84+begin
85+ //=は保存時に使うのでエスケープする
86+ FCategory := MojuUtils.CustomStringReplace(Value, '=', '&#61;');
87+end;
88+//! FTextに設定されている値を取得する
89+function TResistWord.GetText: String;
90+begin
91+ //エスケープしている=を復元する
92+ Result := MojuUtils.CustomStringReplace(FText, '&#61;', '=');
93+ // #1にした改行コードを#13#10に復元する
94+ Result := MojuUtils.CustomStringReplace(Result, #1, #13#10);
95+end;
96+procedure TResistWord.SetText(Value: String);
97+begin
98+ //=は保存時に使うのでエスケープする
99+ FText := MojuUtils.CustomStringReplace(Value, '=', '&#61;');
100+ //改行コードを#1にする(1行にするため)
101+ FText := MojuUtils.CustomStringReplace(FText, #13#10, #1);
102+end;
103+//! ファイルを読み込んで初期化する
104+procedure TInputAssistDM.Init(FilePath: String);
105+var
106+ ini : TMemIniFile;
107+ sections: TStringList;
108+ keys: TStringList;
109+ i, j : Integer;
110+ resWord : TResistWord;
111+begin
112+ FInit := True;
113+ try
114+ // ファイルの存在を確認
115+ if FileExists(FilePath) then begin
116+ ini := TMemIniFile.Create(FilePath);
117+ sections := TStringList.Create;
118+ keys := TStringList.Create;
119+ try
120+ ini.ReadSections(sections);
121+
122+ for i :=0 to sections.Count - 1 do begin
123+ keys.Clear;
124+ ini.ReadSection(sections[i], keys);
125+ for j := 0 to keys.Count - 1 do begin
126+ resWord := TResistWord.Create;
127+ resWord.SetCategory(sections[i]);
128+ resWord.SetKey(keys[j]);
129+ resWord.SetText(ini.ReadString(sections[i], keys[j], ''));
130+ FDictionary.AddObject(resWord.GetKey, resWord);
131+ end;
132+ end;
133+ finally
134+ keys.Free;
135+ sections.Free;
136+ ini.Free;
137+ end;
138+ end;
139+
140+ except
141+ FInit := False;
142+ end;
143+end;
144+//! 指定されたパスのファイルに保存する
145+procedure TInputAssistDM.SaveToFile(FilePath: String);
146+var
147+ ini : TMemIniFile;
148+ i : Integer;
149+ resWord : TResistWord;
150+begin
151+ if FileExists(FilePath) then begin
152+ try
153+ DeleteFile(FilePath);
154+ except
155+ end;
156+ end;
157+ ini := TMemIniFile.Create(FilePath);
158+ try
159+ for i :=0 to FDictionary.Count - 1 do begin
160+ resWord := TResistWord(FDictionary.Objects[i]);
161+ ini.WriteString(resWord.FCategory, resWord.FKey, resWord.FText);
162+ end;
163+ ini.UpdateFile;
164+ finally
165+ ini.Free;
166+ end;
167+end;
168+//! デストラクタ
169+procedure TInputAssistDM.DataModuleDestroy(Sender: TObject);
170+var
171+ i : Integer;
172+begin
173+ if (FDictionary <> nil) then begin
174+ for i := FDictionary.Count - 1 downto 0 do begin
175+ TResistWord(FDictionary.Objects[i]).Free;
176+ end;
177+ FDictionary.Clear;
178+ FDictionary.Capacity := 0;
179+ FDictionary.Free;
180+ end;
181+end;
182+//! コンストラクタ
183+procedure TInputAssistDM.DataModuleCreate(Sender: TObject);
184+begin
185+ FDictionary := TStringList.Create;
186+ FDictionary.Duplicates := dupAccept;
187+ FDictionary.Sorted := True;
188+end;
189+//! 登録単語数取得
190+function TInputAssistDM.ResistWordCount : Integer;
191+begin
192+ Result := 0;
193+ if (FDictionary <> nil) then begin
194+ Result := FDictionary.Count;
195+ end;
196+end;
197+//! 登録単語取得
198+function TInputAssistDM.GetResistWord(Index: Integer): TResistWord;
199+begin
200+ Result := nil;
201+ if (FDictionary <> nil) then begin
202+ if (Index >= 0) and (Index < FDictionary.Count) then begin
203+ Result := TResistWord(FDictionary.Objects[index]);
204+ end;
205+ end;
206+end;
207+//! 登録単語の削除
208+procedure TInputAssistDM.DeleteResistWord(ResistWord: TResistWord);
209+var
210+ i : Integer;
211+begin
212+ if (FDictionary <> nil) then begin
213+ for i := 0 to FDictionary.Count - 1 do begin
214+ if (ResistWord = FDictionary.Objects[i]) then begin
215+ TResistWord(FDictionary.Objects[i]).Free;
216+ FDictionary.Delete(i);
217+ break;
218+ end;
219+ end;
220+ end;
221+end;
222+//! 登録単語追加
223+function TInputAssistDM.Add(Key: String): TResistWord;
224+var
225+ resWord : TResistWord;
226+begin
227+ Result := nil;
228+ if (FDictionary <> nil) then begin
229+ resWord := TResistWord.Create;
230+ resWord.SetKey(Key);
231+ resWord.SetCategory('カテゴリ');
232+ resWord.SetText('定型文');
233+ FDictionary.AddObject(Key, resWord);
234+ Result := resWord;
235+ end;
236+end;
237+//! 登録単語のキー変更
238+procedure TInputAssistDM.ChangeKey(ResistWord: TResistWord);
239+var
240+ i : Integer;
241+begin
242+ if (FDictionary <> nil) then begin
243+ for i := 0 to FDictionary.Count - 1 do begin
244+ if (ResistWord = FDictionary.Objects[i]) then begin
245+ FDictionary.Strings[i] := ResistWord.GetKey;
246+ break;
247+ end;
248+ end;
249+ end;
250+end;
251+//! Keyを持つ登録されている単語を取得
252+function TInputAssistDM.GetStartWithKeyResistWords(Key: String; var list: TStringList): Integer;
253+var
254+ i : Integer;
255+ resWord : TResistWord;
256+
257+begin
258+ Result := 0;
259+ if (FDictionary <> nil) and (list <> nil) then begin
260+ Key := ZenToHan(Key);
261+ for i := 0 to FDictionary.Count - 1 do begin
262+ if (AnsiPos(Key, ZenToHan(FDictionary.Strings[i])) = 1) then begin
263+ Inc(Result);
264+ resWord := TResistWord(FDictionary.Objects[i]);
265+ list.AddObject(resWord.GetKey + '(' +
266+ resWord.GetCategory + ')', resWord);
267+ end else if (Result > 0) then begin
268+ //ソートされているから、ヒットすれば連続するはず
269+ break;
270+ end;
271+ end;
272+ end;
273+end;
274+//! Keyをカテゴリに持つ登録されている単語を取得
275+function TInputAssistDM.GetStartWithCategoryResistWords(Key: String; var list: TStringList): Integer;
276+var
277+ i : Integer;
278+ resWord : TResistWord;
279+begin
280+ Result := 0;
281+ if (FDictionary <> nil) and (list <> nil) then begin
282+ Key := ZenToHan(Key);
283+ for i := 0 to FDictionary.Count - 1 do begin
284+ resWord := TResistWord(FDictionary.Objects[i]);
285+ if (AnsiPos(Key, ZenToHan(resWord.GetCategory)) = 1) then begin
286+ Inc(Result);
287+ list.AddObject(resWord.GetKey + '(' +
288+ resWord.GetCategory + ')', resWord);
289+ end;
290+ end;
291+ list.CustomSort(CategorySort);
292+ end;
293+end;
294+
295+//! ソートの状態の取得
296+function TInputAssistDM.GetSorted: Boolean;
297+begin
298+ Result := False;
299+ if (FDictionary <> nil) then begin
300+ Result := FDictionary.Sorted;
301+ end;
302+end;
303+//! ソート状態の設定
304+procedure TInputAssistDM.SetSorted(Value: Boolean);
305+begin
306+ if (FDictionary <> nil) then begin
307+ FDictionary.Sorted := Value;
308+ end;
309+end;
310+
311+//! Keyをカテゴリに持つ登録単語を返す時のソート用比較メソッド
312+function CategorySort(List: TStringList; Index1, Index2: Integer): Integer;
313+var
314+ resWord1 : TResistWord;
315+ resWord2 : TResistWord;
316+begin
317+ Result := 0;
318+ try
319+ resWord1 := TResistWord(List.Objects[Index1]);
320+ resWord2 := TResistWord(List.Objects[Index2]);
321+ Result := AnsiCompareStr(resWord1.GetCategory, resWord2.GetCategory);
322+ if (Result = 0) then begin
323+ Result := AnsiCompareStr(resWord1.GetKey, resWord2.GetKey);
324+ end;
325+ except
326+ end;
327+end;
328+
329+end.
--- a/KeySetting.pas
+++ b/KeySetting.pas
@@ -111,7 +111,6 @@ begin
111111 if ListView.Items.Count > 0 then
112112 ListView.Selected := ListView.Items[0];
113113 EditorForm := TEditorForm.Create(Self);
114- GikoSys.LoadKeySetting(EditorForm.ActionList, GikoSys.GetEditorKeyFileName);
115114 try
116115 for i := 0 to EditorForm.ActionList.ActionCount - 1 do begin
117116 if EditorForm.ActionList.Actions[i] is TAction then begin
--- a/ListViewUtils.pas
+++ b/ListViewUtils.pas
@@ -10,6 +10,7 @@ type
1010 TListViewUtils = class(TObject)
1111 private
1212 {Private 宣言}
13+
1314 class procedure DrawCategoryItem(BBS: TBBS; Item: TListItem; ListView: TListView);
1415 class procedure DrawBoardItem(Category: TCategory; Item: TListItem; ListView: TListView);
1516 class procedure DrawThreadItem(Board: TBoard; Item: TListItem; ListView: TListView);
@@ -30,11 +31,10 @@ type
3031 class procedure ListViewData(Sender: TObject; Item: TListItem);
3132 end;
3233
33-
3434 implementation
3535
3636 uses
37- GikoSystem, Sort, Setting, Giko, MojuUtils, GikoDataModule;
37+ GikoSystem, Sort, Setting, Giko, MojuUtils, GikoDataModule, DateUtils, Math;
3838
3939 const
4040 //ツリー・リストアイコン
@@ -612,6 +612,7 @@ end;
612612 class procedure TListViewUtils.DrawItemLogThread(Thread: TThreadItem; Item: TListItem; ColumnCount: Integer);
613613 var
614614 i, idx : Integer;
615+ spanday: Double;
615616 begin
616617 idx := 0;
617618 for i := 0 to ColumnCount - 1 do begin
@@ -655,6 +656,16 @@ begin
655656 Item.SubItems[ idx ] := '';
656657 end else
657658 Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', Thread.LastModified);
659+ gbcVigor:
660+ begin
661+ spanday := DaySpan(Sort.GetSortDate, Thread.CreateDate);
662+ if (spanday > 0) then begin
663+ Item.SubItems[ idx ] := Format('%f', [Thread.AllResCount / spanday]);
664+ end else begin
665+ Item.SubItems[ idx ] := '';
666+ end;
667+
668+ end;
658669 end;
659670 Inc( idx );
660671 end;
@@ -668,6 +679,7 @@ end;
668679 class procedure TListViewUtils.DrawItemNoLogThread(Thread: TThreadItem; Item: TListItem; ColumnCount: Integer);
669680 var
670681 i, idx: Integer;
682+ spanday: Double;
671683 begin
672684 idx := 0;
673685 for i := 0 to ColumnCount - 1do begin
@@ -686,9 +698,20 @@ begin
686698 Item.SubItems[ idx ] := FormatDateTime('yyyy/mm/dd hh:mm:ss', Thread.CreateDate);
687699 gbcLastModified:
688700 Item.SubItems[ idx ] := '';
701+ gbcVigor:
702+ begin
703+ spanday := DaySpan(Sort.GetSortDate, Thread.CreateDate);
704+ if (spanday > 0) then begin
705+ Item.SubItems[ idx ] := Format('%f', [Thread.AllResCount / spanday]);
706+ end else begin
707+ Item.SubItems[ idx ] := '';
708+ end;
709+
710+ end;
689711 else
690712 Item.SubItems[ idx ] := '';
691713 end;
714+
692715 Inc( idx );
693716 end;
694717 if Thread.NewArrival then
--- a/MojuUtils.pas
+++ b/MojuUtils.pas
@@ -32,6 +32,10 @@ uses
3232 //<font>タグを全て削除する
3333 function DeleteFontTag( inSource : string) : string;
3434 function RemoveToken(var s: string;const delimiter: string): string;
35+ // 無害化(& -> &amp; " -> &auot; に変換する)
36+ function Sanitize(const s: String): String;
37+ // 無害化解除(&amp; -> & &auot; -> " に変換する)
38+ function UnSanitize(const s: String): String;
3539
3640 implementation
3741 // ポインター&アセンブラによる高速ポス
@@ -358,6 +362,17 @@ begin
358362 s := '';
359363 end;
360364 end;
361-
365+//! 無害化(& -> &amp; " -> &auot; に変換する)
366+function Sanitize(const s: String): String;
367+begin
368+ Result := CustomStringReplace(s, '&', '&amp;');
369+ Result := CustomStringReplace(Result, '"', '&quot;');
370+end;
371+//! 無害化解除(&amp; -> & &auot; -> " に変換する)
372+function UnSanitize(const s: String): String;
373+begin
374+ Result := CustomStringReplace(s, '&quot;', '"');
375+ Result := CustomStringReplace(Result, '&amp;', '&');
376+end;
362377
363378 end.
--- a/Setting.pas
+++ b/Setting.pas
@@ -73,15 +73,15 @@ type
7373 end;
7474 /// スレリストのカラム ID
7575 type TGikoBoardColumnID = (gbcTitle, gbcAllCount, gbcLocalCount, gbcNonAcqCount,
76- gbcNewCount, gbcUnReadCount, gbcRoundName, gbcRoundDate, gbcCreated, gbcLastModified );{gbcLastModified,}
76+ gbcNewCount, gbcUnReadCount, gbcRoundName, gbcRoundDate, gbcCreated, gbcLastModified, gbcVigor );{gbcLastModified,}
7777 /// スレリストのカラム名
78- const GikoBoardColumnCaption : array[0..9] of string =
78+ const GikoBoardColumnCaption : array[0..10] of string =
7979 ( 'スレッド名', 'カウント', '取得', '未取得', '新着',
80- '未読', '巡回予約', '取得日時', 'スレ作成日時', '最終更新日時' );
81- const GikoBoardColumnAlignment : array[0..9] of TAlignment = (
80+ '未読', '巡回予約', '取得日時', 'スレ作成日時', '最終更新日時', '勢い' );
81+ const GikoBoardColumnAlignment : array[0..10] of TAlignment = (
8282 taLeftJustify, taRightJustify, taRightJustify, taRightJustify,
8383 taRightJustify, taRightJustify, taLeftJustify, taLeftJustify,
84- taLeftJustify, taLeftJustify);
84+ taLeftJustify, taLeftJustify, taRightJustify);
8585 /// スレリストカラム配列
8686 type TGikoBoardColumnList = class( TList )
8787 private
@@ -259,7 +259,7 @@ type
259259 //リストカラムヘッダーサイズ
260260 FBBSColumnWidth: array[0..0] of Integer;
261261 FCategoryColumnWidth: array[0..2] of Integer;
262- FBoardColumnWidth: array[0..9] of Integer;
262+ FBoardColumnWidth: array[0..10] of Integer;
263263
264264 /// カテゴリリストカラム順序
265265 FBBSColumnOrder : TGikoBBSColumnList;
@@ -491,7 +491,7 @@ type
491491 function GetMainKeyFileName: String;
492492 function GetEditorKeyFileName: String;
493493 procedure WriteLogFolder(AVal : String);
494-
494+ function GetInputAssistFileName : String;
495495 //受信バッファサイズ
496496 property RecvBufferSize: Integer read FRecvBufferSize write FRecvBufferSize;
497497 //HTTP1.1使用
@@ -772,7 +772,8 @@ const
772772 MAX_POPUP_RES : Integer = 10;
773773 GESTURE_FILE_NAME = 'Gestures.ini';
774774 SPAMFILTER_FILE_NAME = 'SpamFilter.ini';
775- LANGUAGE_FILE_NAME = 'language.ini';
775+ LANGUAGE_FILE_NAME = 'language.ini';
776+ INPUTASSIST_FILE_NAME = 'InputAssist.ini';
776777
777778
778779
@@ -935,7 +936,7 @@ procedure TSetting.ReadSettingFile();
935936 const
936937 DEFAULT_BBS_WIDTH: array[0..0] of Integer = (140);
937938 DEFAULT_CATEGORY_WIDTH: array[0..2] of Integer = (150, 80, 130);
938- DEFAULT_BOARD_WIDTH: array[0..9] of Integer = (350, 60, 60, 60, 60, 60, 80, 130, 130, 130);
939+ DEFAULT_BOARD_WIDTH: array[0..10] of Integer = (350, 60, 60, 60, 60, 60, 80, 130, 130, 130, 60);
939940 MAX_WIDTH: Integer = 2000;
940941 var
941942 ini: TMemIniFile;
@@ -1164,8 +1165,12 @@ begin
11641165 end;
11651166 if FBoardColumnOrder.Count = 0 then begin
11661167 // 設定が無いので作成
1167- for i := 0 to Integer( High( TGikoBoardColumnID ) ) do
1168- FBoardColumnOrder.Add( TGikoBoardColumnID( i ) );
1168+ for i := 0 to Integer( High( TGikoBoardColumnID ) ) do begin
1169+ // 勢いのカラムはデフォルトで非表示にする
1170+ if ( i <> Ord(gbcVigor) ) then begin
1171+ FBoardColumnOrder.Add( TGikoBoardColumnID( i ) );
1172+ end;
1173+ end;
11691174 end;
11701175 finally
11711176 wkList.Free;
@@ -2175,8 +2180,13 @@ begin
21752180 end;
21762181 function TSetting.GetEditorKeyFileName: String;
21772182 begin
2178- Result := GetConfigDir + EKEY_SETTING_FILE_NAME;
2183+ Result := GetConfigDir + EKEY_SETTING_FILE_NAME;
2184+end;
2185+function TSetting.GetInputAssistFileName : String;
2186+begin
2187+ Result := GetConfigDir + INPUTASSIST_FILE_NAME;
21792188 end;
2189+
21802190 end.
21812191
21822192
--- a/Sort.pas
+++ b/Sort.pas
@@ -4,7 +4,7 @@ interface
44 uses
55 Windows, Messages, SysUtils, Classes, Controls, Forms,
66 BoardGroup,DateUtils,
7- Setting;
7+ Setting, Math;
88
99 function CategorySortProc(Item1, Item2: Pointer): integer;
1010 function BoardSortProc(List: TStringList; Item1, Item2: Integer): integer;
@@ -12,13 +12,16 @@ uses
1212 function CompareBool(Item1, Item2: Boolean): integer;
1313 function CompareInt(Item1, Item2: Integer): Integer;
1414 function CompareDate(Item1, Item2: TDateTime): Integer;
15-
15+ procedure SetSortDate(Date: TDateTime);
16+ function GetSortDate(): TDateTime;
1617 var
1718 SortOrder: Boolean;
1819 SortIndex: Integer;
1920 SortNoFlag: Boolean;
2021
2122 implementation
23+var
24+ FSortDate: TDateTime;
2225
2326 function CategorySortProc(Item1, Item2: Pointer): integer;
2427 var
@@ -73,6 +76,7 @@ function ThreadItemSortProc(List: TStringList; Item1, Item2: Integer): integer;
7376 var
7477 ThreadItem1: TThreadItem;
7578 ThreadItem2: TThreadItem;
79+ SpanDay1, SpanDay2: Double;
7680 begin
7781 ThreadItem1 := TThreadItem(List.Objects[ Item1 ]);
7882 ThreadItem2 := TThreadItem(List.Objects[ Item2 ]);
@@ -105,6 +109,22 @@ begin
105109 gbcRoundDate: Result := CompareDateTime(ThreadItem1.RoundDate, ThreadItem2.RoundDate); {gbcLastModified:}
106110 gbcCreated: Result := CompareDateTime(ThreadItem1.CreateDate, ThreadItem2.CreateDate);
107111 gbcLastModified: Result := CompareDateTime(ThreadItem1.LastModified, ThreadItem2.LastModified); {gbcLastModified:}
112+ gbcVigor:
113+ begin
114+ SpanDay1 := DaySpan(FSortDate, ThreadItem1.CreateDate);
115+ SpanDay2 := DaySpan(FSortDate, ThreadItem2.CreateDate);
116+ if (SpanDay1 > 0) and (SpanDay2 > 0) then begin
117+ Result := CompareValue(
118+ ThreadItem1.AllResCount / SpanDay1,
119+ ThreadItem2.AllResCount / SpanDay2);
120+ end else if (SpanDay1 > 0) then begin
121+ Result := 1;
122+ end else if (SpanDay2 > 0) then begin
123+ Result := -1;
124+ end else begin
125+ Result := 0;
126+ end;
127+ end;
108128 else
109129 Result := 0;
110130 end;
@@ -163,5 +183,12 @@ begin
163183 else
164184 Result := 0;
165185 end;
166-
186+procedure SetSortDate(Date: TDateTime);
187+begin
188+ FSortDate := Date;
189+end;
190+function GetSortDate(): TDateTime;
191+begin
192+ Result := FSortDate;
193+end;
167194 end.
--- a/gikoNavi.dpr
+++ b/gikoNavi.dpr
@@ -71,7 +71,9 @@ uses
7171 ListViewUtils in 'ListViewUtils.pas',
7272 GikoDataModule in 'GikoDataModule.pas' {GikoDM: TDataModule},
7373 BrowserRecord in 'BrowserRecord.pas',
74- GikoMessage in 'GikoMessage.pas';
74+ GikoMessage in 'GikoMessage.pas',
75+ InputAssist in 'InputAssist.pas' {InputAssistForm},
76+ InputAssistDataModule in 'InputAssistDataModule.pas' {InputAssistDM: TDataModule};
7577
7678 {$R *.RES}
7779 {$R gikoResource.res}
@@ -90,7 +92,11 @@ begin
9092 Wnd := FindWindow('TGikoForm', nil);
9193 if Wnd <> 0 then begin
9294 //既に起動済みギコナビのアクティブ化&アイコン化されてたら復元
93- SetForegroundWindow(Wnd);
95+ try
96+ SetForegroundWindow(Wnd);
97+ except
98+ //初期化が終わっていないとフォアグラウンドに移せずに例外発生
99+ end;
94100 if IsIconic(Wnd) then
95101 SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, -1);
96102 // AppWnd := GetWindowLong(Wnd, GWL_HWNDPARENT);
@@ -122,6 +128,7 @@ begin
122128 Application.CreateForm(TFavoriteDM, FavoriteDM);
123129 Application.CreateForm(TAddressHistoryDM, AddressHistoryDM);
124130 Application.CreateForm(TGikoDM, GikoDM);
131+ Application.CreateForm(TInputAssistDM, InputAssistDM);
125132 Application.CreateForm(TGikoForm, GikoForm);
126133 Application.Run;
127134 ReleaseMutex(hMutex);
Binary files a/gikoNavi.res and b/gikoNavi.res differ
--- /dev/null
+++ b/readme/InputAssist.ini
@@ -0,0 +1,23 @@
1+[ギコ猫]
2+ぎこ=      ∧∧  〜′ ̄ ̄(,,゚Д゚)   UU ̄U U
3+ぎこ後ろ=    ∧∧   (  ,,)   /  | 〜(__)
4+ぎこ座り=  ∧∧   (,,゚Д゚)  / つつ〜(__)
5+ぎこ立ち=  ∧∧  (,,゚Д゚)  ⊂  つ  〜  |   し`J
6+
7+[カテゴリ]
8+きたー=キタ━━━( ´∀`)゚∀゚)*゚ー゚)・ω・) ゚Д゚)´ー`)・∀・) ̄ー ̄)´_ゝ`)`Д´)-_-)´Д`)━━!!!
9+
10+[多数行]
11+きたー=キタ━━━━━(゚∀゚)━━━━━!!!!キタ━━━━━(゚∀゚)━━━━━!!!!キタ━━━━━(゚∀゚)━━━━━!!!!キタ━━━━━(゚∀゚)━━━━━!!!!キタ━━━━━(゚∀゚)━━━━━!!!!
12+
13+[動物]
14+くっくる=   ノノノノ  -___  (゚∈゚*)  ─_____ ______ ̄  丿\ノ⌒\  ____ ___ 彡/\ /ヽミ __ ___    ./∨\ノ\  =_   .//.\/ヽミ ≡=-  ミ丿 -__ ̄___________
15+
16+[クマー]
17+くまー=   ∩___∩    | ノ      ヽ   /  ●   ● | クマ──!!   |    ( _●_)  ミ  彡、   |∪|  、`\ / __  ヽノ /´>  ) (___)   / (_/  |       /  |  /\ \  | /    )  )  ∪    (  \        \_)
18+殴る=                      _ /- イ、_            __        /: : : : : : : : : : : (           〈〈〈〈 ヽ     /: : : : ::;:;: ;: ;:;: ; : : : ::ゝ           〈⊃  }     {:: : : :ノ --‐' 、_\: : ::}    ∩___∩  |   |      {:: : :ノ ,_;:;:;ノ、 ェェ ヾ: :::}    | ノ      ヽ !   !   、  l: :ノ /二―-、 |: ::ノ   /  ●   ● |  /   ,,・_  | //   ̄7/ /::ノ   |    ( _●_)  ミ/ , ’,∴ ・ ¨  〉(_二─-┘{/  彡、   |∪|  /  、・∵ ’  /、//|  ̄ ̄ヽ / __  ヽノ /         /   // |//\ 〉 (___)   /         /    //   /\ /        /          /        / 
19+
20+[AA]
21+しょぼ=(´・ω・`)
22+もうこねえよ=                 ┌─┐                  |も.|                  |う |                  │来│                  │ね│                  │え .|                  │よ .|       バカ    ゴルァ  │ !!.│                  └─┤    プンプン     ヽ(`Д´)ノ ヽ(`Д´)ノ  (`Д´)ノ    ( `Д)     | ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U 〜 〜  ̄◎ ̄  . ̄◎ ̄   ̄◎ ̄   ◎−>┘◎
23+
--- a/readme/Samba.default
+++ b/readme/Samba.default
@@ -9,11 +9,11 @@ comic6=30
99 dso=10
1010 etc3=30
1111 etc4=30
12-ex9=20
13-ex10=20
14-ex11=20
15-ex12=20
16-ex13=20
12+ex9=15
13+ex11=15
14+ex12=15
15+ex13=15
16+ex14=15
1717 food6=30
1818 game9=30
1919 game10=30
@@ -21,12 +21,9 @@ hobby7=30
2121 hobby8=30
2222 human5=30
2323 life7=30
24-live14=15
25-live16=15
26-live18=15
27-live19=15
28-live20=15
29-live21=15
24+live14=10
25+live19=10
26+live22x=10
3027 love3=30
3128 money4=30
3229 music4=30
@@ -43,8 +40,8 @@ school5=30
4340 science4=30
4441 society3=30
4542 sports2=0
46-sports9=30
47-that3=30
43+sports9=60
44+that4=30
4845 tmp5=45
4946 travel2=30
5047 tv7=30
@@ -53,4 +50,4 @@ idol=30
5350 pie=30
5451 sakura01=30
5552 sakura02=30
56-sakura03=30
\ No newline at end of file
53+sakura03=30
--- a/readme/readme.txt
+++ b/readme/readme.txt
@@ -1,4 +1,4 @@
1-■ギコナビ Version1.00 バタ51 Readme.txt
1+■ギコナビ Version1.00 バタ52 Readme.txt
22
33
44 ------------------------------
@@ -107,21 +107,28 @@ LICENSE
107107 ------------------------------
108108 履歴
109109 ------------------------------
110-200X/XX/XX
110+2006/XX/YY
111+ Version バタ52
112+ 入力アシスト機構追加
113+ スレッド一覧に”勢い”カラム追加(デフォルト非表示)
114+ お気に入り、履歴、送信ログのスレッドタイトル名をサニタイズするように修正
115+(ノートンの誤反応問題への部分的対応)
116+
117+2006/01/14
111118 Version バタ51
119+ メインフォーム上でのショートカットキーの優先順位がギコナビ自体が最上位に変更
112120  スレッド描画処理の最適化
113121  レス番指定URLをクリックしたときの動作で、取得済み外のレス番の場合自動でDLするように変更
114122  レスエディタからSambaの設定値を変更できるように変更
115123  キャビネット上でクリック・ダブルクリックイベントが過剰に発生する不具合の修正
116124  マウスジェスチャー有効時にプレビュー上で右クリックできない不具合の修正
117- メインフォーム上でのショートカットキーの優先順位がギコナビ自体が最上位に変更
118125  メインメニューのお気に入りの描画の高速化
119126  ステータスバーに現在表示しているスレッドの容量を表示するようにした
120127  DAT落ちしたスレの容量を取得できない不具合の修正
121128  板更新でローカルファイルを指定できるように変更
122129  スレッド一覧ダウンロード後のソートをオプション化
123130  NGワードに全半角ひらがなカタカナの違いを同一視するオプションの追加
124- レスの絞込みで全半角ひらがなカタカタの違いを無視するように変更
131+ レスの絞込みで全半角ひらがなカタカナの違いを無視するように変更
125132
126133 2005/10/10
127134 Version バタ50 リリース3
--- a/readme/setup.INF
+++ b/readme/setup.INF
@@ -90,6 +90,7 @@ Folder=gikoNavi
9090 87=config\Board\ギコナビ.txt
9191 88=Samba.default
9292 89=config\language.ini
93+90=config\InputAssist.ini
9394
9495 [Group]
9596 1=ギコナビ,gikoNavi.exe
Show on old repository browser