OSDN Git Service

・Windows 95 でもお気に入りが使えるようになった。
[gikonavigoeson/gikonavi.git] / Editor.pas
1 unit Editor;
2
3 interface
4
5 uses
6         Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
7         Dialogs, StdCtrls, ComCtrls, ExtCtrls, ToolWin, Menus, OleCtrls,
8         SHDocVw_TLB, ActiveX, {HTTPApp,} YofUtils, IniFiles, StrUtils,
9         GikoSystem, GikoUtil, ImgList, Clipbrd, BoardGroup,
10         IdAntiFreezeBase,       IdAntiFreeze, IdBaseComponent, IdComponent,
11         IdTCPConnection, IdTCPClient, IdHTTP, ActnList, StdActns, IdIntercept,
12         IdLogBase, IdLogDebug, IdException;
13
14 type
15 //      TSetLayeredWindowAttributes = function(wnd: HWND; crKey: DWORD; bAlpha: BYTE; dwFlag: DWORD): Boolean; stdcall;
16         //\8f\91\82«\8d\9e\82Ý\96ß\82è\92l\83^\83C\83v
17         TGikoResultType = (grtOK, grtCookie, grtCheck, grtError);
18
19         TEditorForm = class(TForm)
20                 MainMenu: TMainMenu;
21                 FileMenu: TMenuItem;
22                 PostMessage: TMenuItem;
23                 SaveMessage: TMenuItem;
24                 CloseMenu: TMenuItem;
25                 N01: TMenuItem;
26                 StatusBar: TStatusBar;
27                 EditorPage: TPageControl;
28                 EditorTab: TTabSheet;
29                 PreviewTab: TTabSheet;
30                 Browser: TWebBrowser;
31                 EditMenu: TMenuItem;
32                 UndoMenu: TMenuItem;
33                 CutMenu: TMenuItem;
34                 CopyMenu: TMenuItem;
35                 PasteMenu: TMenuItem;
36                 N02: TMenuItem;
37                 ToolBarImageList: TImageList;
38                 HotToobarImageList: TImageList;
39                 BodyEdit: TMemo;
40                 NameBasePanel: TPanel;
41                 NameLabel: TLabel;
42                 MailLabel: TLabel;
43                 NameComboBox: TComboBox;
44                 MailComboBox: TComboBox;
45                 ToolBar: TToolBar;
46                 SendToolButton: TToolButton;
47                 OutBoxToolButton: TToolButton;
48                 ToolButton5: TToolButton;
49                 UndoToolButton: TToolButton;
50                 CutToolButton: TToolButton;
51                 CopyToolButton: TToolButton;
52                 PasteToolButton: TToolButton;
53                 ToolButton3: TToolButton;
54                 TransToolButton: TToolButton;
55                 TopToolButton: TToolButton;
56                 Indy: TIdHTTP;
57                 IdAntiFreeze: TIdAntiFreeze;
58                 ToolButton1: TToolButton;
59                 ToolButton2: TToolButton;
60                 ActionList: TActionList;
61                 SendAction: TAction;
62                 SaveAction: TAction;
63                 CloseAction: TAction;
64                 UndoAction: TAction;
65                 CutAction: TAction;
66                 CopyAction: TAction;
67                 PasteAction: TAction;
68                 AbortAction: TAction;
69                 TopAction: TAction;
70                 Show1: TMenuItem;
71                 T1: TMenuItem;
72                 N1: TMenuItem;
73                 S1: TMenuItem;
74                 SageCheckBox: TCheckBox;
75                 IdLogDebug: TIdLogDebug;
76                 TransAction: TAction;
77                 A1: TMenuItem;
78                 KotehanCheckBox: TCheckBox;
79     TitlePanel: TPanel;
80                 Label1: TLabel;
81                 TitleEdit: TEdit;
82     SelectAllAction: TAction;
83     N2: TMenuItem;
84     SelectAll1: TMenuItem;
85                 procedure EditorPageChange(Sender: TObject);
86                 procedure FormCreate(Sender: TObject);
87                 procedure BrowserStatusTextChange(Sender: TObject;
88                         const Text: WideString);
89                 procedure FormClose(Sender: TObject; var Action: TCloseAction);
90                 procedure FormDestroy(Sender: TObject);
91                 procedure SendActionExecute(Sender: TObject);
92                 procedure SaveActionExecute(Sender: TObject);
93                 procedure AbortActionExecute(Sender: TObject);
94                 procedure CloseActionExecute(Sender: TObject);
95                 procedure UndoActionExecute(Sender: TObject);
96                 procedure CutActionExecute(Sender: TObject);
97                 procedure CopyActionExecute(Sender: TObject);
98                 procedure PasteActionExecute(Sender: TObject);
99                 procedure SendActionUpdate(Sender: TObject);
100                 procedure SaveActionUpdate(Sender: TObject);
101                 procedure CloseActionUpdate(Sender: TObject);
102                 procedure UndoActionUpdate(Sender: TObject);
103                 procedure CutActionUpdate(Sender: TObject);
104                 procedure CopyActionUpdate(Sender: TObject);
105                 procedure PasteActionUpdate(Sender: TObject);
106                 procedure TopActionExecute(Sender: TObject);
107                 procedure TopActionUpdate(Sender: TObject);
108                 procedure SageCheckBoxClick(Sender: TObject);
109                 procedure MailComboBoxChange(Sender: TObject);
110                 procedure TransActionExecute(Sender: TObject);
111                 procedure TransActionUpdate(Sender: TObject);
112                 procedure IdLogDebugReceive(ASender: TIdConnectionIntercept;
113                         AStream: TStream);
114                 procedure IdLogDebugSend(ASender: TIdConnectionIntercept;
115                         AStream: TStream);
116     procedure SelectAllActionExecute(Sender: TObject);
117         private
118                 FThreadItem: TThreadItem;
119                 FBoard: TBoard;
120                 FNameComboEdit: THandle;
121                 FMailComboEdit: THandle;
122                 FAbort: Boolean;
123                 FWork: Boolean;
124                 FStatusCode: Integer;
125                 FDebugStrReceive: string;
126                 FDebugStrSend: string;
127
128                 procedure Preview;
129                 function RepHtml(s: string): string;
130                 function Check: Boolean;
131                 procedure SetNameList(sName, sMail: string);
132 //              procedure Send(SendType: TGikoSendType; SPID: string; PON: string; FirstWriting: Boolean);
133                 procedure Send(SPID: string; PON: string; FirstWriting: Boolean);
134
135                 function GetActiveControlHandle: THandle;
136 //              function GetSendData: string;
137 //              procedure GetSendData(Source: TStringStream);
138                 procedure GetSendData(Source: TStringStream);
139                 procedure SaveSendFile;
140                 procedure SetContent(Content: string);
141                 function GetSPID(CookieLine: string): string;
142                 function GetPON(CookieLine: string): string;
143                 function GetResultType(ResponseText: string): TGikoResultType;
144         protected
145                 procedure CreateParams(var Params: TCreateParams); override;
146         public
147                 procedure SetFont;
148                 procedure SetThreadItem(Item: TThreadItem);
149                 procedure SetBoard(Item: TBoard);
150         end;
151
152 implementation
153
154 uses
155         Giko, ItemDownload;
156 const
157         CAPTION_NAME_NEW: string = '\83M\83R\83i\83\83X\83\8c\97§\82Ä\83G\83f\83B\83^';
158         CAPTION_NAME_RES: string = '\83M\83R\83i\83\83\8c\83X\83G\83f\83B\83^';
159
160         //DAX\82³\82ñ±Ø¶ÞÄ!(\81L\81¤\81M)
161         READCGI_ERR                     = '-ERR';
162         READCGI_INCR            = '-INCR';
163         READCGI_OK                      = '+OK';
164         READCGI_PARTIAL = '+PARTIAL';
165         READCGI_ERR_FOUND_KAKO  = '-ERR \89ß\8b\8e\83\8d\83O\91q\8cÉ\82Å\94­\8c©';
166         READCGI_ERR_NOT_HTML            = '-ERR html\89»\91Ò\82¿';
167         READCGI_ERR_NOT_FOUND           = '-ERR \82»\82ñ\82È\94Âor\83X\83\8c\83b\83h\82È\82¢\82Å\82·\81B';
168         READCGI_ERR_ABONE                               = '-ERR \82Ç\82±\82©\82Å\82 \82Ú\81[\82ñ\82ª\82 \82Á\82½\82Ý\82½\82¢\82Å\82·\81B';
169         READCGI_ERR_TIMEOUT                     = '-ERR \8ew\92è\8e\9e\8aÔ\82ª\89ß\82¬\82Ü\82µ\82½\81B';
170         READCGI_ERR_CANTUSE                     = '-ERR \82à\82¤\81@\82Â\82©\82¦\82Ü\82¹\82ñ';
171         RES2CH_TRUE                             = '<!-- 2ch_X:true -->';
172         RES2CH_FALSE                    = '<!-- 2ch_X:false -->';
173         RES2CH_ERROR                    = '<!-- 2ch_X:error -->';
174         RES2CH_CHECK                    = '<!-- 2ch_X:check -->';
175         RES2CH_COOKIE                   = '<!-- 2ch_X:cookie -->';
176
177 type
178         TSelection = record
179                 StartPos, EndPos: Integer;
180         end;
181
182 {$R *.DFM}
183
184 {constructor TEditorForm.Create(AOwner: TComponent; Item: TBoard);
185 begin
186         inherited Create(AOwner);
187 end;}
188
189 procedure TEditorForm.CreateParams(var Params: TCreateParams);
190 begin
191         inherited;
192         if FormStyle in [fsNormal, fsStayOnTop] then
193                 if BorderStyle in [bsSingle, bsSizeable] then begin
194                         Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
195                         Params.WndParent := 0;
196                 end;
197 end;
198
199 {procedure TEditorForm.CreateParams(var Params: TCreateParams);
200 begin
201         inherited CreateParams(Params);
202         Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
203 end;}
204
205 procedure TEditorForm.FormCreate(Sender: TObject);
206 var
207 //      i: Integer;
208         u32: Boolean;
209         wp: TWindowPlacement;
210 begin
211         FWork := False;
212         Browser.Navigate('about:blank');
213
214         FBoard := nil;
215         FThreadItem := nil;
216
217         //\83E\83B\83\93\83h\83E\82Ì\88Ê\92u\90Ý\92è
218 {       i := GikoSys.Setting.EditWindowLeft +
219                          GikoSys.Setting.EditWindowTop +
220                          GikoSys.Setting.EditWindowWidth +
221                          GikoSys.Setting.EditWindowHeight;
222         if i > 0 then begin
223                 SetBounds(GikoSys.Setting.EditWindowLeft, GikoSys.Setting.EditWindowTop,
224                                                         GikoSys.Setting.EditWindowWidth, GikoSys.Setting.EditWindowHeight);
225                 if GikoSys.Setting.EditWindowMax then
226                         WindowState := wsMaximized;
227         end;}
228         //\83E\83B\83\93\83h\83E\82Ì\88Ê\92u\90Ý\92è
229         wp.length := sizeof(wp);
230         wp.rcNormalPosition.Top := GikoSys.Setting.EditWindowTop;
231         wp.rcNormalPosition.Left := GikoSys.Setting.EditWindowLeft;
232         wp.rcNormalPosition.Bottom := GikoSys.Setting.EditWindowTop + GikoSys.Setting.EditWindowHeight;
233         wp.rcNormalPosition.Right := GikoSys.Setting.EditWindowLeft + GikoSys.Setting.EditWindowWidth;
234         wp.showCmd := SW_HIDE;
235         SetWindowPlacement(Handle, @wp);
236
237         if GikoSys.Setting.EditWindowMax then
238                 WindowState := wsMaximized;
239
240         //\83E\83B\83\93\83h\83E\82ª\89æ\96Ê\8aO\82È\82ç\89æ\96Ê\93à\82É\88Ú\93®\82·\82é
241         if (Left + Width) > Screen.Width then
242                 Left := Screen.Width - Width;
243         if (Top + Height) > Screen.Height then
244                 Top := Screen.Height - Height;
245         if Left < 0 then
246                 Left := 0;
247         if Top < 0 then
248                 Top := 0;
249
250         //\95\9d\82Æ\8d\82\82³\82ª0\82È\82ç\91å\82«\82­\82·\82é
251         if GikoSys.Setting.EditWindowHeight < 0 then
252                 Height := 400;
253         if GikoSys.Setting.EditWindowWidth < 0 then
254                 Width := 600;
255
256         EditorPage.ActivePage := EditorTab;
257         FNameComboEdit := GetWindow(NameComboBox.Handle, GW_CHILD);
258         FMailComboEdit := GetWindow(MailComboBox.Handle, GW_CHILD);
259         NameComboBox.Items.Assign(GikoSys.Setting.NameList);
260         MailComboBox.Items.Assign(GikoSys.Setting.MailList);
261         SetFont;
262         u32 := GetModuleHandle('User32.dll') <> 0;
263         TransAction.Enabled := u32;
264 end;
265
266 procedure TEditorForm.SetBoard(Item: TBoard);
267 begin
268         FBoard := Item;
269         Caption := CAPTION_NAME_NEW + ' - [' + Item.Title + ']';
270         NameComboBox.Text := FBoard.KotehanName;
271         MailComboBox.Text := FBoard.KotehanMail;
272         SageCheckBox.Checked := AnsiPos('sage', MailComboBox.Text) <> 0;
273         TitlePanel.Visible := True;
274 end;
275
276 procedure TEditorForm.SetThreadItem(Item: TThreadItem);
277 begin
278         FThreadItem := Item;
279         Caption := CAPTION_NAME_RES + ' - [' + FThreadItem.Title + ']';
280         NameComboBox.Text := FThreadItem.ParentBoard.KotehanName;
281         MailComboBox.Text := FThreadItem.ParentBoard.KotehanMail;
282         SageCheckBox.Checked := AnsiPos('sage', MailComboBox.Text) <> 0;
283         TitlePanel.Visible := False;
284 end;
285
286 procedure TEditorForm.SetFont;
287 begin
288         BodyEdit.Font.Name := GikoSys.Setting.EditorFontName;
289         BodyEdit.Font.Size := GikoSys.Setting.EditorFontSize;
290         BodyEdit.Font.Color := GikoSys.Setting.EditorFontColor;
291         BodyEdit.Color := GikoSys.Setting.EditorBackColor;
292 end;
293
294 procedure TEditorForm.Preview;
295 var
296         Title: string;
297         No: string;
298         Mail: string;
299         Namae: string;
300         DateTime: string;
301         Body: string;
302         s: string;
303
304         posTrip : Integer;
305         temp1, temp2 : string;
306 begin
307         if FThreadItem = nil then begin
308                 No := '1';
309                 Title := RepHtml(TitleEdit.Text);
310         end else begin
311                 No := IntToStr(FThreadItem.Count + 1);
312                 Title := RepHtml(FThreadItem.Title);
313         end;
314
315         Namae := RepHtml(NameComboBox.Text);
316         Mail := RepHtml(MailComboBox.Text);
317         Body := RepHtml(BodyEdit.Text);
318         Body := StringReplace(Body, #13#10, '<br>', [rfReplaceAll]);
319         DateTime := FormatDateTime('yyyy/mm/dd(aaa) hh:nn', now);
320
321         if Trim(Namae) = '' then
322                 Namae := '\96¼\96³\82µ\82³\82ñ';
323
324         s := '<HTML><HEAD>' + #13#10
325                         + '<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">' + #13#10
326                         + '<TITLE>' + title + '</TITLE>' + #13#10
327 //                      + '<STYLE><!--BODY{font-size : 9pt;font-family : "\82l\82\82o\83S\83V\83b\83N";}--></STYLE>' + #13#10
328                         + '</HEAD>' + #13#10
329                         + '<BODY text="#000000" bgcolor="#EFEFEF" link="#0000FF" alink="#FF0000" vlink="#660099">' + #13#10
330                         + '<FONT COLOR="#FF0000">' + title + '</FONT>' + #13#10
331                         + '<DL>' + #13#10;
332         posTrip := Pos( '#', Namae );
333         if posTrip > 0 then
334         begin
335                 //Namae := LeftStr( Namae, posTrip - 1 ) + '\81\9f' + get_2ch_trip( PChar( Copy( Namae, posTrip + 1, Length( Namae ) ) ) );
336                 temp1 := Copy( Namae, 1, posTrip - 1 ) + '\81\9f';
337                 temp2 := Copy( Namae, posTrip + 1, Length( Namae ) );
338                 temp2 := get_2ch_trip( PChar( temp2 ) );
339                 Namae := temp1 + temp2;
340         end;
341         if Mail = '' then
342                 s := s + '<DT>' + No + ' \96¼\91O\81F <FONT color="forestgreen"><B>' + Namae + '</B></FONT> \93\8a\8de\93ú\81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10
343         else
344                 s := s + '<DT>' + No + ' \96¼\91O\81F <A href="mailto:' + Mail + '"><B>' + Namae + '</B></A> \93\8a\8de\93ú\81F ' + DateTime+ '<BR><DD>' + Body + '<BR><BR><BR>' + #13#10;
345         s := s + '</BODY></HTML>';
346         SetContent(s);
347 end;
348
349 function TEditorForm.RepHtml(s: string): string;
350 begin
351 //      s := StringReplace(s, '&', '&amp;', [rfReplaceAll]);
352         s := StringReplace(s, '<', '&lt;', [rfReplaceAll]);
353         s := StringReplace(s, '>', '&gt;', [rfReplaceAll]);
354 //      s := StringReplace(s, ' ', '&nbsp;', [rfReplaceAll]);  //\8ed\97l\95Ï\8dX\82É\82æ\82è&nbsp;\8eg\97p\95s\89Â
355         s := StringReplace(s, '"', '&quot;', [rfReplaceAll]);
356         Result := s;
357 end;
358
359 procedure TEditorForm.EditorPageChange(Sender: TObject);
360 begin
361         if EditorPage.ActivePage = PreviewTab then begin
362                 Preview;
363         end else begin
364                 Browser.Navigate('about:blank');
365         end;
366 end;
367
368 procedure TEditorForm.BrowserStatusTextChange(Sender: TObject;
369         const Text: WideString);
370 begin
371         if EditorPage.ActivePage = PreviewTab then begin
372                 StatusBar.Panels[0].Text := Text;
373         end else begin
374                 StatusBar.Panels[0].Text := '';
375         end;
376 end;
377
378 function TEditorForm.Check: Boolean;
379 var
380         Msg: string;
381         rc: Integer;
382         Board: TBoard;
383 begin
384         Result := True;
385         if FThreadItem = nil then
386                 Board := FBoard
387         else
388                 Board := FThreadItem.ParentBoard;
389
390         if (not GikoSys.Setting.UseMachineTime) and
391                  ((Board.LastGetTime = 0) or
392                         (Board.LastGetTime = ZERO_DATE)) then begin
393                 Msg := '\83T\81[\83o\82Ì\8e\9e\8d\8f\82ª\95ª\82©\82ç\82È\82¢\82½\82ß\81A\91\97\90M\8fo\97\88\82Ü\82¹\82ñ'#13#10
394                                  + '\83X\83\8c\83b\83h\82ð\8dX\90V\81i\8eæ\93¾\81j\8cã\81A15\95b\91Ò\82Á\82Ä\82©\82ç\91\97\90M\82µ\82Ä\82­\82¾\82³\82¢';
395                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
396                 Result := False;
397         end else if BodyEdit.Text = '' then begin
398                 Msg := '\96{\95\82ª\93ü\97Í\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B';
399                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
400                 Result := False;
401         end else if (FBoard <> nil) and (Trim(TitleEdit.Text) = '') then begin
402                 Msg := '\83^\83C\83g\83\8b\82ª\93ü\97Í\82³\82ê\82Ä\82¢\82Ü\82¹\82ñ\81B';
403                 MsgBox(Handle, Msg, '\83G\83\89\81[', MB_OK or MB_ICONSTOP);
404                 Result := False;
405         end else begin
406                 if (not GikoSys.Dolib.Connected) and (AnsiPos('\81\9c', NameComboBox.Text) <> 0) then begin
407                         Msg := '\83\8d\83O\83C\83\93\82µ\82Ä\82¢\82È\82¢\82Ì\82Å\81\9c\82Ì\8b@\94\\82Í\97\98\97p\8fo\97\88\82Ü\82¹\82ñ\81B'#13#10
408                                          + '\82±\82Ì\82Ü\82Ü\91\97\90M\82µ\82Ä\82à\82æ\82ë\82µ\82¢\82Å\82·\82©\81H';
409                         rc := MsgBox(Handle, Msg, '\8am\94F', MB_YESNO or MB_ICONQUESTION);
410                         Result := (rc = IDYES);
411                 end;
412         end;
413 end;
414
415 procedure TEditorForm.FormClose(Sender: TObject; var Action: TCloseAction);
416 begin
417         Action := caFree;
418 end;
419
420 procedure TEditorForm.FormDestroy(Sender: TObject);
421 var
422         wp: TWindowPlacement;
423 begin
424         //\8dÅ\91å\89»\81E\83E\83B\83\93\83h\83E\88Ê\92u\95Û\91
425         wp.length := sizeof(wp);
426         GetWindowPlacement(Handle, @wp);
427
428         GikoSys.Setting.EditWindowTop := wp.rcNormalPosition.Top;
429         GikoSys.Setting.EditWindowLeft := wp.rcNormalPosition.Left;
430         GikoSys.Setting.EditWindowHeight := wp.rcNormalPosition.Bottom - wp.rcNormalPosition.Top;
431         GikoSys.Setting.EditWindowWidth := wp.rcNormalPosition.Right - wp.rcNormalPosition.Left;
432         GikoSys.Setting.EditWindowMax := WindowState = wsMaximized;
433 end;
434
435 procedure TEditorForm.SetNameList(sName, sMail: string);
436 begin
437         if Trim(sName) <> '' then begin
438                 if GikoSys.Setting.NameList.IndexOf(sName) = -1 then
439                         GikoSys.Setting.NameList.Insert(0, sName);
440         end;
441         if Trim(sMail) <> '' then begin
442                 if GikoSys.Setting.MailList.IndexOf(sMail) = -1 then
443                         GikoSys.Setting.MailList.Insert(0, sMail);
444         end;
445 end;
446
447 function TEditorForm.GetActiveControlHandle: THandle;
448 begin
449         if EditorPage.ActivePage = EditorTab then begin
450                 if ActiveControl = NameComboBox then
451                         Result := FNameComboEdit
452                 else if ActiveControl = MailComboBox then
453                         Result := FMailComboEdit
454                 else if ActiveControl = BodyEdit then
455                         Result := BodyEdit.Handle
456                 else if ActiveControl = TitleEdit then
457                         Result := TitleEdit.Handle
458                 else
459                         Result := 0;
460         end else
461                 Result := 0;
462 end;
463
464 procedure TEditorForm.SetContent(Content: string);
465 var
466         doc : Variant;
467 begin
468         doc := Browser.Document;
469         doc.Clear;
470         doc.open;
471         doc.charset := 'Shift_JIS';
472         doc.Write(Content);
473         doc.Close;
474 end;
475
476 procedure TEditorForm.Send(SPID: string; PON: string; FirstWriting: Boolean);
477 var
478         TextStream: TStringStream;
479         Source: TStringStream;
480         ResponseText: string;
481         URL: string;
482         RefURL: string;
483         State: TGikoDownloadState;
484         ResultType: TGikoResultType;
485         MsgResult: Integer;
486         Cookie: string;
487         Board: TBoard;
488 begin
489         FAbort := False;
490         State := gdsError;
491         if FThreadItem = nil then
492                 Board := FBoard
493         else
494                 Board := FThreadItem.ParentBoard;
495
496         Indy.Request.Clear;
497         Indy.ProxyParams.BasicAuthentication := False;
498         if GikoSys.Setting.WriteProxy then begin
499                 Indy.ProxyParams.ProxyServer := GikoSys.Setting.WriteProxyAddress;
500                 Indy.ProxyParams.ProxyPort := GikoSys.Setting.WriteProxyPort;
501                 Indy.ProxyParams.ProxyUsername := GikoSys.Setting.WriteProxyUserID;
502                 Indy.ProxyParams.ProxyPassword := GikoSys.Setting.WriteProxyPassword;
503                 if GikoSys.Setting.ReadProxyUserID <> '' then
504                         Indy.ProxyParams.BasicAuthentication := True;
505         end else begin
506                 Indy.ProxyParams.ProxyServer := '';
507                 Indy.ProxyParams.ProxyPort := 80;
508                 Indy.ProxyParams.ProxyUsername := '';
509                 Indy.ProxyParams.ProxyPassword := '';
510         end;
511         if FThreadItem = nil then begin
512                 URL := FBoard.GetSendURL;
513                 RefURL := GikoSys.UrlToServer(FBoard.URL) + 'test/bbs.cgi';
514         end else begin
515                 URL := FThreadItem.GetSendURL;
516                 RefURL := GikoSys.UrlToServer(FThreadItem.ParentBoard.URL)
517                                                 + 'test/read.cgi/'
518                                                 + FThreadItem.ParentBoard.BBSID
519                                                 + '/' + ChangeFileExt(FThreadItem.FileName, '')
520                                                 + '/l50';
521         end;
522         Indy.Request.UserAgent := GikoSys.GetUserAgent;
523         Indy.Request.Referer := RefURL;
524         Indy.Request.AcceptEncoding := '';
525
526         Cookie := '';
527         if SPID <> '' then
528                 Cookie := Cookie + 'SPID=' + SPID + '; ';
529         if PON <> '' then
530                 Cookie := Cookie + 'PON=' + PON + '; ';
531         Cookie := 'Cookie: ' + Cookie + 'NAME=' + NameComboBox.Text + '; MAIL=' + MailComboBox.Text;
532
533         Indy.Request.CustomHeaders.Clear;
534 //      Indy.Request.CacheControl := 'no-cache';
535         Indy.Request.CustomHeaders.Add('Pragma: no-cache');
536         Indy.Request.AcceptLanguage := 'ja';
537         Indy.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*';
538         Indy.Request.ContentType := 'application/x-www-form-urlencoded';
539         Indy.Request.CustomHeaders.Add(Cookie);
540         TextStream := TStringStream.Create('');
541         Source := TStringStream.Create('');
542         try
543                 try
544                         FDebugStrReceive := '';
545                         FDebugStrSend := '';
546                         GetSendData(Source);
547                         Indy.Post(URL, Source, TextStream);
548                         ResponseText := TextStream.DataString;
549
550                         ResultType := GetResultType(ResponseText);
551
552                         if ResultType = grtOK then
553                                 State := gdsComplete
554                         else if ResultType = grtCookie then begin
555                                 //\83\8b\81[\83v\96h\8e~
556                                 if not FirstWriting then
557                                         raise Exception.Create('');
558                                 MsgResult := MsgBox(
559                                         Handle,
560                                         '\81E\93\8a\8de\82³\82ê\82½\93à\97e\82Í\83R\83s\81[\81A\95Û\91\81A\88ø\97p\81A\93]\8dÚ\93\99\82³\82ê\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B' + #13#10 +
561                                         '\81E\93\8a\8de\82É\8aÖ\82µ\82Ä\94­\90\82·\82é\90Ó\94C\82Í\91S\82Ä\93\8a\8de\8eÒ\82É\8bA\82µ\82Ü\82·\81B' + #13#10#13#10 +
562                                         '\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Ý\82Ü\82·\82©\81H',
563                                         '\8fî\95ñ',
564                                         MB_YESNO or MB_ICONQUESTION);
565                                 if MsgResult = IDYES then begin
566                                         Board.SPID := GetSPID(Indy.Response.RawHeaders.Values['Set-Cookie']);
567                                         Board.PON := GetPON(Indy.Response.RawHeaders.Values['Set-Cookie']);
568                                         if (Board.SPID = '') and (Board.PON = '') then
569                                                 raise Exception.Create('');
570                                         //\82à\82¤\88ê\89ñ\82±\82Ì\83\81\83\\83b\83h
571                                         Send(Board.SPID, Board.PON, False);
572                                         Exit;
573                                 end else begin
574                                         Board.SPID := '';
575                                         Board.PON := '';
576                                         Exit;
577                                 end;
578                         end else if ResultType = grtCheck then begin
579                                 //
580                                 //\83\8b\81[\83v\96h\8e~
581                                 if not FirstWriting then
582                                         raise Exception.Create('');
583
584                                 MsgResult := MsgBox(
585                                         Handle,
586                                         '\8f\91\82«\8d\9e\82Ý\82É\8aÖ\82µ\82Ä\82Í\97l\81X\82È\83\8d\83O\8fî\95ñ\82ª\8bL\98^\82³\82ê\82Ä\82¢\82Ü\82·\81B' + #13#10 +
587                                         '\93\8a\8de\82É\8aÖ\82µ\82Ä\94­\90\82·\82é\90Ó\94C\82Í\91S\82Ä\93\8a\8de\8eÒ\82É\8bA\82µ\82Ü\82·\81B' + #13#10 +
588                                         '\8cö\8f\98\97Ç\91­\82É\94½\82µ\82½\82è\81A\91¼\90l\82É\96À\98f\82ð\82©\82¯\82é\8f\91\82«\8d\9e\82Ý\82Í\8dT\82¦\82Ä\89º\82³\82¢\81B' + #13#10 +
589                                         '\93\8a\8de\82³\82ê\82½\93à\97e\82Í\83R\83s\81[\81E\95Û\91\81E\88ø\97p\81E\93]\8dÚ\93\99\82³\82ê\82é\8fê\8d\87\82ª\82 \82è\82Ü\82·\81B' + #13#10 +
590                                         #13#10 +
591                                         '\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Ý\82Ü\82·\82©\81H',
592                                         '\8am\94F',
593                                         MB_YESNO or MB_ICONQUESTION);
594
595                                 if MsgResult = IDYES then begin
596                                         Board.SPID := GetSPID(Indy.Response.RawHeaders.Values['Set-Cookie']);
597                                         Board.PON := GetPON(Indy.Response.RawHeaders.Values['Set-Cookie']);
598                                         if (Board.SPID = '') and (Board.PON = '') then
599                                                 raise Exception.Create('');
600                                         Send(Board.SPID, Board.PON, False);
601                                         Exit;
602                                 end else begin
603                                         Board.SPID := '';
604                                         Board.PON := '';
605                                         Exit;
606                                 end;
607                         end else begin
608                                 State := gdsError;
609                                 raise Exception.Create('');
610                         end;
611                 except
612                         on E: EIdConnectException do begin
613                                 State := gdsError;
614                                 ResponseText := '<html><body>'
615                                                                                         + '<div>\90Ú\91±\82ª\8e¸\94s\82µ\82Ü\82µ\82½<br>'
616                                                                                         + '\89ñ\90ü\82â\83v\83\8d\83L\83V\82Ì\8fó\91Ô\82ð\92²\82×\82Ä\82­\82¾\82³\82¢<br></div>'
617                                                                                         + '<br><br><div>' + E.Message + '</div>'
618                                                                                         + '</body></html>';
619                         end;
620                         on E: Exception do begin
621                                 State := gdsError;
622
623                                 FDebugStrReceive := AnsiReplaceText(FDebugStrReceive, '<', '&lt;');
624                                 FDebugStrReceive := AnsiReplaceText(FDebugStrReceive, '>', '&gt;');
625                                 FDebugStrSend := AnsiReplaceText(FDebugStrSend, '<', '&lt;');
626                                 FDebugStrSend := AnsiReplaceText(FDebugStrSend, '>', '&gt;');
627
628                                 ResponseText := '<html><body>' + TextStream.DataString;
629                                 ResponseText := AnsiReplaceText(ResponseText, '</body>', '');
630                                 ResponseText := AnsiReplaceText(ResponseText, '</html>', '');
631                                 ResponseText := ResponseText + '<hr><div align="left"><pre>';
632                                 ResponseText := ResponseText + '<b>\82±\82±\82©\82ç\83M\83R\83i\83r\82Ì\8fî\95ñ</b>'#13#10;
633                                 ResponseText := ResponseText + #13#10'\81\9c\91\97\90M'#13#10;
634                                 ResponseText := ResponseText + FDebugStrSend;
635                                 ResponseText := ResponseText + #13#10'\81\9c\8eó\90M'#13#10;
636                                 ResponseText := ResponseText + FDebugStrReceive;
637                                 ResponseText := ResponseText + '</pre></div></body></html>';
638                         end;
639                 end;
640                 FStatusCode := Indy.ResponseCode;
641                 if FAbort then
642                         State := gdsAbort;
643         finally
644                 Source.Free;
645                 TextStream.Free;
646         end;
647
648         if State = gdsComplete then begin
649                 GikoForm.PlaySound('ResEnd');
650                 SaveSendFile;
651                 if FThreadItem = nil then
652                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8fI\97¹]', nil, gmiOK)
653                 else
654                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8fI\97¹]', nil, gmiOK);
655                 Close;
656         end else if State = gdsError then begin
657                 if FThreadItem = nil then
658                         GikoForm.AddMessageList(FBoard.Title + ' [\90V\83X\83\8c\91\97\90M\8e¸\94s]', nil, gmiNG)
659                 else
660                         GikoForm.AddMessageList(FThreadItem.Title + ' [\83\8c\83X\91\97\90M\8e¸\94s]', nil, gmiNG);
661                 EditorPage.ActivePage := PreviewTab;
662                 SetContent(ResponseText);
663         end else if State = gdsAbort then begin
664                 GikoForm.AddMessageList(FThreadItem.Title + ' [\92\86\92f]', nil, gmiSAD);
665         end;
666 end;
667
668 function TEditorForm.GetResultType(ResponseText: string): TGikoResultType;
669 begin
670         if AnsiPos('\8f\91\82«\82±\82Ý\82ª\8fI\82í\82è\82Ü\82µ\82½', ResponseText) <> 0 then
671                 Result := grtOK
672         else if (AnsiPos('\83N\83b\83L\81[\82ª\82È\82¢\82©\8aú\8cÀ\90Ø\82ê\82Å\82·', ResponseText) > 0) or
673                                         (AnsiPos('<title>\83N\83b\83L\81[\8am\94F\81I</title>', ResponseText) > 0)  or
674                                         (AnsiPos('<title>\81¡\83N\83b\83L\81[\8am\94F\81I\81¡</title>', ResponseText) > 0)  or
675                                         //(AnsiPos('\83N\83b\83L\81[\8am\94F', ResponseText) > 0) or
676                                         (AnsiPos(RES2CH_COOKIE, ResponseText) > 0)  then
677                 Result := grtCookie
678         else if (AnsiPos('<font size=+2 color=#FF0000>\8f\91\82«\8d\9e\82Ý\83`\83F\83b\83N\81I </font>', ResponseText) > 0)  or
679                                         (AnsiPos('<title>\81¡ \8f\91\82«\8d\9e\82Ý\8am\94F\82µ\82Ü\82· \81¡</title>', ResponseText) > 0)  or
680                                         (AnsiPos('<title>\93\8a\8de\8am\94F</title>', ResponseText) > 0)  or
681                                         (AnsiPos('<b>\8f\91\82«\82±\82Ý\8am\94F</b>', ResponseText) > 0)  or
682                                         (AnsiPos('="../test/subbbs.cgi">', ResponseText) > 0)  or
683                                         (AnsiPos(RES2CH_FALSE, ResponseText) > 0)  then
684                 Result := grtCheck
685         else
686                 Result := grtError;
687 end;
688
689
690 procedure TEditorForm.GetSendData(Source: TStringStream);
691 var
692         SessionID: string;
693         s: string;
694         SendTime: Integer;
695         Adjust: Integer;
696         Board: TBoard;
697 begin
698         if FThreadItem = nil then
699                 Board := FBoard
700         else
701                 Board := FThreadItem.ParentBoard;
702
703         if GikoSys.Setting.UseMachineTime then begin
704                 if GikoSys.Setting.TimeAdjust then
705                         Adjust := Gikosys.Setting.TimeAdjustSec
706                 else
707                         Adjust := GikoSys.Setting.TimeAdjustSec * -1;
708                 SendTime := GikoSys.DateTimeToInt(Now) - (9 * 60 * 60) + Adjust
709         end else begin
710                 if (Board.LastGetTime = 0) or (Board.LastGetTime = ZERO_DATE) then
711                         SendTime := GikoSys.DateTimeToInt(Now)
712                 else
713                         SendTime := GikoSys.DateTimeToInt(Board.LastGetTime);
714         end;
715         SessionID := GikoSys.Dolib.SessionID;
716         if SessionID <> '' then
717                 s := 'sid=' + HttpEncode(SessionID) + '&'
718         else
719                 s := '';
720         s := s + 'subject=&'
721                                  + 'FROM=' + HttpEncode(NameComboBox.Text) + '&'
722                                  + 'mail=' + HttpEncode(MailComboBox.Text) + '&'
723                                  + 'MESSAGE=' + HttpEncode(BodyEdit.Text) + '&'
724                                  + 'bbs=' + Board.BBSID + '&'
725                                  + 'time=' + IntToStr(SendTime) + '&';
726         if FThreadItem = nil then begin
727                 s := s + 'subject=' + HttpEncode(TitleEdit.Text) + '&';
728                 s := s + 'submit=' + HttpEncode('\91S\90Ó\94C\82ð\95\89\82¤\82±\82Æ\82ð\8f³\91ø\82µ\82Ä\8f\91\82«\8d\9e\82Þ') + #13#10;
729         end else begin
730                 s := s + 'key=' + ChangeFileExt(FThreadItem.FileName, '') + '&';
731                 s := s + 'submit=' + HttpEncode('\8f\91\82«\8d\9e\82Þ') + #13#10;
732         end;
733         Source.WriteString(s);
734 end;
735
736 procedure TEditorForm.SaveSendFile;
737 var
738         sDate: string;
739         ini: TMemIniFile;
740 begin
741         ini := TMemIniFile.Create(GikoSys.GetSentFileName);
742         try
743                 sDate := IntToStr(GikoSys.DateTimeToInt(Now));
744
745                 ini.WriteString(sDate, 'Name', NameComboBox.Text);
746                 ini.WriteString(sDate, 'EMail', MailComboBox.Text);
747                 ini.WriteString(sDate, 'Body', HttpEncode(BodyEdit.Text));
748                 ini.WriteInteger(sDate, 'Status', FStatusCode);
749                 ini.WriteDateTime(sDate, 'Date', Now);
750                 if FThreadItem = nil then begin
751                         ini.WriteString(sDate, 'Title', TitleEdit.Text);
752                         ini.WriteString(sDate, 'BBS', FBoard.BBSID);
753                         ini.WriteInteger(sDate, 'NewThread', 1);
754                 end else begin
755                         ini.WriteString(sDate, 'Title', FThreadItem.Title);
756                         ini.WriteString(sDate, 'BBS', FThreadItem.ParentBoard.BBSID);
757                         ini.WriteString(sDate, 'Key', ChangeFileExt(FThreadItem.FileName, ''));
758                 end;
759
760                 ini.UpdateFile;
761         finally
762                 ini.Free;
763         end;
764 end;
765
766 procedure TEditorForm.SendActionExecute(Sender: TObject);
767 var
768         Board: TBoard;
769         rc: Integer;
770 begin
771         if FWork then
772                 Exit;
773         try
774                 FWork := True;
775                 SendAction.Enabled := False;
776                 Application.ProcessMessages;
777                 if not Check then Exit;
778
779                 if FThreadItem = nil then
780                         Board := FBoard
781                 else
782                         Board := FThreadItem.ParentBoard;
783
784                 if FThreadItem = nil then begin
785                         rc := GikoUtil.MsgBox(Handle,
786                                                                                                         '\81u' + Board.Title + '\81v\94Â\82É\90V\82µ\82¢\83X\83\8c\83b\83h\97§\82Ä\82Ü\82·'#13#10#13#10
787                                                                                                         + '\81E\94Â\82Ì\83\8b\81[\83\8b\82ð\8eç\82Á\82½\8f\91\82«\8d\9e\82Ý\82Å\82 \82é\82±\82Æ\82ð\8am\94F\82µ\82Ü\82µ\82½\82©\81H'#13#10
788                                                                                                         + '\81E\91¼\82É\93¯\82\82æ\82¤\82È\83X\83\8c\83b\83h\82ª\96³\82©\82Á\82½\82±\82Æ\82ð\8am\94F\82µ\82Ü\82µ\82½\82©\81H'#13#10#13#10
789                                                                                                         + '\81u\82Í\82¢\81v\82ð\89\9f\82·\82Æ\91\97\90M\82µ\82Ü\82·',
790                                                                                                         '\8am\94F',
791                                                                                                         MB_ICONQUESTION or MB_YESNO);
792                         if rc <> ID_YES then
793                                 Exit;
794                 end;
795
796                 SetNameList(NameComboBox.Text, MailComboBox.Text);
797                 if KotehanCheckBox.Checked then begin
798                         Board.KotehanName := NameComboBox.Text;
799                         Board.KotehanMail := MailComboBox.Text;
800                 end;
801                 Send(Board.SPID, Board.PON, True);
802         finally
803                 FWork := False;
804         end;
805 end;
806
807 procedure TEditorForm.SaveActionExecute(Sender: TObject);
808 begin
809 //
810 end;
811
812 procedure TEditorForm.CloseActionExecute(Sender: TObject);
813 begin
814         Close;
815 end;
816
817 procedure TEditorForm.UndoActionExecute(Sender: TObject);
818 begin
819         SendMessage(GetActiveControlHandle, WM_UNDO, 0, 0);
820 end;
821
822 procedure TEditorForm.CutActionExecute(Sender: TObject);
823 begin
824         SendMessage(GetActiveControlHandle, WM_CUT, 0, 0);
825 end;
826
827 procedure TEditorForm.CopyActionExecute(Sender: TObject);
828 begin
829         SendMessage(GetActiveControlHandle, WM_COPY, 0, 0);
830 end;
831
832 procedure TEditorForm.PasteActionExecute(Sender: TObject);
833 begin
834         SendMessage(GetActiveControlHandle, WM_PASTE, 0, 0);
835 end;
836
837 procedure TEditorForm.SelectAllActionExecute(Sender: TObject);
838 begin
839         SendMessage(GetActiveControlHandle, EM_SETSEL, 0, GetWindowTextLength(GetActiveControlHandle));
840 end;
841
842 procedure TEditorForm.TopActionExecute(Sender: TObject);
843 begin
844         if TopAction.Checked then
845                 FormStyle := fsStayOnTop
846         else
847                 FormStyle := fsNormal;
848 end;
849
850 procedure TEditorForm.AbortActionExecute(Sender: TObject);
851 begin
852         FAbort := True;
853 end;
854
855 procedure TEditorForm.SendActionUpdate(Sender: TObject);
856 begin
857         SendAction.Enabled := not FWork;
858 end;
859
860 procedure TEditorForm.SaveActionUpdate(Sender: TObject);
861 begin
862         SaveAction.Enabled := False;
863 end;
864
865 procedure TEditorForm.CloseActionUpdate(Sender: TObject);
866 begin
867         SendAction.Enabled := not FWork;
868 end;
869
870 procedure TEditorForm.UndoActionUpdate(Sender: TObject);
871 begin
872         UndoAction.Enabled := (GetActiveControlHandle <> 0)
873                                                                                                 and (SendMessage(GetActiveControlHandle, EM_CANUNDO, 0, 0) <> 0)
874                                                                                                 and (not FWork);
875 end;
876
877 procedure TEditorForm.CutActionUpdate(Sender: TObject);
878 var
879         Selection: TSelection;
880         AHandle: THandle;
881 begin
882         AHandle := GetActiveControlHandle;
883         SendMessage(AHandle, EM_GETSEL, Longint(@Selection.StartPos), Longint(@Selection.EndPos));
884         CutAction.Enabled := (AHandle <> 0)
885                                                                                 and ((Selection.EndPos - Selection.StartPos) <> 0)
886                                                                                 and (not FWork);
887 end;
888
889 procedure TEditorForm.CopyActionUpdate(Sender: TObject);
890 var
891         Selection: TSelection;
892         AHandle: THandle;
893 begin
894         AHandle := GetActiveControlHandle;
895         SendMessage(AHandle, EM_GETSEL, Longint(@Selection.StartPos), Longint(@Selection.EndPos));
896         CopyAction.Enabled := (AHandle <> 0)
897                                                                                 and ((Selection.EndPos - Selection.StartPos) <> 0)
898                                                                                 and (not FWork);
899 end;
900
901 procedure TEditorForm.PasteActionUpdate(Sender: TObject);
902 begin
903         PasteAction.Enabled := (GetActiveControlHandle <> 0)
904                                                                                         and (Clipboard.HasFormat(CF_TEXT))
905                                                                                         and (not FWork);
906 end;
907
908 procedure TEditorForm.TopActionUpdate(Sender: TObject);
909 begin
910         TopAction.Enabled := not FWork;
911 end;
912
913 procedure TEditorForm.SageCheckBoxClick(Sender: TObject);
914 begin
915         if SageCheckBox.Checked then begin
916                 if AnsiPos('sage', MailComboBox.Text) = 0 then
917                         MailComboBox.Text := 'sage' + MailComboBox.Text;
918         end else begin
919                 if AnsiPos('sage', MailComboBox.Text) <> 0 then
920                         MailComboBox.Text := StringReplace(MailComboBox.Text, 'sage', '', [rfReplaceAll]);
921         end;
922 end;
923
924 procedure TEditorForm.MailComboBoxChange(Sender: TObject);
925 begin
926         if AnsiPos('sage', MailComboBox.Text) = 0 then
927                 SageCheckBox.Checked := False
928         else
929                 SageCheckBox.Checked := True;
930 end;
931
932
933 function TEditorForm.GetSPID(CookieLine: string): string;
934 var
935         s: string;
936         i: Integer;
937 begin
938         Result := '';
939         i := 0;
940         while True do begin
941                 s := Trim(GikoSys.GetTokenIndex(CookieLine, ';', i));
942                 if s = '' then
943                         Break
944                 else begin
945                         if Pos('SPID=', s) = 1 then begin
946                                 Result := Trim(Copy(s, 6, Length(s)));
947                                 Break;
948                         end;
949                 end;
950                 inc(i);
951         end;
952 end;
953
954 function TEditorForm.GetPON(CookieLine: string): string;
955 var
956         s: string;
957         i: Integer;
958 begin
959         Result := '';
960         i := 0;
961         while True do begin
962                 s := Trim(GikoSys.GetTokenIndex(CookieLine, ';', i));
963                 if s = '' then
964                         Break
965                 else begin
966                         if Pos('PON=', s) = 1 then begin
967                                 Result := Trim(Copy(s, 5, Length(s)));
968                                 Break;
969                         end;
970                 end;
971                 inc(i);
972         end;
973 end;
974
975 procedure TEditorForm.IdLogDebugReceive(ASender: TIdConnectionIntercept;
976         AStream: TStream);
977 var
978         StringStream: TStringStream;
979 begin
980         StringStream := TStringStream.Create('');
981         try
982                 StringStream.CopyFrom(AStream, AStream.Size);
983                 FDebugStrReceive := FDebugStrReceive + StringStream.DataString;
984         finally
985                 StringStream.Free;
986         end;
987 end;
988
989 procedure TEditorForm.IdLogDebugSend(ASender: TIdConnectionIntercept;
990         AStream: TStream);
991 var
992         StringStream: TStringStream;
993 begin
994         StringStream := TStringStream.Create('');
995         try
996                 StringStream.CopyFrom(AStream, AStream.Size);
997                 FDebugStrSend := FDebugStrSend + StringStream.DataString;
998         finally
999                 StringStream.Free;
1000         end;
1001 end;
1002
1003 procedure TEditorForm.TransActionExecute(Sender: TObject);
1004 begin
1005         AlphaBlend := TransAction.Checked;
1006 end;
1007
1008 procedure TEditorForm.TransActionUpdate(Sender: TObject);
1009 begin
1010         TransAction.Enabled := not FWork;
1011 end;
1012
1013 end.
1014