/* * This file is part of the KFTPGrabber project * * Copyright (C) 2003-2006 by the KFTPGrabber developers * Copyright (C) 2003-2006 Jernej Kos * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. 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 Steet, Fifth Floor, Boston, * MA 02110-1301, USA. * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "filtereditor.h" #include "listview.h" #include "misc/filterwidgethandler.h" #include #include #include #include #include #include #include #include #include using namespace KFTPCore::Filter; namespace KFTPWidgets { FilterEditor::FilterEditor(TQWidget *parent) : TQWidget(parent), m_rule(0) { TQHBoxLayout *mainLayout = new TQHBoxLayout(this, 0, KDialog::spacingHint()); m_listView = new FilterListView(this); mainLayout->addWidget(m_listView, 1); TQVBoxLayout *rightLayout = new TQVBoxLayout(mainLayout); mainLayout->setStretchFactor(rightLayout, KDialog::spacingHint()); m_enabledCheck = new TQCheckBox(i18n("Filter &enabled"), this); rightLayout->addWidget(m_enabledCheck); m_conditionsList = new FilterConditionsList(this); rightLayout->addWidget(m_conditionsList, 0, TQt::AlignTop); m_actionsList = new FilterActionsList(this); rightLayout->addWidget(m_actionsList, 0, TQt::AlignTop); rightLayout->addStretch(1); // Connect some signals connect(m_enabledCheck, SIGNAL(clicked()), this, SLOT(slotEnabledChanged())); connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), this, SLOT(slotRuleChanged(KFTPCore::Filter::Rule*))); connect(m_listView, SIGNAL(ruleRemoved()), this, SLOT(slotRuleRemoved())); connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), m_conditionsList, SLOT(loadRule(KFTPCore::Filter::Rule*))); connect(m_listView, SIGNAL(ruleRemoved()), m_conditionsList, SLOT(reset())); connect(m_listView, SIGNAL(ruleChanged(KFTPCore::Filter::Rule*)), m_actionsList, SLOT(loadRule(KFTPCore::Filter::Rule*))); connect(m_listView, SIGNAL(ruleRemoved()), m_actionsList, SLOT(reset())); } void FilterEditor::slotRuleChanged(KFTPCore::Filter::Rule *rule) { m_enabledCheck->setEnabled(true); m_enabledCheck->setChecked(rule->isEnabled()); m_rule = rule; } void FilterEditor::slotRuleRemoved() { m_enabledCheck->setChecked(false); m_enabledCheck->setEnabled(false); } void FilterEditor::slotEnabledChanged() { if (m_rule) m_rule->setEnabled(m_enabledCheck->isChecked()); } void FilterEditor::reset() { m_enabledCheck->setChecked(false); m_enabledCheck->setEnabled(false); m_conditionsList->reset(); m_actionsList->reset(); m_listView->reset(); } FilterListItem::FilterListItem(ListView *parent, KFTPCore::Filter::Rule *rule) : TQListViewItem(parent), m_rule(rule) { setText(0, rule->name()); } FilterListView::FilterListView(TQWidget *parent) : TQGroupBox(1, Horizontal, i18n("Filters"), parent) { m_listView = new ListView(this); m_listView->setSelectionMode(TQListView::Single); m_listView->setSorting(-1); m_listView->header()->hide(); m_listView->setMinimumWidth(150); m_listView->setEmptyListText(i18n("No filters.")); m_listView->addColumn(""); m_listView->setFullWidth(true); TQHBox *hb = new TQHBox(this); hb->setSpacing(4); // Up/down buttons m_buttonUp = new KPushButton(TQString::null, hb); m_buttonUp->setAutoRepeat(true); m_buttonUp->setIconSet(BarIconSet("go-up", TDEIcon::SizeSmall)); m_buttonUp->setMinimumSize(m_buttonUp->sizeHint() * 1.2); m_buttonDown = new KPushButton(TQString::null, hb); m_buttonDown->setAutoRepeat(true); m_buttonDown->setIconSet(BarIconSet("go-down", TDEIcon::SizeSmall)); m_buttonDown->setMinimumSize(m_buttonDown->sizeHint() * 1.2); TQToolTip::add(m_buttonUp, i18n("Up")); TQToolTip::add(m_buttonDown, i18n("Down")); // New, copy, delete buttons hb = new TQHBox(this); hb->setSpacing(4); m_buttonNew = new TQPushButton(TQString::null, hb); m_buttonNew->setPixmap(BarIcon("document-new", TDEIcon::SizeSmall)); m_buttonNew->setMinimumSize(m_buttonNew->sizeHint() * 1.2); m_buttonCopy = new TQPushButton(TQString::null, hb); m_buttonCopy->setPixmap(BarIcon("edit-copy", TDEIcon::SizeSmall)); m_buttonCopy->setMinimumSize(m_buttonCopy->sizeHint() * 1.2); m_buttonDelete = new TQPushButton(TQString::null, hb); m_buttonDelete->setPixmap(BarIcon("edit-delete", TDEIcon::SizeSmall)); m_buttonDelete->setMinimumSize(m_buttonDelete->sizeHint() * 1.2); m_buttonRename = new TQPushButton(i18n("Rename..."), hb); TQToolTip::add(m_buttonNew, i18n("New")); TQToolTip::add(m_buttonCopy, i18n("Copy")); TQToolTip::add(m_buttonDelete, i18n("Delete")); // Connect the signals connect(m_buttonNew, SIGNAL(clicked()), this, SLOT(slotNewRule())); connect(m_buttonDelete, SIGNAL(clicked()), this, SLOT(slotDeleteRule())); connect(m_buttonRename, SIGNAL(clicked()), this, SLOT(slotRenameRule())); connect(m_buttonCopy, SIGNAL(clicked()), this, SLOT(slotCopyRule())); connect(m_buttonUp, SIGNAL(clicked()), this, SLOT(slotUp())); connect(m_buttonDown, SIGNAL(clicked()), this, SLOT(slotDown())); connect(m_listView, SIGNAL(selectionChanged(TQListViewItem*)), this, SLOT(slotSelectionChanged(TQListViewItem*))); m_buttonUp->setEnabled(false); m_buttonDown->setEnabled(false); m_buttonRename->setEnabled(false); // Reset the view, loading all the existing rules reset(); } void FilterListView::reset() { m_listView->clear(); // Load all existing rules Filters *filters = Filters::self(); Filters::ConstIterator le = filters->end(); for (Filters::ConstIterator i = filters->begin(); i != le; ++i) { FilterListItem *item = new FilterListItem(m_listView, (*i)); item->moveItem(m_listView->lastItem()); } // Select the first rule m_listView->setSelected(m_listView->firstChild(), true); } void FilterListView::slotSelectionChanged(TQListViewItem *item) { FilterListItem *selected = static_cast(item); m_buttonUp->setEnabled(item->itemAbove()); m_buttonDown->setEnabled(item->nextSibling()); m_buttonRename->setEnabled(true); // Signal the rule change emit ruleChanged(selected->rule()); } void FilterListView::slotNewRule() { Rule *rule = new Rule(i18n("Unnamed Rule")); FilterListItem *selected = static_cast(m_listView->selectedItem()); FilterListItem *item = new FilterListItem(m_listView, rule); if (selected) { Filters::self()->insert(Filters::self()->findRef(selected->rule()) + 1, rule); item->moveItem(selected); } else { Filters::self()->append(rule); } m_listView->setSelected(item, true); } void FilterListView::slotDeleteRule() { FilterListItem *selected = static_cast(m_listView->selectedItem()); if (selected) { Rule *rule = selected->rule(); delete selected; emit ruleRemoved(); Filters::self()->removeRef(rule); m_listView->setSelected(m_listView->lastItem(), true); } if (!m_listView->selectedItem()) m_buttonRename->setEnabled(false); } void FilterListView::slotRenameRule() { FilterListItem *selected = static_cast(m_listView->selectedItem()); if (selected) { TQString name = KInputDialog::getText(i18n("Rename Rule"), i18n("Rename rule '%1' to:").arg(selected->rule()->name()), selected->rule()->name()); if (name.stripWhiteSpace().isEmpty()) name = i18n("Unnamed Rule"); selected->rule()->setName(name); selected->setText(0, name); } } void FilterListView::slotCopyRule() { FilterListItem *selected = static_cast(m_listView->selectedItem()); if (selected) { Rule *rule = new Rule(selected->rule()); FilterListItem *item = new FilterListItem(m_listView, rule); Filters::self()->insert(Filters::self()->findRef(selected->rule()) + 1, rule); item->moveItem(selected); m_listView->setSelected(item, true); } } void FilterListView::slotUp() { FilterListItem *selected = static_cast(m_listView->selectedItem()); TQListViewItem *tmp = selected->itemAbove(); if (!tmp) return; FilterListItem *previous = static_cast(tmp->itemAbove()); if (selected) { Rule *rule = Filters::self()->take(Filters::self()->findRef(selected->rule())); if (previous) { Filters::self()->insert(Filters::self()->findRef(previous->rule()) + 1, rule); selected->moveItem(previous); } else { Filters::self()->insert(0, rule); m_listView->takeItem(selected); m_listView->insertItem(selected); m_listView->setSelected(selected, true); } m_buttonUp->setEnabled(selected->itemAbove()); m_buttonDown->setEnabled(selected->nextSibling()); } } void FilterListView::slotDown() { FilterListItem *selected = static_cast(m_listView->selectedItem()); FilterListItem *next = static_cast(selected->nextSibling()); if (selected && next) { Rule *rule = Filters::self()->take(Filters::self()->findRef(selected->rule())); Filters::self()->insert(Filters::self()->findRef(next->rule()) + 1, rule); selected->moveItem(next); m_buttonUp->setEnabled(selected->itemAbove()); m_buttonDown->setEnabled(selected->nextSibling()); } } FilterConditionsList::FilterConditionsList(TQWidget *parent) : TQGroupBox(1, Horizontal, i18n("Conditions"), parent) { setEnabled(false); m_buttonAll = new TQRadioButton(i18n("Match a&ll of the following"), this); m_buttonAny = new TQRadioButton(i18n("Match an&y of the following"), this); m_buttonAll->setChecked(true); m_buttonAny->setChecked(false); TQButtonGroup *bg = new TQButtonGroup(this); bg->hide(); bg->insert(m_buttonAll, (int) ConditionChain::All); bg->insert(m_buttonAny, (int) ConditionChain::Any); // Connect some signals connect(bg, SIGNAL(clicked(int)), this, SLOT(slotMatchTypeChanged(int))); m_lister = new FilterConditionWidgetLister(this); } void FilterConditionsList::reset() { m_lister->clear(); setEnabled(false); } void FilterConditionsList::loadRule(Rule *rule) { m_rule = rule; switch (rule->conditions()->type()) { case ConditionChain::All: m_buttonAll->setChecked(true); break; case ConditionChain::Any: m_buttonAny->setChecked(true); break; } m_lister->loadConditions(rule); setEnabled(true); } void FilterConditionsList::slotMatchTypeChanged(int type) { if (m_rule) const_cast(m_rule->conditions())->setType((ConditionChain::Type) type); } FilterConditionWidgetLister::FilterConditionWidgetLister(TQWidget *parent) : WidgetLister(parent, 0, 7), m_rule(0) { setMinimumWidth(400); } void FilterConditionWidgetLister::loadConditions(KFTPCore::Filter::Rule *rule) { const ConditionChain *conditions = rule->conditions(); // Clear the current list setNumberShown(TQMAX(conditions->count(), 0)); ConditionChain::ConstIterator le = conditions->end(); TQPtrList::Iterator wi = m_widgetList.begin(); for (ConditionChain::ConstIterator i = conditions->begin(); i != le; ++i, ++wi) static_cast((*wi))->setCondition((*i)); m_rule = rule; } void FilterConditionWidgetLister::slotMore() { WidgetLister::slotMore(); // Actually add the condition and update the latest widget Condition *condition = new Condition(Filename, Condition::Contains, TQVariant("")); const_cast(m_rule->conditions())->append(condition); static_cast(m_widgetList.last())->setCondition(condition); } void FilterConditionWidgetLister::slotFewer() { // Actually remove the condition Condition *condition = static_cast(m_widgetList.last())->condition(); const_cast(m_rule->conditions())->remove(condition); WidgetLister::slotFewer(); } void FilterConditionWidgetLister::slotClear() { if (m_rule) const_cast(m_rule->conditions())->clear(); WidgetLister::slotClear(); } TQWidget *FilterConditionWidgetLister::createWidget(TQWidget *parent) { return new FilterConditionWidget(parent); } FilterConditionWidget::FilterConditionWidget(TQWidget *parent) : TQWidget(parent), m_condition(0) { TQHBoxLayout *layout = new TQHBoxLayout(this, 0, KDialog::spacingHint()); m_fieldCombo = new TQComboBox(this); m_fieldCombo->insertStringList(Filters::self()->getFieldNames()); layout->addWidget(m_fieldCombo); m_typeStack = new TQWidgetStack(this); m_typeStack->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); layout->addWidget(m_typeStack); m_valueStack = new TQWidgetStack(this); m_valueStack->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); layout->addWidget(m_valueStack); layout->setStretchFactor(m_valueStack, 10); // Initialize widgets WidgetHandlerManager::self()->createConditionWidgets(m_typeStack, m_valueStack, this); // Connect signals connect(m_fieldCombo, SIGNAL(activated(int)), this, SLOT(slotFieldChanged(int))); setFocusProxy(m_fieldCombo); } void FilterConditionWidget::setCondition(const Condition *condition) { m_condition = const_cast(condition); m_fieldCombo->setCurrentItem((int) condition->field()); WidgetHandlerManager::self()->setCondition(m_typeStack, m_valueStack, condition); } void FilterConditionWidget::slotFieldChanged(int field) { WidgetHandlerManager::self()->update((Field) field, m_typeStack, m_valueStack); if (m_condition) { // Update the current condition m_condition->setField((Field) field); slotTypeChanged(); } } void FilterConditionWidget::slotTypeChanged() { if (m_condition) { // Update the current condition m_condition->setType(WidgetHandlerManager::self()->getConditionType(m_condition->field(), m_typeStack)); slotValueChanged(); } } void FilterConditionWidget::slotValueChanged() { if (m_condition) { // Update the current condition m_condition->setValue(WidgetHandlerManager::self()->getConditionValue(m_condition->field(), m_valueStack)); } } FilterActionsList::FilterActionsList(TQWidget *parent) : TQGroupBox(1, Horizontal, i18n("Actions"), parent) { setEnabled(false); m_lister = new FilterActionWidgetLister(this); } void FilterActionsList::reset() { m_lister->clear(); setEnabled(false); } void FilterActionsList::loadRule(Rule *rule) { m_rule = rule; m_lister->loadActions(rule); setEnabled(true); } FilterActionWidgetLister::FilterActionWidgetLister(TQWidget *parent) : WidgetLister(parent, 0, 7), m_rule(0) { setMinimumWidth(400); } void FilterActionWidgetLister::loadActions(KFTPCore::Filter::Rule *rule) { const ActionChain *actions = rule->actions(); // Clear the current list setNumberShown(TQMAX(actions->count(), 0)); ActionChain::ConstIterator le = actions->end(); TQPtrList::Iterator wi = m_widgetList.begin(); for (ActionChain::ConstIterator i = actions->begin(); i != le; ++i, ++wi) static_cast((*wi))->setAction((*i)); m_rule = rule; } void FilterActionWidgetLister::slotMore() { WidgetLister::slotMore(); // Actually add the action and update the latest widget Action *action = new Action(Action::None, TQVariant()); const_cast(m_rule->actions())->append(action); static_cast(m_widgetList.last())->setAction(action); } void FilterActionWidgetLister::slotFewer() { // Actually remove the action Action *action = static_cast(m_widgetList.last())->action(); const_cast(m_rule->actions())->remove(action); WidgetLister::slotFewer(); } void FilterActionWidgetLister::slotClear() { if (m_rule) const_cast(m_rule->actions())->clear(); WidgetLister::slotClear(); } TQWidget *FilterActionWidgetLister::createWidget(TQWidget *parent) { return new FilterActionWidget(parent); } FilterActionWidget::FilterActionWidget(TQWidget *parent) : TQWidget(parent), m_action(0) { TQHBoxLayout *layout = new TQHBoxLayout(this, 0, KDialog::spacingHint()); m_actionCombo = new TQComboBox(this); m_actionCombo->insertStringList(Filters::self()->getActionNames()); layout->addWidget(m_actionCombo); m_valueStack = new TQWidgetStack(this); m_valueStack->setSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Fixed); layout->addWidget(m_valueStack); layout->setStretchFactor(m_valueStack, 10); // Initialize widgets WidgetHandlerManager::self()->createActionWidgets(m_valueStack, this); // Connect signals connect(m_actionCombo, SIGNAL(activated(int)), this, SLOT(slotActionChanged(int))); connect(m_actionCombo, SIGNAL(activated(int)), m_valueStack, SLOT(raiseWidget(int))); setFocusProxy(m_actionCombo); } void FilterActionWidget::setAction(const Action *action) { m_action = const_cast(action); m_actionCombo->setCurrentItem((int) action->type()); WidgetHandlerManager::self()->setAction(m_valueStack, action); } void FilterActionWidget::slotActionChanged(int field) { if (m_action) { m_action->setType((Action::Type) field); slotValueChanged(); } } void FilterActionWidget::slotValueChanged() { if (m_action) m_action->setValue(WidgetHandlerManager::self()->getActionValue(m_valueStack)); } } #include "filtereditor.moc"