diff options
| author | 2010-08-17 18:05:36 +0000 | |
|---|---|---|
| committer | 2010-08-17 18:05:36 +0000 | |
| commit | 3720126545edcf4a976568f2d740ab5d8d86940e (patch) | |
| tree | a9a9685f97f5f1f1ff0290c28eea3319b38bb7e3 | |
| parent | Fix an undetected syntax error in tmphighlight. (diff) | |
| download | KVIrc-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.cpp | 2 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircurl.cpp | 5 | ||||
| -rw-r--r-- | src/kvirc/sparser/kvi_sp_literal.cpp | 21 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_channel.cpp | 62 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_channel.h | 45 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_console.cpp | 5 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_modeeditor.cpp | 448 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_modeeditor.h | 33 | ||||
| -rw-r--r-- | src/kvirc/ui/kvi_modew.cpp | 8 | ||||
| -rw-r--r-- | src/modules/chan/libkvichan.cpp | 16 |
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; |
