TizenRefApp-8426 Implement text limit exceeded case 86/126886/1
authorDenis Dolzhenko <d.dolzhenko@samsung.com>
Mon, 24 Apr 2017 15:27:28 +0000 (18:27 +0300)
committerDenis Dolzhenko <d.dolzhenko@samsung.com>
Tue, 25 Apr 2017 08:09:03 +0000 (11:09 +0300)
Change-Id: I72c933d5cc07a3cd9f51a831e3debc37f3e5c140
Signed-off-by: Denis Dolzhenko <d.dolzhenko@samsung.com>
18 files changed:
.cproject
src/Common/MsgEngine/inc/MsgComposer.h
src/Common/MsgEngine/inc/MsgEngine.h
src/Common/MsgEngine/src/MsgEngine.cpp
src/Common/MsgEngine/src/MsgUtils.cpp
src/Common/MsgEngine/src/dummy/MsgComposerDummy.cpp
src/Common/MsgEngine/src/dummy/MsgComposerDummy.h
src/Common/MsgEngine/src/private/MsgComposerPrivate.cpp
src/Common/MsgEngine/src/private/MsgComposerPrivate.h
src/Common/MsgEngine/src/private/MsgTransportPrivate.cpp
src/Common/View/inc/BasePopup.h
src/Common/View/src/BasePopup.cpp
src/Common/View/src/PopupManager.cpp
src/Composer/Controller/inc/MsgBodyFrame.h
src/Composer/Controller/src/MsgBodyFrame.cpp
src/MsgThread/Controller/inc/ThreadList.h
src/MsgThread/Controller/src/MsgThreadFrame.cpp
src/MsgThread/Controller/src/ThreadList.cpp

index 61d61eb2fe75ee8ee1236f1a1d541f76281fd909..d13879023b644b5cd27a429c9eccda3d5a4e0bc5 100644 (file)
--- a/.cproject
+++ b/.cproject
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.dialect.std.1756711526" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
-                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.1776859471" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols"/>
+                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.1776859471" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" useByScannerDiscovery="false" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="MSG_PRIVATE_API"/>
+                                                               </option>
                                                                <option id="gnu.cpp.compiler.option.other.other.1256197611" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wno-extern-c-compat" valueType="string"/>
                                                                <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1529131313" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
                                                        </tool>
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.dialect.std.177145679" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
-                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.889877088" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols"/>
+                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.889877088" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def"/>
                                                                <option id="gnu.cpp.compiler.option.other.other.645149247" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0 -Wno-extern-c-compat" valueType="string"/>
                                                                <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1209285457" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
                                                        </tool>
index 9f9a3aa27e8b12c0c5a8cd02c42e28fa6e58512a..8d08ac2b06927b0a3180b88fdbb1d2323c960ce9 100644 (file)
@@ -21,6 +21,9 @@
 #include "MessageMms.h"
 #include "MsgUtils.h"
 #include "Logger.h"
