|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2005 by Tobi Vollebregt <tobivollebregt@gmail.com>
|
|
|
|
Copyright (C) 2004 by Vinay Khaitan <vkhaitan@iitk.ac.in>
|
|
|
|
Copyright (C) 2004 Arend van Beelen jr. <arend@auton.nl>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; see the file COPYING. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <dcopclient.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <kconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <khtml_part.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <klineedit.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
#include <kprocess.h>
|
|
|
|
#include <kprotocolinfo.h>
|
|
|
|
#include <kprotocolmanager.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kurifilter.h>
|
|
|
|
|
|
|
|
#include <kio/job.h>
|
|
|
|
|
|
|
|
#include <kparts/mainwindow.h>
|
|
|
|
#include <kparts/partmanager.h>
|
|
|
|
|
|
|
|
#include <qpainter.h>
|
|
|
|
#include <qpopupmenu.h>
|
|
|
|
#include <qtimer.h>
|
|
|
|
#include <qstyle.h>
|
|
|
|
#include <qwhatsthis.h>
|
|
|
|
#include "searchbar.h"
|
|
|
|
|
|
|
|
typedef KGenericFactory<SearchBarPlugin> SearchBarPluginFactory;
|
|
|
|
K_EXPORT_COMPONENT_FACTORY(libsearchbarplugin,
|
|
|
|
SearchBarPluginFactory("searchbarplugin"))
|
|
|
|
|
|
|
|
|
|
|
|
SearchBarPlugin::SearchBarPlugin(QObject *parent, const char *name,
|
|
|
|
const QStringList &) :
|
|
|
|
KParts::Plugin(parent, name),
|
|
|
|
m_searchCombo(0),
|
|
|
|
m_searchMode(UseSearchProvider),
|
|
|
|
m_urlEnterLock(false),
|
|
|
|
m_gsTimer(this),
|
|
|
|
m_googleMode(GoogleOnly)
|
|
|
|
{
|
|
|
|
m_searchCombo = new SearchBarCombo(0L, "search combo");
|
|
|
|
m_searchCombo->setDuplicatesEnabled(false);
|
|
|
|
m_searchCombo->setMaxCount(5);
|
|
|
|
m_searchCombo->setFixedWidth(180);
|
|
|
|
m_searchCombo->setLineEdit(new KLineEdit(m_searchCombo));
|
|
|
|
m_searchCombo->lineEdit()->installEventFilter(this);
|
|
|
|
m_searchCombo->listBox()->setFocusProxy(m_searchCombo);
|
|
|
|
|
|
|
|
m_popupMenu = 0;
|
|
|
|
m_googleMenu = 0;
|
|
|
|
|
|
|
|
m_searchComboAction = new KWidgetAction(m_searchCombo, i18n("Search Bar"), 0,
|
|
|
|
0, 0, actionCollection(), "toolbar_search_bar");
|
|
|
|
m_searchComboAction->setShortcutConfigurable(false);
|
|
|
|
|
|
|
|
connect(m_searchCombo, SIGNAL(activated(const QString &)),
|
|
|
|
SLOT(startSearch(const QString &)));
|
|
|
|
connect(m_searchCombo, SIGNAL(iconClicked()), SLOT(showSelectionMenu()));
|
|
|
|
|
|
|
|
QWhatsThis::add(m_searchCombo, i18n("Search Bar<p>"
|
|
|
|
"Enter a search term. Click on the icon to change search mode or provider."));
|
|
|
|
|
|
|
|
new KAction( i18n( "Focus Searchbar" ), CTRL+Key_S,
|
|
|
|
this, SLOT(focusSearchbar()),
|
|
|
|
actionCollection(), "focus_search_bar");
|
|
|
|
|
|
|
|
configurationChanged();
|
|
|
|
|
|
|
|
KParts::MainWindow *mainWin = static_cast<KParts::MainWindow*>(parent);
|
|
|
|
|
|
|
|
//Grab the part manager. Don't know of any other way, and neither does Tronical, so..
|
|
|
|
KParts::PartManager *partMan = static_cast<KParts::PartManager*>(mainWin->child(0, "KParts::PartManager"));
|
|
|
|
if (partMan)
|
|
|
|
{
|
|
|
|
connect(partMan, SIGNAL(activePartChanged(KParts::Part*)),
|
|
|
|
SLOT (partChanged (KParts::Part*)));
|
|
|
|
partChanged(partMan->activePart());
|
|
|
|
}
|
|
|
|
|
|
|
|
connect(this, SIGNAL(gsCompleteDelayed()), SLOT(gsStartDelay()));
|
|
|
|
connect(&m_gsTimer, SIGNAL(timeout()), SLOT(gsMakeCompletionList()));
|
|
|
|
connect(m_searchCombo->listBox(), SIGNAL(highlighted(const QString&)), SLOT(gsSetCompletedText(const QString&)));
|
|
|
|
connect(m_searchCombo, SIGNAL(activated(const QString&)), SLOT(gsPutTextInBox(const QString&)));
|
|
|
|
}
|
|
|
|
|
|
|
|
SearchBarPlugin::~SearchBarPlugin()
|
|
|
|
{
|
|
|
|
KConfig *config = kapp->config();
|
|
|
|
config->setGroup("SearchBar");
|
|
|
|
config->writeEntry("Mode", (int) m_searchMode);
|
|
|
|
config->writeEntry("CurrentEngine", m_currentEngine);
|
|
|
|
config->writeEntry("GoogleSuggestMode", m_googleMode);
|
|
|
|
|
|
|
|
delete m_searchCombo;
|
|
|
|
m_searchCombo = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
QChar delimiter()
|
|
|
|
{
|
|
|
|
KConfig config( "kuriikwsfilterrc", true, false );
|
|
|
|
config.setGroup( "General" );
|
|
|
|
return config.readNumEntry( "KeywordDelimiter", ':' );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SearchBarPlugin::eventFilter(QObject *o, QEvent *e)
|
|
|
|
{
|
|
|
|
if( o==m_searchCombo->lineEdit() && e->type() == QEvent::KeyPress )
|
|
|
|
{
|
|
|
|
QKeyEvent *k = (QKeyEvent *)e;
|
|
|
|
QString text = k->text();
|
|
|
|
if(!text.isEmpty())
|
|
|
|
{
|
|
|
|
if(k->key() != Qt::Key_Return && k->key() != Key_Enter && k->key() != Key_Escape)
|
|
|
|
{
|
|
|
|
emit gsCompleteDelayed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(k->state() & ControlButton)
|
|
|
|
{
|
|
|
|
if(k->key()==Key_Down)
|
|
|
|
{
|
|
|
|
nextSearchEntry();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(k->key()==Key_Up)
|
|
|
|
{
|
|
|
|
previousSearchEntry();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (k->key() == Key_Up || k->key() == Key_Down)
|
|
|
|
{
|
|
|
|
if(m_searchCombo->listBox()->isVisible())
|
|
|
|
{
|
|
|
|
qApp->sendEvent(m_searchCombo->listBox(), e);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (k->key() == Key_Enter || k->key() == Key_Return)
|
|
|
|
{
|
|
|
|
/*- Fix a bug which caused the searchbar to search for the completed
|
|
|
|
input instead of the literal input when enter was pressed and
|
|
|
|
the listbox was visible.
|
|
|
|
if(m_searchCombo->listBox()->isVisible())
|
|
|
|
{
|
|
|
|
qApp->sendEvent(m_searchCombo->listBox(),e);
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
if (k->key() == Key_Escape)
|
|
|
|
{
|
|
|
|
m_searchCombo->listBox()->hide();
|
|
|
|
if (m_searchCombo->lineEdit()->hasSelectedText())
|
|
|
|
{
|
|
|
|
m_searchCombo->lineEdit()->setText(m_searchCombo->currentText().left(m_searchCombo->lineEdit()->selectionStart()));
|
|
|
|
}
|
|
|
|
m_gsTimer.stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::nextSearchEntry()
|
|
|
|
{
|
|
|
|
if(m_searchMode == FindInThisPage)
|
|
|
|
{
|
|
|
|
m_searchMode = UseSearchProvider;
|
|
|
|
if(m_searchEngines.count())
|
|
|
|
{
|
|
|
|
m_currentEngine = *m_searchEngines.at(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_currentEngine = "google";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QStringList::ConstIterator it = m_searchEngines.find(m_currentEngine);
|
|
|
|
it++;
|
|
|
|
if(it==m_searchEngines.end())
|
|
|
|
{
|
|
|
|
m_searchMode = FindInThisPage;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_currentEngine = *it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::previousSearchEntry()
|
|
|
|
{
|
|
|
|
if(m_searchMode == FindInThisPage)
|
|
|
|
{
|
|
|
|
m_searchMode = UseSearchProvider;
|
|
|
|
if(m_searchEngines.count())
|
|
|
|
{
|
|
|
|
m_currentEngine = *m_searchEngines.fromLast();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_currentEngine = "google";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QStringList::ConstIterator it = m_searchEngines.find(m_currentEngine);
|
|
|
|
if(it==m_searchEngines.begin())
|
|
|
|
{
|
|
|
|
m_searchMode = FindInThisPage;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
it--;
|
|
|
|
m_currentEngine = *it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::startSearch(const QString &_search)
|
|
|
|
{
|
|
|
|
if(m_urlEnterLock || _search.isEmpty() || !m_part)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_gsTimer.stop();
|
|
|
|
m_searchCombo->listBox()->hide();
|
|
|
|
|
|
|
|
QString search = _search.section('(', 0, 0).stripWhiteSpace();
|
|
|
|
|
|
|
|
if(m_searchMode == FindInThisPage)
|
|
|
|
{
|
|
|
|
m_part->findText(search, 0);
|
|
|
|
m_part->findTextNext();
|
|
|
|
}
|
|
|
|
else if(m_searchMode == UseSearchProvider)
|
|
|
|
{
|
|
|
|
m_urlEnterLock = true;
|
|
|
|
KService::Ptr service;
|
|
|
|
KURIFilterData data;
|
|
|
|
QStringList list;
|
|
|
|
list << "kurisearchfilter" << "kuriikwsfilter";
|
|
|
|
|
|
|
|
service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(m_currentEngine));
|
|
|
|
if (service) {
|
|
|
|
const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + delimiter();
|
|
|
|
data.setData( searchProviderPrefix + search );
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!service || !KURIFilter::self()->filterURI(data, list))
|
|
|
|
{
|
|
|
|
data.setData( QString::fromLatin1( "google" ) + delimiter() + search );
|
|
|
|
KURIFilter::self()->filterURI( data, list );
|
|
|
|
}
|
|
|
|
|
|
|
|
if(KApplication::keyboardMouseState() & Qt::ControlButton)
|
|
|
|
{
|
|
|
|
KParts::URLArgs args;
|
|
|
|
args.setNewTab(true);
|
|
|
|
emit m_part->browserExtension()->createNewWindow( data.uri(), args );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit m_part->browserExtension()->openURLRequest(data.uri());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(m_searchCombo->text(0).isEmpty())
|
|
|
|
{
|
|
|
|
m_searchCombo->changeItem(m_searchIcon, search, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(m_searchCombo->findHistoryItem(search) == -1)
|
|
|
|
{
|
|
|
|
m_searchCombo->insertItem(m_searchIcon, search, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_searchCombo->setCurrentText("");
|
|
|
|
m_urlEnterLock = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::setIcon()
|
|
|
|
{
|
|
|
|
QString hinttext;
|
|
|
|
if(m_searchMode == FindInThisPage)
|
|
|
|
{
|
|
|
|
m_searchIcon = SmallIcon("find");
|
|
|
|
hinttext = i18n("Find in This Page");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QString providername;
|
|
|
|
KService::Ptr service;
|
|
|
|
KURIFilterData data;
|
|
|
|
QStringList list;
|
|
|
|
list << "kurisearchfilter" << "kuriikwsfilter";
|
|
|
|
|
|
|
|
service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(m_currentEngine));
|
|
|
|
if (service) {
|
|
|
|
const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + delimiter();
|
|
|
|
data.setData( searchProviderPrefix + "some keyword" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (service && KURIFilter::self()->filterURI(data, list))
|
|
|
|
{
|
|
|
|
QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
|
|
|
|
if(iconPath.isEmpty())
|
|
|
|
{
|
|
|
|
m_searchIcon = SmallIcon("enhanced_browsing");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_searchIcon = QPixmap(iconPath);
|
|
|
|
}
|
|
|
|
providername = service->name();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_searchIcon = SmallIcon("google");
|
|
|
|
providername = "Google";
|
|
|
|
}
|
|
|
|
hinttext = i18n("%1 Search").arg(providername);;
|
|
|
|
}
|
|
|
|
static_cast<KLineEdit*>(m_searchCombo->lineEdit())->setClickMessage(hinttext);
|
|
|
|
|
|
|
|
// Create a bit wider icon with arrow
|
|
|
|
QPixmap arrowmap = QPixmap(m_searchIcon.width()+5,m_searchIcon.height()+5);
|
|
|
|
arrowmap.fill(m_searchCombo->lineEdit()->backgroundColor());
|
|
|
|
QPainter p( &arrowmap );
|
|
|
|
p.drawPixmap(0, 2, m_searchIcon);
|
|
|
|
QStyle::SFlags arrowFlags = QStyle::Style_Default;
|
|
|
|
m_searchCombo->style().drawPrimitive(QStyle::PE_ArrowDown, &p, QRect(arrowmap.width()-6,
|
|
|
|
arrowmap.height()-6, 6, 5), m_searchCombo->colorGroup(), arrowFlags, QStyleOption() );
|
|
|
|
p.end();
|
|
|
|
m_searchIcon = arrowmap;
|
|
|
|
|
|
|
|
m_searchCombo->setIcon(m_searchIcon);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::showSelectionMenu()
|
|
|
|
{
|
|
|
|
if(!m_popupMenu)
|
|
|
|
{
|
|
|
|
KService::Ptr service;
|
|
|
|
QPixmap icon;
|
|
|
|
KURIFilterData data;
|
|
|
|
QStringList list;
|
|
|
|
list << "kurisearchfilter" << "kuriikwsfilter";
|
|
|
|
|
|
|
|
m_popupMenu = new QPopupMenu(m_searchCombo, "search selection menu");
|
|
|
|
m_popupMenu->insertItem(SmallIcon("find"), i18n("Find in This Page"), this, SLOT(useFindInThisPage()), 0, 999);
|
|
|
|
m_popupMenu->insertSeparator();
|
|
|
|
|
|
|
|
int i=-1;
|
|
|
|
for (QStringList::ConstIterator it = m_searchEngines.begin(); it != m_searchEngines.end(); ++it )
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(*it));
|
|
|
|
if(!service)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + delimiter();
|
|
|
|
data.setData( searchProviderPrefix + "some keyword" );
|
|
|
|
|
|
|
|
if(KURIFilter::self()->filterURI(data, list))
|
|
|
|
{
|
|
|
|
QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
|
|
|
|
if(iconPath.isEmpty())
|
|
|
|
{
|
|
|
|
icon = SmallIcon("enhanced_browsing");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
icon = QPixmap( iconPath );
|
|
|
|
}
|
|
|
|
m_popupMenu->insertItem(icon, service->name(), i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_popupMenu->insertSeparator();
|
|
|
|
m_googleMenu = new KSelectAction(i18n("Use Google Suggest"), SmallIconSet("ktip"), 0, this, SLOT(selectGoogleSuggestMode()), m_popupMenu);
|
|
|
|
QStringList google_modes;
|
|
|
|
google_modes << i18n("For Google Only") << i18n("For All Searches") << i18n("Never");
|
|
|
|
m_googleMenu->setItems(google_modes);
|
|
|
|
m_googleMenu->plug(m_popupMenu);
|
|
|
|
m_popupMenu->insertItem(SmallIcon("enhanced_browsing"), i18n("Select Search Engines..."),
|
|
|
|
this, SLOT(selectSearchEngines()), 0, 1000);
|
|
|
|
connect(m_popupMenu, SIGNAL(activated(int)), SLOT(useSearchProvider(int)));
|
|
|
|
}
|
|
|
|
m_googleMenu->setCurrentItem(m_googleMode);
|
|
|
|
m_popupMenu->popup(m_searchCombo->mapToGlobal(QPoint(0, m_searchCombo->height() + 1)), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::useFindInThisPage()
|
|
|
|
{
|
|
|
|
m_searchMode = FindInThisPage;
|
|
|
|
setIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::useSearchProvider(int id)
|
|
|
|
{
|
|
|
|
if(id>900)
|
|
|
|
{
|
|
|
|
// Not a search engine entry selected
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_searchMode = UseSearchProvider;
|
|
|
|
m_currentEngine = *m_searchEngines.at(id);
|
|
|
|
setIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::selectSearchEngines()
|
|
|
|
{
|
|
|
|
KProcess *process = new KProcess;
|
|
|
|
|
|
|
|
*process << "kcmshell" << "ebrowsing";
|
|
|
|
|
|
|
|
connect(process, SIGNAL(processExited(KProcess *)), SLOT(searchEnginesSelected(KProcess *)));
|
|
|
|
|
|
|
|
if(!process->start())
|
|
|
|
{
|
|
|
|
kdDebug(1202) << "Couldn't invoke kcmshell." << endl;
|
|
|
|
delete process;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::searchEnginesSelected(KProcess *process)
|
|
|
|
{
|
|
|
|
if(!process || process->exitStatus() == 0)
|
|
|
|
{
|
|
|
|
KConfig *config = kapp->config();
|
|
|
|
config->setGroup("SearchBar");
|
|
|
|
config->writeEntry("CurrentEngine", m_currentEngine);
|
|
|
|
config->sync();
|
|
|
|
configurationChanged();
|
|
|
|
}
|
|
|
|
delete process;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::configurationChanged()
|
|
|
|
{
|
|
|
|
KConfig *config = new KConfig("kuriikwsfilterrc");
|
|
|
|
config->setGroup("General");
|
|
|
|
QString engine = config->readEntry("DefaultSearchEngine", "google");
|
|
|
|
|
|
|
|
QStringList favoriteEngines;
|
|
|
|
favoriteEngines << "google" << "google_groups" << "google_news" << "webster" << "dmoz" << "wikipedia";
|
|
|
|
favoriteEngines = config->readListEntry("FavoriteSearchEngines", favoriteEngines);
|
|
|
|
|
|
|
|
delete m_popupMenu;
|
|
|
|
m_popupMenu = 0;
|
|
|
|
m_searchEngines.clear();
|
|
|
|
m_searchEngines << engine;
|
|
|
|
for (QStringList::ConstIterator it = favoriteEngines.begin(); it != favoriteEngines.end(); ++it )
|
|
|
|
if(*it!=engine)
|
|
|
|
m_searchEngines << *it;
|
|
|
|
|
|
|
|
delete config;
|
|
|
|
if(engine.isEmpty())
|
|
|
|
{
|
|
|
|
m_providerName = "Google";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KDesktopFile file("searchproviders/" + engine + ".desktop", true, "services");
|
|
|
|
m_providerName = file.readName();
|
|
|
|
}
|
|
|
|
|
|
|
|
config = kapp->config();
|
|
|
|
config->setGroup("SearchBar");
|
|
|
|
m_searchMode = (SearchModes) config->readNumEntry("Mode", (int) UseSearchProvider);
|
|
|
|
m_currentEngine = config->readEntry("CurrentEngine", engine);
|
|
|
|
m_googleMode=(GoogleMode)config->readNumEntry("GoogleSuggestMode", GoogleOnly);
|
|
|
|
|
|
|
|
if ( m_currentEngine.isEmpty() )
|
|
|
|
m_currentEngine = "google";
|
|
|
|
|
|
|
|
setIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::partChanged(KParts::Part *newPart)
|
|
|
|
{
|
|
|
|
m_part = ::qt_cast<KHTMLPart*>(newPart);
|
|
|
|
|
|
|
|
//Delay since when destroying tabs part 0 gets activated for a bit, before the proper part
|
|
|
|
QTimer::singleShot(0, this, SLOT(updateComboVisibility()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::updateComboVisibility()
|
|
|
|
{
|
|
|
|
if (m_part.isNull() || !m_searchComboAction->isPlugged())
|
|
|
|
{
|
|
|
|
m_searchCombo->setPluginActive(false);
|
|
|
|
m_searchCombo->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_searchCombo->setPluginActive(true);
|
|
|
|
m_searchCombo->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::focusSearchbar()
|
|
|
|
{
|
|
|
|
QFocusEvent::setReason( QFocusEvent::Shortcut );
|
|
|
|
m_searchCombo->setFocus();
|
|
|
|
QFocusEvent::resetReason();
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Google Suggest code
|
|
|
|
|
|
|
|
void SearchBarPlugin::selectGoogleSuggestMode()
|
|
|
|
{
|
|
|
|
m_googleMode = (GoogleMode)m_googleMenu->currentItem();
|
|
|
|
KConfig *config = kapp->config();
|
|
|
|
config->setGroup("SearchBar");
|
|
|
|
config->writeEntry("GoogleSuggestMode", m_googleMode);
|
|
|
|
config->sync();
|
|
|
|
}
|
|
|
|
|
|
|
|
// adapted and modified by Tobi Vollebregt
|
|
|
|
// original code from Googlebar by Vinay Khaitan
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsStartDelay()
|
|
|
|
{
|
|
|
|
m_gsTimer.stop();
|
|
|
|
m_searchCombo->listBox()->hide();
|
|
|
|
// FIXME: make configurable
|
|
|
|
m_gsTimer.start(500, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsMakeCompletionList()
|
|
|
|
{
|
|
|
|
if ((m_googleMode==GoogleOnly && m_currentEngine != "google") || m_googleMode==Never)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!m_searchCombo->currentText().isEmpty())
|
|
|
|
{
|
|
|
|
KIO::TransferJob* tj =
|
|
|
|
KIO::get(KURL("http://www.google.com/complete/search?hl=en&js=true&qu=" + m_searchCombo->currentText()), false, false);
|
|
|
|
connect(tj, SIGNAL(data(KIO::Job*, const QByteArray&)), this, SLOT(gsDataArrived(KIO::Job*, const QByteArray&)));
|
|
|
|
connect(tj, SIGNAL(result(KIO::Job*)), this, SLOT(gsJobFinished(KIO::Job*)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsDataArrived(KIO::Job*, const QByteArray& data)
|
|
|
|
{
|
|
|
|
m_gsData += QString::fromUtf8(data.data());
|
|
|
|
}
|
|
|
|
|
|
|
|
static QString reformatNumber(const QString& number)
|
|
|
|
{
|
|
|
|
static const char suffix[] = { 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
|
|
|
|
QString s = number.stripWhiteSpace();
|
|
|
|
uint c = 0;
|
|
|
|
for (int i = s.length() - 1; i > 0 && s[i] == '0'; --i) ++c;
|
|
|
|
c /= 3;
|
|
|
|
if (c >= sizeof(suffix)/sizeof(suffix[0]))
|
|
|
|
c = sizeof(suffix)/sizeof(suffix[0]) - 1;
|
|
|
|
s = s.left(s.length() - c * 3) + suffix[c];
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsJobFinished(KIO::Job* job)
|
|
|
|
{
|
|
|
|
if (((KIO::TransferJob*)job)->error() == 0)
|
|
|
|
{
|
|
|
|
QString temp;
|
|
|
|
temp = m_gsData.mid(m_gsData.find('(') + 1, m_gsData.findRev(')') - m_gsData.find('(') - 1);
|
|
|
|
temp = temp.mid(temp.find('(') + 1, temp.find(')') - temp.find('(') - 1);
|
|
|
|
temp.remove('"');
|
|
|
|
QStringList compList1 = QStringList::split(',', temp);
|
|
|
|
temp = m_gsData.mid(m_gsData.find(')') + 1, m_gsData.findRev(')') - m_gsData.find('(') - 1);
|
|
|
|
temp = temp.mid(temp.find('(') + 1, temp.find(')') - temp.find('(') - 1);
|
|
|
|
temp.remove('"');
|
|
|
|
temp.remove(',');
|
|
|
|
temp.remove('s');
|
|
|
|
QStringList compList2 = QStringList::split("reult", temp);
|
|
|
|
QStringList finalList;
|
|
|
|
for(uint j = 0; j < compList1.count(); j++)
|
|
|
|
{
|
|
|
|
if (m_googleMode!=ForAll || m_currentEngine == "google")
|
|
|
|
finalList.append(compList1[j].stripWhiteSpace() + " (" + reformatNumber(compList2[j]) + ")");
|
|
|
|
else
|
|
|
|
finalList.append(compList1[j].stripWhiteSpace());
|
|
|
|
}
|
|
|
|
//store text so that we can restore it if it gets erased after GS returns no results
|
|
|
|
temp = m_searchCombo->currentText();
|
|
|
|
m_searchCombo->listBox()->clear();
|
|
|
|
m_searchCombo->listBox()->insertStringList(finalList);
|
|
|
|
m_searchCombo->setIcon(m_searchIcon);
|
|
|
|
//restore text
|
|
|
|
m_searchCombo->lineEdit()->setText(temp);
|
|
|
|
if (finalList.count() != 0 && !m_gsTimer.isActive())
|
|
|
|
{
|
|
|
|
m_searchCombo->popup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_gsData = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsSetCompletedText(const QString& text)
|
|
|
|
{
|
|
|
|
QString currentText;
|
|
|
|
if (m_searchCombo->lineEdit()->hasSelectedText())
|
|
|
|
currentText = m_searchCombo->currentText().left(m_searchCombo->lineEdit()->selectionStart());
|
|
|
|
else
|
|
|
|
currentText = m_searchCombo->currentText();
|
|
|
|
if (currentText == text.left(currentText.length()))
|
|
|
|
{
|
|
|
|
m_searchCombo->lineEdit()->setText(text.left(text.find('(') - 1));
|
|
|
|
m_searchCombo->lineEdit()->setCursorPosition(currentText.length());
|
|
|
|
m_searchCombo->lineEdit()->setSelection(currentText.length(), m_searchCombo->currentText().length() - currentText.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SearchBarPlugin::gsPutTextInBox(const QString& text)
|
|
|
|
{
|
|
|
|
m_searchCombo->lineEdit()->setText(text.section('(', 0, 0).stripWhiteSpace());
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "searchbar.moc"
|