• R/O
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revision3 (tree)
Time2018-12-09 00:45:20
Authorkentamaken

Log Message

ドラッグ修正
リストのツリー化
検索文字列も表示

Change Summary

Incremental Difference

--- textdefind.dproj (revision 2)
+++ textdefind.dproj (revision 3)
@@ -72,6 +72,7 @@
7272 <DCC_RemoteDebug>true</DCC_RemoteDebug>
7373 </PropertyGroup>
7474 <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
75+ <Debugger_RunParams>/IUV3</Debugger_RunParams>
7576 <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
7677 <DCC_DebugDCUs>false</DCC_DebugDCUs>
7778 <AppEnableHighDPI>true</AppEnableHighDPI>
--- textdefindunit.pas (revision 2)
+++ textdefindunit.pas (revision 3)
@@ -16,6 +16,10 @@
1616
1717 end;
1818
19+ TStringsHelper=class helper for TStrings
20+ function setstrings(sa:TStringDynArray):Integer;
21+ end;
22+
1923 TStringDynArrayHelper=record helper for TStringDynArray
2024 function add(s:string):Integer;
2125 function adduni(s:string):Integer;
@@ -76,7 +80,6 @@
7680 Panel1:TPanel;
7781 Path:TComboBox;
7882 Find:TButton;
79- Text:TRichEdit;
8083 GridFiles: TStringGrid;
8184 PopupMenu2:TPopupMenu;
8285 PFileCut:TMenuItem;
@@ -94,6 +97,14 @@
9497 TMP:TComboBox;
9598 SaveDialog:TSaveDialog;
9699 OpenDialog:TOpenDialog;
100+ Panel2: TPanel;
101+ Name: TComboBox;
102+ Text: TRichEdit;
103+ Tree: TTreeView;
104+ Button1: TButton;
105+ Splitter1: TSplitter;
106+ PFileExec: TMenuItem;
107+ PFileFolder: TMenuItem;
97108 procedure FindClick(Sender:TObject);
98109 procedure FormCreate(Sender:TObject);
99110 procedure GridFilesMouseDown(Sender:TObject;Button:TMouseButton;
@@ -109,6 +120,11 @@
109120 procedure PTextSaveAsClick(Sender:TObject);
110121 procedure PTextOpenClick(Sender:TObject);
111122 procedure FormDestroy(Sender:TObject);
123+ procedure NameChange(Sender: TObject);
124+ procedure TreeClick(Sender: TObject);
125+ procedure Button1Click(Sender: TObject);
126+ procedure PFileFolderClick(Sender: TObject);
127+ procedure PFileExecClick(Sender: TObject);
112128 private
113129 { Private 宣言 }
114130 public
@@ -117,17 +133,15 @@
117133
118134 function QueryContinueDrag(fEscapePressed:BOOL;grfKeyState:Longint):HResult;stdcall;
119135 function GiveFeedback(dwEffect:Longint):HResult;stdcall;
136+ function GetFilePathDataObject(G:TStringGrid):IDataObject;
120137 end;
121138
122-
123- function GetFilePathDataObject(G:TStringGrid):IDataObject;
124-
125139 var
126140 TextDeFindForm:TTextDeFindForm;
127141
128142 implementation
129143
130-uses strutils,IOUtils,masks,clipbrd,inifiles;
144+uses strutils,IOUtils,masks,clipbrd,inifiles,SHELLAPI;
131145
132146 var
133147 Malloc :IMalloc;
@@ -135,6 +149,7 @@
135149 SL :TStringDynArray;
136150 Ini :TIniFile;
137151 inidir :string;
152+ pname :string;
138153
139154 const
140155 TKNMAXLEN=1024;
@@ -143,9 +158,28 @@
143158 LF =#10;
144159 CRLF =#13#10;
145160 TAB =#9;
161+ CTEXT =1;
162+ CFILE =2;
163+ CPATH =3;
164+var
165+ CHEAD:TStringDynArray =['','テキスト','ファイル','パス'];
146166
147167 {$R *.dfm}
148168
169+function INCBS(const s:string):string;
170+begin
171+ Result:=s;
172+ if not IsPathDelimiter(Result,Length(Result)) then Result:=Result+'\';
173+end;
174+
175+function EXCBS(const s:string):string;
176+begin
177+ Result:=s;
178+ if IsPathDelimiter(Result,Length(Result)) then SetLength(Result,Length(Result)-1);
179+end;
180+
181+
182+
149183 procedure TTextDeFindForm.FormCreate(Sender:TObject);
150184 begin
151185 Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI'));
@@ -158,10 +192,16 @@
158192 Text.Width:=Ini.ReadInteger('','Text.Width',Text.Width);
159193 Font.Size:=Ini.ReadInteger('','Font.Size',Font.Size);
160194
195+ Path.Text:=Ini.ReadString('','Path.Text','');
196+
161197 // Files:=GridFiles;
162198 Files:=TGrid.CreateEX(GridFiles);
163- Text.lines.LoadFromFile(ChangeFileExt(Application.ExeName,'.txt'));
199+
200+ Tree.LoadFromFile(ChangeFileExt(Application.ExeName,'.txt'));
164201 files.Load(ChangeFileExt(Application.ExeName,'.csv'));
202+ NameChange(Sender);
203+ pname:=Name.Text;
204+ TreeClick(Sender);
165205 end;
166206
167207 procedure TTextDeFindForm.FormDestroy(Sender:TObject);
@@ -170,9 +210,11 @@
170210 Ini.WriteInteger('','Height',Height);
171211 Ini.WriteInteger('','Text.Width',Text.Width);
172212 Ini.WriteInteger('','Font.Size',Font.Size);
213+ Ini.WriteString('','Path.Text',Path.Text);
173214 Ini.Free;
174215
175- Text.lines.SaveToFile(ChangeFileExt(Application.ExeName,'.txt'));
216+ NameChange(Sender);
217+ Tree.SaveToFile(ChangeFileExt(Application.ExeName,'.txt'));
176218 files.save(ChangeFileExt(Application.ExeName,'.csv'));
177219
178220 end;
@@ -192,6 +234,7 @@
192234 else Result:=S_OK;
193235 end;
194236
237+
195238 function TTextDeFindForm.GiveFeedback(dwEffect:Longint):HResult;
196239 begin
197240 //デフォルトのカーソルを使う
@@ -208,6 +251,19 @@
208251 files.cutcopy(true);
209252 end;
210253
254+procedure TTextDeFindForm.PFileExecClick(Sender: TObject);
255+begin
256+ with GridFiles do
257+ ShellExecute(Handle,'open',Pchar(INCBS(cells[CPATH,row])+cells[CFILE,row]),'','',1);
258+end;
259+
260+procedure TTextDeFindForm.PFileFolderClick(Sender: TObject);
261+begin
262+ with GridFiles do
263+ ShellExecute(Handle,'open',Pchar(INCBS(cells[CPATH,row])),'','',1);
264+
265+end;
266+
211267 procedure TTextDeFindForm.PFileOpenClick(Sender:TObject);
212268 begin
213269 OpenDialog.DefaultExt:='csv';
@@ -257,72 +313,138 @@
257313
258314 end;
259315
260-function INCBS(const s:string):string;
261-begin
262- Result:=s;
263- if not IsPathDelimiter(Result,Length(Result)) then Result:=Result+'\';
264-end;
265316
266-function EXCBS(const s:string):string;
317+
318+function gridInRect(X,Y:Integer;const r:TGridRect):boolean;
267319 begin
268- Result:=s;
269- if IsPathDelimiter(Result,Length(Result)) then SetLength(Result,Length(Result)-1);
320+ Result:=true;
321+ if ((X<r.left)or(X>r.right)or(Y<r.top)or(Y>r.Bottom)) then Result:=false;
270322 end;
271323
272-function GetFilePathDataObject(G:TStringGrid):IDataObject;
324+procedure TTextDeFindForm.GridFilesMouseDown(Sender:TObject;Button:TMouseButton;
325+ Shift:TShiftState;X,Y:Integer);
273326 var
274- fDesktop,fTargetFolder:IShellFolder;
275- Filepidl :packed array of PItemIDList;
276- Dirpidl :PItemIDList;
277- pchEaten,dwAttributes :Cardinal;
278- Dir,FileName :Widestring;
279- i,r,count :Integer;
280- SourceFile :string;
327+ ACol,ARow:Longint;
328+
281329 begin
282- Result:=nil;
330+ Files.MouseToCell(X,Y,ACol,ARow);
331+ if gridInRect(ACol,ARow,Files.selection) then exit;
332+ Files.MouseToCell(X,Y,ACol,ARow);
283333
284- count:=G.selection.Bottom-G.selection.top+1;
285- SetLength(Filepidl,count);
286- for i:=0 to count-1 do begin
287- r:=i+G.selection.top;
334+end;
288335
289- SourceFile:=INCBS(G.cells[2,r])+G.cells[1,r];
290- if not FileExists(SourceFile) then exit;
291336
292- Dir:=ExtractFileDir(SourceFile);
293- FileName:=ExtractFileName(SourceFile);
337+procedure TTextDeFindForm.TreeClick(Sender: TObject);
338+var N:TTreeNode;
339+ppname:string;
340+i:integer;
294341
295- SHGetDesktopFolder(fDesktop);
296342
297- if Failed(fDesktop.ParseDisplayName(0,nil,PWideChar(Dir),pchEaten,Dirpidl,dwAttributes)) then exit;
298- if Failed(fDesktop.BindToObject(Dirpidl,nil,IID_IShellFolder,fTargetFolder)) then exit;
299- if Failed(fTargetFolder.ParseDisplayName(0,nil,PWideChar(FileName),pchEaten,Filepidl[i],dwAttributes)) then
300- end;
343+begin
301344
302- if count<1 then exit;
345+ ppname:=Name.Text;
303346
304- fTargetFolder.GetUIObjectOf(0,count,Filepidl[0],IDataObject,nil,Pointer(Result));
347+
348+// for i:=Name.Items.Count-1 downto 1 do
349+// Name.Items.Delete(i);
350+
351+ Tmp.Clear;
352+ N:=Tree.Items.GetFirstNode;
353+ while N<>nil do begin
354+ Tmp.Items.add(N.Text);
355+ N:=N.getNextSibling;
356+ end;
357+ Name.Enabled:=false;
358+ Name.Items.Text:=Tmp.Items.text;
359+// Name.ItemIndex:=-1;
360+// Name.Text:=ppname;
361+ Name.ItemIndex:=Name.Items.IndexOf(ppname);
362+// Application.ProcessMessages;
363+ Name.Enabled:=true;
305364 end;
306365
307-
308-function gridInRect(X,Y:Integer;const r:TGridRect):boolean;
366+procedure TTextDeFindForm.Button1Click(Sender: TObject);
309367 begin
310- Result:=true;
311- if ((X<r.left)or(X>r.right)or(Y<r.top)or(Y>r.Bottom)) then Result:=false;
368+ TreeClick(Sender);
312369 end;
313370
314-procedure TTextDeFindForm.GridFilesMouseDown(Sender:TObject;Button:TMouseButton;
315- Shift:TShiftState;X,Y:Integer);
316-var
317- ACol,ARow:Longint;
318371
372+procedure TTextDeFindForm.NameChange(Sender: TObject);
373+var N,NN:TTreeNode;
374+s:string;
375+ function childtext(N:TTreeNode):string;
376+ begin
377+ N:=N.getFirstChild;
378+ while N<>nil do begin
379+ Text.Lines.add(N.Text);
380+ N:=N.getNextSibling;
381+ end;
382+
383+ end;
384+
385+
319386 begin
320- Files.MouseToCell(X,Y,ACol,ARow);
321- if gridInRect(ACol,ARow,Files.selection) then exit;
322- Files.MouseToCell(X,Y,ACol,ARow);
387+ if Trim(pname)<>'' then begin
388+ N:=Tree.Items.GetFirstNode;
389+ NN:=nil;
390+ while N<>nil do begin
391+ if N.text=pname then begin
392+ NN:=N;
393+ break;
394+ end;
395+ N:=N.getNextSibling;
396+ end;
397+ if Trim(Text.lines.Text)='' then begin //空ならリストから消す
398+ if NN<>nil then begin
399+ NN.Delete;
400+ TreeClick(Sender);
401+ end;
323402
403+ end else begin //空以外ならリストへ
404+ if NN=nil then begin
405+ NN:=Tree.Items.Add(nil,pname);
406+ TreeClick(Sender);
407+ end;
408+
409+ NN.DeleteChildren;
410+ for s in Text.lines do
411+ Tree.Items.AddChild(NN,s);
412+
413+ end;
414+
415+ end;
416+
417+ Text.Text:='';
418+ N:=Tree.Items.GetFirstNode;
419+ while N<>nil do begin
420+ if N.text=Name.text then begin
421+ childtext(N);
422+ end;
423+ N:=N.getNextSibling;
424+ end;
425+
426+
427+
428+
429+
430+// if Trim(Text.lines.Text)<>'' then begin
431+// Ini.EraseSection(Name.Text);
432+//
433+// Tmp.Items.LoadFromFile(Ini.FileName);
434+// Tmp.Items.Add('['+Name.Text+']');
435+// Tmp.Items.AddStrings(Text.Lines);
436+// Tmp.Items.SaveToFile(Ini.FileName);
437+//
438+// end;
439+// Ini.ReadSection(Name.Text,Tmp.Items);
440+// Text.lines.Text:=Tmp.Items.Text;
441+// Text.lines.Text:=
442+// Ini.ReadSectionValues(Name.Text,Text.lines);
443+
444+ pname:=Name.Text;
324445 end;
325446
447+
326448 procedure TTextDeFindForm.FindClick(Sender:TObject);
327449 var
328450 op :TSearchOption;
@@ -330,14 +452,39 @@
330452 s,ss :string;
331453 snm,nm:string;
332454 sub :boolean;
455+
456+ function hankaku(Str : String) : String;//全角半角
457+ var
458+  Buf:array [0 .. 1023] of Char;
459+ begin
460+  LCMapString(GetUserDefaultLCID, LCMAP_HALFWIDTH, PChar(Str), Length(Str)+1, Buf, 1024);
461+  Result:=String(Buf);
462+ end;
463+ function hira(Str : String) : String; //カタカナひらがな
464+ var
465+  Buf:array [0 .. 1023] of Char;
466+ begin
467+  LCMapString(GetUserDefaultLCID, LCMAP_FULLWIDTH, PChar(Str), Length(Str)+1, Buf, 1024);
468+  Str:=String(Buf);
469+  LCMapString(GetUserDefaultLCID, LCMAP_HIRAGANA, PChar(Str), Length(Str)+1, Buf, 1024);
470+  Result:=String(Buf);
471+ end;
472+
473+ function findr(s:string):string;
474+ begin
475+ s:=s.ToUpper;
476+ s:=hankaku(s);
477+ result:=s;
478+ end;
333479 begin
334480 try
335481 Screen.Cursor:=crHourGlass;
336482 Application.ProcessMessages;
483+ Path.Text:=incbs(Path.Text);
484+// snm:=ExtractFileName(Path.Text);
485+// if snm='' then
486+ snm:='*';
337487
338- snm:=ExtractFileName(Path.Text);
339- if snm='' then snm:='*';
340-
341488 // if sub then
342489 op:=TSearchOption.soAllDirectories;
343490 // else
@@ -344,20 +491,22 @@
344491 // op := TSearchOption.soTopDirectoryOnly;
345492 SA:=TDirectory.GetFiles(Path.Text,snm,op);
346493 Files.RowCount:=1;
347- Files.ColCount:=3;
494+ Files.ColCount:=4;
495+ Files.Rows[0].setstrings(['','検索文字','ファイル','パス']);
348496
349497 for s in SA do begin
350498 for ss in Text.lines do begin
351- nm:=Trim(ss);
499+ nm:=Trim(findr(ss));
352500 if nm='' then continue;
353501
354502 if Pos('*',nm)=0 then
355503 if Pos('?',nm)=0 then nm:='*'+nm+'*';
356- snm:=ExtractFileName(s);
504+ snm:=findr(ExtractFileName(s));
357505 if MatchesMask(snm,nm) then begin
358506 Files.RowCount:=Files.RowCount+1;
359- Files.cells[2,Files.RowCount-1]:=ExtractFileDir(s);
360- Files.cells[1,Files.RowCount-1]:=ExtractFileName(s);
507+ Files.cells[CTEXT,Files.RowCount-1]:=(nm);
508+ Files.cells[CPATH,Files.RowCount-1]:=ExtractFileDir(s);
509+ Files.cells[CFILE,Files.RowCount-1]:=ExtractFileName(s);
361510 break;
362511 end;
363512 end;
@@ -369,6 +518,52 @@
369518 end;
370519 end;
371520
521+
522+function TTextDeFindForm.GetFilePathDataObject(G:TStringGrid):IDataObject;
523+var
524+ fDesktop,fTargetFolder:IShellFolder;
525+ Filepidl :packed array of PItemIDList;
526+ Dirpidl :PItemIDList;
527+ pchEaten,dwAttributes :Cardinal;
528+ Dir,FileName :Widestring;
529+ i,r,count :Integer;
530+ SourceFile :string;
531+begin
532+ Result:=nil;
533+
534+ count:=G.selection.Bottom-G.selection.top+1;
535+ SetLength(Filepidl,count);
536+ SHGetDesktopFolder(fDesktop);
537+ if Failed(fDesktop.ParseDisplayName(0,nil,PWideChar(Path.text),pchEaten,Dirpidl,dwAttributes)) then exit;
538+ if Failed(fDesktop.BindToObject(Dirpidl,nil,IID_IShellFolder,fTargetFolder)) then exit;
539+
540+
541+ for i:=0 to count-1 do begin
542+ r:=i+G.selection.top;
543+
544+ SourceFile:=INCBS(G.cells[CPATH,r])+G.cells[CFILE,r];
545+ if not FileExists(SourceFile) then exit;
546+
547+ Dir:=ExtractFileDir(SourceFile);
548+ FileName:=ExtractRelativePath(INCBS(Path.text),SourceFile);
549+
550+ if Failed(fTargetFolder.ParseDisplayName(0,nil,PWideChar(FileName),pchEaten,Filepidl[i],dwAttributes)) then exit;
551+
552+ end;
553+
554+ if count<1 then exit;
555+
556+ fTargetFolder.GetUIObjectOf(0,count,Filepidl[0],IDataObject,nil,Pointer(Result));
557+end;
558+
559+
560+
561+//--------------------------------------------------------------------------------
562+
563+
564+
565+
566+
372567 procedure TGrid.copy(G:TGrid);
373568 var
374569 r:TGridRect;
@@ -546,7 +741,6 @@
546741 end;
547742
548743 function TGrid.load(fn:string):boolean;
549-const CHEAD=',ファイル,パス';
550744 var
551745 i :Integer;
552746 TMP:TStringList;
@@ -566,8 +760,8 @@
566760 Rows[i]:=TMP;
567761 end;
568762
569- ColCount:=SplitString(CHEAD,',').count;
570- Rows[0].CommaText:=CHEAD;
763+ ColCount:=CHEAD.count;
764+ Rows[0].setstrings(CHEAD);
571765 setfixed;
572766
573767 savebuf;
@@ -645,6 +839,8 @@
645839 inherited;
646840 end;
647841
842+
843+
648844 procedure TGrid.MouseMove(Shift:TShiftState;X,Y:Integer);
649845 var
650846 DataObject:IDataObject;
@@ -653,6 +849,8 @@
653849 ACol,ARow :Longint;
654850 savesel :TGridRect;
655851
852+
853+
656854 begin
657855 MouseToCell(X,Y,ACol,ARow);
658856 if not downinselection then begin
@@ -675,7 +873,7 @@
675873 //BeginDrag(true);
676874
677875 //ファイル名からIDataObjectを取得
678- DataObject:=GetFilePathDataObject(Self);
876+ DataObject:=TextDeFindForm.GetFilePathDataObject(Self);
679877 //OLEドラッグ&ドロップ開始
680878 dwEffect:=DROPEFFECT_NONE;
681879 DoDragDrop(DataObject,TextDeFindForm,DROPEFFECT_COPY,dwEffect);
@@ -859,6 +1057,18 @@
8591057 end;
8601058
8611059 //初期化処理
1060+{ TStringsHelper }
1061+
1062+function TStringsHelper.setstrings(sa: TStringDynArray): Integer;
1063+var i:integer;
1064+begin
1065+ for i:=0 to sa.Count-1 do
1066+ if i<Count then
1067+ Self[i]:=sa[i];
1068+
1069+
1070+end;
1071+
8621072 initialization
8631073
8641074 SHGetMalloc(Malloc);