+#include "MsgTypes.h"
+
+#include <vector>
 
 namespace Msg {
     class MsgComposer {
@@ -29,6 +32,14 @@ namespace Msg {
 
             virtual MessageSMSRef createSms() = 0;
             virtual MessageMmsRef createMms() = 0;
+            virtual std::vector<MessageRef> createMultiMessage(const std::string &text) = 0;
+
+            /**
+             * @brief Calculates input text length by encode type.
+             * @param[in] text input text.
+             * @param[out] text metric.
+             **/
+            virtual void calculateTextMetric(const std::string &text, MsgTextMetric &textMetric) = 0;
 
             MessageRef createMessage(Message::Type type);
     };
index 4072033ca343fd88dc34d9f8041b126f86b10467..00fb908d328c7ef38436b73aba117295392ac334 100644 (file)
@@ -80,13 +80,6 @@ namespace Msg {
              */
             static std::string whatError(int error);
 
-            /**
-             * @brief Calculates input text length by encode type.
-             * @param[in] text input text.
-             * @param[out] text metric.
-             **/
-            static void calculateTextMetric(const std::string &text, MsgTextMetric &textMetric);
-
         private:
             std::unique_ptr<MsgStorage>  m_Storage;
             std::unique_ptr<MsgTransport> m_Transport;
index c123f0bf24a127f2a7b33be4fe5bf00d0987779e..0e45d49e93d9a3db81817c42bd0a230614bab52a 100644 (file)
@@ -68,7 +68,7 @@ int MsgEngine::openService()
 
     m_Storage.reset(new MsgStoragePrivate(m_MsgHandle));
     m_Transport.reset(new MsgTransportPrivate(m_MsgHandle));
-    m_Composer.reset(new MsgComposerPrivate());
+    m_Composer.reset(new MsgComposerPrivate(*this));
 #elif MSG_PUBLIC_API
     // TODO: impl for public API
 
@@ -431,56 +431,3 @@ std::string MsgEngine::whatError(int error)
 #endif
     return "SOME ANOTHER ERROR";
 }
-
-void MsgEngine::calculateTextMetric(const std::string &text, MsgTextMetric &textMetric)
-{
-    textMetric.reset();
-
-#ifdef MSG_PRIVATE_API
-    static const int maxGsm7Len = 160;
-    static const int maxUnicodeLen = 70;
-    static const int maxMmsLen = 180; // In bytes
-    int maxSmsLen = maxGsm7Len; // In chars
-
-    msg_encode_type_t encode = MSG_ENCODE_GSM7BIT;
-    unsigned textLen = 0;
-    unsigned segmentLen = 0;
-    int bytesInChar = 1;
-
-    if (!text.empty()) {
-        if (msg_util_calculate_text_length(text.c_str(), MSG_ENCODE_AUTO, &textLen, &segmentLen, &encode) != 0) {
-            MSG_LOG_ERROR("msg_util_calculate_text_length returns error");
-        }
-
-        switch (encode)
-        {
-        case MSG_ENCODE_UCS2:
-            bytesInChar = 2;
-            maxSmsLen = maxUnicodeLen;
-            break;
-
-        case MSG_ENCODE_GSM7BIT:
-        case MSG_ENCODE_AUTO:
-            bytesInChar = 1;
-            maxSmsLen = maxGsm7Len;
-            break;
-
-        default:
-            MSG_LOG_ERROR("Unknown encode type: ", encode);
-            break;
-        }
-
-        textLen /= bytesInChar;
-    }
-
-    if (textLen == 0)
-        textLen = text.length() / bytesInChar;
-
-    textMetric.isMms = textLen > maxSmsLen;
-    textMetric.bytes = textLen * bytesInChar;
-    textMetric.textLen = textLen;
-    textMetric.maxLen = textMetric.isMms ? maxMmsLen : maxSmsLen;
-
-
-#endif
-}
index da53637e6c8f02c6ad598660757c8ef669b2f6c3..dd86771d3238e45b5748de835a30c52eae2ded3e 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "MsgUtils.h"
 #include "LangUtils.h"
+#include "Logger.h"
 
 #include <string.h>
 #include <ctype.h>
@@ -173,13 +174,14 @@ std::list<std::string> splitUtf8String(const std::string &str, const int maxSize
     do {
         prevIndex = index;
         eina_unicode_utf8_next_get(str.c_str(), &index);
+        // FIXME: recognize graphemes
 
         bytes += index - prevIndex;
 
         if (bytes >= maxSize || index == size) {
             int from = startIndex;
             int to = 0;
-            if (bytes == maxSize || index == size) {
+            if (bytes <= maxSize) {
                 to = index;
             } else {
                 to = prevIndex;
@@ -187,6 +189,7 @@ std::list<std::string> splitUtf8String(const std::string &str, const int maxSize
             }
             startIndex = index;
             std::string s(&str[from], &str[to]);
+
             if (!s.empty() && s.size() <= maxSize)
                 list.push_back(std::move(s));
             bytes = 0;
index b8555371b458ee50745bec8e252318be2eb6d105..aa3cd9b84820711db8ca8157af8371da6972d805 100644 (file)
@@ -47,6 +47,11 @@ MessageMmsRef MsgComposerDummy::createMms()
     return mmsRef;
 }
 
+std::vector<MessageRef> MsgComposerDummy::createMultiMessage(const std::string &text)
+{
+    return {};
+}
+
 void MsgComposerDummy::setSmilHeader(bool isTextTop)
 {
 }
index 6997cc137c76cde95f76e5a713968e897d8f0cf9..44b00edaf717b99edf9b3204cfd713172a3bff23 100644 (file)
@@ -32,6 +32,7 @@ namespace Msg
 
             virtual MessageSMSRef createSms();
             virtual MessageMmsRef createMms();
+            virtual std::vector<MessageRef> createMultiMessage(const std::string &text);
 
         private:
             void setSmilHeader(bool isTextTop);
index 82dc2a4f84c2ef3a17c4a4dc40629f2da669a3dc..00d4d87662632e0d26bb3722824589ecfaecc54a 100644 (file)
  * limitations under the License.
  */
 
+#include "MsgEngine.h"
 #include "MsgComposerPrivate.h"
 #include "MessageSMSPrivate.h"
 #include "MessageMmsPrivate.h"
 #include "MsgUtilsPrivate.h"
 #include "MsgDefPrivate.h"
+#include "MsgUtils.h"
+#include "MsgEngine.h"
+#include "Logger.h"
 
 #include <msg.h>
 
 using namespace Msg;
 
 
-MsgComposerPrivate::MsgComposerPrivate()
+MsgComposerPrivate::MsgComposerPrivate(MsgEngine &msgEngine)
+    : m_Engine(msgEngine)
 {
 }
 
@@ -106,3 +111,77 @@ void MsgComposerPrivate::setSmilHeader(msg_struct_t mms, bool isTextTop)
     msg_set_int_value(imageRegion, MSG_MMS_REGION_LENGTH_HEIGHT_INT, smilRegionHeight);
     msg_set_bool_value(imageRegion, MSG_MMS_REGION_LENGTH_HEIGHT_PERCENT_BOOL, true);
 }
+
+std::vector<MessageRef> MsgComposerPrivate::createMultiMessage(const std::string &text)
+{
+    std::vector<MessageRef> msgList;
+    int maxMsgSize = m_Engine.getSettings().getMaxMmsSize();
+    if (maxMsgSize <= 0) {
+        MSG_LOG_ERROR("getMaxMmsSize() returns 0");
+        return {};
+    }
+
+    auto textList = MsgUtils::splitUtf8String(text, maxMsgSize);
+
+    for (auto &&text : textList) {
+        MsgTextMetric metric;
+        calculateTextMetric(text, metric);
+        Message::Type type = metric.isMms ? Message::MT_MMS : Message::MT_SMS;
+        auto msg = createMessage(type);
+        if (msg) {
+            msg->setText(std::move(text));
+            msgList.push_back(msg);
+        }
+    }
+
+    return msgList;
+}
+
+void MsgComposerPrivate::calculateTextMetric(const std::string &text, MsgTextMetric &textMetric)
+{
+    textMetric.reset();
+
+    static const int maxGsm7Len = 160;
+    static const int maxUnicodeLen = 70;
+    const int maxMmsLen = m_Engine.getSettings().getMaxMmsSize();; // In bytes
+    int maxSmsLen = maxGsm7Len; // In chars
+
+    msg_encode_type_t encode = MSG_ENCODE_GSM7BIT;
+    unsigned textLen = 0;
+    unsigned segmentLen = 0;
+    int bytesInChar = 1;
+
+    if (!text.empty()) {
+        if (msg_util_calculate_text_length(text.c_str(), MSG_ENCODE_AUTO, &textLen, &segmentLen, &encode) != 0) {
+            MSG_LOG_ERROR("msg_util_calculate_text_length returns error");
+        }
+
+        switch (encode)
+        {
+        case MSG_ENCODE_UCS2:
+            bytesInChar = 2;
+            maxSmsLen = maxUnicodeLen;
+            break;
+
+        case MSG_ENCODE_GSM7BIT:
+        case MSG_ENCODE_AUTO:
+            bytesInChar = 1;
+            maxSmsLen = maxGsm7Len;
+            break;
+
+        default:
+            MSG_LOG_ERROR("Unknown encode type: ", encode);
+            break;
+        }
+
+        textLen /= bytesInChar;
+    }
+
+    if (textLen == 0)
+        textLen = text.length() / bytesInChar;
+
+    textMetric.isMms = textLen > maxSmsLen;
+    textMetric.bytes = textLen * bytesInChar;
+    textMetric.textLen = textLen;
+    textMetric.maxLen = textMetric.isMms ? maxMmsLen : maxSmsLen;
+}
index 8f6cda48ad13463d6580770c96cc5c16174e8bfd..e6416f3a94c249d45047a7aed4d73edac1d59c32 100644 (file)
 #include <msg_types.h>
 
 namespace Msg {
+    class MsgEngine;
     class MsgComposerPrivate
         : public MsgComposer {
         public:
-            MsgComposerPrivate();
+            MsgComposerPrivate(MsgEngine &msgEngine);
             MsgComposerPrivate(MsgComposerPrivate&) = delete;
             MsgComposerPrivate &operator=(MsgComposerPrivate&) = delete;
             virtual ~MsgComposerPrivate();
 
-            virtual MessageSMSRef createSms();
-            virtual MessageMmsRef createMms();
+            MessageSMSRef createSms() override;
+            MessageMmsRef createMms() override;
+            std::vector<MessageRef> createMultiMessage(const std::string &text) override;
+            void calculateTextMetric(const std::string &text, MsgTextMetric &textMetric) override;
 
         private:
             void setSmilHeader(msg_struct_t mms, bool isTextTop);
+
+        private:
+            MsgEngine &m_Engine;
     };
 }
 
index f535f846eb4aa6afef44ccf008e811702064be64..ce06f780ed62888a8b7bf3f44ac3dc0fc700689a 100644 (file)
@@ -60,7 +60,6 @@ MsgTransport::SendResult MsgTransportPrivate::sendMessage(Message &msg, ThreadId
 
     msg_set_struct_handle(req, MSG_REQUEST_MESSAGE_HND, privMsg);
 
-
     if (privMsg.isMms()) {
         MSG_LOG("Sending MMS");
         err = msg_mms_send_message(m_ServiceHandle, req);
index 4cdb496b2ffc90d9c208b59a1a75fc13faf64705..08c6ff3a0f8764ef7d9636bc6b0b05abb4fafad9 100644 (file)
@@ -34,15 +34,20 @@ namespace Msg {
 
             void setDismissByOutsideTapFlag(bool value);
             bool getDismissByOutsideTapFlag() const;
+
             void setDismissByPauseAppFlag(bool value);
             bool getDismissByPauseAppFlag() const;
 
+            void setDismissByBackButtonFlag(bool value);
+            bool getDismissByBackButtonFlag() const;
+
         protected:
             static Evas_Object *getWindow();
 
         private:
             bool m_OutsideTapDismiss;
             bool m_PauseAppDismiss;
+            bool m_BackButtonDismiss;
     };
 }
 
index ae3115695f06d47d21e14f89fc095ec08aa90d9e..a326f65830e1d9d5db92f87077ef4be3510cc65c 100644 (file)
@@ -24,6 +24,7 @@ using namespace Msg;
 BasePopup::BasePopup(Evas_Object *popup)
     : m_OutsideTapDismiss(false)
     , m_PauseAppDismiss(false)
+    , m_BackButtonDismiss(true)
 {
     setEo(popup);
     App::getInst().getPopupManager().push(*this);
@@ -62,3 +63,13 @@ bool BasePopup::getDismissByPauseAppFlag() const
 {
     return m_PauseAppDismiss;
 }
+
+void BasePopup::setDismissByBackButtonFlag(bool value)
+{
+    m_BackButtonDismiss = value;
+}
+
+bool BasePopup::getDismissByBackButtonFlag() const
+{
+    return m_BackButtonDismiss;
+}
index 0d69e3f0d81d92e7d7d9763150c6e71a43920c67..39a972c9ca84140b03c9951ad67e957131335d69 100644 (file)
@@ -76,7 +76,8 @@ BasePopup *PopupManager::getTop() const
 
 void PopupManager::onHwBackButtonClicked(Evas_Object *obj, void *eventInfo)
 {
-    pop();
+    if (m_pPopup && m_pPopup->getDismissByBackButtonFlag())
+        pop();
 }
 
 void PopupManager::onPause()
index 6cdc37d7449521adfc736158a60764ce6ecd42ff..73a5ab4d7c1fa327bee80ffaa2a2367383c91ef5 100644 (file)
 #include "Recipient.h"
 #include "MsgStorage.h"
 
+#include <set>
+
 namespace Msg {
 
+    class MsgEngine;
     class DefaultLayout;
     class IconTextPopup;
     class Popup;
@@ -45,11 +48,25 @@ namespace Msg {
             void onHwBackButtonPreessed(Evas_Object *obj, void *event);
 
         private:
+            struct SendInfo {
+                SendInfo ();
+                void reset();
+                std::vector<MessageRef> msgs;
+                std::set<RequestId> reqtIdSet;
+                Message::NetworkStatus status;
+                ThreadId threadId;
+                bool inProgress;
+            };
+
             void prepareLayout();
             void prepareBody();
             void updateTextCounter();
-            void sendMsg();
-            bool checkBeforeSend(const Message &msg);
+            std::vector<MessageRef> createMessage();
+            void sendMessage();
+            void requestSendMessage();
+            void resetSendInfo();
+            MsgEngine &getMsgEngine();
+            bool checkBeforeSend(Message::Type type);
             void handleSendResult(const Message &msg, MsgTransport::SendResult result);
             bool read(Message &msg);
             bool readBody(Message &msg);
@@ -68,6 +85,7 @@ namespace Msg {
 
             // Popup callback:
             void onSendingPopupDestroy(Evas *e, Evas_Object *obj, void *event_info);
+            void onSendingPopupBackButtonPressed(Evas_Object *obj, void *event_info);
             void onTurnOffFlightModeClicked(Popup &popup);
             void onAllowTransmissionTextLClicked(Popup &popup);
             void onEnableDataRoamingClicked(Popup &popup);
@@ -91,8 +109,7 @@ namespace Msg {
             IconTextPopup *m_pSendingPopup;
             MsgTextMetric m_TextMetric;
             Recipient m_Recip;
-            ThreadId m_ThreadId;
-            RequestId m_ReqtId;
+            SendInfo m_SendInfo;
     };
 }
 
index 012e9c1f3b3624462b8eeb81f4a00c64a3cd56b5..122bae98ac5baabb6aa382ef84bdfdbe1054f3be 100644 (file)
 #include "SystemSettingsManager.h"
 #include "PopupManager.h"
 #include "ConvFrame.h"
+#include "MsgUtils.h"
 
 using namespace Msg;
 
+MsgBodyFrame::SendInfo::SendInfo()
+    : reqtIdSet()
+    , status(Message::NS_Unknown)
+    , threadId()
+    , inProgress(false)
+{
+}
+
+void MsgBodyFrame::SendInfo::reset()
+{
+    msgs.clear();
+    inProgress = false;
+    reqtIdSet.clear();
+    status = Message::NS_Unknown;
+    threadId.reset();
+}
+
 MsgBodyFrame::MsgBodyFrame(NaviFrameController &parent, Recipient recip)
     : FrameController(parent)
     , m_pLayout(nullptr)
@@ -39,13 +57,15 @@ MsgBodyFrame::MsgBodyFrame(NaviFrameController &parent, Recipient recip)
     MSG_LOG("");
     prepareLayout();
     prepareBody();
-    App::getInst().getMsgEngine().getTransport().addListener(*this);
+    getMsgEngine().getTransport().addListener(*this);
 }
 
 MsgBodyFrame::~MsgBodyFrame()
 {
     MSG_LOG("");
-    App::getInst().getMsgEngine().getTransport().removeListener(*this);
+    if (m_pSendingPopup)
+        m_pSendingPopup->destroy();
+    getMsgEngine().getTransport().removeListener(*this);
 }
 
 void MsgBodyFrame::prepareLayout()
@@ -72,7 +92,7 @@ void MsgBodyFrame::prepareBody()
 void MsgBodyFrame::updateTextCounter()
 {
     const std::string &text = m_pBody->getEntry().getText();
-    App::getInst().getMsgEngine().calculateTextMetric(text, m_TextMetric);
+    getMsgEngine().getComposer().calculateTextMetric(text, m_TextMetric);
 
     m_TextMetric.isMms ?
         m_pBody->setCounter(msgt("WDS_MSG_SBODY_MMS_ABB")) :
@@ -87,7 +107,7 @@ void MsgBodyFrame::handleSendResult(const Message &msg, MsgTransport::SendResult
     // TODO: impl.
 }
 
-bool MsgBodyFrame::checkBeforeSend(const Message &msg)
+bool MsgBodyFrame::checkBeforeSend(Message::Type type)
 {
     if (!App::getInst().getSysSettingsManager().isSimInserted()) {
          // TODO: popup for No SIM card
@@ -99,7 +119,7 @@ bool MsgBodyFrame::checkBeforeSend(const Message &msg)
         return false;
     }
 
-    if (msg.isMms() && !App::getInst().getSysSettingsManager().isMobileDataEnabled()) {
+    if (MsgUtils::isMms(type) && !App::getInst().getSysSettingsManager().isMobileDataEnabled()) {
         showMobileNetworkSettingsPopup();
         return false;
     }
@@ -138,26 +158,63 @@ bool MsgBodyFrame::readAddress(Message &msg)
     return false;
 }
 
-void MsgBodyFrame::sendMsg()
+MsgEngine &MsgBodyFrame::getMsgEngine()
 {
-    auto msgRef = App::getInst().getMsgEngine().getComposer().createMessage(m_TextMetric.isMms ? Message::MT_MMS : Message::MT_SMS);
-    if (!msgRef)
-        return;
+    return App::getInst().getMsgEngine();
+}
 
-    Message &msg = *msgRef;
+std::vector<MessageRef> MsgBodyFrame::createMessage()
+{
+    const std::string &text = m_pBody->getEntry().getText();
+    std::vector<MessageRef> msgList = getMsgEngine().getComposer().createMultiMessage(text);
 
-    if (!read(msg) || !checkBeforeSend(msg))
+    for (MessageRef &msg : msgList) {
+        readAddress(*msg);
+    }
+
+    return msgList;
+}
+
+void MsgBodyFrame::requestSendMessage()
+{
+    m_SendInfo.reset();
+
+    m_SendInfo.msgs = createMessage();
+    if (m_SendInfo.msgs .empty())
         return;
 
-    MsgTransport::SendResult sendRes = App::getInst().getMsgEngine().getTransport().sendMessage(msg, &m_ThreadId, &m_ReqtId);
-    MSG_LOG("Send result = ", sendRes);
-    MSG_LOG("Request id = ", m_ReqtId);
+    if (!checkBeforeSend(m_SendInfo.msgs [0]->getType()))
+        return;
+
+    sendMessage();
+}
+
+void MsgBodyFrame::sendMessage()
+{
+    MsgTransport::SendResult sendRes = MsgTransport::SendFail;
+    MessageRef lastSentMsg;
+
+    for (MessageRef msg : m_SendInfo.msgs) {
+        lastSentMsg = msg;
+        RequestId reqId;
+        sendRes = getMsgEngine().getTransport().sendMessage(msg, &m_SendInfo.threadId, &reqId);
+
+        MSG_LOG("Send result = ", sendRes);
+        MSG_LOG("Request id = ", reqId);
+
+        if (sendRes != MsgTransport::SendSuccess)
+            break;
 
-    if (sendRes == MsgTransport::SendSuccess && m_ThreadId.isValid()) {
+        m_SendInfo.inProgress = true;
+        m_SendInfo.reqtIdSet.insert(reqId);
+    }
+
+    if (sendRes == MsgTransport::SendSuccess && m_SendInfo.threadId.isValid()) {
         m_pBody->getEntry().clear();
         showSendingProgressPopup();
     } else {
-        handleSendResult(msg, sendRes);
+        if (lastSentMsg)
+            handleSendResult(*lastSentMsg, sendRes);
     }
 }
 
@@ -168,14 +225,14 @@ void MsgBodyFrame::navigateAfterSent()
 
     if (!App::getInst().isTerminating()) {
         // Navigate to ConvFrame
-        if (m_ThreadId.isValid()) {
-            ConvFrame *conv = getParent().getTopFrame<ConvFrame>();
+        if (m_SendInfo.threadId.isValid()) {
+            auto *conv = getParent().getTopFrame<ConvFrame>();
             if (!conv) {
                 conv = new ConvFrame(getParent());
-                conv->setThreadId(m_ThreadId);
+                conv->setThreadId(m_SendInfo.threadId);
                 getParent().push(*conv);
             } else {
-                conv->setThreadId(m_ThreadId);
+                conv->setThreadId(m_SendInfo.threadId);
                 getParent().promote(*conv);
             }
         }
@@ -209,7 +266,9 @@ void MsgBodyFrame::showSendingProgressPopup()
 {
     if (!m_pSendingPopup) {
         m_pSendingPopup = new IconTextPopup;
+        m_pSendingPopup->setDismissByBackButtonFlag(false);
         m_pSendingPopup->addEventCb(EVAS_CALLBACK_DEL, makeCbFirst(&MsgBodyFrame::onSendingPopupDestroy), this);
+        m_pSendingPopup->addHwButtonEvent(EEXT_CALLBACK_BACK, makeCbFirst(&MsgBodyFrame::onSendingPopupBackButtonPressed), this);
         m_pSendingPopup->setIcon(IconTextPopup::ProgressIcon);
         m_pSendingPopup->setText(msgt("IDS_MSG_BODY_SENDING_ING_M_STATUS_ABB"));
         m_pSendingPopup->show();
@@ -228,7 +287,7 @@ void MsgBodyFrame::showMmsTextLimitExceededPopup()
 {
     auto *popup = new StandardPopup(StandardPopup::buttons2Style);
     // TODO: remove later
-    int numberOfCharacters = 2048;
+    int numberOfCharacters = getMsgEngine().getSettings().getMaxMmsSize();
     int numberOfMmsMsg = 2;
 
     std::string popupMessage = msgArgs("WDS_MSG_BODY_MAXIMUM_NUMBER_OF_CHARACTERS_HPD_EXCEEDED", numberOfCharacters);
@@ -266,6 +325,18 @@ void MsgBodyFrame::onSendingPopupDestroy(Evas *e, Evas_Object *obj, void *event_
     m_pSendingPopup = nullptr;
 }
 
+void MsgBodyFrame::onSendingPopupBackButtonPressed(Evas_Object *obj, void *event_info)
+{
+    MSG_LOG("");
+    if (m_pSendingPopup)
+        m_pSendingPopup->destroy();
+
+    if (m_SendInfo.inProgress) {
+        m_SendInfo.reset();
+        getParent().popGroup(*this);
+    }
+}
+
 void MsgBodyFrame::onTurnOffFlightModeClicked(Popup &popup)
 {
     MSG_LOG("");
@@ -322,13 +393,13 @@ void  MsgBodyFrame::onEntryChanged(Evas_Object *obj, void *event)
 void MsgBodyFrame::onEntryActivated(Evas_Object *obj, void *event)
 {
     MSG_LOG("");
-    sendMsg();
+    requestSendMessage();
 }
 
 void MsgBodyFrame::onSendButtonClicked()
 {
     MSG_LOG("");
-    sendMsg();
+    requestSendMessage();
 }
 
 void MsgBodyFrame::onEntryFilter(Evas_Object *obj, char **text)
@@ -350,19 +421,45 @@ void MsgBodyFrame::onMsgTransportSentStatus(const MsgSentStatus &status)
     MSG_LOG("Id = ", id);
     MSG_LOG("Network status = ", networkStatus);
 
-    if (m_pSendingPopup && m_ReqtId == id && networkStatus != Message::NS_Sending) {
-        if (networkStatus == Message::NS_Send_Success) {
+    auto reqIdIt = m_SendInfo.reqtIdSet.find(id);
+    bool reqFound = reqIdIt != m_SendInfo.reqtIdSet.end();
+
+    // Skip unknown request
+    if (!reqFound)
+        return;
+
+    if (networkStatus == Message::NS_Sending)
+        return;
+
+    m_SendInfo.reqtIdSet.erase(reqIdIt);
+    bool isLast = m_SendInfo.reqtIdSet.empty();
+
+    if (networkStatus == Message::NS_Send_Fail)
+        m_SendInfo.status = Message::NS_Send_Fail;
+    else if (networkStatus == Message::NS_Send_Pending && m_SendInfo.status != Message::NS_Send_Fail)
+        m_SendInfo.status = Message::NS_Send_Pending;
+    else if (m_SendInfo.status == Message::NS_Unknown)
+        m_SendInfo.status = networkStatus;
+
+    if (isLast || m_SendInfo.status == Message::NS_Send_Fail) {
+
+        m_SendInfo.inProgress = false;
+        m_SendInfo.reqtIdSet.clear();
+
+        if (m_SendInfo.status == Message::NS_Send_Success) {
             m_pSendingPopup->setIcon(IconTextPopup::CheckIcon);
             m_pSendingPopup->setText(msgt("WDS_WNOTI_TPOP_SENT_ABB"));
             m_pSendingPopup->setTimeOut();
-        } else if (networkStatus == Message::NS_Send_Fail) {
+        } else if (m_SendInfo.status == Message::NS_Send_Fail) {
             m_pSendingPopup->setIcon(IconTextPopup::FailedIcon);
             m_pSendingPopup->setText(msgt("WDS_MSG_TPOP_SENDING_FAILED_ABB"));
             m_pSendingPopup->setTimeOut();
-        } else if (networkStatus != Message::NS_Send_Pending) {
+        } else if (m_SendInfo.status != Message::NS_Send_Pending) {
             m_pSendingPopup->destroy();
             showSentWhenServiceBecomesAvailablePopup();
         }
+
         navigateAfterSent();
+        m_SendInfo.reset();
     }
 }
index db9d57f8d1b815e695161b951cff4af48dfe0f0f..81363b55abbcc68f30fc8f184b152390d2d087a2 100644 (file)
@@ -43,7 +43,7 @@ namespace Msg {
         , private IThreadComposeListViewItemListener {
 
         public:
-            ThreadList(DefaultLayout *parent);
+            ThreadList(DefaultLayout &parent);
             virtual ~ThreadList();
 
             void setListener(IThreadListListener *l);
@@ -97,7 +97,6 @@ namespace Msg {
             PaddingListViewItem *m_pTopPadItem;
             PaddingListViewItem *m_pBottomPadItem;
             NoContentListViewItem *m_pNoContentItem;
-            DefaultLayout *m_pParentLayout;
     };
 
     class IThreadListListener {
index 1c1988de5e03a87a001193e29590cda53cd002bb..c87132aed423e1931b4805b2deae65894f05d60e 100644 (file)
@@ -101,7 +101,7 @@ void MsgThreadFrame::setDeleteMode(bool value)
 void MsgThreadFrame::prepareThreadList()
 {
     if (!m_pThreadList) {
-        m_pThreadList = new ThreadList(m_pLayout);
+        m_pThreadList = new ThreadList(*m_pLayout);
         m_pThreadList->setListener(this);
         m_pLayout->setContent(*m_pThreadList);
         m_pLayout->showContent(true);
index 9579f014ba4142165dba070a3245cf7c48d5843d..f1c47a5232008f8cac13d7b632cc080f73e148e1 100644 (file)
@@ -34,8 +34,8 @@ namespace {
     }
 }
 
-ThreadList::ThreadList(DefaultLayout *parent)
-    : ListView(*parent, App::getInst().getWindow().getCircleSurface())
+ThreadList::ThreadList(DefaultLayout &parent)
+    : ListView(parent, App::getInst().getWindow().getCircleSurface())
     , m_pListener(nullptr)
     , m_App(App::getInst())
     , m_DeleteMode(false)
@@ -43,7 +43,6 @@ ThreadList::ThreadList(DefaultLayout *parent)
     , m_pTopPadItem(nullptr)
     , m_pBottomPadItem(nullptr)
     , m_pNoContentItem(nullptr)
-    , m_pParentLayout(parent)
 {
     ListView::setListener(this);
     ListView::setHomogeneous(false);