2020-12-18 12:38 PM
Hello!
I have code, working with FatFS in system area of my project.
main.c
res = f_opendir(&dir, "0:/");
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
fn = fileInfo.fname;
// ... some code
}
else break;
}
f_closedir(&dir);
And I have scrollList widget, where I want to show filelist.
How can I send list of filenames to widget by Model->Presenter->View ?
What can you advise for me?
Solved! Go to Solution.
2020-12-19 11:28 AM
"no dir handle is private and all operation is created and closed in screen in my example."
YOu mean like this:
void STORAGE_SCREENView::setupScreen()
{
DIR dir;
FILINFO fileInfo;
if (f_mount(&fileSystem, "", 0) == FR_OK)
{
res = f_opendir(&dir, "0:/");
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
fn = fileInfo.fname;
(*(FileList_Container*)scrollList1ListItems.getDrawable(fc)).SetItemFName(fileInfo.fname);
}
}
}
}
That is, I first fill the container by reading the folder. and then when i selected something, i found out the item number, do i have to read the folder again and look for the file with the received number? Isn't it easier to read the name in textarea and just open the file with the corresponding name in the folder?
2020-12-19 11:31 AM
I know that 10, is the previous code, i then learned to fill the container with a pre-known number of pre-known elements, do not pay attention.
2020-12-19 11:43 AM
No this will work only when count lines in list on display without scrolling +2 is more as count of files.
In real touch is lines refreshed ontime when scrolling. Then code need update it ontime too.
DIR dir; // can here or in hpp as protected
void STORAGE_SCREENView::setupScreen()
{
if (f_mount(&fileSystem, "", 0) == FR_OK)
{
res = f_opendir(&dir, "0:/");
getcount
}
scrollList1.setNumberOfItems(filescount);
}
void STORAGE_SCREENView::scrollList1UpdateItem(FileList_Container& item, int16_t itemIndex)
{
only semantic
use dir handle
set file on itemindex pos
get filename
item.SetItemFName(fileInfo.fname);
}
2020-12-19 11:51 AM
OK, it seems I understand you.
So, I read directory twice - at first - when I fill container, at second - when I selected file an get number of container element ?
2020-12-19 11:57 AM
I dont rememmber if file function have methods to get count or set position in dir, when no use your while in update method and for count too.
But in setup you dont fill container. This handle update list method.
I see trouble in repeat res = readdir without reset position to start
2020-12-19 12:01 PM
Like this
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
if (files_found==itemIndex) fn = fileInfo.fname;
}
files_found++;
}
2020-12-19 12:14 PM
no you need use
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD index; /* Index of directory entry to start to search next */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _USE_LFN
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Index of last matched LFN entry (0xFFFF:No LFN) */
#endif
} DIR;
your code here
void STORAGE_SCREENView::setupScreen()
{
if (f_mount(&fileSystem, "", 0) == FR_OK)
{
res = f_opendir(&dir, "0:/");
files_found=0;
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
files_found++;
}
else break;
}
}
scrollList1.setNumberOfItems( files_found);
}
void STORAGE_SCREENView::scrollList1UpdateItem(FileList_Container& item, int16_t itemIndex)
{
files_found=0;
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
if (files_found==itemIndex) break;
}
files_found++;
}
item.SetItemFName(fileInfo.fname);
}
2020-12-19 12:20 PM
Thanks, this code I understood,
Next - I click to "myfile.txt" - is element of scrollist woth itemindex=5. I want to get it filename.
This code
while(1)
{
res = f_readdir(&dir, &fileInfo);
if (res==FR_OK && fileInfo.fname[0])
{
if (files_found==itemIndex)
{
fn = fileInfo.fname;
break;
}
}
files_found++;
}
will be good?
Or you mean something other?
2020-12-19 12:27 PM
Yes , but i mean you need add dir.index=1 or 0 before while and when you have external SDRAM , more better is read full dir to array as i write.
when you dont have deleted files in dir maybe while isnt necessary in update and before res try use dir.index=itemIndex-1
2020-12-19 12:42 PM
Thanks!!!
Can I ask another question?
I have problem with cyrillic symbols.
At first I had string
const char* FileList[10] = {"абвгд","�?БВГД", "абвгд","�?БВГД","абвгд","�?БВГД","абвгд","�?БВГД","абвгд","�?БВГД"};
and this code for output
Unicode::UnicodeChar buffer[20];
Unicode::strncpy(buffer, FileList[data], 20);
Unicode::snprintf(textArea1Buffer, 20, "%s", buffer);
textArea1.setWildcard(textArea1Buffer);
textArea1.invalidate();
It was problem to print cyrillic symbols, which solved by replacing
Unicode::strncpy(buffer, FileList[data], 20);
to
Unicode::fromUTF8((const uint8_t*)FileList[data],buffer, 20);//
Now I have cyrillic filenames in RAM, which coded in CP1251
How can I output theese filenames to TextArea?