Merge pull request #1353 from csoler/v0.6-FileLists

V0.6 file lists
This commit is contained in:
csoler 2018-09-30 13:31:26 +02:00 committed by GitHub
commit 79a8b2183f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 295 additions and 98 deletions

View File

@ -865,7 +865,7 @@ void InternalFileHierarchyStorage::print() const
for(uint32_t i=0;i<mNodes.size();++i) for(uint32_t i=0;i<mNodes.size();++i)
if(mNodes[i] == NULL) if(mNodes[i] == NULL)
{ {
std::cerr << " Node " << i << ": empty " << std::endl; //std::cerr << " Node " << i << ": empty " << std::endl;
++nempty ; ++nempty ;
} }
else if(mNodes[i]->type() == FileStorageNode::TYPE_DIR) else if(mNodes[i]->type() == FileStorageNode::TYPE_DIR)
@ -1183,6 +1183,11 @@ bool InternalFileHierarchyStorage::load(const std::string& fname)
} }
free(buffer) ; free(buffer) ;
std::string err_str ;
if(!check(err_str))
std::cerr << "(EE) Error while loading file hierarchy " << fname << std::endl;
return true ; return true ;
} }
catch(read_error& e) catch(read_error& e)

View File

@ -25,6 +25,7 @@ static const uint32_t DELAY_BETWEEN_DIRECTORY_UPDATES = 600 ; // 10 m
static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ = 120 ; // 2 minutes static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ = 120 ; // 2 minutes
static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 sec. But we only update for real if something has changed. static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 sec. But we only update for real if something has changed.
static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP = 60 ; // 60 sec. static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP = 60 ; // 60 sec.
static const uint32_t DELAY_BETWEEN_EXTRA_FILES_CACHE_UPDATES = 2 ; // 2 sec.
static const uint32_t DELAY_BEFORE_DELETE_NON_EMPTY_REMOTE_DIR = 60*24*86400 ; // delete non empty remoe directories after 60 days of inactivity static const uint32_t DELAY_BEFORE_DELETE_NON_EMPTY_REMOTE_DIR = 60*24*86400 ; // delete non empty remoe directories after 60 days of inactivity
static const uint32_t DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR = 5*24*86400 ; // delete empty remote directories after 5 days of inactivity static const uint32_t DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR = 5*24*86400 ; // delete empty remote directories after 5 days of inactivity

View File

