aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Fabio Bas2010-08-17 18:05:36 +0000
committerGravatar Fabio Bas2010-08-17 18:05:36 +0000
commit3720126545edcf4a976568f2d740ab5d8d86940e (patch)
treea9a9685f97f5f1f1ff0290c28eea3319b38bb7e3
parentFix an undetected syntax error in tmphighlight. (diff)
downloadKVIrc-3720126545edcf4a976568f2d740ab5d8d86940e.tar.gz
KVIrc-3720126545edcf4a976568f2d740ab5d8d86940e.tar.bz2
KVIrc-3720126545edcf4a976568f2d740ab5d8d86940e.zip
Reworked the way kvirc parses channel modes;
addded to the mode editor the ability to set/unset additional modes with parameters and added a throttle to handle correctly multiple mode changes in a single row still wip: modewidget (still lacks the ability to show the additional modes), encoding stuff git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@4891 17fca916-40b9-46aa-a4ea-0a15b648b75c
-rw-r--r--src/kvirc/kernel/kvi_irccontext.cpp2
-rw-r--r--src/kvirc/kernel/kvi_ircurl.cpp5
-rw-r--r--src/kvirc/sparser/kvi_sp_literal.cpp21
-rw-r--r--src/kvirc/ui/kvi_channel.cpp62
-rw-r--r--src/kvirc/ui/kvi_channel.h45
-rw-r--r--src/kvirc/ui/kvi_console.cpp5
-rw-r--r--src/kvirc/ui/kvi_modeeditor.cpp448
-rw-r--r--src/kvirc/ui/kvi_modeeditor.h33
-rw-r--r--src/kvirc/ui/kvi_modew.cpp8
-rw-r--r--src/modules/chan/libkvichan.cpp16
10 files changed, 368 insertions, 277 deletions
diff --git a/src/kvirc/kernel/kvi_irccontext.cpp b/src/kvirc/kernel/kvi_irccontext.cpp
index 436e6eb24..fe471a9b8 100644
--- a/src/kvirc/kernel/kvi_irccontext.cpp
+++ b/src/kvirc/kernel/kvi_irccontext.cpp
@@ -744,7 +744,7 @@ void KviIrcContext::connectionTerminated()
// first only chans without key, in groups of 4
for(c = connection()->channelList()->first(); c; c = connection()->channelList()->next())
{
- szCurPass = c->channelKey();
+ szCurPass = c->hasChannelMode('k') ? c->channelModeParam('k') : "";
szCurChan = c->windowName();
if(szCurPass.isEmpty())
{
diff --git a/src/kvirc/kernel/kvi_ircurl.cpp b/src/kvirc/kernel/kvi_ircurl.cpp
index 2018af1be..6ec8bfb16 100644
--- a/src/kvirc/kernel/kvi_ircurl.cpp
+++ b/src/kvirc/kernel/kvi_ircurl.cpp
@@ -330,9 +330,10 @@ int KviIrcUrl::run(const QString& text,int contextSpec,KviConsole* pConsole)
for(KviChannel * c = pConsole->connection()->channelList()->first();c;c = pConsole->connection()->channelList()->next())
{
tmp=c->target();
- if(c->hasChannelKey()) {
+ if(c->hasChannelMode('k'))
+ {
tmp.append("?");
- tmp.append(c->channelKey());
+ tmp.append(c->channelModeParam('k'));
}
if(!parts.chanList.removeAll(tmp))
{
diff --git a/src/kvirc/sparser/kvi_sp_literal.cpp b/src/kvirc/sparser/kvi_sp_literal.cpp
index 16b879d96..fbe95e609 100644
--- a/src/kvirc/sparser/kvi_sp_literal.cpp
+++ b/src/kvirc/sparser/kvi_sp_literal.cpp
@@ -573,7 +573,7 @@ void KviServerParser::parseLiteralKick(KviIrcMessage *msg)
msg->setHaltOutput();
if(!KVI_OPTION_STRING(KviOption_stringOnMeKickedSound).isEmpty()) KviKvsScript::run("snd.play $0",0,new KviKvsVariantList(new KviKvsVariant(KVI_OPTION_STRING(KviOption_stringOnMeKickedSound))));
- QString szPass = chan->channelKey();
+ QString szPass = chan->hasChannelMode('k') ? chan->channelModeParam('k') : "";
if(KVI_OPTION_BOOL(KviOption_boolKeepChannelOpenOnKick))
{
@@ -1786,7 +1786,7 @@ void KviServerParser::parseChannelMode(const QString &szNick,const QString &szUs
case 'k':
if(bSet)aParam = msg->safeParam(curParam++);
else aParam = "";
- chan->setChannelKey(aParam.toUtf8().data());
+ chan->setChannelModeWithParam('k',aParam);
if(bSet) {
if(KVS_TRIGGER_EVENT_4_HALTED(KviEvent_OnKeySet,chan,szNick,szUser,szHost,aParam))
@@ -1810,7 +1810,7 @@ void KviServerParser::parseChannelMode(const QString &szNick,const QString &szUs
case 'l':
if(bSet)aParam = msg->safeParam(curParam++);
else aParam = "";
- chan->setChannelLimit(aParam.toUtf8().data());
+ chan->setChannelModeWithParam('l',aParam);
if(bSet) {
if(KVS_TRIGGER_EVENT_4_HALTED(KviEvent_OnLimitSet,chan,szNick,szUser,szHost,aParam))
@@ -1969,7 +1969,7 @@ void KviServerParser::parseChannelMode(const QString &szNick,const QString &szUs
default:
// check if the mode "eats" a parameter
if(msg->connection()->serverInfo()->supportedParameterModes().contains(*aux)
- || (msg->connection()->serverInfo()->supportedParameterWhenSetModes().contains(*aux) && bSet)
+ || (msg->connection()->serverInfo()->supportedParameterWhenSetModes().contains(*aux) && bSet)
|| msg->connection()->serverInfo()->supportedListModes().contains(*aux))
{
/*
@@ -1978,7 +1978,8 @@ void KviServerParser::parseChannelMode(const QString &szNick,const QString &szUs
* Channel join throttling like "4:5", see bug #731
*/
aParam = msg->connection()->decodeText(msg->safeParam(curParam++));
- chan->setChannelMode(*aux,bSet);
+ chan->setChannelModeWithParam(*aux,aParam);
+
if(!(msg->haltOutput() || (KVI_OPTION_BOOL(KviOption_boolShowCompactModeChanges) && bIsMultiMode)))
{
if(aParam.isEmpty())
@@ -1995,7 +1996,15 @@ void KviServerParser::parseChannelMode(const QString &szNick,const QString &szUs
}
}
} else {
- chan->setChannelMode(*aux,bSet);
+ if(msg->connection()->serverInfo()->supportedParameterWhenSetModes().contains(*aux))
+ {
+ // a mode with parameter that does not receive one when unset
+ QString szEmptyParam("");
+ chan->setChannelModeWithParam(*aux,szEmptyParam);
+ } else {
+ chan->setChannelMode(*aux,bSet);
+ }
+
if(!(msg->haltOutput() || (KVI_OPTION_BOOL(KviOption_boolShowCompactModeChanges) && bIsMultiMode)))
{
chan->output(KVI_OUT_CHANMODE,
diff --git a/src/kvirc/ui/kvi_channel.cpp b/src/kvirc/ui/kvi_channel.cpp
index 757708bfc..86bd4e71c 100644
--- a/src/kvirc/ui/kvi_channel.cpp
+++ b/src/kvirc/ui/kvi_channel.cpp
@@ -447,8 +447,8 @@ void KviChannel::toggleModeEditor()
m_pModeEditorButton->setChecked(false);
resizeEvent(0);
} else {
- m_pModeEditor = new KviModeEditor(m_pSplitter,m_pModeEditorButton,"mode_editor",console(),m_szChannelMode,m_szChannelKey,m_szChannelLimit);
- connect(m_pModeEditor,SIGNAL(setMode(const char *)),this,SLOT(setMode(const char *)));
+ m_pModeEditor = new KviModeEditor(m_pSplitter,m_pModeEditorButton,"mode_editor",this);
+ connect(m_pModeEditor,SIGNAL(setMode(QString &)),this,SLOT(setMode(QString &)));
connect(m_pModeEditor,SIGNAL(done()),this,SLOT(modeSelectorDone()));
m_pModeEditor->show();
//setFocusHandlerNoClass(m_pInput,m_pModeEditor,"QLineEdit");
@@ -463,13 +463,16 @@ void KviChannel::modeSelectorDone()
toggleModeEditor();
}
-void KviChannel::setMode(const char * mode)
+void KviChannel::setMode(QString & szMode)
{
if(!connection())
return;
- QByteArray tmp = connection()->encodeText(m_szName);
- connection()->sendFmtData("MODE %s %s",tmp.data(),mode);
+ QByteArray channelName = connection()->encodeText(m_szName);
+ //FIXME is it right to assume this encoding?
+ QByteArray modes = connection()->encodeText(szMode);
+
+ connection()->sendFmtData("MODE %s %s",channelName.data(),modes.data());
}
void KviChannel::toggleBanEditor()
@@ -627,25 +630,19 @@ void KviChannel::setChannelMode(char mode, bool bAdd)
m_szChannelMode.append(mode);
} else {
if(m_szChannelMode.contains(mode))
- {
m_szChannelMode.replace(mode,"");
- }
}
updateModeLabel();
updateCaption();
}
}
-void KviChannel::setChannelKey(const char * key)
-{
- m_szChannelKey = key;
- updateModeLabel();
- updateCaption();
-}
-
-void KviChannel::setChannelLimit(const char * limit)
+void KviChannel::setChannelModeWithParam(char cMode, QString & szParam)
{
- m_szChannelLimit = limit;
+ if(szParam.isEmpty())
+ m_szChannelParameterModes.remove(cMode);
+ else
+ m_szChannelParameterModes.insert(cMode,szParam);
updateModeLabel();
updateCaption();
}
@@ -666,10 +663,10 @@ void KviChannel::removeHighlightedUser(const QString & szNick)
void KviChannel::getChannelModeString(QString & szBuffer)
{
szBuffer = m_szChannelMode;
- if(!m_szChannelKey.isEmpty())
- szBuffer.append('k');
- if(!m_szChannelLimit.isEmpty())
- szBuffer.append('l');
+ //add modes that use a parameter
+ QList<char> keys = m_szChannelParameterModes.keys();
+ for(int i=0; i<keys.count(); i++)
+ szBuffer.append(keys.at(i));
}
void KviChannel::setDeadChan()
@@ -699,8 +696,7 @@ void KviChannel::setDeadChan()
m_uActionHistoryHotActionCount = 0;
m_szChannelMode = "";
- m_szChannelKey = "";
- m_szChannelLimit = "";
+ m_szChannelParameterModes.clear();
// this should be moved to irc context!
if(connection())
@@ -1683,9 +1679,7 @@ void KviChannel::internalMask(const QString & szMask, bool bAdd, const QString &
void KviChannel::updateModeLabel()
{
- QString szTmp = m_szChannelMode;
QString szTip = __tr2qs("<b>Channel mode:</b>");
- //const char * aux = m_szChannelMode.toUtf8().data(); leaks memory and will not work with getChannelModeDescription() (can channel modes be multibyte ?)
KviStr szMod = m_szChannelMode;
const char * pcAux = szMod.ptr();
while(*pcAux)
@@ -1694,23 +1688,11 @@ void KviChannel::updateModeLabel()
++pcAux;
}
- if(!m_szChannelKey.isEmpty())
- {
- if(!szTmp.isEmpty())
- szTmp.append(' ');
-
- KviQString::appendFormatted(szTmp,"k:%s",m_szChannelKey.toUtf8().data());
- KviQString::appendFormatted(szTip,__tr2qs("<br><b>Key:</b> %s"),m_szChannelKey.toUtf8().data());
- }
+ if(hasChannelMode('k'))
+ szTip.append(__tr2qs("<br><b>Key:</b> %1").arg(channelModeParam('k')));
- if(!m_szChannelLimit.isEmpty())
- {
- if(!szTmp.isEmpty())
- szTmp.append(' ');
-
- KviQString::appendFormatted(szTmp,"l:%s",m_szChannelLimit.toUtf8().data());
- KviQString::appendFormatted(szTip,__tr2qs("<br><b>Limit:</b> %s"),m_szChannelLimit.toUtf8().data());
- }
+ if(hasChannelMode('l'))
+ szTip.append(__tr2qs("<br><b>Limit:</b> %1").arg(channelModeParam('k')));
m_pModeWidget->refreshModes();
KviTalToolTip::remove(m_pModeWidget);
diff --git a/src/kvirc/ui/kvi_channel.h b/src/kvirc/ui/kvi_channel.h
index 8434b85ed..35aec516f 100644
--- a/src/kvirc/ui/kvi_channel.h
+++ b/src/kvirc/ui/kvi_channel.h
@@ -201,8 +201,7 @@ protected:
KviModeWidget * m_pModeWidget;
int m_iStateFlags;
QString m_szChannelMode;
- QString m_szChannelKey;
- QString m_szChannelLimit;
+ QMap<char, QString> m_szChannelParameterModes;
KviPointerList<KviMaskEntry> * m_pBanList;
KviPointerList<KviMaskEntry> * m_pBanExceptionList;
KviPointerList<KviMaskEntry> * m_pInviteList;
@@ -923,42 +922,26 @@ public:
void getChannelModeString(QString & szBuffer);
/**
- * \brief Sets the limit for the channel
- * \param pcLimit The limit of the channel
+ * \brief Sets a channel mode with a parameter; an empty parameter unsets the mode
+ * \param char The mode
+ * \param QString & The parameter for the mode
* \return void
*/
- void setChannelLimit(const char * pcLimit);
+ void setChannelModeWithParam(char cMode, QString & szParam);
/**
- * \brief Returns true if the channel has a limit set
+ * \brief Returns true if the channel has a mode set
+ * \param char The mode
* \return bool
*/
- bool hasChannelLimit(){ return !m_szChannelLimit.isEmpty(); };
+ bool hasChannelMode(char cMode) { return m_szChannelParameterModes.contains(cMode); };
/**
- * \brief Returns the limit number
- * \return QString &
- */
- QString & channelLimit(){ return m_szChannelLimit; };
-
- /**
- * \brief Sets the key for the channel
- * \param pcKey The key of the channel
- * \return void
- */
- void setChannelKey(const char * pcKey);
-
- /**
- * \brief Returns true if the channel has a key set
- * \return bool
- */
- bool hasChannelKey() { return !m_szChannelKey.isEmpty(); };
-
- /**
- * \brief Returns the channel key
- * \return QString &
+ * \brief Returns the value for a channel mode
+ * \param char The mode
+ * \return QString
*/
- QString & channelKey(){ return m_szChannelKey; };
+ QString channelModeParam(char cMode) const { return m_szChannelParameterModes.value(cMode); };
/**
* \brief Adds a user to the highlight list
@@ -1201,10 +1184,10 @@ private slots:
/**
* \brief Called when we select the modes from the mode editor
- * \param pcMode The modes selected
+ * \param QString The modes selected, including any plus/minus sign and parameters
* \return void
*/
- void setMode(const char * pcMode);
+ void setMode(QString & szMode);
/**
* \brief Called when we right-click the irc view.
diff --git a/src/kvirc/ui/kvi_console.cpp b/src/kvirc/ui/kvi_console.cpp
index 08b490f38..b9fa01a64 100644
--- a/src/kvirc/ui/kvi_console.cpp
+++ b/src/kvirc/ui/kvi_console.cpp
@@ -475,9 +475,10 @@ void KviConsole::updateUri()
for(KviChannel * c = connection()->channelList()->first();c;c = connection()->channelList()->next())
{
uri.append(c->target());
- if(c->hasChannelKey()) {
+ if(c->hasChannelMode('k'))
+ {
uri.append("?");
- uri.append(c->channelKey());
+ uri.append(c->channelModeParam('k'));
}
if(c!=last) uri.append(",");
}
diff --git a/src/kvirc/ui/kvi_modeeditor.cpp b/src/kvirc/ui/kvi_modeeditor.cpp
index b9a32a479..15ba968a2 100644
--- a/src/kvirc/ui/kvi_modeeditor.cpp
+++ b/src/kvirc/ui/kvi_modeeditor.cpp
@@ -26,7 +26,6 @@
#include "kvi_iconmanager.h"
#include "kvi_locale.h"
#include "kvi_qstring.h"
-#include "kvi_console.h"
#include "kvi_ircconnection.h"
#include "kvi_ircconnectionserverinfo.h"
#include "kvi_channel.h"
@@ -36,27 +35,28 @@
#include <QScrollArea>
#include <QLayout>
#include <QLabel>
+#include <QCheckBox>
+#include <QLineEdit>
+#include <QPushButton>
-KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char *,KviConsole * c,const QString &mode,const QString &key,const QString &limit)
+
+KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char * name,KviChannel * pChan)
: KviWindowToolWidget(par,button)
{
- m_szMode = mode;
- m_szKey = key;
- m_szLimit = limit;
- bool isEnabled = true;
-
- QObject * w = parent();
- while(w)
+ setObjectName(name);
+ m_pChannel = pChan;
+ bool bIsEnabled = true;
+ if(pChan)
{
- if(w->inherits("KviChannel"))
- {
- KviChannel *chan = ((KviChannel *)w);
- if(!( chan->isMeHalfOp() || chan->isMeOp() || chan->isMeChanOwner() || chan->isMeChanAdmin() || chan->connection()->userInfo()->hasUserMode('o') || chan->connection()->userInfo()->hasUserMode('O') ) ) isEnabled = false;
- break;
- }
- w = w->parent();
+ if(!( pChan->isMeHalfOp() ||
+ pChan->isMeOp() ||
+ pChan->isMeChanOwner() ||
+ pChan->isMeChanAdmin() ||
+ pChan->connection()->userInfo()->hasUserMode('o') ||
+ pChan->connection()->userInfo()->hasUserMode('O')
+ ) ) bIsEnabled = false;
}
-
+
QGridLayout *pMasterLayout = new QGridLayout(this);
setFocusPolicy(Qt::ClickFocus);
@@ -66,15 +66,13 @@ KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const
pMasterLayout->addWidget(pScrollArea,0,0);
pMasterLayout->setRowStretch(1,1);
- QPushButton * b;
- if(isEnabled) b = new QPushButton(__tr2qs("&Apply"),this);
- else b = new QPushButton(__tr2qs("Close"),this);
-
+
+ QPushButton * b = new QPushButton(bIsEnabled ? __tr2qs("&Apply") : __tr2qs("Close"), this);
pMasterLayout->addWidget(b,1,0);
connect(b,SIGNAL(clicked()),this,SLOT(commit()));
QWidget * pBackground = new QWidget(pScrollArea->viewport());
-
+
QGridLayout *g = new QGridLayout(pBackground);
QLabel * l = new QLabel("",pBackground);
@@ -89,73 +87,77 @@ KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const
f->setFrameStyle(QFrame::HLine | QFrame::Sunken);
g->addWidget(f,1,0,1,3);
- int i = 1;
- QString tmp;
-
- m_pCheckBoxes = new KviPointerList<QCheckBox>;
- m_pCheckBoxes->setAutoDelete(false);
+ QCheckBox * pCheckBox = 0;
+ QLineEdit * pLineEdit = 0;
+ int iRow = 1;
+ QString szTmp;
+ char cMode = 0;
- // first che basic checkable modes pstnmi
+ // first, the basic checkable modes pstnmi
QString szModes = "pstnmi";
while(!szModes.isEmpty())
{
- QChar ccc = szModes[0];
+ cMode = szModes[0].unicode();
szModes.remove(0,1);
- KviQString::sprintf(tmp,"%c: %Q",ccc.unicode(),&(c->connection()->serverInfo()->getChannelModeDescription(ccc)));
- QCheckBox * cb = new QCheckBox(tmp,pBackground);
- cb->setEnabled(isEnabled);
- m_pCheckBoxes->append(cb);
- cb->setChecked(m_szMode.contains((char)ccc.unicode()));
- i++;
- g->addWidget(cb,i,0,1,3);
+ KviQString::sprintf(szTmp,"%c: %Q",cMode, getModeDescription(cMode));
+ pCheckBox = new QCheckBox(szTmp,pBackground);
+ pCheckBox->setEnabled(bIsEnabled);
+ m_pCheckBoxes.insert(cMode,pCheckBox);
+ if(pChan)
+ pCheckBox->setChecked(pChan->channelMode().contains(cMode));
+ iRow++;
+ g->addWidget(pCheckBox,iRow,0,1,3);
}
- KviQString::sprintf(tmp,"l: %Q",&(c->connection()->serverInfo()->getChannelModeDescription('l')));
- m_pLimitBox = new QCheckBox(tmp,pBackground);
- m_pLimitBox->setEnabled(isEnabled);
- i++;
- g->addWidget(m_pLimitBox,i,0,1,3);
- connect(m_pLimitBox,SIGNAL(toggled(bool)),this,SLOT(limitBoxToggled(bool)));
- m_pLimitEdit = new QLineEdit(pBackground);
- m_pLimitEdit->setEnabled(isEnabled);
- i++;
- g->addWidget(m_pLimitEdit,i,1,1,2);
- if(!m_szLimit.isEmpty())
+ // second, che basic modes with parameter lk
+ szModes = "lk";
+
+ while(!szModes.isEmpty())
{
- m_pLimitBox->setChecked(true);
- m_pLimitEdit->setText(m_szLimit);
- } else {
- m_pLimitEdit->setEnabled(false);
- }
+ cMode = szModes[0].unicode();
+ szModes.remove(0,1);
- KviQString::sprintf(tmp,"k: %Q",&(c->connection()->serverInfo()->getChannelModeDescription('k')));
- m_pKeyBox = new QCheckBox(tmp,pBackground);
- m_pKeyBox->setEnabled(isEnabled);
- i++;
+ KviQString::sprintf(szTmp,"%c: %Q",cMode, getModeDescription(cMode));
+ pCheckBox = new QCheckBox(szTmp,pBackground);
+ m_pCheckBoxes.insert(cMode,pCheckBox);
+ pCheckBox->setEnabled(bIsEnabled);
+ iRow++;
+ g->addWidget(pCheckBox,iRow,0,1,3);
- g->addWidget(m_pKeyBox,i,0,1,3);
- connect(m_pKeyBox,SIGNAL(toggled(bool)),this,SLOT(keyBoxToggled(bool)));
- m_pKeyEdit = new QLineEdit(pBackground);
- m_pKeyEdit->setEnabled(isEnabled);
- i++;
- g->addWidget(m_pKeyEdit,i,1,1,2);
- if(!m_szKey.isEmpty())
- {
- m_pKeyBox->setChecked(true);
- m_pKeyEdit->setText(m_szKey);
- } else {
- m_pKeyEdit->setEnabled(false);
+ connect(pCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool)));
+ pLineEdit = new QLineEdit(pBackground);
+ m_pLineEdits.insert(cMode,pLineEdit);
+ pLineEdit->setEnabled(bIsEnabled);
+ iRow++;
+ g->addWidget(pLineEdit,iRow,1,1,2);
+
+ if(pChan)
+ {
+ if(pChan->hasChannelMode(cMode))
+ {
+ pCheckBox->setChecked(true);
+ pLineEdit->setText(pChan->channelModeParam(cMode));
+ } else {
+ pLineEdit->setEnabled(false);
+ }
+ }
}
- // add plain supported modes (the one that doesn't need a parameter)
- if(c->connection())
+ // third, check if the we have any info about other modes supported by the server
+ KviIrcConnectionServerInfo * pServerInfo = getServerInfo();
+ if(!pServerInfo)
{
- if(c->connection()->serverInfo())
- szModes = c->connection()->serverInfo()->supportedPlainModes();
+ g->setRowStretch(++iRow,1);
+ g->setColumnStretch(2,1);
+ pScrollArea->setWidget(pBackground);
+ return;
}
+ // 4th, more plain modes supported by the server
+ szModes = pServerInfo->supportedPlainModes();
+
// remove modes that we already implemented
szModes.remove("p");
szModes.remove("s");
@@ -166,147 +168,267 @@ KviModeEditor::KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const
while(!szModes.isEmpty())
{
- QChar ccc = szModes[0];
+ cMode = szModes[0].unicode();
szModes.remove(0,1);
- KviQString::sprintf(tmp,"%c: %Q",(char)ccc.unicode(),&(c->connection()->serverInfo()->getChannelModeDescription(ccc)));
- QCheckBox * cb = new QCheckBox(tmp,pBackground);
- cb->setEnabled(isEnabled);
- m_pCheckBoxes->append(cb);
- cb->setChecked(m_szMode.contains((char)ccc.unicode()));
- i++;
- g->addWidget(cb,i,0,1,3);
+ KviQString::sprintf(szTmp,"%c: %Q",cMode, getModeDescription(cMode));
+ pCheckBox = new QCheckBox(szTmp,pBackground);
+ pCheckBox->setEnabled(bIsEnabled);
+ m_pCheckBoxes.insert(cMode,pCheckBox);
+ if(pChan)
+ pCheckBox->setChecked(pChan->channelMode().contains(cMode));
+
+ iRow++;
+ g->addWidget(pCheckBox,iRow,0,1,3);
}
- // TODO: add complex supported modes (the one that need a parameter)
- i++;
+ iRow++;
- g->setRowStretch(i,1);
- g->setColumnStretch(2,1);
+ // parameterized modes
+ szModes = pServerInfo->supportedParameterModes();
+ szModes.append(pServerInfo->supportedParameterWhenSetModes());
+
+ // remove modes that we already implemented
+ szModes.remove("k");
+ szModes.remove("l");
+
+ while(!szModes.isEmpty())
+ {
+ cMode = szModes[0].unicode();
+ szModes.remove(0,1);
+
+ KviQString::sprintf(szTmp,"%c: %Q",cMode, getModeDescription(cMode));
+ pCheckBox = new QCheckBox(szTmp,pBackground);
+ m_pCheckBoxes.insert(cMode,pCheckBox);
+ pCheckBox->setEnabled(bIsEnabled);
+ iRow++;
+ g->addWidget(pCheckBox,iRow,0,1,3);
+ connect(pCheckBox,SIGNAL(toggled(bool)),this,SLOT(checkBoxToggled(bool)));
+ pLineEdit = new QLineEdit(pBackground);
+ m_pLineEdits.insert(cMode,pLineEdit);
+ pLineEdit->setEnabled(bIsEnabled);
+ iRow++;
+ g->addWidget(pLineEdit,iRow,1,1,2);
+
+ if(pChan->hasChannelMode(cMode))
+ {
+ pCheckBox->setChecked(true);
+ pLineEdit->setText(pChan->channelModeParam(cMode));
+ } else {
+ pLineEdit->setEnabled(false);
+ }
+ }
+
+ g->setRowStretch(++iRow,1);
+ g->setColumnStretch(2,1);
pScrollArea->setWidget(pBackground);
}
KviModeEditor::~KviModeEditor()
{
- delete m_pCheckBoxes;
-}
+ for(int i=0;i<m_pLineEdits.count();++i)
+ delete m_pLineEdits.value(i);
-void KviModeEditor::limitBoxToggled(bool bChecked)
-{
- m_pLimitEdit->setEnabled(bChecked);
+ for(int i=0;i<m_pCheckBoxes.count();++i)
+ delete m_pCheckBoxes.value(i);
}
-void KviModeEditor::keyBoxToggled(bool bChecked)
+void KviModeEditor::checkBoxToggled(bool bChecked)
{
- m_pKeyEdit->setEnabled(bChecked);
+ // enable/disable the lineedit if any
+ if(!sender())
+ return;
+
+ QChar c = m_pCheckBoxes.key((QCheckBox *)sender());
+ if(c.isNull())
+ return;
+
+ QLineEdit * pLineEdit = m_pLineEdits.value(c.unicode());
+ if(!pLineEdit)
+ return;
+
+ pLineEdit->setEnabled(bChecked);
}
void KviModeEditor::commit()
{
- KviStr szPlusModes;
- KviStr szMinusModes;
+ if(!m_pChannel)
+ {
+ emit done();
+ return;
+ }
+
+ QMap<char, QString> szPlusModes;
+ QMap<char, QString> szMinusModes;
+
+ QCheckBox * pCheckBox;
+ QLineEdit * pLineEdit;
+ char cMode = 0;
- if(!m_szKey.isEmpty())
+ QList<char> modes = m_pCheckBoxes.keys();
+
+ for(int i=0; i < modes.count();++i)
{
- // had a key before
- if(m_pKeyBox->isChecked())
+ cMode = modes.at(i);
+ pCheckBox = m_pCheckBoxes.value(cMode);
+ if(!pCheckBox)
+ continue; // wtf!?
+
+ pLineEdit = m_pLineEdits.value(cMode);
+ if(pLineEdit)
{
- // still have it
- QString tmp = m_pKeyEdit->text().trimmed();
- if(!tmp.isEmpty())
+ // mode with parameter (with an exception)
+ if(pCheckBox->isChecked())
{
- if(tmp != m_szKey)
+ // mode is checked
+ if(!m_pChannel->hasChannelMode(cMode) ||
+ (pLineEdit->text().trimmed() != m_pChannel->channelModeParam(cMode)))
{
- // not the same key!
- // set the new one
- KviStr mode(KviStr::Format,"-k %s",m_szKey.toUtf8().data()); // FIXME: assuming utf8 is wrong here!
- emit setMode(mode.ptr());
- mode.sprintf("+k %s",tmp.toUtf8().data());
- emit setMode(mode.ptr());
+ // mode was not checked before, or the parameter has changed
+ szPlusModes.insert(cMode, pLineEdit->text().trimmed());
+ }
+ } else {
+ // mode is not checked
+ if(m_pChannel->hasChannelMode(cMode))
+ {
+ // but it was checked before
+
+ // checks if this specific mode does not need a parameter when set
+ if(modeNeedsParameterOnlyWhenSet(cMode))
+ {
+ szMinusModes.insert(cMode,QString());
+ continue;
+ }
+
+ // unset the previously set mode
+ szMinusModes.insert(cMode, m_pChannel->channelModeParam(cMode));
}
}
} else {
- // no key now! reset
- KviStr mode(KviStr::Format,"-k %s",m_szKey.toUtf8().data());
- emit setMode(mode.ptr());
- }
- } else {
- // there was no key before
- if(m_pKeyBox->isChecked())
- {
- QString tmp = m_pKeyEdit->text().trimmed();
- if(!tmp.isEmpty())
+ //mode without parameter
+ if(pCheckBox->isChecked())
{
- // new key to be set
- KviStr mode(KviStr::Format,"+k %s",tmp.toUtf8().data());
- emit setMode(mode.ptr());
+ if(!m_pChannel->channelMode().contains(cMode))
+ szPlusModes.insert(cMode, QString());
+ } else {
+ if(m_pChannel->channelMode().contains(cMode))
+ szMinusModes.insert(cMode,QString());
}
}
}
- if(!m_szLimit.isEmpty())
+ // now flush out mode changes
+ int iModesPerLine=3; // a good default
+ KviIrcConnectionServerInfo * pServerInfo = getServerInfo();
+ if(pServerInfo)
{
- // had a limit before
- if(m_pLimitBox->isChecked())
+ iModesPerLine = pServerInfo->maxModeChanges();
+ if(iModesPerLine < 1) iModesPerLine = 1;
+ }
+
+ QString szModes;
+ QStringList szParameters;
+ int iModes=0;
+
+ QMap<char, QString>::const_iterator iter = szMinusModes.constBegin();
+ while (iter != szMinusModes.constEnd())
+ {
+ if(iter == szMinusModes.constBegin())
+ szModes.append("-");
+ szModes.append(iter.key());
+ szParameters.append(iter.value());
+ ++iModes;
+ ++iter;
+
+ //time to commit?
+ if(iModes == iModesPerLine)
{
- // still have it
- QString tmp = m_pLimitEdit->text().trimmed();
- bool bOk;
- unsigned int uLimit = tmp.toUInt(&bOk);
- if(bOk)
+ QString szCommitModes = szModes;
+ if(iter == szMinusModes.constEnd())
+ szModes.clear();
+ else
+ szModes="-";
+ if(szParameters.count())
{
- if(m_szLimit != tmp)
- {
- // not the same limit!
- KviStr mode(KviStr::Format,"+l %u",uLimit);
- emit setMode(mode.ptr());
- }
+ szCommitModes.append(QChar(' '));
+ szCommitModes.append(szParameters.join(QString(" ")));
+ szParameters.clear();
}
- } else {
- // no limit now! reset
- szMinusModes.append('l');
+ iModes=0;
+
+ emit setMode(szCommitModes);
}
- } else {
- // there was no limit before
- if(m_pLimitBox->isChecked())
+ }
+
+ iter = szPlusModes.constBegin();
+ while (iter != szPlusModes.constEnd())
+ {
+ if(iter == szPlusModes.constBegin())
+ szModes.append("+");
+ szModes.append(iter.key());
+ szParameters.append(iter.value());
+ ++iModes;
+ ++iter;
+
+ //time to commit? this should be an ==, but includes the minus sign so "+aaa" = 4 chars
+ if(iModes == iModesPerLine)
{
- QString tmp = m_pLimitEdit->text().trimmed();
- bool bOk;
- unsigned int uLimit = tmp.toUInt(&bOk);
- if(bOk)
+ QString szCommitModes = szModes;
+ if(iter == szPlusModes.constEnd())
+ szModes.clear();
+ else
+ szModes="+";
+ if(szParameters.count())
{
- // new limit to be set
- KviStr mode(KviStr::Format,"+l %u",uLimit);
- emit setMode(mode.ptr());
+ szCommitModes.append(QChar(' '));
+ szCommitModes.append(szParameters.join(QString(" ")));
+ szParameters.clear();
}
+ iModes=0;
+
+ emit setMode(szCommitModes);
}
}
-
- for(QCheckBox * cb = m_pCheckBoxes->first();cb;cb = m_pCheckBoxes->next())
+ if(iModes)
{
- QString sz = cb->text();
- sz.replace("&","");
- if(sz.length() > 0)
+ QString szCommitModes = szModes;
+ szModes.clear();
+ if(szParameters.count())
{
- QChar ccc = sz[0];
- if(cb->isChecked())
- {
- if(!m_szMode.contains((char)ccc.unicode()))szPlusModes.append((char)ccc.unicode());
- } else {
- if(m_szMode.contains((char)ccc.unicode()))szMinusModes.append((char)ccc.unicode());
- }
+ szCommitModes.append(QChar(' '));
+ szCommitModes.append(szParameters.join(QString(" ")));
+ szParameters.clear();
}
+ emit setMode(szCommitModes);
}
- KviStr szModes;
+ emit done();
+}
- if(szMinusModes.hasData())szModes.sprintf("-%s",szMinusModes.ptr());
- if(szPlusModes.hasData())szModes.append(KviStr::Format,"+%s",szPlusModes.ptr());
- if(szModes.hasData())emit setMode(szModes.ptr());
+inline KviIrcConnectionServerInfo * KviModeEditor::getServerInfo()
+{
+ if(!m_pChannel) return 0;
+ if(!m_pChannel->console()) return 0;
+ if(!m_pChannel->console()->connection()) return 0;
+ return m_pChannel->console()->connection()->serverInfo();
+}
- emit done();
+inline const QString * KviModeEditor::getModeDescription(char cMode)
+{
+ KviIrcConnectionServerInfo * pServerInfo = getServerInfo();
+ if(pServerInfo)
+ return &(pServerInfo->getChannelModeDescription(cMode));
+ return 0; //safe, as will be used with KviQString::sprintf("%Q", ..);
+}
+
+inline bool KviModeEditor::modeNeedsParameterOnlyWhenSet(char cMode)
+{
+ KviIrcConnectionServerInfo * pServerInfo = getServerInfo();
+ if(pServerInfo)
+ return pServerInfo->supportedParameterWhenSetModes().contains(cMode);
+ return false;
}
#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES
diff --git a/src/kvirc/ui/kvi_modeeditor.h b/src/kvirc/ui/kvi_modeeditor.h
index aae14c343..34007f533 100644
--- a/src/kvirc/ui/kvi_modeeditor.h
+++ b/src/kvirc/ui/kvi_modeeditor.h
@@ -29,13 +29,12 @@
#include "kvi_pointerlist.h"
#include "kvi_toolwindows_container.h"
-#include <QWidget>
-#include <QPushButton>
-#include <QCheckBox>
-#include <QLineEdit>
-#include <QLabel>
+#include <QMap>
-class KviConsole;
+class QCheckBox;
+class QLineEdit;
+class KviIrcConnectionServerInfo;
+class KviChannel;
//////////////////////////////////////////////////////////////////////
// class KviModeEditor
@@ -46,23 +45,21 @@ class KVIRC_API KviModeEditor : public KviWindowToolWidget
{
Q_OBJECT
public:
- KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char * nam,KviConsole * c,const QString &mode,const QString &key,const QString &limit);
+ KviModeEditor(QWidget * par,KviWindowToolPageButton* button,const char * name,KviChannel * pChan);
~KviModeEditor();
protected: // fields
- QString m_szMode;
- QString m_szKey;
- QString m_szLimit;
- KviPointerList<QCheckBox> * m_pCheckBoxes;
- QCheckBox * m_pLimitBox;
- QLineEdit * m_pLimitEdit;
- QCheckBox * m_pKeyBox;
- QLineEdit * m_pKeyEdit;
+ KviChannel * m_pChannel;
+ QMap<char, QCheckBox *> m_pCheckBoxes;
+ QMap<char, QLineEdit *> m_pLineEdits;
+protected:
+ const QString * getModeDescription(char cMode);
+ bool modeNeedsParameterOnlyWhenSet(char cMode);
+ KviIrcConnectionServerInfo * getServerInfo();
signals:
- void setMode(const char *);
+ void setMode(QString & szMode);
void done();
protected slots:
- void limitBoxToggled(bool bChecked);
- void keyBoxToggled(bool bChecked);
+ void checkBoxToggled(bool bChecked);
void commit();
};
diff --git a/src/kvirc/ui/kvi_modew.cpp b/src/kvirc/ui/kvi_modew.cpp
index edfafd880..e649b3630 100644
--- a/src/kvirc/ui/kvi_modew.cpp
+++ b/src/kvirc/ui/kvi_modew.cpp
@@ -59,10 +59,10 @@ void KviModeWidget::refreshModes()
{
// TODO: support other complex supported modes (the one that need a parameter)
QString szMode=m_pChannel->channelMode();
- if(!m_pChannel->channelKey().isEmpty())
- szMode+=QString(" k:%1").arg(m_pChannel->channelKey());
- if(!m_pChannel->channelLimit().isEmpty())
- szMode+=QString(" l:%1").arg(m_pChannel->channelLimit().toUtf8().data());
+ if(m_pChannel->hasChannelMode('k'))
+ szMode+=QString(" k:%1").arg(m_pChannel->channelModeParam('k'));
+ if(m_pChannel->hasChannelMode('l'))
+ szMode+=QString(" l:%1").arg(m_pChannel->channelModeParam('l'));
setText(szMode);
}
diff --git a/src/modules/chan/libkvichan.cpp b/src/modules/chan/libkvichan.cpp
index e9647f436..d5c767aaf 100644
--- a/src/modules/chan/libkvichan.cpp
+++ b/src/modules/chan/libkvichan.cpp
@@ -112,10 +112,10 @@ static bool chan_kvs_fnc_getUrl(KviKvsModuleFunctionCall * c)
if (ch) {
KviIrcUrl::join(url,ch->connection()->target()->server());
url.append(ch->windowName());
- if(ch->hasChannelKey())
+ if(ch->hasChannelMode('k'))
{
- url.append('?');
- url.append(ch->channelKey());
+ url.append("?");
+ url.append(ch->channelModeParam('k'));
}
} else {
if(c->window()->connection()) {
@@ -942,7 +942,7 @@ static bool chan_kvs_fnc_key(KviKvsModuleFunctionCall * c)
KVSM_PARAMETER("window id",KVS_PT_STRING,KVS_PF_OPTIONAL,szId)
KVSM_PARAMETERS_END(c)
KviChannel * ch = chan_kvs_find_channel(c,szId);
- if (ch) c->returnValue()->setString(ch->channelKey());
+ if (ch) c->returnValue()->setString(ch->hasChannelMode('k') ? ch->channelModeParam('k') : "");
return true;
}
@@ -972,14 +972,10 @@ static bool chan_kvs_fnc_limit(KviKvsModuleFunctionCall * c)
KVSM_PARAMETERS_END(c)
KviChannel * ch = chan_kvs_find_channel(c,szId);
kvs_int_t limit=0;
- QString lim;
if (ch)
{
- if(ch->hasChannelLimit())
- {
- lim = ch->channelLimit().toUtf8().data();
- limit = lim.toInt();
- }
+ if(ch->hasChannelMode('l'))
+ limit = ch->channelModeParam('l').toInt();
c->returnValue()->setInteger(limit);
}
return true;