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();
> 

Reply via email to