allow to search and higlight options

This commit is contained in:
Denis Rouzaud 2016-05-30 17:11:32 +02:00
parent f3102bbf8f
commit a1369955de
4 changed files with 242 additions and 1 deletions

View File

@ -1023,6 +1023,7 @@ void QgsOptions::iconSizeChanged( const QString &iconSize )
QgisApp::instance()->setIconSizes( iconSize.toInt() );
}
void QgsOptions::uiThemeChanged( const QString &theme )
{
if ( theme == QgsApplication::themeName() )

View File

@ -16,17 +16,26 @@
#include "qgsoptionsdialogbase.h"
#include <QCheckBox>
#include <QDialog>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QListWidget>
#include <QListWidgetItem>
#include <QMessageBox>
#include <QPainter>
#include <QScrollBar>
#include <QStackedWidget>
#include <QSplitter>
#include <QStackedWidget>
#include <QTimer>
#include "qgsfilterlineedit.h"
#include "qgslogger.h"
QgsOptionsDialogBase::QgsOptionsDialogBase( const QString& settingsKey, QWidget* parent, Qt::WindowFlags fl, QSettings* settings )
: QDialog( parent, fl )
, mOptsKey( settingsKey )
@ -35,6 +44,7 @@ QgsOptionsDialogBase::QgsOptionsDialogBase( const QString& settingsKey, QWidget*
, mOptStackedWidget( nullptr )
, mOptSplitter( nullptr )
, mOptButtonBox( nullptr )
, mSearchLineEdit( nullptr )
, mDialogTitle( QLatin1String( "" ) )
, mIconOnly( false )
, mSettings( settings )
@ -92,6 +102,7 @@ void QgsOptionsDialogBase::initOptionsBase( bool restoreUi, const QString& title
mOptSplitter = findChild<QSplitter*>( QStringLiteral( "mOptionsSplitter" ) );
mOptButtonBox = findChild<QDialogButtonBox*>( QStringLiteral( "buttonBox" ) );
QFrame* buttonBoxFrame = findChild<QFrame*>( QStringLiteral( "mButtonBoxFrame" ) );
mSearchLineEdit = findChild<QgsFilterLineEdit*>( "mSearchLineEdit" );
if ( !mOptListWidget || !mOptStackedWidget || !mOptSplitter || !optionsFrame )
{
@ -130,6 +141,12 @@ void QgsOptionsDialogBase::initOptionsBase( bool restoreUi, const QString& title
connect( mOptStackedWidget, SIGNAL( currentChanged( int ) ), this, SLOT( optionsStackedWidget_CurrentChanged( int ) ) );
connect( mOptStackedWidget, SIGNAL( widgetRemoved( int ) ), this, SLOT( optionsStackedWidget_WidgetRemoved( int ) ) );
if ( mSearchLineEdit )
{
mSearchLineEdit->setShowSearchIcon( true );
connect( mSearchLineEdit, &QgsFilterLineEdit::textChanged, this, &QgsOptionsDialogBase::searchText );
}
mInit = true;
if ( restoreUi )
@ -196,6 +213,70 @@ void QgsOptionsDialogBase::restoreOptionsBaseUi( const QString& title )
mOptListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );
}
void QgsOptionsDialogBase::searchText( QString text )
{
if ( !mOptStackedWidget )
return;
mOptStackedWidget->show();
if ( mOptButtonBox )
mOptButtonBox->show();
// hide all page if text has to be search, show them all otherwise
for ( int r = 0; r < mOptListWidget->count(); ++r )
{
mOptListWidget->setRowHidden( r, !text.isEmpty() );
}
QPair< QgsSearchHighlightOptionWidget, int > rsw;
Q_FOREACH ( rsw, mRegisteredSearchWidgets )
{
rsw.first.reset();
if ( !text.isEmpty() && rsw.first.searchHighlight( text ) )
{
QgsDebugMsg( QString( "Found %1 in %2 (tab: %3)" )
.arg( text )
.arg( rsw.first.widgetName() )
.arg( mOptListWidget->item( rsw.second )->text() ) );
mOptListWidget->setRowHidden( rsw.second, false );
}
}
if ( mOptListWidget->isRowHidden( mOptStackedWidget->currentIndex() ) )
{
for ( int r = 0; r < mOptListWidget->count(); ++r )
{
if ( !mOptListWidget->isRowHidden( r ) )
{
mOptListWidget->setCurrentRow( r );
return;
}
}
// if no page can be shown, hide stack widget
mOptStackedWidget->hide();
if ( mOptButtonBox )
mOptButtonBox->hide();
}
}
void QgsOptionsDialogBase::registerTextSearch()
{
mRegisteredSearchWidgets.clear();
for ( int i = 0; i < mOptStackedWidget->count(); i++ )
{
Q_FOREACH ( QWidget* w, mOptStackedWidget->widget( i )->findChildren<QWidget*>() )
{
QgsSearchHighlightOptionWidget shw = QgsSearchHighlightOptionWidget( w );
QgsDebugMsg( QString( "Registering: %1 %2" ).arg( w->objectName() ).arg( shw.isValid() ? "valid" : "invalid" ) );
if ( shw.isValid() )
{
mRegisteredSearchWidgets.append( qMakePair( shw, i ) );
}
}
}
}
void QgsOptionsDialogBase::showEvent( QShowEvent* e )
{
if ( mInit )
@ -208,6 +289,11 @@ void QgsOptionsDialogBase::showEvent( QShowEvent* e )
QTimer::singleShot( 0, this, SLOT( warnAboutMissingObjects() ) );
}
if ( mSearchLineEdit )
{
registerTextSearch();
}
QDialog::showEvent( e );
}
@ -281,6 +367,8 @@ void QgsOptionsDialogBase::optionsStackedWidget_WidgetRemoved( int indx )
{
// will need to take item first, if widgets are set for item in future
delete mOptListWidget->item( indx );
registerTextSearch();
}
void QgsOptionsDialogBase::warnAboutMissingObjects()
@ -292,3 +380,91 @@ void QgsOptionsDialogBase::warnAboutMissingObjects()
QMessageBox::Ok,
QMessageBox::Ok );
}
QgsSearchHighlightOptionWidget::QgsSearchHighlightOptionWidget( QWidget* widget )
: mWidget( nullptr )
, mOriginalPalette( QPalette() )
, mColorRole( QPalette::Window )
, mColor( Qt::yellow )
, mText( [=]( QWidget* ) {return QString();} )
{
if ( !widget )
{
return;
}
if ( qobject_cast<QLabel*>( widget ) )
{
mColorRole = QPalette::Window;
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QLabel*>( widget )->text() : QString(); };
}
else if ( qobject_cast<QCheckBox*>( widget ) )
{
mColorRole = QPalette::Button;
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QCheckBox*>( widget )->text() : QString(); };
}
else if ( qobject_cast<QGroupBox*>( widget ) )
{
mColorRole = QPalette::WindowText;
mText = [=]( QWidget * widget ) {return widget ? qobject_cast<QGroupBox*>( widget )->title() : QString(); };
}
else
{
return;
}
mWidget = widget;
mOriginalPalette = mWidget->palette();
}
QgsSearchHighlightOptionWidget::~QgsSearchHighlightOptionWidget()
{
}
bool QgsSearchHighlightOptionWidget::isValid()
{
return mWidget;
}
bool QgsSearchHighlightOptionWidget::searchHighlight( QString searchText )
{
bool found = false;
if ( !mWidget )
return found;
if ( !searchText.isEmpty() )
{
QString origText = mText( mWidget );
if ( origText.contains( searchText, Qt::CaseInsensitive ) )
{
found = true;
}
}
if ( found )
{
QPalette pal( mOriginalPalette );
pal.setColor( mColorRole, mColor );
mWidget->setAutoFillBackground( true );
mWidget->setPalette( pal );
}
return found;
}
void QgsSearchHighlightOptionWidget::reset()
{
if ( mWidget )
{
mWidget->setPalette( mOriginalPalette );
}
}
QString QgsSearchHighlightOptionWidget::widgetName()
{
QString name;
if ( mWidget )
name = mWidget->objectName();
return name;
}

