feedback
libtzplatform-config
notification
+ storage
)
set(INCLUDES "${TIZEN_PACKAGES_INCLUDE_DIRS};inc")
virtual bool onCancel();
void cancel();
- bool onProgress(int value);
+ bool onProgress(size_t value);
private:
void createProgressPopup(Evas_Object *parent, const char *title, int maxValue);
static void onStart(void *data, Ecore_Thread *thread);
+ static void onNotify(void *data, Ecore_Thread *thread, void *msgData);
static void onFinish(void *data, Ecore_Thread *thread);
static void onCanceled(void *data, Ecore_Thread *thread);
void ProgressController::run()
{
- m_Thread = ecore_thread_run(onStart, onFinish, onCanceled, this);
+ m_Thread = ecore_thread_feedback_run(onStart, onNotify, onFinish, onCanceled, this, EINA_FALSE);
}
void ProgressController::setFinishCallback(FinishCallback callback)
m_IsCanceled = true;
}
-bool ProgressController::onProgress(int value)
+bool ProgressController::onProgress(size_t value)
{
- m_ProgressPopup->setProgress(value);
+ ecore_thread_feedback(m_Thread, (void *)value);
+
return !m_IsCanceled;
}
{
RETM_IF_ERR(!data, "invalid data");
ProgressController *controller = (ProgressController *)data;
- controller->onStart(controller->m_Thread);
+ controller->onStart(thread);
+}
+
+void ProgressController::onNotify(void *data, Ecore_Thread *thread, void *msgData)
+{
+ RETM_IF_ERR(!data || !msgData, "invalid data");
+ ProgressController *controller = (ProgressController *)data;
+
+ controller->m_ProgressPopup->setProgress((size_t)msgData);
}
void ProgressController::onFinish(void *data, Ecore_Thread *thread)
--- /dev/null
+/*
+ * Copyright (c) 2015 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_COMMON_UTILS_H
+#define CONTACTS_COMMON_UTILS_H
+
+#include <storage.h>
+#include <string>
+
+namespace Contacts
+{
+ namespace Common
+ {
+ /**
+ * @brief Gets root or certain storage directory path.
+ * @details If you want to get root storage directory path use STORAGE_DIRECTORY_MAX for @a dirType.
+ *
+ * @param[in] storageType The storage Type
+ * @param[in] dirType The directory type
+ *
+ * @return The directory path
+ */
+ std::string getDirectoryPath(storage_type_e storageType, storage_directory_e dirType);
+ }
+}
+
+#endif /* CONTACTS_COMMON_UTILS_H */
--- /dev/null
+/*
+ * Copyright (c) 2015 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_SETTINGS_EXPORT_CONTROLLER_H
+#define CONTACTS_SETTINGS_EXPORT_CONTROLLER_H
+
+#include <string>
+#include <vector>
+
+#include "Ui/ProgressController.h"
+#include "Contacts/Common/Utils.h"
+
+namespace Contacts
+{
+ namespace Settings
+ {
+ /**
+ * @brief Type of storage where vcard will be created.
+ */
+ enum TargetStorage
+ {
+ TargetStorageDevice,
+ TargetStorageSdCard,
+ TargetStorageInternalOther
+ };
+
+ /**
+ * @brief Controller for Export ProgressPopup
+ */
+ class ExportController : public Ui::ProgressController
+ {
+ public:
+ /**
+ * @brief Create controller for Export ProgressPopup.
+ * @param[in] parent Parent object.
+ * @param[in] title Progress popup title.
+ * @param[in] personIdList Person id list.
+ * @param[in] vcardStorage Type of storage where vcard will be created.
+ */
+ ExportController(Evas_Object *parent, const char *title,
+ std::vector<int> personIdList, TargetStorage vcardStorage);
+
+ private:
+ void createDirectory(const std::string &directoryPath);
+ std::string getVcardDirectoryPath();
+ std::string getVcardFilePath();
+
+ virtual void onStart(Ecore_Thread *thread) override;
+ virtual void onCanceled() override;
+
+ private:
+ std::vector<int> m_PersonIdList;
+ std::string m_VcardPath;
+ TargetStorage m_VcardStorage;
+ };
+ }
+}
+
+#endif /* CONTACTS_SETTINGS_EXPORT_CONTROLLER_H */
--- /dev/null
+/*
+ * Copyright (c) 2015 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/Common/Utils.h"
+#include "Utils/Logger.h"
+
+using namespace Contacts::Common;
+using namespace Contacts;
+
+namespace
+{
+ struct StorageData
+ {
+ storage_type_e m_Type;
+ int m_StorageId;
+ };
+
+ bool storageCb(int storageId, storage_type_e type, storage_state_e state, const char *path, void *userData)
+ {
+ RETVM_IF(!userData, false, "Empty user data");
+ StorageData *storageData = static_cast<StorageData *>(userData);
+
+ if (type == storageData->m_Type && STORAGE_STATE_MOUNTED == state) {
+ storageData->m_StorageId = storageId;
+ return false;
+ }
+ return true;
+ }
+
+ int getStorageId(storage_type_e storageType)
+ {
+ StorageData storageData {storageType, -1};
+ int error = storage_foreach_device_supported(storageCb, &storageData);
+ RETVM_IF_ERR(error, -1, "storage_foreach_device_supported() failed");
+
+ return storageData.m_StorageId;
+ }
+}
+
+std::string Common::getDirectoryPath(storage_type_e storageType, storage_directory_e dirType)
+{
+ char *dirPath = nullptr;
+ int error = STORAGE_ERROR_NONE;
+
+ if (dirType == STORAGE_DIRECTORY_MAX) {
+ error = storage_get_root_directory(getStorageId(storageType), &dirPath);
+ } else {
+ error = storage_get_directory(getStorageId(storageType), dirType, &dirPath);
+ }
+ RETVM_IF_ERR(error, std::string(), "failed to get directory path");
+
+ std::string res = dirPath;
+ free(dirPath);
+
+ return res;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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/Common/Utils.h"
+#include "Contacts/Settings/ExportController.h"
+#include "Utils/Logger.h"
+
+#include <contacts.h>
+#include <notification.h>
+
+using namespace Contacts::Common;
+using namespace Contacts::Settings;
+
+#define BUFFER_SIZE 64
+
+#define RELATIVE_EXPORT_PATH "/Device/Contacts/Exported"
+
+namespace
+{
+ struct {
+ storage_type_e type;
+ storage_directory_e directory;
+ } storageParam[] = {
+ /* [TargetStorageDevice] = */ { STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_MAX },
+ /* [TargetStorageSdCard] = */ { STORAGE_TYPE_EXTERNAL, STORAGE_DIRECTORY_MAX },
+ /* [TargetStorageInternalOther] = */ { STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_OTHERS }
+ };
+}
+
+ExportController::ExportController(Evas_Object *parent, const char *title,
+ std::vector<int> personIdList, TargetStorage vcardStorage)
+ : ProgressController(parent, title, personIdList.size()),
+ m_PersonIdList(std::move(personIdList)), m_VcardStorage(vcardStorage)
+{
+ m_VcardPath = getVcardFilePath();
+}
+
+void ExportController::createDirectory(const std::string &directoryPath)
+{
+ std::string command("mkdir -p ");
+ command.append(directoryPath);
+
+ WARN_IF(system(command.c_str()) == -1, "failed to create folder: %s", strerror(errno));
+}
+
+std::string ExportController::getVcardDirectoryPath()
+{
+ std::string directoryPath = getDirectoryPath(storageParam[m_VcardStorage].type, storageParam[m_VcardStorage].directory);
+
+ if ((storageParam[m_VcardStorage].directory == STORAGE_DIRECTORY_MAX)
+ && !directoryPath.empty()) {
+ directoryPath.append(RELATIVE_EXPORT_PATH);
+ createDirectory(directoryPath);
+ }
+
+ return directoryPath;
+}
+
+std::string ExportController::getVcardFilePath()
+{
+ std::string directoryPath = getVcardDirectoryPath();
+ RETVM_IF(directoryPath.empty(), std::string(), "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;
+ }
+ }
+
+ ERR("Too many vcards. Delete some before creating new.");
+ notification_status_message_post(_("IDS_PB_POP_FAILED"));
+ return std::string();
+}
+
+void ExportController::onStart(Ecore_Thread *thread)
+{
+ FILE *file = fopen(m_VcardPath.c_str(), "a");
+ RETM_IF(!file, "fopen failed: %s", strerror(errno));
+ size_t currentCount = 0;
+
+ for (auto &&personId : m_PersonIdList) {
+ contacts_record_h personRecord = nullptr;
+ int err = contacts_db_get_record(_contacts_person._uri, personId, &personRecord);
+ LOG_IF_ERR(err, continue, "contacts_db_get_record failed: ");
+
+ char *vcardStream = nullptr;
+ err = contacts_vcard_make_from_person(personRecord, &vcardStream);
+ contacts_record_destroy(personRecord, true);
+ LOG_IF_ERR(err, continue, "contacts_vcard_make_from_person failed: ");
+
+ fputs(vcardStream, file);
+ free(vcardStream);
+
+ ++currentCount;
+ if (!onProgress(currentCount)) {
+ ecore_thread_cancel(thread);
+ break;
+ }
+ }
+ fclose(file);
+}
+
+void ExportController::onCanceled()
+{
+ if (!m_VcardPath.empty()) {
+ remove(m_VcardPath.c_str());
+ }
+
+ notification_status_message_post(_("IDS_PB_SBODY_EXPORTING_CANCELLED_M_STATUS_ABB"));
+}
<privilege>http://tizen.org/privilege/callhistory.read</privilege>
<privilege>http://tizen.org/privilege/contact.read</privilege>
<privilege>http://tizen.org/privilege/contact.write</privilege>
+ <privilege>http://tizen.org/privilege/externalstorage</privilege>
<privilege>http://tizen.org/privilege/mediastorage</privilege>
<privilege>http://tizen.org/privilege/notification</privilege>
</privileges>
BuildRequires: pkgconfig(feedback)
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(storage)
%description
Contacts and Phone Reference Applications.