kde-workspace/khotkeys/kcm_hotkeys/conditions/conditions_widget.cpp
2015-05-20 13:39:58 +00:00

427 lines
11 KiB
C++

/* Copyright (C) 2009 Michael Jansen <kde@michael-jansen.biz>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "conditions/conditions_widget.h"
#include "conditions/conditions_list_base.h"
#include "conditions/conditions_list.h"
#include "conditions/condition.h"
#include "conditions/conditions.h"
#include "conditions/conditions_visitor.h"
#include "conditions/existing_window_condition.h"
#include "conditions/active_window_condition.h"
#include "windows_helper/window_selection_list.h"
#include "helper_widgets/window_definition_list_widget.h"
#include "condition_type_menu.h"
#include <QtCore/QStack>
#include <KDebug>
class BuildTree : public KHotKeys::ConditionsVisitor
{
public:
BuildTree(QTreeWidget *tree);
void build();
virtual void visitConditionsListBase(KHotKeys::Condition_list_base *list);
virtual void visitConditionsList(KHotKeys::Condition_list *list);
virtual void visitCondition( KHotKeys::Condition *condition );
QMap<QTreeWidgetItem*, KHotKeys::Condition*> _items;
private:
QTreeWidget *_tree;
QStack<QTreeWidgetItem*> _stack;
};
BuildTree::BuildTree( QTreeWidget *tree )
: _tree(tree)
{
_stack.push(_tree->invisibleRootItem());
}
void BuildTree::visitCondition(KHotKeys::Condition *cond)
{
QTreeWidgetItem *item = new QTreeWidgetItem(_stack.top());
item->setText(0, cond->description());
_items.insert(item, cond);
}
void BuildTree::visitConditionsList(KHotKeys::Condition_list *list)
{
Q_ASSERT(_stack.count()==1);
QTreeWidgetItem *parent = _stack.top();
QTreeWidgetItem *item = new QTreeWidgetItem(parent);
item->setText(0, i18nc("Add a new condition", "And"));
_items.insert(item, list);
_stack.push(item);
for(KHotKeys::Condition_list_base::Iterator it = list->begin();
it != list->end();
++it)
{
(*it)->visit(this);
}
_tree->expandAll();
}
void BuildTree::visitConditionsListBase(KHotKeys::Condition_list_base *list)
{
QTreeWidgetItem *parent = _stack.top();
QTreeWidgetItem *item = new QTreeWidgetItem(parent);
item->setText(0, list->description());
_items.insert(item, list);
_stack.push(item);
for(KHotKeys::Condition_list_base::Iterator it = list->begin();
it != list->end();
++it)
{
// QTreeWidgetItem *child = new QTreeWidgetItem(item);
// child->setText(0, (*it)->description());
// _items.insert(child, list);
(*it)->visit(this);
}
_stack.pop();
}
ConditionsWidget::ConditionsWidget(QWidget *parent)
: QWidget(parent)
,_working(NULL)
,_changed(false)
{
ui.setupUi(this);
connect(ui.edit_button, SIGNAL(clicked(bool)),
SLOT(slotEdit()));
connect(ui.delete_button, SIGNAL(clicked(bool)),
SLOT(slotDelete()));
ui.new_button->setMenu(new ConditionTypeMenu(this));
connect(ui.new_button->menu(), SIGNAL(triggered(QAction*)),
SLOT(slotNew(QAction*)));
}
ConditionsWidget::~ConditionsWidget()
{
delete _working; _working = NULL;
}
void ConditionsWidget::copyFromObject()
{
Q_ASSERT(_conditions_list);
// Clear the tree and delete our old working copy
ui.tree->clear();
if (_working) delete _working;
// Create the working copy
_working = _conditions_list->copy();
Q_ASSERT(_working->count() == _conditions_list->count());
kDebug() << _working->count();
kDebug() << _conditions_list->count();
// Build the tree
BuildTree builder(ui.tree);
_working->visit(&builder);
_items = builder._items;
_changed = false;
}
void ConditionsWidget::copyToObject()
{
kDebug();
Q_ASSERT(_conditions_list);
if (!_conditions_list) return;
// Just copy the content from our working copy to the original
// Remove the old content
qDeleteAll(*_conditions_list);
_conditions_list->clear();
for (KHotKeys::Condition_list::Iterator it = _working->begin();
it != _working->end();
++it)
{
kDebug();
_conditions_list->append((*it)->copy());
}
Q_ASSERT(_working->count() == _conditions_list->count());
_changed = false;
}
void ConditionsWidget::emitChanged(bool chgd)
{
if (_changed == ( chgd || _changed ))
return;
// Once changed always changed
_changed = chgd || _changed;
emit changed(_changed);
}
bool ConditionsWidget::hasChanges() const
{
return _changed;
}
void ConditionsWidget::setConditionsList( KHotKeys::Condition_list *list)
{
Q_ASSERT(list);
_conditions_list = list;
}
void ConditionsWidget::slotDelete()
{
QTreeWidgetItem *citem = ui.tree->currentItem();
// If no item is selected just return
if (!citem) return;
// TODO: Ask for confirmation before deleting
// Get the currently select condition
KHotKeys::Condition *cond = _items.value(citem);
// Do not allow deleting the root item
if (cond==_working) return;
delete cond;
delete citem;
emitChanged(true);
}
void ConditionsWidget::slotEdit()
{
// Get the currently select condition
QTreeWidgetItem *citem = ui.tree->currentItem();
// If no item is selected just return
if (!citem) return;
KHotKeys::Condition *cond = _items.value(citem);
// Currently we only allow editing existing and active window conditions.
// TODO: Disable buttons according to active item
KHotKeys::Existing_window_condition *ewcond =
dynamic_cast<KHotKeys::Existing_window_condition*>(cond);
if (ewcond)
{
WindowDefinitionListDialog dialog(ewcond->window());
switch (dialog.exec())
{
case QDialog::Accepted:
{
citem->setText(0, ewcond->description());
emitChanged(true);
}
break;
case QDialog::Rejected:
// Nothing to do
return;
default:
Q_ASSERT(false);
return;
}
}
KHotKeys::Active_window_condition *awcond =
dynamic_cast<KHotKeys::Active_window_condition*>(cond);
if (awcond)
{
WindowDefinitionListDialog dialog(awcond->window());
switch (dialog.exec())
{
case QDialog::Accepted:
{
citem->setText(0, awcond->description());
emitChanged(true);
}
break;
case QDialog::Rejected:
// Nothing to do
return;
default:
Q_ASSERT(false);
return;
}
}
return;
}
void ConditionsWidget::slotNew(QAction* action)
{
QTreeWidgetItem *citem = ui.tree->currentItem();
KHotKeys::Condition *cond;
if (!citem)
{
// If no item is selected create the new condition as a top level
// condition
cond = _working;
citem = ui.tree->invisibleRootItem()->child(0);
Q_ASSERT(citem);
}
else
{
// Get the currently select condition
cond = _items.value(citem);
}
// get the nearest list
KHotKeys::Condition_list_base *parent = dynamic_cast<KHotKeys::Condition_list_base*>(cond);
if (!parent)
{
parent = cond->parent();
citem = citem->parent();
}
Q_ASSERT(parent);
switch (action->data().toInt())
{
case ConditionTypeMenu::ACTIVE_WINDOW:
{
KHotKeys::Windowdef_list *list = new KHotKeys::Windowdef_list();
WindowDefinitionListDialog dialog(list);
switch (dialog.exec())
{
case QDialog::Accepted:
{
KHotKeys::Active_window_condition *cond =
new KHotKeys::Active_window_condition(list, parent);
QTreeWidgetItem *item = new QTreeWidgetItem(citem);
item->setText(0, cond->description());
_items.insert(item, cond);
}
break;
case QDialog::Rejected:
delete list;
return;
default:
Q_ASSERT(false);
delete list;
return;
}
}
break;
case ConditionTypeMenu::EXISTING_WINDOW:
{
KHotKeys::Windowdef_list *list = new KHotKeys::Windowdef_list();
WindowDefinitionListDialog dialog(list);
switch (dialog.exec())
{
case QDialog::Accepted:
{
KHotKeys::Existing_window_condition *cond =
new KHotKeys::Existing_window_condition(list, parent);
QTreeWidgetItem *item = new QTreeWidgetItem(citem);
item->setText(0, cond->description());
_items.insert(item, cond);
}
break;
case QDialog::Rejected:
delete list;
return;
default:
Q_ASSERT(false);
delete list;
return;
}
}
break;
case ConditionTypeMenu::AND:
{
KHotKeys::And_condition *cond = new KHotKeys::And_condition(parent);
QTreeWidgetItem *item = new QTreeWidgetItem(citem);
item->setText(0, cond->description());
_items.insert(item, cond);
}
break;
case ConditionTypeMenu::OR:
{
KHotKeys::Or_condition *cond = new KHotKeys::Or_condition(parent);
QTreeWidgetItem *item = new QTreeWidgetItem(citem);
item->setText(0, cond->description());
_items.insert(item, cond);
}
break;
case ConditionTypeMenu::NOT:
{
KHotKeys::Not_condition *cond = new KHotKeys::Not_condition(parent);
QTreeWidgetItem *item = new QTreeWidgetItem(citem);
item->setText(0, cond->description());
_items.insert(item, cond);
}
break;
default:
Q_ASSERT(false);
break;
}
emitChanged(true);
}
#include "moc_conditions_widget.cpp"