//=============================================================================
//
// File : libkvipopup.cpp
// Creation date : Fri Sep 03 2010 15:23:00 CEST by Fabio Bas
//
// This file is part of the KVIrc IRC client distribution
// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
//
// 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 (at your option) 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, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#include "KviModule.h"
#include "KviLocale.h"
#include "KviKvsPopupManager.h"
#define GET_KVS_POPUP(LOCKING_CHECK) \
int iIdx = szPopupName.indexOf(QChar('.')); \
if(iIdx == 0) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Empty popup name supplied", "kvs")); \
return true; \
} \
if(iIdx > 0) \
{ \
if(iIdx == szPopupName.size()) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Empty subpopup name supplied", "kvs")); \
return true; \
} \
szSubPopupName = szPopupName.mid(iIdx + 1); \
szPopupName.truncate(iIdx); \
} \
KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szPopupName); \
if(!pPopup) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Popup \"%Q\" doesn't exist", "kvs"), &szPopupName); \
return true; \
} \
if(pPopup->LOCKING_CHECK()) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Popup menu self-modification is not allowed (the popup is probably open)", "kvs")); \
return true; \
} \
while(!szSubPopupName.isEmpty()) \
{ \
iIdx = szSubPopupName.indexOf(QChar('.')); \
QString szTargetPopupName; \
if(iIdx >= 0) \
{ \
szTargetPopupName = szSubPopupName.mid(0, iIdx); \
szSubPopupName = szSubPopupName.mid(iIdx + 1); \
} \
else \
{ \
szTargetPopupName = szSubPopupName; \
szSubPopupName = QString(); \
} \
pPopup = pPopup->findChildPopupByName(szTargetPopupName); \
if(!pPopup) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Popup \"%Q\" doesn't exist", "kvs"), &szTargetPopupName); \
return true; \
} \
if(pPopup->LOCKING_CHECK()) \
{ \
if(!c->hasSwitch('q', "quiet")) \
c->warning(__tr2qs_ctx("Popup menu self-modification is not allowed (the popup is probably open)", "kvs")); \
return true; \
} \
}
#define GET_KVS_POPUP_FNC \
int iIdx = szPopupName.indexOf(QChar('.')); \
if(iIdx == 0) \
{ \
c->warning(__tr2qs_ctx("Empty popup name supplied", "kvs")); \
return true; \
} \
if(iIdx > 0) \
{ \
if(iIdx == szPopupName.size()) \
{ \
c->warning(__tr2qs_ctx("Empty subpopup name supplied", "kvs")); \
return true; \
} \
szSubPopupName = szPopupName.mid(iIdx + 1); \
szPopupName.truncate(iIdx); \
} \
KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szPopupName); \
if(!pPopup) \
{ \
c->warning(__tr2qs_ctx("Popup \"%Q\" doesn't exist", "kvs"), &szPopupName); \
return true; \
} \
while(!szSubPopupName.isEmpty()) \
{ \
iIdx = szSubPopupName.indexOf(QChar('.')); \
QString szTargetPopupName; \
if(iIdx >= 0) \
{ \
szTargetPopupName = szSubPopupName.mid(0, iIdx); \
szSubPopupName = szSubPopupName.mid(iIdx + 1); \
} \
else \
{ \
szTargetPopupName = szSubPopupName; \
szSubPopupName = QString(); \
} \
pPopup = pPopup->findChildPopupByName(szSubPopupName); \
if(!pPopup) \
{ \
c->warning(__tr2qs_ctx("Popup \"%Q\" doesn't exist", "kvs"), &szTargetPopupName); \
return true; \
} \
}
/*
@doc: popup.addItem
@type:
command
@title:
popup.addItem
@syntax:
popup.addItem [-q] (<popupname:string>, <text:string>[, <icon:string>[, <item_id:string>[, <condition:string>]]])
[{]
<command>
[}]
@short:
Adds an item to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a menu item with visible <text> and the optional <icon> to an already existing popup or
nested popup named <popupname>. If you want to add an item to a nested popup, use the form
"popup.addItem", for example, "channeltextview.myNestedItem".[br]
<text> is a string that is evaluated at [cmd]popup[/cmd] call time and may contain
identifiers and variables.[br]
<icon> is an optional [doc:image_id]image identifier[/doc].[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
If <condition> is given, it is evaluated at [cmd]popup.show[/cmd] call time and if the
result is 0, the item is not shown in the physical popup.[br]
If this item gets clicked, the code inside <command> will be executed.
<command> can be a simple instruction or an instruction block delimited by curly brackets.[br]
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd]
*/
static bool popup_kvs_cmd_addItem(KviKvsModuleCallbackCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId, szText, szIcon, szCondition;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("text", KVS_PT_NONEMPTYSTRING, 0, szText)
KVSM_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETER("condition", KVS_PT_STRING, KVS_PF_OPTIONAL, szCondition)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
if(c->callback()->code().trimmed().isEmpty() && !c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("Found empty instruction for popup item: maybe you need to fix the script?", "kvs"));
pPopup->addItem(szItemId, c->callback()->code(), szText, szIcon, szCondition);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addPrologue
@type:
command
@title:
popup.addPrologue
@syntax:
popup.addPrologue [-q] (<popupname:string>[, <item_id:string>])
[{]
<command>
[}]
@short:
Adds a prologue to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a menu prologue to an already existing popup or nested popup named <popupname>. If you
want to add an item to a nested popup, use the form "popup.addItem", for example,
"channeltextview.myNestedItem".[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
<command> will be executed just before the popup is filled at [cmd]popup.show[/cmd] command call.
<command> can be a simple instruction or an instruction block delimited by curly brackets.[br]
Please note that some instructions are not allowed here, You can't delete the prologue's parent
popup (calling [cmd]popup.clear[/cmd] or [cmd]popup.destroy[/cmd]) or modify prologues/epilogues
(calling [cmd]popup.addPrologue[/cmd] or [cmd]popup.addEpilogue[/cmd])
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.addEpilogue[/cmd]
*/
static bool popup_kvs_cmd_addPrologue(KviKvsModuleCallbackCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isSoftLocked)
if(c->callback()->code().trimmed().isEmpty() && !c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("Found empty prologue block: maybe you need to fix the script?", "kvs"));
pPopup->addPrologue(szItemId, c->callback()->code());
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addEpilogue
@type:
command
@title:
popup.addEpilogue
@syntax:
popup.addEpilogue [-q] (<popupname:string>[, <item_id:string>])
[{]
<command>
[}]
@short:
Adds an epilogue to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a menu epilogue to an already existing popup or nested popup named <popupname>. If you
want to add an item to a nested popup, use the form "popup.addItem", for example,
"channeltextview.myNestedItem".[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
<command> will be executed just after the popup is filled at [cmd]popup.show[/cmd] command call.
<command> can be a simple instruction or an instruction block delimited by curly brackets.[br]
Please note that some instructions are not allowed here, You can't delete the prologue's parent
popup (calling [cmd]popup.clear[/cmd] or [cmd]popup.destroy[/cmd]) or modify prologues/epilogues
(calling [cmd]popup.addPrologue[/cmd] or [cmd]popup.addEpilogue[/cmd])
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.addPrologue[/cmd]
*/
static bool popup_kvs_cmd_addEpilogue(KviKvsModuleCallbackCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isSoftLocked)
if(c->callback()->code().trimmed().isEmpty() && !c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("Found empty epilogue block: maybe you need to fix the script?", "kvs"));
pPopup->addEpilogue(szItemId, c->callback()->code());
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addExtPopup
@type:
command
@title:
popup.addExtPopup
@syntax:
popup.addExtPopup [-q] <popupname:string> <external_popup:string> <text:string> [<icon:string> [<item_id:string> [<condition:string>]]]
@short:
Adds an external popup to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a nested popup item with visible <text> and the optional <icon> to an already existing popup or
nested popup named <popupname>. If you want to add an item to a nested popup, use the form
"popup.addItem", for example, "channeltextview.myNestedItem".[br]
<text> is a string that is evaluated at [cmd]popup[/cmd] call time and may contain
identifiers and variables.[br]
<icon> is an optional [doc:image_id]image identifier[/doc].[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
If <condition> is given, it is evaluated at [cmd]popup.show[/cmd] call time and if the
result is 0, the item is not shown in the physical popup.[br]
If this item is hovered over, the nested popup <external_popup> will be shown.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.addSubPopup[/cmd]
*/
static bool popup_kvs_cmd_addExtPopup(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId, szExtPopupName, szText, szIcon, szCondition;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("external_popup", KVS_PT_NONEMPTYSTRING, 0, szExtPopupName)
KVSM_PARAMETER("text", KVS_PT_NONEMPTYSTRING, 0, szText)
KVSM_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETER("condition", KVS_PT_STRING, KVS_PF_OPTIONAL, szCondition)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
pPopup->addExtPopup(szItemId, szExtPopupName, szText, szIcon, szCondition);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addLabel
@type:
command
@title:
popup.addLabel
@syntax:
popup.addLabel [-q] <popupname:string> <text:string> [<icon:string> [<item_id:string> [<condition:string>]]]
@short:
Adds a label to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a descriptive label with visible <text> and the optional <icon> to an already existing popup or
nested popup named <popupname>. If you want to add an item to a nested popup, use the form
"popup.addItem", for example, "channeltextview.myNestedItem". The label acts like a separator - it is
not selectable or clickable.[br]
<text> is a string that is evaluated at [cmd]popup[/cmd] call time and may contain
identifiers and variables.[br]
<icon> is an optional [doc:image_id]image identifier[/doc].[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
If <condition> is given, it is evaluated at [cmd]popup.show[/cmd] call time and if the
result is 0, the item is not shown in the physical popup.[br]
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd]
*/
static bool popup_kvs_cmd_addLabel(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId, szText, szIcon, szCondition;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("text", KVS_PT_NONEMPTYSTRING, 0, szText)
KVSM_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETER("condition", KVS_PT_STRING, KVS_PF_OPTIONAL, szCondition)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
pPopup->addLabel(szItemId, szText, szIcon, szCondition);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addSubPopup
@type:
command
@title:
popup.addSubPopup
@syntax:
popup.addSubPopup [-q] (<popupname:string>, <text:string>[, <icon:string>[, <item_id:string>[, <condition:string>]]])
@short:
Adds a nested popup to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds an empty nested popup item with visible <text> and the optional <icon> to an already existing popup or
nested popup named <popupname>. If you want to add an item to a nested popup, use the form
"popup.addItem", for example, "channeltextview.myNestedItem".[br]
<text> is a string that is evaluated at [cmd]popup[/cmd] call time and may contain
identifiers and variables.[br]
<icon> is an optional [doc:image_id]image identifier[/doc].[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
If <condition> is given, it is evaluated at [cmd]popup.show[/cmd] call time and if the
result is 0, the item is not shown in the physical popup.[br]
If this item is hovered over, the nested popup will be shown.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.addExtPopup[/cmd]
*/
static bool popup_kvs_cmd_addSubPopup(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId, szText, szIcon, szCondition;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("text", KVS_PT_NONEMPTYSTRING, 0, szText)
KVSM_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETER("condition", KVS_PT_STRING, KVS_PF_OPTIONAL, szCondition)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
pPopup->addPopup(szItemId, szText, szIcon, szCondition);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.addSeparator
@type:
command
@title:
popup.addSeparator
@syntax:
popup.addSeparator [-q] <popupname:string> [<item_id:string> [<condition:string>]]
@short:
Adds a separator to a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Adds a separator (typically drawn as a straight line) to an already existing popup or
nested popup named <popupname>. If you want to add an item to a nested popup, use the form
"popup.addItem", for example, "channeltextview.myNestedItem". The separator is not selectable
or clickable.[br]
<item_id> is the optional item ID - if not specified, it will be generated automatically.[br]
If <condition> is given, it is evaluated at [cmd]popup.show[/cmd] call time and if the
result is 0, the item is not shown in the physical popup.[br]
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd]
*/
static bool popup_kvs_cmd_addSeparator(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId, szCondition;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("item_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szItemId)
KVSM_PARAMETER("condition", KVS_PT_STRING, KVS_PF_OPTIONAL, szCondition)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
pPopup->addSeparator(szItemId, szCondition);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.clear
@type:
command
@title:
popup.clear
@syntax:
popup.clear [-q] <popupname:string>
@short:
Clears all the items of a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Removes all the items from an already existing popup or nested popup named <popupname>.
If you want to clear a nested popup, use the form "popup.delItem", for example,
"channeltextview.myNestedItem".[br]
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [fnc]popup.isEmpty[/fnc]
*/
static bool popup_kvs_cmd_clear(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isSoftLocked)
pPopup->doClear();
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.create
@type:
command
@title:
popup.create
@syntax:
popup.create [-q] <popupname:string>
@short:
Creates a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Creates a popup named <popupname>; if the popup already exists, a warning is printed.
To create a nested popup, use [cmd]popup.addSubPopup[/cmd] instead.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.destroy[/cmd], [fnc]popup.exists[/fnc]
*/
static bool popup_kvs_cmd_create(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
if(KviKvsPopupManager::instance()->lookup(szPopupName))
{
if(!c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("The popup \"%Q\" already exists", "kvs"), &szPopupName);
return true;
}
KviKvsPopupMenu * pMenu = new KviKvsPopupMenu(szPopupName);
KviKvsPopupManager::instance()->add(szPopupName, pMenu);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.destroy
@type:
command
@title:
popup.destroy
@syntax:
popup.destroy [-q] <popupname:string>
@short:
Destroies a popup
@switches:
!sw: -q | --quiet
Run quietly: don't print warning and errors
@description:
Destroys a popup named <popupname>.
To destroy a nested popup, use [cmd]popup.delItem[/cmd] instead.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.create[/cmd], [fnc]popup.exists[/fnc]
*/
static bool popup_kvs_cmd_destroy(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szPopupName);
if(!pPopup)
{
if(!c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("Popup \"%Q\" doesn't exist", "kvs"), &szPopupName);
return true;
}
if(pPopup->isSoftLocked())
{
if(!c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("Popup menu self-modification is not allowed (the popup is probably open)", "kvs"));
return true;
}
KviKvsPopupManager::instance()->remove(szPopupName);
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.delitem
@type:
command
@title:
popup.delitem
@syntax:
popup.delitem [-d] [-q] <popupname:string> <item_id:string>
@short:
Deletes an item from a popup
@switches:
!sw: -q | --quiet
Run quietly
!sw: -d | --deep
Search the whole popup tree instead of only the first level
@description:
Deletes the item specified by <id> from the popup <popupname>.
If the -d flag is specified then the item with the specified
<id> is searched in the whole popup tree (containing submenus)
otherwise only the first level is searched. [br]
If the -q flag is specified, the command does not complain
about non-existent items or popup menus.[br]
See [cmd]defpopup[/cmd] for more information.[br]
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd]
*/
static bool popup_kvs_cmd_delItem(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName, szItemId;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETER("item_id", KVS_PT_NONEMPTYSTRING, 0, szItemId)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP(isHardLocked)
if(!pPopup->removeItemByName(szItemId, c->hasSwitch('d', "deep")))
{
if(!c->hasSwitch('q', "quiet"))
c->warning(__tr2qs_ctx("The menu item with ID \"%Q\" doesn't exist in popup \"%Q\"", "kvs"), &szItemId, &szPopupName);
}
KviKvsPopupManager::instance()->emitRefresh(szPopupName);
return true;
}
/*
@doc: popup.exists
@type:
function
@title:
$popup.exists
@syntax:
$popup.exists(<popupname:string>)
@short:
Returns true if a popup exists
@description:
Returns true if a popup exists or false otherwise.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.create[/cmd], [cmd]popup.destroy[/cmd]
*/
static bool popup_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
int iIdx = szPopupName.indexOf(QChar('.'));
if(iIdx == 0)
{
c->warning(__tr2qs_ctx("Empty subpopup name supplied", "kvs"));
return true;
}
if(iIdx > 0)
{
if(iIdx == szPopupName.size())
{
c->warning(__tr2qs_ctx("Empty subpopup name supplied", "kvs"));
return true;
}
szSubPopupName = szPopupName.mid(iIdx + 1);
szPopupName.truncate(iIdx);
}
KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szPopupName);
if(!pPopup)
{
c->returnValue()->setBoolean(false);
return true;
}
if(!szSubPopupName.isEmpty())
{
pPopup = pPopup->findChildPopupByName(szSubPopupName);
if(!pPopup)
{
c->returnValue()->setBoolean(false);
return true;
}
}
c->returnValue()->setBoolean(true);
return true;
}
/*
@doc: popup.isEmpty
@type:
function
@title:
$popup.isEmpty
@syntax:
$popup.isEmpty(<popupname:string>)
@short:
Returns true if a popup is empty
@description:
Returns true if a popup is empty or false otherwise.
@seealso:
[cmd]defpopup[/cmd], [cmd]popup.show[/cmd], [cmd]popup.clear[/cmd]
*/
static bool popup_kvs_fnc_isEmpty(KviKvsModuleFunctionCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popupname", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
GET_KVS_POPUP_FNC
c->returnValue()->setBoolean(pPopup->isEmpty());
return true;
}
/*
@doc: popup.currentItemId
@type:
function
@title:
$popup.currentItemId
@syntax:
$popup.currentItemId()
@short:
Returns the popup item ID that owns the executing code
@description:
When called inside a popup item's callback, this function returns the ID of the popup item.
Outside of callback code, $null is returned.
@examples:
[example]
#clean any previous popup by the same name
setmenu test
popup.clear test
popup.destroy test
#create the popup
popup.create test
popup.addPrologue(test)
{
# loop ten times
foreach(%i,0,1,2,3,4,5,6,7,8,9)
{
# delete previous created item to avoid duplication
popup.delItem test %i
# create a test item using %i as its "item id"
popup.addItem(test, item%i, , %i)
{
#get back "item id" inside the callback
debug "chosen item $popup.currentItemId()";
}
}
}
setmenu test test
[/example]
@seealso:
[cmd]popup.show[/cmd], [cmd]popup.addItem[/cmd]
*/
static bool popup_kvs_fnc_currentItemId(KviKvsModuleFunctionCall * c)
{
QString * pPopupId = c->context()->popupId();
if(pPopupId)
{
c->returnValue()->setString(pPopupId);
}
else
{
c->returnValue()->setNothing();
}
return true;
}
/*
@doc: popup.show
@type:
command
@title:
popup.show
@syntax:
popup.show [-p=<screen_coordinates:string>] <popup_name:string> [<parameter1:variant> [<parameter2:variant> [...]]]
@short:
Shows a popup menu
@switches:
!sw: -p=<screen_coordinates:string> | --point=<screen_coordinates:string>
@description:
Shows the popup menu <popup_name> at the current cursor position,
eventually passing the [parameters]. Please note that you can't
use this command inside one of the [cmd]defpopup[/cmd] command
handlers for <popup_name>. In other words, you can't "popup
a popup" while it is being popped up. :) (This would
be an endless recursive behaviour).[br]
If the -p switch is used, then <screen_coordinates> must be
in the form <x>,<y> and will be used as screen coordinates
for the placement of the popup (instead of the current cursor position).[br]
@seealso:
[cmd]defpopup[/cmd]
*/
static bool popup_kvs_cmd_show(KviKvsModuleCommandCall * c)
{
QString szPopupName, szSubPopupName;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("popup_name", KVS_PT_NONEMPTYSTRING, 0, szPopupName)
KVSM_PARAMETERS_END(c)
// copy parameters
KviKvsVariantList * pPopupParams = new KviKvsVariantList();
c->params()->first();
while(KviKvsVariant * v = c->params()->next())
pPopupParams->append(new KviKvsVariant(*v));
KviKvsPopupMenu * pMenu = KviKvsPopupManager::instance()->lookup(szPopupName);
if(!pMenu)
{
delete pPopupParams;
pPopupParams = nullptr;
c->error(__tr2qs_ctx("Popup %Q is not defined", "kvs"), &szPopupName);
return false;
}
if(pMenu->isSoftLocked())
{
delete pPopupParams;
pPopupParams = nullptr;
c->error(__tr2qs_ctx("A popup menu can't be popped up twice", "kvs"));
return false;
}
QPoint pnt = QCursor::pos();
KviKvsVariant * pCoords = c->getSwitch('p', "point");
if(pCoords)
{
QString szCoords;
pCoords->asString(szCoords);
int idx = szCoords.indexOf(',');
bool bCoordsOk = true;
if(idx == -1)
bCoordsOk = false;
else
{
QString szX = szCoords.left(idx);
szCoords.remove(0, idx + 1);
bool bOk1, bOk2;
int iX = szX.toInt(&bOk1);
int iY = szCoords.toInt(&bOk2);
if(bOk1 && bOk2)
pnt = QPoint(iX, iY);
else
bCoordsOk = false;
}
if(!bCoordsOk)
c->warning(__tr2qs_ctx("Invalid syntax for screen coordinates, using cursor position", "kvs"));
}
pMenu->doPopup(pnt, c->window(), pPopupParams);
return true;
}
static bool popup_module_init(KviModule * m)
{
KVSM_REGISTER_CALLBACK_COMMAND(m, "addItem", popup_kvs_cmd_addItem);
KVSM_REGISTER_CALLBACK_COMMAND(m, "addPrologue", popup_kvs_cmd_addPrologue);
KVSM_REGISTER_CALLBACK_COMMAND(m, "addEpilogue", popup_kvs_cmd_addEpilogue);
KVSM_REGISTER_SIMPLE_COMMAND(m, "addExtPopup", popup_kvs_cmd_addExtPopup);
KVSM_REGISTER_SIMPLE_COMMAND(m, "addLabel", popup_kvs_cmd_addLabel);
KVSM_REGISTER_SIMPLE_COMMAND(m, "addSubPopup", popup_kvs_cmd_addSubPopup);
KVSM_REGISTER_SIMPLE_COMMAND(m, "addSeparator", popup_kvs_cmd_addSeparator);
KVSM_REGISTER_SIMPLE_COMMAND(m, "clear", popup_kvs_cmd_clear);
KVSM_REGISTER_SIMPLE_COMMAND(m, "create", popup_kvs_cmd_create);
KVSM_REGISTER_SIMPLE_COMMAND(m, "delItem", popup_kvs_cmd_delItem);
KVSM_REGISTER_SIMPLE_COMMAND(m, "destroy", popup_kvs_cmd_destroy);
KVSM_REGISTER_SIMPLE_COMMAND(m, "show", popup_kvs_cmd_show);
KVSM_REGISTER_FUNCTION(m, "exists", popup_kvs_fnc_exists);
KVSM_REGISTER_FUNCTION(m, "isEmpty", popup_kvs_fnc_isEmpty);
KVSM_REGISTER_FUNCTION(m, "currentItemId", popup_kvs_fnc_currentItemId);
return true;
}
static bool popup_module_cleanup(KviModule *)
{
return true;
}
static bool popup_module_can_unload(KviModule *)
{
return true;
}
KVIRC_MODULE(
"Userlist", // module name
"4.0.0", // module version
"Copyright (C) 2010 Fabio Bas (ctrlaltca at gmail dot com)", // author & (C)
"KVIrc popup management functions",
popup_module_init,
popup_module_can_unload,
0,
popup_module_cleanup,
0)