Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / interface_v3 / action_handler_item.cpp
blob9bbf9fbc8d05b51c08100d3d693d660975d4b92f
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "stdpch.h"
26 #include "action_handler_item.h"
27 #include "nel/gui/action_handler.h"
28 #include "interface_manager.h"
29 #include "../sheet_manager.h"
30 #include "dbctrl_sheet.h"
31 #include "dbgroup_list_sheet.h"
32 #include "nel/gui/group_editbox.h"
33 #include "nel/gui/interface_expr.h"
34 #include "player_trade.h"
35 #include "../user_entity.h"
36 #include "../net_manager.h"
37 #include "nel/gui/group_menu.h"
38 #include "../global.h"
39 #include "nel/gui/group_html.h"
42 #include "game_share/inventories.h"
43 #include "game_share/bot_chat_types.h"
45 #include "macrocmd_manager.h"
46 #include "inventory_manager.h"
48 #include "nel/gui/ctrl_base_button.h"
49 #include "../connection.h"
50 #include "nel/gui/view_bitmap.h"
51 #include "../item_group_manager.h"
52 extern CSheetManager SheetMngr;
53 extern NLMISC::CLog g_log;
55 using namespace std;
56 using namespace NLMISC;
58 #ifdef DEBUG_NEW
59 #define new DEBUG_NEW
60 #endif
62 CInterfaceItemEdition *CInterfaceItemEdition::_Instance = NULL;
64 // ********************************************************************************************
65 CInterfaceItemEdition *CInterfaceItemEdition::getInstance()
67 if (!_Instance) _Instance = new CInterfaceItemEdition;
68 return _Instance;
71 // ********************************************************************************************
72 void CInterfaceItemEdition::releaseInstance()
74 if( _Instance )
76 delete _Instance;
77 _Instance = NULL;
81 // ********************************************************************************************
82 void CInterfaceItemEdition::setCurrWindow(CDBCtrlSheet* ctrlSheet, const std::string &windowName, const bool &isInEditionMode)
84 _CurrWindow.end();
86 if (ctrlSheet && !windowName.empty())
88 _CurrWindow.ItemSheet = ctrlSheet->getSheetId();
89 _CurrWindow.ItemSlotId = getInventory().getItemSlotId(ctrlSheet);
90 _CurrWindow._CurrItemSheet = ctrlSheet;
91 _CurrWindow.WindowName = windowName;
92 _CurrWindow.IsInEditionMode = isInEditionMode;
93 _CurrWindow.begin();
97 // ********************************************************************************************
98 void CInterfaceItemEdition::update()
100 _CurrWindow.update();
102 // ********************************************************************************************
103 void CInterfaceItemEdition::validate()
105 _CurrWindow.validate();
106 setCurrWindow(NULL);
109 // ********************************************************************************************
110 void CInterfaceItemEdition::CItemEditionWindow::infoReceived()
112 if(_CurrItemSheet && !WindowName.empty())
114 const CItemSheet *pIS = _CurrItemSheet->asItemSheet();
115 if ((pIS != NULL) && ITEMFAMILY::isTextCustomizable(pIS->Family) )
117 CInterfaceManager *pIM = CInterfaceManager::getInstance();
118 // get the dialog stack
119 CInterfaceGroup* group = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(WindowName) );
121 CInterfaceGroup* editShort = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_short")) );
122 CGroupEditBox* editBoxShort = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_short")) );
123 CInterfaceGroup* editLarge = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_large")) );
124 CGroupEditBox* editBoxLarge = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_large")) );
125 CViewText* display = dynamic_cast<CViewText*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_display")) );
126 if (group && editShort && editBoxShort && editLarge && editBoxLarge && display)
128 CClientItemInfo const& itemInfo = getInventory().getItemInfo( ItemSlotId );
129 if (IsInEditionMode)
131 if ( pIS->Family == ITEMFAMILY::SCROLL)
133 editBoxLarge->setInputString(itemInfo.CustomText.toUtf8()); // TODO: UTF-8 (serial)
134 editLarge->setActive(true);
135 editBoxLarge->setActive(true);
137 // Set the Keyboard focus to the editbox (after the enableModalWindow())
138 CWidgetManager::getInstance()->setCaptureKeyboard(editBoxLarge);
139 // Select all the text for easier selection
140 editBoxLarge->setSelectionAll();
142 else
144 string customText;
145 if (!itemInfo.CustomText.empty())
147 customText = itemInfo.CustomText.toUtf8(); // TODO: UTF-8 (serial)
148 strFindReplace(customText, "%mfc", string());
151 editBoxShort->setInputString(customText);
152 editShort->setActive(true);
153 editBoxShort->setActive(true);
155 // Set the Keyboard focus to the editbox (after the enableModalWindow())
156 CWidgetManager::getInstance()->setCaptureKeyboard(editBoxShort);
157 // Select all the text for easier selection
158 editBoxShort->setSelectionAll();
160 group->setActive(true);
162 else
164 const char *localDesc = STRING_MANAGER::CStringManagerClient::getItemLocalizedDescription(pIS->Id);
165 if (itemInfo.CustomText.empty())
166 display->setTextFormatTaged(localDesc);
167 else
169 string text = itemInfo.CustomText.toUtf8();
170 if (text.size() > 3 && text[0]=='@' && text[1]=='W' && text[2]=='E' && text[3]=='B')
172 CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:web_transactions:content:html"));
173 if (pGH)
174 pGH->browse(text.substr(4, text.size()-4).c_str());
175 text = localDesc;
177 else if (text.size() > 3 && text[0]=='@' && text[1]=='L' && text[2]=='U' && text[3]=='A')
179 string code = text.substr(4, text.size()-4);
180 if (!code.empty())
181 CLuaManager::getInstance().executeLuaScript(code);
182 text = localDesc;
184 if (!text.empty())
186 display->setTextFormatTaged(text);
187 group->setActive(true);
198 // ********************************************************************************************
199 void CInterfaceItemEdition::CItemEditionWindow::update()
201 if(_CurrItemSheet && ((sint32)ItemSheet != _CurrItemSheet->getSheetId()))
203 end();
206 // ********************************************************************************************
207 void CInterfaceItemEdition::CItemEditionWindow::begin()
209 if(_CurrItemSheet && !WindowName.empty())
212 const CItemSheet *pIS = _CurrItemSheet->asItemSheet();
213 if ((pIS != NULL) && ITEMFAMILY::isTextCustomizable(pIS->Family) )
215 CInterfaceManager *pIM = CInterfaceManager::getInstance();
216 // get the dialog stack
217 CGroupContainer* group = dynamic_cast<CGroupContainer*>( CWidgetManager::getInstance()->getElementFromId(WindowName) );
219 CInterfaceGroup* editShort = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_short")) );
220 CGroupEditBox* editBoxShort = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_short")) );
221 CInterfaceGroup* editLarge = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_large")) );
222 CGroupEditBox* editBoxLarge = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_large")) );
223 CViewText* display = dynamic_cast<CViewText*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_display")) );
224 CInterfaceGroup* editButtons = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_buttons")) );
225 CCtrlBaseButton* closeButton = dynamic_cast<CCtrlBaseButton*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_close_button")) );
226 CViewBitmap* background = dynamic_cast<CViewBitmap*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_background")) );
227 if (group && editShort && editBoxShort && editLarge && editBoxLarge && display && editButtons && closeButton && background)
230 const CClientItemInfo &itemInfo = getInventory().getItemInfo( ItemSlotId );
231 if ( IsInEditionMode )
233 // Enable the windows
234 editLarge->setActive(false);
235 editBoxLarge->setActive(false);
236 editShort->setActive(false);
237 editBoxShort->setActive(false);
238 display->setActive(false);
239 editButtons->setActive(true);
240 closeButton->setActive(false);
241 group->setActive(true);
243 editBoxShort->setInputString(std::string());
244 editBoxLarge->setInputString(std::string());
245 display->setTextFormatTaged(std::string());
248 // Finish the display or add the waiter
249 if (getInventory().isItemInfoUpToDate(ItemSlotId))
251 // If we already have item info
252 if ( pIS->Family == ITEMFAMILY::SCROLL)
254 editBoxLarge->setInputString(itemInfo.CustomText.toUtf8()); // TODO: UTF-8 (serial)
255 editLarge->setActive(true);
256 editBoxLarge->setActive(true);
258 // Set the Keyboard focus to the editbox
259 CWidgetManager::getInstance()->setCaptureKeyboard(editBoxLarge);
260 // Select all the text for easier selection
261 editBoxLarge->setSelectionAll();
263 else
266 string customText;
267 if (!itemInfo.CustomText.empty())
269 customText = itemInfo.CustomText.toUtf8();
270 strFindReplace(customText, "%mfc", string());
273 editBoxShort->setInputString(customText);
274 editShort->setActive(true);
275 editBoxShort->setActive(true);
277 // Set the Keyboard focus to the editbox
278 CWidgetManager::getInstance()->setCaptureKeyboard(editBoxShort);
279 // Select all the text for easier selection
280 editBoxShort->setSelectionAll();
283 else
285 // Add the waiter
286 getInventory().addItemInfoWaiter(this);
289 else
291 // Enable the windows
292 editShort->setActive(false);
293 editBoxShort->setActive(false);
294 editLarge->setActive(false);
295 editBoxLarge->setActive(false);
296 display->setActive(true);
297 editButtons->setActive(false);
298 closeButton->setActive(true);
299 group->setActive(false);
301 editBoxShort->setInputString(std::string());
302 editBoxLarge->setInputString(std::string());
303 display->setTextFormatTaged(std::string());
305 // Finish the display or add the waiter
306 if (getInventory().isItemInfoUpToDate(ItemSlotId))
308 const char *localDesc = STRING_MANAGER::CStringManagerClient::getItemLocalizedDescription(pIS->Id);
309 if (itemInfo.CustomText.empty())
310 display->setTextFormatTaged(localDesc);
311 else
313 string text = itemInfo.CustomText.toUtf8();
314 if (text.size() > 3 && text[0]=='@' && text[1]=='W' && text[2]=='E' && text[3]=='B')
316 CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:web_transactions:content:html"));
317 if (pGH)
318 pGH->browse(text.substr(4, text.size()-4).c_str());
319 text = localDesc;
321 else if (text.size() > 3 && text[0]=='@' && text[1]=='L' && text[2]=='U' && text[3]=='A')
323 string code = text.substr(4, text.size()-4);
324 if (!code.empty())
325 CLuaManager::getInstance().executeLuaScript(code);
326 text = localDesc;
328 if (!text.empty())
329 display->setTextFormatTaged(text);
332 else
334 // Add the waiter
335 getInventory().addItemInfoWaiter(this);
342 // ********************************************************************************************
343 void CInterfaceItemEdition::CItemEditionWindow::end()
346 CDBCtrlSheet *pCSItem = _CurrItemSheet;
347 std::string windowName = WindowName;
348 if(pCSItem && !windowName.empty())
350 // remove infos waiter (if not already canceled)
351 getInventory().removeItemInfoWaiter(this);
352 _CurrItemSheet = NULL;
353 WindowName.clear();
355 // hide the dialog
356 CInterfaceManager *pIM = CInterfaceManager::getInstance();
357 // get the dialog stack
358 CInterfaceGroup* group = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(windowName) );
360 CInterfaceGroup* editShort = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_short")) );
361 CGroupEditBox* editBoxShort = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_short")) );
362 CInterfaceGroup* editLarge = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_large")) );
363 CGroupEditBox* editBoxLarge = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_large")) );
364 CViewText* display = dynamic_cast<CViewText*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_display")) );
365 CInterfaceGroup* editButtons = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_buttons")) );
366 CCtrlBaseButton* closeButton = dynamic_cast<CCtrlBaseButton*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_close_button")) );
367 CViewBitmap* background = dynamic_cast<CViewBitmap*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_background")) );
368 if (group && editShort && editBoxShort && editLarge && editBoxLarge && display && editButtons && closeButton && background)
370 // disable the window
371 editBoxShort->setActive(false);
372 editShort->setActive(false);
373 editBoxLarge->setActive(false);
374 editLarge->setActive(false);
375 display->setActive(false);
376 editButtons->setActive(false);
377 closeButton->setActive(false);
379 group->setActive(false);
387 // *******************************************************************************************
388 void CInterfaceItemEdition::CItemEditionWindow::validate()
390 CDBCtrlSheet *pCSItem = _CurrItemSheet;
391 std::string windowName = WindowName;
392 if(pCSItem && !windowName.empty())
395 CInterfaceManager *pIM = CInterfaceManager::getInstance();
396 // get the dialog stack
397 CInterfaceGroup* group = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(windowName) );
399 CInterfaceGroup* editShort = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_short")) );
400 CGroupEditBox* editBoxShort = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_short")) );
401 CInterfaceGroup* editLarge = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_large")) );
402 CGroupEditBox* editBoxLarge = dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_box_large")) );
403 CViewText* display = dynamic_cast<CViewText*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_display")) );
404 CInterfaceGroup* editButtons = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_edit_buttons")) );
405 CCtrlBaseButton* closeButton = dynamic_cast<CCtrlBaseButton*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_close_button")) );
406 CViewBitmap* background = dynamic_cast<CViewBitmap*>( CWidgetManager::getInstance()->getElementFromId(CWidgetManager::getInstance()->getParser()->getDefine("edit_custom_background")) );
407 if (group && editShort && editBoxShort && editLarge && editBoxLarge && display && editButtons && closeButton && background)
409 bool textValid = editShort->getActive();
410 string text = editBoxShort->getInputString();
411 if (!textValid)
413 textValid = editLarge->getActive();
414 text = editBoxLarge->getInputString();
417 if (textValid)
419 CBitMemStream out;
420 const char *msgName = "EVENT:SET_ITEM_CUSTOM_TEXT";
421 if (!GenericMsgHeaderMngr.pushNameToStream(msgName, out))
423 nlwarning ("don't know message name %s", msgName);
425 else
427 uint32 uiInventory = (uint32)pCSItem->getInventoryIndex();
428 out.serial(uiInventory);
429 uint32 uiSlot = (uint32)pCSItem->getIndexInDB();
430 out.serial(uiSlot);
431 ucstring ucText = ucstring::makeFromUtf8(text); // TODO: UTF-8 (serial)
432 out.serial(ucText);
433 NetMngr.push(out);
434 //nlinfo("impulseCallBack : %s %s %d \"%s\" sent", msgName.c_str(), INVENTORIES::toString((INVENTORIES::TInventory)pCSItem->getInventoryIndex()).c_str(), pCSItem->getIndexInDB(), text.toUtf8().c_str());
440 // ***********************************************************************************************************/
441 enum TStackMode {StackModeSwap= 0, StackModeExchange};
444 // Globals.
445 static CDBCtrlSheet *CurrentStackSrc= NULL;
446 static CDBCtrlSheet *CurrentStackDst= NULL;
447 static TStackMode CurrentStackMode;
450 static void validateStackItem(CDBCtrlSheet *src, CDBCtrlSheet *dest, sint32 quantity, TStackMode stackMode);
451 static void checkItemCommand(const CItemSheet *itemSheet);
453 //=====================================================================================================================
454 /** Send a swap item msg to the server
456 static void sendSwapItemMsg(const CDBCtrlSheet *pCSSrc, const CDBCtrlSheet *pCSDst, sint32 quantitySrc)
458 CBitMemStream out;
459 const char *sMsg = "ITEM:SWAP";
460 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
462 // Swap all the Src (quantity= quantitySrc) to dest
463 uint16 srcInvId= (uint16)pCSSrc->getInventoryIndex();
464 uint16 srcSlotId= (uint16)pCSSrc->getIndexInDB();
465 uint16 dstInvId= (uint16)pCSDst->getInventoryIndex();
466 uint16 dstSlotId= (uint16)pCSDst->getIndexInDB();
467 uint16 quantity= (uint16)quantitySrc;
469 out.serial(srcInvId);
470 out.serial(srcSlotId);
471 out.serial(dstInvId);
472 out.serial(dstSlotId);
473 out.serial(quantity);
475 // Special case for guilds that are not on the same counter as the other inventories
476 // The guild counter is global on the server so it can changes without this client
477 uint16 nGuildSessionCounter = 0;
478 if ((srcInvId == (uint16)INVENTORIES::guild) || (dstInvId == (uint16)INVENTORIES::guild))
480 CInterfaceManager *pIM = CInterfaceManager::getInstance();
481 nGuildSessionCounter = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:GUILD:INVENTORY:SESSION")->getValue16();
483 out.serial(nGuildSessionCounter); // always serial to use the fixed-sized msg.xml scheme
485 NetMngr.push(out);
487 CInterfaceManager *pIM = CInterfaceManager::getInstance();
488 pIM->incLocalSyncActionCounter();
489 //nlinfo("impulseCallBack : %s %d %d %d %d %d sent", sMsg.c_str(), srcInvId, srcSlotId, dstInvId, dstSlotId, quantity);
491 else
492 nlwarning(" unknown message name '%s'",sMsg);
495 /** Display the popup to ask item quantity
497 //=====================================================================================================================
498 static void displayQuantityPopup(CCtrlBase *pCaller, CDBCtrlSheet *pCSSrc, CDBCtrlSheet *pCSDst, sint32 availableStack, TStackMode stackMode)
500 CInterfaceManager *pIM = CInterfaceManager::getInstance();
501 // get the dialog stack
502 CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:stack_dialog") );
503 CGroupEditBox *editBox= dynamic_cast<CGroupEditBox*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:stack_dialog:edit:eb") );
504 if(group && editBox)
506 // write all info for the modal
507 //set the selected stack variables
508 CurrentStackSrc= pCSSrc;
509 CurrentStackDst= pCSDst;
510 CurrentStackMode= stackMode;
512 // tmp sheet to copy aspect in the local db
513 CViewBase::TCtorParam params;
514 CDBCtrlSheet destSheet(params);
515 destSheet.setSheet(string("UI:VARIABLES:STACK_SELECTED:DSPSLOT"));
516 pCSSrc->copyAspect(&destSheet);
518 // init the editbox ctrl. init cur default to max
519 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:STACK_SELECTED:CUR_QUANTITY")->setValue32(availableStack);
520 editBox->setInputStringAsInt(availableStack);
522 // enable the modal
523 CWidgetManager::getInstance()->enableModalWindow(pCaller, group);
525 // Set the Keyboard focus to the editbox (after the enableModalWindow())
526 CWidgetManager::getInstance()->setCaptureKeyboard(editBox);
527 // Select all the text for easier selection
528 editBox->setSelectionAll();
532 /** Have a last chance to directly drop stack items if CTRL or SHIFT pressed.
534 //=====================================================================================================================
535 static void openStackItem(CCtrlBase *pCaller, CDBCtrlSheet *pCSSrc, CDBCtrlSheet *pCSDst, sint32 availableStack, TStackMode stackMode)
537 // If the quantity to stack is just 1, then don't open the stack
538 if(availableStack==1)
540 validateStackItem(pCSSrc, pCSDst, 1, stackMode);
542 // Ctrl+Drop means only 1 of the STACK
543 else if(Driver->AsyncListener.isKeyDown(KeyCONTROL) ||
544 Driver->AsyncListener.isKeyDown(KeyLCONTROL) ||
545 Driver->AsyncListener.isKeyDown(KeyRCONTROL) )
547 validateStackItem(pCSSrc, pCSDst, 1, stackMode);
549 // Shift+Drop means all the STACK
550 else if(Driver->AsyncListener.isKeyDown(KeySHIFT) ||
551 Driver->AsyncListener.isKeyDown(KeyLSHIFT) ||
552 Driver->AsyncListener.isKeyDown(KeyRSHIFT) )
554 validateStackItem(pCSSrc, pCSDst, availableStack, stackMode);
556 // Else display the Select popup!
557 else
559 displayQuantityPopup(pCaller, pCSSrc, pCSDst, availableStack, stackMode);
564 //=====================================================================================================================
565 static void sendExchangeAddToServer(uint16 srcSlotIndex, uint16 destSlotIndex, uint16 quantitySrc)
567 CInterfaceManager *pIM= CInterfaceManager::getInstance();
569 CBitMemStream out;
570 const char *sMsg = "EXCHANGE:ADD";
571 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
573 // Swap all the Src (quantity= quantitySrc) to dest
574 out.serial(srcSlotIndex);
575 out.serial(destSlotIndex);
576 out.serial(quantitySrc);
577 NetMngr.push(out);
579 pIM->incLocalSyncActionCounter();
580 //nlinfo("impulseCallBack : %s %d %d %d sent", sMsg.c_str(), srcSlotIndex, destSlotIndex, quantitySrc);
582 else
583 nlwarning(" unknown message name '%s'",sMsg);
586 //=====================================================================================================================
587 /** An item from the exchange window is put back in the inventory.
588 * This put the items back in its start place, and unlock them. There may be several items
589 * This put the destination item in the exchange slot, unless it is the same item than src
591 static void putInventoryItemToExchange(CDBCtrlSheet *src, CDBCtrlSheet *dest)
593 CInterfaceManager *pIM = CInterfaceManager::getInstance();
594 if (!src || !dest) return;
596 // **** Decide if can split stack
597 // remove any selection
598 CDBCtrlSheet::setCurrSelection(NULL);
599 sint32 stackCapacity= src->getStackable();
600 bool canStack= stackCapacity>1;
601 sint32 quantitySrc= src->getNonLockedQuantity();
603 // if the dest is empty and that current quantity is ONE, just exchange
604 if(canStack && quantitySrc<=1)
605 canStack= false;
607 // **** exchange or display dialog for selection
608 // exchange full if can't stack
609 if(!canStack)
611 // Modify LOCAL
612 PlayerTrade.putItemInExchange(src, dest, quantitySrc);
614 // user changed the proposal => reset the local ACCEPTED db
615 NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
617 // send msg to server
618 sendExchangeAddToServer((uint16)src->getIndexInDB(), (uint8)dest->getIndexInDB(), (uint16)quantitySrc);
620 else
622 openStackItem(NULL, src, dest, min(quantitySrc, stackCapacity), StackModeExchange );
626 //=====================================================================================================================
627 // An exchange item is put back in the inventory
628 static void putExchangedItemToInventory(CDBCtrlSheet *exchangeSlot)
630 CInterfaceManager *pIM = CInterfaceManager::getInstance();
631 if (!exchangeSlot) return;
632 PlayerTrade.restoreItem(exchangeSlot);
634 // user changed the proposal => reset the local ACCEPTED db
635 NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
637 // send msg to server
638 CBitMemStream out;
639 const char *sMsg = "EXCHANGE:REMOVE";
640 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
642 // Swap all the Src (quantity= quantitySrc) to dest
643 uint16 slotIndex = (uint16) exchangeSlot->getIndexInDB();
644 out.serial(slotIndex);
645 NetMngr.push(out);
646 pIM->incLocalSyncActionCounter();
647 //nlinfo("impulseCallBack : %s %d sent", sMsg.c_str(), slotIndex);
649 else
650 nlwarning(" unknown message name '%s'",sMsg);
654 // ***************************************************************************
655 static void validateStackItem(CDBCtrlSheet *pCSSrc, CDBCtrlSheet *pCSDst, sint32 val, TStackMode stackMode)
657 // if ok, and if some value to drop
658 if(pCSSrc && pCSDst && val>0)
660 // **** Swap???
661 if(stackMode==StackModeSwap)
663 // special case : add item to exchange slot
664 sint32 stackCapacity= pCSSrc->getStackable();
665 sint32 quantitySrc= pCSSrc->getQuantity();
666 sint32 quantityDst;
667 if (pCSDst->getSheetId())
669 quantityDst = pCSDst->getQuantity();
670 if (pCSDst->getLockValuePtr())
672 quantityDst -= pCSDst->getLockValuePtr()->getValue32();
675 else
677 quantityDst = 0;
681 val= min(val, quantitySrc);
682 val= min(val, stackCapacity-quantityDst);
684 // write to Local database for minimum effective Lag
685 if (pCSSrc->getInventoryIndex() != INVENTORIES::guild)
687 quantitySrc-= val;
688 pCSSrc->setQuantity(quantitySrc);
689 // if the src has no more quantity, disable it.
690 if(quantitySrc==0)
691 pCSSrc->setSheetId(0);
693 if (pCSDst->getInventoryIndex() != INVENTORIES::guild)
695 quantityDst+= val;
696 pCSDst->setQuantity(quantityDst);
697 // the dest get our type (case was an empty slot)
698 pCSDst->setSheetId(pCSSrc->getSheetId());
699 pCSDst->setQuality(pCSSrc->getQuality());
702 // send msg to server
703 if(!ClientCfg.Local)
705 // \todo yoyo TODO_GAMEDEV: TEST NETWORK
706 sendSwapItemMsg(pCSSrc, pCSDst, val);
709 // **** Exchange
710 else
712 CInterfaceManager *pIM= CInterfaceManager::getInstance();
714 // clamp
715 sint32 stackCapacity= pCSSrc->getStackable();
716 sint32 quantitySrc= pCSSrc->getQuantity();
717 val= min(val, quantitySrc);
718 val= min(val, stackCapacity);
719 if(val>0)
721 // Modify LOCAL
722 PlayerTrade.putItemInExchange(pCSSrc, pCSDst, val);
724 // user changed the proposal => reset the local ACCEPTED db
725 NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
727 // send msg to server
728 sendExchangeAddToServer((uint16)pCSSrc->getIndexInDB(), (uint8)pCSDst->getIndexInDB(), (uint16)val);
735 // ***************************************************************************
736 /** Swap an item with another in the inventory.
737 * eg: place in sword in the set, or place an armor in the kit, or swap 2 items in bags
739 class CHandlerSwapItem: public IActionHandler
741 public:
742 virtual void execute (CCtrlBase *pCaller, const string &Params)
744 CInterfaceManager *pIM = CInterfaceManager::getInstance();
745 string src = getParam(Params, "src");
746 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
747 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
748 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
749 if ((pCSSrc == NULL) || (pCSDst == NULL)) return;
751 if (pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item)
752 if (pCSDst->getType() == CCtrlSheetInfo::SheetType_Item)
755 if (pCSDst->getInventoryIndex() == INVENTORIES::exchange)
757 putInventoryItemToExchange(pCSSrc, pCSDst);
758 return;
761 if (pCSSrc->getInventoryIndex() == INVENTORIES::exchange)
763 putExchangedItemToInventory(pCSSrc);
764 return;
767 // Ok, the 2 ctrls are item type. swap or stack them
768 // Don't swap anything if one of them is grayed (LOCKED)
769 if(pCSSrc->getGrayed() || pCSDst->getGrayed())
770 return;
773 // remove any selection
774 CDBCtrlSheet::setCurrSelection(NULL);
775 // \todo yoyo TODO_GAMEDEV: Locked ??? gestion
777 sint32 stackCapacity= pCSSrc->getStackable();
778 bool canStack= stackCapacity>1;
779 sint32 quantitySrc= pCSSrc->getQuantity();
780 sint32 quantityDst= pCSDst->getQuantity();
781 // if the dest is not empty
782 if(canStack && pCSDst->getSheetId()!=0)
784 // must be same sheet, and same quality
785 canStack= canStack && pCSDst->getSheetId()==pCSSrc->getSheetId();
786 canStack= canStack && pCSDst->getQuality()==pCSSrc->getQuality();
787 // the quantity of the dest must not be full
788 if(canStack)
790 // can't drop: full
791 if(quantityDst>=stackCapacity)
792 return;
795 // if the dest is empty and that current quantity is ONE, just swap
796 if(canStack && pCSDst->getSheetId()==0 && quantitySrc<=1)
797 canStack= false;
799 // swap if can't stack
800 if(!canStack)
802 if ((pCSDst->getInventoryIndex() != INVENTORIES::guild) &&
803 (pCSSrc->getInventoryIndex() != INVENTORIES::guild)) // ? why not always skip it now with the new itemSwap?
805 // write to Local database for minimum effective Lag
806 pCSDst->swapSheet(pCSSrc);
809 // send to server
810 sendSwapItemMsg(pCSSrc, pCSDst, quantitySrc);
812 else
814 openStackItem(pCaller, pCSSrc, pCSDst, min(quantitySrc, stackCapacity-quantityDst), StackModeSwap );
819 REGISTER_ACTION_HANDLER( CHandlerSwapItem, "swap_item");
821 // ***************************************************************************
822 /** When an item swap open a "StackDialog" for items with quantities, this is called to validate the item drop
824 class CHandlerStackOk: public IActionHandler
826 public:
827 virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
829 CInterfaceManager *pIM = CInterfaceManager::getInstance();
830 // get the value to drop
831 sint32 val= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:STACK_SELECTED:CUR_QUANTITY")->getValue32();
832 CDBCtrlSheet *pCSSrc = CurrentStackSrc;
833 CDBCtrlSheet *pCSDst = CurrentStackDst;
834 CurrentStackSrc= NULL;
835 CurrentStackDst= NULL;
836 validateStackItem(pCSSrc, pCSDst, val, CurrentStackMode);
839 REGISTER_ACTION_HANDLER( CHandlerStackOk, "stack_item");
841 // ***************************************************************************
842 // called when an item as been selected from a modal to put in exchange window
843 class CPlayerTradePutBagItemToExchange : public IActionHandler
845 public:
846 virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
848 CInterfaceManager *im = CInterfaceManager::getInstance();
849 CDBCtrlSheet *src = dynamic_cast<CDBCtrlSheet *>(pCaller);
850 CDBCtrlSheet *dest = dynamic_cast<CDBCtrlSheet *>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
851 if (src->getSheetId() == 0)
853 putExchangedItemToInventory(dest);
855 else
857 putInventoryItemToExchange(src, dest);
861 REGISTER_ACTION_HANDLER(CPlayerTradePutBagItemToExchange, "put_bag_item_to_exchange");
863 // ***************************************************************************
864 // called when an item is retored to the inventory
865 class CPlayerTradePutExchangeItemtoBag : public IActionHandler
867 public:
868 virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
870 CDBCtrlSheet *src = dynamic_cast<CDBCtrlSheet *>(pCaller);
871 if (src) putExchangedItemToInventory(src);
874 REGISTER_ACTION_HANDLER(CPlayerTradePutExchangeItemtoBag, "put_exchange_item_to_bag");
878 // **********************************************************************************************************
879 /** drag'n'drop: true if the ctrlSheet is an item
881 class CIsItem : public IActionHandler
883 public:
884 virtual void execute (CCtrlBase *pCaller, const string &Params)
886 CInterfaceManager *pIM = CInterfaceManager::getInstance();
887 string src = getParam(Params, "src");
888 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
889 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
890 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
891 if (pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item)
892 if (pCSDst->getType() == CCtrlSheetInfo::SheetType_Item)
894 pCSDst->setCanDrop (true);
898 REGISTER_ACTION_HANDLER (CIsItem, "isitem");
901 // Action handle for drag'n'drop system
902 class CItemToEmptySlotTest : public IActionHandler
904 public:
905 virtual void execute (CCtrlBase *pCaller, const string &Params)
907 CInterfaceManager *pIM = CInterfaceManager::getInstance();
908 string src = getParam(Params, "src");
909 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
910 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
911 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
912 if (pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item)
914 if (pCSDst->getSheetId() == 0) // the destination must be empty
916 pCSDst->setCanDrop (true);
921 REGISTER_ACTION_HANDLER (CItemToEmptySlotTest, "itemtoemptyslottest");
923 // **********************************************************************************************************
924 // Action handle for drag'n'drop system
925 // Test if an item come from the player inventory
926 class CIsPlayerItem : public IActionHandler
928 public:
929 virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
931 CDBCtrlSheet *cs = dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() );
932 if (cs)
934 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
935 if (pCSDst) pCSDst->setCanDrop(cs->getSelectionGroupAsString() == "inventory_selection");
939 REGISTER_ACTION_HANDLER (CIsPlayerItem, "isplayeritem");
942 // **********************************************************************************************************
943 /** drag'n'drop: true if the ctrlSheet is an item of a special slot ("chest", "legs", etc...)
944 * example: Used to kwon if can drop a "chest" on the "chest" Kit.
946 class CIsItemSlot : public IActionHandler
948 public:
949 virtual void execute (CCtrlBase *pCaller, const string &Params)
951 CInterfaceManager *pIM = CInterfaceManager::getInstance();
952 string src = getParam(Params, "src");
953 string strTestEmpty= getParam(Params, "test_empty");
954 bool testEmpty= strTestEmpty=="true";
955 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
956 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
957 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
958 if (!pCSSrc || !pCSDst) return;
959 if (pCSSrc->getInventoryIndex() == INVENTORIES::exchange &&
960 pCSDst->getInventoryIndex() == INVENTORIES::exchange
963 return;
965 if (pCSSrc && pCSSrc->getType() == CCtrlSheetInfo::SheetType_Item)
966 if (pCSDst && pCSDst->getType() == CCtrlSheetInfo::SheetType_Item)
967 if ( !testEmpty || pCSDst->getSheetId() == 0 ) // the destination must be empty if testEmpty
969 if (pCSSrc->getInventoryIndex() == INVENTORIES::exchange)
971 // can always put back to inventory if it is in the right slot
972 if (pCSDst->canDropItem(pCSSrc))
974 pCSDst->setCanDrop ( true );
977 else
979 // Ok if the swap can be done on the 2 slots
980 if( pCSSrc->canDropItem(pCSDst) && pCSDst->canDropItem(pCSSrc) )
981 pCSDst->setCanDrop ( true );
986 REGISTER_ACTION_HANDLER (CIsItemSlot, "isitem_slot");
989 // **********************************************************************************************************
990 // Check if we can exchange the item with a player or a bot
991 bool checkCanExchangeItem(CDBCtrlSheet *pCSSrc)
993 if(!pCSSrc)
994 return false;
996 // Check if item is completely locked
997 if (pCSSrc->getNonLockedQuantity() == 0)
998 return false;
1000 bool bWeared = false;
1001 bool bDropOrSell = true;
1003 // Check if item weared
1004 // --------------------
1005 if (pCSSrc->getSecondIndexInDB()==INVENTORIES::bag)
1007 CInventoryManager *pInv = CInventoryManager::getInstance();
1008 if (pInv->isBagItemWeared(pCSSrc->getIndexInDB()))
1009 bWeared= true;
1012 // Check if item sellable and dropable
1013 // -----------------------------------
1014 const CItemSheet *pIS = pCSSrc->asItemSheet();
1015 if (pIS != NULL)
1017 bDropOrSell = pIS->canExchangeOrGive(PlayerTrade.BotChatGiftContext);
1020 // Locked by owner; cannot trade
1021 if (pCSSrc->getLockedByOwner())
1023 return false;
1026 // Special case if this is an animal ticket
1027 if ((pIS != NULL) && (pIS->Family == ITEMFAMILY::PET_ANIMAL_TICKET))
1029 // If we are not giving something to a bot (so we are exchanging with a player)
1030 if (PlayerTrade.BotChatGiftContext == false)
1031 bDropOrSell = true;
1034 if (!bWeared && bDropOrSell)
1035 return true;
1036 return false;
1039 // **********************************************************************************************************
1040 class CCanDropToExchange : public IActionHandler
1042 virtual void execute (CCtrlBase *pCaller, const string &Params)
1044 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1045 string src = getParam(Params, "src");
1046 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId(src);
1047 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(pElt);
1048 CDBCtrlSheet *pCSDst = dynamic_cast<CDBCtrlSheet*>(pCaller);
1049 if (!pCSSrc || !pCSDst) return;
1051 // Exchange can only be done from bag to exchange inventories
1053 if (pCSSrc->getSecondIndexInDB() == INVENTORIES::bag &&
1054 pCSDst->getSecondIndexInDB() == INVENTORIES::exchange)
1056 if (checkCanExchangeItem(pCSSrc))
1058 pCSDst->setCanDrop ( true );
1063 REGISTER_ACTION_HANDLER (CCanDropToExchange, "can_drop_to_exchange");
1066 // **********************************************************************************************************
1068 /** Clear the selected sheet
1070 class CClearSelectedSheet : public IActionHandler
1072 virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
1074 CDBCtrlSheet::setCurrSelection(NULL);
1077 REGISTER_ACTION_HANDLER (CClearSelectedSheet, "clear_selected_sheet");
1080 //accept exchange
1081 class CHandlerAcceptExchange: public IActionHandler
1083 public:
1084 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1086 sint64 counter;
1087 if (!CInterfaceExpr::evalAsInt(getParam(sParams, "counter"), counter))
1089 nlwarning("<CHandlerAcceptExchange::execute> Can't retrieve counter.");
1090 return;
1092 CBitMemStream out;
1093 if(GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:VALIDATE", out))
1095 uint8 u8counter = (uint8) counter;
1096 out.serial(u8counter);
1097 NetMngr.push(out);
1099 else
1100 nlwarning("<CHandlerAcceptExchange::execute> unknown message name 'EXCHANGE:VALIDATE");
1102 private:
1103 CCDBNodeLeaf* _Counter;
1105 REGISTER_ACTION_HANDLER( CHandlerAcceptExchange, "accept_exchange");
1108 //invalidate exchange
1109 class CHandlerInvalidateExchange: public IActionHandler
1111 public:
1112 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1114 sint64 counter;
1115 if (!CInterfaceExpr::evalAsInt(getParam(sParams, "counter"), counter))
1117 nlwarning("<CHandlerInvalidateExchange::execute> Can't retrieve counter.");
1118 return;
1120 CBitMemStream out;
1121 if(GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:INVALIDATE", out))
1123 NetMngr.push(out);
1125 else
1126 nlwarning("<CHandlerInvalidateExchange::execute> unknown message name 'EXCHANGE:INVALIDATE");
1128 private:
1129 CCDBNodeLeaf* _Counter;
1131 REGISTER_ACTION_HANDLER( CHandlerInvalidateExchange, "invalidate_exchange");
1134 //end exchange
1135 class CHandlerEndExchange: public IActionHandler
1137 public:
1138 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
1140 PlayerTrade.restoreAllItems();
1141 CInterfaceManager *im = CInterfaceManager::getInstance();
1142 NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:BEGUN")->setValue32(0);
1144 if (!ClientCfg.Local)
1146 CBitMemStream out;
1147 if(GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:END", out))
1149 // must increment action counter
1150 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1151 pIM->incLocalSyncActionCounter();
1153 // send the msg
1154 NetMngr.push(out);
1156 else
1157 nlwarning("<CHandlerEndExchange::execute> unknown message name 'EXCHANGE:END");
1161 REGISTER_ACTION_HANDLER( CHandlerEndExchange, "end_exchange");
1165 //validate the selected quantity of seed
1166 class CHandlerValidateSeedSel: public IActionHandler
1168 public:
1169 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1171 sint64 quantity;
1172 if (!CInterfaceExpr::evalAsInt(getParam(sParams, "quantity"), quantity))
1174 nlwarning("<CHandlerValidateSeedSel::execute> Can't retrieve quantity of seeds");
1175 return;
1177 // user changed the proposal => reset the local ACCEPTED db
1178 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1179 NLGUI::CDBManager::getInstance()->getDbProp("LOCAL:EXCHANGE:ACCEPTED")->setValue32(0);
1181 // Send the msg
1182 CBitMemStream out;
1183 if(!GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:SEEDS", out))
1185 nlwarning("CHandlerValidateSeedSel : unknown message EXCHANGE:SEEDS");
1186 return;
1189 out.serial(quantity);
1191 NetMngr.push(out);
1192 // increment counter
1193 pIM->incLocalSyncActionCounter();
1196 REGISTER_ACTION_HANDLER( CHandlerValidateSeedSel, "validate_seed_sel");
1201 //accept exchange invitation
1202 class CHandlerAcceptExchangeInvite: public IActionHandler
1204 public:
1205 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
1207 CBitMemStream out;
1208 if(GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:ACCEPT_INVITATION", out))
1210 NetMngr.push(out);
1211 //nlinfo("impulseCallBack : EXCHANGE:ACCEPT_INVITATION sent");
1213 else
1214 nlwarning("<CHandlerAcceptExchangeInvite::execute> unknown message name 'EXCHANGE:ACCEPT_INVITATION");
1217 REGISTER_ACTION_HANDLER( CHandlerAcceptExchangeInvite, "accept_exchange_invitation");
1219 //decline exchange invitation
1220 class CHandlerDeclineExchangeInvite: public IActionHandler
1222 public:
1223 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
1225 CBitMemStream out;
1226 if(GenericMsgHeaderMngr.pushNameToStream("EXCHANGE:DECLINE_INVITATION", out))
1228 NetMngr.push(out);
1229 //nlinfo("impulseCallBack : EXCHANGE:DECLINE_INVITATION sent");
1231 else
1232 nlwarning("<CHandlerDeclineExchangeInvite::execute> unknown message name 'EXCHANGE:DECLINE_INVITATION");
1235 REGISTER_ACTION_HANDLER( CHandlerDeclineExchangeInvite, "decline_exchange_invitation");
1239 // tool fct to destroy or drop an item
1240 static void dropOrDestroyItem(CDBCtrlSheet *item, CBitMemStream &out, uint16 quantity)
1242 CInventoryManager::getInstance()->dropOrDestroyItem(item, out, quantity);
1245 // destroy an item
1246 class CHandlerDestroyItem : public IActionHandler
1248 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1250 sint64 quantity;
1251 if (!CInterfaceExpr::evalAsInt(getParam(sParams, "quantity"), quantity))
1253 nlwarning("<CHandlerDestroyItem::execute> Can't retrieve quantity");
1254 return;
1256 // get the calling item
1257 CDBCtrlSheet *item = CDBCtrlSheet::getCurrSelSheet();
1258 if (!item)
1260 nlwarning("<CHandlerDestroyItem::execute> no caller sheet found");
1261 return;
1264 // Don't destroy locked items
1265 if (item->getLockedByOwner())
1267 return;
1270 // if the item is currently selected, removes the selection
1271 if (item == CDBCtrlSheet::getCurrSelection())
1273 CDBCtrlSheet::setCurrSelection(NULL);
1274 // old bot chat code
1275 /*CBotChatUI::removeItemHighlight();
1276 CBotChatUI::removeFocusFromItemQuantityEditBox();*/
1278 if (!ClientCfg.Local)
1281 CBitMemStream out;
1282 if(!GenericMsgHeaderMngr.pushNameToStream( "ITEM:DESTROY", out))
1284 nlwarning("<CHandlerDestroyItem::execute> unknown message name 'ITEM:DESTROY'");
1285 return;
1287 dropOrDestroyItem(item, out, (uint16) quantity);
1289 else
1291 item->setSheetId(0);
1295 REGISTER_ACTION_HANDLER( CHandlerDestroyItem, "destroy_item");
1298 // drop an item
1299 class CHandlerDropItem : public IActionHandler
1301 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1303 sint64 quantity = 1;
1304 string sQuantity = getParam(sParams, "quantity");
1305 if (!sQuantity.empty())
1306 if (!CInterfaceExpr::evalAsInt(sQuantity, quantity))
1308 nlwarning("<CHandlerDropItem::execute> Can't retrieve quantity");
1309 quantity = 1;
1311 // get the calling item
1312 CDBCtrlSheet *item = CDBCtrlSheet::getCurrSelSheet();
1313 if (!item)
1315 nlwarning("<CHandlerDestroyItem::execute> no caller sheet found");
1316 return;
1319 CBitMemStream out;
1320 if(!GenericMsgHeaderMngr.pushNameToStream( "ITEM:DROP", out))
1322 nlwarning("<CHandlerDropItem::execute> unknown message name 'ITEM:DROP'");
1323 return;
1325 dropOrDestroyItem(item, out, (uint16)quantity);
1328 REGISTER_ACTION_HANDLER( CHandlerDropItem, "drop_item");
1330 // **********************************************************************************************************
1332 class CHandlerActiveSheath : public IActionHandler
1334 void execute (CCtrlBase *pCaller, const std::string &sParams)
1336 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1338 // Get the user interface value.
1339 uint8 activeSheath = (uint8)NLGUI::CDBManager::getInstance()->getDbProp( CWidgetManager::getInstance()->getParser()->getDefine("ui_set_active") )->getValue32();
1341 // Write to the Local Database.
1342 NLGUI::CDBManager::getInstance()->getDbProp( "LOCAL:INVENTORY:ACTIVE_SHEATH" )->setValue32(activeSheath);
1344 // Send to server
1345 if(!ClientCfg.Local)
1347 CBitMemStream out;
1348 if(!GenericMsgHeaderMngr.pushNameToStream( "ITEM:ACTIVATE_SHEATH", out) )
1350 nlwarning("<CHandlerServerActiveSheath::execute> unknown message name 'ITEM:ACTIVATE_SHEATH'");
1351 return;
1353 nlinfo("<CHandlerActiveSheath> send %d",activeSheath);
1354 out.serial( activeSheath );
1355 NetMngr.push(out);
1356 CMacroCmdManager::getInstance()->incActionId();
1357 // Yoyo: must increment the InterfaceCounter.
1358 pIM->incLocalSyncActionCounter();
1362 REGISTER_ACTION_HANDLER( CHandlerActiveSheath, "active_sheath" );
1364 // **********************************************************************************************************
1366 class CHandlerReceiveActiveSheath : public IActionHandler
1368 void execute (CCtrlBase *pCaller, const std::string &sParams)
1370 // NB: the System does not recurs between active_sheath and receive_active_sheath since
1371 // at a time, the 2 values 'ui_set_active' and LOCAL:INVENTORY:ACTIVE_SHEATH
1372 // will be the same (an observer is called only if the value change)
1374 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1376 // Get the user interface value.
1377 uint8 activeSheath = (uint8)NLGUI::CDBManager::getInstance()->getDbProp( "LOCAL:INVENTORY:ACTIVE_SHEATH" )->getValue32();
1379 // Write to the Local Database.
1380 NLGUI::CDBManager::getInstance()->getDbProp( CWidgetManager::getInstance()->getParser()->getDefine("ui_set_active") )->setValue32(activeSheath);
1383 REGISTER_ACTION_HANDLER( CHandlerReceiveActiveSheath, "receive_active_sheath" );
1385 // **********************************************************************************************************
1386 class CHandlerEndHarvest : public IActionHandler
1388 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1390 CBitMemStream out;
1391 if( sParams == string("loot") )
1393 if (!GenericMsgHeaderMngr.pushNameToStream( "ITEM:PICK_UP_CLOSE", out ) )
1395 nlwarning("<CHandlerEndHarvest::execute> unknown message name 'PICK_UP_CLOSE'");
1396 return;
1399 else
1401 if (!GenericMsgHeaderMngr.pushNameToStream( "ITEM:HARVEST_CLOSE", out ) )
1403 nlwarning("<CHandlerEndHarvest::execute> unknown message name 'ITEM:HARVEST_CLOSE'");
1404 return;
1407 NetMngr.push(out);
1410 REGISTER_ACTION_HANDLER( CHandlerEndHarvest, "end_harvest" );
1412 // **********************************************************************************************************
1413 class CHandlerHarvestItem : public IActionHandler
1415 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
1417 CBitMemStream out;
1419 if (!GenericMsgHeaderMngr.pushNameToStream( "ITEM:HARVEST", out ) )
1421 nlwarning("<CHandlerEndHarvest::execute> unknown message name 'PICK_UP_CLOSE'");
1422 return;
1424 CDBCtrlSheet *sheet = dynamic_cast<CDBCtrlSheet *>(pCaller);
1425 if (!sheet)
1427 nlwarning("Can't get sheet or bad type.");
1428 return;
1430 IListSheetBase *sheetList = sheet->getListSheetParent();
1431 if (!sheetList)
1433 nlwarning("Can't get sheet list or bad type.");
1434 return;
1436 sint sheetIndex = sheetList->getIndexOf(sheet);
1437 if (sheetIndex == -1)
1439 nlwarning("Can't retrieve sheet index");
1440 return;
1442 uint16 slot = (uint16) sheetIndex;
1443 uint16 quantity = (uint16) sheet->getQuantity();
1444 out.serial(slot);
1445 out.serial(quantity);
1446 NetMngr.push(out);
1449 REGISTER_ACTION_HANDLER( CHandlerHarvestItem, "harvest_item" );
1451 // **********************************************************************************************************
1452 void getCtrlSheets(CInterfaceGroup *pIG, vector<CDBCtrlSheet*> &res)
1454 uint i;
1455 const vector<CInterfaceGroup*> child = pIG->getGroups();
1456 for (i = 0; i < child.size(); ++i)
1457 if (child[i]->getActive())
1458 getCtrlSheets (child[i], res);
1460 const vector<CCtrlBase*> &rCBs = pIG->getControls();
1461 for (i = 0; i < rCBs.size(); ++i)
1463 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(rCBs[i]);
1464 if (pCS != NULL)
1465 res.push_back(pCS);
1469 // MOVE AN ITEM
1470 // **********************************************************************************************************
1471 class CHandlerMoveItem : public IActionHandler
1473 void execute (CCtrlBase *pCaller, const std::string &sParams)
1475 // get the calling item
1476 CDBCtrlSheet *item = CDBCtrlSheet::getCurrSelSheet();
1477 if (item == NULL)
1479 item = dynamic_cast<CDBCtrlSheet*>(pCaller);
1480 if (item == NULL)
1482 nlwarning("<CHandlerMoveItem::execute> no caller sheet found");
1483 return;
1486 if (item->getGrayed()) return;
1488 // Check for a place
1490 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1491 string sDest = getParam(sParams, "to");
1492 // Test With List of Items.
1493 if (sDest == "lists")
1495 uint nListIt = 0, nNbList = 1024;
1496 string sNbList = getParam(sParams, "nblist");
1497 if (!sNbList.empty())
1499 CInterfaceExprValue res;
1500 if (!CInterfaceExpr::eval(sNbList,res))
1501 return;
1502 nNbList = (uint)res.getInteger();
1505 // Test All Lists
1506 if (nNbList > 0)
1508 string sListId = getParam(sParams, "listsheet"+toString(nListIt));
1509 while (!sListId.empty())
1511 IListSheetBase *pLS = dynamic_cast<IListSheetBase*>(CWidgetManager::getInstance()->getElementFromId(sListId));
1512 if (pLS == NULL) return;
1513 // search an empty slot where to put
1514 sint32 nbelt = pLS->getNbSheet();
1515 for (sint32 i = 0; i < nbelt; ++i)
1517 if (pLS->getSheet(i)->getSheetId() == 0)
1519 // Send swap_item
1520 CAHManager::getInstance()->runActionHandler("swap_item", pLS->getSheet(i), "src="+toString(pCaller->getId()));
1521 return;
1524 // ok try next list
1525 nListIt++;
1526 if (nListIt >= nNbList)
1528 // Display a Warning Message because no more slot in inventory
1529 pIM->displaySystemInfo(CI18N::get("uiMoveToNoMoreSlot"), "CHK");
1530 return;
1532 sListId = getParam(sParams, "listsheet"+toString(nListIt));
1536 // Test With Group of Items. YOYO: TODO: test if works
1537 /*else if (sDest == "groups")
1539 uint nGrpIt = 0, nNbGrp = 1024, nGrpBeg = 0;
1540 string sNbGrp = getParam(sParams, "nbgroup");
1541 string sGrpBeg = getParam(sParams, "groupbegin");
1543 if (!sNbGrp.empty())
1545 CInterfaceExprValue res;
1546 if (!CInterfaceExpr::eval(sNbGrp, res))
1548 nlwarning("cannot evaluate %s",sNbGrp.c_str());
1549 return;
1551 nNbGrp = (uint)res.getInteger();
1554 if (!sGrpBeg.empty())
1556 CInterfaceExprValue res;
1557 if (!CInterfaceExpr::eval(sGrpBeg, res))
1559 nlwarning("cannot evaluate %s",sGrpBeg.c_str());
1560 return;
1562 nGrpBeg = (uint)res.getInteger();
1565 nGrpIt = nGrpBeg;
1566 string sGrpId = getParam(sParams, "groupsheet"+toString(nGrpIt));
1567 // Begin by trying to put the item in an empty slot
1568 if (nNbGrp > 0)
1569 while (!sGrpId.empty())
1571 uint i;
1572 CInterfaceGroup *pIG = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(sGrpId));
1573 if (pIG != NULL)
1575 // Get all the sheets of the group
1576 vector<CDBCtrlSheet*> vDBCS;
1577 getCtrlSheets (pIG, vDBCS);
1578 for (i = 0; i < vDBCS.size(); ++i)
1580 CDBCtrlSheet *pCS = vDBCS[i];
1581 if ((pCS != NULL) && (pCS->getType() == CCtrlSheetInfo::SheetType_Item) &&
1582 (pCS->getSheetId() == 0) && pCS->canDropItem(item) && (!pCS->getGrayed()))
1584 // Send swap_item
1585 CAHManager::getInstance()->runActionHandler("swap_item", pCS, "src="+toString(pCaller->getId()));
1586 return;
1590 // Next Group
1591 nGrpIt++;
1592 if (nGrpIt == nNbGrp) nGrpIt = 0;
1593 if (nGrpIt == nGrpBeg) break;
1594 sGrpId = getParam(sParams, "groupsheet"+toString(nGrpIt));
1597 // If there was no empty slot try to swap item from an existing slot
1598 nGrpIt = nGrpBeg;
1599 sGrpId = getParam(sParams, "groupsheet"+toString(nGrpIt));
1601 if (nNbGrp > 0)
1602 while (!sGrpId.empty())
1604 uint i;
1605 CInterfaceGroup *pIG = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(sGrpId));
1606 if (pIG != NULL)
1608 // Get all the sheets of the group
1609 vector<CDBCtrlSheet*> vDBCS;
1610 getCtrlSheets (pIG, vDBCS);
1611 for (i = 0; i < vDBCS.size(); ++i)
1613 CDBCtrlSheet *pCS = vDBCS[i];
1614 if ((pCS != NULL) && (pCS->getType() == CCtrlSheetInfo::SheetType_Item))
1616 if ((pCS->canDropItem(item)) && (!pCS->getGrayed()))
1618 // Send swap_item
1619 CAHManager::getInstance()->runActionHandler("swap_item", pCS, "src="+toString(pCaller->getId()));
1620 return;
1625 // Next Group
1626 nGrpIt++;
1627 if (nGrpIt == nNbGrp) nGrpIt = 0;
1628 if (nGrpIt == nGrpBeg) break;
1629 sGrpId = getParam(sParams, "groupsheet"+toString(nGrpIt));
1635 REGISTER_ACTION_HANDLER( CHandlerMoveItem, "move_item" );
1638 // DragNDrop AN ITEM
1639 // **********************************************************************************************************
1640 class CHandlerDragNDrop : public IActionHandler
1642 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
1644 string sSrc = getParam(sParams,"src");
1645 string sDst = getParam(sParams,"dst");
1646 string sAH = getParam(sParams,"ah");
1647 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1648 CDBCtrlSheet *pCSsrc = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getElementFromId(sSrc));
1649 CDBCtrlSheet *pCSdst = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getElementFromId(sDst));
1650 if ((pCSdst == NULL) || (pCSsrc == NULL) || sAH.empty()) return;
1651 CAHManager::getInstance()->runActionHandler(sAH, pCSdst, "src="+pCSsrc->getId());
1654 REGISTER_ACTION_HANDLER( CHandlerDragNDrop, "drag_n_drop" );
1657 // **********************************************************************************************************
1658 static void sendToServerEnchantMessage(uint8 invent, uint16 slot)
1660 CBitMemStream out;
1661 const char *sMsg = "ITEM:ENCHANT";
1663 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
1665 out.serial( invent );
1666 out.serial( slot );
1667 NetMngr.push(out);
1669 else
1670 nlinfo("unknown message %s", sMsg);
1673 // **********************************************************************************************************
1674 class CHandlerItemCristalEnchant : public IActionHandler
1676 void execute (CCtrlBase *pCaller, const std::string &sParams)
1678 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1679 CAHManager::getInstance()->runActionHandler("item_cristal_reload", pCaller, sParams);
1682 REGISTER_ACTION_HANDLER( CHandlerItemCristalEnchant, "item_cristal_enchant" );
1684 // **********************************************************************************************************
1685 class CHandlerItemCristalReload : public IActionHandler
1687 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
1689 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1690 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
1691 if (pCS == NULL) return;
1693 const CItemSheet *pIS = pCS->asItemSheet();
1694 if (pIS && pIS->Scroll.Label.empty())
1695 checkItemCommand(pIS);
1697 sendToServerEnchantMessage((uint8)pCS->getInventoryIndex(), (uint16)pCS->getIndexInDB());
1700 REGISTER_ACTION_HANDLER( CHandlerItemCristalReload, "item_cristal_reload" );
1702 // **********************************************************************************************************
1703 class CItemMenuInBagInfoWaiter
1704 : public IItemInfoWaiter
1706 public:
1707 // The item used to open this window
1708 CDBCtrlSheet* CtrlSheet;
1709 public:
1710 void infoValidated(CDBCtrlSheet* CtrlSheet);
1711 virtual void infoReceived();
1713 static CItemMenuInBagInfoWaiter ItemMenuInBagUpdater;
1715 void CItemMenuInBagInfoWaiter::infoReceived()
1717 getInventory().removeItemInfoWaiter(&ItemMenuInBagUpdater);
1718 infoValidated(CtrlSheet);
1722 void CItemMenuInBagInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet)
1724 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1726 // get the dialog stack
1727 CInterfaceGroup* pMenu = dynamic_cast<CInterfaceGroup*>( CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag") );
1728 if(!pMenu) return;
1730 const CItemSheet *pIS = ctrlSheet->asItemSheet();
1731 CViewTextMenu *pItemTextEdition = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_text_edition"));
1732 if (pIS != NULL && pItemTextEdition && ITEMFAMILY::isTextCustomizable(pIS->Family))
1734 CClientItemInfo const& itemInfo = getInventory().getItemInfo(getInventory().getItemSlotId(ctrlSheet) );
1736 // get the CreatorTextID
1737 bool isCraftedByUserEntity = false;
1738 string creatorNameString;
1739 if( STRING_MANAGER::CStringManagerClient::instance()->getString ( itemInfo.CreatorName, creatorNameString) )
1741 std::string userNameString = UserEntity->getEntityName() + PlayerSelectedHomeShardNameWithParenthesis;
1742 if (NLMISC::compareCaseInsensitive(userNameString, creatorNameString) == 0)
1743 isCraftedByUserEntity = true;
1746 pItemTextEdition->setActive(isCraftedByUserEntity);
1751 // ***************************************************************************
1753 class CHandlerItemMenuCheck : public IActionHandler
1755 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
1757 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1758 uint i;
1760 // Get the ctrl sheet that launched this menu
1761 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
1762 if (pCS == NULL) return;
1763 INVENTORIES::TInventory invId= (INVENTORIES::TInventory)pCS->getInventoryIndex();
1765 // Get the menu launched
1766 CInterfaceGroup *pMenu= dynamic_cast<CInterfaceGroup*>(pCaller);
1767 if(!pMenu) return;
1769 // Get all Text entries
1770 CViewTextMenu *pEquip = dynamic_cast<CViewTextMenu*>(pMenu->getView("equip"));
1771 CViewTextMenu *pCrisEnchant = dynamic_cast<CViewTextMenu*>(pMenu->getView("cris_enchant"));
1772 CViewTextMenu *pCrisReload = dynamic_cast<CViewTextMenu*>(pMenu->getView("cris_reload"));
1773 CViewTextMenu *pTeleportUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("teleport_use"));
1774 CViewTextMenu *pItemConsume = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_consume"));
1775 CViewTextMenu *pItemExecute = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_execute"));
1776 CViewTextMenu *pXpCatalyserUse = dynamic_cast<CViewTextMenu*>(pMenu->getView("xp_catalyser_use"));
1777 CViewTextMenu *pDrop = dynamic_cast<CViewTextMenu*>(pMenu->getView("drop"));
1778 CViewTextMenu *pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy"));
1779 CViewTextMenu *pLockUnlock = dynamic_cast<CViewTextMenu*>(pMenu->getView("lockunlock"));
1780 CViewTextMenu *pMoveSubMenu = dynamic_cast<CViewTextMenu*>(pMenu->getView("move"));
1781 CViewTextMenu *pMoveToBag = dynamic_cast<CViewTextMenu*>(pMenu->getView("bag"));
1782 CViewTextMenu *pMoveToGuild = dynamic_cast<CViewTextMenu*>(pMenu->getView("guild"));
1783 CViewTextMenu *pMoveToRoom = dynamic_cast<CViewTextMenu*>(pMenu->getView("room"));
1784 CViewTextMenu *pMoveToPa[MAX_INVENTORY_ANIMAL];
1786 bool bIsLockedByOwner = pCS->getLockedByOwner();
1788 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
1790 pMoveToPa[i]= dynamic_cast<CViewTextMenu*>(pMenu->getView(toString("pa%d", i)));
1792 CViewTextMenu *pItemInfos = dynamic_cast<CViewTextMenu*>(pMenu->getView("infos"));
1793 CViewTextMenu *pItemTextDisplay = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_text_display"));
1794 CViewTextMenu *pItemTextEdition = dynamic_cast<CViewTextMenu*>(pMenu->getView("item_text_edition"));
1797 // **** Active Entries
1798 // Active Enchant / Reload for a subset of items
1799 if(pCrisEnchant) pCrisEnchant->setActive(false);
1800 if(pCrisReload) pCrisReload->setActive(false);
1801 if(pTeleportUse) pTeleportUse->setActive(false);
1802 if(pItemConsume) pItemConsume->setActive(false);
1803 if(pItemExecute) pItemExecute->setActive(false);
1804 if(pXpCatalyserUse) pXpCatalyserUse->setActive(false);
1805 if(pItemTextDisplay) pItemTextDisplay->setActive(false);
1806 if(pItemTextEdition) pItemTextEdition->setActive(false);
1808 if(pLockUnlock) pLockUnlock->setActive(true);
1810 const CItemSheet *pIS = pCS->asItemSheet();
1811 if (invId != INVENTORIES::guild)
1812 if (pIS != NULL)
1814 if (pCrisEnchant && pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL && !bIsLockedByOwner)
1815 pCrisEnchant->setActive(true);
1816 if (pCrisReload && pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE && !bIsLockedByOwner)
1817 pCrisReload->setActive(true);
1818 // teleport can be used only from bag (NB: should not exist in mektoub....)
1819 if (pTeleportUse && pIS->Family == ITEMFAMILY::TELEPORT && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner)
1821 pTeleportUse->setActive(true);
1823 if (pItemConsume && pIS->IsConsumable == true && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner)
1825 pItemConsume->setActive(true);
1827 if (pXpCatalyserUse && pIS->Family == ITEMFAMILY::XP_CATALYSER && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner)
1829 pXpCatalyserUse->setActive(true);
1831 if (pItemTextEdition && ITEMFAMILY::isTextCustomizable(pIS->Family))
1833 if (pCS->getInventoryIndex()==INVENTORIES::bag)
1835 bool isTextEditionActive = false;
1836 static const string itemTextEditionPriv = ":DEV:SGM:GM:EM:";
1837 if (!UserPrivileges.empty() && itemTextEditionPriv.find(UserPrivileges)!=std::string::npos)
1839 isTextEditionActive = true;
1841 else
1843 // Finish setting the isTextEditionActive boolean or add the waiter
1844 if (getInventory().isItemInfoUpToDate(getInventory().getItemSlotId(pCS)))
1846 // get the CreatorTextID
1847 string creatorNameString;
1848 if( STRING_MANAGER::CStringManagerClient::instance()->getString ( getInventory().getItemInfo(getInventory().getItemSlotId(pCS)).CreatorName, creatorNameString) )
1850 string userNameString = UserEntity->getEntityName() + PlayerSelectedHomeShardNameWithParenthesis;
1851 if (NLMISC::compareCaseInsensitive(userNameString, creatorNameString) == 0)
1852 isTextEditionActive = true;
1855 else
1857 // Prepare the waiter
1858 ItemMenuInBagUpdater.ItemSheet= pCS->getSheetId();
1859 ItemMenuInBagUpdater.ItemSlotId= getInventory().getItemSlotId(pCS);
1860 ItemMenuInBagUpdater.CtrlSheet = pCS;
1861 // Add the waiter
1862 getInventory().addItemInfoWaiter(&ItemMenuInBagUpdater);
1865 pItemTextEdition->setActive(isTextEditionActive);
1867 pItemInfos->setActive(true);
1869 if (pItemTextDisplay && pIS->Family == ITEMFAMILY::SCROLL)
1871 if (pCS->getInventoryIndex()==INVENTORIES::bag)
1872 pItemTextDisplay->setActive(true);
1873 pItemInfos->setActive(false);
1875 else
1877 pItemInfos->setActive(true);
1879 // item has a label?
1880 if (!pIS->Scroll.Label.empty())
1882 CGroupMenu *menu = dynamic_cast<CGroupMenu *>(
1883 CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag")
1885 // add the label to default menu
1886 if (!pIS->Scroll.LuaCommand.empty() || !pIS->Scroll.WebCommand.empty())
1887 menu->setActionHandler(4, menu->getActionHandler(4));
1888 else
1890 // replace default menu and redirect action handler
1891 if (pCrisEnchant && pCrisEnchant->getActive())
1893 pCrisEnchant->setActive(false);
1894 menu->setActionHandler(4, menu->getActionHandler(0));
1896 if (pCrisReload && pCrisReload->getActive())
1898 pCrisReload->setActive(false);
1899 menu->setActionHandler(4, menu->getActionHandler(1));
1901 if (pTeleportUse && pTeleportUse->getActive())
1903 pTeleportUse->setActive(false);
1904 menu->setActionHandler(4, menu->getActionHandler(2));
1906 if (pItemConsume && pItemConsume->getActive())
1908 pItemConsume->setActive(false);
1909 menu->setActionHandler(4, menu->getActionHandler(3));
1911 if (pXpCatalyserUse && pXpCatalyserUse->getActive())
1913 pXpCatalyserUse->setActive(false);
1914 menu->setActionHandler(4, menu->getActionHandler(5));
1916 if (pItemTextDisplay && pItemTextDisplay->getActive())
1918 pItemTextDisplay->setActive(false);
1919 menu->setActionHandler(4, menu->getActionHandler(6));
1920 menu->setActionHandlerParam(4, menu->getActionHandlerParam(6));
1923 if (!bIsLockedByOwner)
1925 if (pCS->getInventoryIndex() == INVENTORIES::bag)
1926 pItemExecute->setActive(true);
1927 // enchant and reload can be used from anywhere
1928 if (pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL || pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE)
1929 pItemExecute->setActive(true);
1931 pItemExecute->setText(CI18N::get(pIS->Scroll.Label));
1936 CInventoryManager &invMngr= getInventory();
1938 // If the item is an animal representation or rpjob item
1939 if (pIS!=NULL && ((pIS->Family == ITEMFAMILY::PET_ANIMAL_TICKET) || (pIS->Id.toString().substr(0, 6) == "rpjob_")))
1941 // cannot move to other animals! :)
1942 if(pMoveToBag) pMoveToBag->setActive(false);
1943 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
1944 if(pMoveToPa[i]) pMoveToPa[i]->setActive(false);
1946 // additionnaly, cannot drop/destroy/lock an animal item.
1947 if(pDrop) pDrop->setActive(false);
1948 if(pDestroy) pDestroy->setActive(false);
1949 if(pLockUnlock) pLockUnlock->setActive(false);
1951 else
1953 // Disable Text entries not supported by this menu (eg: if I am the Bag, i cannot drop to myself!)
1954 // Also Disable Text entries if the inventory is not present
1955 if(pMoveToBag)
1956 pMoveToBag->setActive( invId!=INVENTORIES::bag &&
1957 invMngr.isInventoryPresent(INVENTORIES::bag) &&
1958 (invId!=INVENTORIES::guild || invMngr.isInventoryPresent(INVENTORIES::guild)) );
1960 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
1962 if (pMoveToPa[i])
1963 pMoveToPa[i]->setActive(invId!=INVENTORIES::guild &&
1964 (uint)invId!=INVENTORIES::pet_animal+i &&
1965 invMngr.isInventoryPresent((INVENTORIES::TInventory)(INVENTORIES::pet_animal+i)) );
1968 if (pMoveToGuild)
1969 pMoveToGuild->setActive(invId==INVENTORIES::bag && invMngr.isInventoryPresent(INVENTORIES::guild));
1971 if (pMoveToRoom)
1972 pMoveToRoom->setActive(invId==INVENTORIES::bag && invMngr.isInventoryPresent(INVENTORIES::player_room));
1974 // std case: can drop / destroy
1975 if(pDrop) pDrop->setActive(invId!=INVENTORIES::guild);
1976 if(pDestroy) pDestroy->setActive(invId!=INVENTORIES::guild);
1977 if(pLockUnlock) pLockUnlock->setActive(invId!=INVENTORIES::guild);
1980 // hide the move entry completely?
1981 bool someMovePossible= false;
1982 if(pMoveSubMenu)
1984 if(pMoveToBag) someMovePossible= someMovePossible || pMoveToBag->getActive();
1985 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
1987 if(pMoveToPa[i]) someMovePossible= someMovePossible || pMoveToPa[i]->getActive();
1989 if(pMoveToGuild) someMovePossible= someMovePossible || pMoveToGuild->getActive();
1990 if(pMoveToRoom) someMovePossible= someMovePossible || pMoveToRoom->getActive();
1991 pMoveSubMenu->setActive(someMovePossible);
1994 // Equip
1995 if (pEquip != NULL)
1997 // active for some of item categories
1998 bool valid= (invId==INVENTORIES::bag) && pIS && (
1999 pIS->Family==ITEMFAMILY::ARMOR ||
2000 pIS->Family==ITEMFAMILY::MELEE_WEAPON ||
2001 pIS->Family==ITEMFAMILY::RANGE_WEAPON ||
2002 pIS->Family==ITEMFAMILY::AMMO ||
2003 pIS->Family==ITEMFAMILY::SHIELD ||
2004 pIS->Family==ITEMFAMILY::CRAFTING_TOOL ||
2005 pIS->Family==ITEMFAMILY::HARVEST_TOOL ||
2006 pIS->Family==ITEMFAMILY::TAMING_TOOL ||
2007 pIS->Family==ITEMFAMILY::TRAINING_TOOL ||
2008 pIS->Family==ITEMFAMILY::JEWELRY ||
2009 pIS->Family==ITEMFAMILY::HANDLED_ITEM);
2010 pEquip->setActive(valid);
2012 /* gray if crafting window is opened (cannot equip another tool while crafting),
2013 and the item is a HAND item
2015 if(valid)
2017 pEquip->setGrayed(
2018 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:ISACTIVE:PHRASE_FABER")->getValueBool() &&
2019 pIS->Family!=ITEMFAMILY::ARMOR &&
2020 pIS->Family!=ITEMFAMILY::JEWELRY
2025 //Item Text Edition
2026 if (pItemTextEdition != NULL && pItemTextDisplay != NULL)
2028 pItemTextEdition->setGrayed(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:ISACTIVE:PHRASE_EDIT_CUSTOM")->getValueBool());
2029 pItemTextDisplay->setGrayed(NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:ISACTIVE:PHRASE_EDIT_CUSTOM")->getValueBool());
2032 if (pCS->getGrayed())
2034 if (pEquip) pEquip->setActive(false);
2035 if (pDestroy) pDestroy->setActive(false);
2036 if (pLockUnlock) pLockUnlock->setActive(false);
2037 if (pMoveSubMenu) pMoveSubMenu->setActive(false);
2040 if (bIsLockedByOwner)
2042 if (pLockUnlock) pLockUnlock->setHardText("uimUnlockItem");
2043 // Cannot drop/destroy if locked by owner
2044 if (pDrop) pDrop->setActive(false);
2045 if (pDestroy) pDestroy->setActive(false);
2047 else
2049 if (pLockUnlock) pLockUnlock->setHardText("uimLockItem");
2052 // Only show lock menu item if inventory contains the info
2053 if (pLockUnlock) pLockUnlock->setActive(pCS->canOwnerLock());
2056 // **** Gray Entries
2057 // If ourselves are not available, then gray all
2058 if(!invMngr.isInventoryAvailable(invId))
2060 if(pCrisEnchant) pCrisEnchant->setGrayed(true);
2061 if(pCrisReload) pCrisReload->setGrayed(true);
2062 if(pTeleportUse) pTeleportUse->setGrayed(true);
2063 if(pItemConsume) pItemConsume->setGrayed(true);
2064 if(pItemExecute) pItemExecute->setGrayed(true);
2065 if(pXpCatalyserUse) pXpCatalyserUse->setGrayed(true);
2066 if(pDrop) pDrop->setGrayed(true);
2067 if(pDestroy) pDestroy->setGrayed(true);
2068 if(pLockUnlock) pLockUnlock->setGrayed(true);
2069 if(pMoveSubMenu) pMoveSubMenu->setGrayed(true);
2070 if(pMoveToBag) pMoveToBag->setGrayed(true);
2071 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
2073 if(pMoveToPa[i]) pMoveToPa[i]->setGrayed(true);
2076 // Gray Text entries according to Availables Destinations
2077 else
2079 // ungray basics
2080 if(pCrisEnchant) pCrisEnchant->setGrayed(false);
2081 if(pCrisReload) pCrisReload->setGrayed(false);
2082 if(pTeleportUse) pTeleportUse->setGrayed(false);
2083 if(pItemConsume) pItemConsume->setGrayed(false);
2084 if(pItemExecute) pItemExecute->setGrayed(false);
2085 if(pXpCatalyserUse) pXpCatalyserUse->setGrayed(false);
2086 if(pDrop) pDrop->setGrayed(false);
2087 if(pDestroy) pDestroy->setGrayed(false);
2088 if(pLockUnlock) pLockUnlock->setGrayed(false);
2089 if(pMoveSubMenu) pMoveSubMenu->setGrayed(false);
2091 // check each inventory dest if available
2092 if(pMoveToBag) pMoveToBag->setGrayed(!invMngr.isInventoryAvailable(INVENTORIES::bag));
2093 for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
2095 if(pMoveToPa[i]) pMoveToPa[i]->setGrayed(!invMngr.isInventoryAvailable(
2096 (INVENTORIES::TInventory)(INVENTORIES::pet_animal+i)));
2100 //Item GROUP logic
2101 CGroupMenu *pGroupRootMenu = dynamic_cast<CGroupMenu*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:item_menu_in_bag:item_group_menu"));
2102 if(pGroupRootMenu)
2104 CGroupSubMenu *pGroupMenu = pGroupRootMenu->getRootMenu();
2105 std::vector<std::string> groupNames = CItemGroupManager::getInstance()->getGroupNames(pCS);
2106 CViewText *pGroup = dynamic_cast<CViewText*>(pMenu->getView("item_group"));
2107 //First, hide/show the menu if pertinent (we need to hide the action due to it beeing a submenu)
2108 if(pGroup)
2110 if(groupNames.empty())
2112 pGroup->setActive(false);
2114 else
2116 pGroup->setActive(true);
2119 //Reset everything and recreate the submenu for current item
2120 // We do it the lazy way : active/gray options matching regular options (when you do things on a single item)
2121 // Same for translated name of interface
2122 pGroupMenu->reset();
2123 for(i=0; i<groupNames.size(); i++)
2125 std::string name = groupNames[i];
2126 std::string ahParams = "name=" + name;
2127 //Use utf-8 string because group name can contain accentued characters (and stuff like that)
2128 pGroupMenu->addLine(name, "", "", name);
2129 CGroupSubMenu* pNewSubMenu = new CGroupSubMenu(CViewBase::TCtorParam());
2130 pGroupMenu->setSubMenu(pGroupMenu->getNumLine()-1, pNewSubMenu);
2131 if(pNewSubMenu)
2133 if(pEquip)
2134 pNewSubMenu->addLine(pEquip->getHardText(), "item_group_equip", ahParams, name + "_equip");
2135 // Add move sub menu
2136 if (pMoveSubMenu)
2138 pNewSubMenu->addLine(pMoveSubMenu->getHardText(), "", "", name + "_move");
2139 CGroupSubMenu* tmp = new CGroupSubMenu(CViewBase::TCtorParam());
2140 pNewSubMenu->setSubMenu(pNewSubMenu->getNumLine() - 1, tmp);
2141 pNewSubMenu = tmp;
2143 if(pMoveToBag && pMoveToBag->getActive())
2145 CViewTextMenu* tmp = pNewSubMenu->addLine(pMoveToBag->getHardText(),"item_group_move", "destination=bag|" + ahParams, name + "_bag");
2146 if(tmp) tmp->setGrayed(pMoveToBag->getGrayed());
2148 for(int j=0;j< MAX_INVENTORY_ANIMAL; j++)
2150 if(pMoveToPa[j] && pMoveToPa[j]->getActive())
2152 //there is an offset of 1 because TInventory names are pet_animal1/2/3/4
2153 std::string dst = toString("destination=pet_animal%d|", j + 1);
2154 CViewTextMenu* tmp = pNewSubMenu->addLine(pMoveToPa[j]->getHardText(),"item_group_move", dst + ahParams, name + toString("_pa%d", j + 1));
2155 if(tmp) tmp->setGrayed(pMoveToPa[j]->getGrayed());
2158 if(pMoveToRoom && pMoveToRoom->getActive())
2160 CViewTextMenu* tmp = pNewSubMenu->addLine(pMoveToRoom->getHardText(), "item_group_move", "destination=player_room|" + ahParams, name + "_room");
2161 if(tmp) tmp->setGrayed(pMoveToRoom->getGrayed());
2163 if(pMoveToGuild && pMoveToGuild->getActive() && ClientCfg.ItemGroupAllowGuild)
2165 CViewTextMenu* tmp = pNewSubMenu->addLine(pMoveToGuild->getHardText(),"item_group_move", "destination=guild|" + ahParams, name + "_guild");
2166 if(tmp) tmp->setGrayed(pMoveToRoom->getGrayed());
2174 REGISTER_ACTION_HANDLER( CHandlerItemMenuCheck, "item_menu_check" );
2176 class CHandlerItemMenuDeactivate : public IActionHandler
2178 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
2180 // The waiter may exist here only if at window init item info was
2181 // incorrect, and it hasn't been updated since then, but that's only
2182 // place to remove it in that case
2183 getInventory().removeItemInfoWaiter(&ItemMenuInBagUpdater);
2186 REGISTER_ACTION_HANDLER( CHandlerItemMenuDeactivate, "item_menu_deactivate" );
2189 // ***************************************************************************
2191 class CHandlerItemMenuBaseCheck : public IActionHandler
2193 void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
2195 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2197 // Get the ctrl sheet that launched this menu
2198 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2199 if (pCS == NULL) return;
2200 INVENTORIES::TInventory invId= (INVENTORIES::TInventory)pCS->getInventoryIndex();
2202 // Get the menu launched
2203 CInterfaceGroup *pMenu= dynamic_cast<CInterfaceGroup*>(pCaller);
2204 if(!pMenu) return;
2206 // Get all needed text entries
2207 CViewTextMenu *pDestroy = dynamic_cast<CViewTextMenu*>(pMenu->getView("destroy"));
2208 CViewTextMenu *pLockUnlock = dynamic_cast<CViewTextMenu*>(pMenu->getView("lockunlock"));
2210 if (pCS->getLockedByOwner())
2212 pLockUnlock->setHardText("uimUnlockItem");
2213 // Cannot destroy if locked by owner
2214 if (pDestroy) pDestroy->setActive(false);
2216 else
2218 pLockUnlock->setHardText("uimLockItem");
2219 if (pDestroy) pDestroy->setActive(true);
2224 REGISTER_ACTION_HANDLER( CHandlerItemMenuBaseCheck, "item_menu_base_check" );
2227 // ***************************************************************************
2228 static void sendMsgUseItem(uint16 slot)
2230 if(!ClientCfg.Local)
2232 CBitMemStream out;
2233 const char *sMsg = "ITEM:USE_ITEM";
2235 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
2237 out.serial( slot );
2238 NetMngr.push(out);
2240 else
2241 nlinfo("unknown message %s", sMsg);
2245 // ***************************************************************************
2246 static void sendMsgStopUseXpCat( bool isRingCatalyser )
2248 if(!ClientCfg.Local)
2250 CBitMemStream out;
2251 const char *sMsg = "ITEM:STOP_USE_XP_CAT";
2253 if(GenericMsgHeaderMngr.pushNameToStream(sMsg, out))
2255 out.serial( isRingCatalyser );
2256 NetMngr.push(out);
2258 else
2259 nlinfo("unknown message %s", sMsg);
2263 // ***************************************************************************
2264 static void checkItemCommand(const CItemSheet *itemSheet)
2266 if (itemSheet)
2268 if (!itemSheet->Scroll.LuaCommand.empty())
2269 CLuaManager::getInstance().executeLuaScript(itemSheet->Scroll.LuaCommand);
2270 // webig
2271 if (!itemSheet->Scroll.WebCommand.empty())
2273 CGroupHTML *pGH = dynamic_cast<CGroupHTML*>(
2274 CWidgetManager::getInstance()->getElementFromId("ui:interface:web_transactions:content:html")
2276 if (pGH) pGH->browse(itemSheet->Scroll.WebCommand.c_str());
2279 return;
2282 // ***************************************************************************
2283 class CHandlerTeleportUse : public IActionHandler
2285 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2287 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2288 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2289 if (pCS == NULL) return;
2291 // use the item
2292 sendMsgUseItem(uint16(pCS->getIndexInDB()));
2294 // Last loading is a teleport
2295 LoadingBackground = TeleportKamiBackground;
2296 const CItemSheet *pIS = pCS->asItemSheet();
2297 if ((pIS != NULL) && (pIS->Family == ITEMFAMILY::TELEPORT))
2299 switch (pIS->Teleport.Type)
2301 case TELEPORT_TYPES::NONE:
2302 case TELEPORT_TYPES::KAMI:
2303 LoadingBackground = TeleportKamiBackground;
2304 break;
2305 case TELEPORT_TYPES::KARAVAN:
2306 LoadingBackground = TeleportKaravanBackground;
2307 break;
2309 if (pIS->Scroll.Label.empty())
2310 checkItemCommand(pIS);
2314 REGISTER_ACTION_HANDLER( CHandlerTeleportUse, "teleport_use" );
2316 // ***************************************************************************
2317 class CHandlerItemConsume : public IActionHandler
2319 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2321 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2322 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2323 if (pCS == NULL) return;
2325 const CItemSheet *pIS = pCS->asItemSheet();
2326 if (pIS && pIS->Scroll.Label.empty())
2327 checkItemCommand(pIS);
2329 // use the item
2330 sendMsgUseItem(uint16(pCS->getIndexInDB()));
2333 REGISTER_ACTION_HANDLER( CHandlerItemConsume, "item_consume" );
2335 // ***************************************************************************
2336 class CHandlerItemExecute : public IActionHandler
2338 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2340 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2341 if (pCS)
2342 checkItemCommand(pCS->asItemSheet());
2343 return;
2346 REGISTER_ACTION_HANDLER( CHandlerItemExecute, "item_execute" );
2348 // ***************************************************************************
2349 class CHandlerValidateItemTextEdition : public IActionHandler
2351 void execute (CCtrlBase * /* pCaller */, const std::string & /* sParams */)
2353 CInterfaceItemEdition::getInstance()->validate();
2356 REGISTER_ACTION_HANDLER( CHandlerValidateItemTextEdition, "validate_edit_custom" );
2359 // ***************************************************************************
2360 class CHandlerItemTextDisplay : public IActionHandler
2362 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
2364 std::string const& windowName = sParams;
2365 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2366 CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2367 if (pCSItem == NULL || windowName.empty())
2368 return;
2370 const CItemSheet *pIS = pCSItem->asItemSheet();
2371 if (pIS && pIS->Scroll.Label.empty())
2372 checkItemCommand(pIS);
2374 CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, false);
2377 REGISTER_ACTION_HANDLER( CHandlerItemTextDisplay, "item_text_display" );
2379 // ***************************************************************************
2381 class CHandlerItemTextEdition : public IActionHandler
2383 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
2385 std::string const& windowName = sParams;
2386 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2387 CDBCtrlSheet *pCSItem = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2388 if (pCSItem == NULL || windowName.empty())
2389 return;
2391 CInterfaceItemEdition::getInstance()->setCurrWindow(pCSItem, windowName, true);
2394 REGISTER_ACTION_HANDLER( CHandlerItemTextEdition, "item_text_edition" );
2396 // ***************************************************************************
2397 class CHandlerItemTextEditionClose : public IActionHandler
2399 void execute (CCtrlBase * /* pCaller */, const std::string & /* sParams */)
2401 CInterfaceItemEdition::getInstance()->setCurrWindow(NULL);
2404 REGISTER_ACTION_HANDLER( CHandlerItemTextEditionClose, "on_close_edit_custom" );
2406 // ***************************************************************************
2407 class CHandlerXpCatalyserUse : public IActionHandler
2409 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2411 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2412 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
2413 if (pCS == NULL) return;
2415 const CItemSheet *pIS = pCS->asItemSheet();
2416 if (pIS && pIS->Scroll.Label.empty())
2417 checkItemCommand(pIS);
2419 // use the item
2420 sendMsgUseItem(uint16(pCS->getIndexInDB()));
2423 REGISTER_ACTION_HANDLER( CHandlerXpCatalyserUse, "xp_catalyser_use" );
2426 // ***************************************************************************
2427 class CHandlerXpCatalyserStopUse : public IActionHandler
2429 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2431 // stop use the item
2432 sendMsgStopUseXpCat(false);
2435 REGISTER_ACTION_HANDLER( CHandlerXpCatalyserStopUse, "xp_catalyser_stop_use" );
2437 // ***************************************************************************
2438 class CHandlerRingXpCatalyserStopUse : public IActionHandler
2440 void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
2442 // stop use the item
2443 sendMsgStopUseXpCat(true);
2446 REGISTER_ACTION_HANDLER( CHandlerRingXpCatalyserStopUse, "ring_xp_catalyser_stop_use" );
2449 // ***************************************************************************
2450 // item groups
2451 class CHandlerItemGroupMove : public IActionHandler
2453 void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
2455 std::string destination = getParam(sParams, "destination");
2456 std::string name = getParam(sParams, "name");
2457 if(name.empty())
2459 nlinfo("Trying to move a group with a caller not part of any group");
2460 return;
2463 CItemGroupManager::getInstance()->moveGroup(name, INVENTORIES::toInventory(destination));
2466 REGISTER_ACTION_HANDLER(CHandlerItemGroupMove, "item_group_move");
2469 // ***************************************************************************
2470 class CHandlerItemGroupEquip : public IActionHandler
2472 void execute (CCtrlBase * /* pCaller */, const std::string & sParams)
2474 std::string name = getParam(sParams, "name");
2475 if(name.empty())
2477 nlinfo("Trying to move a group with a caller not part of any group");
2478 return;
2481 CItemGroupManager::getInstance()->equipGroup(name);
2484 REGISTER_ACTION_HANDLER(CHandlerItemGroupEquip, "item_group_equip");