View File

@ -18,17 +18,50 @@
#define QGSOPTIONSDIALOGBASE_H
#include "qgisgui.h"
#include <functional>
#include <QDialog>
#include <QPointer>
#include <QSettings>
#include <QStyledItemDelegate>
#include "qgis_gui.h"
class QDialogButtonBox;
class QListWidget;
class QModelIndex;
class QPalette;
class QPainter;
class QStackedWidget;
class QStyleOptionViewItem;
class QSplitter;
class QgsFilterLineEdit;
class GUI_EXPORT QgsSearchHighlightOptionWidget
{
public:
explicit QgsSearchHighlightOptionWidget( QWidget* widget = 0 );
~QgsSearchHighlightOptionWidget();
bool isValid();
bool searchHighlight( QString searchText );
void reset();
QString widgetName();
private:
QWidget* mWidget;
QPalette mOriginalPalette;
QPalette::ColorRole mColorRole;
QColor mColor;
std::function < QString( QWidget* ) > mText;
};
/** \ingroup gui
* \class QgsOptionsDialogBase
* A base dialog for options and properties dialogs that offers vertical tabs.
@ -80,6 +113,14 @@ class GUI_EXPORT QgsOptionsDialogBase : public QDialog
*/
bool iconOnly() {return mIconOnly;}
public slots:
/**
* searchText searches for a text in all the pages of the stacked widget and highlight the results
* @param text the text to search
*/
void searchText( QString text );
protected slots:
void updateOptionsListVerticalTabs();
void optionsStackedWidget_CurrentChanged( int indx );
@ -92,12 +133,17 @@ class GUI_EXPORT QgsOptionsDialogBase : public QDialog
virtual void updateWindowTitle();
void registerTextSearch();
QList< QPair< QgsSearchHighlightOptionWidget, int > > mRegisteredSearchWidgets;
QString mOptsKey;
bool mInit;
QListWidget* mOptListWidget;
QStackedWidget* mOptStackedWidget;
QSplitter* mOptSplitter;
QDialogButtonBox* mOptButtonBox;
QgsFilterLineEdit* mSearchLineEdit;
QString mDialogTitle;
bool mIconOnly;
// pointer to app or custom, external QSettings

View File

@ -57,6 +57,9 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QgsFilterLineEdit" name="mSearchLineEdit"/>
</item>
<item>
<widget class="QListWidget" name="mOptionsListWidget">
<property name="minimumSize">
@ -1806,6 +1809,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbxEvaluateDefaultValues">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When digitizing a new feature, default values are retrieved from the database. With this option turned on, the default values will be evaluated at the time of digitizing. With this option turned off, the default values will be evaluated at the time of saving.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Evaluate default values</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -5466,6 +5479,11 @@
<header>qgsautheditorwidgets.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
<header>qgsfilterlineedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mOptionsListWidget</tabstop>