/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ /* Copyright (C) 2005-2007 Peter Simonsson Copyright (C) 2006 Dario Abatianni Copyright (C) 2006-2007 Eike Hein */ #include "channeloptionsdialog.h" #include "konversationapplication.h" #include "channeloptionsui.h" #include "channel.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace Konversation { ChannelOptionsDialog::ChannelOptionsDialog(Channel *channel) : KDialogBase(channel, "channelOptions", false, i18n("Channel Settings for %1").arg(channel->getName()), Ok|Cancel, Ok) { Q_ASSERT(channel); m_widget = new ChannelOptionsUI(this); setMainWidget(m_widget); m_widget->otherModesList->setRenameable(0, false); m_widget->otherModesList->setRenameable(1, true); m_widget->otherModesList->hide(); // don't allow sorting. most recent topic is always first m_widget->topicHistoryList->setSortColumn(-1); m_widget->clearButton->setIconSet(SmallIconSet("locationbar_erase")); m_widget->banList->setDefaultRenameAction(TQListView::Accept); m_widget->banListSearchLine->setListView(m_widget->banList); // hide column where the complete topic will be put in for convenience m_widget->topicHistoryList->hideColumn(2); // do not allow the user to resize the hidden column back into view m_widget->topicHistoryList->header()->setResizeEnabled(false,2); m_channel = channel; m_editingTopic = false; connect(m_widget->topicHistoryList, TQT_SIGNAL(clicked(TQListViewItem*)), this, TQT_SLOT(topicHistoryItemClicked(TQListViewItem*))); connect(m_widget->topicHistoryList, TQT_SIGNAL(selectionChanged(TQListViewItem*)), this, TQT_SLOT(topicHistoryItemClicked(TQListViewItem*))); connect(m_widget->toggleAdvancedModes, TQT_SIGNAL(clicked()), this, TQT_SLOT(toggleAdvancedModes())); connect(m_widget->topicEdit, TQT_SIGNAL(modificationChanged(bool)), this, TQT_SLOT(topicBeingEdited(bool))); connect(m_channel, TQT_SIGNAL(topicHistoryChanged()), this, TQT_SLOT(refreshTopicHistory())); connect(m_channel, TQT_SIGNAL(modesChanged()), this, TQT_SLOT(refreshModes())); connect(m_channel->getOwnChannelNick(), TQT_SIGNAL(channelNickChanged()), this, TQT_SLOT(refreshEnableModes())); connect(this, TQT_SIGNAL(cancelClicked()), this, TQT_SLOT(cancelClicked())); connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(changeOptions())); connect(this, TQT_SIGNAL(okClicked()), this, TQT_SLOT(okClicked())); connect(m_channel, TQT_SIGNAL(banAdded(const TQString&)), this, TQT_SLOT(addBan(const TQString&))); connect(m_channel, TQT_SIGNAL(banRemoved(const TQString&)), this, TQT_SLOT(removeBan(const TQString&))); connect(m_channel, TQT_SIGNAL(banListCleared()), m_widget->banList, TQT_SLOT(clear())); connect(m_widget->addBan, TQT_SIGNAL(clicked()), this, TQT_SLOT(addBanClicked())); connect(m_widget->removeBan, TQT_SIGNAL(clicked()), this, TQT_SLOT(removeBanClicked())); connect(m_widget->banList, TQT_SIGNAL(itemRenamed (TQListViewItem*)), this, TQT_SLOT(banEdited(TQListViewItem*))); connect(m_widget->banList, TQT_SIGNAL(itemRenamed (TQListViewItem*, int, const TQString&)), this, TQT_SLOT(banEdited(TQListViewItem*))); refreshTopicHistory(); refreshBanList(); refreshAllowedChannelModes(); refreshModes(); } ChannelOptionsDialog::~ChannelOptionsDialog() { } void ChannelOptionsDialog::changeOptions() { TQString newTopic = topic(), oldTopic=m_channel->getTopicHistory().first().section(' ', 2); if(newTopic != oldTopic) { // Pass a ^A so we can determine if we want to clear the channel topic. if (newTopic.isEmpty()) { if (!oldTopic.isEmpty()) m_channel->sendChannelText(Preferences::commandChar() + "TOPIC " + m_channel->getName() + " \x01"); } else m_channel->sendChannelText(Preferences::commandChar() + "TOPIC " + m_channel->getName() + ' ' + newTopic); } TQStringList newModeList = modes(); TQStringList currentModeList = m_channel->getModeList(); TQStringList rmModes; TQStringList addModes; TQStringList tmp; TQString modeString; bool plus; TQString command("MODE %1 %2%3 %4"); for(TQStringList::iterator it = newModeList.begin(); it != newModeList.end(); ++it) { modeString = (*it).mid(1); plus = ((*it)[0] == '+'); tmp = currentModeList.grep(TQRegExp('^' + modeString)); if(tmp.isEmpty() && plus) { m_channel->getServer()->queue(command.arg(m_channel->getName()).arg("+").arg(modeString[0]).arg(modeString.mid(1))); } else if(!tmp.isEmpty() && !plus) { //FIXME: Bahamuth requires the key parameter for -k, but ircd breaks on -l with limit number. //Hence two versions of this. if (modeString[0] == 'k') m_channel->getServer()->queue(command.arg(m_channel->getName()).arg("-").arg(modeString[0]).arg(modeString.mid(1))); else m_channel->getServer()->queue(command.arg(m_channel->getName()).arg("-").arg(modeString[0]).arg("")); } } hide(); } void ChannelOptionsDialog::toggleAdvancedModes() { bool ison = m_widget->toggleAdvancedModes->isOn(); m_widget->otherModesList->setShown(ison); if(ison) { m_widget->toggleAdvancedModes->setText(i18n("&Hide Advanced Modes <<")); } else { m_widget->toggleAdvancedModes->setText(i18n("&Show Advanced Modes >>")); } } void ChannelOptionsDialog::topicBeingEdited(bool state) { m_editingTopic = state; } TQString ChannelOptionsDialog::topic() { return m_widget->topicEdit->text().replace("\n"," "); } void ChannelOptionsDialog::refreshTopicHistory() { TQStringList history = m_channel->getTopicHistory(); m_widget->topicHistoryList->clear(); for(TQStringList::const_iterator it = history.fromLast(); it != history.end(); --it) { TQDateTime date; date.setTime_t((*it).section(' ', 0 ,0).toUInt()); new KListViewItem(m_widget->topicHistoryList, (*it).section(' ', 1, 1), date.toString(Qt::LocalDate), (*it).section(' ', 2)); } // update topic preview topicHistoryItemClicked(m_widget->topicHistoryList->selectedItem()); // don't destroy the user's edit box if they started editing if(!m_editingTopic) m_widget->topicEdit->setText(history.first().section(' ', 2)); } void ChannelOptionsDialog::topicHistoryItemClicked(TQListViewItem* item) { // if they didn't click on anything, item is null if(item) // update topic preview m_widget->topicPreview->setText(item->text(2)); else // clear topic preview m_widget->topicPreview->setText(""); } void ChannelOptionsDialog::refreshEnableModes() { bool enable = m_channel->getOwnChannelNick()->isAnyTypeOfOp(); m_widget->otherModesList->setEnabled(enable); m_widget->topicEdit->setReadOnly(!enable && m_widget->topicModeChBox->isChecked()); m_widget->topicModeChBox->setEnabled(enable); m_widget->messageModeChBox->setEnabled(enable); m_widget->userLimitChBox->setEnabled(enable); m_widget->userLimitEdit->setEnabled(enable); m_widget->inviteModeChBox->setEnabled(enable); m_widget->moderatedModeChBox->setEnabled(enable); m_widget->secretModeChBox->setEnabled(enable); m_widget->keyModeChBox->setEnabled(enable); m_widget->keyModeEdit->setEnabled(enable); m_widget->banList->setItemsRenameable(enable); m_widget->addBan->setEnabled(enable); m_widget->removeBan->setEnabled(enable); } void ChannelOptionsDialog::refreshAllowedChannelModes() { TQString modeString = m_channel->getServer()->allowedChannelModes(); // These modes are handled in a special way: ntimslkbeI modeString.remove('t'); modeString.remove('n'); modeString.remove('l'); modeString.remove('i'); modeString.remove('m'); modeString.remove('s'); modeString.remove('k'); modeString.remove('b'); modeString.remove('e'); modeString.remove('I'); modeString.remove('O'); modeString.remove('o'); modeString.remove('v'); for(unsigned int i = 0; i < modeString.length(); i++) { new TQCheckListItem(m_widget->otherModesList, TQString(modeString[i]), TQCheckListItem::CheckBox); } } void ChannelOptionsDialog::refreshModes() { TQStringList modes = m_channel->getModeList(); m_widget->topicModeChBox->setChecked(false); m_widget->messageModeChBox->setChecked(false); m_widget->userLimitChBox->setChecked(false); m_widget->userLimitEdit->setValue(0); m_widget->inviteModeChBox->setChecked(false); m_widget->moderatedModeChBox->setChecked(false); m_widget->secretModeChBox->setChecked(false); m_widget->keyModeChBox->setChecked(false); m_widget->keyModeEdit->setText(""); TQListViewItem* item = m_widget->otherModesList->firstChild(); while(item) { static_cast(item)->setOn(false); item = item->nextSibling(); } char mode; for(TQStringList::const_iterator it = modes.begin(); it != modes.end(); ++it) { mode = (*it)[0]; switch(mode) { case 't': m_widget->topicModeChBox->setChecked(true); break; case 'n': m_widget->messageModeChBox->setChecked(true); break; case 'l': m_widget->userLimitChBox->setChecked(true); m_widget->userLimitEdit->setValue((*it).mid(1).toInt()); break; case 'i': m_widget->inviteModeChBox->setChecked(true); break; case 'm': m_widget->moderatedModeChBox->setChecked(true); break; case 's': m_widget->secretModeChBox->setChecked(true); break; case 'k': m_widget->keyModeChBox->setChecked(true); m_widget->keyModeEdit->setText((*it).mid(1)); break; default: { bool found = false; item = m_widget->otherModesList->firstChild(); TQString modeString; modeString = mode; while(item && !found) { if(item->text(0) == modeString) { found = true; static_cast(item)->setOn(true); item->setText(1, (*it).mid(1)); } else { item = item->nextSibling(); } } break; } } } refreshEnableModes(); } TQStringList ChannelOptionsDialog::modes() { TQStringList modes; TQString mode; mode = (m_widget->topicModeChBox->isChecked() ? "+" : "-"); mode += 't'; modes.append(mode); mode = (m_widget->messageModeChBox->isChecked() ? "+" : "-"); mode += 'n'; modes.append(mode); mode = (m_widget->userLimitChBox->isChecked() ? "+" : "-"); mode += 'l' + TQString::number( m_widget->userLimitEdit->value() ); modes.append(mode); mode = (m_widget->inviteModeChBox->isChecked() ? "+" : "-"); mode += 'i'; modes.append(mode); mode = (m_widget->moderatedModeChBox->isChecked() ? "+" : "-"); mode += 'm'; modes.append(mode); mode = (m_widget->secretModeChBox->isChecked() ? "+" : "-"); mode += 's'; modes.append(mode); if (m_widget->keyModeChBox->isChecked() && !m_widget->keyModeEdit->text().isEmpty()) { mode = '+'; mode += 'k' + m_widget->keyModeEdit->text(); modes.append(mode); } else if (!m_widget->keyModeChBox->isChecked()) { mode = '-'; mode += 'k' + m_widget->keyModeEdit->text(); modes.append(mode); } TQListViewItem* item = m_widget->otherModesList->firstChild(); while(item) { mode = (static_cast(item)->isOn() ? "+" : "-"); mode += item->text(0) + item->text(1); modes.append(mode); item = item->nextSibling(); } return modes; } // Ban List tab related functions void ChannelOptionsDialog::refreshBanList() { TQStringList banlist = m_channel->getBanList(); m_widget->banList->clear(); for (TQStringList::const_iterator it = banlist.fromLast(); it != banlist.end(); --it) addBan((*it)); } void ChannelOptionsDialog::addBan(const TQString& newban) { new BanListViewItem(m_widget->banList, newban.section(' ', 0, 0), newban.section(' ', 1, 1).section('!', 0, 0), newban.section(' ', 2 ,2).toUInt()); } void ChannelOptionsDialog::removeBan(const TQString& ban) { delete m_widget->banList->findItem(ban, 0); } void ChannelOptionsDialog::banEdited(TQListViewItem *edited) { if (edited == m_NewBan) { if (!m_NewBan->text(0).isEmpty()) { m_channel->getServer()->requestBan(TQStringList(m_NewBan->text(0)), m_channel->getName(), TQString()); } // We will delete the item and let the addBan slot handle // readding the item because for some odd reason using // startRename causes further attempts to rename the item // using 2 mouse clicks to fail in odd ways. delete edited; return; } BanListViewItem *new_edited = dynamic_cast (edited); if (new_edited == NULL) return; // Should not happen. if (new_edited->getOldValue() != new_edited->text(0)) { m_channel->getServer()->requestUnban(new_edited->getOldValue(), m_channel->getName()); if (!new_edited->text(0).isEmpty()) { m_channel->getServer()->requestBan(TQStringList(new_edited->text(0)), m_channel->getName(), TQString()); } // We delete the existing item because it's possible the server may // Modify the ban causing us not to catch it. If that happens we'll be // stuck with a stale item and a new item with the modified hostmask. delete new_edited; } } void ChannelOptionsDialog::addBanClicked() { m_NewBan = new BanListViewItem(m_widget->banList, true); m_NewBan->setRenameEnabled(0,true); m_NewBan->startRename(0); } void ChannelOptionsDialog::removeBanClicked() { if (m_widget->banList->currentItem()) m_channel->getServer()->requestUnban(m_widget->banList->currentItem()->text(0), m_channel->getName()); } void ChannelOptionsDialog::cancelClicked() { if (m_widget->banList->renameLineEdit()->isShown()) { TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Escape, 27, Qt::NoButton); TDEApplication::sendEvent(m_widget->banList->renameLineEdit(), &e); } topicBeingEdited(false); hide(); } void ChannelOptionsDialog::okClicked() { if (m_widget->banList->renameLineEdit()->isShown()) { TQKeyEvent e(TQEvent::KeyPress, TQt::Key_Return, 13, Qt::NoButton); TDEApplication::sendEvent(m_widget->banList->renameLineEdit(), &e); } } // This is our implementation of BanListViewItem BanListViewItem::BanListViewItem(TQListView *parent) : KListViewItem(parent) { m_isNewBan = 0; } BanListViewItem::BanListViewItem(TQListView *parent, bool isNew) : KListViewItem(parent) { m_isNewBan = isNew; } BanListViewItem::BanListViewItem (TQListView *parent, const TQString& label1, const TQString& label2, uint timestamp) : KListViewItem(parent, label1, label2) { m_isNewBan = 0; m_timestamp.setTime_t(timestamp); } BanListViewItem::BanListViewItem (TQListView *parent, bool isNew, const TQString& label1, const TQString& label2, uint timestamp) : KListViewItem(parent, label1, label2) { m_isNewBan = isNew; m_timestamp.setTime_t(timestamp); } TQString BanListViewItem::text(int column) const { if (column == 2) return KGlobal::locale()->formatDateTime(m_timestamp, true, true); return KListViewItem::text(column); } int BanListViewItem::compare(TQListViewItem *i, int col, bool ascending) const { if (col == 2) { BanListViewItem* item = static_cast(i); if (m_timestamp == item->timestamp()) return 0; else if (m_timestamp < item->timestamp()) return -1; else return 1; } return KListViewItem::compare(i, col, ascending); } void BanListViewItem::startRename( int col ) { m_oldValue = text(col); KListViewItem::startRename(col); } void BanListViewItem::cancelRename( int col ) { if (text(col).isEmpty() && m_isNewBan) delete this; else KListViewItem::cancelRename(col); } } #include "channeloptionsdialog.moc"