Commit 183fde7a authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD #175] - this is a filter mechanism for our module context menu. When the...

[ADD #175] - this is a filter mechanism for our module context menu. When the menu is opened, type your text and the menu will contain only the matching modules. Pressing escape resets the filter. Closing a menu resets the filter too.
parent 5a870215
......@@ -60,6 +60,7 @@
#include "../events/WRoiAssocEvent.h"
#include "../events/WRoiRemoveEvent.h"
#include "../guiElements/WQtModuleMetaInfo.h"
#include "../guiElements/WQtMenuFiltered.h"
#include "../networkEditor/WQtNetworkEditor.h"
#include "WQtBranchTreeItem.h"
#include "WQtColormapper.h"
......@@ -1045,28 +1046,28 @@ void WQtControlPanel::createCompatibleButtons( boost::shared_ptr< WModule > modu
}
// build the add menu
QMenu* m = new QMenu( m_moduleTreeWidget );
QMenu* m = new WQtMenuFiltered( m_moduleTreeWidget );
m->addActions( m_addModuleActionList );
m_addModuleAction->setDisabled( !m_addModuleActionList.size() || module ); // disable if no entry inside or a module was selected
delete( m_addModuleAction->menu() ); // ensure that combiners get free'd
m_addModuleAction->setMenu( m );
// build the prototype menu
m = new QMenu( m_moduleTreeWidget );
m = new WQtMenuFiltered( m_moduleTreeWidget );
m->addActions( m_connectWithPrototypeActionList );
m_connectWithPrototypeAction->setDisabled( !m_connectWithPrototypeActionList.size() ); // disable if no entry inside
delete( m_connectWithPrototypeAction->menu() ); // ensure that combiners get free'd
m_connectWithPrototypeAction->setMenu( m );
// build the module menu
m = new QMenu( m_moduleTreeWidget );
m = new WQtMenuFiltered( m_moduleTreeWidget );
m->addActions( m_connectWithModuleActionList );
m_connectWithModuleAction->setDisabled( !m_connectWithModuleActionList.size() ); // disable if no entry inside
delete m_connectWithModuleAction->menu();
m_connectWithModuleAction->setMenu( m );
// build the disconnect menu
m = new QMenu( m_moduleTreeWidget );
m = new WQtMenuFiltered( m_moduleTreeWidget );
m->addActions( m_disconnectActionList );
m_disconnectAction->setDisabled( !m_disconnectActionList.size() ); // disable if no entry inside
delete( m_disconnectAction->menu() ); // ensure that combiners get free'd
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "core/common/WLogger.h"
#include "WQtMenuFiltered.h"
#include "WQtMenuFiltered.moc"
WQtMenuFiltered::WQtMenuFiltered( QWidget* parent ):
QMenu( parent )
{
WQtMenuFiltered::setupFilter( this );
}
WQtMenuFiltered::WQtMenuFiltered( const QString& title, QWidget* parent ):
QMenu( title, parent )
{
WQtMenuFiltered::setupFilter( this );
}
WQtMenuFiltered::~WQtMenuFiltered()
{
// cleanup
}
void WQtMenuFiltered::setupFilter( WQtMenuFiltered* to )
{
// the widget contains the label and text filter box
QWidget* widget = new QWidget( to );
QHBoxLayout* layout = new QHBoxLayout( widget );
widget->setLayout( layout );
QLabel* label = new QLabel( "Filter:", widget );
to->m_edit = new QLineEdit( widget );
layout->addWidget( label );
layout->addWidget( to->m_edit );
// Add the widget as QWidgetAction
QWidgetAction* action = new QWidgetAction( to );
action->setDefaultWidget( widget );
to->addAction( action );
// give focus by default
to->m_edit->setFocus();
// update filter if text changes
connect( to->m_edit, SIGNAL( textChanged( const QString& ) ), to, SLOT( filterUpdate() ) );
}
void WQtMenuFiltered::keyPressEvent( QKeyEvent* e )
{
// Fake default QMenu feeling for these keys:
// Tab and Cursor
// Enter
// Escape
// But handle keys a-z,A-Z
if( ( ( e->key() >= Qt::Key_A ) && ( e->key() <= Qt::Key_Z ) ) ||
( ( e->key() >= Qt::Key_0 ) && ( e->key() <= Qt::Key_9 ) ) ||
( e->key() == Qt::Key_Underscore ) ||
( e->key() == Qt::Key_Space ) ||
( e->key() == Qt::Key_Minus ) ||
( e->key() == Qt::Key_Plus )
)
{
m_edit->setText( m_edit->text() + e->text() );
}
else if( ( e->key() == Qt::Key_Backspace ) )
{
m_edit->backspace();
}
else if( ( e->key() == Qt::Key_Escape ) ) // if escape and currently a filter is active: remove filter
{
if( m_edit->text() != "" )
{
resetFilter();
}
else
{
QMenu::keyPressEvent( e );
}
}
else
{
QMenu::keyPressEvent( e );
}
}
void WQtMenuFiltered::hideEvent( QHideEvent* /* e */ )
{
resetFilter();
}
void WQtMenuFiltered::filterUpdate()
{
QString filter = m_edit->text();
// NOTE: we ignore the first element. It is the filter widget.
// Important: we need to use a COPY of the action list as Qt sometimes removes actions there. I do not fully understand why.
typedef QList< QAction* > Actions;
Actions allActions = this->actions();
size_t nbLeft = 0; // keep track how many items are left
QAction* lastVisibleAction = NULL;
for( Actions::const_iterator a = allActions.begin() + 1; a != allActions.end(); ++a )
{
// strange but I had the issue that there was a NULL item in this list.
if( ( *a ) != NULL )
{
QString s = ( *a )->text();
// match value against filter
if( s.contains( filter, Qt::CaseInsensitive ) )
{
( *a )->setVisible( true );
nbLeft++;
lastVisibleAction = *a;
}
else
{
( *a )->setVisible( false );
}
}
}
// if only one item is left, select it automatically
if( nbLeft == 1 )
{
setActiveAction( lastVisibleAction );
}
}
void WQtMenuFiltered::resetFilter()
{
// reset text filter. This triggers filterUpdate!
m_edit->setText( "" );
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WQTMENUFILTERED_H
#define WQTMENUFILTERED_H
#include <QtGui/QKeyEvent>
#include <QtGui/QMenu>
#include <QtGui/QLineEdit>
#include <QtGui/QLabel>
#include <QtGui/QWidget>
#include <QtGui/QWidgetAction>
#include <QtGui/QHBoxLayout>
/**
* A menu derived from QMenu with additional filtering.
*/
class WQtMenuFiltered: public QMenu
{
Q_OBJECT
public:
/**
* Create filtered menu.
*
* \param parent parent widget
*/
explicit WQtMenuFiltered( QWidget* parent = 0 );
/**
* Create filtered menu.
*
* \param title
* \param parent
*/
WQtMenuFiltered( const QString& title, QWidget* parent = 0 );
/**
* Destructor.
*/
virtual ~WQtMenuFiltered();
public slots:
/**
* Updates the filter
*/
void filterUpdate();
/**
* Resets the filter. All elements are visible again.
*/
void resetFilter();
protected:
/**
* Grab key events. Used for filtering.
*
* \param e the key event
*/
virtual void keyPressEvent( QKeyEvent* e );
/**
* Called when hiding the menu. Used to reset the filter.
*
* \param e the event
*/
void hideEvent( QHideEvent* e );
private:
/**
* Setup filter on given menu
*
* \param to the menu
*/
static void setupFilter( WQtMenuFiltered* to );
/**
* Filter textfield
*/
QLineEdit* m_edit;
};
#endif // WQTMENUFILTERED_H
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