Commit ebdd0544 authored by Michael Pyne's avatar Michael Pyne
Browse files

Refactor list view related code a bit, and add a "Remove all {functions,variables}" feature.

I should really add an undo command for that as well. :)

svn path=/trunk/playground/utils/abakus/; revision=468395
parent b38ed0ec
......@@ -16,18 +16,28 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <klocale.h>
#include <kpopupmenu.h>
#include <kdebug.h>
#include <qdragobject.h>
#include <qcursor.h>
#include <qheader.h>
#include "dragsupport.h"
#include "abakuslistview.h"
#include "valuemanager.h"
#include "function.h"
ListView::ListView(QWidget *parent, const char *name) :
KListView(parent, name)
KListView(parent, name), m_menu(0), m_usePopup(false), m_removeSingleId(0),
m_removeAllId(0)
{
setResizeMode(LastColumn);
setDragEnabled(true);
connect(this, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)),
SLOT(rightClicked(QListViewItem *, const QPoint &)));
}
QDragObject *ListView::dragObject()
......@@ -47,6 +57,71 @@ QDragObject *ListView::dragObject()
return drag;
}
void ListView::enablePopupHandler(bool enable)
{
if(enable == m_usePopup)
return;
m_usePopup = enable;
if(m_usePopup) {
if(m_menu)
kdError() << "ListView menu shouldn't exist here!\n";
m_menu = new KPopupMenu(this);
m_removeSingleId = m_menu->insertItem(removeItemString(), this, SLOT(removeSelected()));
m_removeAllId = m_menu->insertItem("Placeholder", this, SLOT(removeAllItems()));
}
else {
delete m_menu;
m_menu = 0;
}
}
QString ListView::removeItemString() const
{
return QString();
}
QString ListView::removeAllItemsString(unsigned count) const
{
Q_UNUSED(count);
return QString();
}
void ListView::removeSelectedItem(QListViewItem *item)
{
Q_UNUSED(item);
}
void ListView::removeAllItems()
{
}
bool ListView::isItemRemovable(QListViewItem *item) const
{
Q_UNUSED(item);
return false;
}
void ListView::rightClicked(QListViewItem *item, const QPoint &pt)
{
if(!m_usePopup)
return;
m_menu->setItemEnabled(m_removeSingleId, item && isItemRemovable(item));
m_menu->changeItem(m_removeAllId, removeAllItemsString(childCount()));
m_menu->popup(pt);
}
void ListView::removeSelected()
{
removeSelectedItem(selectedItem());
}
ValueListViewItem::ValueListViewItem(QListView *listView, const QString &name,
const Abakus::number_t &value) :
KListViewItem(listView, name), m_value(value)
......@@ -59,3 +134,99 @@ void ValueListViewItem::valueChanged()
setText(1, m_value.toString());
repaint();
}
void ValueListViewItem::valueChanged(const Abakus::number_t &newValue)
{
m_value = newValue;
valueChanged();
}
Abakus::number_t ValueListViewItem::itemValue() const
{
return m_value;
}
VariableListView::VariableListView(QWidget *parent, const char *name) :
ListView(parent, name)
{
enablePopupHandler(true);
}
QString VariableListView::removeItemString() const
{
return i18n("Remove selected variable");
}
QString VariableListView::removeAllItemsString(unsigned count) const
{
// count is unreliable because not all of the elements in the list view
// can be removed.
count = 0;
QStringList values = ValueManager::instance()->valueNames();
for(QStringList::ConstIterator value = values.constBegin(); value != values.constEnd(); ++value)
if(!ValueManager::instance()->isValueReadOnly(*value))
++count;
return i18n("Remove all variables (1 variable)",
"Remove all variables (%n variables)",
count);
}
bool VariableListView::isItemRemovable(QListViewItem *item) const
{
return !ValueManager::instance()->isValueReadOnly(item->text(0));
}
void VariableListView::removeSelectedItem(QListViewItem *item)
{
ValueManager::instance()->removeValue(item->text(0));
}
void VariableListView::removeAllItems()
{
ValueManager::instance()->slotRemoveUserVariables();
}
FunctionListView::FunctionListView(QWidget *parent, const char *name) :
ListView(parent, name)
{
enablePopupHandler(true);
}
QString FunctionListView::removeItemString() const
{
return i18n("Remove selected function");
}
QString FunctionListView::removeAllItemsString(unsigned count) const
{
return i18n("Remove all functions (1 function)",
"Remove all functions (%n functions)",
count);
}
bool FunctionListView::isItemRemovable(QListViewItem *item) const
{
return true;
}
void FunctionListView::removeSelectedItem(QListViewItem *item)
{
// Use section to get the beginning of the string up to (and not
// including) the first (
QString name = item->text(0).section('(', 0, 0);
FunctionManager::instance()->removeFunction(name);
}
void FunctionListView::removeAllItems()
{
QStringList fns = FunctionManager::instance()->functionList(FunctionManager::UserDefined);
for(QStringList::ConstIterator fn = fns.constBegin(); fn != fns.constEnd(); ++fn)
FunctionManager::instance()->removeFunction(*fn);
}
#include "abakuslistview.moc"
......@@ -23,13 +23,70 @@
#include "numerictypes.h"
class KPopupMenu;
class ListView : public KListView
{
Q_OBJECT
public:
ListView(QWidget *parent, const char *name = 0);
protected:
virtual QDragObject *dragObject();
/**
* Used to enable fancy popup handling support in subclasses. Subclasses
* also need to reimplement a few functions if they want to use this.
*
* This should be called in the subclass's constructor.
*/
void enablePopupHandler(bool enable);
/**
* If using the popup menu handling, the subclass needs to return a
* translated string of the form "Remove selected <itemtype>".
*/
virtual QString removeItemString() const;
/**
* If using the popup menu handling, the subclass needs to return a
* translated string of the form "Remove all <itemtype>s." I recommend
* also appending a " (%n <itemtype>s), which you can use the @p count
* parameter for.
*/
virtual QString removeAllItemsString(unsigned count) const;
protected slots:
/**
* If using the popup menu handing, the subclass needs to reimplement this
* function to remove the selected item, which is passed in as a
* parameter.
*/
virtual void removeSelectedItem(QListViewItem *item);
/**
* If using the popup menu handling, the subclass needs to reimplement this
* function to remove all items.
*/
virtual void removeAllItems();
/**
* If using the popup menu handling, this function may be called to
* determine whether the selected item given by @p item is removable.
*/
virtual bool isItemRemovable(QListViewItem *item) const;
private slots:
void rightClicked(QListViewItem *item, const QPoint &pt);
void removeSelected();
private:
KPopupMenu *m_menu;
bool m_usePopup;
int m_removeSingleId;
int m_removeAllId;
};
class ValueListViewItem : public KListViewItem
......@@ -39,11 +96,52 @@ class ValueListViewItem : public KListViewItem
// Will cause the list item to rethink the text.
void valueChanged();
void valueChanged(const Abakus::number_t &newValue);
void valueChanged(const Abakus::number_t &newValue) { m_value = newValue; valueChanged(); }
Abakus::number_t itemValue() const;
private:
Abakus::number_t m_value;
};
/**
* Subclass used for the list of variables.
*/
class VariableListView : public ListView
{
Q_OBJECT
public:
VariableListView(QWidget *parent, const char *name = 0);
protected:
virtual QString removeItemString() const;
virtual QString removeAllItemsString(unsigned count) const;
virtual bool isItemRemovable(QListViewItem *item) const;
protected slots:
virtual void removeSelectedItem(QListViewItem *item);
virtual void removeAllItems();
};
/**
* Subclass used for the list of functions.
*/
class FunctionListView : public ListView
{
Q_OBJECT
public:
FunctionListView(QWidget *parent, const char *name = 0);
protected:
virtual QString removeItemString() const;
virtual QString removeAllItemsString(unsigned count) const;
virtual bool isItemRemovable(QListViewItem *item) const;
protected slots:
virtual void removeSelectedItem(QListViewItem *item);
virtual void removeAllItems();
};
#endif
......@@ -121,17 +121,13 @@ MainWindow::MainWindow() : KMainWindow(0, "abakus-mainwindow"), m_popup(0), m_in
connect(m_edit, SIGNAL(textChanged()), SLOT(slotTextChanged()));
m_listSplitter = new QSplitter(Vertical, m_mainSplitter);
m_fnList = new ListView(m_listSplitter);
m_fnList = new FunctionListView(m_listSplitter);
m_fnList->addColumn("Functions");
m_fnList->addColumn("Value");
connect(m_fnList, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)),
SLOT(slotFnRightClick(QListViewItem *, const QPoint &)));
m_varList = new ListView(m_listSplitter);
m_varList = new VariableListView(m_listSplitter);
m_varList->addColumn("Variables");
m_varList->addColumn("Value");
connect(m_varList, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)),
SLOT(slotVarRightClick(QListViewItem *, const QPoint &)));
connect(FunctionManager::instance(), SIGNAL(signalFunctionAdded(const QString &)),
this, SLOT(slotNewFunction(const QString &)));
......@@ -728,53 +724,6 @@ QString MainWindow::interpolateExpression(const QString &text, ResultListViewTex
return str;
}
void MainWindow::slotFnRightClick(QListViewItem *item, const QPoint &point)
{
if(!item)
return;
static KPopupMenu *menu = 0;
if(!menu) {
menu = new KPopupMenu(this);
menu->insertItem(i18n("Remove &function"), this, SLOT(slotRemoveSelectedFn()));
}
menu->popup(point);
}
void MainWindow::slotVarRightClick(QListViewItem *item, const QPoint &point)
{
if(!item)
return;
static KPopupMenu *menu = 0;
static int enableMenuId = -1;
if(!menu) {
menu = new KPopupMenu(this);
enableMenuId = menu->insertItem(i18n("Remove &variable"), this, SLOT(slotRemoveSelectedVar()));
}
menu->setItemEnabled(enableMenuId, !ValueManager::instance()->isValueReadOnly(item->text(0)));
menu->popup(point);
}
void MainWindow::slotRemoveSelectedFn()
{
// Use section to get the beginning of the string up to (and not
// including) the first (
QString name = m_fnList->selectedItem()->text(0).section('(', 0, 0);
FunctionManager::instance()->removeFunction(name);
}
void MainWindow::slotRemoveSelectedVar()
{
QString name = m_varList->selectedItem()->text(0);
ValueManager::instance()->removeValue(name);
}
void MainWindow::slotPrecisionAuto()
{
Abakus::m_prec = -1;
......
......@@ -91,12 +91,6 @@ class MainWindow : public KMainWindow
void slotNewFunction(const QString &name);
void slotRemoveFunction(const QString &name);
void slotFnRightClick(QListViewItem *item, const QPoint &point);
void slotVarRightClick(QListViewItem *item, const QPoint &point);
void slotRemoveSelectedFn();
void slotRemoveSelectedVar();
private:
int getParenthesesLevel(const QString &str);
......
......@@ -76,6 +76,15 @@ void ValueManager::removeValue(const QString &name)
m_values.remove(name);
}
void ValueManager::slotRemoveUserVariables()
{
QStringList vars = valueNames();
for(QStringList::ConstIterator var = vars.constBegin(); var != vars.constEnd(); ++var)
if(!isValueReadOnly(*var))
removeValue(*var);
}
QStringList ValueManager::valueNames() const
{
return m_values.keys();
......
......@@ -54,6 +54,9 @@ class ValueManager : public QObject
void signalValueRemoved(const QString &name);
void signalValueChanged(const QString &name, Abakus::number_t newValue);
public slots:
void slotRemoveUserVariables();
private:
ValueManager(QObject *parent = 0, const char *name = "value manager");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment