po::options_description command("COMMANDS");
command.add_options()
("print,p","Prints the local database tree (default=off)")
- ("file,f",po::value< vector<string> >(),"Adds the file to the local database")
+ ("files,f",po::value< vector<string> >(),"Adds the file(s) to the local database")
("dir,d",po::value< vector<string> >(),"Adds the directory to the local database")
("sync,s",po::value< vector<string> >(),"Synchronizes the local database with the files")
- ("recurse,r","Recurse into sub-directories (default=off)")
- ("repair,R","Repair the database (on synchronization) (default=off)")
- ("check,c","Check for attribute differences (on synchronization) (default=off)");
+ ("copy,c",po::value< vector<string> >(),"Copies the files into a local directory");
-
//Describes third group of options
po::options_description option("OPTIONS");
option.add_options()
("verbose,v",po::value<int>(&verb),"Verbosity level (default=`1')")
- ("debug,D",po::value<int>(&deb),"Debug messages level (default=`0')");
+ ("debug,D",po::value<int>(&deb),"Debug messages level (default=`0')")
+ ("recurse,r","Recurse into sub-directories (default=off)")
+ ("repair,R","Repair the database (on synchronization) (default=off)")
+ ("check,C","Check for attribute differences (on synchronization) (default=off)")
+ ("handler,H",po::value<string>(&handler),"Handler name (default=`Local database')");
//Adds the groups into a big one
po::options_description cmdline_options;
po::store(po::parse_command_line(ac, av, cmdline_options), vm);
po::notify(vm);
+
//Does something on each option
//GENERIC
if (vm.count("help")) {
||vm.count("file")
||vm.count("dir")
||vm.count("sync")
+ ||vm.count("copy")
)
+ {
try
{
if(out2.str().compare("1")==0){chk=true;}
cout<<g.Synchronize(name.front(),rep,chk)<<"\n";
}
+ if (vm.count("copy")) {
+ std::vector<std::string> name=vm["copy"].as< vector<string> >();
+ g.CopyFiles(name,handler);
+ }
g.Finalize();
}
catch (crea::Exception e)
{
e.Print();
}
+ }
return 0;
//========================================================================
+ void Gimmick::CopyFiles(const std::vector<std::string>& filenames, const std::string& d )
+ {
+ TreeHandler * handler=GetTreeHandler(d);
+ mImageAdder.SetCurrentDatabase(d);
+ mImageAdder.SetTreeHandler(handler);
+ mImageAdder.SetTimestampHandler(mTimestampDatabase);
+ mImageAdder.SetSynchronizer(mSynchronizer);
+ mImageAdder.CopyFiles(filenames, mSettings->getValue(SETTINGS_COPY_PATH));
+ }
+
+ //========================================================================
+
std::string Gimmick::Synchronize(const std::string& d, bool repair, bool checkAttributes)
{
TreeHandler * handler=GetTreeHandler(d);
void RemoveFile(const std::string& d,
tree::Node* filename);
+ /// Copies the files into the local directory
+ void CopyFiles(const std::vector<std::string>& filenames, const std::string& d );
+
+
///Synchronizes the loaded data with the database d. If repair is true the database will be updated, otherwise
///only a warning sign will be issued
std::string Synchronize(const std::string& d, bool repair, bool checkAttributes);
virtual void AddIgnoreFile(tree::Node* toRemove)
{ GimmickError("INTERNAL ERROR : AddIgnoreFile not implemented"); }
+ ///Copies selected files
+ virtual void CopyFiles(const std::vector<std::string>& filenames)
+ { GimmickError("INTERNAL ERROR : CopyFiles not implemented"); }
///Validates the dimension compliance of the images with the maximum and minimum given, and between their sizes
bool ValidateSelected (tree::Node* sel, int min_dim, int max_dim);
Keys.push_back(SETTINGS_SYNC_EVENT);
Keys.push_back(SETTINGS_DBPATH);
Keys.push_back(SETTINGS_SYNC_FREQ);
+ Keys.push_back(SETTINGS_COPY_PATH);
readSettings(Keys, sets);
}
m_SettingsMap[SETTINGS_SYNC_EVENT] = "end";
m_SettingsMap[SETTINGS_DBPATH] = "";
m_SettingsMap[SETTINGS_DICOM_LIBRARY] = "gdcm";
+ m_SettingsMap[SETTINGS_COPY_PATH] = m_SettingsFileName.substr(0,m_SettingsFileName.find_last_of('\\')+1)+"Copied files";
writeSettingsFile();
}
#define SETTINGS_SYNC_EVENT "<syncro_event>"
#define SETTINGS_SYNC_FREQ "<syncro_frequency>"
#define SETTINGS_DBPATH "<dbpath>"
+#define SETTINGS_COPY_PATH "<copy_path>"
namespace creaImageIO
//=====================================================================
std::string TimestampDatabaseHandler::IsIndexed(const std::string& path, const std::string& refdb)
{
+ std::string pat=path.c_str();
+ CleanPath(pat);
std::stringstream out;
std::stringstream result;
- out<<"SELECT ID FROM FILES WHERE PATH='"<<path<<"' AND REFERENCEDDB='"<<refdb<<"';";
+ out<<"SELECT ID FROM FILES WHERE PATH='"<<pat<<"' AND REFERENCEDDB='"<<refdb<<"';";
CppSQLite3Query q;
QUERYTIMESTAMPDB(out.str(),q);
//=======================================================================
+ void TreeHandlerImageAdder::CopyFiles(const std::vector<std::string>& filenames, const std::string directory )
+ {
+ std::vector<std::string>::const_iterator i;
+ if(!boost::filesystem::exists(directory))
+ {
+ boost::filesystem::create_directory(boost::filesystem::path(directory));
+ mTimestampHandler->AddDirectory("",directory,fs::last_write_time(directory)+10, time(0),mCurrentDB);
+ mSynchronizer->InsertAddOp(directory,"0","0",mCurrentDB);
+ }
+ std::string addKey=mSynchronizer->GetAttribute("ADD_KEY","ADD_OPS","PATH",directory,mCurrentDB);
+ std::string parent_id=mTimestampHandler->IsIndexed(directory,mCurrentDB);
+ size_t last;
+ std::vector<std::string> newNames;
+ for(i=filenames.begin();i!=filenames.end();++i)
+ {
+ std::string dir=directory.c_str();
+ mTimestampHandler->CleanPath(dir);
+ if(boost::filesystem::exists(*i) && (*i).find(dir)==std::string::npos)
+ {
+ std::string path=*i;
+ last=(*i).find_last_of('/');
+ std::string f="\\"+(*i).substr(last+1);
+
+ int p=1;
+ std::stringstream out;
+ out<<directory<<f;
+ while(boost::filesystem::exists(out.str()))
+ {
+ out.str("");
+ out<<directory<<f.substr(0,f.size()-4)<<"("<<p<<")"<<f.substr(f.size()-4);
+ p++;
+ }
+ std::string result=out.str();
+ mTimestampHandler->CleanPath(result);
+ boost::filesystem::copy_file((*i),result);
+
+ //To update image database
+ mTreeHandler->SetAttribute("Image","FullFileName",result,"FullFileName", (*i));
+
+ //To update timestamp database
+ mTimestampHandler->SetAttribute("PATH",result,"PATH",(*i));
+ mTimestampHandler->SetAttribute("PARENT_ID",parent_id,"PATH",result);
+ std::stringstream t;
+ t<<fs::last_write_time(directory)+10;
+ mTimestampHandler->SetAttribute("LastModified",t.str(),"PATH",result);
+
+ //To update maintenance database
+ //1.Add the new path and increase number of children on new operation.
+ std::stringstream removedOn;
+ removedOn<<time(0);
+ //Inserts the file
+ mSynchronizer->InsertIgnoreFile(addKey, result,"0",removedOn.str(),mCurrentDB);
+ //Gets the number of files added
+ int files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",addKey,mCurrentDB)).c_str());
+ files=files+1;
+ std::stringstream fil;
+ fil<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",addKey,mCurrentDB);
+ fil.str("");
+
+ //2.Set the old path as removed and decrease number of children on old operation.
+ //Gets the old add key
+ std::string oldAddKey=mSynchronizer->GetAttribute("ADD_KEY","IGNORED_FILES","PATH",path,mCurrentDB);
+ //Sets the file as removed
+ mSynchronizer->SetAttribute("REMOVE","IGNORED_FILES","1","PATH = '"+path+"' AND ADD_KEY",oldAddKey,mCurrentDB);
+ //Gets the number of files added
+ files=atoi((mSynchronizer->GetAttribute("FILES_ADDED","ADD_OPS","ADD_KEY",oldAddKey,mCurrentDB)).c_str());
+ files=files-1;
+ fil<<files;
+ //Sets the new number of files
+ mSynchronizer->SetAttribute("FILES_ADDED","ADD_OPS",fil.str(),"ADD_KEY",oldAddKey,mCurrentDB);
+
+ }
+
+ }
+ }
+
+ //=======================================================================
}
std::vector<std::string> &i_ignorefiles,
std::vector<std::string> & attsModified,
std::vector<std::string> & newfiles);
+ ///Copies the files indicated in the vector and updates all databases
+ void CopyFiles(const std::vector<std::string>& filenames, const std::string directory );
///Finds the node that matches the specified parameters
void FindNode(tree::Node* parent, int level,
const std::string& searchParam,
GetTreeViewMap()[crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection()))]->UpdateLevel(1);
}
+ //=================================================
+ void WxGimmickView::CopyFiles(const std::vector<std::string>& filenames)
+ {
+ mGimmick->CopyFiles(filenames, crea::wx2std(mNotebook->GetPageText(mNotebook->GetSelection())));
+ wxMessageBox(std2wx("The selected files have been copied"),_T("Copy files"),wxOK,this);
+ }
+
//=================================================
void WxGimmickView::OnSynchronize(wxCommandEvent& event)
{
void AddIgnoreFile(tree::Node* toRemove);
///Resets the default image
void ClearSelection();
+ ///Copies selected files
+ void CopyFiles(const std::vector<std::string>& filenames);
///Sends a request to read the currently selected node and the ones that surround it.
mAnonymizingID=m1Item->GetId();
mLocalCopyID=m2Item->GetId();
//Connect( mAnonymizingID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnAnonymize) );
- //Connect( mLocalCopyID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnLocalCopy) );
+ Connect( mLocalCopyID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(WxTreeView::OnLocalCopy) );
#endif // wxUSE_MENUS
-
-
/// Initialize the first level splitter
sizer->Add( mLevelList[0].wxSplitter ,1, wxGROW ,0);
//=====================================================================
- const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
+ const std::vector<tree::Node*>& WxTreeView::GetSelected(int level)
{
// if (GetSelectedUpToDate(level))
int l = level - 1;
// the selection of upper level
- std::vector<tree::Node*>& sel(mLevelList[level-1].Selected);
+ std::vector<tree::Node*>& sel(mLevelList[level-1].Selected);
sel.clear();
if (level == 1)
{
sel.push_back(GetTreeHandler()->GetTree().GetTree());
}
- else if (level < 5)
+ else if (level < mLevelList.size()+2 )
{
long item = -1;
for ( ;; )
{
std::string val;
// Temporary correction : it works but no explanation about the problem FCY
+
if(k==0 && level <3)
+ {
val = (*j)->GetAttribute("NumberOfChildren");
+ }
else
val = (*j)->GetAttribute(mLevelList[l].key[k]);
if(((*j)->GetAttributeDescriptor(mLevelList[l].key[k])).isDateEntry()) // Date
}
//================================================================
+ //================================================================
+ void WxTreeView::OnLocalCopy(wxCommandEvent& event)
+ {
+ wxBusyCursor busy;
+
+ unsigned int tempLevel = mLastLevel;
+ mLastLevel+=1;
+ const std::vector<tree::Node*>& sel=GetSelected(mLastLevel+1);
+
+ if(sel.size() != 0)
+ {
+ bool copy=false;
+ std::stringstream out;
+ std::string levelName=GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName();
+ out<<"Copy ";
+ out<<sel.size();
+ if(sel.size()>1&&levelName.at(levelName.size()-1)!='s')
+ {
+ out<<" "<<levelName;
+ out<<"s to .gimmick?";
+ }
+ else
+ {
+ out<<" "<<GetTreeHandler()->GetTree().GetLevelDescriptor(mLastLevel).GetName()<<" to .gimmick?";
+ }
+ if (wxMessageBox(crea::std2wx(out.str()),
+ _T("Remove Files"),
+ wxYES_NO,this ) == wxYES)
+ {
+ copy = true;
+ }
+ if(copy)
+ {
+ std::vector<std::string> s;
+ GetFilenamesAsString(sel,s);
+ GetGimmickView()->CopyFiles(s);
+ }
+ }
+ else
+ {
+ mLastLevel = tempLevel;
+ }
+
+
+ }
+ //================================================================
+
//================================================================
void WxTreeView::SortLevel(int level)
{
}
if(GetCtrl(level)->GetItemState(item, wxLIST_STATE_SELECTED)==0 )
{
+
adr = GetCtrl(level)->GetItemData(item);
nod = ((ItemData*)adr)->node;
nodes.push_back(nod);
}
}
+ //================================================================
+ void WxTreeView::GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s)
+ {
+ std::vector<tree::Node*>::const_iterator i;
+
+ for (i=nodes.begin(); i!=nodes.end(); ++i)
+ {
+ if((*i)->GetLevel()<mLevelList.size())
+ {
+ GetTreeHandler()->LoadChildren(*i,0);
+ GetFilenamesAsString((*i)->GetChildrenList(),s);
+ }
+ else
+ {
+ std::string filename=(*i)->GetAttribute("FullFileName");
+ s.push_back(filename);
+ }
+ }
+ }
+
//================================================================
void WxTreeView::SetColor(int l, int item)
{
///Callback when the user need the items filtered
void OnPopupFilter(wxCommandEvent& event);
+
+ ///Callback when the user need the items filtered
+ void OnLocalCopy(wxCommandEvent& event);
///Callback on mouse click
void OnMouseClick(wxMouseEvent& event);
void ValidateSelectedImages(bool isSelection);
///Gets selected filenames
void GetSelectedAsString(std::vector<std::string>&s);
- /// Gets the next nodes on the list, be it up(true) or down(false).
+ ///Gets the filenames of the given nodes and returns them on the given vector. Is recursive.
+ void GetFilenamesAsString(const std::vector<tree::Node*>& nodes, std::vector<std::string>&s);
+ /// Gets the next nodes on the list, be it up(true) or down(false).
void GetNodes(std::vector<tree::Node*>& nodes, bool direction);
/// Updates the view of a level given the selected items of upper level
/// Recursive method