Recent

Author Topic: Selecting, not opening, multiple files so as to use path/file names  (Read 6572 times)

stephanos14

  • Newbie
  • Posts: 6
Dear All
I have written a playlist programme for my mp3 player in Lazarus 2.0.8.  It writes to an M3U file on the player and the programme is on the player as well.  When the programme starts it reads the M3U file and places the content into a memo:
     
Code: Pascal  [Select][+][-]
  1. Memo1.Lines.LoadFromFile('PlayListStephen.m3u');
   

I have been using a TfileNameEdit window (and the OnChange event), to navigate to an MP3 file and select it.  Then append it to the memo content:
   
Code: Pascal  [Select][+][-]
  1. TheFileName := FileNameEdit1.Text; // a variable :=  the path/file name
  2.       menuString := Memo1.Lines.Text; // a variable :=  the memo text
  3.       menuString := Concat(menuString, TheFileName); // concat the two variables
// Now write new content of menuString back into the Play List Window (Memo.Lines.Text)
 
Code: Pascal  [Select][+][-]
  1.  Memo1.Lines.Text := menuString;

This works fine for one mp3 file selection.  But I want to expand the programme to select multiple files.  To this end I have set “OfAllowMultuSelect” of TfileNameEdit, to true.  I can now select multiple files from within the Open window.  When two or more files are selected their names appear in the input window (.Text property).  However, the File Name input of the Open dialogue box shows the two files I selected, each contained in double quotes with a space between them.  Like this: [ "SimpleForms.res" "SimpleForms.exe" ].  After pressing the Open button, I have coded to place the content of the Text property input to a variable:
     
Code: Pascal  [Select][+][-]
  1. TheFileName := FileNameEdit1.Text;
and then use it as a caption for a label, just to make sure I have both file names:
   
Code: Pascal  [Select][+][-]
  1.  Label10.Caption := TheFileName;
The output/Caption is:
     C:\Users\stephanos\MyFiles\Delphi(Lazarus)\PlayListV11\SimpleForms.exe

But I do not have both file names.  Only the file name of the first selected file, and its full path.  The full path is needed as are subsequent file names.

What is the best way to achieve this objective?

The answer appears to be use the onAcceptFileName event and SynEdit (SynMemo being deprecated).  I added to “uses”:
    SynEdit, SynEditKeyCmds;
but got this error message at compile:
   “Compile Project, Target: SimpleForms.exe: Exit code 1, Errors: 1
     simpleformsunit.pas(8,3) Fatal: Cannot find SynEdit used by SimpleFormsUnit.
     Check if package SynEdit is in the dependencies of the Project Inspector.”

I found the Project Inspector but cannot progress as it is all new to me.  I looked around but cannot find any clear instructions.  I am using Windows 10 and Lazarus 2.0.8.

Any help appreciated and I also recognise this is a big ask

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #1 on: June 06, 2021, 07:48:12 pm »
apparently the

FileNameEdit1.DialogFiles.Text contains the list after the dialog closes with full path for each entry

The only true wisdom is knowing you know nothing

stephanos14

  • Newbie
  • Posts: 6
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #2 on: June 06, 2021, 09:24:35 pm »
Dear jamie

Thanks.  But the reality is it does not or it does not when I want to use the variable for the caption of a label.

There is much I do not know.  Can you assist further?

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #3 on: June 06, 2021, 10:30:38 pm »
Yes, it appears that control is a little buggy..

The OnAcceptFileName comes in before the DialogFiles gets populated.

Here is an work around with code to show you how to scroll through the list.

This is just a part you need to drop into an app, add the FIleNameEditIndex in the form ..
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FileNameEdit1Change(Sender: TObject);
  2. begin
  3.   If Not FileNameEdit1.Modified Then
  4.    Begin
  5.     Memo1.Text := FileNameEdit1.DialogFiles.Text;
  6.    end;
  7.  FileNameEdit1.Modified := false;
  8. end;
  9.  
  10. procedure TForm1.FileNameEdit1KeyDown(Sender: TObject; var Key: Word;
  11.   Shift: TShiftState);
  12. begin
  13.  if FileNameEdit1.DialogFiles.Count <> 0 THen
  14.   Begin
  15.   If Key =VK_up Then
  16.     Begin
  17.       FileNameEditIndex := (FIleNameEditIndex-1) mod FileNameEdit1.DialogFiles.Count;
  18.       if FIleNameEditIndex < 0 Then FileNameEditIndex := FileNameEdit1.DialogFiles.Count-1;
  19.     End
  20.      else
  21.   If key=VK_Down Then
  22.           FileNameEditIndex := (FileNameEditIndex+1) mod FileNameEdit1.DialogFiles.Count;
  23.       FileNameEdit1.Caption :=
  24.         FileNameEdit1.DialogFiles[FileNameEditIndex];
  25.    FileNameEDit1.Modified := True;
  26.   end;
  27. end;
  28.  
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #4 on: June 06, 2021, 10:55:44 pm »
I found the missed up location in the source file
if you want to fix it you can but do as you please. Maybe I should report this...

Looks like someone was having fun, must likely more of this in there.
Code: Pascal  [Select][+][-]
  1. procedure TFileNameEdit.SaveDialogResult(AKind: TDialogKind; D: TCommonDialog);
  2. var
  3.   FN: String;
  4. begin
  5.   case AKind of
  6.     dkOpen, dkPictureOpen :
  7.     begin
  8.       FilterIndex := TOpenDialog(D).FilterIndex;
  9.       FN := TOpenDialog(D).FileName;
  10.       if (FN <> '') then
  11.       begin
  12.         if Assigned(OnAcceptFileName) then
  13.           OnAcceptFileName(Self, FN);
  14.       end;
  15.       if (FN <> '') then
  16.       begin
  17.         // set FDialogFiles first since assigning of FileName trigger events
  18.         FDialogFiles.Text := TOpenDialog(D).Files.Text;
  19.         FileName := FN;
  20.       end;
  21.     end;
  22.     dkSave, dkPictureSave :
  23.     begin
  24.       FileName := TSaveDialog(D).FileName;
  25.       FilterIndex := TSaveDialog(D).FilterIndex;
  26.       FDialogFiles.Clear;
  27.     end;
  28.   end;
  29. end;                              
  30.  

