A new user interface for you! Read more...

File permanent-searchbar.diff of Package kdeaddons3

--- ./konq-plugins/dirfilter/dirfilterplugin.cpp	2006/12/01 10:54:21	1.1
+++ ./konq-plugins/dirfilter/dirfilterplugin.cpp	2006/12/01 13:51:40
@@ -19,6 +19,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 
+#include <qpainter.h>
+#include <qstyle.h>
 #include <qtimer.h>
 #include <qapplication.h>
 #include <qlabel.h>
@@ -45,6 +47,7 @@
 #include <kstaticdeleter.h>
 #include <kgenericfactory.h>
 #include <kparts/browserextension.h>
+#include <kio/netaccess.h>
 
 #include "dirfilterplugin.h"
 
@@ -122,6 +125,7 @@
 
   cfg.writeEntry ("ShowCount", showCount);
   cfg.writeEntry ("UseMultipleFilters", useMultipleFilters);
+  cfg.writeEntry ("SearchMode", searchMode);
   cfg.sync();
 }
 
@@ -135,6 +139,7 @@
 
   showCount = cfg.readBoolEntry ("ShowCount", false);
   useMultipleFilters = cfg.readBoolEntry ("UseMultipleFilters", true);
+  searchMode = (SearchModes)cfg.readNumEntry("SearchMode", Beagle);
   m_pid = getpid ();
   m_bSettingsLoaded = true;
 }
@@ -144,7 +149,9 @@
 DirFilterPlugin::DirFilterPlugin (QObject* parent, const char* name,
                                   const QStringList&)
                 :KParts::Plugin (parent, name),
+                 m_beagled_running(false),
                  m_pFilterMenu(0),
