You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
921 lines
30 KiB
921 lines
30 KiB
//=============================================================================
|
|
//
|
|
// File : libkvidialog.cpp
|
|
// Creation date : Sat Sep 15 2001 01:13:25 by Szymon Stefanek
|
|
//
|
|
// This file is part of the KVirc irc client distribution
|
|
// Copyright (C) 2001-2005 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 opinion) 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 "libkvidialog.h"
|
|
|
|
#include <tqmessagebox.h>
|
|
#include <tqlayout.h>
|
|
#include "kvi_tal_hbox.h"
|
|
#include <tqlineedit.h>
|
|
#ifdef COMPILE_USE_QT4
|
|
#include <tq3multilineedit.h>
|
|
#define TQMultiLineEdit Q3MultiLineEdit
|
|
#include <tqdesktopwidget.h>
|
|
#else
|
|
#include <tqmultilineedit.h>
|
|
#endif
|
|
#include <tqevent.h>
|
|
#include <tqlabel.h>
|
|
#include <tqpushbutton.h>
|
|
|
|
#include "kvi_locale.h"
|
|
#include "kvi_module.h"
|
|
#include "kvi_modulemanager.h"
|
|
#include "kvi_error.h"
|
|
#include "kvi_app.h"
|
|
#include "kvi_iconmanager.h"
|
|
#include "kvi_console.h"
|
|
#include "kvi_iconmanager.h"
|
|
#include "kvi_kvs_script.h"
|
|
#include "kvi_msgbox.h"
|
|
|
|
static KviPointerList<TQWidget> * g_pDialogModuleDialogList;
|
|
|
|
KviKvsCallbackMessageBox::KviKvsCallbackMessageBox(
|
|
const TQString &szCaption,
|
|
const TQString &szText,
|
|
const TQString &szIcon,
|
|
const TQString &szButton0,
|
|
const TQString &szButton1,
|
|
const TQString &szButton2,
|
|
const TQString &szCode,
|
|
KviKvsVariantList * pMagicParams,
|
|
KviWindow * pWindow,bool modal)
|
|
: TQMessageBox(
|
|
szCaption,
|
|
szText,
|
|
TQMessageBox::NoIcon,
|
|
szButton0.isEmpty() ? TQMessageBox::NoButton : TQMessageBox::Ok | TQMessageBox::Default,
|
|
szButton1.isEmpty() ? TQMessageBox::NoButton : (szButton2.isEmpty() ? TQMessageBox::No | TQMessageBox::Escape : TQMessageBox::No),
|
|
szButton2.isEmpty() ? TQMessageBox::NoButton : TQMessageBox::Cancel | TQMessageBox::Escape,
|
|
0,0,modal) ,
|
|
KviKvsCallbackObject("dialog.message",pWindow,szCode,pMagicParams,0)
|
|
{
|
|
g_pDialogModuleDialogList->append(this);
|
|
#ifndef COMPILE_USE_QT4
|
|
setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
|
|
#endif
|
|
|
|
TQPixmap * pix = g_pIconManager->getImage(szIcon);
|
|
|
|
if(pix)setIconPixmap(*pix);
|
|
else {
|
|
if(KviTQString::equalCI(szIcon,"information"))setIcon(TQMessageBox::Information);
|
|
else if(KviTQString::equalCI(szIcon,"warning"))setIcon(TQMessageBox::Warning);
|
|
else if(KviTQString::equalCI(szIcon,"critical"))setIcon(TQMessageBox::Critical);
|
|
}
|
|
if(!szButton0.isEmpty())setButtonText(TQMessageBox::Ok,szButton0);
|
|
if(!szButton1.isEmpty())setButtonText(TQMessageBox::No,szButton1);
|
|
if(!szButton2.isEmpty())setButtonText(TQMessageBox::Cancel,szButton2);
|
|
}
|
|
|
|
KviKvsCallbackMessageBox::~KviKvsCallbackMessageBox()
|
|
{
|
|
g_pDialogModuleDialogList->removeRef(this);
|
|
}
|
|
|
|
void KviKvsCallbackMessageBox::done(int code)
|
|
{
|
|
TQMessageBox::done(code);
|
|
|
|
kvs_int_t iVal = 0;
|
|
|
|
switch(code)
|
|
{
|
|
case TQMessageBox::No: iVal = 1; break;
|
|
case TQMessageBox::Cancel: iVal = 2; break;
|
|
}
|
|
|
|
KviKvsVariantList params;
|
|
params.append(new KviKvsVariant(iVal));
|
|
|
|
execute(¶ms);
|
|
|
|
delete this;
|
|
}
|
|
|
|
|
|
/*
|
|
@doc: dialog.message
|
|
@type:
|
|
command
|
|
@title:
|
|
dialog.message
|
|
@short:
|
|
Shows a message box
|
|
@syntax:
|
|
dialog.message [-b] (<caption>,<message_text>,<icon>,<button0>[,<button1>[,<button2>[,<magic1>[,<magic2>[...]]]]])
|
|
{
|
|
<callback_command>
|
|
}
|
|
@description:
|
|
Shows a message dialog box with the specified <caption> , <message_text> , <icon> and
|
|
buttons.[br]
|
|
<caption> is a text string that will appear in the caption of the dialog box.[br]
|
|
<message_text> is a text string that will appear in the dialog box and can contain HTML formatting.[br]
|
|
<icon> is an [doc:image_id]image identifier[/doc] that defines an icon to be placed in the dialog box.
|
|
<icon> can be a relative or absolute path to an image file , a signed number (in that case it defines
|
|
an internal KVIrc image) or one of the special strings "critical", "information" and "warning".[br]
|
|
<button0> is the text of the first button (on the left).[br]
|
|
<button1> is the text of the second button (if empty or not given at all, only one button will appear in the dialog).[br]
|
|
<button2> is the text of the third button (if empty or not given, only two buttons will appear in the dialog).[br]
|
|
The first button is always the default button: it is activated when the user presses the
|
|
enter key. The thirs, or the second if the third is not present, is the escape button
|
|
and is activated when the user presses the Esc key.[br]
|
|
<magic1>,<magic2>... are the magic parameters: evaluated at dialog.message call time and passed
|
|
to the <callback_command> as positional parameters.[br]
|
|
If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
|
|
it will appear above its parent widget and block its input until it's closed.[br]
|
|
Once the dialog has been shown , the user will click one of the buttons. At this point the dialog
|
|
is hidden and the <callback_command> is executed passing the number of the button clicked
|
|
as $0 and the magic parameters as positional parameters $1 , $2 , $3....[br]
|
|
Please note that if the user closes the window with the window manager close button ,
|
|
the action is interpreted as a button2 click (that is usually sth as "Cancel").[br]
|
|
@examples:
|
|
[example]
|
|
[comment]# Just a warning dialog[/comment]
|
|
dialog.message("Warning","You're being <b>warned</b>",warning,"Ok"){ echo The user clicked OK; }
|
|
[comment]# A question[/comment]
|
|
dialog.message("And now ?","What do you want to do ?",information,"Go home","Watch TV","Scream")
|
|
{
|
|
if($0 == 0)echo "The user want's to go home"
|
|
else if($0 == 1)echo "The user want's to watch TV"
|
|
else echo "The user wants to scream!"
|
|
}
|
|
[/example]
|
|
*/
|
|
|
|
static bool dialog_kvs_cmd_message(KviKvsModuleCallbackCommandCall * c)
|
|
{
|
|
TQString szCaption,szMessage,szIcon,szButton0,szButton1,szButton2;
|
|
KviKvsVariantList params;
|
|
|
|
KVSM_PARAMETERS_BEGIN(c)
|
|
KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
|
|
KVSM_PARAMETER("message",KVS_PT_STRING,0,szMessage)
|
|
KVSM_PARAMETER("icon",KVS_PT_STRING,0,szIcon)
|
|
KVSM_PARAMETER("button0",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton0)
|
|
KVSM_PARAMETER("button1",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton1)
|
|
KVSM_PARAMETER("button2",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton2)
|
|
KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
|
|
KVSM_PARAMETERS_END(c)
|
|
bool modal;
|
|
if(c->hasSwitch('b',"modal")) modal=true;
|
|
else modal=false;
|
|
TQString szCmd = c->callback()->code();
|
|
|
|
KviKvsCallbackMessageBox * box = new KviKvsCallbackMessageBox(
|
|
szCaption,szMessage,szIcon,szButton0,szButton1,szButton2,szCmd,¶ms,c->window(),modal);
|
|
box->show();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
KviKvsCallbackTextInput::KviKvsCallbackTextInput(
|
|
const TQString &szCaption,
|
|
const TQString &szLabel,
|
|
const TQString &szDefaultText,
|
|
const TQString &szIcon,
|
|
bool bMultiLine,
|
|
const TQString &szButton0,
|
|
const TQString &szButton1,
|
|
const TQString &szButton2,
|
|
const TQString &szCode,
|
|
KviKvsVariantList * pMagicParams,
|
|
KviWindow * pWindow,bool modal)
|
|
: TQDialog(), KviKvsCallbackObject("dialog.textinput",pWindow,szCode,pMagicParams,0)
|
|
{
|
|
g_pDialogModuleDialogList->append(this);
|
|
setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_KVIRC)));
|
|
setModal(modal);
|
|
setCaption(szCaption);
|
|
|
|
TQGridLayout * g = new TQGridLayout(this,2,3,5,5);
|
|
|
|
TQPixmap * pix = g_pIconManager->getImage(szIcon);
|
|
|
|
if(pix)
|
|
{
|
|
TQLabel * il = new TQLabel(this);
|
|
il->setPixmap(*pix);
|
|
il->setAlignment(TQt::AlignCenter);
|
|
g->addWidget(il,0,0);
|
|
TQLabel * tl = new TQLabel(szLabel,this);
|
|
g->addWidget(tl,0,1);
|
|
} else {
|
|
TQLabel * tl = new TQLabel(szLabel,this);
|
|
g->addMultiCellWidget(tl,0,0,0,1);
|
|
}
|
|
|
|
g->setColStretch(1,1);
|
|
|
|
m_bMultiLine = bMultiLine;
|
|
|
|
if(m_bMultiLine)
|
|
{
|
|
m_pEdit = new TQMultiLineEdit(this);
|
|
((TQMultiLineEdit *)m_pEdit)->setText(szDefaultText);
|
|
} else {
|
|
m_pEdit = new TQLineEdit(this);
|
|
((TQLineEdit *)m_pEdit)->setText(szDefaultText);
|
|
}
|
|
|
|
g->addMultiCellWidget(m_pEdit,1,1,0,1);
|
|
|
|
KviTalHBox * box = new KviTalHBox(this);
|
|
g->addMultiCellWidget(box,2,2,0,1);
|
|
|
|
m_iEscapeButton = 0;
|
|
m_iDefaultButton = 0;
|
|
|
|
if(!szButton0.isEmpty())
|
|
{
|
|
TQString szB = szButton0;
|
|
bool bDef = false;
|
|
if(KviTQString::equalCIN(szB,"default=",8))
|
|
{
|
|
bDef = true;
|
|
szB.remove(0,8);
|
|
m_iDefaultButton = 0;
|
|
} else if(KviTQString::equalCIN(szB,"escape=",7))
|
|
{
|
|
szB.remove(0,7);
|
|
m_iEscapeButton = 0;
|
|
}
|
|
TQPushButton * pb1 = new TQPushButton(szB,box);
|
|
if(bDef)pb1->setDefault(true);
|
|
connect(pb1,TQT_SIGNAL(clicked()),this,TQT_SLOT(b0Clicked()));
|
|
}
|
|
|
|
if(!szButton1.isEmpty())
|
|
{
|
|
TQString szB = szButton1;
|
|
bool bDef = false;
|
|
if(KviTQString::equalCIN(szB,"default=",8))
|
|
{
|
|
bDef = true;
|
|
szB.remove(0,8);
|
|
m_iDefaultButton = 1;
|
|
} else if(KviTQString::equalCIN(szB,"escape=",7))
|
|
{
|
|
szB.remove(0,7);
|
|
m_iEscapeButton = 1;
|
|
}
|
|
TQPushButton * pb2 = new TQPushButton(szB,box);
|
|
if(bDef)pb2->setDefault(true);
|
|
connect(pb2,TQT_SIGNAL(clicked()),this,TQT_SLOT(b1Clicked()));
|
|
}
|
|
|
|
if(!szButton2.isEmpty())
|
|
{
|
|
TQString szB = szButton2;
|
|
bool bDef = false;
|
|
if(KviTQString::equalCIN(szB,"default=",8))
|
|
{
|
|
bDef = true;
|
|
szB.remove(0,8);
|
|
m_iDefaultButton = 2;
|
|
} else if(KviTQString::equalCIN(szB,"escape=",7))
|
|
{
|
|
szB.remove(0,7);
|
|
m_iEscapeButton = 2;
|
|
}
|
|
TQPushButton * pb3 = new TQPushButton(szB,box);
|
|
if(bDef)pb3->setDefault(true);
|
|
connect(pb3,TQT_SIGNAL(clicked()),this,TQT_SLOT(b2Clicked()));
|
|
}
|
|
|
|
}
|
|
|
|
KviKvsCallbackTextInput::~KviKvsCallbackTextInput()
|
|
{
|
|
g_pDialogModuleDialogList->removeRef(this);
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::b0Clicked()
|
|
{
|
|
done(0+10);
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::b1Clicked()
|
|
{
|
|
done(1+10);
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::b2Clicked()
|
|
{
|
|
done(2+10);
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::closeEvent(TQCloseEvent *e)
|
|
{
|
|
e->ignore();
|
|
done(m_iEscapeButton+10);
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::done(int code)
|
|
{
|
|
if(code >= 10)
|
|
{
|
|
code -= 10;
|
|
} else {
|
|
switch(code)
|
|
{
|
|
case TQDialog::Accepted:
|
|
code = m_iDefaultButton;
|
|
break;
|
|
default:
|
|
code = m_iEscapeButton;
|
|
break;
|
|
}
|
|
}
|
|
|
|
TQString txt;
|
|
|
|
if(m_bMultiLine)
|
|
{
|
|
txt = ((TQMultiLineEdit *)m_pEdit)->text();
|
|
} else {
|
|
txt = ((TQLineEdit *)m_pEdit)->text();
|
|
}
|
|
|
|
KviKvsVariantList params;
|
|
params.append(new KviKvsVariant((kvs_int_t)code));
|
|
params.append(new KviKvsVariant(txt));
|
|
|
|
execute(¶ms);
|
|
|
|
//TQDialog::done(code);
|
|
|
|
delete this;
|
|
}
|
|
|
|
void KviKvsCallbackTextInput::showEvent(TQShowEvent *e)
|
|
{
|
|
move((g_pApp->desktop()->width() - width())/2,(g_pApp->desktop()->height() - height()) / 2);
|
|
TQDialog::showEvent(e);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
@doc: dialog.textinput
|
|
@type:
|
|
command
|
|
@title:
|
|
dialog.textinput
|
|
@short:
|
|
Shows a dialog that accepts user input as text
|
|
@syntax:
|
|
dialog.textinput [-d=<default text>] [-i=<icon>] [-m] [-b] (<caption>,<info_text>,<button0>[,<button1>[,<button2>[,<magic1>[,<magic2>[...]]]]])
|
|
{
|
|
<callback_command>
|
|
}
|
|
@switches:
|
|
!sw: -d=<default_text> | --default=<default_text>
|
|
Set the initial text input value to <default_text>
|
|
!sw: -i=<icon> | --icon=<icon>
|
|
Display the specified icon, just of the left of the informational text
|
|
!sw: -m | --multiline
|
|
Input multiline text instead of single line
|
|
@description:
|
|
Shows a text input dialog box with the specified <caption> , <info_text> , <icon> and
|
|
buttons.[br]
|
|
<caption> is a text string that will appear in the caption of the dialog box.[br]
|
|
<info_text> is a fixed text string that will appear in the dialog box and can contain HTML formatting.[br]
|
|
<button0> is the text of the first button (on the left).[br]
|
|
<button1> is the text of the second button (if empty or not given at all, only one button will appear in the dialog).[br]
|
|
<button2> is the text of the third button (if empty or not given, only two buttons will appear in the dialog).[br]
|
|
If one of the text strings starts with a "default=" prefix then the button is assumed
|
|
to be the default button of the dialog and will be also activated when the user presses enter.
|
|
If the -m switch is used , the dialog will be a multi-line text input, otherwise the user will be able to
|
|
input only a single line of text.[br]
|
|
If the -d switch is used , the initial text input value is set to <default text>.[br]
|
|
If the -i switch is used , the dialog displays also the icon <icon> , just on the left ot the <info_text>[br]
|
|
If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
|
|
it will appear above its parent widget and block its input until it's closed.[br]
|
|
In that case <icon> is an [doc:image_id]image identifier[/doc] (can be a relative or absolute
|
|
path to an image file or a signed number (in that case it defines an internal KVIrc image).[br]
|
|
<magic1>,<magic2>... are the magic parameters: evaluated at dialog.textinput call time and passed
|
|
to the <callback_command> as positional parameters.[br]
|
|
Once the dialog has been shown , the user will click one of the buttons. At this point the dialog
|
|
is hidden and the <callback_command> is executed passing the text input value in $1, the number of the button clicked
|
|
as $0, and the magic parameters as positional parameters $2 , $3 , $4....[br]
|
|
Please note that if the user closes the window with the window manager close button ,
|
|
the action is interpreted as a button2 click (that is usually sth as "Cancel").[br]
|
|
@examples:
|
|
[example]
|
|
[comment]# We need a single line "reason"[/comment]
|
|
dialog.textinput -d="Working !" (Away,<center>Please enter the <h1>away message</h1></center>,"Ok","Cancel")
|
|
{
|
|
switch($0)
|
|
{
|
|
case(0):
|
|
away $1-
|
|
break;
|
|
default:
|
|
# Cancelled
|
|
break;
|
|
}
|
|
}
|
|
[/example]
|
|
*/
|
|
|
|
static bool dialog_kvs_cmd_textinput(KviKvsModuleCallbackCommandCall * c)
|
|
{
|
|
TQString szCaption,szInfoText,szIcon,szDefaultText,szButton0,szButton1,szButton2;
|
|
KviKvsVariantList params;
|
|
|
|
KVSM_PARAMETERS_BEGIN(c)
|
|
KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
|
|
KVSM_PARAMETER("info_text",KVS_PT_STRING,0,szInfoText)
|
|
KVSM_PARAMETER("button0",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton0)
|
|
KVSM_PARAMETER("button1",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton1)
|
|
KVSM_PARAMETER("button2",KVS_PT_STRING,KVS_PF_OPTIONAL,szButton2)
|
|
KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
|
|
KVSM_PARAMETERS_END(c)
|
|
|
|
TQString szCmd = c->callback()->code();
|
|
|
|
c->switches()->getAsStringIfExisting('i',"icon",szIcon);
|
|
c->switches()->getAsStringIfExisting('d',"default",szDefaultText);
|
|
bool modal;
|
|
if(c->hasSwitch('b',"modal")) modal=true;
|
|
else modal=false;
|
|
KviKvsCallbackTextInput * box = new KviKvsCallbackTextInput(
|
|
szCaption,szInfoText,szDefaultText,szIcon,c->switches()->find('m',"multiline"),
|
|
szButton0,szButton1,szButton2,szCmd,¶ms,c->window(),modal);
|
|
box->show();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// New KVS
|
|
KviKvsCallbackFileDialog::KviKvsCallbackFileDialog(
|
|
const TQString &szCaption,
|
|
const TQString &szInitialSelection,
|
|
const TQString &szFilter,
|
|
const TQString &szCode,
|
|
KviKvsVariantList * pMagicParams,
|
|
KviWindow * pWindow,bool modal)
|
|
: KviFileDialog(szInitialSelection,szFilter,0,0,modal), KviKvsCallbackObject("dialog.file",pWindow,szCode,pMagicParams,0)
|
|
{
|
|
g_pDialogModuleDialogList->append(this);
|
|
setCaption(szCaption);
|
|
}
|
|
|
|
KviKvsCallbackFileDialog::~KviKvsCallbackFileDialog()
|
|
{
|
|
g_pDialogModuleDialogList->removeRef(this);
|
|
}
|
|
|
|
void KviKvsCallbackFileDialog::done(int code)
|
|
{
|
|
KviFileDialog::done(code);
|
|
KviKvsVariantList params;
|
|
|
|
if(code == TQDialog::Accepted)
|
|
{
|
|
#ifdef COMPILE_TDE_SUPPORT
|
|
if(mode() == KFile::ExistingOnly)
|
|
#else
|
|
if(mode() == TQFileDialog::ExistingFiles)
|
|
#endif
|
|
{
|
|
KviKvsArray * a = new KviKvsArray();
|
|
TQStringList sl = selectedFiles();
|
|
int idx = 0;
|
|
for(TQStringList::Iterator it = sl.begin();it != sl.end();++it)
|
|
{
|
|
a->set(idx,new KviKvsVariant(*it));
|
|
idx++;
|
|
}
|
|
params.append(new KviKvsVariant(a));
|
|
} else {
|
|
params.append(new KviKvsVariant(selectedFile()));
|
|
}
|
|
} else {
|
|
params.append(new KviKvsVariant(TQString("")));
|
|
}
|
|
|
|
hide(); // ensure we're hidden
|
|
|
|
// ugly workaround for the TQt filedialog "destructive accept() before this reference" bug
|
|
// we can't delete ourselves in this moment.... :(((
|
|
// ...so skip out of this call stack and ask KviApp to destroy us just
|
|
// when the control returns to the main loop.
|
|
// If the module is unloaded then , KviApp will notice it and will NOT delete the dialog
|
|
g_pApp->collectGarbage(TQT_TQOBJECT(this));
|
|
|
|
// calling dialog.unload here WILL lead to a sigsegv (this is SURE
|
|
// with a lot of qt versions that have the ugly file dialog "accept before this reference" bug)
|
|
// to avoid it, we can execute the callback triggered by a timer...
|
|
// ... umpf ...
|
|
execute(¶ms);
|
|
}
|
|
|
|
/*
|
|
@doc: dialog.file
|
|
@type:
|
|
command
|
|
@title:
|
|
dialog.file
|
|
@short:
|
|
Shows a file dialog
|
|
@syntax:
|
|
dialog.file [-b] (<mode>,<caption>[,<initial_selection[,<file_filter>[,<magic1>[,<magic2>[...]]]]]])
|
|
{
|
|
<callback_command>
|
|
}
|
|
@description:
|
|
Shows an openfile dialog box with the specified <caption> , <initial_selection> , and <file_filter>.[br]
|
|
<mode> can be "open" , "openm" , "save" or "dir":[br]
|
|
"open" causes the dialog to return an existing file[br]
|
|
"openm" is similar to open but allows returning multiple files as a comma separated list[br]
|
|
"save" causes the dialog to return any file name (no overwrite confirmation is built in the dialog!)[br]
|
|
"dir" causes the dialog to return an existing directory name[br]
|
|
<mode> defaults to "open".[br]
|
|
<caption> is a text string that will appear in the caption of the dialog box.[br]
|
|
<initial_selection> can be a directory or filename that will be initially selected in the dialog.[br]
|
|
Only files matching <file_filter> are selectable. If filter is an empty string, all files are selectable.[br]
|
|
In the filter string multiple filters can be specified separated by either two semicolons next to each
|
|
other or separated by newlines. To add two filters, one to show all C++ files and one to show all
|
|
header files, the filter string could look like "C++ Files (*.cpp *.cc *.C *.cxx *.c++);;Header Files (*.h *.hxx *.h++)"
|
|
<magic1>,<magic2>... are the magic parameters: evaluated at dialog.message call time and passed
|
|
to the <callback_command> as positional parameters.[br]
|
|
If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
|
|
it will appear above its parent widget and block its input until it's closed.[br]
|
|
Once the dialog has been shown , the user will select an EXISTING file and click either
|
|
Ok or Cancel. At this point the dialog is hidden and the <callback_command> is executed passing the selected file(s) as $0
|
|
and the magic parameters as positional parameters $1 , $2 , $3....[br]
|
|
If the user clicks "Cancel" or does not select any file the positional parameter $0 will be empty.[br]
|
|
@examples:
|
|
[example]
|
|
dialog.file(open,Choose an audio file,/home/pragma/TheAudio.au,"Audio files (*.au *.wav *.snd)")
|
|
{
|
|
if("$0" != "")run play $0
|
|
}
|
|
[/example]
|
|
*/
|
|
|
|
//#warning "Examples for these dialogs!"
|
|
|
|
|
|
static bool dialog_kvs_cmd_file(KviKvsModuleCallbackCommandCall * c)
|
|
{
|
|
TQString szMode,szCaption,szInitialSelection,szFilter;
|
|
KviKvsVariantList params;
|
|
|
|
KVSM_PARAMETERS_BEGIN(c)
|
|
KVSM_PARAMETER("mode",KVS_PT_STRING,0,szMode)
|
|
KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
|
|
KVSM_PARAMETER("initial_selection",KVS_PT_STRING,KVS_PF_OPTIONAL,szInitialSelection)
|
|
KVSM_PARAMETER("filter",KVS_PT_STRING,KVS_PF_OPTIONAL,szFilter)
|
|
KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
|
|
KVSM_PARAMETERS_END(c)
|
|
bool modal;
|
|
if(c->hasSwitch('b',"modal")) modal=true;
|
|
else modal=false;
|
|
TQString szCmd = c->callback()->code();
|
|
|
|
KviKvsCallbackFileDialog * box = new KviKvsCallbackFileDialog(szCaption,szInitialSelection,szFilter,szCmd,¶ms,c->window(),modal);
|
|
|
|
KviFileDialog::FileMode md = KviFileDialog::ExistingFile;
|
|
|
|
if(KviTQString::equalCI(szMode,"openm"))md = KviFileDialog::ExistingFiles;
|
|
else if(KviTQString::equalCI(szMode,"save"))md = KviFileDialog::AnyFile;
|
|
else if(KviTQString::equalCI(szMode,"dir"))md = KviFileDialog::DirectoryOnly;
|
|
|
|
box->setFileMode(md);
|
|
|
|
box->show();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// New KVS
|
|
KviKvsCallbackImageDialog::KviKvsCallbackImageDialog(
|
|
const TQString &szCaption,
|
|
const TQString &szInitialSelection,
|
|
int iType,
|
|
int iMaxSize,
|
|
const TQString &szCode,
|
|
KviKvsVariantList * pMagicParams,
|
|
KviWindow * pWindow,bool modal)
|
|
: KviImageDialog(0,szCaption,iType,0,szInitialSelection,iMaxSize,modal), KviKvsCallbackObject("dialog.image",pWindow,szCode,pMagicParams,0)
|
|
{
|
|
g_pDialogModuleDialogList->append(this);
|
|
}
|
|
|
|
KviKvsCallbackImageDialog::~KviKvsCallbackImageDialog()
|
|
{
|
|
g_pDialogModuleDialogList->removeRef(this);
|
|
}
|
|
|
|
void KviKvsCallbackImageDialog::done(int code)
|
|
{
|
|
KviImageDialog::done(code);
|
|
KviKvsVariantList params;
|
|
|
|
if(code == TQDialog::Accepted)
|
|
{
|
|
params.append(new KviKvsVariant(selectedImage()));
|
|
} else {
|
|
params.append(new KviKvsVariant(TQString("")));
|
|
}
|
|
|
|
hide(); // ensure we're hidden
|
|
|
|
// ugly workaround for the TQt filedialog "destructive accept() before this reference" bug
|
|
// we can't delete ourselves in this moment.... :(((
|
|
// ...so skip out of this call stack and ask KviApp to destroy us just
|
|
// when the control returns to the main loop.
|
|
// If the module is unloaded then , KviApp will notice it and will NOT delete the dialog
|
|
g_pApp->collectGarbage(TQT_TQOBJECT(this));
|
|
|
|
// calling dialog.unload here WILL lead to a sigsegv (this is SURE
|
|
// with a lot of qt versions that have the ugly file dialog "accept before this reference" bug)
|
|
// to avoid it, we can execute the callback triggered by a timer...
|
|
// ... umpf ...
|
|
execute(¶ms);
|
|
}
|
|
|
|
|
|
/*
|
|
@doc: dialog.image
|
|
@type:
|
|
command
|
|
@title:
|
|
dialog.image
|
|
@short:
|
|
Shows a image dialog
|
|
@syntax:
|
|
dialog.image [-b] (<type>,<caption>,<initial_directory>,[<maxsize>,[,<magic1>[,<magic2>[...]]]]]])
|
|
{
|
|
<callback_command>
|
|
}
|
|
@description:
|
|
Shows a dialog that allows selecting an [doc:image_id]image_id[doc].
|
|
The <type> parameter must be a combination of the following flags:<br>
|
|
's' : allow selecting from the KVIrc builtin small icons<br>
|
|
'f' : allow browsing the local directories<br>
|
|
'a' : all of the above<br>
|
|
The default for <type> is 'a'.<br>
|
|
<caption> is the caption string for the dialog.<br>
|
|
<initial_directory> makes sense only if 'f' is specified (if <initial_directory> is empty
|
|
then the last path used by the image dialog will be used).<br>
|
|
<maxsize> is the maximum size of the images for that the preview will be generated:
|
|
this is 256000 bytes by default (if unspecified). Don't make it a lot bigger : it can take a lot to make
|
|
the thumbnails for bigger images (and it can eat a considerable amount of memory).<br>
|
|
<magic1>,<magic2>... are the magic parameters: evaluated at dialog.image call time and passed
|
|
to the <callback_command> as positional parameters.[br]
|
|
If the -b or -modal switch is specified the dialog will have non-blocking modal behaviour:
|
|
it will appear above its parent widget and block its input until it's closed.[br]
|
|
Once the dialog has been shown , the user will select an EXISTING file and click either
|
|
Ok or Cancel. At this point the dialog is hidden and the <callback_command> is executed passing the selected file(s) as $0
|
|
and the magic parameters as positional parameters $1 , $2 , $3....[br]
|
|
If the user clicks "Cancel" or does not select any image the positional parameter $0 will be empty.[br]
|
|
@examples:
|
|
[example]
|
|
dialog.image(f,Choose an image file,/home/pragma/,"256000")
|
|
{
|
|
if("$0" != "")run kview $0
|
|
}
|
|
[/example]
|
|
*/
|
|
|
|
//#warning "Examples for these dialogs!"
|
|
|
|
|
|
static bool dialog_kvs_cmd_image(KviKvsModuleCallbackCommandCall * c)
|
|
{
|
|
TQString szType,szCaption,szInitialSelection;
|
|
kvs_uint_t iMaxSize;
|
|
KviKvsVariantList params;
|
|
|
|
KVSM_PARAMETERS_BEGIN(c)
|
|
KVSM_PARAMETER("mode",KVS_PT_STRING,0,szType)
|
|
KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
|
|
KVSM_PARAMETER("initial_directory",KVS_PT_STRING,0,szInitialSelection)
|
|
KVSM_PARAMETER("maxsize",KVS_PT_UINT,KVS_PF_OPTIONAL,iMaxSize)
|
|
KVSM_PARAMETER("magic",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,params)
|
|
KVSM_PARAMETERS_END(c)
|
|
bool modal;
|
|
if(c->hasSwitch('b',"modal")) modal=true;
|
|
else modal=false;
|
|
TQString szCmd = c->callback()->code();
|
|
|
|
int iType = 0;
|
|
|
|
if(szType.contains('s'))iType |= KID_TYPE_BUILTIN_IMAGES_SMALL;
|
|
if(szType.contains('f'))iType |= KID_TYPE_FULL_PATH;
|
|
if(szType.isEmpty())iType = KID_TYPE_ALL;
|
|
|
|
if(iMaxSize < 1)iMaxSize = 256000;
|
|
|
|
KviKvsCallbackImageDialog * box = new KviKvsCallbackImageDialog(szCaption,szInitialSelection,iType,iMaxSize,szCmd,¶ms,c->window(),modal);
|
|
|
|
box->show();
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
@doc: dialog.yesno
|
|
@type:
|
|
function
|
|
@title:
|
|
$dialog.yesno
|
|
@short:
|
|
Shows a simple yes/no dialog
|
|
@syntax:
|
|
$dialog.yesno(<caption:string>,<szText:string>)
|
|
@description:
|
|
Shows a simple yes/no dialog. Returns 1 if user clicks "Yes" and 0 if (s)he clicks "No".
|
|
Please note that this dialog is BLOCKING: it blocks execution of the script
|
|
until the user has selected either YES or NO.
|
|
@examples:
|
|
@seealso:
|
|
*/
|
|
|
|
static bool dialog_kvs_fnc_yesno(KviKvsModuleFunctionCall * c)
|
|
{
|
|
TQString szCaption;
|
|
TQString szText;
|
|
KVSM_PARAMETERS_BEGIN(c)
|
|
KVSM_PARAMETER("caption",KVS_PT_STRING,0,szCaption)
|
|
KVSM_PARAMETER("text",KVS_PT_STRING,0,szText)
|
|
KVSM_PARAMETERS_END(c)
|
|
|
|
c->enterBlockingSection();
|
|
bool yes=KviMessageBox::yesNo(szCaption,szText); // this will happily crash on quit ?
|
|
if(!c->leaveBlockingSection())return true; // just die
|
|
c->returnValue()->setBoolean(yes);
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
|
|
static int g_iLocalEventLoops = 0;
|
|
|
|
static bool dialog_module_cmd_unload(KviModule *m,KviCommand *c)
|
|
{
|
|
// We use local loops in this module: we must FORBID explicit unloading of the
|
|
// module while local even loops are running
|
|
ENTER_STACK_FRAME(c,"dialog_module_cmd_unload");
|
|
c->warning(__tr("The dialog module can't be explicitly unloaded: a modal dialog is currently open"));
|
|
return c->leaveStackFrame();
|
|
}
|
|
|
|
static void dialog_module_entering_local_loop(KviModule * m)
|
|
{
|
|
// Replace unload
|
|
g_iLocalEventLoops++;
|
|
if(g_iLocalEventLoops == 1)m->registerCommand("unload",dialog_module_cmd_unload);
|
|
}
|
|
|
|
static void dialog_module_exiting_local_loop(KviModule * m)
|
|
{
|
|
g_pModuleManager->registerDefaultCommands(m);
|
|
g_iLocalEventLoops--;
|
|
}
|
|
|
|
static bool dialog_module_fnc_textline(KviModule *m,KviCommand *c,KviParameterList * parms,KviStr &buffer)
|
|
{
|
|
ENTER_STACK_FRAME(c,"dialog_module_fnc_textline");
|
|
|
|
KviStr caption = parms->safeFirstParam();
|
|
KviStr info = parms->safeNextParam();
|
|
KviStr initial = parms->safeNextParam();
|
|
|
|
dialog_module_entering_local_loop(m);
|
|
TQMessageBox::information(0,caption.ptr(),info.ptr(),TQMessageBox::Ok);
|
|
dialog_module_exiting_local_loop(m);
|
|
|
|
// It might be that the current window is no longer available!!!
|
|
|
|
return c->leaveStackFrame();
|
|
}
|
|
|
|
*/
|
|
|
|
/*
|
|
@doc: noblockingdialogs
|
|
@type:
|
|
generic
|
|
@title:
|
|
Why there are no blocking dialogs in KVIrc ?
|
|
@short:
|
|
Tecnical answer
|
|
@description:
|
|
Why there are no blocking dialogs in KVIrc ?[br]
|
|
The answer is simple: because they're more confusing and tricky than it seems.[br]
|
|
Blocking the entire program control flow while showing a dialog is
|
|
rather a bad idea since we have to deal with external entities (servers and other users)
|
|
that are NOT blocked. This means that the blocking dialogs must block only the
|
|
script control-flow but let the rest of the application running.
|
|
Such blocking dialogs actually seem to simplify scripting because
|
|
the programmer "feels" that the control is always left in the script snippet that he is writing.
|
|
This is actually confusing: the control IS in the script snippet but while the dialog
|
|
is open the whole world can change: you can return from the dialog call and discover
|
|
that the server connection no longer exists and the application is about to quit.[br]
|
|
This may happen even with non-blocking dialogs ,but in non-blocking mode you have
|
|
a way to handle this event. Consider the following snippet of code:[br]
|
|
[example]
|
|
echo My name is $?
|
|
[/example]
|
|
Where $? stands for a blocking input dialog that asks the user for some text.[br]
|
|
When the input dialog returns the window that the echo was directed to no longer
|
|
exists and you have no way to stop the echo! (Well...I could add extra code
|
|
in the executable to handle all these situations but that would be really too expensive).[br]
|
|
With object scripting this is actually dangerous: you might use a blocking dialog
|
|
in an object signal handler and when returning discover that this object has been deleted!
|
|
(The example refers to a simple object , but think about a complex hierarchy of objects
|
|
where one random gets deleted...).[br]
|
|
This is why the dialogs in KVIrc are non-blocking :)[br]
|
|
That's REAL programming.
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool dialog_module_init(KviModule * m)
|
|
{
|
|
g_pDialogModuleDialogList = new KviPointerList<TQWidget>;
|
|
g_pDialogModuleDialogList->setAutoDelete(false);
|
|
|
|
KVSM_REGISTER_CALLBACK_COMMAND(m,"message",dialog_kvs_cmd_message);
|
|
KVSM_REGISTER_CALLBACK_COMMAND(m,"textinput",dialog_kvs_cmd_textinput);
|
|
KVSM_REGISTER_CALLBACK_COMMAND(m,"file",dialog_kvs_cmd_file);
|
|
KVSM_REGISTER_CALLBACK_COMMAND(m,"image",dialog_kvs_cmd_image);
|
|
|
|
KVSM_REGISTER_FUNCTION(m,"yesno",dialog_kvs_fnc_yesno);
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool dialog_module_cleanup(KviModule *m)
|
|
{
|
|
// Here we get a tragedy if g_iLocalEventLoops > 0!
|
|
while(g_pDialogModuleDialogList->first())delete g_pDialogModuleDialogList->first();
|
|
delete g_pDialogModuleDialogList;
|
|
g_pDialogModuleDialogList = 0;
|
|
return true;
|
|
}
|
|
|
|
static bool dialog_module_can_unload(KviModule *m)
|
|
{
|
|
return g_pDialogModuleDialogList->isEmpty();
|
|
}
|
|
|
|
|
|
KVIRC_MODULE(
|
|
"KVIrc script dialogs",
|
|
"1.0.0",
|
|
"Szymon Stefanek <pragma at kvirc dot net>" ,
|
|
"Adds the /dialog.* commands functionality\n",
|
|
dialog_module_init ,
|
|
dialog_module_can_unload,
|
|
0,
|
|
dialog_module_cleanup
|
|
)
|
|
|
|
#include "libkvidialog.moc"
|