Skip to content

Commit

Permalink
allow to search and higlight options
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Feb 11, 2017
1 parent f3102bb commit a136995
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/app/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() )
Expand Down
178 changes: 177 additions & 1 deletion src/gui/qgsoptionsdialogbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand All @@ -35,6 +44,7 @@ QgsOptionsDialogBase::QgsOptionsDialogBase( const QString& settingsKey, QWidget*
, mOptStackedWidget( nullptr )
, mOptSplitter( nullptr )
, mOptButtonBox( nullptr )
, mSearchLineEdit( nullptr )
, mDialogTitle( QLatin1String( "" ) )
, mIconOnly( false )
, mSettings( settings )
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 )
Expand All @@ -208,6 +289,11 @@ void QgsOptionsDialogBase::showEvent( QShowEvent* e )
QTimer::singleShot( 0, this, SLOT( warnAboutMissingObjects() ) );
}

if ( mSearchLineEdit )
{
registerTextSearch();
}

QDialog::showEvent( e );
}

Expand Down Expand Up @@ -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()
Expand All @@ -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;
}
46 changes: 46 additions & 0 deletions src/gui/qgsoptionsdialogbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 );
Expand All @@ -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
Expand Down
18 changes: 18 additions & 0 deletions src/ui/qgsoptionsbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down

0 comments on commit a136995

Please sign in to comment.