+                 m_popupMenu(0),
                  m_searchWidget(0)
 {
   m_part = ::qt_cast<KonqDirPart*>(parent);
@@ -172,40 +179,77 @@
   QHBox *hbox = new QHBox(m_part->widget());
   hbox->hide();
 
-  KAction *clear = new KAction(i18n("Clear Filter Field"),
+  m_clear = new KAction(i18n("Clear Filter Field"),
                                QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
                                0, 0, 0, actionCollection(), "clear_filter");
 
-  clear->setWhatsThis(i18n("Clear filter field<p>Clears the content of the filter field."));
-
-  if ( ::qt_cast<KListView*>(m_part->scrollWidget()) )
-  {
-    m_searchWidget = new KListViewSearchLine(hbox);
-    static_cast<KListViewSearchLine*>(m_searchWidget)->setListView(static_cast<KListView*>(m_part->scrollWidget()));
-  }
-  else if ( ::qt_cast<QIconView*>(m_part->scrollWidget()) )
-  {
-    m_searchWidget = new KIconViewSearchLine(hbox);
-    static_cast<KIconViewSearchLine*>(m_searchWidget)->setIconView(static_cast<QIconView*>(m_part->scrollWidget()));
-  }
+  m_clear->setWhatsThis(i18n("Clear filter field<p>Clears the content of the filter field."));
 
-
-  if ( m_searchWidget )
-  {
-    QWhatsThis::add(m_searchWidget, i18n("Enter here a text which an item in the view must contain anywhere to be shown."));
-    connect(clear, SIGNAL(activated()), m_searchWidget, SLOT(clear()));
-  }
+  m_searchWidget = new SearchBarCombo(hbox, "search combo");
+  m_searchWidget->setDuplicatesEnabled(false);
+  m_searchWidget->setMaxCount(5);
+  m_searchWidget->setFixedWidth(180);
+  connect(m_searchWidget, SIGNAL(activated(const QString &)),
+                         SLOT(startSearch(const QString &)));
+  connect(m_searchWidget, SIGNAL(iconClicked()), SLOT(showSelectionMenu()));
 
   KWidgetAction *filterAction = new KWidgetAction(hbox, i18n("Filter Field"),
                                                   0, 0, 0, actionCollection(), "toolbar_filter_field");
   filterAction->setShortcutConfigurable(false);
+
+  m_timerDetectBeagle = new QTimer(this);
+  connect(m_timerDetectBeagle, SIGNAL(timeout()), SLOT(slotDetectBeagle()));
+  m_timerDetectBeagle->start(0, true);
 }
 
 DirFilterPlugin::~DirFilterPlugin()
 {
+  m_timerDetectBeagle->stop();
+  if (checking_for_beagle) {
+      checking_for_beagle = false;
+      qApp->exit_loop();
+  }
   delete m_pFilterMenu;
 }
 
+void DirFilterPlugin::slotDetectBeagle()
+{
+  KIO::UDSEntry uds;
+  const KURL kurl("beagle:?beagled-status");
+  if (checking_for_beagle) {
+    m_timerDetectBeagle->start(10, true);
+    return;
+  }
+  checking_for_beagle = true;
+  bool stat_result = KIO::NetAccess::stat(kurl, uds);
+  if (!checking_for_beagle)
+     return;
+  if (!stat_result) {
+     switchToFilter();
+  }
+  else {
+     m_beagled_running = true;
+     if (SessionManager::self()->searchMode==SessionManager::Beagle) {
+       setIcon();
+       slotUseBeagle();
+     }
+     else {
+       setIcon();
+       switchToFilter();
+     }
+  }
+  checking_for_beagle = false;
+}
+
+void DirFilterPlugin::startSearch(const QString &search)
+{
+	if( SessionManager::self()->searchMode == SessionManager::Filter )
+		return;
+
+	emit m_part->extension()->openURLRequest("beagle:"+search);
+}
+
+
 void DirFilterPlugin::slotOpenURL ()
 {
   KURL url = m_part->url();
@@ -218,12 +262,13 @@
     //Clears the hidden list which is by now outdated...
     if (m_searchWidget)
     {
-      SessionManager::self()->save(m_pURL, m_searchWidget->text());
+      SessionManager::self()->save(m_pURL, m_searchWidget->lineEdit()->text());
       m_searchWidget->clear();
 
       QString typedFilter(SessionManager::self()->restoreTypedFilter(url));
       m_searchWidget->completionObject()->addItem(typedFilter);
-      m_searchWidget->setText(typedFilter);
+      m_searchWidget->lineEdit()->setText(typedFilter);
+      setIcon();
     }
 
     m_pURL = url;
@@ -485,6 +530,162 @@
     m_part->openURL (m_part->url());
 }
 
+void DirFilterPlugin::setIcon()
+{
+	QString hinttext;
+	QPixmap m_searchIcon;
+	if (SessionManager::self()->searchMode == SessionManager::Filter) {
+		m_searchIcon = SmallIcon("filter");
+		hinttext = i18n("Filter This Folder");
+	}
+	else {
+		m_searchIcon = SmallIcon("kio_beagle");
+		hinttext = i18n("Search Index");
+	}
+
+	if (m_beagled_running) {
+        	// Create a bit wider icon with arrow
+		QPixmap arrowmap = QPixmap(m_searchIcon.width()+5,m_searchIcon.height()+5);
+		arrowmap.fill(m_searchWidget->lineEdit()->backgroundColor());
+		QPainter p( &arrowmap );
+		p.drawPixmap(0, 2, m_searchIcon);
+		QStyle::SFlags arrowFlags = QStyle::Style_Default;
+		m_searchWidget->style().drawPrimitive(QStyle::PE_ArrowDown, &p, QRect(arrowmap.width()-6, 
+	    	arrowmap.height()-6, 6, 5), m_searchWidget->colorGroup(), arrowFlags, QStyleOption() );
+		p.end();
+		m_searchIcon = arrowmap;
+	}
+
+	m_searchWidget->setIcon(m_searchIcon);
+	static_cast<KLineEdit*>(m_searchWidget->lineEdit())->setClickMessage(hinttext);
+}
+
+void DirFilterPlugin::showSelectionMenu()
+{
+	if (!m_beagled_running)
+		return;
+
+	if(!m_popupMenu)
+	{
+		m_popupMenu = new QPopupMenu(m_searchWidget, "search mode selection");
+		m_popupMenu->insertItem(SmallIcon("kio_beagle"), i18n("Search Index"), this, SLOT(slotUseBeagle()));
+		m_popupMenu->insertItem(SmallIcon("filter"), i18n("Filter This Folder"), this, SLOT(slotUseFilter()));
+	}
+	m_popupMenu->popup(m_searchWidget->mapToGlobal(QPoint(0, m_searchWidget->height() + 1)), 0);
+}
+
+void DirFilterPlugin::slotUseBeagle()
+{
+	SessionManager::self()->searchMode = SessionManager::Beagle;
+	m_searchWidget->setLineEdit(new KLineEdit(m_searchWidget));
+	m_searchWidget->lineEdit()->installEventFilter(this);
+	m_searchWidget->setFocus();
+	QWhatsThis::add(m_searchWidget->lineEdit(), i18n("Enter here a text which shall be searched on the whole system in the Beagle index."));
+	connect(m_clear, SIGNAL(activated()), m_searchWidget->lineEdit(), SLOT(clear()));
+	setIcon();
+}
+
+void DirFilterPlugin::slotUseFilter()
+{
+        switchToFilter();
+	m_searchWidget->setFocus();
+}
+
+void DirFilterPlugin::switchToFilter()
+{
+	SessionManager::self()->searchMode = SessionManager::Filter;
+	if ( ::qt_cast<KListView*>(m_part->scrollWidget()) ) {
+		KListViewSearchLine* searchlineWidget = new KListViewSearchLine(m_searchWidget);
+		m_searchWidget->setLineEdit(searchlineWidget);
+		searchlineWidget->setListView(static_cast<KListView*>(m_part->scrollWidget()));
+	}
+	else if ( ::qt_cast<QIconView*>(m_part->scrollWidget()) ) {
+		KIconViewSearchLine* searchlineWidget = new KIconViewSearchLine(m_searchWidget);
+		m_searchWidget->setLineEdit(searchlineWidget);
+		searchlineWidget->setIconView(static_cast<QIconView*>(m_part->scrollWidget()));
+	}
+	m_searchWidget->lineEdit()->installEventFilter(this);
+	QWhatsThis::add(m_searchWidget->lineEdit(), i18n("Enter here a text which an item in the view must contain anywhere to be shown."));
+	connect(m_clear, SIGNAL(activated()), m_searchWidget->lineEdit(), SLOT(clear()));
+	setIcon();
+}
+
+SearchBarCombo::SearchBarCombo(QWidget *parent, const char *name) :
+  KHistoryCombo(parent, name),
+  m_pluginActive(true)
+{
+	connect(this, SIGNAL(cleared()), SLOT(historyCleared()));
+}
+
+const QPixmap &SearchBarCombo::icon() const
+{
+	return m_icon;
+}
+
+void SearchBarCombo::setIcon(const QPixmap &icon)
+{
+	m_icon = icon;
+
+	if(count() == 0)
+	{
+		insertItem(m_icon, 0);
+	}
+	else
+	{
+		for(int i = 0; i < count(); i++)
+		{
+			changeItem(m_icon, text(i), i);
+		}
+	}
+}
+
+int SearchBarCombo::findHistoryItem(const QString &searchText)
+{
+	for(int i = 0; i < count(); i++)
+	{
+		if(text(i) == searchText)
+		{
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+void SearchBarCombo::mousePressEvent(QMouseEvent *e)
+{
+	int x0 = QStyle::visualRect( style().querySubControlMetrics( QStyle::CC_ComboBox, this, QStyle::SC_ComboBoxEditField ), this ).x();
+
+	if(e->x() > x0 + 2 && e->x() < lineEdit()->x())
+	{
+		emit iconClicked();
+
+		e->accept();
+	}
+	else
+	{
+		KHistoryCombo::mousePressEvent(e);
+	}
+}
+
+void SearchBarCombo::historyCleared()
+{
+	setIcon(m_icon);
+}
+
+void SearchBarCombo::setPluginActive(bool pluginActive)
+{
+	m_pluginActive = pluginActive;
+}
+
+void SearchBarCombo::show()
+{
+	if(m_pluginActive)
+	{
+		KHistoryCombo::show();
+	}
+}
+
 typedef KGenericFactory<DirFilterPlugin> DirFilterFactory;
 K_EXPORT_COMPONENT_FACTORY (libdirfilterplugin, DirFilterFactory("dirfilterplugin"))
 
--- ./konq-plugins/dirfilter/dirfilterplugin.rc	2006/12/01 10:54:23	1.1
+++ ./konq-plugins/dirfilter/dirfilterplugin.rc	2006/12/01 10:54:38
@@ -9,5 +9,6 @@
   <Action name="filterdir"/>
 </ToolBar>
 <ToolBar fullWidth="true" name="locationToolBar" newline="true"><text>Filter Toolbar</text>
+  <Action name="toolbar_filter_field" />
 </ToolBar>
 </kpartplugin>
--- ./konq-plugins/dirfilter/dirfilterplugin.h	2006/12/01 10:54:19	1.1
+++ ./konq-plugins/dirfilter/dirfilterplugin.h	2006/12/01 13:09:31
@@ -27,10 +27,13 @@
 #include <kfileitem.h>
 #include <klibloader.h>
 #include <kparts/plugin.h>
+#include <kcombobox.h>
 
 class KActionMenu;
 class KonqDirPart;
 class KLineEdit;
+class SearchBarCombo;
+class QPopupMenu;
 
 
 namespace KParts
@@ -54,8 +57,12 @@
   void save (const KURL& url, const QStringList& filters);
   void save (const KURL& url, const QString& typedFilter);
 
+  /** Possible search modes */
+  enum SearchModes { Beagle = 0, Filter };
+
   bool showCount;
   bool useMultipleFilters;
+  SearchModes searchMode;
 
 protected:
 
@@ -76,6 +83,7 @@
   QMap<QString,QString> m_typedFilter;
 };
 
+static bool checking_for_beagle = false;
 
 class DirFilterPlugin : public KParts::Plugin
 {
@@ -108,6 +116,7 @@
 
   void loadSettings();
   void saveSettings();
+  void setIcon();
 
 private slots:
   void slotReset();
@@ -119,14 +128,86 @@
   void slotItemSelected(int);
   void slotItemRemoved(const KFileItem *);
   void slotItemsAdded(const KFileItemList &);
+  void showSelectionMenu();
+  void slotUseBeagle();
+  void slotUseFilter();
+  void slotDetectBeagle();
+  void startSearch(const QString &search);
 
 private:
+  void switchToFilter();
+
+
+  bool m_beagled_running;
+  QTimer *m_timerDetectBeagle;
   KURL m_pURL;
   KonqDirPart* m_part;
   KActionMenu* m_pFilterMenu;
+  QPopupMenu* m_popupMenu;
+  KAction *m_clear;
 
-  KLineEdit *m_searchWidget;
+  SearchBarCombo *m_searchWidget;
   QMap<QString,MimeInfo> m_pMimeInfo;
   typedef QMap<QString,MimeInfo>::Iterator MimeInfoIterator;
 };
+
+/**
+ * Combo box which catches mouse clicks on the pixmap.
+ */
+class SearchBarCombo : public KHistoryCombo
+{
+	Q_OBJECT
+
+	public:
+		/**
+		 * Constructor.
+		 */
+		SearchBarCombo(QWidget *parent, const char *name);
+
+		/**
+		 * Returns the icon currently displayed in the combo box.
+		 */
+		const QPixmap &icon() const;
+
+		/**
+		 * Sets the icon displayed in the combo box.
+		 */
+		void setIcon(const QPixmap &icon);
+
+		/**
+		 * Finds a history item by its text.
+		 * @return The item number, or -1 if the item is not found.
+		 */
+		int findHistoryItem(const QString &text);
+
+		/**
+		 * Sets whether the plugin is active. It can be inactive
+		 * in case the current Konqueror part isn't a KHTML part.
+		 */
+		void setPluginActive(bool pluginActive);
+
+	public slots:
+		virtual void show();
+
+	signals:
+		/**
+		 * Emitted when the icon was clicked.
+		 */
+		void iconClicked();
+
+	protected:
+		/**
+		 * Captures mouse clicks and emits iconClicked() if the icon
+		 * was clicked.
+		 */
+		virtual void mousePressEvent(QMouseEvent *e);
+
+	private slots:
+		void historyCleared();
+
+	private:
+		QPixmap m_icon;
+		bool    m_pluginActive;
+};
+
 #endif