@ -37,7 +37,8 @@
#define P3FILELISTS_ERROR() std::cerr << "***ERROR***" << " : FILE_LISTS : " << __FUNCTION__ << " : " #define P3FILELISTS_ERROR() std::cerr << "***ERROR***" << " : FILE_LISTS : " << __FUNCTION__ << " : "
//#define DEBUG_P3FILELISTS 1 //#define DEBUG_P3FILELISTS 1
#define DEBUG_CONTENT_FILTERING 1 //#define DEBUG_CONTENT_FILTERING 1
//#define DEBUG_FILE_HIERARCHY 1
static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ;
static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ;
@ -71,6 +72,7 @@ p3FileDatabase::p3FileDatabase(p3ServiceControl *mpeers)
mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ; mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ;
mLastRemoteDirSweepTS = 0 ; mLastRemoteDirSweepTS = 0 ;
mLastExtraFilesCacheUpdate = 0;
mLastCleanupTime = 0 ; mLastCleanupTime = 0 ;
mLastDataRecvTS = 0 ; mLastDataRecvTS = 0 ;
mTrustFriendNodesForBannedFiles = TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT; mTrustFriendNodesForBannedFiles = TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT;
@ -884,6 +886,8 @@ void p3FileDatabase::requestDirUpdate(void *ref)
} }
} }
// Finds the pointer to the sub-element #row under element ref.
bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result,
FileSearchFlags flags ) const FileSearchFlags flags ) const
{ {
@ -891,10 +895,10 @@ bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result,
{ {
if(flags & RS_FILE_HINTS_LOCAL) if(flags & RS_FILE_HINTS_LOCAL)
{ {
if(row != 0) if(row != 0 && row != 1)
return false ; return false ;
convertEntryIndexToPointer<sizeof(void*)>(0,0,result); convertEntryIndexToPointer<sizeof(void*)>(0,row,result);
return true ; return true ;
} }
@ -913,12 +917,18 @@ bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result,
convertPointerToEntryIndex<sizeof(void*)>(ref,e,fi); convertPointerToEntryIndex<sizeof(void*)>(ref,e,fi);
// check consistency // check consistency
if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL))) if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 1 && (flags & RS_FILE_HINTS_LOCAL)))
{ {
P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl;
return false ; return false ;
} }
DirectoryStorage *storage = (fi==0)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]);
if(fi==1 && (flags & RS_FILE_HINTS_LOCAL)) // extra list
{
convertEntryIndexToPointer<sizeof(void*)>(row+1,1,result);
return true;
}
DirectoryStorage *storage = (flags & RS_FILE_HINTS_LOCAL)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]);
// Case where the index is the top of a single person. Can be us, or a friend. // Case where the index is the top of a single person. Can be us, or a friend.
@ -950,6 +960,78 @@ int p3FileDatabase::getSharedDirStatistics(const RsPeerId& pid,SharedDirStats& s
} }
} }
void p3FileDatabase::removeExtraFile(const RsFileHash& hash)
{
{
RS_STACK_MUTEX(mFLSMtx) ;
mExtraFiles->removeExtraFile(hash);
mLastExtraFilesCacheUpdate = 0 ; // forced cache reload
}
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIndex e,DirDetails& d) const
{
// update the cache of extra files if last requested too long ago
time_t now = time(NULL);
if(mLastExtraFilesCacheUpdate + DELAY_BETWEEN_EXTRA_FILES_CACHE_UPDATES <= now)
{
mExtraFiles->getExtraFileList(mExtraFilesCache);
mLastExtraFilesCacheUpdate = now;
}
//
if(e == 0) // "virtual extra files directory" => create a dir with as many child as they are extra files
{
d.parent = NULL ;
d.prow = 0;//fi-1 ;
d.type = DIR_TYPE_PERSON;
d.hash.clear() ;
d.count = mExtraFilesCache.size();
d.max_mtime = time(NULL);
d.mtime = time(NULL);
d.name = "[Extra List]";
d.path = "/";
d.ref = ref ;
for(uint32_t i=0;i<mExtraFilesCache.size();++i)
{
DirStub stub;
stub.type = DIR_TYPE_FILE;
stub.name = mExtraFilesCache[i].fname;
convertEntryIndexToPointer<sizeof(void*)>(i+1,1,stub.ref); // local shared files from extra list
d.children.push_back(stub);
}
}
else // extra file. Just query the corresponding data from ftExtra
{
d.prow = 1;//fi-1 ;
d.type = DIR_TYPE_EXTRA_FILE;
FileInfo& f(mExtraFilesCache[(int)e-1]) ;
d.hash = f.hash;
d.count = f.size;
d.max_mtime = 0; // this is irrelevant
d.mtime = 0; // this is irrelevant
d.name = f.path; // so that the UI shows the complete path, since the parent directory is not really a directory.
d.path = f.path;
d.ref = ref ;
convertEntryIndexToPointer<sizeof(void*)>(0,1,d.parent) ;
}
d.flags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ;
d.id = RsPeerId();
}
// This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files. // This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files.
int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const
{ {
@ -975,10 +1057,8 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
{ {
d.ref = NULL ; d.ref = NULL ;
d.type = DIR_TYPE_ROOT; d.type = DIR_TYPE_ROOT;
d.count = 1;
d.parent = NULL; d.parent = NULL;
d.prow = -1; d.prow = -1;
d.ref = NULL;
d.name = "root"; d.name = "root";
d.hash.clear() ; d.hash.clear() ;
d.path = ""; d.path = "";
@ -989,13 +1069,28 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
if(flags & RS_FILE_HINTS_LOCAL) if(flags & RS_FILE_HINTS_LOCAL)
{ {
void *p; void *p;
convertEntryIndexToPointer<sizeof(void*)>(0,0,p);
{
convertEntryIndexToPointer<sizeof(void*)>(0,0,p); // root of own directories
DirStub stub; DirStub stub;
stub.type = DIR_TYPE_PERSON; stub.type = DIR_TYPE_PERSON;
stub.name = mServCtrl->getOwnId().toStdString(); stub.name = mServCtrl->getOwnId().toStdString();
stub.ref = p; stub.ref = p;
d.children.push_back(stub); d.children.push_back(stub);
}
if(mExtraFiles->size() > 0)
{
convertEntryIndexToPointer<sizeof(void*)>(0,1,p); // local shared files from extra list
DirStub stub;
stub.type = DIR_TYPE_PERSON; // not totally exact, but used as a trick.
stub.name = "[Extra List]";
stub.ref = p;
d.children.push_back(stub);
}
} }
else for(uint32_t i=0;i<mRemoteDirectories.size();++i) else for(uint32_t i=0;i<mRemoteDirectories.size();++i)
if(mRemoteDirectories[i] != NULL) if(mRemoteDirectories[i] != NULL)
@ -1014,6 +1109,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
#ifdef DEBUG_FILE_HIERARCHY #ifdef DEBUG_FILE_HIERARCHY
P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl;
P3FILELISTS_DEBUG() << d << std::endl;
#endif #endif
return true ; return true ;
@ -1025,12 +1121,25 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
convertPointerToEntryIndex<sizeof(void*)>(ref,e,fi); convertPointerToEntryIndex<sizeof(void*)>(ref,e,fi);
// check consistency // check consistency
if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL))) if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 1 && (flags & RS_FILE_HINTS_LOCAL)))
{ {
P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl;
return false ; return false ;
} }
DirectoryStorage *storage = (fi==0)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]);
if((flags & RS_FILE_HINTS_LOCAL) && fi == 1) // extra list
{
getExtraFilesDirDetails(ref,e,d);
#ifdef DEBUG_FILE_HIERARCHY
P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl;
P3FILELISTS_DEBUG() << d << std::endl;
#endif
return true;
}
DirectoryStorage *storage = (flags & RS_FILE_HINTS_LOCAL)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]);
// Case where the index is the top of a single person. Can be us, or a friend. // Case where the index is the top of a single person. Can be us, or a friend.
@ -1085,7 +1194,7 @@ int p3FileDatabase::RequestDirDetails(const RsPeerId &/*uid*/, const std::string
// NOT_IMPLEMENTED(); // NOT_IMPLEMENTED();
// return 0; // return 0;
//} //}
uint32_t p3FileDatabase::getType(void *ref) const uint32_t p3FileDatabase::getType(void *ref,FileSearchFlags flags) const
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
@ -1100,12 +1209,25 @@ uint32_t p3FileDatabase::getType(void *ref) const
if(e == 0) if(e == 0)
return DIR_TYPE_PERSON ; return DIR_TYPE_PERSON ;
if(fi == 0 && mLocalSharedDirs != NULL) if(flags & RS_FILE_HINTS_LOCAL)
return mLocalSharedDirs->getEntryType(e) ; {
else if(fi-1 < mRemoteDirectories.size() && mRemoteDirectories[fi-1]!=NULL) if(fi == 0 && mLocalSharedDirs != NULL)
return mRemoteDirectories[fi-1]->getEntryType(e) ; return mLocalSharedDirs->getEntryType(e) ;
else
if(fi == 1)
return DIR_TYPE_EXTRA_FILE;
P3FILELISTS_ERROR() << " Cannot determine type of entry " << ref << std::endl;
return DIR_TYPE_ROOT ;// some failure case. Should not happen return DIR_TYPE_ROOT ;// some failure case. Should not happen
}
else
{
if(fi-1 < mRemoteDirectories.size() && mRemoteDirectories[fi-1]!=NULL)
return mRemoteDirectories[fi-1]->getEntryType(e) ;
P3FILELISTS_ERROR() << " Cannot determine type of entry " << ref << std::endl;
return DIR_TYPE_ROOT ;// some failure case. Should not happen
}
} }
void p3FileDatabase::forceDirectoryCheck() // Force re-sweep the directories and see what's changed void p3FileDatabase::forceDirectoryCheck() // Force re-sweep the directories and see what's changed

