--- /dev/null
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef COMMON_FILE_UTILS_H
+#define COMMON_FILE_UTILS_H
+
+#include <tizen.h>
+#include <string>
+
+namespace Common
+{
+ /**
+ * @brief Get available file path for a new file.
+ * @details Appends file index if file already exists.
+ * @param[in] dirPath Directory path
+ * @param[in] namePrefix File name prefix (before the index)
+ * @param[in] nameSuffix File name suffix (e.g. file extension)
+ * @param[in] maxCount Maximum file count (i.e. maximum index value)
+ * @return Available path or empty string if maximum file count is exceeded.
+ */
+ EXPORT_API std::string getAvailableFilePath(const char *dirPath,
+ const char *namePrefix, const char *nameSuffix, size_t maxCount = 999);
+
+ /**
+ * @brief Copy file.
+ * @param[in] srcPath Source path.
+ * @param[in] destPath Destination path.
+ * @return true if success.
+ */
+ EXPORT_API bool copyFile(const char *srcPath, const char *destPath);
+
+ /**
+ * @brief Remove file.
+ * @param[in] filePath File to remove.
+ * @return true if success.
+ */
+ EXPORT_API bool removeFile(const char *filePath);
+}
+
+#endif /* COMMON_FILE_UTILS_H */
--- /dev/null
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Common/FileUtils.h"
+
+#include <fstream>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <linux/limits.h>
+#include "Utils/Logger.h"
+
+std::string Common::getAvailableFilePath(const char *dirPath,
+ const char *namePrefix, const char *nameSuffix, size_t maxCount)
+{
+ for (size_t i = 0; i <= maxCount; ++i) {
+ char path[PATH_MAX];
+
+ if (i == 0) {
+ snprintf(path, sizeof(path), "%s/%s%s", dirPath, namePrefix, nameSuffix);
+ } else {
+ snprintf(path, sizeof(path), "%s/%s_%03zu%s", dirPath, namePrefix, i, nameSuffix);
+ }
+
+ struct stat buf;
+ if (stat(path, &buf) != 0) {
+ return path;
+ }
+ }
+
+ ERR("Maximum file count exceeded.");
+ return { };
+}
+
+bool Common::copyFile(const char *srcPath, const char *destPath)
+{
+ std::ifstream ifs(srcPath, std::ios::binary);
+ if (ifs.is_open()) {
+ std::ofstream ofs(destPath, std::ios::binary);
+ if (ofs.is_open() && !ofs.bad()) {
+ ofs << ifs.rdbuf();
+ ofs.close();
+ ifs.close();
+ return true;
+ }
+ ifs.close();
+ }
+
+ return false;
+}
+
+bool Common::removeFile(const char *filePath)
+{
+ struct stat st = { 0 };
+ if (filePath && stat(filePath, &st) == 0) {
+ return std::remove(filePath) == 0;
+ }
+ return false;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef CONTACTS_MODEL_CONTACT_IMAGE_FIELD_H
+#define CONTACTS_MODEL_CONTACT_IMAGE_FIELD_H
+
+#include "Contacts/Model/ContactTextField.h"
+
+namespace Contacts
+{
+ namespace Model
+ {
+ /**
+ * @brief Represents image path field. Creates and manages temporary copy of image file.
+ */
+ class ContactImageField : public ContactTextField
+ {
+ public:
+ using ContactTextField::ContactTextField;
+ virtual ~ContactImageField() override;
+
+ /**
+ * @brief Set text field value.
+ */
+ virtual void setValue(const char *value) override;
+
+ protected:
+ /**
+ * @see ContactField::onUpdate()
+ */
+ virtual void onUpdate(contacts_record_h record) override;
+
+ private:
+ void removeTempFile();
+
+ std::string m_TempPath;
+ };
+ }
+}
+
+#endif /* CONTACTS_MODEL_CONTACT_IMAGE_FIELD_H */
/**
* @brief Set text field value.
*/
- void setValue(const char *value);
+ virtual void setValue(const char *value);
protected:
/**
#include "Contacts/Model/ContactArray.h"
#include "Contacts/Model/ContactBoolField.h"
+#include "Contacts/Model/ContactImageField.h"
#include "Contacts/Model/ContactIntField.h"
#include "Contacts/Model/ContactDateField.h"
#include "Contacts/Model/ContactEnumField.h"
case TypeEnum:
field = new ContactEnumField(parent, metadata); break;
case TypeText:
- field = new ContactTextField(parent, metadata); break;
+ if (metadata.id == FieldImage) {
+ field = new ContactImageField(parent, metadata);
+ } else {
+ field = new ContactTextField(parent, metadata);
+ }
+ break;
case TypeDate:
field = new ContactDateField(parent, metadata); break;
case TypeArray:
--- /dev/null
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Contacts/Model/ContactImageField.h"
+#include "Common/FileUtils.h"
+#include "App/Path.h"
+
+#include <string.h>
+
+#define IMAGE_FILE_PREFIX "contact_image"
+
+using namespace Common;
+using namespace Contacts::Model;
+
+ContactImageField::~ContactImageField()
+{
+ removeTempFile();
+}
+
+void ContactImageField::setValue(const char *value)
+{
+ removeTempFile();
+ if (value) {
+ const char *ext = strrchr(value, '.');
+ std::string path = getAvailableFilePath(App::getDataDir().c_str(),
+ IMAGE_FILE_PREFIX, ext ? ext : "");
+
+ if (!path.empty() && copyFile(value, path.c_str())) {
+ m_TempPath = std::move(path);
+ }
+ }
+
+ ContactTextField::setValue(m_TempPath.c_str());
+}
+
+void ContactImageField::onUpdate(contacts_record_h record)
+{
+ removeTempFile();
+ ContactTextField::onUpdate(record);
+}
+
+void ContactImageField::removeTempFile()
+{
+ if (!m_TempPath.empty()) {
+ removeFile(m_TempPath.c_str());
+ m_TempPath.clear();
+ }
+}
#include "Contacts/Settings/Model/Storage.h"
#include "Contacts/Settings/ExportController.h"
+#include "Common/FileUtils.h"
#include "Ui/Popup.h"
#include "Utils/Logger.h"
std::string ExportController::getVcardFilePath()
{
std::string directoryPath = getVcardDirectoryPath();
- RETVM_IF(directoryPath.empty(), std::string(), "Cannot get directory path to storage");
+ RETVM_IF(directoryPath.empty(), { }, "Cannot get directory path to storage");
- const int vcardMaxNumber = 999;
-
- for (int fileNumber = 1; fileNumber <= vcardMaxNumber; ++fileNumber) {
- char path[BUFFER_SIZE] = { 0, };
-
- if (fileNumber == 1) {
- snprintf(path, sizeof(path), "%s/Contacts.vcf", directoryPath.c_str());
- } else {
- snprintf(path, sizeof(path), "%s/Contacts_%03d.vcf", directoryPath.c_str(), fileNumber);
- }
-
- struct stat buf;
- if (stat(path, &buf) != 0) {
- return path;
- }
+ std::string filePath = Common::getAvailableFilePath(directoryPath.c_str(), "Contacts", ".vcf");
+ if (filePath.empty()) {
+ notification_status_message_post(_("IDS_PB_POP_FAILED"));
}
- ERR("Too many vcards. Delete some before creating new.");
- notification_status_message_post(_("IDS_PB_POP_FAILED"));
- return std::string();
+ return filePath;
}
void ExportController::onStart()