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 ContactsExported = 0;
27 long ContactsCollected = 0;
30 wxString FinalFilename;
31 wxArrayString SelectedFileList;
32 wxString SelectedFileDirectory;
35 int ImportErrorCount = 0;
37 std::map<int,wxString> *ResultData = new std::map<int,wxString>;
39 FileTypes.Append(wxT("vCard 4.0 Contact(s) (*.vcf)"));
40 FileTypes.Append(wxT("|*.vcf|"));
41 FileTypes.Append(wxT("vCard 3.0 Contact(s) (*.vcf)"));
42 FileTypes.Append(wxT("|*.vcf"));
44 // Open up the dialog to export file data.
46 wxFileDialog ExportDlg(frmMainPtrInc, wxT("Import Contacts"), wxT(""), wxT(""),
47 FileTypes, wxFD_OPEN|wxFD_MULTIPLE);
49 if (ExportDlg.ShowModal() == wxID_CANCEL){
51 frmMainPtrInc->ResumeAllTimers();
56 // Get the list of filenames.
58 ExportDlg.GetPaths(SelectedFileList);
60 // Find which data type is being used.
62 ExportType = ExportDlg.GetFilterIndex();
64 std::map<int, ImportDataContact> ContactData;
68 ContactData = ImportVCard4(&SelectedFileList);
76 ContactData = ImportVCard3(&SelectedFileList);
80 // Check how many contacts are in the set. If zero, throw an error
83 if (ContactData.size() == 0){
85 wxMessageBox(_("No valid contacts within the file(s) selected."), _("Unable to import"));
91 // Show a form to let the user select the
92 // contacts needed to import and which account
95 frmImportContacts *frmIC = new frmImportContacts(frmMainPtrInc);
97 frmIC->SetupList(&ContactData);
99 frmIC->GetResults(&ContactData);
100 AccountName = frmIC->GetAccount();
101 AccountType = frmIC->GetAccountType();
103 if (frmIC->GetDialogResult() == FALSE){
105 // User decided not to import. Clean up the
110 frmMainPtrInc->ResumeAllTimers();
118 // Import the contacts into the selected account.
123 // Setup the directory for writing into.
125 wxString AccountDirFinal = GetAccountDir(AccountName, FALSE);
127 wxString GeneratedFilename;
128 wxString OutputFilename;
129 wxString UIDValueFinal;
131 bool UIDFilterOK = FALSE;
134 GeneratedFilename.Clear();
135 OutputFilename.Clear();
137 static wxString BadCharList = wxFileName::GetForbiddenChars(wxPATH_NATIVE);
138 wxString BadCharListFinal;
139 BadCharListFinal.Append(wxT("["));
140 BadCharListFinal.Append(BadCharList);
141 BadCharListFinal.Append(wxT("]"));
144 BadCharRex.Compile(BadCharListFinal);
146 for(std::map<int,ImportDataContact>::iterator iter = ContactData.begin();
147 iter != ContactData.end(); iter++){
149 if (iter->second.ContactSelected == TRUE){
151 // Workout the file name. void CloseWindow( wxCommandEvent& event );
152 // Get the UID value and check if it is empty.
153 // If it isn't empty, check it can be used for a valid
154 // filename other wise generate a file name for the purposes
157 // Filter UID incase writing outside the
158 // directory is attempted.
160 #if defined(__HAIKU__)
164 #elif defined(__WIN32__)
166 wxStringTokenizer UIDValueCheck(iter->second.UIDValue, wxT("\\"));
167 while (UIDValueCheck.HasMoreTokens()){
168 UIDValueCheck.GetNextToken();
174 wxStringTokenizer UIDValueCheck(iter->second.UIDValue, wxT("/"));
175 while (UIDValueCheck.HasMoreTokens()){
176 UIDValueCheck.GetNextToken();
182 if (FilterCount == 1){
186 if (BadCharRex.Matches(iter->second.UIDValue) && UIDFilterOK == TRUE){
188 bool NewFileExists = TRUE;
190 while (NewFileExists){
192 // Generate the UID and check if it exists.
194 wxString CheckFilename;
196 UIDToken = GenerateUUID();
198 CheckFilename.Append(AccountDirFinal);
199 CheckFilename.Append(UIDToken);
200 CheckFilename.Append(wxT(".vcf"));
202 if (!wxFileExists(CheckFilename)){
204 NewFileExists = FALSE;
212 UIDToken = iter->second.UIDValue;
216 // Check if the file exists in the directory already.
218 OutputFilename.Append(AccountDirFinal);
219 OutputFilename.Append(wxT("/"));
220 OutputFilename.Append(UIDToken);
221 OutputFilename.Append(wxT(".vcf"));
223 if(wxFileExists(OutputFilename)){
225 // File already exists so mark as an error.
227 ResultData->insert(std::make_pair(ImportSeek, wxString::Format(_("Unable to import '%s'(%s): %s"), iter->second.FriendlyName, UIDToken, _("Contact already exists."))));
230 GeneratedFilename.Clear();
231 OutputFilename.Clear();
232 UIDValueFinal.Clear();
239 // Write to the file.
243 #if wxABI_VERSION < 20900
244 if(!OutputFile.Open(OutputFilename, wxT("w"))){
246 if(!OutputFile.Open(OutputFilename, wxT("w"))){
248 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."))));
252 OutputFile.Write(iter->second.ContactData, wxConvAuto());
256 ResultData->insert(std::make_pair(ImportSeek, wxString::Format(_("Contact '%s'(%s) was successfully imported."), iter->second.FriendlyName, UIDToken)));
260 // Check if there is a UID value set. If there is not a UID
261 // value set then generate a new one.
267 GeneratedFilename.Clear();
268 OutputFilename.Clear();
269 UIDValueFinal.Clear();
278 // Check if the import error count is more than 0. If it is, then
279 // display the results dialog.
281 wxCommandEvent imprres(IMPORT_RESULTSSHOW);
282 imprres.SetClientData(ResultData);
283 imprres.SetInt(ImportCount);
284 imprres.SetExtraLong(ImportErrorCount);
285 wxPostEvent(frmMainPtrInc, imprres);
287 // Syncronise the account which the contacts got imported to.
288 // (If the account is not a local account).
290 if (AccountType != wxT("Local") && AccountType != wxT("local")){
292 wxString AccNamePostEvent;
294 AccNamePostEvent.Clear();
295 AccNamePostEvent.Append(AccountName);
296 AccNamePostEvent.Trim();
298 wxCommandEvent accevent(SYNCACCOUNT);
299 accevent.SetString(AccNamePostEvent);
301 wxPostEvent(frmMainPtrInc, accevent);
305 // Resume the timers.
307 frmMainPtrInc->ResumeAllTimers();