From 2b0936e4eafee4da5e2ff3c0a7b7fd0df8a9f5c4 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Thu, 20 Aug 2015 19:02:40 +0300
Subject: Add ability for insert cards into items by dragging.

---
 src/CMakeLists.txt                  |  1 +
 src/Makefile.am                     |  1 +
 src/gui/widgets/itemcontainer.cpp   | 13 +++++++++
 src/gui/windows/inventorywindow.cpp | 41 ++++++++++++++++++++++++++++
 src/gui/windows/inventorywindow.h   |  3 +++
 src/listeners/insertcardlistener.h  | 53 +++++++++++++++++++++++++++++++++++++
 6 files changed, 112 insertions(+)
 create mode 100644 src/listeners/insertcardlistener.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0b21bd5c0..a5694f788 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1167,6 +1167,7 @@ SET(SRCS
     listeners/guitableactionlistener.h
     listeners/inputactionreplaylistener.cpp
     listeners/inputactionreplaylistener.h
+    listeners/insertcardlistener.h
     listeners/inventorylistener.h
     events/inputguievent.h
     input/key.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 054b7b634..aa9192666 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1003,6 +1003,7 @@ manaplus_SOURCES += main.cpp \
 	      listeners/playerpostdeathlistener.h \
 	      listeners/inputactionreplaylistener.cpp \
 	      listeners/inputactionreplaylistener.h \
+	      listeners/insertcardlistener.h \
 	      listeners/inventorylistener.h \
 	      listeners/updatestatuslistener.cpp \
 	      listeners/updatestatuslistener.h \
diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp
index e728cb3a4..b533aadd3 100644
--- a/src/gui/widgets/itemcontainer.cpp
+++ b/src/gui/widgets/itemcontainer.cpp
@@ -36,6 +36,7 @@
 #include "gui/popups/itempopup.h"
 
 #include "gui/windows/chatwindow.h"
+#include "gui/windows/inventorywindow.h"
 #include "gui/windows/shopwindow.h"
 #include "gui/windows/shortcutwindow.h"
 
@@ -579,6 +580,18 @@ void ItemContainer::mouseReleased(MouseEvent &event)
             dstContainer = InventoryType::CART;
             inventory = PlayerInfo::getInventory();
         }
+        if (src == DRAGDROP_SOURCE_INVENTORY
+            && dst == DRAGDROP_SOURCE_INVENTORY)
+        {
+            const int index = getSlotIndex(event.getX(), event.getY());
+            if (index == Inventory::NO_SLOT_INDEX)
+                return;
+            if (index == mSelectedIndex || mSelectedIndex == -1)
+                return;
+            if (inventoryWindow)
+                inventoryWindow->combineItems(index, mSelectedIndex);
+            return;
+        }
         else if (src == DRAGDROP_SOURCE_CART
                  && dst == DRAGDROP_SOURCE_INVENTORY)
         {
diff --git a/src/gui/windows/inventorywindow.cpp b/src/gui/windows/inventorywindow.cpp
index d4f27fd74..931acdf4a 100644
--- a/src/gui/windows/inventorywindow.cpp
+++ b/src/gui/windows/inventorywindow.cpp
@@ -40,11 +40,13 @@
 #include "gui/popups/popupmenu.h"
 #include "gui/popups/textpopup.h"
 
+#include "gui/windows/confirmdialog.h"
 #include "gui/windows/itemamountwindow.h"
 #include "gui/windows/setupwindow.h"
 #include "gui/windows/tradewindow.h"
 
 #include "gui/widgets/button.h"
+#include "gui/widgets/createwidget.h"
 #include "gui/widgets/containerplacer.h"
 #include "gui/widgets/dropdown.h"
 #include "gui/widgets/itemcontainer.h"
@@ -56,6 +58,8 @@
 #include "gui/widgets/textfield.h"
 #include "gui/widgets/windowcontainer.h"
 
+#include "listeners/insertcardlistener.h"
+
 #include "net/inventoryhandler.h"
 
 #include "resources/iteminfo.h"
@@ -70,6 +74,7 @@ InventoryWindow *storageWindow = nullptr;
 InventoryWindow *cartWindow = nullptr;
 #endif
 InventoryWindow::WindowList InventoryWindow::invInstances;
+InsertCardListener insertCardListener;
 
 InventoryWindow::InventoryWindow(Inventory *const inventory) :
     Window("Inventory", Modal_false, nullptr, "inventory.xml"),
@@ -1004,3 +1009,39 @@ void InventoryWindow::attributeChanged(const AttributesT id,
         updateWeight();
     }
 }
+
+#ifdef EATHENA_SUPPORT
+void InventoryWindow::combineItems(const int index1,
+                                   const int index2)
+{
+    if (!mInventory)
+        return;
+    const Item *item1 = mInventory->getItem(index1);
+    if (!item1)
+        return;
+    const Item *item2 = mInventory->getItem(index2);
+    if (!item2)
+        return;
+
+    if (item1->getType() != ItemType::CARD)
+    {
+        const Item *tmpItem = item1;
+        item1 = item2;
+        item2 = tmpItem;
+    }
+
+    ConfirmDialog *const confirmDlg = CREATEWIDGETR(ConfirmDialog,
+        // TRANSLATORS: question dialog title
+        _("Insert card request"),
+        // TRANSLATORS: question dialog message
+        strprintf(_("Insert %s into %s?"),
+        item1->getName().c_str(),
+        item2->getName().c_str()),
+        SOUND_REQUEST,
+        false,
+        Modal_true);
+    insertCardListener.itemIndex = item2->getInvIndex();
+    insertCardListener.cardIndex = item1->getInvIndex();
+    confirmDlg->addActionListener(&insertCardListener);
+}
+#endif
diff --git a/src/gui/windows/inventorywindow.h b/src/gui/windows/inventorywindow.h
index 790593b6f..a579373e3 100644
--- a/src/gui/windows/inventorywindow.h
+++ b/src/gui/windows/inventorywindow.h
@@ -156,6 +156,9 @@ class InventoryWindow final : public Window,
                               const int oldVal,
                               const int newVal) override final;
 
+        void combineItems(const int index1,
+                          const int index2);
+
         static bool isAnyInputFocused();
 
         static InventoryWindow *getFirstVisible();
diff --git a/src/listeners/insertcardlistener.h b/src/listeners/insertcardlistener.h
new file mode 100644
index 000000000..ce973cb70
--- /dev/null
+++ b/src/listeners/insertcardlistener.h
@@ -0,0 +1,53 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2004-2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011-2015  The ManaPlus Developers
+ *
+ *  This file is part of The ManaPlus Client.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LISTENERS_INSERTCARDLISTENER_H
+#define LISTENERS_INSERTCARDLISTENER_H
+
+#include "listeners/actionlistener.h"
+
+#include "net/inventoryhandler.h"
+
+#include "localconsts.h"
+
+struct InsertCardListener final : public ActionListener
+{
+    InsertCardListener() :
+        ActionListener(),
+        cardIndex(0),
+        itemIndex(0)
+    {
+    }
+
+    A_DELETE_COPY(InsertCardListener)
+
+    void action(const ActionEvent &event) override final
+    {
+        if (event.getId() == "yes" && inventoryHandler)
+            inventoryHandler->insertCard(cardIndex, itemIndex);
+    }
+
+    int cardIndex;
+    int itemIndex;
+};
+
+#endif  // LISTENERS_INSERTCARDLISTENER_H
-- 
cgit v1.2.3-70-g09d2