Ping
> -----Original Message-----
> From: lyx-devel@lists.lyx.org
> [mailto:lyx-devel@lists.lyx.org] On Behalf Of venom00
> Sent: Friday, April 22, 2011 5:24 PM
> To: lyx-devel@lists.lyx.org
> Cc: 'Vincent van Ravesteijn'; 'Peter Kümmel'
> Subject: RE: Too much options in LyX
>
> OK, I've fixed everything you suggested me.
>
> Here's the new version. I've tried to limit the search to
> QAbstractButton,
> QGroupBox and Qlabel but no big improvements. Maybe we should
> simply add a
> delay, so the user can type the whole search query and then
> start the search,
> 200-400 ms. Other ideas?
>
> Now when the dialog is hidden the search box is reset.
> The "rubber" button will be in the next patch, maybe. :P
>
> Thanks for your comments!
> venom00
>
> Index: src/frontends/qt4/GuiDocument.h
> ===================================================================
> --- src/frontends/qt4/GuiDocument.h (revisione 38474)
> +++ src/frontends/qt4/GuiDocument.h (copia locale)
> @@ -77,6 +77,7 @@
> void updateDefaultFormat();
> void updatePagestyle(std::string const &, std::string const &);
> bool isChildIncluded(std::string const &);
> + void hideView();
>
> ///
> BufferParams const & params() const { return bp_; }
> Index: src/frontends/qt4/GuiDocument.cpp
> ===================================================================
> --- src/frontends/qt4/GuiDocument.cpp (revisione 38474)
> +++ src/frontends/qt4/GuiDocument.cpp (copia locale)
> @@ -2139,6 +2139,11 @@
> includeonlys_.end(), child) !=
> includeonlys_.end());
> }
>
> +void GuiDocument::hideView() {
> + Dialog::hideView();
> + // Reset the search box
> + this->docPS->resetSearch();
> +}
>
> void GuiDocument::applyView()
> {
> Index: src/frontends/qt4/GuiPrefs.cpp
> ===================================================================
> --- src/frontends/qt4/GuiPrefs.cpp (revisione 38474)
> +++ src/frontends/qt4/GuiPrefs.cpp (copia locale)
> @@ -3201,6 +3201,11 @@
> modules_[i]->update(rc);
> }
>
> +void GuiPreferences::hideView() {
> + Dialog::hideView();
> + // Reset the search box
> + this->prefsPS->resetSearch();
> +}
>
> void GuiPreferences::applyView()
> {
> Index: src/frontends/qt4/PanelStack.cpp
> ===================================================================
> --- src/frontends/qt4/PanelStack.cpp (revisione 38474)
> +++ src/frontends/qt4/PanelStack.cpp (copia locale)
> @@ -15,12 +15,21 @@
> #include "qt_helpers.h"
>
> #include "support/debug.h"
> +#include "support/foreach.h"
>
> +#include <QApplication>
> +#include <QAbstractButton>
> +#include <QComboBox>
> #include <QFontMetrics>
> +#include <QGroupBox>
> #include <QHBoxLayout>
> #include <QHeaderView>
> +#include <QLabel>
> +#include <QLineEdit>
> +#include <QListWidget>
> #include <QStackedWidget>
> #include <QTreeWidget>
> +#include <QVBoxLayout>
>
> #include "support/lassert.h"
>
> @@ -35,7 +44,9 @@
> {
> list_ = new QTreeWidget(this);
> stack_ = new QStackedWidget(this);
> + search_ = new QLineEdit(this);
>
> + // Configure tree
> list_->setRootIsDecorated(false);
> list_->setColumnCount(1);
> list_->header()->hide();
> @@ -43,14 +54,28 @@
> list_->header()->setStretchLastSection(false);
> list_->setMinimumSize(list_->viewport()->size());
>
> +
> connect(list_, SIGNAL(currentItemChanged(QTreeWidgetItem*,
> QTreeWidgetItem*)),
> this, SLOT(switchPanel(QTreeWidgetItem *,
> QTreeWidgetItem*)));
> connect(list_, SIGNAL(itemClicked (QTreeWidgetItem*, int)),
> this, SLOT(itemSelected(QTreeWidgetItem *, int)));
>
> - QHBoxLayout * layout = new QHBoxLayout(this);
> - layout->addWidget(list_, 0);
> - layout->addWidget(stack_, 1);
> + // Configure the search box
> +#if QT_VERSION >= 0x040700
> + search_->setPlaceholderText(qt_("Search"));
> +#endif
> +
> + connect(search_, SIGNAL(textChanged(QString)), this,
> SLOT(filterChanged(QString)));
> +
> + // Create the output layout, horizontal plus a VBox on
> the left with the
> search
> + // box and the tree
> + QVBoxLayout * left_layout = new QVBoxLayout();
> + left_layout->addWidget(search_, 0);
> + left_layout->addWidget(list_, 1);
> +
> + QHBoxLayout * main_layout = new QHBoxLayout(this);
> + main_layout->addLayout(left_layout, 0);
> + main_layout->addWidget(stack_, 1);
> }
>
>
> @@ -136,11 +161,18 @@
> return;
>
> // if we have a category, expand the tree and go to the
> - // first item
> + // first enabled item
> if (item->childCount() > 0) {
> item->setExpanded(true);
> - if (previous && previous->parent() != item)
> - switchPanel( item->child(0), previous );
> + if (previous && previous->parent() != item) {
> + // Looks for a child not disabled
> + for (int i = 0; i < item->childCount(); ++i) {
> + if (item->child(i)->flags() &
> Qt::ItemIsEnabled)
> {
> +
> switchPanel(item->child(i), previous);
> + break;
> + }
> + }
> + }
> }
> else if (QWidget * w = widget_map_.value(item, 0)) {
> stack_->setCurrentWidget(w);
> @@ -148,6 +180,106 @@
> }
>
>
> +void PanelStack::filterChanged(QString const & search) {
> + bool enable_all = search.length() == 0;
> +
> + // If the search string is empty we have to re-enable everything
> + if (enable_all) {
> + foreach (QTreeWidgetItem * tree_item, panel_map_) {
> + tree_item->setDisabled(false);
> + tree_item->setTextColor(0,
> QApplication::palette().color(QPalette::Active, QPalette::Text));
> + }
> + } else {
> + // Otherwise disable everything and then re-enable panes
> matching the
> + // search criteria
> + foreach (QTreeWidgetItem * tree_item, panel_map_) {
> + tree_item->setDisabled(true);
> + tree_item->setTextColor(0,
> QApplication::palette().color(QPalette::Disabled, QPalette::Text));
> + }
> + }
> +
> + foreach (QTreeWidgetItem * tree_item, panel_map_) {
> +
> + // Current widget
> + QWidget * pane_widget = this->widget_map_[tree_item];
> +
> + // First of all we look in the pane name
> + bool pane_matches = tree_item->text(0).contains(search,
> Qt::CaseInsensitive);
> +
> + // If the tree item has an associated pane
> + if (pane_widget) {
> +
> + // Collect all the children widgets (recursive)
> + QList<QWidget *> children =
> pane_widget->findChildren<QWidget *>();
> +
> + // Loops on the list of children widgets
> + size_t last_child = children.size();
> + for (size_t child_index = 0;
> child_index != last_child;
> ++child_index) {
> + bool widget_matches = false;
> +
> + // Try to cast to the most
> common widgets and
> looks in it's content by each
> + // It's bad OOP, it would be
> nice to have a
> QWidget::toString() overloaded by
> + // each widget, but this would
> require to change
> Qt or subclass each widget.
> + // Note that we have to ignore
> the amperstand
> symbol
> + if (QAbstractButton * button =
> qobject_cast<QAbstractButton *>(children[child_index])) {
> + widget_matches =
> button->text().replace('&', "")
> + .contains(search,
> Qt::CaseInsensitive);
> +
> + } else if (QGroupBox * group_box =
> qobject_cast<QGroupBox *>(children[child_index])) {
> + widget_matches =
> group_box->title().replace('&', "")
> + .contains(search,
> Qt::CaseInsensitive);
> +
> + } else if (QLabel * label =
> qobject_cast<QLabel
> *>(children[child_index])) {
> + widget_matches =
> label->text().replace('&', "")
> + .contains(search,
> Qt::CaseInsensitive);
> +
> + } else if (QLineEdit * line_edit =
> qobject_cast<QLineEdit *>(children[child_index])) {
> + widget_matches =
> line_edit->text().replace('&', "")
> + .contains(search,
> Qt::CaseInsensitive);
> +
> + } else if (QListWidget * list_widget =
> qobject_cast<QListWidget *>(children[child_index])) {
> + widget_matches =
> (list_widget->findItems(search, Qt::MatchContains)).count() != 0;
> +
> + } else if (QTreeWidget * tree_view =
> qobject_cast<QTreeWidget *>(children[child_index])) {
> + widget_matches =
> (tree_view->findItems(search, Qt::MatchContains)).count() != 0;
> +
> + } else if (QComboBox * combo_box =
> qobject_cast<QComboBox *>(children[child_index])) {
> + widget_matches =
> (combo_box->findText(search, Qt::MatchContains)) != -1;
> +
> + } else {
> + continue;
> + }
> +
> + // If this widget meets the
> search criteria
> + if (widget_matches && !enable_all) {
> + // The pane too meets the search
> criteria
> + pane_matches = true;
> + // Highlight the widget
> + QPalette widget_palette =
> children[child_index]->palette();
> +
> widget_palette.setColor(children[child_index]->foregroundRole(
> ), Qt::red);
> +
> children[child_index]->setPalette(widget_palette);
> + } else {
> + // Reset the color of the widget
> +
> children[child_index]->setPalette(
> QApplication::palette( children[child_index] ) );
> + }
> + }
> +
> + // If the pane meets the search criteria
> + if (pane_matches && !enable_all) {
> + // Expand and enable the pane
> and his ancestors
> (typically just the parent)
> + QTreeWidgetItem * item = tree_item;
> + do {
> + item->setExpanded(true);
> + item->setDisabled(false);
> + item->setTextColor(0,
> QApplication::palette().color(QPalette::Active, QPalette::Text));
> + item = item->parent();
> + } while (item);
> + }
> + }
> +
> + }
> +}
> +
> void PanelStack::itemSelected(QTreeWidgetItem * item, int)
> {
> // de-select the category if a child is selected
> @@ -162,6 +294,10 @@
> qMax(list_->height(), stack_->height()));
> }
>
> +void PanelStack::resetSearch() {
> + this->search_->setText("");
> +}
> +
> } // namespace frontend
> } // namespace lyx
>
> Index: src/frontends/qt4/PanelStack.h
> ===================================================================
> --- src/frontends/qt4/PanelStack.h (revisione 38474)
> +++ src/frontends/qt4/PanelStack.h (copia locale)
> @@ -16,6 +16,7 @@
> #include <QWidget>
> #include <QHash>
>
> +class QLineEdit;
> class QTreeWidget;
> class QTreeWidgetItem;
> class QStackedWidget;
> @@ -44,8 +45,12 @@
> bool isCurrentPanel(QString const & name) const;
> ///
> QSize sizeHint() const;
> + /// resets the search box
> + void resetSearch();
>
> public Q_SLOTS:
> + /// the option filter changed
> + void filterChanged(QString const & search);
> /// set current panel from an item
> void switchPanel(QTreeWidgetItem * it, QTreeWidgetItem
> * previous = 0);
> /// click on the tree
> @@ -61,6 +66,9 @@
>
> WidgetMap widget_map_;
>
> + /// contains the search box
> + QLineEdit * search_;
> +
> /// contains the items
> QTreeWidget * list_;
>
> Index: src/frontends/qt4/Dialog.h
> ===================================================================
> --- src/frontends/qt4/Dialog.h (revisione 38474)
> +++ src/frontends/qt4/Dialog.h (copia locale)
> @@ -119,7 +119,7 @@
> virtual void applyView() = 0;
>
> /// Hide the dialog from sight
> - void hideView();
> + virtual void hideView();
>
> /// Prepare dialog and display it.
> void showView();
> Index: src/frontends/qt4/GuiPrefs.h
> ===================================================================
> --- src/frontends/qt4/GuiPrefs.h (revisione 38474)
> +++ src/frontends/qt4/GuiPrefs.h (copia locale)
> @@ -67,6 +67,7 @@
>
> void apply(LyXRC & rc) const;
> void updateRc(LyXRC const & rc);
> + void hideView();
>
> public Q_SLOTS:
> void change_adaptor();
>