1 #include <wx/filedlg.h>
2 #include <wx/filename.h>
4 #include <wx/tokenzr.h>
8 #include "import-vcard3.h"
9 #include "import-vcard4.h"
10 #include "import-struct.h"
11 #include "../frmMain.h"
12 #include "frmImportContacts.h"
13 #include "frmImportResults.h"
14 #include "../common/uuid.h"
15 #include "../common/dirs.h"
17 void ImportRun(frmMain *frmMainPtrInc){
19 // Bring up a dialog selecting one or multiple
20 // files for processing based on type.
22 frmMainPtrInc->PauseAllTimers();
26 long ContactsImported = 0;
27 long ContactsCollected = 0;
29 wxString FinalFilename;
30 wxArrayString SelectedFileList;
31 wxString SelectedFileDirectory;
34 int ImportErrorCount = 0;
36 std::map<int,wxString> *ResultData = new std::map<int,wxString>;
38 FileTypes.Append(wxT("vCard 4.0 Contact(s) (*.vcf)"));
39 FileTypes.Append(wxT("|*.vcf|"));
40 FileTypes.Append(wxT("vCard 3.0 Contact(s) (*.vcf)"));
41 FileTypes.Append(wxT("|*.vcf"));
43 // Open up the dialog to import file data.
45 wxFileDialog ImportDlg(frmMainPtrInc, wxT("Import Contacts"), wxT(""), wxT(""),
46 FileTypes, wxFD_OPEN|wxFD_MULTIPLE);
48 if (ImportDlg.ShowModal() == wxID_CANCEL){
50 frmMainPtrInc->ResumeAllTimers();
55 // Get the list of filenames.
57 ImportDlg.GetPaths(SelectedFileList);
59 // Find which data type is being used.
61 ImportType = ImportDlg.GetFilterIndex();
63 std::map<int, ImportDataContact> ContactData;
67 ContactData = ImportVCard4(&SelectedFileList);
75 ContactData = ImportVCard3(&SelectedFileList);
79 // Check how many contacts are in the set. If zero, throw an error
82 if (ContactData.size() == 0){
84 wxMessageBox(_("No valid contacts within the file(s) selected."), _("Unable to import"));
90 // Show a form to let the user select the
91 // contacts needed to import and which account
94 frmImportContacts *frmIC = new frmImportContacts(frmMainPtrInc);
96 frmIC->SetupList(&ContactData);
98 frmIC->GetResults(&ContactData);
99 AccountName = frmIC->GetAccount();
100 AccountType = frmIC->GetAccountType();
102 if (frmIC->GetDialogResult() == FALSE){
104 // User decided not to import. Clean up the
109 frmMainPtrInc->ResumeAllTimers();
117 // Import the contacts into the selected account.
122 // Setup the directory for writing into.
124 wxString AccountDirFinal = GetAccountDir(AccountName, FALSE);
126 wxString GeneratedFilename;
127 wxString OutputFilename;
128 wxString UIDValueFinal;
130 bool UIDFilterOK = FALSE;
133 GeneratedFilename.Clear();
134 OutputFilename.Clear();
136 static wxString BadCharList = wxFileName::GetForbiddenChars(wxPATH_NATIVE);
137 wxString BadCharListFinal;
138 BadCharListFinal.Append(wxT("["));
139 BadCharListFinal.Append(BadCharList);
140 BadCharListFinal.Append(wxT("]"));
143 BadCharRex.Compile(BadCharListFinal);
145 for(std::map<int,ImportDataContact>::iterator iter = ContactData.begin();
146 iter != ContactData.end(); iter++){
148 if (iter->second.ContactSelected == TRUE){
150 // Workout the file name. void CloseWindow( wxCommandEvent& event );
151 // Get the UID value and check if it is empty.
152 // If it isn't empty, check it can be used for a valid
153 // filename other wise generate a file name for the purposes
156 // Filter UID incase writing outside the
157 // directory is attempted.
159 #if defined(__HAIKU__)
163 #elif defined(__WIN32__)
165 wxStringTokenizer UIDValueCheck(iter->second.UIDValue, wxT("\\"));
166 while (UIDValueCheck.HasMoreTokens()){
167 UIDValueCheck.GetNextToken();
173 wxStringTokenizer UIDValueCheck(iter->second.UIDValue, wxT("/"));
174 while (UIDValueCheck.HasMoreTokens()){
175 UIDValueCheck.GetNextToken();
181 if (FilterCount == 1){
185 if (BadCharRex.Matches(iter->second.UIDValue) && UIDFilterOK == TRUE){
187 bool NewFileExists = TRUE;
189 while (NewFileExists){
191 // Generate the UID and check if it exists.
193 wxString CheckFilename;
195 UIDToken = GenerateUUID();
197 CheckFilename.Append(AccountDirFinal);
198 CheckFilename.Append(UIDToken);
199 CheckFilename.Append(wxT(".vcf"));
201 if (!wxFileExists(CheckFilename)){
203 NewFileExists = FALSE;
211 UIDToken = iter->second.UIDValue;
215 // Check if the file exists in the directory already.
217 OutputFilename.Append(AccountDirFinal);
218 OutputFilename.Append(wxT("/"));
219 OutputFilename.Append(UIDToken);
220 OutputFilename.Append(wxT(".vcf"));
222 if(wxFileExists(OutputFilename)){
224 // File already exists so mark as an error.
226 ResultData->insert(std::make_pair(ImportSeek, wxString::Format(_("Unable to import '%s'(%s): %s"), iter->second.FriendlyName, UIDToken, _("Contact already exists."))));
229 GeneratedFilename.Clear();
230 OutputFilename.Clear();
231 UIDValueFinal.Clear();
238 // Write to the file.
242 #if wxABI_VERSION < 20900
243 if(!OutputFile.Open(OutputFilename, wxT("w"))){
245 if(!OutputFile.Open(OutputFilename, wxT("w"))){
247 ResultData->insert(std::make_pair(ImportSeek, wxString::Format(_("Unable to import '%s'(%s): %s"), iter->second.FriendlyName, UIDToken, _("Error occured whilst trying to create this contact. Please check permissions and storage device."))));
251 OutputFile.Write(iter->second.ContactData, wxConvAuto());
255 ResultData->insert(std::make_pair(ImportSeek, wxString::Format(_("Contact '%s'(%s) was successfully imported."), iter->second.FriendlyName, UIDToken)));
259 // Check if there is a UID value set. If there is not a UID
260 // value set then generate a new one.
266 GeneratedFilename.Clear();
267 OutputFilename.Clear();
268 UIDValueFinal.Clear();
277 // Check if the import error count is more than 0. If it is, then
278 // display the results dialog.
280 wxCommandEvent imprres(IMPORT_RESULTSSHOW);
281 imprres.SetClientData(ResultData);
282 imprres.SetInt(ImportCount);
283 imprres.SetExtraLong(ImportErrorCount);
284 wxPostEvent(frmMainPtrInc, imprres);
286 // Syncronise the account which the contacts got imported to.
287 // (If the account is not a local account).
289 if (AccountType != wxT("Local") && AccountType != wxT("local")){
291 wxString AccNamePostEvent;
293 AccNamePostEvent.Clear();
294 AccNamePostEvent.Append(AccountName);
295 AccNamePostEvent.Trim();
297 wxCommandEvent accevent(SYNCACCOUNT);
298 accevent.SetString(AccNamePostEvent);
300 wxPostEvent(frmMainPtrInc, accevent);
304 // Resume the timers.
306 frmMainPtrInc->ResumeAllTimers();