Examine that and tell me what you fine that looks wrong. Also take note of the comment left there.  %)
The only true wisdom is knowing you know nothing

stephanos14

  • Newbie
  • Posts: 6
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #5 on: June 29, 2021, 02:15:31 pm »
Dear Jamie

Thank for all that but, I am not knowledgeable enough to understand any of it.  For example the
“If Not FileNameEdit1.Modified Then”
Is .Modifed an event or a property?  I cannot find either with that name.

I understand “procedure TForm1.FileNameEdit1Change(Sender: Tobject);” as that is where I have written the code that I submitted.

In addition this bit of code is confusing as well
“procedure TFileNameEdit.SaveDialogResult(AKind: TDialogKind; D: TcommonDialog);”
It looks like an Event but not one I see listed

Perhaps I gave the impression I know more than I did when I submitted the question.  However, I have coded for very few events and only know about a few properties.

Much more novice orientated assistance required, if possible


jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #6 on: June 29, 2021, 11:57:54 pm »
Dear stephanos14

  I realize some new adventures may require a steep learning curve.

  The control you are using has some quirks in it but is useable but you need to at times look at the source code of the control which is included in Lazarus to study the reasons why the life of the control goes on as it does.

  The examples I gave above minus the code frag that is in the last post I made was an example of how to get the list of files you selected and also scroll through those entries once the file dialog exits.

 The FileName returned is the first one listed as you have already seen however, all of the files you selected are in the DialogFiles property..

 FileNameEdit.DialogFIles;

 This is a StringList, it contains your complete list however, this list isn't valid with this control until the OnChange event of the FileEditName is triggered after the dialog closes.

 The use of the MODIFIED property is to inform you who changed the content within the EDIT field of the control, if it is set, then this means the user was typing in there that caused the change otherwise it was the File Dialog that caused the change when it set the value to the FILE NAME..
   
 Using the MODIFIED property is a way to determine who changed the EDIT field, the user or was it in code?

 In any case, within the OnChange event you can then examine the FileNameEdit.DialogFiles string list for all the files you selected.
The only true wisdom is knowing you know nothing

stephanos

  • New Member
  • *
  • Posts: 38
Re: Selecting, not opening, multiple files so as to use path/file names
« Reply #7 on: July 07, 2021, 09:18:18 pm »
Dear Jamie and others

I have made considerable progress with selecting multiple files and processing the paths/file names.  Thanks.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FileNameEdit1Change(Sender: TObject);
  2. var
  3.           loop, count, size : integer;
  4. begin
  5.     loop := 1; count := 0; size := 0;  //
  6. // Select your MP3 file(s).  The full path and file names are returned in FileNameEdit1.DialogFiles.Text,
  7. // which is populated with the path/file name(s) after the dialog box is closed/
  8. // First - test to see how many files have been selected using ".mp3" as the counter.  Remember, there is a
  9. // newline between each file path/name
  10.      TheFileName := FileNameEdit1.DialogFiles.Text;  // Parse the list of files to a string
  11.      FileNameEdit1.DialogFiles.Text := '';  // Empty .DialogFiles.Text so that the content is no longer used
  12.      size := Length(TheFileName);  // the size of the string, including #13#10 between files and at the end
  13.  
  14.   // loop through the string and count the number of '.mp3'
  15.      while loop < size do  // |Iterate 1 - 89 times, but not really
  16.      begin
  17.           Tag := PosEx('.mp3', TheFileName, loop); // never use zero
  18.           if Tag > 1 then
  19.           begin
  20.              Inc(count, 1);   // the occurrences of '.mp3' in the string
  21.              loop := (Tag + 6);
  22.              Label3.Caption := 'You have ' + IntToStr(count) + ' file(s) waiting to be written to the M3U (PlayList) file '#13#10'Press Save';
  23.           end
  24.           else  // If no .mp3 is found anywhere in the string of file paths/names, exit the loop
  25.           begin
  26.                loop := size + 1;
  27.                Label3.Caption := 'No mp3 found';
  28.           end;
  29.      end;
  30.  
  31. // Second - If you found at least 1 occurrence of '.mp3', count will be greater than zero
  32.    // remove all occurrences of C:\Music from the string.
  33.    if count > 0 then
  34.    begin
  35.       for loop := 1 to count do // loop 2 times, the number of files found
  36.       begin
  37.            Delete(  TheFileName, (Pos('Music',TheFileName)-3) , length('C:\Music\')  );
  38.       end;
  39.    // now append the file(s) to the current content of the Play List window
  40.       menuString := Memo1.Lines.Text; // Copy the current content of the Play List Window to menuString
  41.       menuString := Concat(menuString, TheFileName); // Append the new entry or entries to menuString
  42.    // Now write new content of menuString back into the Play List Window (Memo.Lines.Text)
  43.       Memo1.Lines.Text := menuString;
  44.    end;
  45.    FileNameEdit1.Text := 'To append a song or songs to the Play List Window press this button -> ';
  46.    TheFileName := '';  //FileNameEdit1.Text := '';
  47. //
  48. end;

I did not need to scroll through the selection.

Thanks to all.  This is now closed.  More to come.

 

TinyPortal © 2005-2018