// Scan items to see if listing is necessary void FXDirList::scan(FXbool force){ FXString pathname; FXDirItem *item; FXStat info; // Do root first time if(!firstitem || force){ listRootItems(); } // Check all items item=(FXDirItem*)firstitem; while(item){ // Is directory already populated? if(item->isDirectory() && item->getFirst()){ // Get the full path of the item pathname=getItemPathname(item); // Stat this directory; should not fail as parent has been scanned already FXStat::statFile(pathname,info); // Get the mod date of the item FXTime newdate=info.modified(); // Forced, date was changed, or failed to get proper date and counter expired if(force || (item->date!=newdate) || (counter==0)){ // And do the refresh listChildItems(item,force,true); // Remember when we did this item->date=newdate; } // Go deeper if(item->first){ item=(FXDirItem*)item->first; continue; } } // Go up while(!item->next && item->parent){ item=(FXDirItem*)item->parent; } // Go to next item=(FXDirItem*)item->next; } }
void GMSyncTask::update() { GMTrackFilenameList tracklist; FXStringList pathlist; FXStat data; database->beginTask(); taskmanager->setStatus("Updating Files.."); for (FXint i=0;i<files.no() && processing;i++) { database->getPathList(files[i],pathlist); for (FXint p=0;p<pathlist.no() && processing;p++) { const FXString & path = pathlist[p]; if (!options.exclude_folder.empty() && filter_path(options.exclude_folder,path)) continue; const FXint path_index = dbtracks.hasPath(path); database->getFileList(path,tracklist); for (FXint t=0;t<tracklist.no() && processing;t++) { const FXString & name = tracklist[t].filename; if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) { if (FXStat::statFile(path+PATHSEPSTRING+name,data)) { if (data.isReadable()) parse_update(path,name,options_sync.update_always ? forever : data.modified(),path_index); else parse_update(path,name,0,path_index); } else if (options_sync.remove_missing) { dbtracks.remove(tracklist[t].id); changed=true; } } } if (processing) update_tracks(path_index); } } if (changed) { database->sync_album_year(); database->sync_tracks_removed(); } database->commitTask(); }
void GMSyncTask::traverse(const FXString & path,Seen * seen,FXlong index) { FXDir directory; FXStat data; FXString name; // Location Seen here={seen,index}; // First scan subfolders if (directory.open(path)) { while(directory.next(name) && processing) { if (FXStat::statLink(path+PATHSEPSTRING+name,data)) { if (data.isDirectory()) { if(!(name[0]=='.' && (name[1]==0 || (name[1]=='.' && name[2]==0)))){ for(Seen *s=seen; s; s=s->next){ if(data.index()==s->node) goto next_dir; } if (options.exclude_folder.empty() || !FXPath::match(name,options.exclude_folder,matchflags)) traverse(path+PATHSEPSTRING+name,&here,data.index()); } } } next_dir:; } directory.close(); } // Scan files in current folder if(directory.open(path) && processing) { FXint path_index = dbtracks.hasPath(path); while(directory.next(name) && processing) { if (FXStat::statFile(path+PATHSEPSTRING+name,data)) { if (!data.isDirectory() && data.isReadable()) { if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) { if (FXPath::match(name,FILE_PATTERNS,matchflags)) { parse_update(path,name,options_sync.update_always ? forever : data.modified(),path_index); } } } } } if (processing) update_tracks(path_index); } }
// List child items void FXDirList::listChildItems(FXDirItem *par,FXbool force,FXbool notify){ FXDirItem *oldlist=par->list; FXDirItem *newlist=NULL; FXDirItem **po=&oldlist; FXDirItem **pn=&newlist; FXDirItem *olditem=NULL; FXDirItem *newitem=NULL; FXDirItem *link; FXString pathname; FXString directory; FXString name; FXStat info; FXDir dir; FXuint mode; //FXTRACE((1,"FXDirList::listChildItems(%p = \"%s\",%s)\n",par,par->getText().text(),force?"true":"false")); // Path to parent node directory=getItemPathname(par); // Managed to open directory if(dir.open(directory)){ // Process directory entries while(dir.next(name)){ // Never show "." and ".." in the directory list widget if(name[0]=='.' && (name[1]==0 || (name[1]=='.' && name[2]==0))) continue; // Normally don't show hiden files or directories if(name[0]=='.' && !(options&DIRLIST_SHOWHIDDEN)) continue; // Build full pathname of entry pathname=directory; if(!ISPATHSEP(pathname.tail())) pathname+=PATHSEPSTRING; pathname+=name; #ifdef WIN32 // Get file/link info if(!FXStat::statFile(pathname,info)) continue; mode=info.mode(); // Normally don't show hiden files or directories if((mode&FXIO::Hidden) && !(options&DIRLIST_SHOWHIDDEN)) continue; #else // Get file/link info if(!FXStat::statLink(pathname,info)) continue; mode=info.mode(); // If its a link, get file mode from target if(info.isLink()){ mode=FXStat::mode(pathname) | FXIO::SymLink; } #endif // Skip item if it is a file and we want only directories, or if it fails to match wildcard pattern if(!(mode&FXIO::Directory) && !((options&DIRLIST_SHOWFILES) && FXPath::match(name,pattern,matchmode))) continue; // Find it, and take it out from the old list if found for(FXDirItem** pp=po; (olditem=*pp)!=NULL; pp=&olditem->link){ if(compare(olditem->label,name)==0){ *pp=olditem->link; olditem->link=NULL; break; } } // Use a new item if forced, if there was no old item, or if the item information was changed if(force || !olditem || olditem->getDate()!=info.modified() || olditem->getSize()!=info.size() || olditem->getMode()!=mode){ // Make new item newitem=(FXDirItem*)createItem(name,NULL,NULL,NULL); // Update item information newitem->setDraggable(draggable); newitem->setAssoc(NULL); newitem->setSize(info.size()); newitem->setDate(info.modified()); newitem->setMode(mode); // Determine icons and type if(newitem->isDirectory()){ newitem->setHasItems(true); newitem->setOpenIcon(opendiricon); newitem->setClosedIcon(closeddiricon); if(associations) newitem->setAssoc(associations->findDirBinding(pathname)); } else if(newitem->isExecutable()){ newitem->setHasItems(false); newitem->setOpenIcon(applicationicon); newitem->setClosedIcon(applicationicon); if(associations) newitem->setAssoc(associations->findExecBinding(pathname)); } else{ newitem->setHasItems(false); newitem->setOpenIcon(documenticon); newitem->setClosedIcon(documenticon); if(associations) newitem->setAssoc(associations->findFileBinding(pathname)); } // If association is found, use it if(newitem->getAssoc()){ if(newitem->getAssoc()->miniicon) newitem->setClosedIcon(newitem->getAssoc()->miniicon); if(newitem->getAssoc()->miniiconopen) newitem->setOpenIcon(newitem->getAssoc()->miniiconopen); } // Create item if(id()) newitem->create(); // Replace existing item or add new one if(olditem){ newitem->list=olditem->list; // Old items list of children setItem(olditem,newitem,notify); } else{ appendItem(par,newitem,notify); } *pn=newitem; pn=&newitem->link; // Hang newitem in list } // No change else{ *pn=olditem; pn=&olditem->link; // Hang olditem in list } } dir.close(); } // Wipe items remaining in list:- they have disappeared!! for(olditem=oldlist; olditem; olditem=link){ link=olditem->link; removeItem(olditem,notify); } // Now we know for sure whether we really have subitems or not par->setHasItems(!!par->first); // Remember new list par->list=newlist; // Update sort order sortChildItems(par); // Need to layout recalc(); }