View File

@ -45,6 +45,7 @@
#pragma once #pragma once
#include "ft/ftsearch.h" #include "ft/ftsearch.h"
#include "ft/ftextralist.h"
#include "retroshare/rsfiles.h" #include "retroshare/rsfiles.h"
#include "services/p3service.h" #include "services/p3service.h"
@ -87,9 +88,10 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
// [...] more to add here // [...] more to add here
}; };
explicit p3FileDatabase(p3ServiceControl *mpeers) ; explicit p3FileDatabase(p3ServiceControl *mpeers);
~p3FileDatabase(); ~p3FileDatabase();
void setExtraList(ftExtraList *f) { mExtraFiles = f ; }
/*! /*!
* \brief forceSyncWithPeers * \brief forceSyncWithPeers
* *
@ -107,6 +109,9 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
virtual int SearchKeywords(const std::list<std::string>& keywords, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) ; virtual int SearchKeywords(const std::list<std::string>& keywords, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) ;
virtual int SearchBoolExp(RsRegularExpression::Expression *exp, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const ; virtual int SearchBoolExp(RsRegularExpression::Expression *exp, std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const ;
// Extra file list
virtual void removeExtraFile(const RsFileHash& hash);
// Interface for browsing dir hierarchy // Interface for browsing dir hierarchy
// //
@ -119,7 +124,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
void requestDirUpdate(void *ref) ; // triggers an update. Used when browsing. void requestDirUpdate(void *ref) ; // triggers an update. Used when browsing.
int RequestDirDetails(void *, DirDetails&, FileSearchFlags) const ; int RequestDirDetails(void *, DirDetails&, FileSearchFlags) const ;
uint32_t getType(void *) const ; uint32_t getType(void *, FileSearchFlags flags) const ;
// proxy method used by the web UI. Dont't delete! // proxy method used by the web UI. Dont't delete!
int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const; int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const;
@ -169,6 +174,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
bool hashingProcessPaused(); bool hashingProcessPaused();
protected: protected:
void getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIndex e,DirDetails& d) const;
int filterResults(const std::list<void*>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const; int filterResults(const std::list<void*>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const;
std::string makeRemoteFileName(const RsPeerId& pid) const; std::string makeRemoteFileName(const RsPeerId& pid) const;
@ -219,8 +225,8 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
std::vector<RemoteDirectoryStorage *> mRemoteDirectories ; std::vector<RemoteDirectoryStorage *> mRemoteDirectories ;
LocalDirectoryStorage *mLocalSharedDirs ; LocalDirectoryStorage *mLocalSharedDirs ;
LocalDirectoryUpdater *mLocalDirWatcher ; LocalDirectoryUpdater *mLocalDirWatcher ;
ftExtraList *mExtraFiles;
// utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc // utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc
@ -268,6 +274,8 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
std::map<RsFileHash,BannedFileEntry> mPrimaryBanList ; // primary list (user controlled) of files banned from FT search and forwarding. map<real hash, BannedFileEntry> std::map<RsFileHash,BannedFileEntry> mPrimaryBanList ; // primary list (user controlled) of files banned from FT search and forwarding. map<real hash, BannedFileEntry>
std::map<RsPeerId,PeerBannedFilesEntry> mPeerBannedFiles ; // records of which files other peers ban, stored as H(H(f)) std::map<RsPeerId,PeerBannedFilesEntry> mPeerBannedFiles ; // records of which files other peers ban, stored as H(H(f))
std::set<RsFileHash> mBannedFileList ; // list of banned hashes. This include original hashs and H(H(f)) when coming from friends. std::set<RsFileHash> mBannedFileList ; // list of banned hashes. This include original hashs and H(H(f)) when coming from friends.
mutable std::vector<FileInfo> mExtraFilesCache; // cache for extra files, to avoid requesting them too often.
mutable time_t mLastExtraFilesCacheUpdate ;
bool mTrustFriendNodesForBannedFiles ; bool mTrustFriendNodesForBannedFiles ;
bool mBannedFileListNeedsUpdate; bool mBannedFileListNeedsUpdate;
time_t mLastPrimaryBanListChangeTimeStamp; time_t mLastPrimaryBanListChangeTimeStamp;

View File

@ -96,7 +96,7 @@ void ftExtraList::hashAFile()
FileDetails details; FileDetails details;
{ {
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
if (mToHash.empty()) if (mToHash.empty())
return; return;
@ -113,10 +113,9 @@ void ftExtraList::hashAFile()
/* hash it! */ /* hash it! */
std::string name, hash; std::string name, hash;
//uint64_t size; //uint64_t size;
if (RsDirUtil::hashFile(details.info.path, details.info.fname, if (RsDirUtil::hashFile(details.info.path, details.info.fname, details.info.hash, details.info.size))
details.info.hash, details.info.size))
{ {
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
/* stick it in the available queue */ /* stick it in the available queue */
mFiles[details.info.hash] = details; mFiles[details.info.hash] = details;
@ -146,7 +145,7 @@ bool ftExtraList::addExtraFile(std::string path, const RsFileHash& hash,
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
FileDetails details; FileDetails details;
@ -166,11 +165,9 @@ bool ftExtraList::addExtraFile(std::string path, const RsFileHash& hash,
return true; return true;
} }
bool ftExtraList::removeExtraFile(const RsFileHash& hash, TransferRequestFlags flags) bool ftExtraList::removeExtraFile(const RsFileHash& hash)
{ {
/* remove unused parameter warnings */ /* remove unused parameter warnings */
(void) flags;
#ifdef DEBUG_ELIST #ifdef DEBUG_ELIST
std::cerr << "ftExtraList::removeExtraFile()"; std::cerr << "ftExtraList::removeExtraFile()";
std::cerr << " hash: " << hash; std::cerr << " hash: " << hash;
@ -179,7 +176,7 @@ bool ftExtraList::removeExtraFile(const RsFileHash& hash, TransferRequestFlags f
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
mHashOfHash.erase(makeEncryptedHash(hash)) ; mHashOfHash.erase(makeEncryptedHash(hash)) ;
@ -230,7 +227,7 @@ bool ftExtraList::cleanupOldFiles()
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
time_t now = time(NULL); time_t now = time(NULL);
@ -286,7 +283,7 @@ bool ftExtraList::hashExtraFile(std::string path, uint32_t period, TransferRequ
#endif #endif
/* add into queue */ /* add into queue */
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
FileDetails details(path, period, flags); FileDetails details(path, period, flags);
details.info.age = time(NULL) + period; details.info.age = time(NULL) + period;
@ -305,7 +302,7 @@ bool ftExtraList::hashExtraFileDone(std::string path, FileInfo &info)
RsFileHash hash; RsFileHash hash;
{ {
/* Find in the path->hash map */ /* Find in the path->hash map */
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
std::map<std::string, RsFileHash>::iterator it; std::map<std::string, RsFileHash>::iterator it;
if (mHashedList.end() == (it = mHashedList.find(path))) if (mHashedList.end() == (it = mHashedList.find(path)))
@ -420,7 +417,7 @@ bool ftExtraList::saveList(bool &cleanup, std::list<RsItem *>& sList)
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
std::map<RsFileHash, FileDetails>::const_iterator it; std::map<RsFileHash, FileDetails>::const_iterator it;
@ -489,7 +486,7 @@ bool ftExtraList::loadList(std::list<RsItem *>& load)
/* add into system */ /* add into system */
FileDetails file; FileDetails file;
RsStackMutex stack(extMutex); RS_STACK_MUTEX(extMutex);
FileDetails details; FileDetails details;
@ -513,3 +510,12 @@ bool ftExtraList::loadList(std::list<RsItem *>& load)
return true; return true;
} }
void ftExtraList::getExtraFileList(std::vector<FileInfo>& files) const
{
RS_STACK_MUTEX(extMutex);
files.clear();
for(auto it(mFiles.begin());it!=mFiles.end();++it)
files.push_back(it->second.info);
}

View File

@ -117,11 +117,13 @@ public:
bool addExtraFile(std::string path, const RsFileHash &hash, bool addExtraFile(std::string path, const RsFileHash &hash,
uint64_t size, uint32_t period, TransferRequestFlags flags); uint64_t size, uint32_t period, TransferRequestFlags flags);
bool removeExtraFile(const RsFileHash& hash, TransferRequestFlags flags); bool removeExtraFile(const RsFileHash& hash);
bool moveExtraFile(std::string fname, const RsFileHash& hash, uint64_t size, bool moveExtraFile(std::string fname, const RsFileHash& hash, uint64_t size,
std::string destpath); std::string destpath);
uint32_t size() const { return mFiles.size() ; }
/*** /***
* Hash file, and add to the files, * Hash file, and add to the files,
* file is removed after period. * file is removed after period.
@ -137,6 +139,12 @@ public:
**/ **/
virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const;
/*!
* \brief getExtraFileList
* Retrieves the list for display purposes
*/
void getExtraFileList(std::vector<FileInfo>& files) const ;
/*** /***
* Thread Main Loop * Thread Main Loop
**/ **/
@ -146,6 +154,7 @@ public:
* Configuration - store extra files. * Configuration - store extra files.
* *
**/ **/
protected: protected:
virtual RsSerialiser *setupSerialiser(); virtual RsSerialiser *setupSerialiser();
virtual bool saveList(bool &cleanup, std::list<RsItem*>&); virtual bool saveList(bool &cleanup, std::list<RsItem*>&);

View File

@ -174,8 +174,11 @@ void ftServer::SetupFtServer()
void ftServer::connectToFileDatabase(p3FileDatabase *fdb) void ftServer::connectToFileDatabase(p3FileDatabase *fdb)
{ {
mFileDatabase = fdb ; mFileDatabase = fdb ;
mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_LOCAL); // due to a bug in addSearchModule, modules can only be added one by one. Using | between flags wont work. mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_LOCAL); // due to a bug in addSearchModule, modules can only be added one by one. Using | between flags wont work.
mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_REMOTE); mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_REMOTE);
mFileDatabase->setExtraList(mFtExtra);
} }
void ftServer::connectToTurtleRouter(p3turtle *fts) void ftServer::connectToTurtleRouter(p3turtle *fts)
{ {
@ -674,9 +677,10 @@ bool ftServer::ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t
return mFtExtra->addExtraFile(fname, hash, size, period, flags); return mFtExtra->addExtraFile(fname, hash, size, period, flags);
} }
bool ftServer::ExtraFileRemove(const RsFileHash& hash, TransferRequestFlags flags) bool ftServer::ExtraFileRemove(const RsFileHash& hash)
{ {
return mFtExtra->removeExtraFile(hash, flags); mFileDatabase->removeExtraFile(hash);
return true;
} }
bool ftServer::ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags) bool ftServer::ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags)
@ -711,9 +715,9 @@ int ftServer::RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags
{ {
return mFileDatabase->RequestDirDetails(ref,details,flags) ; return mFileDatabase->RequestDirDetails(ref,details,flags) ;
} }
uint32_t ftServer::getType(void *ref, FileSearchFlags /* flags */) uint32_t ftServer::getType(void *ref, FileSearchFlags flags)
{ {
return mFileDatabase->getType(ref) ; return mFileDatabase->getType(ref,flags) ;
} }
/***************************************************************/ /***************************************************************/
/******************** Search Interface *************************/ /******************** Search Interface *************************/

View File

@ -180,7 +180,7 @@ public:
* Extra List Access * Extra List Access
***/ ***/
virtual bool ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t size, uint32_t period, TransferRequestFlags flags); virtual bool ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t size, uint32_t period, TransferRequestFlags flags);
virtual bool ExtraFileRemove(const RsFileHash& hash, TransferRequestFlags flags); virtual bool ExtraFileRemove(const RsFileHash& hash);
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags); virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags);
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info); virtual bool ExtraFileStatus(std::string localpath, FileInfo &info);
virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath); virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath);

View File

@ -409,7 +409,7 @@ public:
* Extra List Access * Extra List Access
***/ ***/
//virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags) = 0; //virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileRemove(const RsFileHash& hash, TransferRequestFlags flags) = 0; virtual bool ExtraFileRemove(const RsFileHash& hash) = 0;
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags) = 0; virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0; virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0;
virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath) = 0; virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath) = 0;

View File

@ -160,6 +160,7 @@ struct PeerBandwidthLimits : RsSerializable
#define DIR_TYPE_PERSON 0x02 #define DIR_TYPE_PERSON 0x02
#define DIR_TYPE_DIR 0x04 #define DIR_TYPE_DIR 0x04
#define DIR_TYPE_FILE 0x08 #define DIR_TYPE_FILE 0x08
#define DIR_TYPE_EXTRA_FILE 0x10
/* flags for Directry request - /* flags for Directry request -
* two types; * two types;

View File

@ -1291,9 +1291,9 @@ bool p3GxsChannels::ExtraFileHash(const std::string& path)
bool p3GxsChannels::ExtraFileRemove(const RsFileHash &hash) bool p3GxsChannels::ExtraFileRemove(const RsFileHash &hash)
{ {
TransferRequestFlags tflags = RS_FILE_REQ_ANONYMOUS_ROUTING | RS_FILE_REQ_EXTRA; //TransferRequestFlags tflags = RS_FILE_REQ_ANONYMOUS_ROUTING | RS_FILE_REQ_EXTRA;
RsFileHash fh = RsFileHash(hash); RsFileHash fh = RsFileHash(hash);
return rsFiles->ExtraFileRemove(fh, tflags); return rsFiles->ExtraFileRemove(fh);
} }

View File

@ -76,6 +76,7 @@
#define IMAGE_COLLOPEN ":/images/library.png" #define IMAGE_COLLOPEN ":/images/library.png"
#define IMAGE_EDITSHARE ":/images/edit_16.png" #define IMAGE_EDITSHARE ":/images/edit_16.png"
#define IMAGE_MYFILES ":/icons/svg/folders1.svg" #define IMAGE_MYFILES ":/icons/svg/folders1.svg"
#define IMAGE_REMOVE ":/images/deletemail24.png"
/*define viewType_CB value */ /*define viewType_CB value */
#define VIEW_TYPE_TREE 0 #define VIEW_TYPE_TREE 0
@ -229,6 +230,9 @@ SharedFilesDialog::SharedFilesDialog(RetroshareDirModel *_tree_model,RetroshareD
sendlinkAct = new QAction(QIcon(IMAGE_COPYLINK), tr( "Send retroshare Links" ), this ); sendlinkAct = new QAction(QIcon(IMAGE_COPYLINK), tr( "Send retroshare Links" ), this );
connect( sendlinkAct , SIGNAL( triggered() ), this, SLOT( sendLinkTo( ) ) ); connect( sendlinkAct , SIGNAL( triggered() ), this, SLOT( sendLinkTo( ) ) );
removeExtraFileAct = new QAction(QIcon(IMAGE_REMOVE), tr( "Stop sharing this file" ), this );
connect( removeExtraFileAct , SIGNAL( triggered() ), this, SLOT( removeExtraFile() ) );
collCreateAct= new QAction(QIcon(IMAGE_COLLCREATE), tr("Create Collection..."), this) ; collCreateAct= new QAction(QIcon(IMAGE_COLLCREATE), tr("Create Collection..."), this) ;
connect(collCreateAct,SIGNAL(triggered()),this,SLOT(collCreate())) ; connect(collCreateAct,SIGNAL(triggered()),this,SLOT(collCreate())) ;
collModifAct= new QAction(QIcon(IMAGE_COLLMODIF), tr("Modify Collection..."), this) ; collModifAct= new QAction(QIcon(IMAGE_COLLMODIF), tr("Modify Collection..."), this) ;
@ -1093,7 +1097,7 @@ void LocalSharedFilesDialog::spawnCustomPopupMenu( QPoint point )
currentFile = model->data(midx, RetroshareDirModel::FileNameRole).toString() ; currentFile = model->data(midx, RetroshareDirModel::FileNameRole).toString() ;
int type = model->getType(midx) ; int type = model->getType(midx) ;
if (type != DIR_TYPE_DIR && type != DIR_TYPE_FILE) return; if (type != DIR_TYPE_DIR && type != DIR_TYPE_FILE && type != DIR_TYPE_EXTRA_FILE) return;
QMenu contextMnu(this) ; QMenu contextMnu(this) ;
@ -1127,58 +1131,70 @@ void LocalSharedFilesDialog::spawnCustomPopupMenu( QPoint point )
contextMnu.addMenu(&collectionMenu) ; contextMnu.addMenu(&collectionMenu) ;
contextMnu.addSeparator() ;//------------------------------------ contextMnu.addSeparator() ;//------------------------------------
contextMnu.addAction(QIcon(IMAGE_MSG), tr("Recommend in a message to..."), this, SLOT(recommendFilesToMsg())) ; contextMnu.addAction(QIcon(IMAGE_MSG), tr("Recommend in a message to..."), this, SLOT(recommendFilesToMsg())) ;
break;
case DIR_TYPE_EXTRA_FILE:
contextMnu.addAction(openfileAct) ;
contextMnu.addSeparator() ;//------------------------------------
contextMnu.addAction(copylinkAct) ;
contextMnu.addAction(sendlinkAct) ;
contextMnu.addAction(removeExtraFileAct) ;
break ; break ;
default : default :
return ; return ;
} }
GxsChannelDialog *channelDialog = dynamic_cast<GxsChannelDialog*>(MainWindow::getPage(MainWindow::Channels)); if(type != DIR_TYPE_EXTRA_FILE)
QMenu shareChannelMenu(tr("Share on channel...")) ; // added here because the shareChannelMenu QMenu object is deleted afterwards
if(channelDialog != NULL)
{ {
shareChannelMenu.setIcon(QIcon(IMAGE_CHANNEL)); GxsChannelDialog *channelDialog = dynamic_cast<GxsChannelDialog*>(MainWindow::getPage(MainWindow::Channels));
QMenu shareChannelMenu(tr("Share on channel...")) ; // added here because the shareChannelMenu QMenu object is deleted afterwards
std::map<RsGxsGroupId,RsGroupMetaData> grp_metas ; if(channelDialog != NULL)
channelDialog->getGroupList(grp_metas) ; {
shareChannelMenu.setIcon(QIcon(IMAGE_CHANNEL));
std::vector<std::pair<std::string,RsGxsGroupId> > grplist ; // I dont use a std::map because two or more channels may have the same name. std::map<RsGxsGroupId,RsGroupMetaData> grp_metas ;
channelDialog->getGroupList(grp_metas) ;
for(auto it(grp_metas.begin());it!=grp_metas.end();++it) std::vector<std::pair<std::string,RsGxsGroupId> > grplist ; // I dont use a std::map because two or more channels may have the same name.
if(IS_GROUP_PUBLISHER((*it).second.mSubscribeFlags) && IS_GROUP_SUBSCRIBED((*it).second.mSubscribeFlags))
grplist.push_back(std::make_pair((*it).second.mGroupName, (*it).second.mGroupId));
std::sort(grplist.begin(),grplist.end(),ChannelCompare()) ; for(auto it(grp_metas.begin());it!=grp_metas.end();++it)
if(IS_GROUP_PUBLISHER((*it).second.mSubscribeFlags) && IS_GROUP_SUBSCRIBED((*it).second.mSubscribeFlags))
grplist.push_back(std::make_pair((*it).second.mGroupName, (*it).second.mGroupId));
for(auto it(grplist.begin());it!=grplist.end();++it) std::sort(grplist.begin(),grplist.end(),ChannelCompare()) ;
for(auto it(grplist.begin());it!=grplist.end();++it)
shareChannelMenu.addAction(QString::fromUtf8((*it).first.c_str()), this, SLOT(shareOnChannel()))->setData(QString::fromStdString((*it).second.toStdString())) ; shareChannelMenu.addAction(QString::fromUtf8((*it).first.c_str()), this, SLOT(shareOnChannel()))->setData(QString::fromStdString((*it).second.toStdString())) ;
contextMnu.addMenu(&shareChannelMenu) ; contextMnu.addMenu(&shareChannelMenu) ;
} }
GxsForumsDialog *forumsDialog = dynamic_cast<GxsForumsDialog*>(MainWindow::getPage(MainWindow::Forums)); GxsForumsDialog *forumsDialog = dynamic_cast<GxsForumsDialog*>(MainWindow::getPage(MainWindow::Forums));
QMenu shareForumMenu(tr("Share on forum...")) ; // added here because the shareChannelMenu QMenu object is deleted afterwards QMenu shareForumMenu(tr("Share on forum...")) ; // added here because the shareChannelMenu QMenu object is deleted afterwards
if(forumsDialog != NULL) if(forumsDialog != NULL)
{ {
shareForumMenu.setIcon(QIcon(IMAGE_FORUMS)); shareForumMenu.setIcon(QIcon(IMAGE_FORUMS));
std::map<RsGxsGroupId,RsGroupMetaData> grp_metas ; std::map<RsGxsGroupId,RsGroupMetaData> grp_metas ;
forumsDialog->getGroupList(grp_metas) ; forumsDialog->getGroupList(grp_metas) ;
std::vector<std::pair<std::string,RsGxsGroupId> > grplist ; // I dont use a std::map because two or more channels may have the same name. std::vector<std::pair<std::string,RsGxsGroupId> > grplist ; // I dont use a std::map because two or more channels may have the same name.
for(auto it(grp_metas.begin());it!=grp_metas.end();++it) for(auto it(grp_metas.begin());it!=grp_metas.end();++it)
if(IS_GROUP_SUBSCRIBED((*it).second.mSubscribeFlags)) if(IS_GROUP_SUBSCRIBED((*it).second.mSubscribeFlags))
grplist.push_back(std::make_pair((*it).second.mGroupName, (*it).second.mGroupId)); grplist.push_back(std::make_pair((*it).second.mGroupName, (*it).second.mGroupId));
std::sort(grplist.begin(),grplist.end(),ChannelCompare()) ; std::sort(grplist.begin(),grplist.end(),ChannelCompare()) ;
for(auto it(grplist.begin());it!=grplist.end();++it) for(auto it(grplist.begin());it!=grplist.end();++it)
shareForumMenu.addAction(QString::fromUtf8((*it).first.c_str()), this, SLOT(shareInForum()))->setData(QString::fromStdString((*it).second.toStdString())) ; shareForumMenu.addAction(QString::fromUtf8((*it).first.c_str()), this, SLOT(shareInForum()))->setData(QString::fromStdString((*it).second.toStdString())) ;
contextMnu.addMenu(&shareForumMenu) ; contextMnu.addMenu(&shareForumMenu) ;
}
} }
contextMnu.exec(QCursor::pos()) ; contextMnu.exec(QCursor::pos()) ;
@ -1564,6 +1580,20 @@ void SharedFilesDialog::FilterItems()
#endif #endif
} }
void SharedFilesDialog::removeExtraFile()
{
std::list<DirDetails> files_info ;
model->getFileInfoFromIndexList(getSelected(),files_info);
for(auto it(files_info.begin());it!=files_info.end();++it)
{
std::cerr << "removing file " << (*it).name << ", hash = " << (*it).hash << std::endl;
rsFiles->ExtraFileRemove((*it).hash);
}
}
#ifdef DEPRECATED_CODE #ifdef DEPRECATED_CODE
bool SharedFilesDialog::flat_FilterItem(const QModelIndex &index, const QString &text, int /*level*/) bool SharedFilesDialog::flat_FilterItem(const QModelIndex &index, const QString &text, int /*level*/)
{ {

View File

@ -66,6 +66,7 @@ private slots:
void copyLink(); void copyLink();
void copyLinkhtml(); void copyLinkhtml();
void sendLinkTo(); void sendLinkTo();
void removeExtraFile();
void collCreate(); void collCreate();
void collModif(); void collModif();
@ -122,6 +123,7 @@ protected:
QAction* sendlinkAct; QAction* sendlinkAct;
QAction* sendchatlinkAct; QAction* sendchatlinkAct;
QAction* copylinkhtmlAct; QAction* copylinkhtmlAct;
QAction* removeExtraFileAct;
QAction *collCreateAct; QAction *collCreateAct;
QAction *collModifAct; QAction *collModifAct;

View File

@ -162,7 +162,7 @@ bool TreeStyle_RDM::hasChildren(const QModelIndex &parent) const
return false; return false;
} }
if (details.type == DIR_TYPE_FILE) if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE)
{ {
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "lookup FILE -> false"; std::cerr << "lookup FILE -> false";
@ -220,7 +220,7 @@ int TreeStyle_RDM::rowCount(const QModelIndex &parent) const
#endif #endif
return 0; return 0;
} }
if (details.type == DIR_TYPE_FILE) if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE)
{ {
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "lookup FILE: 0"; std::cerr << "lookup FILE: 0";
@ -425,7 +425,7 @@ QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln)
else else
return QIcon(categoryIcon); return QIcon(categoryIcon);
} }
else if (details.type == DIR_TYPE_FILE) /* File */ else if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
{ {
// extensions predefined // extensions predefined
if(details.hash.isNull()) if(details.hash.isNull())
@ -457,13 +457,12 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
QString res ; QString res ;
if(RemoteMode) if(RemoteMode)
{
res = QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); res = QString::fromUtf8(rsPeers->getPeerName(details.id).c_str());
} else if(details.id == rsPeers->getOwnId())
else res = tr("My files");
{ else
res = tr("My files"); res = tr("Temporary shared files");
}
return res ; return res ;
} }
case COLUMN_FILENB: { case COLUMN_FILENB: {
@ -471,8 +470,10 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
if(RemoteMode) if(RemoteMode)
rsFiles->getSharedDirStatistics(details.id,stats) ; rsFiles->getSharedDirStatistics(details.id,stats) ;
else else if(details.id == rsPeers->getOwnId())
rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ; rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ;
else
stats.total_number_of_files = details.count;
if(stats.total_number_of_files > 0) if(stats.total_number_of_files > 0)
{ {
@ -488,8 +489,10 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
if(RemoteMode) if(RemoteMode)
rsFiles->getSharedDirStatistics(details.id,stats) ; rsFiles->getSharedDirStatistics(details.id,stats) ;
else else if(details.id == rsPeers->getOwnId())
rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ; rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ;
else
return QString();
if(stats.total_shared_size > 0) if(stats.total_shared_size > 0)
return misc::friendlyUnit(stats.total_shared_size) ; return misc::friendlyUnit(stats.total_shared_size) ;
@ -499,6 +502,8 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
case COLUMN_AGE: case COLUMN_AGE:
if(!isNewerThanEpoque(details.max_mtime)) if(!isNewerThanEpoque(details.max_mtime))
return QString(); return QString();
else if(details.id != rsPeers->getOwnId())
return QString();
else else
return misc::timeRelativeToNow(details.max_mtime); return misc::timeRelativeToNow(details.max_mtime);
@ -506,7 +511,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
return QString() ; return QString() ;
} }
} }
else if (details.type == DIR_TYPE_FILE) /* File */ else if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
{ {
switch(coln) switch(coln)
{ {
@ -517,7 +522,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const
case COLUMN_SIZE: case COLUMN_SIZE:
return misc::friendlyUnit(details.count); return misc::friendlyUnit(details.count);
case COLUMN_AGE: case COLUMN_AGE:
return misc::timeRelativeToNow(details.max_mtime); return (details.type == DIR_TYPE_FILE)?(misc::timeRelativeToNow(details.max_mtime)):QString();
case COLUMN_FRIEND_ACCESS: case COLUMN_FRIEND_ACCESS:
return QVariant(); return QVariant();
case COLUMN_WN_VISU_DIR: case COLUMN_WN_VISU_DIR:
@ -598,7 +603,7 @@ QString FlatStyle_RDM::computeDirectoryPath(const DirDetails& details) const
QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const
{ {
if (details.type == DIR_TYPE_FILE) /* File */ if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
switch(coln) switch(coln)
{ {
case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); case COLUMN_NAME: return QString::fromUtf8(details.name.c_str());
@ -654,7 +659,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails&
return QString(); return QString();
} }
} }
else if (details.type == DIR_TYPE_FILE) /* File */ else if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
{ {
switch(coln) switch(coln)
{ {
@ -707,7 +712,7 @@ QVariant FlatStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails&
* Dir : name, (0) count, (0) path, (0) ts * Dir : name, (0) count, (0) path, (0) ts
*/ */
if (details.type == DIR_TYPE_FILE) /* File */ if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
{ {
switch(coln) switch(coln)
{ {
@ -769,7 +774,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const
if (role == Qt::TextColorRole) if (role == Qt::TextColorRole)
{ {
if(details.type == DIR_TYPE_FILE && details.hash.isNull()) if((details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) && details.hash.isNull())
return QVariant(QColor(Qt::green)) ; return QVariant(QColor(Qt::green)) ;
else if(ageIndicator != IND_ALWAYS && details.max_mtime + ageIndicator < time(NULL)) else if(ageIndicator != IND_ALWAYS && details.max_mtime + ageIndicator < time(NULL))
return QVariant(QColor(Qt::gray)) ; return QVariant(QColor(Qt::gray)) ;
@ -796,7 +801,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const
return decorationRole(details,coln) ; return decorationRole(details,coln) ;
if(role == Qt::ToolTipRole) if(role == Qt::ToolTipRole)
if(!isNewerThanEpoque(details.max_mtime)) if(!isNewerThanEpoque(details.max_mtime) && details.type == DIR_TYPE_PERSON)
return tr("This node hasn't sent any directory information yet.") ; return tr("This node hasn't sent any directory information yet.") ;
/***************** /*****************
@ -1083,6 +1088,7 @@ Qt::ItemFlags RetroshareDirModel::flags( const QModelIndex & index ) const
case DIR_TYPE_PERSON: return isNewerThanEpoque(details.max_mtime)? (Qt::ItemIsEnabled):(Qt::NoItemFlags) ; case DIR_TYPE_PERSON: return isNewerThanEpoque(details.max_mtime)? (Qt::ItemIsEnabled):(Qt::NoItemFlags) ;
case DIR_TYPE_DIR: return Qt::ItemIsSelectable | Qt::ItemIsEnabled; case DIR_TYPE_DIR: return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
case DIR_TYPE_FILE: return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled; case DIR_TYPE_FILE: return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled;
case DIR_TYPE_EXTRA_FILE: return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled;
} }
return Qt::ItemIsSelectable; return Qt::ItemIsSelectable;
@ -1400,7 +1406,7 @@ void RetroshareDirModel::openSelected(const QModelIndexList &qmil)
QDir dir(QString::fromUtf8((*it).path.c_str())); QDir dir(QString::fromUtf8((*it).path.c_str()));
QString dest; QString dest;
if ((*it).type & DIR_TYPE_FILE) { if ((*it).type & DIR_TYPE_FILE || (*it).type & DIR_TYPE_EXTRA_FILE) {
dest = dir.absoluteFilePath(QString::fromUtf8(it->name.c_str())); dest = dir.absoluteFilePath(QString::fromUtf8(it->name.c_str()));
} else if ((*it).type & DIR_TYPE_DIR) { } else if ((*it).type & DIR_TYPE_DIR) {
dest = dir.absolutePath(); dest = dir.absolutePath();
@ -1509,7 +1515,7 @@ void RetroshareDirModel::filterItems(const std::list<std::string>& keywords,uint
mFilteredPointers.insert(p) ; mFilteredPointers.insert(p) ;
++found ; ++found ;
while(det.type == DIR_TYPE_FILE || det.type == DIR_TYPE_DIR) while(det.type == DIR_TYPE_FILE || det.type == DIR_TYPE_EXTRA_FILE || det.type == DIR_TYPE_DIR)
{ {
p = det.parent ; p = det.parent ;
rsFiles->RequestDirDetails( p, det, flags); rsFiles->RequestDirDetails( p, det, flags);
@ -1555,7 +1561,7 @@ QMimeData * RetroshareDirModel::mimeData ( const QModelIndexList & indexes ) con
std::cerr << "Path: " << details.path << std::endl; std::cerr << "Path: " << details.path << std::endl;
#endif #endif
if (details.type != DIR_TYPE_FILE) if (details.type != DIR_TYPE_FILE && details.type != DIR_TYPE_EXTRA_FILE)
{ {
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "RetroshareDirModel::mimeData() Not File" << std::endl; std::cerr << "RetroshareDirModel::mimeData() Not File" << std::endl;
@ -1657,7 +1663,7 @@ void FlatStyle_RDM::updateRefs()
if (requestDirDetails(ref, RemoteMode,details)) if (requestDirDetails(ref, RemoteMode,details))
{ {
if(details.type == DIR_TYPE_FILE) // only push files, not directories nor persons. if(details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) // only push files, not directories nor persons.
_ref_entries.push_back(ref) ; _ref_entries.push_back(ref) ;
#ifdef RDM_DEBUG #ifdef RDM_DEBUG
std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl; std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl;
@ -1683,6 +1689,9 @@ void FlatStyle_RDM::updateRefs()
std::cerr << "reference tab contains " << std::dec << _ref_entries.size() << " files" << std::endl; std::cerr << "reference tab contains " << std::dec << _ref_entries.size() << " files" << std::endl;
} }
if(_ref_stack.empty())
_needs_update = false ;
RetroshareDirModel::postMods() ; RetroshareDirModel::postMods() ;
} }

View File

@ -561,7 +561,7 @@ void SubFileItem::cancel()
if (((mType == SFI_TYPE_ATTACH) || (mType == SFI_TYPE_CHANNEL)) && (mFlag & SFI_FLAG_CREATE)) if (((mType == SFI_TYPE_ATTACH) || (mType == SFI_TYPE_CHANNEL)) && (mFlag & SFI_FLAG_CREATE))
{ {
hide(); hide();
rsFiles->ExtraFileRemove(FileHash(), RS_FILE_REQ_ANONYMOUS_ROUTING | RS_FILE_REQ_EXTRA); rsFiles->ExtraFileRemove(FileHash());//, RS_FILE_REQ_ANONYMOUS_ROUTING | RS_FILE_REQ_EXTRA);
mPath = ""; mPath = "";
} }
else else